# Multilayer Network Visualizer

Interactive manual — all features, modes, and controls

##
Import Network Data

The Data panel is always visible in the left sidebar, regardless of active mode.

### Load Example Data

Opens a dialog with seven built-in datasets. See Built-in Datasets below for the full list.

### Load User Data (JSON)

Upload a `.json` file formatted according to the JSON format below.

    {
      "directed": false,
      "directed_interlayer": false,
      "layers": [
        { "layer_id": 1, "layer_name": "Forest", "latitude": 42.3, "longitude": 3.1, "bipartite": true }
      ],
      "nodes": [
        { "node_id": "sp_1", "node_name": "Bee", "node_type": "pollinator" }
      ],
      "extended": [
        { "layer_from": "Forest", "node_from": "Bee", "layer_to": "Forest", "node_to": "Flower", "weight": 1.5 }
      ],
      "state_nodes": [
        { "layer_name": "Forest", "node_name": "Bee" }
      ]
    }

#### Global fields

- `directed` (Boolean) — renders arrowheads on all edges. Default: `false`.
- `directed_interlayer` (Boolean, optional) — when `true`, interlayer edges are treated as directed even if the overall network is undirected. Useful for temporal networks where direction represents time (e.g. year t → year t+1). Defaults to the value of `directed`.

#### `layers` array

- `layer_id` — unique identifier.
- `layer_name` — display name.
- `latitude` / `longitude` (optional) — unlocks Map Mode.
- `bipartite` (optional, Boolean) — set `true` to mark this layer bipartite. Nodes must carry a `node_type` attribute with exactly two distinct values within this layer. Different layers may use different pairs (diagonal-coupling). Never auto-detected.
- Any extra fields become selectable attributes for color/size mapping.

#### `nodes` array

- `node_id` — unique identifier.
- `node_name` — display label.
- `node_type` (required for bipartite layers) — each bipartite layer must have exactly two distinct values among its own nodes; determines Set A vs. Set B. Globally more than two values are allowed (diagonal-coupling networks).
- Any extra fields become selectable attributes for color/size mapping.

#### `extended` array

One row per edge. Intralayer and interlayer edges both go here.

- `layer_from`, `node_from`, `layer_to`, `node_to` — required.
- `weight` (optional) — line thickness/opacity. Defaults to 1.
- Any extra fields become selectable attributes for color/size mapping.

#### `state_nodes` array

Enumerates every (layer, node) pair present. Required for correct rendering.

- `layer_name`, `node_name` — required.
- Any extra fields carry per-layer node attributes — attributes whose value can differ for the same node in different layers (e.g. `abundance`, `module`). These are distinct from physical node attributes (in the `nodes` array), which are constant across layers.

### Load User Data (CSV)

Load network data from CSV files. A modal dialog accepts up to four files:

- Extended Edge List (required) — one row per link, columns: `layer_from`, `node_from`, `layer_to`, `node_to`, `weight` (optional). Both intralayer and interlayer links go in this single file.
- Layer Attributes (optional) — columns: `layer_id`, `layer_name`, `latitude`, `longitude`, `bipartite` (TRUE/FALSE), and any additional columns for layer attributes (e.g. `area`, `elevation`) which become available for color mapping. If omitted, layers are derived from the edge list and all treated as unipartite.
- Node Attributes (optional) — columns: `node_name` (required), `node_type` (required when any layer is marked bipartite — each bipartite layer must have exactly two distinct `node_type` values among its own nodes, but different layers may use different pairs, supporting diagonal-coupling networks), and any additional columns for physical node attributes that are the same across all layers (e.g. `body_mass`, `guild`). If omitted, nodes are derived from the edge list with no attributes.
- State Node Attributes (optional) — columns: `layer_name` (required), `node_name` (required), plus any additional columns for per-layer node attributes that can differ across layers (e.g. `abundance`, `module`). Use this when the same species or node has a different value in each temporal or spatial layer. Rows that do not match a (layer, node) pair already present in the edge list are silently ignored.

