JavaScript is required

HTML data, events, and API

Initial data

const data = {
  rootId: 'root',
  nodes: [
    {id: 'root', text: 'Root', x: 0, y: 0},
    {id: 'service', text: 'Service', data: {status: 'healthy'}}
  ],
  lines: [
    {id: 'root-service', from: 'root', to: 'service', text: 'calls'}
  ],
  fakeLines: []
};

const graph = await createRelationGraph('#graph', {data});

Nodes and lines should have stable, unique string id values. from and to reference node IDs; keep business fields under data. See Node data, Line data, and FakeLine.

Data API

await graph.setJsonData(data);
await graph.appendJsonData(moreData);

graph.addNode({id: 'new', text: 'New'});
graph.addNodes(nodeList);
graph.addLine({id: 'new-line', from: 'root', to: 'new'});
graph.addLines(lineList);

graph.updateNode('new', {text: 'Updated'});
graph.updateNodeData('new', {status: 'warning'});
graph.updateLine('new-line', {color: '#dc2626'});

graph.removeNodeById('new');
graph.removeLineById('new-line');
graph.clearGraph();

Query methods return read-only objects:

const node = graph.getNodeById('root');
const line = graph.getLineById('root-service');
const nodes = graph.getNodes();
const links = graph.getLinks();
const json = graph.getGraphJsonData();

Do not mutate query results. Use update/add/remove methods so indexes, layouts, MiniView, and rendering stay consistent.

Configuration events

Events that participate in default behavior or return-value decisions belong in config.events:

const graph = await createRelationGraph('#graph', {
  data,
  events: {
    onNodeClick(node, event) {
      console.log(node.id, event.type);
    },
    onLineClick(line, link, event) {
      console.log(line.id);
    },
    onNodeDragging(node, x, y) {
      return {
        x: Math.round(x / 10) * 10,
        y: Math.round(y / 10) * 10
      };
    },
    beforeZoomStart(zoom) {
      return zoom < 20 ? true : undefined;
    },
    beforeCreateLine({fromNode, toNode}) {
      return fromNode.id === toNode.id ? true : undefined;
    },
    onLineBeCreated({lineJson}) {
      graph.addLine(lineJson);
    }
  }
});

Return-value semantics include:

  • Return true from beforeZoomStart, beforeScrollStart, or beforeCreateLine to cancel.
  • Return false from beforeNodeResize to reject the current size application.
  • onNodeDragging and onCanvasDragging may return replacement coordinates.

See Events for the complete list.

DOM mirror events

The host dispatches read-only, bubbling rg:* CustomEvents:

const host = document.querySelector('#graph');

host.addEventListener('rg:node-click', event => {
  console.log(event.detail.node.id);
  console.log(event.detail.graph === graph);
});

host.addEventListener('rg:viewport-change', event => {
  console.log(event.detail.canvasZoom);
});

Common events include rg:ready, rg:node-click, rg:line-click, rg:canvas-click, rg:zoom-end, rg:view-resize, rg:viewport-change, rg:selection-change, and rg:destroy. Returning a value from a mirror event cannot cancel core behavior.

State subscriptions

const stopViewport = graph.subscribe('viewport', viewport => {
  console.log(viewport.canvasZoom, viewport.canvasOffset);
});

const stopSelection = graph.subscribe('selection', selection => {
  console.log(selection.checkedNodeId, selection.checkedLineId);
});

const stopEditing = graph.subscribe('editing', editingState => {
  console.log(editingState.nodes, editingState.line);
});

stopViewport();
stopSelection();
stopEditing();

Domains are options, viewport, selection, editing, and renderPlan.

View, layout, and export API

graph.moveToCenter();
graph.zoomToFit();
graph.setZoom(120);
graph.zoom(10);
graph.focusNodeById('root');
graph.doLayout();
graph.toggleAutoLayout();
await graph.getGraphImageBase64('png');

The instance also exposes selection, expansion, coordinate conversion, graph analysis, fullscreen, and image APIs. See the full RelationGraphInstance API.

Next: Renderers, layers, and plugins.