{"id":283,"date":"2013-05-29T07:55:08","date_gmt":"2013-05-29T07:55:08","guid":{"rendered":"http:\/\/mindfusion.eu\/blog\/?p=283"},"modified":"2021-01-08T15:27:27","modified_gmt":"2021-01-08T15:27:27","slug":"create-a-block-diagram-editor-in-javascript","status":"publish","type":"post","link":"https:\/\/mindfusion.dev\/blog\/create-a-block-diagram-editor-in-javascript\/","title":{"rendered":"Create a block diagram editor in JavaScript"},"content":{"rendered":"<p>In this example, we will create a block diagram editor using MindFusion.Diagramming for JavaScript.<\/p>\n<p>First, let&#8217;s add two HTML canvas elements to a page, one for the Diagram control and one for a NodeListView control that will serve as a tool palette:<\/p>\n<pre id=\"line1\"><span class=\"comment\">&lt;!-- The Diagram component is bound to the canvas element below --&gt;<\/span>\n<span id=\"line244\"><\/span>\n<span id=\"line245\"><\/span>&lt;<span class=\"start-tag\">div<\/span> <span class=\"attribute-name\">style<\/span>=\"<a class=\"attribute-value\">width:800px; height:600px; overflow:auto; border: 1px solid;<\/a>\"&gt;\n<span id=\"line246\"><\/span>  &lt;<span class=\"start-tag\">canvas<\/span> <span class=\"attribute-name\">id<\/span>=\"<a class=\"attribute-value\">diagram<\/a>\" <span class=\"attribute-name\">width<\/span>=\"<a class=\"attribute-value\">2100<\/a>\" <span class=\"attribute-name\">height<\/span>=\"<a class=\"attribute-value\">2100<\/a>\"&gt;\n<span id=\"line247\"><\/span>    This page requires a browser that supports HTML 5 Canvas element.\n<span id=\"line248\"><\/span>  &lt;\/<span class=\"end-tag\">canvas<\/span>&gt;\n<span id=\"line249\"><\/span>&lt;\/<span class=\"end-tag\">div<\/span>&gt;\n<span id=\"line250\"><\/span>\n<span id=\"line251\"><\/span>\n<span id=\"line252\"><\/span><span class=\"comment\">&lt;!-- NodeListView control --&gt;<\/span>\n<span id=\"line253\"><\/span>\n<span id=\"line254\"><\/span>&lt;<span class=\"start-tag\">div<\/span> <span class=\"attribute-name\">style<\/span>=\"<a class=\"attribute-value\">width:130px; height:600px; overflow:none; border: 1px solid rgb(0, 0, 0);<\/a>\"&gt;\n<span id=\"line255\"><\/span>  &lt;<span class=\"start-tag\">canvas<\/span> <span class=\"attribute-name\">id<\/span>=\"<a class=\"attribute-value\">nodeList<\/a>\" <span class=\"attribute-name\">width<\/span>=\"<a class=\"attribute-value\">130<\/a>\" <span class=\"attribute-name\">height<\/span>=\"<a class=\"attribute-value\">600<\/a>\"&gt;&lt;\/<span class=\"end-tag\">canvas<\/span>&gt;\n<span id=\"line256\"><\/span>&lt;\/<span class=\"end-tag\">div<\/span>&gt;<\/pre>\n<p>Next, add references to the necessary script files:<\/p>\n<pre id=\"line1\">&lt;<span class=\"start-tag\">script<\/span> <span class=\"attribute-name\">src<\/span>=\"<a class=\"attribute-value\" href=\"view-source:https:\/\/mindfusion.dev\/blog\/create-a-block-diagram-editor-in-javascript\/MicrosoftAjax.js\">MicrosoftAjax.js<\/a>\" <span class=\"attribute-name\">type<\/span>=\"<a class=\"attribute-value\">text\/javascript<\/a>\"&gt;&lt;\/<span class=\"end-tag\">script<\/span>&gt;\n<span id=\"line261\"><\/span>&lt;<span class=\"start-tag\">script<\/span> <span class=\"attribute-name\">src<\/span>=\"<a class=\"attribute-value\" href=\"view-source:https:\/\/mindfusion.dev\/blog\/create-a-block-diagram-editor-in-javascript\/MindFusion.Diagramming.js\">MindFusion.Diagramming.js<\/a>\" <span class=\"attribute-name\">type<\/span>=\"<a class=\"attribute-value\">text\/javascript<\/a>\"&gt;&lt;\/<span class=\"end-tag\">script<\/span>&gt;\n<span id=\"line262\"><\/span>&lt;<span class=\"start-tag\">script<\/span> <span class=\"attribute-name\">src<\/span>=\"<a class=\"attribute-value\" href=\"view-source:https:\/\/mindfusion.dev\/blog\/create-a-block-diagram-editor-in-javascript\/BlockDiagEdit.js\">BlockDiagEdit.js<\/a>\" <span class=\"attribute-name\">type<\/span>=\"<a class=\"attribute-value\">text\/javascript<\/a>\"&gt;&lt;\/<span class=\"end-tag\">script<\/span>&gt;<\/pre>\n<p>In the load handler in the script file, setup the diagram properties and populate the node list with prototype containers and shape nodes, that will represent respectively systems and modules in our block diagrams:<\/p>\n<pre>Sys.Application.add_load(function (sender, args)\n{\n\t\/\/ create a Diagram component that wraps the \"diagram\" canvas\n\tdiagram = $create(Diagram, null, null, null, $get(\"diagram\"));\n\tdiagram.addEventListener(Events.nodeCreated, onNodeCreated);\n\tdiagram.addEventListener(Events.linkCreated, onLinkCreated);\n\tdiagram.setLinkHeadShapeSize(3);\n\tdiagram.setLinkHeadShape(\"Alternative\");\n\tdiagram.setAllowInplaceEdit(true);\n\n\t\/\/ create a NodeListView component that wraps the \"nodeList\" canvas\n\tvar nodeList = $create(MindFusion.Diagramming.NodeListView,\n        null, null, null, $get(\"nodeList\"));\n\tnodeList.setIconSize(new Size(48, 48));\n\tnodeList.setDefaultNodeSize(new Size(24, 24));\n\n\tvar colors = [\n\t\t\"#FF5555\",\n\t\t\"#55FF55\",\n\t\t\"#5555FF\",\n\t\t\"#FFFFFF\"\n\t];\n\n\t\/\/ add container to the NodeListView to represent \"system\" blocks\n\tfor (var i = 0; i &lt; 4; ++i)\n\t{\n\t\tvar node = new ContainerNode(diagram);\n\t\tnode.setBrush(colors[i]);\n\t\tnodeList.addNode(node, \"System \" + (i + 1));\n\t}\n\n\t\/\/ add container to the NodeListView to represent \"module\" blocks\n\tfor (var i = 0; i &lt; 4; ++i)\n\t{\n\t\tvar node = new MindFusion.Diagramming.ShapeNode(diagram);\n\t\tnode.setShape(\"Rectangle\");\n\t\tnode.setBrush(colors[i]);\n\t\tnodeList.addNode(node, \"Module \" + (i + 1));\n\t}\n});\n<\/pre>\n<p>Handle the nodeCreated event to make containers larger, and start inplace edit operation to let users enter text immediately after dropping a node:<\/p>\n<pre>function onNodeCreated(sender, args)\n{\n\tvar node = args.getNode();\n\tif (ContainerNode.isInstanceOfType(node))\n\t{\n\t\t\/\/ make containers larger\n\t\tvar bounds = node.getBounds().clone();\n\t\tbounds.width = 100;\n\t\tbounds.height = 75;\n\t\tnode.setBounds(bounds);\n\t}\n\n\t\/\/ let user enter text immediately\n\tdiagram.beginEdit(node);\n}\n<\/pre>\n<p>When there aren&#8217;t anchor points defined, the diagram control snaps link points to nearest point of nodes borders. Let&#8217;s automatically align points when links are created to make them straight horizontal or vertical lines if they are already close to being such. Otherwise leave points unchanged to let users draw diagonal lines too:<\/p>\n<pre>function onLinkCreated(sender, args)\n{\n\tvar link = args.getLink();\n\tvar start = link.getStartPoint();\n\tvar end = link.getEndPoint();\n\n\t\/\/ make link horizontal if close to being one\n\tif (Math.abs(start.x - end.x) &gt; 10 &amp;&amp; Math.abs(start.y - end.y) &lt; 4)\n\t{\n\t\tend.y = start.y;\n\t\tlink.setEndPoint(end);\n\t}\n\n\t\/\/ make link vertical if close to being one\n\tif (Math.abs(start.y - end.y) &gt; 10 &amp;&amp; Math.abs(start.x - end.x) &lt; 4)\n\t{\n\t\tend.x = start.x;\n\t\tlink.setEndPoint(end);\n\t}\n}\n<\/pre>\n<p>Here&#8217;s the kind of block diagrams and flowcharts you can now draw:<br \/>\n<img decoding=\"async\" src=\"http:\/\/mindfusion.dev\/_samples\/BlockDiagEdit.png\" alt=\"Block diagram\" \/><\/p>\n<p>The complete example can be downloaded from this link:<br \/>\n<a href=\"https:\/\/mindfusion.dev\/_samples\/BlockDiagEdit.zip\">https:\/\/mindfusion.dev\/_samples\/BlockDiagEdit.zip<\/a><\/p>\n<p>Enjoy!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this example, we will create a block diagram editor using MindFusion.Diagramming for JavaScript. First, let&#8217;s add two HTML canvas elements to a page, one for the Diagram control and one for a NodeListView control that will serve as a &hellip; <a href=\"https:\/\/mindfusion.dev\/blog\/create-a-block-diagram-editor-in-javascript\/\">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":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":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[95,74],"tags":[96,10,3,4,97,80],"class_list":["post-283","post","type-post","status-publish","format-standard","hentry","category-diagramming-2","category-sample-code","tag-block","tag-canvas","tag-diagram","tag-flowchart","tag-html","tag-javascript"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3RlKs-4z","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/283","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=283"}],"version-history":[{"count":5,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/283\/revisions"}],"predecessor-version":[{"id":2436,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/283\/revisions\/2436"}],"wp:attachment":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/media?parent=283"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/categories?post=283"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/tags?post=283"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}