Bipartite declaration: bipartite is never auto-detected. Mark a layer as bipartite via the `bipartite=TRUE` column in the layers file, and provide a `node_type` column in the nodes file. Each bipartite layer must have exactly two distinct `node_type` values among its own nodes. Diagonal-coupling networks (e.g. plant–pollinator + plant–herbivore) are supported: different layers may share one node set but pair it with a different partner set, resulting in more than two `node_type` values globally — this is fine as long as each individual layer has exactly two.

The Directed checkbox marks all edges as directed before loading. Comma, tab, and semicolon delimiters are auto-detected.

Note: The (layer, node) pairs are derived automatically from the edge list — you do not need to supply them. The optional State Node Attributes file lets you attach per-layer attributes to those pairs without modifying any other file.

#### Example — four-file import (temporal network with per-layer abundance)

network_edges.csv (required)

    layer_from,node_from,layer_to,node_to,weight
    1982,Apodemus_agrarius,1982,Ixodes_ricinus,1
    1982,Apodemus_peninsulae,1982,Ixodes_ricinus,1
    1983,Apodemus_agrarius,1983,Ixodes_ricinus,1

network_layers.csv (optional)

    layer_id,layer_name
    1,1982
    2,1983

network_nodes.csv (optional — physical attributes, same across all layers)

    node_name,body_mass_g
    Apodemus_agrarius,22
    Apodemus_peninsulae,28
    Ixodes_ricinus,0.003

network_state_nodes.csv (optional — per-layer attributes, can differ across layers)

    layer_name,node_name,abundance,module
    1982,Apodemus_agrarius,82,3
    1982,Apodemus_peninsulae,14,3
    1983,Apodemus_agrarius,61,2
    1983,Apodemus_peninsulae,19,1

After loading, `abundance` and `module` appear in the Color By and Size By dropdowns as State attributes, and their values reflect the specific layer each node is in.

##
Built-in Example Datasets

Dataset | Reference | Type | Layers | Notes
--- | --- | --- | --- | ---
Canary Islands pollination network | Vitali et al. 2024 | Undirected bipartite | 5 | Spatial pollination; GPS coordinates → Map Mode and geographic Layer View
Basque Country spatial pollination | Magrach et al. (EuPPollNet) | Undirected bipartite | 5 | Spatial pollination; GPS coordinates
Portuguese temporal seed dispersal | Costa et al. 2020 | Undirected bipartite, directed interlayer | 5 | Temporal (annual 2012–2016); interlayer weights = abundance ratio t+1/t
Chilean intertidal food web | Kéfi et al. 2016 | Directed unipartite | 3 | Multiplex: trophic, positive non-trophic, negative non-trophic interactions
Siberian host–parasite network | Pilosof et al. 2017 | Undirected bipartite, directed interlayer | 6 | Temporal (annual 1982–1987)

##
Visualization Modes

Six modes are available, switched via the top toolbar strip. The left sidebar is dynamic — its panels (Data, Layers, Nodes, Links, Search, and others) change automatically to show controls relevant to the active mode.

##
Network Mode Default

All layers rendered simultaneously in a continuous 3D coordinate space.

#### Navigation

- Rotate — drag the background.
- Pan — `Shift` + drag.
- Drag a layer — `Cmd` / `Ctrl` + drag a layer outline.
- Zoom — scroll wheel or `+` / `−` toolbar buttons.

#### Interactions

- Node / Link Hover — highlights the hovered element's connections and dims the rest. A tooltip shows node or link data.
- Click a node — locks its web of connections in focus. Click the background to clear.
- Search Nodes — type in the sidebar search box to locate a node by name; click a result to select and center it.

### Sidebar Controls

#### Layers

