Skip to content
D
Documentation

Layout and routing

concept
2 min readUpdated
mermaid
flowchart LR
  S["Node and edge specs"] --> M["Diagram model"]
  M --> L["Layout algorithm"]
  L --> P["Node positions"]
  P --> R["Edge router"]
  M --> R
  R --> G["Routed edge geometry"]
  P --> V["Renderer"]
  G --> V

Layout arranges nodes

Use the mounted DiagramInstance to reach the engine that owns layout and to render the resulting positions.

The layout algorithm reads the graph's relationships, groups, and node sizes. It writes positions, not new relationships. Choose a layout according to the graph:

GraphAlgorithmResult
Flowcharts, pipelines, and DAGselk, layered, or dagreLayered ranking with fewer crossings; ELK also handles ports and nesting.
Architecture diagrams with zonesarchitectureRegions on a grid, sized boxes in rows, and bends in gutters.
Hierarchies and org chartstreeTidy, parent-centered placement.
Networks and clustersforce, community, or spectralPhysical spread or community-oriented placement.
Catalogs and galleriesgrid, circular, or radialUniform placement.
An unknown graph shapeautoGraph classification followed by algorithm selection.

Routing turns edge intent into geometry

See the JavaScript quick start for the complete EdgeSpec shape and how source and target identify the endpoints. This page adds the routing choice: set router to change the edge geometry without changing the relationship:

ts
import type { EdgeSpec } from '@grafloria/renderer';

const edges: EdgeSpec[] = [
  {
    id: 'request',
    source: 'client',
    target: 'service',
    router: 'avoid',
    label: 'request',
  },
];

router answers “which path does the line take?” The shipped routers provide these choices:

RouterPath behavior
straightDirect line between the endpoints.
orthogonalRight-angled path from the port's exit direction.
manhattanGrid-based right-angle routing with turn minimization.
avoidWalks around obstacles and re-routes as nodes move.
elkUses ELK edge routing for an ELK-laid-out graph.

Use waypoints or points when the route has explicit bends. Handles can name a port, a side such as 'right', or a position along a side such as 'right@36'. If you omit both handles, the edge uses the default port facing its partner as nodes move.

Declarative layout and explicit re-layout

Bindings can receive a layout value at mount time. The binding re-runs layout when that value changes, but not when node data changes. That prevents a user drag from being immediately overwritten by an automatic re-layout.

When relationship or node data changes after mount, call the engine's layout() explicitly and then render:

ts
import type { DiagramInstance } from '@grafloria/renderer';

export async function reflowAfterDataChange(instance: DiagramInstance): Promise<void> {
  await instance.getEngine().layout('elk');
  instance.renderNow();
}

For an already-laid-out graph, incremental layout moves only the neighborhood of inserted nodes instead of scrambling the whole mental map. Use the full layout when you want a new global arrangement; use incremental layout when preserving the existing arrangement matters.

Extend routing only when the shipped routers are insufficient

The engine exposes a RoutingEngine for extension. A custom IRouter supplies route() and getName(); register it with registerRouter(), then select its name through an edge's router value. A per-edge router choice is sufficient when one of the shipped algorithms provides the required geometry.

Pitfall: data changes do not re-run layout

Changing node data does not re-run the declarative layout value. Invoke the engine's layout() explicitly, then render. Automatic re-layout on every data change would fight user dragging.

Live examples

  • Layout demos compare architecture and layered layout on the same text.
  • Edge routing demo shows edge types, routers, and connectors on a mounted diagram.

See How Grafloria works, Apply auto-layout, and Route and edit edges for the surrounding model, layout procedure, and edge-editing workflows.

Was this page helpful?

Layout and routing — Grafloria · GPT-5.6 Luna