Example #1
0
        private ICurve GetClusterCollapsedBoundary(Subgraph subgraph)
        {
            double width, height;

            FrameworkElement fe;

            if (drawingObjectsToFrameworkElements.TryGetValue(subgraph, out fe))
            {
                width  = fe.Width + 2 * subgraph.Attr.LabelMargin + subgraph.DiameterOfOpenCollapseButton;
                height = Math.Max(fe.Height + 2 * subgraph.Attr.LabelMargin, subgraph.DiameterOfOpenCollapseButton);
            }
            else
            {
                return(GetApproximateCollapsedBoundary(subgraph));
            }

            if (width < drawingGraph.Attr.MinNodeWidth)
            {
                width = drawingGraph.Attr.MinNodeWidth;
            }
            if (height < drawingGraph.Attr.MinNodeHeight)
            {
                height = drawingGraph.Attr.MinNodeHeight;
            }
            return(NodeBoundaryCurves.GetNodeBoundaryCurve(subgraph, width, height));
        }
 internal void CreateNodeBoundaryPath()
 {
     if (FrameworkElementOfNodeForLabel != null)
     {
         // FrameworkElementOfNode.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
         var center = Node.GeometryNode.Center;
         var margin = 2 * Node.Attr.LabelMargin;
         var bc     = NodeBoundaryCurves.GetNodeBoundaryCurve(Node,
                                                              FrameworkElementOfNodeForLabel
                                                              .Width + margin,
                                                              FrameworkElementOfNodeForLabel
                                                              .Height + margin);
         bc.Translate(center);
         //                if (LgNodeInfo != null) {
         //                    //LgNodeInfo.OriginalCurveOfGeomNode = bc;
         //                    Node.GeometryNode.BoundaryCurve =
         //                        bc.Transform(PlaneTransformation.ScaleAroundCenterTransformation(LgNodeInfo.Scale,
         //                            Node.GeometryNode.Center))
         //                            .Clone();
         //                }
     }
     BoundaryPath = new Path {
         Data = CreatePathFromNodeBoundary(), Tag = this
     };
     Panel.SetZIndex(BoundaryPath, ZIndex);
     SetFillAndStroke();
     if (Node.Label != null)
     {
         BoundaryPath.ToolTip = this.Node.LabelText;
         if (FrameworkElementOfNodeForLabel != null)
         {
             FrameworkElementOfNodeForLabel.ToolTip = this.Node.LabelText;
         }
     }
 }
Example #3
0
 internal void CreateNodeBoundaryPath()
 {
     if (FrameworkElementOfNodeForLabel != null)
     {
         var center = Node.GeometryNode.Center;
         var margin = 2 * Node.Attr.LabelMargin;
         var bc     = NodeBoundaryCurves.GetNodeBoundaryCurve(Node,
                                                              FrameworkElementOfNodeForLabel
                                                              .Width + margin,
                                                              FrameworkElementOfNodeForLabel
                                                              .Height + margin);
         bc.Translate(center);
     }
     BoundaryPath = new WPath {
         Data = CreatePathFromNodeBoundary(), Tag = this
     };
     WPanel.SetZIndex(BoundaryPath, ZIndex);
     SetFillAndStroke();
     if (Node.Label != null)
     {
         BoundaryPath.ToolTip = Node.LabelText;
         if (FrameworkElementOfNodeForLabel != null)
         {
             FrameworkElementOfNodeForLabel.ToolTip = Node.LabelText;
         }
     }
 }
