DEV Community

Ramy Othman
Ramy Othman

Posted on Originally published at grafloria.com

Auto-layout you don't have to build

Originally published on the Grafloria engineering blog.

There's a special kind of feature request: the one filed as issue #5 of a project and still generating tutorials years later. For flow libraries that's auto-layout. The mainstream answer became "integrate dagre or elk yourself", and an entire genre of blog posts exists to walk you through the wiring — graph conversion in, position mapping out, edge cases yours forever. (The sequel, "is dynamic auto layouting possible?", has 28 comments of people discovering the hard parts.)

What the wiring tutorials don't tell you

Getting dagre to emit positions is the easy afternoon. The parts that eat the week:

  • Which algorithm, when? Layered algorithms are right for DAGs and wrong
    for hairballs; trees want tree layouts; a picker is part of the feature.

  • ELK is 1.4 MB. The best layered engine is also the heaviest — ship it
    eagerly and your bundle audit will find it.

  • The second layout. Insert a node into a laid-out graph and a full re-run
    scrambles every position the user has memorized. You need incremental layout, and no wiring tutorial covers it.

  • Don't fight the hands. If layout re-runs on every data change, it undoes
    the drag your user just made. When it runs is as important as what it computes.

One call, and the four problems it absorbs

await engine.layout('elk');                                    // picker: 'auto' inspects the graph
await engine.layout('dagre', { direction: 'TB', rankSpacing: 80 });
await engine.layoutIncremental({ changed: ['inserted-id'], radius: 1 });  // the second layout
Enter fullscreen mode Exit fullscreen mode

Registered names: auto, elk, dagre,
layered, tree, grid, circular,
radial, force, spectral, community.
ELK loads as a lazy chunk on first use — it costs your bundle nothing until someone actually invokes it — and runs off-thread in a Worker. And in every framework binding, the declarative form re-runs on prop-value change only, never on node data, so it structurally cannot fight a user's drag:

// React

// Angular

// Vue

Enter fullscreen mode Exit fullscreen mode

See every algorithm on a real graph: layout demos · the concept guide (including the choosing table): Layout.


Grafloria is an MIT-licensed diagram engine for React, Angular, Vue and plain JavaScript — grafloria.com. If this post was useful, the demo gallery is where the ideas live as running code.

Top comments (0)