- Layer Names — toggle floating title tags above each plane.
- Stacking Mode — Horizontal (layers recede into Z-axis, default) or Vertical (layers drop along Y-axis).
- Layer Spacing — simulated distance between planes.
- Layout Algorithm — Fruchterman-Reingold, Kamada-Kawai, Bipartite (two-row, optional nested sorting), Circle, Grid, or Random.
- Color By (layers) — color layer planes by a numeric attribute (e.g. area, elevation). Produces a continuous Viridis legend.

#### Nodes

- Node Labels — show names on hover or permanently.
- Transform Nodes — skew nodes to match the isometric perspective. Disable for large networks.
- Color By — Layer, Group, or Uniform. Bipartite networks show independent color pickers for Set A and Set B.
- Size By — uniform Base Size slider, or scale by Node Degree. Bipartite networks show independent Size By dropdowns for Set A and Set B.

#### Links

- Show Interlayer Links — toggle cross-layer edges.
- Color By — by type (Inter vs. Intra) or by originating layer color.

#### Search

- Search Nodes — type to filter the node list by name. Matching nodes are highlighted in the canvas; click a result to select and focus it.

##
Map Mode

Layers placed on an interactive Leaflet world map. Only available when the dataset includes `latitude` and `longitude` on its layers.

- Layer Markers — layers appear as blue circle markers on the map.
- Select Layers panel — a draggable, collapsible panel (top-right by default) lists all layers. Click a layer name to pop it into floating 3D space; click `✕` next to an active layer to close it. Useful when multiple layers share the same geographic location and their markers overlap.
- Pop-Out Layers — click a marker or a layer name in the Select Layers panel to pop that layer into floating 3D space. Multiple layers can be popped simultaneously.
- Close Popped Layer — click the red `✕` on a floating layer or the `✕` in the Select Layers panel to return it to the map.
- Map Opacity — slider in the bottom bar fades the satellite imagery. Uncheck "Show Map" to remove it entirely.
- Map Navigation — pan and zoom the Leaflet map freely. `Shift` + drag carries popped-out layers with it.

### Sidebar Controls

Same as Network Mode (Layers, Nodes, Links sections). Map-specific controls appear in the bottom bar:

- Map Opacity — fade the base map tile layer.
- Show Map — toggle the Leaflet tile layer entirely.
- Show Locations — toggle the blue circle layer markers.
- Street Map — switch between satellite imagery (default) and OpenStreetMap street tiles.

##
Layer Mode

Each layer becomes an interactive bubble in a force-directed meta-graph. Individual nodes are abstracted away.

- Inside each bubble: a micro-graph preview of internal topology.
- Blue solid lines — interlayer links. Thickness = count.
- Gray lines — shared physical nodes. Thickness = fraction shared.

### Interactions

- Drag a bubble to pin it. Reset in the toolbar unpins all and re-runs layout.
- Click a bubble — others fade; a Layer Stats panel shows identity, size, connectivity.
- Cmd+click / Ctrl+click a second bubble — opens a Layer Comparison panel with size, overlap (Jaccard, shared nodes/edges), divergence (density ratio, degree histogram), and cross-layer link count.
- Click empty space — deselect and clear the stats panel.
- Scroll — zoom centered on cursor. Drag background — pan.

### Sidebar Controls

#### Layers

- Size by — bubble radius: Number of nodes, Number of edges, Edge density, or Uniform.
- Color by — Layer (categorical), Node count (YlOrRd), Edge density (YlOrRd), or Uniform.
- Size multiplier — global scale (0.5× – 2.0×).
- Show layer name labels — toggle text labels below bubbles.
- Bubble spacing — equilibrium distance in the force layout.

#### Edges

- Show edges — toggle all meta-edges.
- Edge metric — Interlayer links, Shared nodes, or Both.
- Min edge weight — hide edges below this threshold.
- Show edge weight labels — toggle numeric labels.

### Geographic Mode GPS datasets only

When every layer in the dataset has `latitude` and `longitude`, Layer View activates in Geographic mode automatically — bubbles are pinned to their real-world coordinates on a Leaflet satellite map background.

