Skip to content
D
Documentation

JavaScript quick start

tutorial
3 min readUpdated

Mount a working flow diagram in plain JavaScript, connect two nodes, and keep the live instance for later operations.

Grafloria uses one headless model behind its framework bindings. In plain JavaScript, call the render function with diagram data and a sized host element, then use the returned DiagramInstance for the live canvas.

Prerequisites

  • A browser with ES modules and a JavaScript project with npm.
  • @grafloria/element 0.4.83, @grafloria/renderer 0.4.19, and @grafloria/engine 0.3.18.

1. Install the packages

bash
npm install @grafloria/element @grafloria/renderer @grafloria/engine

The element package supplies the plain-JavaScript render() entry point. The renderer and engine packages satisfy its peer dependencies.

2. Give the diagram a real host

Create a host with explicit width and height. The renderer needs the host's resolved height to paint the canvas.

html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Grafloria flow</title>
    <style>
      #canvas {
        width: 800px;
        height: 400px;
      }
    </style>
  </head>
  <body>
    <div id="canvas"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

3. Mount and connect the nodes

Import render(), describe two NodeSpec values with positions and sizes, and connect them with an EdgeSpec. The source and target values refer to node ids.

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

const canvas = document.getElementById('canvas');

if (!(canvas instanceof HTMLElement)) {
  throw new Error('The #canvas host is missing.');
}

canvas.style.width = '800px';
canvas.style.height = '400px';

const instance = render(
  {
    nodes: [
      {
        id: 'a',
        position: { x: 60, y: 80 },
        size: { width: 180, height: 80 },
        label: 'Ingest',
      },
      {
        id: 'b',
        position: { x: 380, y: 80 },
        size: { width: 180, height: 80 },
        label: 'Publish',
      },
    ],
    edges: [{ id: 'e1', source: 'a', target: 'b' }],
  },
  canvas,
);

instance.fitView();
The 800 × 400 canvas shows the Ingest and Publish boxes joined by an edge.

The call mounts the editor into canvas and returns the live DiagramInstance. The browser shows two labelled boxes joined by an edge; you can drag nodes, draw connections, pan, and zoom. fitView() frames all content in the host.

The spec argument is data, not Mermaid text. Use the text import/export APIs on the instance when you need Mermaid-compatible text; see Edit Mermaid diagrams.

Or use the web component

The GrafloriaFlowElement custom element provides the same diagram surface without calling render() directly. Give it a resolved height, assign its node and edge properties, and read its diagram property after it connects.

html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Grafloria element</title>
    <style>
      grafloria-flow {
        display: block;
        width: 800px;
        height: 400px;
      }
    </style>
  </head>
  <body>
    <grafloria-flow id="flow"></grafloria-flow>
    <script type="module">
      import { GrafloriaFlowElement } from '@grafloria/element';

      const flow = document.getElementById('flow');

      if (!(flow instanceof GrafloriaFlowElement)) {
        throw new Error('The #flow element is missing.');
      }

      flow.nodes = [
        { id: 'a', position: { x: 60, y: 80 }, label: 'Ingest' },
        { id: 'b', position: { x: 380, y: 80 }, label: 'Publish' },
      ];
      flow.edges = [{ id: 'e1', source: 'a', target: 'b' }];

      const elementInstance = flow.diagram;

      if (elementInstance === null) {
        throw new Error('The diagram has not connected yet.');
      }

      elementInstance.fitView();
    </script>
  </body>
</html>
The custom element renders the same two connected boxes in its 800 × 400 host.

The browser shows the same two connected boxes. flow.diagram is the live DiagramInstance once the element is connected.

4. Use the live instance

Keep instance in the scope that owns the diagram. For example, replace the current connections through the instance after the canvas has mounted:

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

const canvas = document.getElementById('canvas');

if (!(canvas instanceof HTMLElement)) {
  throw new Error('The #canvas host is missing.');
}

canvas.style.width = '800px';
canvas.style.height = '400px';

const instance = render(
  {
    nodes: [
      { id: 'a', position: { x: 60, y: 80 }, label: 'Ingest' },
      { id: 'b', position: { x: 380, y: 80 }, label: 'Publish' },
    ],
    edges: [{ id: 'e1', source: 'a', target: 'b' }],
  },
  canvas,
);

instance.setEdges([
  { id: 'e1', source: 'a', target: 'b', label: 'published' },
]);

instance.renderNow();
The live instance updates the edge so it displays the published label.

setEdges() reconciles the live edge data, and renderNow() repaints synchronously. The visible connection now carries the published label.

Pitfall: reconciling the same ids

setNodes() and loadText() reconcile by id. Persistent ids retain live objects and stale state. When you reapply externally edited data with the same ids, clear the current edges and nodes first, then load the replacement data:

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

const canvas = document.getElementById('canvas');

if (!(canvas instanceof HTMLElement)) {
  throw new Error('The #canvas host is missing.');
}

canvas.style.width = '800px';
canvas.style.height = '400px';

const instance = render(
  {
    nodes: [
      {
        id: 'a',
        position: { x: 60, y: 80 },
        size: { width: 180, height: 80 },
        label: 'Ingest',
      },
    ],
    edges: [],
  },
  canvas,
);

instance.setEdges([]);
instance.setNodes([]);

instance.setNodes([
  {
    id: 'a',
    position: { x: 60, y: 80 },
    size: { width: 180, height: 80 },
    label: 'Revised ingest',
  },
]);
instance.setEdges([]);
instance.renderNow();
The canvas shows the revised ingest node after the current diagram data is cleared and replaced.

For the host sizing rule and Mermaid round trips, continue to Edit Mermaid diagrams. For the instance lifecycle and deeper model access, read Instance and lifecycle.

What you have at the end

You have a 800 × 400 host containing a connected, interactive diagram. instance is the live handle returned by render(), so later code can update nodes or edges, subscribe to events, fit the view, render immediately, and dispose the diagram during application teardown.

Where next

Was this page helpful?