Clustering
Groups related nodes into single aggregate nodes. Group by data field or custom predicate, then expand clusters.
Usage
// Group by a data field
graph.cluster({ groupBy: 'department' });
// Group by a custom function
graph.cluster({
groupBy: (node) => {
if (node.data.revenue > 1000000) return 'high-value';
if (node.data.revenue > 100000) return 'medium-value';
return 'low-value';
},
});
// Restore original graph
graph.uncluster(); Full Options
graph.cluster({
groupBy: 'data.type',
style: { shape: 'circle', fill: '#3b82f6', radius: 40, stroke: '#60a5fa' },
label: (groupName, nodes) => `${groupName} (${nodes.length})`,
groupStyle: {
'engineering': { fill: '#3b82f6' },
'design': { fill: '#8b5cf6' },
'marketing': { fill: '#10b981' },
},
}); | Option | Type | Description |
|---|---|---|
groupBy | string | (node) => string | Field name (dot-path) or function returning group key. |
style | NodeStyle | Default style for all cluster nodes. |
label | (groupName, nodes) => string | Label generator for cluster nodes. |
groupStyle | Record<string, NodeStyle> | Per-group style overrides. |
Cluster Node Data
Each cluster node has aggregate info on data:
| Property | Type | Description |
|---|---|---|
data._cluster | boolean | Always true. |
data._groupName | string | Group key. |
data._members | Node[] | Original nodes in cluster. |
data._memberCount | number | Node count. |
Cluster Edges
Edges between groups are aggregated into cluster edges with data._clusterEdge, data._edgeCount, and group info. Width scales with edge count.
Complete Example
import { create } from '@topokit/renderer-canvas';
const app = create(container, {
nodes: employees,
edges: collaborations,
layout: 'force',
theme: 'dark',
});
const graph = app.graph;
graph.cluster({
groupBy: 'department',
label: (dept, nodes) => `${dept} (${nodes.length} people)`,
groupStyle: {
'Engineering': { fill: '#3b82f6', radius: 35 },
'Design': { fill: '#8b5cf6', radius: 30 },
'Marketing': { fill: '#f59e0b', radius: 28 },
'Sales': { fill: '#10b981', radius: 32 },
},
});
// Double-click cluster to uncluster and highlight that group
graph.on('node:dblclick', ({ node }) => {
if (node.data._cluster) {
graph.uncluster();
graph.highlightByPredicate(
(n) => n.data.department === node.data._groupName
);
}
}); Next Steps
- Data Mapping -- import JSON and auto-style by group
- Filtering -- filter before or after clustering
- Legend -- auto-generate legend from clusters