{"id":2925,"date":"2025-01-14T07:25:23","date_gmt":"2025-01-14T07:25:23","guid":{"rendered":"https:\/\/mindfusion.eu\/blog\/?p=2925"},"modified":"2025-01-14T08:30:55","modified_gmt":"2025-01-14T08:30:55","slug":"find-descendant-nodes-in-mindfusion-diagrams","status":"publish","type":"post","link":"https:\/\/mindfusion.dev\/blog\/find-descendant-nodes-in-mindfusion-diagrams\/","title":{"rendered":"Find descendant nodes in MindFusion diagrams"},"content":{"rendered":"<p>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):<\/p>\n<p><!--more--><\/p>\n\n\n<pre class=\"wp-block-code\"><code>function traverseGraphBFS(fromNode, processCallback)\n{\n    \/\/ queueing adjacent nodes ensures they are processed\n    \/\/ in order by distance from initial node\n    var queue = &#91;fromNode];\n\n    \/\/ mark nodes that have ever been enqueued, in case multiple\n    \/\/ paths in the graph lead to them\n    var traversed = new Set(queue);\n\n    \/\/ keep some statistics to report to the callback\n    var visitOrder = 0;\n    var distances = new Map(&#91;&#91;fromNode, 0]]);\n\n    while (queue.length &gt; 0)\n    {\n        \/\/ report next node in the queue\n        var current = queue.shift();\n        var distance = distances.get(current);\n        processCallback(current, visitOrder, distance);\n        visitOrder += 1;\n\n        \/\/ process adjacent nodes\n        for (var outLink of current.outgoingLinks)\n        {\n            var nextNode = outLink.destination;\n\n            \/\/ skip nodes we already know about\n            if (traversed.has(nextNode))\n                continue;\n\n            \/\/ mark as known and enque\n            queue.push(nextNode);\n            traversed.add(nextNode);\n            distances.set(nextNode, distance + 1);\n        }\n    }\n}<\/code><\/pre>\n\n\n\n<p>Calling this method from nodeClicked event handler:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>for (var node of diagram.nodes)\n    node.text = \"\";\n\n\ntraverseGraphBFS(args.node, (node, order, distance) =>\n{\n    node.enableStyledText = true;\n    node.text = `&lt;color=\"green\">${order}&lt;\/color> : &lt;color=\"blue\">${distance}&lt;\/color>`;\n});\n<\/code><\/pre>\n\n\n\n<p>displays order counter in green and graph distance in blue:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2025\/01\/bfs.png\"><img loading=\"lazy\" decoding=\"async\" width=\"827\" height=\"433\" src=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2025\/01\/bfs.png\" alt=\"\" class=\"wp-image-2926\" srcset=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2025\/01\/bfs.png 827w, https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2025\/01\/bfs-300x157.png 300w, https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2025\/01\/bfs-768x402.png 768w, https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2025\/01\/bfs-500x262.png 500w\" sizes=\"auto, (max-width: 827px) 100vw, 827px\" \/><\/a><\/figure>\n\n\n\n<p>If you&#8217;d like to find ancestor nodes, change the for-of loop code to enumerate DiagramNode.incomingLinks instead. If you&#8217;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 &#8211; finding paths in a graph &#8211; is provided out of the box by the PathFinder class.<\/p>\n\n\n\n<p>The sample above shows MindFusion\u2019s 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 <a href=\"https:\/\/mindfusion.dev\/downloads.html\">this<\/a> page.<\/p>\n\n\n\n<p>Enjoy!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 &hellip; <a href=\"https:\/\/mindfusion.dev\/blog\/find-descendant-nodes-in-mindfusion-diagrams\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[2],"tags":[3,4,80],"class_list":["post-2925","post","type-post","status-publish","format-standard","hentry","category-product-releases","tag-diagram","tag-flowchart","tag-javascript"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3RlKs-Lb","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2925","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/comments?post=2925"}],"version-history":[{"count":3,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2925\/revisions"}],"predecessor-version":[{"id":2929,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2925\/revisions\/2929"}],"wp:attachment":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/media?parent=2925"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/categories?post=2925"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/tags?post=2925"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}