Routing only edges with MSAGL

1.4k Views Asked by At

Is there a way to route only edges in existing layout with MSAGL?

I have a GeometryGraph object with layout generated using LayeredLayout and I want to remove/add edges without running the layout algorithm again (this operation makes drastic changes to node positions and is confusing to end user).

Can I somehow simply run layout again with all node positions fixed?

3

There are 3 best solutions below

0
On BEST ANSWER

You need to keep InteractiveEdgeRouter in sync with your graph:

edgeRouter_ = new InteractiveEdgeRouter(Graph.Nodes.Select(n => n.BoundaryCurve), 3, 0.65 * 3, 0);

Every recalc of graph layout should also call edgeRouter_.Run() to keep it in sync with obstacle changes (you should add new nodes as well).

After you added new edge, instead of calculating layout again, set the edge curve manually using the router:

 private void RouteMissingEdges()
 {
     foreach (var edge in Graph.Edges)
     {
         if (edge.Curve == null)
         {
             SmoothedPolyline ignore;

             edge.Curve = edgeRouter_.RouteSplineFromPortToPortWhenTheWholeGraphIsReady(
                 new FloatingPort(edge.Source.BoundaryCurve, edge.Source.Center),
                 new FloatingPort(edge.Target.BoundaryCurve, edge.Target.Center),
                 true, out ignore);

             Arrowheads.TrimSplineAndCalculateArrowheads(edge.EdgeGeometry,
                                             edge.Source.BoundaryCurve,
                                             edge.Target.BoundaryCurve,
                                             edge.Curve, true,
                                             false);

         }
     }
}
1
On

Use can use LayoutHelpers.RouteAndLabelEdges:

LayoutAlgorithmSettings settings = new MdsLayoutSettings();
RouteAndLabelEdges(geometryGraph, settings, geometryGraph.Edges);

It is shorter than ghord's solution but requires more calculations.

0
On

I discovered that it can be done in an even simpler way, which I have tried, and it has worked for me.

This appears to be the "just route, please" way:

var rectRouter = new RectilinearEdgeRouter( graph, 10, 0, true );
rectRouter.Run();

No need to involve LayoutAlgorithmSettings since we are not doing layout, and no need for an InteractiveEdgeRouter if we are not doing anything interactively; just instantiate a RectilinearEdgeRouter and Run it.