- A Force Layout toggle button at the top of the Layers sidebar section switches to the standard force-directed view and back.
- Bubbles cannot be dragged — they are pinned to map coordinates. Layers that share the same location (e.g. temporal networks sampled at one site) are automatically fanned out in a circle around their shared coordinate; a dashed tether line connects each bubble back to the true location.
- Scroll and drag pan/zoom the Leaflet map (not the canvas).
- + / − toolbar buttons zoom the map; Reset fits all layers into view.
- Map Opacity, Show Map, and Street Map controls appear in the bottom bar (same controls as Map Mode).
- Hover tooltips, bubble selection, and Cmd+click comparison all work normally.

## Σ Meta-Network Mode

Aggregates all intralayer links across every layer into a single, flat 2D network of unique physical nodes. Use this mode to see the full interaction graph of your multilayer network, independent of which layer each interaction was observed in.

- Nodes — every unique physical node that appears in at least one layer.
- Edges — one edge per unique node pair that shares an intralayer link in any layer. Edge weight depends on the aggregation mode.
- Bipartite networks — when the dataset contains bipartite layers, the mode defaults to the Two-row layout with Set A above and Set B below, separated by dashed guide lines.
- Directed networks — direction is preserved; arrowheads are drawn on each edge.

Activate via the Σ button in the top toolbar strip. Clicking it again returns to Network Mode.

### Interactions

#### Node selection

- Click a node — selects it. The selected node and all its direct neighbours stay fully opaque; everything else fades. An Info panel appears showing Participation, Layers, Meta-degree, and Meta-strength.
- Click the same node again — deselects and restores all opacities.
- Click empty space — deselects.
- Drag a node — pins it at the new position (force and two-row layouts). Click-and-release without moving never pins.

#### Edge selection

- Click an edge — selects it. The edge is redrawn in blue; its two endpoint nodes get blue selection rings and stay fully opaque; all other nodes and edges fade. The Info panel shows how many layers the edge appears in and a per-layer bar chart of its weight.
- Click the same edge again — deselects.

#### Navigation

- Scroll — zoom centred on the cursor.
- Drag background — pan the view.

### Sidebar Controls

#### Aggregation

- Union — an edge exists if it appears in at least one layer; all weights = 1.
- Sum weights — edge weight = sum of `weight` values across all layers it appears in.
- Sum occurrence (default) — edge weight = number of layers the edge appears in.

Edge thickness in the canvas scales linearly with weight.

#### Layout

- Circular (default for unipartite) — nodes arranged on a circle, sorted by meta-degree. Layout is static; dragging nodes keeps them pinned at the new position until Reset Layout is clicked.
- Force layout — d3-force simulation. Nodes repel each other; edges act as springs. The layout settles automatically; individual nodes can be dragged to pin them.
- Two-row (default for bipartite) — Set A fixed on the top row, Set B on the bottom row. Nodes are sorted by meta-degree within each row; when rows are dense, circles overlap to fit within the canvas. The Nested sort checkbox (enabled by default) controls this sorting.

- Reset Layout — re-runs the layout algorithm from scratch, clearing any manual node positions.

#### Appearance

- Color By — color nodes by Participation (number of layers) or Meta-degree (number of unique neighbours), both using the ice palette (light cyan → dark navy). Uniform applies a single green tint to all nodes. A gradient legend appears in the bottom-right corner.
- Size By — scale node radius by Meta-degree (default) or Participation. Uniform gives all nodes the same radius. A size legend appears alongside the color legend.
- Base Size — global multiplier (0.5× – 3.0×) applied on top of the Size By scaling.
- Min Link Weight — hide edges whose weight is below this threshold. Slider maximum matches the heaviest edge in the current aggregation.
- Show Labels — toggle node name labels. Labels are drawn at 45° to reduce overlap; in two-row layout, Set A labels angle upward and Set B downward.
- Nested sort two-row only — sort each row by meta-degree so high-degree nodes cluster at the centre.

