Skip to content
D
Documentation

Validate connections

how-to
2 min readUpdated

Validate connections during a drag

Use a connection validator when your graph has rules that port direction alone does not express. The validator runs before the link is created: return true to allow the candidate, or return a string to veto it with a reason. In this example, an output may connect to an input, but never to another output.

Install

JavaScript uses the element, renderer, and engine packages:

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

Install the binding package as well when you use Angular, Qwik, React, or Vue.

The render function mounts the graph and returns its live DiagramInstance. Use the clearConnectionValidators function before replacing a process-wide rule.

Register the rule

The connection validator receives the candidate's source and target ports. Keep the returned disposer and remove the process-wide registration when the view unmounts.

The following rule allows an incomplete candidate, then rejects output-to-output connections with a readable reason:

ts
import { registerConnectionValidator } from '@grafloria/renderer';

const disposeValidator = registerConnectionValidator(({ sourcePort, targetPort }) => {
  if (!sourcePort || !targetPort) return true;
  if (sourcePort.type === 'output' && targetPort.type === 'output') {
    return 'an output cannot feed another output';
  }
  return true;
});

The disposer belongs in your component's unmount or effect cleanup, not immediately after setup. Registered validators are process-global, so leaving one active can change the rules on another canvas.

Mount a graph

Give the host a resolved height. Hover over a node to reveal its ports, then drag A (out) to C (out): the wire disappears and no edge is created. Drag it to B (in): the connection remains on the canvas.

The Qwik binding uses GrafloriaFlow, and its onInit$ callback receives the shared DiagramInstance. The other bindings expose the same instance through their own init callback.

js
import { render } from '@grafloria/element';
import { registerConnectionValidator, clearConnectionValidators } from '@grafloria/renderer';

const nodes = [
  {
    id: 'a', position: { x: 120, y: 260 }, size: { width: 120, height: 70 }, label: 'A (out)',
    ports: [{ id: 'ao', side: 'right', type: 'output' }],
  },
  {
    id: 'b', position: { x: 640, y: 140 }, size: { width: 120, height: 70 }, label: 'B (in)',
    ports: [{ id: 'bi', side: 'left', type: 'input' }],
  },
  {
    id: 'c', position: { x: 640, y: 400 }, size: { width: 120, height: 70 }, label: 'C (out)',
    ports: [{ id: 'co', side: 'left', type: 'output' }],
  },
];

const host = document.createElement('div');
host.id = 'canvas';
document.body.append(host);
host.style.height = '100vh';

const disposeValidator = registerConnectionValidator(({ sourcePort, targetPort }) => {
  if (!sourcePort || !targetPort) return true;
  if (sourcePort.type === 'output' && targetPort.type === 'output') {
    return 'an output cannot feed another output';
  }
  return true;
});

const instance = render({ nodes, edges: [] }, host);
instance.renderNow();

window.addEventListener('pagehide', () => {
  disposeValidator();
  clearConnectionValidators();
  instance.dispose();
}, { once: true });

Each binding mounts the same model and registers the same rule. During a drag, a rejected drop leaves the model unchanged; an allowed drop adds the link to the mounted diagram. Press Escape during a drag to cancel the attempt.

Options that affect the interaction

OptionTypeDefaultWhat it does
interaction.portVisibility'hover' | 'always''hover'Keeps ports visible during the example when set to 'always'.
ports[].type'input' | 'output' | 'bi'—Controls which direction a port accepts during wiring.

Pitfalls

  • Validators are process-global. Dispose the returned function and call clearConnectionValidators() when the view unmounts; see ports and validation for the warning.
  • Give the canvas host a real height, or the mounted diagram appears blank. See style a diagram.
  • Every registered validator must allow the candidate. Validators have veto power, not voting power.

Live demo

Try the connection-validation demo. It rejects output-to-output and accepts output-to-input during real drags.

Was this page helpful?