Skip to content

Layouts

Layouts position the nodes of the current graph. Each runner on nodus.layouts returns Promise<void>, so await it before framing the graph. For the concepts behind each algorithm see Layouts and the Applying Layouts guide.

Runners

All runners share the signature (opts?) => Promise<void>:

  • force(opts?) — force-directed layout (repulsion between nodes, attraction along edges).
  • forceLink(opts?) — a force layout tuned around link/edge forces.
  • hierarchical(opts?) — layered layout for directed/tree-like graphs.
  • grid(opts?) — arrange nodes on a regular grid.
  • radial(opts?) — arrange nodes radially around a center.
  • concentric(opts?) — arrange nodes in concentric rings.
  • sequential(opts?) — order nodes along a sequence.
  • stop() — stop a running (animated) layout.
await nodus.layouts.force();
await nodus.view.locateGraph();

Common option: duration

Every layout accepts duration (milliseconds):

  • duration: 0 — jump straight to the final positions (static).
  • a positive value — animate to the final positions over that many milliseconds.
// Static: snap to final positions immediately.
await nodus.layouts.hierarchical({ duration: 0 });
// Animated: ease nodes into place over 600 ms.
await nodus.layouts.force({ duration: 600 });

Per-layout options

Each layout accepts duration plus the options below. All have defaults — you can call any layout with no options (except radial and concentric, which require centralNode).

force(opts?)

OptionDescription
gravityPull toward the center that keeps the graph compact (default 0.01).
edgeStrengthAttraction strength along edges (default 0.5).
thetaBarnes–Hut accuracy/speed trade-off (default 0.62).
autoStopStop automatically when the layout settles.
nodeMass(node) / edgeWeight(edge)Per-element mass / edge weight functions.

forceLink(opts?)

OptionDescription
scalingRatioOverall scale of the repulsion/attraction balance.
nodeMass(node) / edgeWeight(edge)Per-element mass / edge weight functions.

hierarchical(opts?)

OptionDescription
directionFlow direction: 'TB' top→bottom (default), 'BT' bottom→top, 'LR' left→right, 'RL' right→left.
nodesSeparationGap between nodes in a layer (default 5).
layerSeparationGap between layers (default 50).
siblingsDistanceGap between sibling subtrees (default 10).
componentsSeparationGap between disconnected components (default 50).
decrossRun crossing reduction (default true).

grid(opts?)

OptionDescription
rows / colsForce a grid shape (otherwise derived from the node count).
rowDistance / colDistanceSpacing between rows / columns.
sortByAttribute name or (node) => value to order the cells.
reverseReverse the sort order.

radial(opts?) — requires centralNode

OptionDescription
centralNodeRequired. Id of the node at the center.
nodeGapMinimum gap between nodes (default 10).
radiusRatioGrowth factor between rings (default √2).
radiusDeltaAdditional fixed spacing between rings (default 0).
centerX / centerYOverride the center position.
await nodus.layouts.radial({ centralNode: 'root', duration: 600 });

concentric(opts?) — requires centralNode

OptionDescription
centralNodeRequired. Id of the node at the innermost ring.
clockwisePlace nodes clockwise (default true).
await nodus.layouts.concentric({ centralNode: 'root', duration: 600 });

sequential(opts?)

Arranges nodes along a sequence. Accepts duration (and runs in a Web Worker by default).

To stop an animating layout early:

nodus.layouts.stop();

Layout factories

For advanced use — registering or configuring a layout outside the everyday nodus.layouts.* API — the factory functions are exported from the package:

import {
forceFactory,
forceLinkFactory,
gridFactory,
hierarchicalFactory,
radialFactory,
concentricFactory,
sequentialFactory,
} from '@kortexya/nodus';

Each factory corresponds to the runner of the same name. For everyday work, prefer the nodus.layouts.* methods above.