Cluster und Hierarchie
Geben Sie einem Knoten children und er wird zu einem Cluster: Reduzieren Sie ihn zu einem einzelnen Knoten, um einen ausgelasteten Graphen zu zähmen, erweitern Sie ihn, um seine in einer Blase angeordneten Mitglieder anzuzeigen. Stattdessen wird eine Kante mit einem Ende innerhalb eines reduzierten Clusters in beliebiger Tiefe zum Cluster gezeichnet, sodass die Topologie immer lesbar bleibt. Das gilt auch dann, wenn beide Enden ausgeblendet sind: Die a3 → b1-Verknüpfung zwischen den beiden Gruppen zielt erneut auf die Knoten ab, die auf dem Bildschirm angezeigt werden – group-a → group-b, wenn beide Kästchen sind, a3 → group-b, sobald Gruppe A geöffnet wird – die Abhängigkeit verschwindet also nie, nur weil Sie ein Kästchen ausgeblendet haben.
Klicken Sie auf das Abzeichen + / − auf einem Cluster, um es umzuschalten, oder steuern Sie es aus dem Code mit graph.toggleExpandNode(node). Gruppe A wird geöffnet, sodass Sie sehen können, wie das Link-Re-Targeting in allen Bundesstaaten erfolgt; Klicken Sie auf Alle reduzieren, um das Diagramm auf zwei Kästchen zu reduzieren, die durch den Cluster-Cross-Pfeil verbunden sind.
// The same toggle programmatically: fetch the cluster node and hand it to
// toggleExpandNode. node.expanded tells you the current state.
function toggleCluster(graph, id) {
const node = graph.getMutableNode(id)
if (node) graph.toggleExpandNode(node)
}
function setAllExpanded(graph, expanded) {
const clusters = ['group-a', 'group-b']
clusters.forEach((id) => {
const node = graph.getMutableNode(id)
if (node && !!node.expanded !== expanded) graph.toggleExpandNode(node)
})
}// enableNodeExpansion (on by default) draws the +/- affordance on clusters and
// makes them clickable. A collapsed cluster shows one node with synthetic edges to
// it; expanding lays its members out in a bubble and reveals their real edges.
const options = {
render: { enableNodeExpansion: true }
}// A node becomes a cluster by giving it `children` — full nodes in their own
// right. `expanded: false` starts it collapsed (rendered as a single node); the
// members and their edges appear when it opens. Edges are always declared at the
// top level, whether they cross clusters or stay inside one.
const data = {
nodes: [
{ id: 'core', data: { label: 'core' } },
{
id: 'group-a',
data: { label: 'Group A' },
expanded: false,
children: [
{ id: 'a1', data: { label: 'a1' } },
{ id: 'a2', data: { label: 'a2' } },
{ id: 'a3', data: { label: 'a3' } }
]
},
{
id: 'group-b',
data: { label: 'Group B' },
expanded: false,
children: [
{ id: 'b1', data: { label: 'b1' } },
{ id: 'b2', data: { label: 'b2' } },
{ id: 'b3', data: { label: 'b3' } }
]
}
],
edges: [
{ from: 'core', to: 'a1' },
{ from: 'a1', to: 'a2' },
{ from: 'a2', to: 'a3' },
{ from: 'core', to: 'b1' },
{ from: 'b1', to: 'b2' },
{ from: 'b2', to: 'b3' },
// Crosses two cluster boundaries: re-targets to whatever's on screen
// (group-a → group-b collapsed, a3 → group-b once A opens, and so on).
{ from: 'a3', to: 'b1' }
]
}