### Layer Filter

A draggable, collapsible Select Layers panel appears in the top-right corner. By default all layers are included (no filtering). Click a layer name to activate it; click again to deactivate. All / Clear buttons select or deselect every layer at once.

When one or more layers are active, only nodes and edges that have links in those layers remain fully opaque; the rest fade to near-invisible. This lets you isolate temporal or spatial slices of the aggregated network.

### Search

The Search Nodes panel in the sidebar (below the main controls) works like network-mode search:

- Type a name to filter nodes. Up to 12 matches appear in a dropdown.
- Hover a result — the node's ego-network is previewed in the canvas immediately.
- Click a result (or press `Enter` for the first match) — commits the selection, opens the Info panel, and keeps the ego-network visible.
- ✕ Clear button — clears the search field and deselects.
- Press `Escape` — closes the dropdown without selecting.

##
Dashboard Mode

Replaces the canvas with analytics panels. All sections are collapsible — click a header to expand/collapse.

### Sidebar Controls

- Sort layers by — order layers in all charts by Participation, Nodes, Intra-links, Inter-links, or Density.
- Show bipartite detail — (bipartite networks only) hide/show Set A / Set B split panels. This checkbox appears in the sidebar only while Dashboard Mode is active.

#### KPI Cards

Five headline numbers: total unique nodes, total layers, total intralayer links, total interlayer links, and mean edge density.

#### Per-Layer Bar Charts

Side-by-side bars per layer: node count, intralayer links, interlayer links, and edge density. The highest-value bar is accent-colored. For bipartite networks the node-count chart becomes a stacked bar split by Set A and Set B. Clicking a layer name highlights it in the background network.

#### Link Weight Distributions

Two histograms showing the distribution of edge weights across the network.

- Intralayer — a dropdown above the histogram lets you choose All layers (aggregated, default) or any specific layer.
- Interlayer — histogram paired with a count heatmap to its left. Heatmap cells show the raw number of interlayer links between each pair of layers (amber colour scale). Click a non-empty cell to filter the histogram to that pair; a ✕ Clear button resets to all pairs. For temporal networks with `directed_interlayer: true` the heatmap is asymmetric (e.g. 1982→1983 is distinct from 1983→1982).

Only shown when the dataset has weighted edges (all weights = 1 still displays, confirming the network is unweighted).

#### Node × Layer Presence Matrix

Heatmap of which nodes appear in which layers. A toggle switches orientation between Layer rows × Node cols (default, exploits screen width) and Node rows × Layer cols. Sort buttons reorder alphabetically or by participation count.

#### Layer Similarity (Jaccard)

Square heatmaps where rows and columns are layers. Each cell = Jaccard similarity (0 = white → 1 = accent).

- Node identity — overlap in which physical nodes appear. Bipartite networks split into Set A, Set B, and edge matrices (three total).
- Edge identity — overlap in which edges appear across layers (amber).

Diagonal = 1 by computation. Empty layers → gray (NaN).

#### Degree Distributions

Histograms of node degree for the full network and per layer. Bipartite: separate histograms for Set A and Set B.

#### Node Participation

Bar chart showing how many layers each node appears in, sorted by count. Bipartite: Set A and Set B shown separately.

##
Data Mode

A tabular inspection and subsetting interface for your network data — similar to Gephi's Data Laboratory. Switch to Data Mode via the grid icon in the top toolbar strip.

### Tables

Four tabs display different aspects of the loaded network:

- Nodes — one row per physical node. Shows `node_name`, `layer_count` (number of layers the node appears in), and any imported node attributes.
- State Nodes — one row per (layer, node) pair. Shows `layer_name`, `node_name`, computed `degree`, and any per-layer state node attributes (e.g. `abundance`, `module`).
- Links — one row per edge. Shows `layer_from`, `node_from`, `layer_to`, `node_to`, `weight`, a type pill (intralayer or interlayer), and any imported link attributes.
- Layers — one row per layer. Shows `layer_name`, `node_count`, `link_count`, a color picker, and any imported layer attributes.

