Skip to content
D
Documentation

Auto-layout a diagram

how-to
3 min readUpdated

Use a layout algorithm when node positions come from the graph rather than from hand-authored coordinates. This page mounts the same pipeline in JavaScript, Angular, Qwik, React, and Vue, runs a named layout, and fits the result into the canvas.

When to use it

Use auto-layout for pipelines, trees, networks, and other graphs whose geometry should follow their nodes and edges. The model remains the source of truth; the engine calculates positions and writes them back to the live diagram.

The layout entry point is DiagramEngine. Use a named algorithm when you want a predictable choice, or omit the name to let auto classify the graph. The registered names include auto, elk, dagre, layered, tree, grid, circular, radial, force, spectral, and community.

Prerequisites

Install the package for your binding and its rendering dependencies. The examples below use the current published versions: @grafloria/engine 0.3.18, @grafloria/renderer 0.4.19, @grafloria/angular 0.13.7, and @grafloria/qwik, @grafloria/react, or @grafloria/vue 0.10.6.

bash
npm install @grafloria/engine @grafloria/renderer

Install the binding package as well when you use Angular, Qwik, React, or Vue.

1. Define a graph and run a layout

Give every node a size and an initial position. Starting the nodes at (0, 0) makes the result visible: the selected algorithm must separate them. Pass the graph to the binding, obtain the DiagramInstance when the canvas is ready, then call getEngine().layout() and fitView().

js
import { render } from '@grafloria/element';

const nodes = [
  { id: 'ingest', position: { x: 0, y: 0 }, size: { width: 130, height: 52 }, label: 'Ingest' },
  { id: 'parse', position: { x: 0, y: 0 }, size: { width: 130, height: 52 }, label: 'Parse' },
  { id: 'validate', position: { x: 0, y: 0 }, size: { width: 130, height: 52 }, label: 'Validate' },
  { id: 'publish', position: { x: 0, y: 0 }, size: { width: 130, height: 52 }, label: 'Publish' },
];
const edges = [
  { id: 'e1', source: 'ingest', target: 'parse' },
  { id: 'e2', source: 'parse', target: 'validate' },
  { id: 'e3', source: 'validate', target: 'publish' },
];

const container = document.getElementById('diagram');
if (!container) throw new Error('Missing #diagram');
container.style.height = '400px';

const instance = render({ nodes, edges }, container);
const engine = instance.getEngine();
async function arrange() {
  await engine.layout('dagre', { nodeSpacing: 40, rankSpacing: 90 });
  instance.renderNow();
  instance.fitView(50);
}
arrange();
The JavaScript canvas shows the four pipeline nodes separated and fitted within the container.
The Angular canvas shows the four pipeline nodes separated and fitted within the container.
The Qwik canvas shows the four pipeline nodes separated and fitted within the container.
The React canvas shows the four pipeline nodes separated and fitted within the container.
The Vue canvas shows the four pipeline nodes separated and fitted within the container.

Each version renders the four-node pipeline with 40 units between neighboring nodes and 90 units between ranks. renderNow() repaints immediately after the engine changes positions; fitView(50) frames the complete graph with padding.

2. Let Grafloria choose

Use auto when the graph shape matters more than a fixed algorithm. The JavaScript form is an omitted name; the component bindings accept the string value.

js
async function fitAutomaticLayout(instance) {
  await instance.getEngine().layout();
  instance.renderNow();
  instance.fitView(50);
}

An unknown layout name throws an error listing the registered names. Use a registered name when your interface lets the reader choose an algorithm.

Options that matter

optiontypedefaultwhat it does
nodeSpacingnumberalgorithm-specificSets spacing between neighboring nodes.
rankSpacingnumberalgorithm-specificSets spacing between ranks.
seednumberfixed layout seedMakes a layout with the same graph reproducible.
nestedbooleanenabled when the diagram has groupsControls nested-container layout; set false to opt out.

The same options object goes to engine.layout(name, options). The engine returns a layout result after it commits positions; the result includes the selected algorithm, seed, node positions, and bounds.

Pitfall: ports are hidden by default

Ports are hidden until hover. If the layout is part of a persistent editing surface and readers need to see connection points, set portVisibility: 'always' when creating the diagram or update the live engine:

js
function showPorts(instance) {
  instance.getEngine().setInteractionConfig({ portVisibility: 'always' });
}

See it running

Open the auto-layout demo to switch between algorithms on a graph whose nodes begin stacked at the origin. The demo also checks that the layout commits positions, avoids overlaps, and produces different pictures for different engines.

The pipeline nodes are spread across the canvas and the selected layout result is visible.

For a graph with disconnected components, see the layout portfolio demo. For incremental changes that preserve the user's mental map, see layout and routing.

Was this page helpful?