Learn / Layout

Layout

Hand-placing nodes stops scaling around fifteen of them. Grafloria puts eleven layout algorithms behind one registry and one call — and keeps the heavyweight (ELK) out of your bundle until the moment it is used.

One call

await engine.layout('elk');                                   // opinionated default
await engine.layout('dagre', { direction: 'TB', rankSpacing: 80 });
await engine.layout();                                        // 'auto' — picks for you

Registered names: auto, elk, dagre, layered, tree, grid, circular, radial, force, spectral, community. An unknown name throws with the list of registered ones — no silent no-op. auto inspects the graph (a tree? a DAG? a hairball?) and dispatches to the right algorithm.

Choosing

GraphReach forWhy
Flowcharts, pipelines, DAGselk or layered/dagre layered ranking, few crossings; ELK handles ports and nesting best
Hierarchies, org chartstreeparent-centered, tidy
Networks, clustersforce, community, spectral physical spread; community detection groups related nodes
Catalogs, galleriesgrid, circular, radialuniform placement
Don't want to thinkautoclassification + dispatch

The cost model — why ELK doesn't bloat you

ELK is the best layered engine available and also ~1.4 MB minified. Grafloria loads it through a lazy import() — a separate chunk (~432 KB gz) that downloads on the first layout('elk') call and never before. It also runs off-thread in a Worker, so a thousand-node layout doesn't freeze your UI. Everything else (dagre, tree, force, grid…) is small and ships eagerly.

Declarative, in every framework

// React
<GrafloriaFlow defaultNodes={nodes} defaultEdges={edges} layout="elk" />

// Angular
<grafloria-diagram-canvas [(nodes)]="nodes" [(edges)]="edges" [layout]="'elk'" />

// object form everywhere
layout={{ name: 'dagre', options: { direction: 'LR' } }}
The binding re-runs when its value changes — never when node data changes. That is deliberate: a user drag round-trips through the nodes binding, and a re-layout firing on every change would fight the user's hands. Re-run on demand with instance.getEngine().layout(...) (React/Vue) or applyLayout() (Angular).

Incremental layout

After inserting into an already-laid-out graph, a full re-layout scrambles the user's mental map. layoutIncremental moves only the neighborhood:

await engine.layoutIncremental({ changed: ['inserted-node-id'], direction: 'LR', radius: 1 });

Live: incremental layout on insert →

Where next