Example #4
0
        private ICurve GetNodeBoundaryCurve(Microsoft.Msagl.Drawing.Node node)
        {
            double width, height;

            FrameworkElement frameworkElement;

            if (this.drawingObjectsToFrameworkElements.TryGetValue(node, out frameworkElement))
            {
                Debug.Assert(frameworkElement.CheckAccess());

                // a Frameworkelement was prerpared beforehand.
                width  = frameworkElement.Width + 2 * node.Attr.LabelMargin;
                height = frameworkElement.Height + 2 * node.Attr.LabelMargin;
            }
            else
            {
                return(GetNodeBoundaryCurveByMeasuringText(node));
            }

            // the calculated width must not be smaller the minimal size.

            if (width < drawingGraph.Attr.MinNodeWidth)
            {
                width = drawingGraph.Attr.MinNodeWidth;
            }
            if (height < drawingGraph.Attr.MinNodeHeight)
            {
                height = drawingGraph.Attr.MinNodeHeight;
            }

            return(NodeBoundaryCurves.GetNodeBoundaryCurve(node, width, height));
        }
Example #5
0
            void CreateNodeGeometry(DrawingNode node, Graph graph, GeometryGraph geometryGraph, GeometryPoint center, ConnectionToGraph connectionTo = ConnectionToGraph.Connected)
            {
                double width, height;

                StringMeasure.MeasureWithFont(node.Label.Text, new Font(node.Label.FontName, (float)node.Label.FontSize, (System.Drawing.FontStyle)(int) node.Label.FontStyle), out width,
                                              out height);

                node.Label.Width  = width;
                node.Label.Height = height;

                if (node.Label != null)
                {
                    width  += 2 * node.Attr.LabelMargin;
                    height += 2 * node.Attr.LabelMargin;
                }
                if (width < graph.Attr.MinNodeWidth)
                {
                    width = graph.Attr.MinNodeWidth;
                }
                if (height < graph.Attr.MinNodeHeight)
                {
                    height = graph.Attr.MinNodeHeight;
                }

                Node geomNode =
                    node.GeometryNode =
                        GeometryGraphCreator.CreateGeometryNode(graph, geometryGraph, node, connectionTo);

                geomNode.BoundaryCurve = NodeBoundaryCurves.GetNodeBoundaryCurve(node, width, height);
                geomNode.BoundaryCurve.Translate(center);
                geomNode.Center = center;
            }
Example #6
0
        private void ShapeStyle_cmb_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (_iset_ShapeStyle)
            {
                _iset_ShapeStyle = false;
                return;
            }
            var objs = _graphViewer.LayoutEditor.dragGroup;

            if ((objs.First() as VNode) == null)
            {
                return;
            }
            foreach (var obj in objs)
            {
                VNode vnode = obj as VNode;
                var   sh    = (Shape)shapeStyle_cmb.SelectedValue;
                if (vnode.Node.Attr.Shape == sh)
                {
                    continue;
                }
                var node = vnode.Node;
                node.Attr.Shape = sh;
                var sz  = Common.MeasureLabel(node.Label);
                var pos = node.GeometryNode.Center;
                node.GeometryNode.BoundaryCurve = NodeBoundaryCurves.GetNodeBoundaryCurve(vnode.Node, sz.Width, sz.Height);
                node.GeometryNode.Center        = pos;
                foreach (var dEdge in node.Edges)
                {
                    StraightLineEdges.CreateSimpleEdgeCurveWithUnderlyingPolyline(dEdge.GeometryEdge);
                    (_graphViewer.GetIViewerObject(dEdge) as VEdge).Invalidate();
                }
                vnode.Invalidate();
            }
        }
