/// <summary> /// Creates a VerticalSeparationConstraint for each edge in the given set to structural constraints, /// to require these edges to be downward pointing. Also checks for cycles, and edges involved /// in a cycle receive no VerticalSeparationConstraint, but can optionally receive a circle constraint. /// </summary> /// <param name="edges"></param> /// <param name="settings"></param> /// <param name="horizontalSolver"></param> /// <param name="verticalSolver"></param> internal static void GenerateEdgeConstraints( IEnumerable <Edge> edges, IdealEdgeLengthSettings settings, AxisSolver horizontalSolver, AxisSolver verticalSolver) { if (settings.EdgeDirectionConstraints == Directions.None) { return; } EdgeConstraintGenerator g = new EdgeConstraintGenerator(edges, settings, horizontalSolver, verticalSolver); g.GenerateSeparationConstraints(); }
/// <summary> /// Creates a VerticalSeparationConstraint for each edge in the given set to structural constraints, /// to require these edges to be downward pointing. Also checks for cycles, and edges involved /// in a cycle receive no VerticalSeparationConstraint, but can optionally receive a circle constraint. /// </summary> /// <param name="edges"></param> /// <param name="settings"></param> /// <param name="horizontalSolver"></param> /// <param name="verticalSolver"></param> internal static void GenerateEdgeConstraints( IEnumerable <Edge> edges, IdealEdgeLengthSettings settings, AxisSolver horizontalSolver, AxisSolver verticalSolver) { if (settings.EdgeDirectionConstraints == Directions.None) { return; } EdgeConstraintGenerator g = new EdgeConstraintGenerator(edges, settings, horizontalSolver, verticalSolver); g.GenerateSeparationConstraints(); // we have in the past used Circular constraints to better show cycles... it's a little experimental though // so it's not currently enabled //foreach (var c in g.CyclicComponents) { // constraints.Add(new ProcrustesCircleConstraint(c)); //} }
internal EdgeConstraintGenerator( IEnumerable <Edge> edges, IdealEdgeLengthSettings settings, AxisSolver horizontalSolver, AxisSolver verticalSolver) { // filter out self edges this.edges = edges.Where(e => e.Source != e.Target); this.settings = settings; this.horizontalSolver = horizontalSolver; this.verticalSolver = verticalSolver; foreach (var e in this.edges) { TNode u = CreateTNode(e.Source), v = CreateTNode(e.Target); u.outNeighbours.Add(v); v.inNeighbours.Add(u); } foreach (var v in nodeMap.Values) { if (v.stackNode == null) { DFS(v); } } while (stack.Count > 0) { component = new List <TNode>(); RDFS(stack.Last.Value); if (component.Count > 1) { var cyclicComponent = new Set <Node>(); foreach (var v in component) { cyclicComponent.Insert(v.v); } cyclicComponents.Add(cyclicComponent); } } switch (settings.EdgeDirectionConstraints) { case Directions.South: this.addConstraint = this.AddSConstraint; break; case Directions.North: this.addConstraint = this.AddNConstraint; break; case Directions.West: this.addConstraint = this.AddWConstraint; break; case Directions.East: this.addConstraint = this.AddEConstraint; break; } }