{"id":2711,"date":"2021-09-29T13:25:44","date_gmt":"2021-09-29T13:25:44","guid":{"rendered":"https:\/\/mindfusion.eu\/blog\/?p=2711"},"modified":"2021-09-29T13:29:46","modified_gmt":"2021-09-29T13:29:46","slug":"alignment-options-in-mindfusion-diagramming","status":"publish","type":"post","link":"https:\/\/mindfusion.dev\/blog\/alignment-options-in-mindfusion-diagramming\/","title":{"rendered":"Alignment options in MindFusion.Diagramming"},"content":{"rendered":"\n<p>In this post we&#8217;ll review several ways to let users align diagram nodes. The sample code is for WPF, but similar properties and methods exist in MindFusion.Diagramming APIs for other platforms.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p><strong>Alignment Grid<\/strong><\/p>\n\n\n\n<p>The alignment grid is used to align nodes coordinates at even intervals during user interactions. To enable alignment, set diagram&#8217;s AlignToGrid property to true. Set ShowGrid to show or hide the grid, and GridStyle to toggle its appearance between points and lines. GridOffsetX and GridOffsetY properties let you offset the grid a bit from diagram&#8217;s edges:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>diagram.ShowGrid = false;\ndiagram.AlignToGrid = false;\ndiagram.GridPen = new Pen(Brushes.LightGray, 0.2);\ndiagram.GridOffsetX = 0;\ndiagram.GridOffsetY = 0;\ndiagram.GridStyle = GridStyle.Lines;<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2021\/09\/align_grid.png\"><img loading=\"lazy\" decoding=\"async\" width=\"419\" height=\"487\" src=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2021\/09\/align_grid.png\" alt=\"\" class=\"wp-image-2712\" srcset=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2021\/09\/align_grid.png 419w, https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2021\/09\/align_grid-258x300.png 258w\" sizes=\"auto, (max-width: 419px) 100vw, 419px\" \/><\/a><\/figure>\n\n\n\n<p>Note that setting items&#8217; coordinates from code does not automatically align them to a grid. Call the AlignPointToGrid method if you need to find aligned coordinates.<\/p>\n\n\n\n<p><strong>Automatic Node align<\/strong><\/p>\n\n\n\n<p>Set the AutoAlignNodes property to enable alignment guides that let users align moved or resized node to nearby nodes. The guides allow aligning nodes&#8217; borders or center points:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>diagram.AutoAlignNodes = true;\ndiagram.AlignmentGuidePen = new Pen(Brushes.Red, 0.2);<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2021\/09\/align_guide.png\"><img loading=\"lazy\" decoding=\"async\" width=\"446\" height=\"509\" src=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2021\/09\/align_guide.png\" alt=\"\" class=\"wp-image-2713\" srcset=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2021\/09\/align_guide.png 446w, https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2021\/09\/align_guide-263x300.png 263w\" sizes=\"auto, (max-width: 446px) 100vw, 446px\" \/><\/a><\/figure>\n\n\n\n<p><strong>Ruler Alignment Guides<\/strong><\/p>\n\n\n\n<p>If the Diagram control is placed inside a Ruler, setting ruler&#8217;s EnableGuides property will let users align nodes by dragging alignment guide from a ruler&#8217;s scale as shown below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ruler.EnableGuides = true;\nruler.GuideColor = Colors.Red;<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2021\/09\/align_ruler.png\"><img loading=\"lazy\" decoding=\"async\" width=\"413\" height=\"488\" src=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2021\/09\/align_ruler.png\" alt=\"\" class=\"wp-image-2714\" srcset=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2021\/09\/align_ruler.png 413w, https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2021\/09\/align_ruler-254x300.png 254w\" sizes=\"auto, (max-width: 413px) 100vw, 413px\" \/><\/a><\/figure>\n\n\n\n<p><strong>Align from Code<\/strong><\/p>\n\n\n\n<p>You can implement menu or toolbar commands to align selected nodes by setting nodes&#8217; Bounds property. E.g. following code will align selected nodes to the active selected node (indicated by white adjustment handles vs gray ones). First, let&#8217;s create an Align method that uses a callback parameter to abstract what parts of the nodes are aligned:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void Align(\n\tFunc&lt;DiagramNode, DiagramNode, Vector&gt; calcOffset)\n{\n\tvar target = diagram.ActiveItem as DiagramNode;\n\tif (target != null)\n\t{\n\t\tforeach (var node in diagram.Selection.Nodes)\n\t\t{\n\t\t\tif (node == target)\n\t\t\t\tcontinue;\n\n\t\t\tvar newBounds = node.Bounds;\n\t\t\tnewBounds.Offset(\n\t\t\t\tcalcOffset(node, target));\n\t\t\tnode.Bounds = newBounds;\n\t\t}\n\t}\n}<\/code><\/pre>\n\n\n\n<p>It allows us implementing different alignment modes like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void OnAlignLeft(object sender, EventArgs e)\n{\n\tAlign((node, target) =&gt; new Vector(\n\t\ttarget.Bounds.Left - node.Bounds.Left, 0));\n}\n\nvoid OnAlignTop(object sender, EventArgs e)\n{\n\tAlign((node, target) =&gt; new Vector(\n\t\t0, target.Bounds.Top - node.Bounds.Top));\n}\n\nvoid OnAlignRight(object sender, EventArgs e)\n{\n\tAlign((node, target) =&gt; new Vector(\n\t\ttarget.Bounds.Right - node.Bounds.Right, 0));\n}\n\nvoid OnAlignBottom(object sender, EventArgs e)\n{\n\tAlign((node, target) =&gt; new Vector(\n\t\t0, target.Bounds.Bottom - node.Bounds.Bottom));\n}\n\nvoid OnAlignCenterX(object sender, EventArgs e)\n{\n\tAlign((node, target) =&gt; new Vector(\n\t\ttarget.GetCenter().X - node.GetCenter().X, 0));\n}\n\nvoid OnAlignCenterY(object sender, EventArgs e)\n{\n\tAlign((node, target) =&gt; new Vector(\n\t\t0, target.GetCenter().Y - node.GetCenter().Y));\n}<\/code><\/pre>\n\n\n\n<p>Enjoy!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post we&#8217;ll review several ways to let users align diagram nodes. The sample code is for WPF, but similar properties and methods exist in MindFusion.Diagramming APIs for other platforms.<\/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":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[95,74],"tags":[680],"class_list":["post-2711","post","type-post","status-publish","format-standard","hentry","category-diagramming-2","category-sample-code","tag-alignment-guides"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3RlKs-HJ","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2711","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=2711"}],"version-history":[{"count":3,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2711\/revisions"}],"predecessor-version":[{"id":2718,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2711\/revisions\/2718"}],"wp:attachment":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/media?parent=2711"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/categories?post=2711"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/tags?post=2711"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}