Find descendant nodes in MindFusion diagrams

This post demonstrates MindFusion.Diagramming API functionality that let you traverse connected diagram elements (following incident edges and adjacent nodes in graph-theory terminology). A diagram is treated as directed graph, where each node exposes incomingLinks and outgoingLinks collection properties, and respectively each link exposes origin and destination node properties. Thus the classic breadth-first search algorithm can be implemented like this for a diagram, with the callback parameter being invoked for each node, also reporting visit order and distance from initial node (as in length of shortest path in the graph):

function traverseGraphBFS(fromNode, processCallback)
{
    // queueing adjacent nodes ensures they are processed
    // in order by distance from initial node
    var queue = [fromNode];

    // mark nodes that have ever been enqueued, in case multiple
    // paths in the graph lead to them
    var traversed = new Set(queue);

    // keep some statistics to report to the callback
    var visitOrder = 0;
    var distances = new Map([[fromNode, 0]]);

    while (queue.length > 0)
    {
        // report next node in the queue
        var current = queue.shift();
        var distance = distances.get(current);
        processCallback(current, visitOrder, distance);
        visitOrder += 1;

        // process adjacent nodes
        for (var outLink of current.outgoingLinks)
        {
            var nextNode = outLink.destination;

            // skip nodes we already know about
            if (traversed.has(nextNode))
                continue;

            // mark as known and enque
            queue.push(nextNode);
            traversed.add(nextNode);
            distances.set(nextNode, distance + 1);
        }
    }
}

Calling this method from nodeClicked event handler:

for (var node of diagram.nodes)
    node.text = "";


traverseGraphBFS(args.node, (node, order, distance) =>
{
    node.enableStyledText = true;
    node.text = `<color="green">${order}</color> : <color="blue">${distance}</color>`;
});

displays order counter in green and graph distance in blue:

If you’d like to find ancestor nodes, change the for-of loop code to enumerate DiagramNode.incomingLinks instead. If you’d like to treat the diagram as undirected graph, enumerate over the result of DiagramNode.getAllLinks() method. Also note that one of the most common reasons for running breadth-first search – finding paths in a graph – is provided out of the box by the PathFinder class.

The sample above shows MindFusion’s JavaScript API. Code for other languages and frameworks will look similar as MindFusion maintains same diagramming model for multiple platforms. You can download the trial version of any MindFusion.Diagramming component from this page.

Enjoy!