Example #7
0
        private ICurve GetNodeBoundaryCurveByMeasuringText(Microsoft.Msagl.Drawing.Node node)
        {
            double width, height;

            if (String.IsNullOrEmpty(node.LabelText))
            {
                width  = 10;
                height = 10;
            }
            else
            {
                var size = MeasureText(node.LabelText, new FontFamily(node.Label.FontName), node.Label.FontSize);
                width  = size.Width;
                height = size.Height;
            }

            width  += 2 * node.Attr.LabelMargin;
            height += 2 * node.Attr.LabelMargin;

            if (width < drawingGraph.Attr.MinNodeWidth)
            {
                width = drawingGraph.Attr.MinNodeWidth;
            }
            if (height < drawingGraph.Attr.MinNodeHeight)
            {
                height = drawingGraph.Attr.MinNodeHeight;
            }

            return(NodeBoundaryCurves.GetNodeBoundaryCurve(node, width, height));
        }
        ICurve GetNodeBoundaryCurve(DrawingNode node)
        {
            double width  = 0;
            double height = 0;

            if (graphObjectsToFrameworkElements.ContainsKey(node))
            {
                FrameworkElement fe = graphObjectsToFrameworkElements[node];
                if (fe == null)
                {
                    return(CurveFactory.CreateRectangleWithRoundedCorners(10, 10, 1, 1, new Point()));
                }
                width  = fe.Width + 2 * node.Attr.LabelMargin;
                height = fe.Height + 2 * node.Attr.LabelMargin;
            }
            else
            {
                return(CurveFactory.CreateRectangleWithRoundedCorners(10, 10, 5, 5, new Point()));
            }


            if (width < drawingGraph.Attr.MinNodeWidth * 2)
            {
                width = drawingGraph.Attr.MinNodeWidth * 2;
            }
            if (height < drawingGraph.Attr.MinNodeHeight * 2)
            {
                height = drawingGraph.Attr.MinNodeHeight * 2;
            }

            return(NodeBoundaryCurves.GetNodeBoundaryCurve(node, width, height));
        }
Example #9
0
        /// <summary>
        /// Create node boundary path.
        /// </summary>
        internal void CreateNodeBoundaryPath()
        {
            if (this.FrameworkElementOfNodeForLabel != null)
            {
                // FrameworkElementOfNode.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
                var center = this.Node.GeometryNode.Center;
                var margin = 2 * this.Node.Attr.LabelMargin;
                var bc     = NodeBoundaryCurves.GetNodeBoundaryCurve(this.Node, this.FrameworkElementOfNodeForLabel.Width + margin, this.FrameworkElementOfNodeForLabel.Height + margin);
                bc.Translate(center);
            }

            this.BoundaryPath = new Path {
                Data = this.CreatePathFromNodeBoundary(), Tag = this
            };
            Panel.SetZIndex(this.BoundaryPath, this.ZIndex);
            this.SetFillAndStroke();
            if (this.Node.Label != null)
            {
                var(_, tooltip)           = GetLabelTextAndToolTip(this.Node.LabelText);
                this.BoundaryPath.ToolTip = tooltip;
                if (this.FrameworkElementOfNodeForLabel != null)
                {
                    this.FrameworkElementOfNodeForLabel.ToolTip = tooltip;
                }
            }
        }
 internal void CreateNodeBoundaryPath()
 {
     if (FrameworkElementOfNodeForLabel != null)
     {
         // FrameworkElementOfNode.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
         var center = Node.GeometryNode.Center;
         var margin = 2 * Node.Attr.LabelMargin;
         var bc     = NodeBoundaryCurves.GetNodeBoundaryCurve(Node,
                                                              FrameworkElementOfNodeForLabel
                                                              .Width + margin,
                                                              FrameworkElementOfNodeForLabel
                                                              .Height + margin);
         bc.Translate(center);
     }
     BoundaryPath = new Path {
         Data = CreatePathFromNodeBoundary(), Tag = this
     };
     Panel.SetZIndex(BoundaryPath, ZIndex);
     SetFillAndStroke();
     if (Node.Label != null)
     {
         BoundaryPath.ToolTip = Node.Attr.Tooltip;
         if (FrameworkElementOfNodeForLabel != null)
         {
             FrameworkElementOfNodeForLabel.ToolTip = Node.Attr.Tooltip;
         }
     }
 }
