Skip to content

network

ClassDescription
ForceLayout-
NetworkThe network rendering engine (epic #98). A dedicated engine — nodes, links, layout, and LOD are one coupled system — built on the shared BaseEngine host/transform/zoom/interaction shell, rendering through the instanced lane (#100) rather than the retained Scene path.
InterfaceDescription
BuildGraphInput-
CoarseLevelOne coarsening level as a weighted, undirected edge list (parallel edges already collapsed).
CoarsenOptions-
CSRCompressed-sparse-row adjacency.
CutOptions-
DeclutterOptions-
FlowBorderSpecFlow-border style (#104 N6): a ring around each node/module whose width encodes a per-node flow (e.g. Infomap enter/exit flow). The app supplies the flow; d3gl renders the ring. For module aggregates the metric is summed over members (see computeLODStyle).
FlowGraphMinimal directed-graph shape (a NetworkGraph satisfies it; raw arrays work too).
FlowOptions-
FlowResult-
ForceParamsForce-directed layout core (sub-issue #102, epic #98). Operates directly on a LayoutGraph’s positions buffer + edge list — pure typed-array math, no DOM, so it runs unchanged on the main thread or inside a Web Worker (the worker + SharedArrayBuffer transport land in a later slice). Repulsion is Barnes-Hut O(n log n) via BarnesHutTree.
HalfLinkGeometryThe resolved anchor + control points of a half-arrow link (the vertices its outline visits).
HalfLinkParamsInputs for one directed half-arrow link (world coordinates/units).
HierarchyA coarsening hierarchy: progressively smaller graphs plus the maps that connect them.
LayoutGraphMinimal graph view the force core needs: node count, a directed edge list (used as undirected springs), and the positions buffer it mutates. NetworkGraph satisfies this structurally, and so does a synthetic coarse level (see ./coarsen.js) — so one force core lays out the full graph and every coarsening level without casts.
LODTransformScreen-space transform: screen = world * k + (x, y) (matches BaseEngine ViewTransform).
LODTreeA retained coarsening tree, flattened to SoA typed arrays for cache-friendly traversal at scale.
ModuleColorOptions-
ModuleNodeA graph node’s placement in the provided module tree — the Infomap JSON node shape. Extra fields (flow, name, modules, …) are accepted and ignored here; flow feeds flow-border rendering in N6b.
ModulePathNodeA node’s placement in the module tree — path is the Infomap 1-based chain (last entry is the rank).
MultilevelLayoutOptions-
NetworkGraphNetwork graph: directed-edge SoA for rendering + CSR for traversal.
NetworkLayoutOptionsHow node positions are produced. The worker / GPU backends land in later slices.
NetworkLODOptionsLevel-of-detail (#103): an adaptive hierarchy cut so a large network draws only what’s visible. Each pan/zoom re-cuts a retained coarsening tree — dense regions collapse to aggregate glyphs and expand into their members as you zoom in — bounding per-frame work to the visible frontier. Opt-in via Network.lod; off by default (every node/link drawn). The tree’s geometry updates as the layout converges (so LOD helps during the solve, not only after), and the zoom-time path re-cuts only the visible frontier. Best paired with style({ sizeMode: "screen" }).
NetworkOptionsOptions for the network engine. Inherits sizing, backend, and tooltipClass.
NetworkStyleVisual style. Link appearance accessors arrive with the link pass (#100 N2.2).
ParsedEdgesEdge-list ingestion (sub-issue #99 / epic #98).
ParsedPajekEdge-list ingestion (sub-issue #99 / epic #98).
PathSinkA minimal 2-D path sink (matches the subset of CanvasRenderingContext2D / d3gl’s PathContext we use).
Type AliasDescription
ImportanceSpecHow a node’s declutter importance is determined: a NodeMetric ("degree"/"strength"/ "flow"/accessor), a per-node Float32Array, or "order" (a flat priority — so the survivor of a cluster falls back to input order, and an aggregate ranks by its subtree size). Resolved per-leaf and summed up the LOD tree (so a module’s importance is its members’ total — e.g. total flow), then used to break overlaps in the declutter: the highest-importance glyph in a cluster is kept.
LinkColorSpecLink colour. A single CSS colour; a (weight) => cssColour scale (a bare d3 sequential/linear colour scale fits — scaleSqrt().range([light, dark]) interpolates RGBA, alpha included); or { by, scale } for parity with LinkWidthSpec. Whichever form, it resolves to a function of a weight value, so a super-edge colours by its accumulated subsumed weight (darker/heavier reads as more important).
LinkStyleHow directed links are drawn: plain "line" + a separate arrowhead, or a fused "half-arrow" (the map glyph).
LinkWidthSpecLink width. A constant, a (weight) => width scale of the edge weight (a bare d3 scale fits — its input is the edge’s weight, which is the per-edge flow), or { by, scale } for parity with NodeRadiusSpec (by is "weight"/"flow" — the same per-edge quantity — so the scale maps the weight). Whichever form, it resolves to a function of a weight value, so a super-edge applies the same scale to the accumulated weight of the edges it subsumes.
NetworkFormatNetwork text formats parseNetwork can read.
NodeMetricA built-in per-node metric d3gl can read directly, or a custom (index, graph) => value accessor. "degree" is the neighbour count (CSR.degree); "strength" the weighted degree (NetworkGraph.strength); "flow" the app-provided NetworkGraph.flow (errors if absent).
NodeRadiusSpecHow node radius is determined. Resolves once (per style() call) to a per-node Float32Array, which is already a per-instance GPU attribute — so any of these forms is free at draw time.
VariableDescription
DEFAULT_FORCE-
FunctionDescription
buildCSRBuild undirected (symmetric) CSR adjacency from a directed edge list. Each edge contributes to both endpoints, so layout/traversal see the graph as undirected while the directed edges remain available for arrow rendering.
buildGraphAssemble a NetworkGraph from a directed edge list.
buildHierarchyBuild the full coarsening hierarchy, stopping at minNodes or when a pass stops reducing.
buildLODTreeBuild the retained LOD tree topology from a graph’s coarsening hierarchy. Geometry is left zeroed; call computeLODGeometry once positions have settled. This is the main-thread path (the force/positions backends and LOD enabled after a worker has finished); the worker backend streams an already-built LODTopology instead (#103), assembled via lodTreeFromTopology.
buildModuleLODTreeBuild a LODTree from a provided module hierarchy (the priority-chain entry that precedes structural coarsening). Geometry is left zeroed — fill it with computeLODGeometry once positions exist.
coarsenLevelOne coarsening step. Visit nodes in index order and pair each unmatched node with its heaviest unmatched neighbour (lowest index breaks ties → deterministic). A node with no unmatched neighbour is adopted into its heaviest already-matched neighbour’s group rather than left as a singleton: without this, hub/star structures (pervasive in power-law graphs) barely shrink — each pass strips only a couple of nodes, the hierarchy hits its level cap, and the multilevel seed runs dozens of force solves on near-full graphs (#117). Adoption keeps the per-level reduction roughly geometric. Then aggregate the surviving inter-group edges (parallel edges summed, internal edges dropped).
computeLODGeometryFill the tree’s full geometry from the settled layout, the per-leaf visual radii, and a per-leaf importance weight — computeLODPositions then computeLODStyle. The main-thread path (synchronous solve / supplied positions); the worker backend splits these passes across threads.
cut-
declutterFrontierThin an LOD frontier in screen space: keep higher-importance glyphs (by tree LODTree.weight = strength) and drop lower-importance ones that would overlap a kept glyph (centre distance < sum of the two radii). Greedy in descending importance over a uniform screen grid, so a dense cluster keeps its most important members and the kept set is overlap-free (no overdraw). Runs per cut, so it’s zoom-dependent — more glyphs resolve as you zoom in. Returns the kept frontier ids (original order).
detectFormatPick a parser: Pajek for a .net filename or text with a *Vertices/*Arcs/*Edges section header; otherwise the plain edge list. A filename extension wins over content sniffing.
halfLinkGeometryResolve the half-arrow link’s outline vertices, or null when the link should be skipped (the nodes overlap and the bend is too small to route around them — matches the reference’s guard).
halfLinkPathStringThe reference SVG path string for a half-arrow link (or "" when skipped) — same command sequence and number formatting as mapequation’s network-rendering, so it is golden-tested against its example.svg.
moduleColorsPer-node CSS colours (indexed by node id) for a module hierarchy. A node takes the hue of its enclosing module (path minus the final rank), so all nodes in a module share a colour and sibling modules get neighbouring hues within their parent’s arc.
multilevelLayoutMultilevel force layout: multilevelSeed then refine the finest level in place. Writes graph.positions. This is the synchronous main-thread path; the worker reuses multilevelSeed and streams the finest-level refinement instead.
network@mapequation/d3gl/network — large-scale network & map-of-networks rendering with level-of-detail (epic #98).
parseEdgeListParse a whitespace-separated edge list: source target [weight] per line. Blank lines and # comment lines are ignored.
parseNetworkParse a network from text, choosing the format via detectFormat: Pajek .net or a plain edge list (source target [weight], # comments). Edge lists are reported as undirected.
parsePajekParse a Pajek .net document into a directed-or-undirected edge list (+ optional positions).
randomWalkFlowCompute the random-walk FlowResult for a directed graph. O(iterations · edges); a handful of milliseconds for the thousands-of-nodes scale this is meant for. Run it offline to bake a fixture.
scaleHalfLinkUniformly scale a resolved half-arrow geometry’s coordinates by s (about the origin). Used to “bake” a screen-space shape for the retained SVG/Canvas path: the shape is solved in pixel space (node centres × k, sizes in px) — because the tip length (width^⅓), tip width (width^½) and outer bend (^0.4) are not linear in size, so they can’t be reproduced by pre-dividing the sizes — and the result is scaled by 1/k, so the Scene’s ×k view transform reproduces the exact pixel shape.
seedPositionsSeed node positions deterministically as a phyllotaxis (“sunflower”) disc centred on the viewport — a good, reproducible starting distribution for ForceLayout when a graph arrives without coordinates (no two nodes coincident, no RNG).
traceHalfLinkTrace a resolved half-arrow link onto a PathSink (Canvas/SVG export), as the reference does: inner-start → source centre → foot → outer edge (quadratic via cp2) → barb → tip → inner base → inner edge (quadratic via cp1) → close.