/// <summary>
        /// Adjusts the edge end points so they don't end outside the shape of the node they are attached to.
        /// </summary>
        private static void AdjustPortLocation(LayoutGraph graph, Edge e, YPointPath path, bool atSource)
        {
            Node   node     = atSource ? e.Source : e.Target;
            YPoint pointRel = atSource ? graph.GetSourcePointRel(e) : graph.GetTargetPointRel(e);
            // get offset from the node center to the end of the shape at the node side the edge connects to
            LineSegment segment = path.GetLineSegment(atSource ? 0 : path.Length() - 2);
            double      offset  = Math.Min(graph.GetWidth(node), graph.GetHeight(node)) / 2;
            double      offsetX = segment.DeltaX > 0 ^ atSource ? -offset : offset;
            double      offsetY = segment.DeltaY > 0 ^ atSource ? -offset : offset;
            // if the edge end point is at the center of this side, we use the calculated offset to put the end point on
            // the node bounds, otherwise we prolong the last segment to the center line of the node so it doesn't end
            // outside the node's shape
            YPoint newPortLocation = segment.IsHorizontal
        ? new YPoint(pointRel.Y != 0 ? 0 : offsetX, pointRel.Y)
        : new YPoint(pointRel.X, pointRel.X != 0 ? 0 : offsetY);

            if (atSource)
            {
                graph.SetSourcePointRel(e, newPortLocation);
            }
            else
            {
                graph.SetTargetPointRel(e, newPortLocation);
            }
        }
        /// <inheritdoc/>
        public void ApplyLayout(LayoutGraph graph)
        {
            var affectedNodesDP = graph.GetDataProvider(AffectedNodesDpKey);

            for (IEdgeCursor ec = graph.GetEdgeCursor(); ec.Ok; ec.Next())
            {
                Edge       e    = ec.Edge;
                YPointPath path = graph.GetPath(e);
                //adjust source point
                if (affectedNodesDP == null || affectedNodesDP.GetBool(e.Source))
                {
                    AdjustPortLocation(graph, e, path, true);
                }
                if (affectedNodesDP == null || affectedNodesDP.GetBool(e.Target))
                {
                    AdjustPortLocation(graph, e, path, false);
                }
            }
        }
예제 #3
0
        public override void ApplyLayout(LayoutGraph graph)
        {
            ApplyLayoutCore(graph);

            foreach (Node n in graph.Nodes)
            {
                foreach (Edge e in n.OutEdges)
                {
                    bool        lastSegmentOverlap = false;
                    IEdgeLayout er = graph.GetLayout(e);
                    if (er.PointCount() > 0)
                    {
                        // last bend point
                        YPoint bendPoint = er.GetPoint(er.PointCount() - 1);

                        IEnumerator <Edge> ecc = n.OutEdges.GetEnumerator();
                        loop : while (ecc.MoveNext())
                        {
                            Edge eccEdge = ecc.Current;
                            if (eccEdge != e)
                            {
                                YPointPath path = graph.GetPath(eccEdge);
                                for (ILineSegmentCursor lc = path.LineSegments(); lc.Ok; lc.Next())
                                {
                                    LineSegment seg = lc.LineSegment;
                                    if (seg.Contains(bendPoint))
                                    {
                                        lastSegmentOverlap = true;
                                        goto loop;
                                    }
                                }
                            }
                        }
                    }


                    YList points = graph.GetPointList(e);
                    for (ListCell c = points.FirstCell; c != null; c = c.Succ())
                    {
                        YPoint p = (YPoint)c.Info;
                        if (c.Succ() == null && !lastSegmentOverlap)
                        {
                            break;
                        }

                        YPoint p0 = (YPoint)(c.Pred() == null ? graph.GetSourcePointAbs(e) : c.Pred().Info);
                        YPoint p2;
                        if (Math.Abs(p0.X - p.X) < 0.01)
                        {
                            p2 = new YPoint(p.X, p.Y - 0.001);
                        }
                        else
                        {
                            p2 = new YPoint(p.X - 0.001, p.Y);
                        }

                        points.InsertBefore(p2, c);
                    }
                    graph.SetPoints(e, points);
                }
            }
        }