Example #11
0
        private ICurve GetApproximateCollapsedBoundary(Subgraph subgraph)
        {
            if (textBoxForApproxNodeBoundaries == null)
            {
                SetUpTextBoxForApproxNodeBoundaries();
            }

            double width, height;

            if (String.IsNullOrEmpty(subgraph.LabelText))
            {
                height = width = subgraph.DiameterOfOpenCollapseButton;
            }
            else
            {
                double a = ((double)subgraph.LabelText.Length) / textBoxForApproxNodeBoundaries.Text.Length *
                           subgraph.Label.FontSize / Label.DefaultFontSize;
                width  = textBoxForApproxNodeBoundaries.Width * a + subgraph.DiameterOfOpenCollapseButton;
                height =
                    Math.Max(
                        textBoxForApproxNodeBoundaries.Height * subgraph.Label.FontSize / Label.DefaultFontSize,
                        subgraph.DiameterOfOpenCollapseButton);
            }

            if (width < drawingGraph.Attr.MinNodeWidth)
            {
                width = drawingGraph.Attr.MinNodeWidth;
            }
            if (height < drawingGraph.Attr.MinNodeHeight)
            {
                height = drawingGraph.Attr.MinNodeHeight;
            }

            return(NodeBoundaryCurves.GetNodeBoundaryCurve(subgraph, width, height));
        }
Example #12
0
        internal static DNode CreateDNodeAndSetNodeBoundaryCurveForSubgraph(Graph drawingGraph, DGraph dGraph, GeometryNode geomNode,
                                                                            DrawingNode drawingNode, GViewer viewer)
        {
            double width  = 0;
            double height = 0;
            var    dNode  = new DNode(drawingNode, viewer);

            dGraph.AddNode(dNode);
            Drawing.Label label = drawingNode.Label;
            if (label != null)
            {
                CreateDLabel(dNode, label, out width, out height, viewer);
            }
            if (width < drawingGraph.Attr.MinNodeWidth)
            {
                width = drawingGraph.Attr.MinNodeWidth;
            }
            if (height < drawingGraph.Attr.MinNodeHeight)
            {
                height = drawingGraph.Attr.MinNodeHeight;
            }

            var cluster = (Cluster)geomNode;
            var margin  = dNode.DrawingNode.Attr.LabelMargin;

            if (label != null)
            {
                CreateDLabel(dNode, label, out width, out height, viewer);
                width  += 2 * dNode.DrawingNode.Attr.LabelMargin + 2 * drawingNode.Attr.LineWidth;
                height += 2 * dNode.DrawingNode.Attr.LabelMargin + 2 * drawingNode.Attr.LineWidth;
            }
            cluster.RectangularBoundary = new RectangularClusterBoundary()
            {
                BottomMargin = margin,
                LeftMargin   = margin,
                RightMargin  = margin,
                TopMargin    = height,
                MinWidth     = width
            };
            // Filippo Polo: I'm taking this out because I've modified the drawing of a double circle
            // so that it can be used with ellipses too.
            //if (drawingNode.Attr.Shape == Shape.DoubleCircle)
            //width = height = Math.Max(width, height) * Draw.DoubleCircleOffsetRatio;
            ICurve curve;

            if (drawingNode.NodeBoundaryDelegate != null &&
                (curve = drawingNode.NodeBoundaryDelegate(drawingNode)) != null)
            {
                geomNode.BoundaryCurve = curve;
            }
            else if (geomNode.BoundaryCurve == null)
            {
                geomNode.BoundaryCurve =
                    NodeBoundaryCurves.GetNodeBoundaryCurve(dNode.DrawingNode, width, height);
            }
            return(dNode);
        }
