Automatic Layouts
JointJS ships several layout plugins that position a graph from its structure, so you don't place nodes by hand. Driving any of them from @joint/react is the same two steps - run the layout once your elements have their sizes, and let it write the positions back onto the cells you already render - so this section shows the pattern once, with Directed Graph as the worked example.
| Layout | Produces | Package |
|---|---|---|
| Directed Graph | Ranked flow (top-down, left-right, …) | @joint/layout-directed-graph (open source) |
| MSAGL | Layered (Sugiyama) flow with edge routing | @joint/layout-msagl (open source) |
| Force Directed | Physics simulation you start and step | JointJS+ |
| Tree | Hierarchies with a chosen direction and sibling order | JointJS+ |
| Stack | Rows or columns | JointJS+ |
| Grid | A grid | JointJS+ |
Each links to its core guide for the call and its options; the entry points are collected in the layout API reference. What is React-specific is when to call it, below.
Once elements are where you want them, Standalone Link Routing keeps the links clear of them.
How a layout runs in @joint/react
Whichever layout you pick, it needs each node's size to place it without overlaps. How you supply that size decides when you can run the layout.
By default a @joint/react node measures itself: HTMLHost and HTMLBox size the element from its rendered content, so its dimensions only exist after it renders. Run a layout any sooner and you arrange zero-sized boxes, stacked at the origin. useOnElementsMeasured waits for the right moment: it fires on the first pass, once the paper has measured the elements, and again on any later size change. Read the graph with useGraph, then run your layout from the callback, guarding on isInitial so it runs the one time the sizes first appear. Here it is with directed graph:
import { useGraph, useOnElementsMeasured } from '@joint/react';
import { DirectedGraph } from '@joint/layout-directed-graph';
function Layout() {
const { graph } = useGraph();
useOnElementsMeasured(({ isInitial }) => {
if (isInitial) {
DirectedGraph.layout(graph, { rankDir: 'TB' });
}
});
return null;
}
A layout reads the elements and links already on the graph and writes a position onto each element. Because those are the same models @joint/react renders, the diagram re-flows on its own with nothing to wire up. Call it from a component inside your <GraphProvider>, and call it again from an event handler to re-flow later, which is how the Directed Graph demo responds when you flip the direction.
useOnElementsMeasured is the right trigger whether your nodes measure themselves or carry explicit sizes. With explicit sizes (a fixed size on the cell, rendered as plain SVG or with <HTMLHost useModelGeometry>) it simply fires as soon as the graph is populated, so you don't change anything. See Reacting after measurement for more on the hook: its { isInitial, paper, graph } payload, targeting a specific paper, and reacting to later size changes.