Skip to content
D
Documentation

Lay out diagrams automatically

how-to
2 min readUpdated

Use automatic layout when you have a populated graph and want Grafloria to place its nodes instead of positioning them by hand. Each example lays out a small tree whose nodes start at the origin.

Arrange a tree when the canvas mounts

Choose a layout algorithm for your populated graph. In plain JavaScript, pass node and edge specs to render(), then call the mounted instance's engine layout method. In Angular, React, and Vue, pass the specs and layout request to the rendered component. In Qwik, mount and lay out the canvas in a browser-only visible task. Each canvas starts with nodes stacked at (0, 0); the selected layout arranges the nodes into a tree.

For plain JavaScript, render mounts the specs into an element and returns a live DiagramInstance. The sample calls the engine through that mounted instance.

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

const ids = ['root', 'a', 'b', 'a1', 'a2', 'b1', 'b2'];
const nodes = ids.map((id) => ({
  id,
  position: { x: 0, y: 0 },
  size: { width: 120, height: 48 },
  label: id,
}));
const edges = [
  { id: 'e1', source: 'root', target: 'a' },
  { id: 'e2', source: 'root', target: 'b' },
  { id: 'e3', source: 'a', target: 'a1' },
  { id: 'e4', source: 'a', target: 'a2' },
  { id: 'e5', source: 'b', target: 'b1' },
];

const container = document.createElement('div');
container.style.height = '520px';
document.body.append(container);

async function showTree() {
  const instance = render({ nodes, edges }, container);
  const engine = instance.getEngine();
  await engine.layout('dagre', {
    nodeSpacing: 40,
    rankSpacing: 80,
  });
  instance.renderNow();
  instance.fitView(40);
}

void showTree();

The Angular, React, and Vue samples reuse EdgeSpec and the mounting patterns from Execute and compute flows, adding a layout request to DiagramCanvasComponent and GrafloriaFlow / GrafloriaFlow to arrange the nodes automatically.

ts
import { Component } from '@angular/core';
import { DiagramCanvasComponent } from '@grafloria/angular';
import type { EdgeSpec, NodeSpec } from '@grafloria/renderer';

const ids = ['root', 'a', 'b', 'a1', 'a2', 'b1', 'b2'];

@Component({
  standalone: true,
  imports: [DiagramCanvasComponent],
  template: `
    <grafloria-diagram-canvas
      [(nodes)]="nodes"
      [(edges)]="edges"
      [layout]="'dagre'"
      style="display:block; height:520px" />
  `,
})
export class DagreTreeComponent {
  nodes: NodeSpec[] = ids.map((id) => ({
    id,
    position: { x: 0, y: 0 },
    size: { width: 120, height: 48 },
    label: id,
  }));
  edges: EdgeSpec[] = [
    { id: 'e1', source: 'root', target: 'a' },
    { id: 'e2', source: 'root', target: 'b' },
    { id: 'e3', source: 'a', target: 'a1' },
    { id: 'e4', source: 'a', target: 'a2' },
    { id: 'e5', source: 'b', target: 'b1' },
  ];
}

What you see

The nodes no longer overlap at their shared starting point: Dagre positions the tree, including the disconnected b2 node, and the canvas shows the arranged graph.

Try the Dagre tree demo and its source to see the same graph laid out live.

Choose a layout

The registry names documented for whole-diagram layout are auto, architecture, elk, dagre, layered, tree, grid, circular, radial, force, spectral, and community. Use auto when you want Grafloria to classify the graph and select an algorithm. For a pipeline or DAG, choose elk, layered, or dagre; for a hierarchy, choose tree; for networks and clusters, consider force, community, or spectral; and for a catalog, use grid, circular, or radial.

OptionTypeDefaultWhat it does
layoutstring or object requestNot setSelects the algorithm on the component. An object request can include the algorithm's options.
namestring—Names the algorithm in an object layout request.
nodeSpacingnumberAlgorithm defaultSets space between nodes in the same rank or row.
rankSpacingnumberAlgorithm defaultSets space between ranks or layers.

The engine also accepts the selected algorithm directly. Call layout() through the mounted instance and await it; the engine commits the new node positions to the diagram. The JavaScript sample calls the DiagramEngine through the instance.

Re-run layout on demand

The component layout binding runs when its value changes, not when node data changes. This keeps a data update caused by dragging from starting a layout that would fight the user's gesture. When you need an explicit rerun, call instance.getEngine().layout('dagre', options) through the mounted instance, or use applyLayout() on the Angular or Vue component. applyLayout() reruns the bound request or accepts a registry layout request.

Was this page helpful?

Lay out diagrams automatically — Grafloria · GPT-6 Luna