Example #13
0
        public void window_loaded_prev2(object sender, RoutedEventArgs e)
        {
            Graph graph = new Graph();
            //graph.Attr.LayerDirection = LayerDirection.LR;
            //graph.AddNode("aaa");

            //graphViewer.Graph.CreateGeometryGraph();

            //var edge = graph.AddEdge("A", "B");
            //edge.DrawEdgeDelegate = edge_rendering_delegate;
            var edgeg = graph.AddEdge("ma", "mi");

            edgeg.LabelText = "has edge";
            var gv = _graphViewer;

            gv.Graph = graph;

            this.MouseWheel += MouseWheelEventHandler;

            //_graphViewer = gv;

            GVH.addNode(gv, "A", 0, 30);
            GVH.addNode(gv, "B", 20, 15);
            var dnode = graph.FindNode("A");
            var vnode = gv.GetIViewerObject(dnode) as VNode;

            //dnode.GeometryNode.BoundaryCurve = null;
            //VDebug.D.tag = 2;
            dnode.Attr.Shape = Shape.Diamond;

            dnode.GeometryNode.BoundaryCurve = NodeBoundaryCurves.GetNodeBoundaryCurve(dnode, 15, 12);


            //vnode.Invalidate();

            var edge = GVH.addLineEdge2(gv, "A", "B");

            //edge.Edge.DrawEdgeDelegate = edge_rendering_delegate;
            edge.Edge.UserData = "center_of";
            GVH.addNode(gv, "55", 0, 0);
            GVH.addLineEdge2(gv, "B", "55");
            graph.GeometryGraph.UpdateBoundingBox();
            //DebugV.D.tag = 1;

            gv.SetInitialTransform();
            gv.Transform = gv.Transform;

            gv.LayoutEditor.ObjectEditingStatusChanged += viewerObjectSelected;

            //timer1 = new System.Windows.Threading.DispatcherTimer();
            //timer1.Tick += TimeTick;
            //timer1.Interval = TimeSpan.FromMilliseconds(500);
            //timer1.Start();
            panel.Focusable = true;
        }
        void UpdateLayeredLayoutWithComp()
        {
            var scene = UIManager.Instance().GetScene();

            Graph graph = new Graph();

            var itemDict = scene.GetItemDict();
            var edgeDict = scene.GetEdgeDict();

            foreach (var item in itemDict)
            {
                var node = graph.AddNode(item.Key);
            }
            foreach (var edge in edgeDict)
            {
                var key = edge.Key;
                graph.AddEdge(key.Item1, key.Item2);
            }
            graph.Attr.LayerDirection = LayerDirection.LR;
            graph.CreateGeometryGraph();
            var layerSetting = graph.LayoutAlgorithmSettings as SugiyamaLayoutSettings;

            if (layerSetting != null)
            {
                layerSetting.LayerSeparation = 120;
                layerSetting.NodeSeparation  = 5;
            }
            foreach (var msaglNode in graph.GeometryGraph.Nodes)
            {
                var    node      = (Microsoft.Msagl.Drawing.Node)msaglNode.UserData;
                var    sceneNode = itemDict[node.Id];
                double radius    = sceneNode.GetRadius();
                double width     = sceneNode.GetWidth();
                double height    = sceneNode.GetHeight();
                msaglNode.BoundaryCurve = NodeBoundaryCurves.GetNodeBoundaryCurve(node, width, height);
            }
            Microsoft.Msagl.Miscellaneous.LayoutHelpers.CalculateLayout(graph.GeometryGraph, graph.LayoutAlgorithmSettings, new Microsoft.Msagl.Core.CancelToken());

            foreach (var msaglNode in graph.GeometryGraph.Nodes)
            {
                var    node      = (Microsoft.Msagl.Drawing.Node)msaglNode.UserData;
                var    nodeBegin = node.Pos.Y - node.Height * 0.5;
                var    sceneNode = itemDict[node.Id];
                double radius    = sceneNode.GetRadius();
                double width     = sceneNode.GetWidth();
                double height    = sceneNode.GetHeight();
                var    pos       = node.Pos;
                sceneNode.SetTargetPos(new Point(pos.X, nodeBegin + radius));
            }
        }
