Skip to content
D
Documentation

Handle connection interactions

how-to
2 min readUpdated

Observe a connection drag from start through completion or cancellation, and let users create links by dragging from a node body to another node.

Use body-to-body connection when users should not have to aim at a small port. The built-in mode starts from the nearest port on the first node and completes at the nearest port on the second. With the mode off, the usual interaction is port-to-port dragging, and dragging a node body moves the node.

Mount the diagram and listen to its connection lifecycle

These examples mount two typed nodes and an empty edge list, then enable body-to-body connection and write each lifecycle event to a visible log. Drag anywhere on the source node to the target node and release to create a link; the log records the gesture as it happens. Drag off the target or press Escape to cancel instead.

For the JavaScript, Angular, and Vue mounting patterns and access to the live canvas, see Build runnable workflows. This page adds body-to-body connection and a log of its lifecycle events. The diagram data uses NodeSpec and EdgeSpec.

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

const log = document.createElement('pre');
log.style.height = '88px';
log.style.overflow = 'auto';
log.textContent = 'Drag from source to target to see the connection lifecycle.';
const canvas = document.createElement('div');
canvas.style.width = '700px';
canvas.style.height = '420px';
document.body.append(log, canvas);

/** @type {import('@grafloria/element').NodeSpec[]} */
const nodes = [
  {
    id: 'src',
    position: { x: 80, y: 70 },
    size: { width: 150, height: 60 },
    label: 'source',
    ports: [{ id: 'src.out', side: 'right', type: 'output' }],
  },
  {
    id: 'dst',
    position: { x: 430, y: 70 },
    size: { width: 150, height: 60 },
    label: 'target',
    ports: [{ id: 'dst.in', side: 'left', type: 'input' }],
  },
];
/** @type {import('@grafloria/element').EdgeSpec[]} */
const edges = [];
const instance = render({ nodes, edges }, canvas);
const engine = instance.getEngine();
engine.setInteractionConfig({ enableEasyConnect: true });

const connectionEvents = [
  'connection:start',
  'connection:update',
  'connection:port-enter',
  'connection:port-leave',
  'connection:complete',
  'connection:cancel',
];
for (const name of connectionEvents) {
  engine.eventBus.on(name, () => {
    if (log.textContent?.startsWith('Drag from')) log.textContent = '';
    log.prepend(`${name}\n`);
  });
}

The log names the six engine events. connection:start carries the source port and valid target ports; connection:update reports the current target and whether it is valid, including a rejection reason; connection:port-enter and connection:port-leave mark target-port crossings; connection:complete identifies the connected ports; and connection:cancel marks an abandoned or refused drag. update can fire repeatedly while the pointer moves. A successful drop ends with complete; a refused drop or Escape ends with cancel.

Open the live connection-events demo or read its source.

Choose the connection gesture

OptionTypeDefaultWhat it does
enableEasyConnectbooleanfalseStarts a connection from the nearest port when the user presses a node body, instead of moving the node.

JavaScript and Vue turn on enableEasyConnect after mount with instance.getEngine().setInteractionConfig(...). Angular accesses its engine through activeEngine() and calls setInteractionConfig(...) there. Leave the option off to keep body-drag-to-move and start connections from ports instead. With it on, press anywhere on the source node and release on the target node; the built-in interaction creates the link without a custom tool.

Open the live easy-connect-body demo or read its source.

Watch for

  • Keep the event subscriptions for the lifetime of the mounted canvas and call each returned disposer when the host unmounts. Otherwise, repeated mounts can leave old listeners recording the same gesture.
  • enableEasyConnect changes what a node-body press does: it starts a connection rather than moving that node. Leave the option disabled when users need body dragging to move nodes.
  • This example logs event names. Read the event payload when the host needs port details or a validation reason.

Was this page helpful?

Handle connection interactions — Grafloria · GPT-6 Luna