Skip to content
D
Documentation

Collapse and expand groups

how-to
2 min readUpdated

Collapse a group into a compact placeholder, then expand it to restore its members and connections.

When to use this

Use collapse when readers need to focus on the surrounding graph without losing a group's contents. The diagram engine treats the group as a container: collapsing hides its members, moves crossing links to a placeholder, and merges parallel crossings; expanding restores the saved state.

Set up a group and add collapse controls

  1. Render nodes and edges, then add a group around the member nodes. The instance gives you the DiagramEngine through getEngine(); addGroup() creates the group, and addToGroup() assigns its members.
  2. Call collapseGroup(groupId, options?) or expandGroup(groupId) from your controls. Both calls return promises, so await them before treating the operation as complete.

The example places three member nodes inside the Service group. On load, all five nodes and four links are visible. Click collapse group: the three members disappear, the group becomes a Service placeholder, and links crossing the group boundary attach to the placeholder. The two links from ext 1 merge into one proxy link labelled 2×; the internal member link disappears while collapsed. Click expand group to restore the three members, their original positions, and all four links.

This page adds collapse and expand controls to the mounted diagram; for mounting the canvas and retrieving its instance in each framework, see Build runnable workflows.

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

const toolbar = document.createElement('div');
const collapseButton = document.createElement('button');
const expandButton = document.createElement('button');
const host = document.createElement('div');
collapseButton.textContent = 'collapse group';
expandButton.textContent = 'expand group';
host.style.height = '480px';
toolbar.append(collapseButton, expandButton);
document.body.append(toolbar, host);

const nodes = [
  { id: 'ext1', position: { x: 60, y: 80 }, size: { width: 120, height: 60 }, label: 'ext 1' },
  { id: 'ext2', position: { x: 60, y: 300 }, size: { width: 120, height: 60 }, label: 'ext 2' },
  { id: 'm1', position: { x: 420, y: 80 }, size: { width: 120, height: 60 }, label: 'member 1' },
  { id: 'm2', position: { x: 420, y: 200 }, size: { width: 120, height: 60 }, label: 'member 2' },
  { id: 'm3', position: { x: 420, y: 320 }, size: { width: 120, height: 60 }, label: 'member 3' },
];
const edges = [
  { id: 'a', source: 'ext1', target: 'm1' },
  { id: 'b', source: 'ext1', target: 'm2' },
  { id: 'c', source: 'ext2', target: 'm3' },
  { id: 'd', source: 'm1', target: 'm2' },
];

async function mountDiagram() {
  const instance = render({ nodes, edges }, host);
  const engine = instance.getEngine();
  const group = await engine.addGroup({ name: 'Service' });
  group.setFrame({ x: 400, y: 60, width: 180, height: 340 });
  for (const id of ['m1', 'm2', 'm3']) {
    await engine.addToGroup(group.id, id);
  }
  instance.fitView(40);
  instance.renderNow();

  collapseButton.addEventListener('click', async () => {
    await engine.collapseGroup(group.id, { proxyLabel: (info) => `${info.count}×` });
    instance.renderNow();
  });
  expandButton.addEventListener('click', async () => {
    await engine.expandGroup(group.id);
    instance.renderNow();
  });
}

void mountDiagram();

Each sample renders the same five nodes and four links. Its setup creates the Service group and assigns m1, m2, and m3; the buttons await the engine operation. The JavaScript, Qwik, React, and Vue samples call renderNow() after the change. The Angular sample gets the active engine from its canvas view.

Options that affect the result

OptionTypeDefaultWhat it does
groupIdstringRequiredIdentifies the group to collapse or expand.
optionsCollapseOptionsundefinedOptional collapse settings.
CollapseOptions.proxyLabel(info: ProxyLabelInfo) => stringThe crossing count as a string when greater than one; no synthetic label for a single crossingSupplies the label for each aggregated proxy link. Returning an empty string suppresses the label.

collapseGroup() resolves after the engine executes the collapse command; expandGroup() resolves after it executes the expand command. Both calls operate on the live diagram through its instance's engine. The collapse snapshot retains member positions and prior group geometry; expanding restores those positions and geometry, restores removed links, and removes the placeholder. Internal links are removed while collapsed. Boundary links are grouped by external node and direction, with one proxy link retained per group.

An empty group has no member nodes to hide, so it collapses without creating a placeholder. For the compact visual representation shown here, add member nodes before collapsing.

Try the live demo

Open the Collapse & expand demo to see the member nodes hide, boundary links re-home to the placeholder, and the parallel links merge into one labelled proxy. The demo source is collapse-expand.html.

Was this page helpful?