Example #15
0
        public static IViewerNode addNode(GraphViewer gv, string id, double x, double y)
        {
            //var node = new Node(id);
            var graph     = gv.Graph;
            var node      = graph.AddNode(id);
            var lnode     = GeometryGraphCreator.CreateGeometryNode(graph, graph.GeometryGraph, node, ConnectionToGraph.Disconnected);
            var labelSize = Common.MeasureLabel(node.Label);

            lnode.BoundaryCurve = NodeBoundaryCurves.GetNodeBoundaryCurve(node, labelSize.Width, labelSize.Height);
            node.GeometryNode   = lnode;
            var vnode = gv.CreateIViewerNode(node, new DPoint(x, y), null);

            return(vnode);
            //gv.AddNode(vnode, true);
            //gv.CreateVNode(node);
        }
Example #16
0
        public static IViewerNode addVnodeByDnode(GraphViewer gv, Node node, DPoint pos)
        {
            var graph = gv.Graph;

            Debug.Assert(node.GeometryNode == null);
            LNode lnode     = GeometryGraphCreator.CreateGeometryNode(graph, graph.GeometryGraph, node, ConnectionToGraph.Disconnected);
            var   labelSize = Common.MeasureLabel(node.Label);
            var   mar       = node.Attr.LabelMargin;

            lnode.BoundaryCurve = NodeBoundaryCurves.GetNodeBoundaryCurve(node, labelSize.Width + mar * 2, labelSize.Height + mar * 2);
            node.GeometryNode   = lnode;

            var vnode = gv.CreateIViewerNode(node, pos, null);

            return(vnode);
        }
Example #17
0
        private static ICurve GetNodeBoundary(DrawingNode node)
        {
            double width;
            double height;
            var    font = new Font(node.Label.FontName, (float)node.Label.FontSize, (System.Drawing.FontStyle)(int) node.Label.FontStyle);

            StringMeasure.MeasureWithFont(node.Label.Text, font, out width, out height);
            width  += node.Attr.LabelMargin * 2;
            height += node.Attr.LabelMargin * 2;
            if (width <= 0)
            {
                // Temporary fix for Win7 where Measure fonts return negative length for the string " ".
                StringMeasure.MeasureWithFont("a", font, out width, out height);
            }

            if ((node.UserData as NodeDisplaySettings).Icon != null)
            {
                width += kIconSize;
            }

            return(NodeBoundaryCurves.GetNodeBoundaryCurve(node, width, height));
        }
