Skip to content
D
Documentation

Add nodes from palettes

how-to
2 min readUpdated

Build a small palette beside a mounted diagram; choosing a shape adds a labelled node to the live model in the next available grid position.

Use this pattern when your app owns a short list of node types and wants readers to add them without editing diagram data directly. The framework bindings mount a canvas; its instance reaches the engine, which adds each selected node to the diagram.

Build a palette

Start with an empty diagram. In JavaScript, React and Vue, keep the live DiagramInstance from the component's init callback and call getEngine().addNode() from each palette button. Angular gets its active engine from the canvas component when a button is clicked; Qwik updates controlled node data. The engine returns a promise for the node it adds; each sample places new nodes in a grid so their labels stay visible beside previous choices.

Unlike a workflow that starts from a fixed graph, each palette choice adds one labelled rect at the next grid position; see Build runnable workflows for the framework-specific mounting patterns.

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

const root = document.createElement('div');
root.style.cssText = 'display:grid;grid-template-columns:160px 1fr;height:420px';
document.body.append(root);

const palette = document.createElement('div');
palette.style.cssText = 'display:flex;flex-direction:column;gap:8px;padding:12px';
const canvas = document.createElement('div');
canvas.style.height = '420px';
root.append(palette, canvas);

const instance = render({ nodes: [], edges: [] }, canvas);
const kinds = ['Source', 'Filter', 'Sink'];

async function addNode(kind) {
  const count = instance.getModel().getNodes().length;
  await instance.getEngine().addNode({
    type: 'rect',
    position: { x: 40 + (count % 4) * 170, y: 40 + Math.floor(count / 4) * 90 },
    size: { width: 140, height: 64 },
    data: { label: kind },
  });
  instance.renderNow();
}

for (const kind of kinds) {
  const button = document.createElement('button');
  button.textContent = kind;
  button.addEventListener('click', () => { void addNode(kind); });
  palette.append(button);
}

Click a palette button to add a labelled rect node. JavaScript, React and Vue call addNode() on the mounted instance; Angular calls addNode() on its active engine, and Qwik updates its controlled node array. Each addition occupies the next grid position.

Options that matter

OptionTypeDefaultWhat it does
defaultNodesNodeSpec[]Not specifiedSeeds the diagram once; the JavaScript, React and Vue samples pass an empty array. Angular and Qwik pass empty controlled node arrays.
defaultEdgesEdgeSpec[]Not specifiedSeeds the diagram's edges; the samples pass an empty array.
onInit / onInit$(instance: DiagramInstance) => voidNot specifiedGives the mounted instance to the JavaScript, React and Vue palette code. Angular reads the active engine from its canvas component; Qwik uses controlled node data.
addNode config typestringRequiredSelects the node type; the sample uses rect.
addNode config positionPointRequiredSets the node's top-left position in diagram coordinates.
addNode config sizeSizeOptionalSets the node's width and height.
addNode config dataanyOptionalCarries node data; data.label supplies the visible label in these samples.

Pitfalls

  • If you later replace externally edited node data with setNodes() or loadText(), those calls reconcile rather than rebuild: ids that remain keep their live objects. Clear the current edges and nodes first, then apply the edited data. See Edit and copy nodes for node-data workflows.
  • This palette uses the built-in rect node and a data label. For custom-rendered nodes, follow Create custom nodes.

See it running

The Drag & drop demo shows a drag-and-drop palette whose nodes land at the drop point. For categorized, searchable built-in shapes, see the Stencil palette demo.

Was this page helpful?

Add nodes from palettes — Grafloria · GPT-6 Luna