Click any column header label to sort by that column. Click again to reverse the sort order. A third click removes sorting.

### Column Filters

Each column header shows a funnel icon (▼). Click it to open a filter popup for that column:

- Checkbox filter — for columns with 40 or fewer unique values. A scrollable list of checkboxes lets you include or exclude specific values. A search box at the top narrows the list. Use Select All / Clear All for bulk toggling.
- Text filter — for numeric columns or columns with many unique values. Type a substring to match against. Press `Enter` or click Apply to commit.

Active filters are indicated by a highlighted (indigo) funnel icon. Multiple column filters combine with AND logic — a row must match all active filters to appear.

Click Reset inside any popup to clear that column's filter.

### Row Selection

Click any row to select it (highlighted in indigo). Multi-select is supported:

- `Cmd` / `Ctrl` + Click — toggle individual rows on or off.
- `Shift` + Click — select a contiguous range from the last-clicked row to the current row.

When rows are selected, a purple action bar appears at the top showing the count. Click Filter to selection to subset the network to only the selected rows. Click Clear to deselect all.

### Subsetting

Filters and selections in Data Mode propagate to Network and Map modes. When a subset is active:

- Only matching nodes, links, and layers are rendered on the canvas.
- A compact amber filter banner appears in the bottom-right corner (above the branding panel) showing how many items are filtered and a Clear button.
- The banner is visible only in Network and Map modes — it hides in other modes.

Subsets are derived from the active tab: filtering the Nodes tab subsets by node names; filtering Layers subsets by layer names; filtering Links subsets by individual link keys.

Tip: Use column filters to narrow the table first, then use row multi-select + Filter to selection for precise control over which items appear in the visualization.

### Layer Colors

The Layers tab includes a color picker in each row. Changing a layer's color here updates it everywhere:

- The color persists when switching back to Network or Map mode.
- In the Network Mode sidebar, set Layer Color By to Individual to use these per-layer colors for the layer planes.

Default colors are assigned from a built-in palette and can be customized at any time.

### CSV Export

Click the Export CSV button to download the currently visible (filtered) rows as a `.csv` file. The export respects all active column filters and row selections — only what you see in the table is exported.

##
Top Toolbar Strip

A full-width frosted-glass strip pinned to the top of the canvas. Buttons from left to right:

Icon | Action
--- | ---
? | Help — opens this manual in a new tab. In the app, clicking it first shows a context-sensitive quick-help popup for the current mode.
| Network Mode — return to the default 3D oblique multilayer canvas.
| Map Mode — toggle geographic Map Mode (only visible when dataset has coordinates).
| Layer Mode — toggle Layer Mode (interactive meta-graph of layers).
Σ | Meta-Network Mode — aggregate all intralayer links into a single 2D monolayer network.
| Dashboard Mode — toggle analytics dashboard.
| Data Mode — tabular inspection and subsetting (nodes, links, layers, state nodes).
+ | Zoom In
− | Zoom Out
Reset | Reset Viewport — reset zoom, pan, and 3D angle. In Layer Mode, also unpins all bubbles and re-runs the force layout.
| Toggle Legend — show or hide the dynamic legend panel.
| Snapshot — high-resolution export. Choose PNG, JPG, or PDF; optionally include the backdrop grid.

##
Dynamic Legend

A legend panel appears in the bottom-right corner whenever color or size mappings are active. Legends expand automatically when you select an attribute. Toggle panel visibility with the legend button in the top toolbar strip.

