public override void ApplyLayout(LayoutGraph graph) { // determine the single node to keep at the center. var provider = graph.GetDataProvider("NodeLayouts"); Node centerNode = null; if (provider != null) { centerNode = graph.Nodes.FirstOrDefault(n => provider.Get(n) != null); } if (CoreLayout != null) { if (centerNode != null) { // remember old center RectD oldLayout = (RectD)provider.Get(centerNode); var fixedLocation = new YPoint(graph.GetX(centerNode) + graph.GetWidth(centerNode), graph.GetY(centerNode)); //Set to saved size (this is important for collapsed nodes to ensure correct size) graph.SetSize(centerNode, oldLayout.Width, oldLayout.Height); // run layout CoreLayout.ApplyLayout(graph); // obtain new center var newFixedLocation = new YPoint(graph.GetX(centerNode) + graph.GetWidth(centerNode), graph.GetY(centerNode)); // and adjust the layout LayoutGraphUtilities.MoveSubgraph(graph, graph.GetNodeCursor(), fixedLocation.X - newFixedLocation.X, fixedLocation.Y - newFixedLocation.Y); } else { CoreLayout.ApplyLayout(graph); } } }
/// <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); } }