documentationfor yFiles for HTML 2.6

Node Aggregation

The node aggregation algorithm repeatedly clusters the nodes of a given graph and creates a hierarchical structure of clusters. It achieves this by smartly selecting appropriate clustering algorithms and applying them repeatedly. The result may for example be used to collapse regions to simplify interactively browsing large graphs. Refer to the LargeGraphAggregation demo on how to integrate the aggregation result for such a use case.

The result of a node aggregation algorithm is a tree of elements of type NodeAggregate. Each NodeAggregate consists of a collection of child aggregates, which together with the NodeAggregate itself represent a cluster of graph nodes. The corresponding graph node of an aggregate can be accessed by each aggregate’s node property. And vice versa, the NodeAggregationResult provides a mapping from nodes to their respective aggregate exposed by the aggregateMap. Also, the NodeAggregationResult provides the root of the resulting tree.

Sample Aggregation
Source Graph
Aggregation Result

An NodeAggregate together with its child nodes represents a cluster. In the example above the NodeAggregate containing the blue node together with its child aggregates forms a cluster which contains the blue, magenta, and orange node.

Calculating a Node Aggregation shows how to structurally aggregate the nodes of a graph.

Calculating a Node Aggregation
// prepare the node aggregation algorithm
const algorithm = new NodeAggregation({
  // determine substructures according to the graph structure, not the geometry/coordinates
  aggregation: NodeAggregationPolicy.STRUCTURAL
})
// run the algorithm
const result = algorithm.run(graph)

Note that some aggregates are purely virtual tree nodes that do not contain a graph node. The leaves of the aggregate tree always contain a graph node. nodesOnlyOnLeaves can be set to prevent non-leaf aggregates from containing a node.

The aggregation algorithm can be configured in a number of ways. The preferred resulting cluster sizes can be set by minimumClusterSize and maximumClusterSize. However, these are hints, and the algorithm does not guarantee that the resulting clusters strictly observe these values.

By setting the aggregation policy, the algorithm can be configured to operate either on the structural properties of the given graph, such that groups of nodes that are highly interconnected are likely placed into the same cluster. Or alternatively, to take the positions of nodes into account, such that nodes that are geometrically close to each other are likely clustered together.

Aggregation Policies
Clustering by Structure
Clustering by Node Coordinates

Node weights can be set to nudge the algorithm into placing certain nodes closer to the root of the aggregation hierarchy. These weights can be set via a mapper such as shown in Setting node weights. For more information about mapping items see Associating Data with Graph Elements. If specific nodes are to be placed at the top of the hierarchy, they can directly be set as top-level nodes.

Setting node weights
// creates a mapping that sets the weight of a node to the length of it's label
// placing nodes with long text higher up the hierarchy
nodeAggregation.nodeWeights.delegate = (node) => node.labels.first().text.length
Node Weights
Source Graph
Resulting Aggregation with heavier nodes placed closer to the top

It is also possible to exclude certain nodes from being clustered together. This can be controlled by associating each node with an arbitrary type object via nodeTypes and setting a NodeAggregationNodeTypeHandlingPolicy to nodeTypeHandling. Nodes with different types are then prevented from being clustered together.

Using Types
Source Graph
Aggregation Result
Preventing clusters of mixed types
// creates a mapping that associates a node to it's color
nodeAggregation.nodeTypes.delegate = (node) => node.tag.color
// sets how the algorithm handles the types
nodeAggregation.nodeTypeHandling = NodeAggregationNodeTypeHandlingPolicy.SEPARATE_AT_LEAVES