{"id":2759,"date":"2022-05-02T09:01:57","date_gmt":"2022-05-02T09:01:57","guid":{"rendered":"https:\/\/mindfusion.eu\/blog\/?p=2759"},"modified":"2022-05-02T09:43:41","modified_gmt":"2022-05-02T09:43:41","slug":"one-way-links-in-diagramming-for-javascript","status":"publish","type":"post","link":"https:\/\/mindfusion.dev\/blog\/one-way-links-in-diagramming-for-javascript\/","title":{"rendered":"One-way Links in Diagramming for JavaScript"},"content":{"rendered":"<p>In this blog post we demonstrate how you can use the JavaScript Diagram library to allow users to draw an org chart or one-way graph. By default, users are allowed to draw links between any two nodes and the count of links is unlimited. We will use event and properties, available in JS Diagram to allow users to:<br \/>\n&#8211; draw only one link between two nodes<br \/>\n&#8211; draw links only in one direction.<\/p>\n<p>This behavior mirrors the hierarchy of an organization: in general , each employee, represented by a node, should have only one direct boss.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/mindfusion.dev\/samples\/javascript\/diagram\/link_restrictions.png\" title=\"Applying Link Restrictions in Diagramming for JavaScript\"><br \/>\n<!--more--><br \/>\n<strong>I. Diagram Setup<\/strong><\/p>\n<p>We copy the JS Diagram files from the &#8220;umd&#8221; folder into the root directory of our application. We need to reference them in the web page of the project:<\/p>\n<pre>&lt;script src=\"umd\/collections.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;\n&lt;script src=\"umd\/drawing.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;\n&lt;script src=\"umd\/controls.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;\n\n&lt;script src=\"umd\/animations.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;\n&lt;script src=\"umd\/graphs.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;\n&lt;script src=\"umd\/diagramming.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;\n&lt;script src=\"FirstDiagram.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;\n<\/pre>\n<p>Finally, we add a reference to a JavaScript code-behind file that will contain the programming logic of our application.<\/p>\n<p>The diagram needs a Canvas element to render itself onto, so we add one to the web page. It is important that you specify an id for it:<\/p>\n<pre>&lt;div&gt;&lt;canvas id=\"diagram\" width=\"2100\" height=\"2100\"&gt;&lt;\/canvas&gt;&lt;\/div&gt;<\/pre>\n<p>In the code-behind file we add mappings to the classes we will use. We do this to make our code easier to read and write:<\/p>\n<pre>\/\/\/ <reference path=\"typescript\/global.d.ts\">\n\nvar Diagram = MindFusion.Diagramming.Diagram;\nvar ShapeNode = MindFusion.Diagramming.ShapeNode;\nvar Behavior = MindFusion.Diagramming.Behavior;\n\/\/ used by link event handling\nvar Events = MindFusion.Diagramming.Events;\nvar PathFinder = MindFusion.Diagramming.PathFinder;\n\nvar diagram = null;\nvar diagramView = null;\n<\/reference><\/pre>\n<p>We add a reference to the global.d.ts TypeScript file, which provides us with IntelliSense support in certain IDEs, like Visual Studio Code. We also declare a diagram variable, which represents the instance of our <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/jsdiagram\/index.htm?P_MindFusion_Diagramming_Overview_diagramView_0.htm\" title=\"MindFusion Diagramming for JavaScript: Diagram\">Diagram<\/a> class. We get it from DiagramView this way:<\/p>\n<pre> \/\/ create a DiagramView component that wraps the \"diagram\" canvas\ndiagramView = MindFusion.Diagramming.DiagramView.create(document.getElementById(\"diagram\"));\n\/\/ diagramView.modificationStart = MindFusion.Diagramming.ModificationStart.AutoHandles;\ndiagramView.behavior = MindFusion.Diagramming.Behavior.LinkShapes;\ndiagram = diagramView.diagram;\n<\/pre>\n<p>The <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/jsdiagram\/index.htm?T_MindFusion_Diagramming_DiagramView_Members.htm\" title=\"MindFusion Diagramming for JavaScript: DiagramView\">DiagramView<\/a> uses the Canvas element to render the diagram and the diagram is a property of the view. Now that we have initialized the diagram, we are ready to implement our features.<\/p>\n<p><strong>II. Implementation of the Link Restrictions<\/strong><\/p>\n<p>We want to stop the user from drawing certain links. That is why we will handle the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/jsdiagram\/index.htm?P_MindFusion_Diagramming_Events_linkCreating_0.htm\" title=\"MindFusion Diagramming for JavaScript: linkCreating\">linkCreating<\/a> event. While the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/jsdiagram\/index.htm?P_MindFusion_Diagramming_Events_linkCreated_0.htm\" title=\"MindFusion Diagramming for JavaScript: linkCreated\">linkCreated<\/a> event is raised after a link is created, the modifying event is fired continuously during the process of drawing the link. More important: it has a &#8220;cancel&#8221; property, which allows us to stop the user from creating the link, which is exactly what we need.<\/p>\n<p>We wire the event this way:<\/p>\n<pre>diagram.addEventListener(Events.linkCreating, onLinkCreating);<\/pre>\n<p>The event handler method has the following signature:<\/p>\n<pre>\/\/we use the event to stop drawing of several\n\/\/links between two nodes\nfunction onLinkCreating(diagram, args)\n{\n....\n}<\/pre>\n<p>First, we need to detect if the destination of the link is known. Since version 4.2 of JS Diagram, the LinkEventsArgs class exposes two new properties: origin and destination. As we said, the linkCreating event fires continuously while the link is drawn and it might not be know yet which node the link is about to connect:<\/p>\n<pre>if (args.destination == null)\n{\n\t\/\/ not pointing to a node yet\n\treturn;\n}\n<\/pre>\n<p>The <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/jsdiagram\/index.htm?CC_T_MindFusion_Diagramming_LinkEventArgs_Members_0.htm\" title=\"MindFusion Diagramming for JavaScript: LinkEventArgs\">LinkEventArgs<\/a> class provides us with reference to the would-be origin and destination nodes of the newly created <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/jsdiagram\/index.htm?CC_T_MindFusion_Diagramming_DiagramLink_Members_0.htm\" title=\"MindFusion Diagramming for JavaScript: DiagramLink\">DiagramLink<\/a> We use the new PathFinder class to detect if a path between the destination and origin of the link exists. If there is, it means there will be a cycle e.g. the user is trying to draw a link in a reverse direction. We need to stop this:<\/p>\n<pre>var pathFinder = new PathFinder(diagram);\nvar path = pathFinder.findShortestPath(\n\targs.destination, args.origin);\n\nif (path != null)\n{\n\t\/\/ adding this new link would create a cycle\n\t\/\/ dest...[node]...[node]...origin...dest\n       args.cancel = true;\n}\n<\/pre>\n<p>We set cancel to &#8220;true&#8221; and the link is not created.<\/p>\n<p>Finally, we need to check the count of incoming links of the destination nodes. We don&#8217;t want to allow the user to connect nodes at the lower level with more than one node from the higher level, which is the rule in an organizational hierarchy.<\/p>\n<pre>if(args.destination.incomingLinks.length &gt;= 1)\n        args.cancel = true;\n<\/pre>\n<p>If we run the application in the browser now, you will see that everything works as it should. Links are created only in one direction in the hierarchy and nodes cannot have more than one parent. There is one problem, however. Users are not stopped from moving existing links and this way they can still connect nodes in a manner that contradicts with the logic of our application. In order to prevent this, we need to handle another event: linkModifying.<\/p>\n<pre>diagram.addEventListener(Events.linkModifying, onLinkCreating);<\/pre>\n<p>We can use the same method for event handling.<\/p>\n<p>Now, if we try to move an existing link to another node and make it hafe two parents, the action is canceled. And that&#8217;s exactly what we want.<\/p>\n<p>You can download the code for this sample, together with all libraries used, from this link:<\/p>\n<p align=\"center\"><a href=\"https:\/\/mindfusion.dev\/samples\/javascript\/diagram\/LinkRestrictions.zip\" title=\"Download the Link Restrictions sample\">Applying Restrictions on Links: Download Sample Source Code<\/a><\/p>\n<p>Technical support is available through MindFusion <a title=\"Js Diagram Discussion Board\" href=\"https:\/\/mindfusion.dev\/Forum\/YaBB.pl?board=jsdiag_disc\">forum here.<\/a><\/p>\n<p><i>About Diagramming for JavaScript:<\/i> This native JavaScript library provides developers with the ability to create and customize any type of diagram, decision tree, flowchart, class hierarchy, graph, genealogy tree, BPMN diagrams and much more. The control offers rich event set, numerous customization options, animations, graph operations, styling and themes. You have more than 100 predefined nodes, table nodes and more than 15 automatic layout algorithms. Learn more about Diagramming for JavaScript at <a title=\"JavaScript Diagram Library\" href=\"https:\/\/mindfusion.dev\/javascript-diagram.html\">https:\/\/mindfusion.dev\/javascript-diagram.html<\/a>.<\/p>\n<p>&#8211;&gt;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this blog post we demonstrate how you can use the JavaScript Diagram library to allow users to draw an org chart or one-way graph. By default, users are allowed to draw links between any two nodes and the count &hellip; <a href=\"https:\/\/mindfusion.dev\/blog\/one-way-links-in-diagramming-for-javascript\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"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":false,"_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":[95,513],"tags":[4,473,692,694],"class_list":["post-2759","post","type-post","status-publish","format-standard","hentry","category-diagramming-2","category-javascript","tag-flowchart","tag-javascript-diagram","tag-one-way-graph","tag-orgchart"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3RlKs-Iv","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2759","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\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/comments?post=2759"}],"version-history":[{"count":7,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2759\/revisions"}],"predecessor-version":[{"id":2768,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2759\/revisions\/2768"}],"wp:attachment":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/media?parent=2759"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/categories?post=2759"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/tags?post=2759"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}