Learn / The DiagramInstance
The DiagramInstance
Everything hands you the same object: render() returns it, React/Vue give it via onInit/@init, the element exposes it as el.diagram. This page is its map.
Orientation: three layers down
const api = render(spec, host); // DiagramInstance — the renderer-level facade api.getModel(); // DiagramModel — the data (nodes, links, groups) api.getEngine(); // DiagramEngine — behavior (commands, layout, validation)
Rule of thumb: pixels and specs → instance; data queries → model; behavior → engine. If a method is missing on the instance, it lives one layer down.
The surface, grouped
| Area | Members |
|---|---|
| Model in/out | setNodes(specs), setEdges(specs) — reconcile specs into the live diagram; getModel() |
| Events | on(event, handler) → unsubscribe fn, off(event, handler) — see Events & interaction |
| Camera | viewport (controller), fitView(padding?) |
| Painting | render() — queued, coalesced; renderNow() — synchronous |
| Batching | batchUpdate((model) => { ... }) — many mutations, one repaint |
| Export | export(format?, options?) async; exportSvgString(), exportPdf() sync — see Export |
| Text | exportText(), loadText(text) — Mermaid round-trip, reconciled into the live canvas |
| Appearance | setTheme(theme) |
| Interaction | interaction (controller); config via getEngine().setInteractionConfig(...) |
| Lifecycle | dispose(); container — the host element |
The reconciler — and its one gotcha
setNodes/setEdges and loadText do not
rebuild the diagram; they reconcile — existing ids keep their live objects
(selection, listeners, plugins all survive), new ids are created, missing ids are
removed. The gotcha: an id that still exists keeps its existing object, so
re-applying externally-edited data for the same ids needs a clear first:
// re-applying edited text/specs where ids persist: api.setEdges([]); api.setNodes([]); // clear, then apply — otherwise stale nodes survive api.setNodes(next.nodes); api.setEdges(next.edges);
What is deliberately NOT here
- undo()/redo() — history lives on the engine:
await api.getEngine().undo(). (⌘Z needs no wiring at all.) - layout() — also the engine:
await api.getEngine().layout('elk'), thenapi.renderNow(). - serialize() — the model:
api.getModel().serialize(); restore losslessly viafromDocument()from@grafloria/element.
If you prefer one flat object over three layers,
createDiagramApi(instance) from @grafloria/element wraps the
common cross-layer calls — including undo()/redo()/execute(command) —
into a single facade.Where next
- FAQ & troubleshooting — the ten minutes of debugging this page prevents.