Disconnected Multi-Group Force Relayout
A full-height viewer that loads several disconnected relationship groups and isolated nodes into one canvas, centers the overview, and then switches the same graph to a force layout after a short delay. It is a focused reference for staged first-frame presentation plus post-load separation of fragmented clusters with minimal styling and no custom control panel.
Disconnected Relationship Groups With a Delayed Force Relayout
What This Example Builds
This example builds a single full-height graph canvas that displays several disconnected relationship islands and two standalone nodes at the same time. The first frame is presented as a centered overview, then the same loaded graph is handed to a force layout half a second later so the islands spread apart without rebuilding the dataset.
The visible result stays deliberately plain: black node borders, black lines, path-following link labels, and the built-in toolbar placed at the lower-right corner. There are no custom panels, buttons, or editing tools. The main lesson is how to stage a predictable first view and then relax a fragmented graph into a more separated layout.
How the Data Is Organized
The data is a single module-scope RGJsonData object with rootId, a flat nodes array, and a flat lines array. That one payload contains multiple disconnected components rather than one continuous tree. It includes a group centered on node 2, another group around node 6, another around node 10, and two isolated nodes named Single 1 and Single 2.
There is no preprocessing before the graph is loaded. initializeGraph() passes myJsonData directly to setJsonData(), so the example’s behavior comes from runtime layout changes instead of data transformation. In real applications, the same structure could represent subsystem catalogs, asset inventories, product-module maps, or any other overview where unrelated clusters still need to share one canvas.
How relation-graph Is Used
The entry component wraps the demo in RGProvider, and MyGraph gets the live instance through RGHooks.useGraphInstance(). That hook drives the full lifecycle: loading the dataset, moving the viewport to the center, fitting the current content, updating layout options, and triggering a second layout pass.
The initial RelationGraph options use layoutName: 'center' with distanceCoefficient: 0.5. The same options object also enables on-path line labels, keeps node borders and lines black, and places the built-in toolbar horizontally at the bottom right. After the initial load, the code calls updateOptions() to switch only the layout section to force, with explicit repulsion, elasticity, and maxLayoutTimes: Number.MAX_SAFE_INTEGER, then calls doLayout().
The component does not add custom slots, custom node rendering, or event handlers. Styling stays close to the built-in appearance. The only concrete SCSS override changes checked line labels to white, while the rest of the nested selectors are empty placeholders. The graph area itself is just a wrapper div with height: '100vh'.
Key Interactions
The first interaction is automatic rather than user-driven. When the component mounts, it loads the graph data, recenters the viewport, and zooms to fit the whole scene.
The second interaction is also automatic. After a 500 millisecond delay, the graph switches from the initial center layout to a force layout and runs another layout pass on the same instance.
The only visible manual controls come from relation-graph’s built-in toolbar. The example configures where that toolbar appears, but it does not add custom click handlers, editing actions, or a separate control surface.
Key Code Fragments
This fragment shows that the dataset is declared inline and already includes isolated nodes inside the same payload.
const myJsonData: RGJsonData = {
rootId: '2',
nodes: [
{ id: '2', text: 'ALTXX' },
{ id: '3', text: 'CH2 TTN' },
{ id: 'single-1', text: 'Single 1' },
{ id: 'single-2', text: 'Single 2' },
{ id: '4', text: 'CH1 AlCu' },
{ id: '5', text: 'MainFrame' },
This fragment shows the monochrome defaults, path-following labels, toolbar placement, and the initial centered layout.
const graphOptions: RGOptions = {
defaultNodeBorderColor: '#000000',
toolBarDirection: 'h',
toolBarPositionH: 'right',
toolBarPositionV: 'bottom',
defaultLineTextOnPath: true,
defaultLineColor: '#000000',
layout: {
layoutName: 'center',
distanceCoefficient: 0.5
}
};
This fragment shows the mount-time initialization sequence that loads data and fits the first view.
const initializeGraph = async () => {
await graphInstance.setJsonData(myJsonData);
graphInstance.moveToCenter();
graphInstance.zoomToFit();
// ...delayed relayout follows...
};
This fragment shows the delayed handoff from center to force on the already loaded graph instance.
setTimeout(() => {
graphInstance.updateOptions({
layout: {
layoutName: 'force',
force_node_repulsion: 0.3,
force_line_elastic: 5,
maxLayoutTimes: Number.MAX_SAFE_INTEGER
}
});
graphInstance.doLayout();
}, 500);
This fragment shows the only concrete style override in the local stylesheet.
.rg-line-peel.rg-line-checked {
.rg-line-label {
color: #fff;
}
}
What Makes This Example Distinct
The comparison data shows that the distinctive part is not disconnected data alone. Compared with multi-group, this example adds a timed post-load separation step instead of stopping after the initial centered overview. Compared with multi-group-2, it emphasizes live layout transition and organic spacing rather than tree readability, curved routing, or junction tuning for the same fragmented dataset family.
It is also narrower than the other runtime-layout neighbors. Compared with switch-layout and force-sea-anemone, this example performs one delayed handoff to force layout, not a repeating layout carousel and not an ambient force animation. The rare combination is a multi-island dataset, truly isolated nodes, a monochrome technical style, on-path labels, bottom-right toolbar placement, and a delayed relayout on the same live graph instance. That makes it a strong starting point when the requirement is “show all disconnected groups first, then let them separate further” without adding custom controls.
Where Else This Pattern Applies
This pattern transfers well to subsystem overviews, mixed asset catalogs, portfolio maps, product-family diagrams, and knowledge-map previews where the data is fragmented but still benefits from one shared canvas. A production version could keep the same initialization sequence while replacing the inline sample with API data, adjusting the force coefficients per dataset size, or turning the delayed relayout into a conditional step after filters or data refreshes.
The reusable idea is the staging strategy: load one disconnected dataset, frame it predictably for the first view, and then re-spread it with a runtime layout change instead of rebuilding the graph from scratch.