- Draggable — drag the legend box to reposition it anywhere on screen.
- Collapsible — click ✕ on a legend box to collapse it to a small expand button; click the button to restore it.
- Per-set legends — bipartite networks show separate color and size legends for Set A and Set B (e.g. "Node Color (bird)" / "Node Color (plant)").
- Categorical color pickers — for any categorical attribute (e.g. `node_type`, `module`), each legend entry shows a circular color swatch. Click a swatch to open the OS color picker and assign a custom color to that value. Changes apply instantly. Overrides persist for the session and are cleared by Reset Visualization Options.
- Continuous/Discrete toggle — for numeric attributes, a pill button in the legend header switches between a continuous gradient and a discrete categorical palette.

##
Integration with the emln R Package

The emln R package provides three functions to load and export multilayer networks directly into MultilayerViz — no manual file preparation required.

    library(emln)
    net <- load_emln(60)               # load a built-in dataset

    # Open directly in the browser
    srv <- plot_multilayer(net, bipartite = TRUE)
    httpuv::stopServer(srv)            # stop server when done

    # Or export to JSON / CSV for manual upload
    multilayer_to_json(net, file = "network.json", bipartite = TRUE)
    multilayer_to_csv(net, dir = "out/", prefix = "net60", bipartite = TRUE)

### plot_multilayer()

Converts the multilayer object to JSON and opens MultilayerViz in the default browser, served over a local HTTP server. The network loads automatically — no file selection needed.

Argument | Default | Description
--- | --- | ---
`multilayer` | — | A multilayer object from `create_multilayer_network()` or `load_emln()`.
`bipartite` | `FALSE` | Set `TRUE` explicitly for bipartite networks. Requires a `node_type` (or legacy `node_group` / `type`) column with exactly two distinct values.
`directed` | `NULL` | If `NULL`, auto-detected from edge symmetry. Set explicitly if auto-detection is wrong (e.g. pollinator networks store edges one-way but are ecologically undirected).
`port` | `8080` | Starting port for the local HTTP server. Next available port is tried automatically if busy. Actual port printed to console; retrieve with `srv$getPort()`.
`viz_path` | `NULL` | Path to the MultilayerViz directory. If `NULL`, uses the copy bundled with the installed emln package. Pass explicitly to use a different version of the app.
`browser` | `getOption("browser")` | Browser command. On macOS, `"chrome"` is automatically expanded to `open -a 'Google Chrome'`.

Returns: the httpuv server handle. Call `httpuv::stopServer(srv)` or close R to shut it down. To kill all app servers from the terminal: `lsof -ti TCP:8000-8200 | xargs kill -9`

### multilayer_to_json()

Exports the network to the JSON format expected by MultilayerViz. Returns the JSON string, or writes it to a file.

Argument | Default | Description
--- | --- | ---
`multilayer` | — | A multilayer object.
`file` | `NULL` | If provided, writes JSON to this file path. If `NULL`, returns the JSON string invisibly.
`bipartite` | `FALSE` | Same as `plot_multilayer()`. Adds `bipartite: true` to every layer in the JSON.
`directed` | `NULL` | Sets the top-level `directed` field in the JSON. Auto-detected if `NULL`.

Legacy column renaming: the nodes table column `node_group` or `type` is automatically renamed to `node_type` (the canonical name) in the output.

### multilayer_to_csv()

Exports the network as CSV files matching the CSV import schema — ready to drag-and-drop into MultilayerViz. Three files are always written (`_edges`, `_layers`, `_nodes`); a fourth `_state_nodes` file is added automatically when the multilayer object contains per-layer node attributes (e.g. `abundance`, `module`).

Argument | Default | Description
--- | --- | ---
`multilayer` | — | A multilayer object.
`dir` | — | Output directory. Created automatically if it does not exist.
`prefix` | `"network"` | File name prefix. Always produces `<prefix>_edges.csv`, `<prefix>_layers.csv`, `<prefix>_nodes.csv`; optionally `<prefix>_state_nodes.csv`.
`bipartite` | `FALSE` | When `TRUE`, adds a `bipartite` column to the layers CSV and writes `node_type` to the nodes CSV.
`directed` | `NULL` | Not written to files — set directed/undirected in the app's CSV import dialog at load time.