Example #18
0
        public static IViewerNode addNodeWithStyles(GraphViewer gv, string id, DPoint pos, ICollection <Style> styles)
        {
            var graph = gv.Graph;
            var node  = graph.AddNode(id);

            if (styles != null)
            {
                foreach (var s in styles)
                {
                    node.Attr.AddStyle(s);
                }
            }

            var lnode     = GeometryGraphCreator.CreateGeometryNode(graph, graph.GeometryGraph, node, ConnectionToGraph.Disconnected);
            var labelSize = Common.MeasureLabel(node.Label);
            var mar       = node.Attr.LabelMargin;

            lnode.BoundaryCurve = NodeBoundaryCurves.GetNodeBoundaryCurve(node, labelSize.Width + mar * 2, labelSize.Height + mar * 2);
            node.GeometryNode   = lnode;
            var vnode = gv.CreateIViewerNode(node, pos, null);

            return(vnode);
        }
        void UpdateLayeredLayoutWithComp()
        {
            var scene = UIManager.Instance().GetScene();

            Graph graph = new Graph();

            var itemDict          = scene.GetItemDict();
            var edgeDict          = scene.GetEdgeDict();
            var nodeDict          = new Dictionary <string, Node>();
            var edgeOrderDict     = new Dictionary <string, List <EdgeOrderData> >(); // store edge order
            var bookmarkOrderDict = new Dictionary <string, List <EdgeOrderData> >();

            foreach (var item in itemDict)
            {
                var node = graph.AddNode(item.Key);
                nodeDict[item.Key] = node;
            }
            foreach (var edge in edgeDict)
            {
                var key     = edge.Key;
                var edgeObj = edge.Value;
                graph.AddEdge(key.Item1, key.Item2);
                if (!edgeOrderDict.ContainsKey(key.Item1))
                {
                    edgeOrderDict[key.Item1] = new List <EdgeOrderData>();
                }
                if (edgeObj.OrderData != null && edgeObj.OrderData.m_order > 0)
                {
                    var node = nodeDict[key.Item2];
                    edgeOrderDict[key.Item1].Add(new EdgeOrderData(node, edgeObj.OrderData.m_order));
                }

                var srcNode = itemDict[key.Item1];
                if (srcNode.GetKind() == DoxygenDB.EntKind.PAGE)
                {
                    var node = nodeDict[key.Item1];

                    if (!bookmarkOrderDict.ContainsKey(key.Item2))
                    {
                        bookmarkOrderDict[key.Item2] = new List <EdgeOrderData>();
                    }

                    var  srcMetric = srcNode.GetMetric();
                    var  file      = srcMetric["file"].m_string;
                    var  line      = srcMetric["line"].m_int;
                    long order     = (file.GetHashCode() & 0x7fff0000) + line;
                    bookmarkOrderDict[key.Item2].Add(new EdgeOrderData(node, (int)order));
                }
            }
            // Sort edge order
            foreach (var item in edgeOrderDict)
            {
                item.Value.Sort((x, y) => x.m_order.CompareTo(y.m_order));
            }
            foreach (var item in bookmarkOrderDict)
            {
                item.Value.Sort((x, y) => x.m_order.CompareTo(y.m_order));
            }
            graph.Attr.LayerDirection = LayerDirection.LR;
            graph.CreateGeometryGraph();

            // Set graph settings
            var layerSetting = graph.LayoutAlgorithmSettings as SugiyamaLayoutSettings;

            if (layerSetting != null)
            {
                layerSetting.LayerSeparation = 120;
                layerSetting.NodeSeparation  = 4;
                foreach (var orderItem in edgeOrderDict)
                {
                    var orderList = orderItem.Value;
                    for (int ithOrder = 0; ithOrder < orderList.Count - 1; ithOrder++)
                    {
                        var prevNode = orderList[ithOrder].m_node.GeometryNode;
                        var nextNode = orderList[ithOrder + 1].m_node.GeometryNode;
                        layerSetting.AddLeftRightConstraint(prevNode, nextNode);
                    }
                }
                foreach (var orderItem in bookmarkOrderDict)
                {
                    var orderList = orderItem.Value;
                    for (int ithOrder = 0; ithOrder < orderList.Count - 1; ithOrder++)
                    {
                        var prevNode = orderList[ithOrder].m_node.GeometryNode;
                        var nextNode = orderList[ithOrder + 1].m_node.GeometryNode;
                        layerSetting.AddLeftRightConstraint(prevNode, nextNode);
                    }
                }
            }
            foreach (var msaglNode in graph.GeometryGraph.Nodes)
            {
                var    node      = (Microsoft.Msagl.Drawing.Node)msaglNode.UserData;
                var    sceneNode = itemDict[node.Id];
                double radius    = sceneNode.GetRadius();
                double width     = sceneNode.GetWidth();
                double height    = sceneNode.GetHeight();
                msaglNode.BoundaryCurve = NodeBoundaryCurves.GetNodeBoundaryCurve(node, width, height);
            }
            Microsoft.Msagl.Miscellaneous.LayoutHelpers.CalculateLayout(graph.GeometryGraph, graph.LayoutAlgorithmSettings, new Microsoft.Msagl.Core.CancelToken());

            foreach (var msaglNode in graph.GeometryGraph.Nodes)
            {
                var    node      = (Microsoft.Msagl.Drawing.Node)msaglNode.UserData;
                var    nodeBegin = node.Pos.Y - node.Height * 0.5;
                var    sceneNode = itemDict[node.Id];
                double radius    = sceneNode.GetRadius();
                double width     = sceneNode.GetWidth();
                double height    = sceneNode.GetHeight();
                var    pos       = node.Pos;
                sceneNode.SetTargetPos(new Point(pos.X, nodeBegin + radius));
            }
        }