public void IsDescendantOf_ManyParents() { Cluster grandMother = new Cluster(); Cluster grandFather = new Cluster(); Cluster parent = new Cluster(); Cluster uncle = new Cluster(); grandMother.AddChild(parent); grandMother.AddChild(uncle); grandFather.AddChild(parent); grandFather.AddChild(uncle); Node child = new Node(); parent.AddChild(child); Assert.IsTrue(child.IsDescendantOf(parent), "The child node should be considered a descendant of its parent."); Assert.IsTrue(child.IsDescendantOf(grandMother), "The child node should be considered a descendant of its grandmother."); Assert.IsTrue(child.IsDescendantOf(grandFather), "The child node should be considered a descendant of its grandfather."); Assert.IsFalse(child.IsDescendantOf(uncle), "The child node should not be considered a descendant of its uncle."); }
public void IsDescendantOf_BasicTest() { Cluster cluster = new Cluster(); Node node = new Node(); Node node2 = new Node(); cluster.AddChild(node); Assert.IsTrue(node.IsDescendantOf(cluster), "Node is a descendant of cluster but IsDescendantOf returns false."); Assert.IsFalse(node2.IsDescendantOf(cluster), "Node2 is not a descendant of cluster but IsDescendantOf returns true."); Assert.IsFalse(cluster.IsDescendantOf(cluster), "A cluster should not be considered a descendant of itself."); }
/// <summary> /// Create deep copy of Cluster hierarchy, where the nodes are already assumed to have been copied and loaded into the original nodes' AlgorithmData /// </summary> /// <param name="top">the source whose copy will become the new top of the cluster hierarchy</param> /// <param name="index">node counter index to use and increment as we add new Cluster nodes</param> /// <returns>Deep copy of cluster hierarchy</returns> static Cluster CopyCluster(Cluster top, ref int index) { var copy = new Cluster(from v in top.Nodes select GetCopy(v)) { UserData = top, RectangularBoundary = top.RectangularBoundary, BoundaryCurve = top.BoundaryCurve.Clone(), CollapsedBoundary = top.CollapsedBoundary == null?null:top.CollapsedBoundary.Clone() }; top.AlgorithmData = new AlgorithmDataNodeWrap(index++, copy); foreach (var c in top.Clusters) { copy.AddChild(CopyCluster(c, ref index)); } return(copy); }
/// <summary> /// Extension method to break a GeometryGraph into connected components taking into consideration clusters. /// Leaves the original graph intact, the resultant components contain copies of the original elements, with /// the original elements referenced in their UserData properties. /// </summary> /// <returns> /// the set of components, each as its own GeometryGraph. /// </returns> public static IEnumerable <GeometryGraph> GetClusteredConnectedComponents(this GeometryGraph graph) { var flatGraph = FlatGraph(graph); var basicFlatGraph = new BasicGraph <AlgorithmDataEdgeWrap>( from e in flatGraph.Edges select(AlgorithmDataEdgeWrap) e.AlgorithmData, flatGraph.Nodes.Count); var nodes = flatGraph.Nodes.ToList(); var graphComponents = new List <GeometryGraph>(); foreach ( var componentNodes in ConnectedComponentCalculator <AlgorithmDataEdgeWrap> .GetComponents(basicFlatGraph)) { var g = new GeometryGraph(); var topClusters = new List <Cluster>(); var topNodes = new List <Node>(); foreach (int i in componentNodes) { var v = nodes[i]; var original = (Node)v.UserData; bool topLevel = ((AlgorithmDataNodeWrap)original.AlgorithmData).TopLevel; if (v.UserData is Cluster) { if (topLevel) { topClusters.Add((Cluster)original); } } else { // clear edges, we fix them up below v.ClearEdges(); g.Nodes.Add(v); if (topLevel) { topNodes.Add(v); } } } // copy the cluster hierarchies from the original graph int index = g.Nodes.Count; if (topClusters.Count != 0) { var root = new Cluster(topNodes); foreach (var top in topClusters) { root.AddChild(CopyCluster(top, ref index)); } g.RootCluster = root; } // add the real edges from the original graph to the component graph foreach (var v in g.GetFlattenedNodesAndClusters()) { var original = v.UserData as Node; Debug.Assert(original != null); foreach (var e in original.InEdges) { var source = GetCopy(e.Source); var target = GetCopy(e.Target); var copy = new Edge(source, target) { Length = e.Length, UserData = e, EdgeGeometry = e.EdgeGeometry }; e.AlgorithmData = copy; g.Edges.Add(copy); } } graphComponents.Add(g); } return(graphComponents); }
static GeometryGraph GetTestGraphWithClusters(out LayoutAlgorithmSettings settings) { GeometryGraph graph = GeometryGraphReader.CreateFromFile( "C:\\dev\\GraphLayout\\MSAGLTests\\Resources\\MSAGLGeometryGraphs\\abstract.msagl.geom", //"E:\\dev\\MSAGL\\GraphLayout\\MSAGLTests\\Resources\\MSAGLGeometryGraphs\\abstract.msagl.geom", out settings); foreach (var edge in graph.Edges) { edge.Curve = null; edge.EdgeGeometry.TargetArrowhead = null; } graph.UpdateBoundingBox(); var root = graph.RootCluster; var a = new Cluster {UserData = "a"}; foreach (string id in new[] {"17", "39", "13", "19", "28", "12"}) a.AddChild(graph.FindNodeByUserData(id)); var b = new Cluster {UserData = "b"}; b.AddChild(a); b.AddChild(graph.FindNodeByUserData("18")); root.AddChild(b); var c = new Cluster {UserData = "c"}; foreach (string id in new[] {"30", "5", "6", "7", "8"}) c.AddChild(graph.FindNodeByUserData(id)); root.AddChild(c); var clusterNodes = new Set<Node>(root.AllClustersDepthFirst().SelectMany(cl => cl.Nodes)); foreach (var node in graph.Nodes.Where(n => clusterNodes.Contains(n) == false)) root.AddChild(node); FixClusterBoundariesWithNoRectBoundaries(root, 5); var fastIncrementalLayoutSettings = new FastIncrementalLayoutSettings(); var d=new Dictionary<Cluster, LayoutAlgorithmSettings>(); d[root] = new FastIncrementalLayoutSettings { AvoidOverlaps = true }; var initialLayout = new InitialLayoutByCluster(graph, fastIncrementalLayoutSettings); initialLayout.Run(); graph.UpdateBoundingBox(); //FixClusterBoundariesWithNoRectBoundaries(root, 5); return graph; }
public void RoutingWithThreeGroups() { var graph = LoadGraph("abstract.msagl.geom"); var root = graph.RootCluster; var a = new Cluster { UserData = "a" }; foreach (string id in new[] { "17", "39", "13", "19", "28", "12" }) a.AddChild(graph.FindNodeByUserData(id)); var b = new Cluster { UserData = "b" }; b.AddChild(a); b.AddChild(graph.FindNodeByUserData("18")); root.AddChild(b); var c = new Cluster { UserData = "c" }; foreach (string id in new[] { "30", "5", "6", "7", "8" }) c.AddChild(graph.FindNodeByUserData(id)); root.AddChild(c); var clusterNodes = new Set<Node>(root.AllClustersDepthFirst().SelectMany(cl => cl.Nodes)); foreach (var node in graph.Nodes.Where(n => clusterNodes.Contains(n) == false)) root.AddChild(node); FixClusterBoundariesWithNoRectBoundaries(root, 5); var defaultSettings = new FastIncrementalLayoutSettings(); var rootSettings = new FastIncrementalLayoutSettings() { AvoidOverlaps = true }; var initialLayout = new InitialLayoutByCluster(graph, new[] { graph.RootCluster }, cl => cl == root ? rootSettings : defaultSettings); initialLayout.Run(); const double Padding = 5; SplineRouter splineRouter = new SplineRouter(graph, Padding/3, Padding, Math.PI / 6); splineRouter.Run(); #if TEST_MSAGL if (!DontShowTheDebugViewer()) { graph.UpdateBoundingBox(); DisplayGeometryGraph.ShowGraph(graph); } #endif }
static void FillClustersAndSettings(FastIncrementalLayoutSettings settings, GeometryGraph geometryGraph) { settings.AvoidOverlaps = true; // settings.RectangularClusters = true; var root = new Cluster(); var cluster = new Cluster(); root.AddChild(cluster); for (int i = 0; i < 4; i++) { var istring = i.ToString(); cluster.AddChild(geometryGraph.Nodes.First(n => n.UserData.ToString() == istring)); } cluster.BoundaryCurve = cluster.BoundingBox.Perimeter(); cluster = new Cluster(); root.AddChild(cluster); geometryGraph.RootCluster.AddChild(root); //make a subcluster var parent = cluster; cluster = new Cluster(); cluster.AddChild(geometryGraph.Nodes.First(n => n.UserData.ToString() == "4")); cluster.AddChild(geometryGraph.Nodes.First(n => n.UserData.ToString() == "5")); parent.AddChild(cluster); cluster = new Cluster(); for (int i = 6; i < 9; i++) { var istring = i.ToString(); cluster.AddChild(geometryGraph.Nodes.First(n => n.UserData.ToString() == istring)); } parent.AddChild(cluster); foreach (var cl in geometryGraph.RootCluster.AllClustersDepthFirst()) { if(cl.BoundaryCurve==null) cl.BoundaryCurve=cl.BoundingBox.Perimeter(); } }
/// <summary> /// Create deep copy of Cluster hierarchy, where the nodes are already assumed to have been copied and loaded into the original nodes' AlgorithmData /// </summary> /// <param name="top">the source whose copy will become the new top of the cluster hierarchy</param> /// <param name="index">node counter index to use and increment as we add new Cluster nodes</param> /// <returns>Deep copy of cluster hierarchy</returns> static Cluster CopyCluster(Cluster top, ref int index) { var copy = new Cluster(from v in top.Nodes select GetCopy(v)) { UserData = top, RectangularBoundary = top.RectangularBoundary, BoundaryCurve = top.BoundaryCurve.Clone(), CollapsedBoundary=top.CollapsedBoundary==null?null:top.CollapsedBoundary.Clone() }; top.AlgorithmData = new AlgorithmDataNodeWrap(index++, copy); foreach (var c in top.Clusters) copy.AddChild(CopyCluster(c, ref index)); return copy; }
/// <summary> /// Extension method to break a GeometryGraph into connected components taking into consideration clusters. /// Leaves the original graph intact, the resultant components contain copies of the original elements, with /// the original elements referenced in their UserData properties. /// </summary> /// <returns> /// the set of components, each as its own GeometryGraph. /// </returns> public static IEnumerable<GeometryGraph> GetClusteredConnectedComponents(this GeometryGraph graph) { var flatGraph = FlatGraph(graph); var basicFlatGraph = new BasicGraph<AlgorithmDataEdgeWrap>( from e in flatGraph.Edges select (AlgorithmDataEdgeWrap) e.AlgorithmData, flatGraph.Nodes.Count); var nodes = flatGraph.Nodes.ToList(); var graphComponents = new List<GeometryGraph>(); foreach ( var componentNodes in ConnectedComponentCalculator<AlgorithmDataEdgeWrap>.GetComponents(basicFlatGraph)) { var g = new GeometryGraph(); var topClusters = new List<Cluster>(); var topNodes = new List<Node>(); foreach (int i in componentNodes) { var v = nodes[i]; var original = (Node) v.UserData; bool topLevel = ((AlgorithmDataNodeWrap) original.AlgorithmData).TopLevel; if (v.UserData is Cluster) { if (topLevel) { topClusters.Add((Cluster) original); } } else { // clear edges, we fix them up below v.ClearEdges(); g.Nodes.Add(v); if (topLevel) { topNodes.Add(v); } } } // copy the cluster hierarchies from the original graph int index = g.Nodes.Count; if (topClusters.Count != 0) { var root = new Cluster(topNodes); foreach (var top in topClusters) { root.AddChild(CopyCluster(top, ref index)); } g.RootCluster = root; } // add the real edges from the original graph to the component graph foreach (var v in g.GetFlattenedNodesAndClusters()) { var original = v.UserData as Node; Debug.Assert(original != null); foreach (var e in original.InEdges) { var source = GetCopy(e.Source); var target = GetCopy(e.Target); var copy = new Edge(source, target) { Length = e.Length, UserData = e, EdgeGeometry = e.EdgeGeometry }; e.AlgorithmData = copy; g.Edges.Add(copy); } } graphComponents.Add(g); } return graphComponents; }
public static GeometryGraph Create() { GeometryGraph graph = new GeometryGraph(); var nodeA0 = new Node(); graph.Nodes.Add(nodeA0); var nodeA1 = new Node(); graph.Nodes.Add(nodeA1); var nodeA2 = new Node(); graph.Nodes.Add(nodeA2); var nodeA3 = new Node(); graph.Nodes.Add(nodeA3); var edgeA0A1 = new Edge(nodeA0, nodeA1); edgeA0A1.EdgeGeometry = new EdgeGeometry() { TargetArrowhead = new Arrowhead() }; nodeA0.AddOutEdge(edgeA0A1); nodeA1.AddInEdge(edgeA0A1); graph.Edges.Add(edgeA0A1); var edgeA0A2 = new Edge(nodeA0, nodeA2); edgeA0A2.EdgeGeometry = new EdgeGeometry() { TargetArrowhead = new Arrowhead() }; nodeA0.AddOutEdge(edgeA0A2); nodeA2.AddInEdge(edgeA0A2); graph.Edges.Add(edgeA0A2); var edgeA2A1 = new Edge(nodeA2, nodeA1); edgeA2A1.EdgeGeometry = new EdgeGeometry() { TargetArrowhead = new Arrowhead() }; nodeA2.AddOutEdge(edgeA2A1); nodeA1.AddInEdge(edgeA2A1); graph.Edges.Add(edgeA2A1); var edgeA0A3 = new Edge(nodeA0, nodeA3); edgeA0A3.EdgeGeometry = new EdgeGeometry() { TargetArrowhead = new Arrowhead() }; nodeA0.AddOutEdge(edgeA0A3); nodeA3.AddInEdge(edgeA0A3); graph.Edges.Add(edgeA0A3); graph.RootCluster.AddChild(nodeA0); graph.RootCluster.AddChild(nodeA3); var cluster = new Cluster(); graph.RootCluster.AddChild(cluster); cluster.AddChild(nodeA1); cluster.AddChild(nodeA2); // This is where I add the edge connecting to a cluster. var edgeA0cluster = new Edge(nodeA0, cluster); edgeA0cluster.EdgeGeometry = new EdgeGeometry() { TargetArrowhead = new Arrowhead() }; nodeA0.AddOutEdge(edgeA0cluster); cluster.AddInEdge(edgeA0cluster); graph.Edges.Add(edgeA0cluster); var nodeA01 = new Node(); graph.Nodes.Add(nodeA01); graph.RootCluster.AddChild(nodeA01); var nodeA02 = new Node(); graph.Nodes.Add(nodeA02); graph.RootCluster.AddChild(nodeA02); var nodeA03 = new Node(); graph.Nodes.Add(nodeA03); graph.RootCluster.AddChild(nodeA03); var edgeA0A01 = new Edge(nodeA0, nodeA01); edgeA0A01.EdgeGeometry = new EdgeGeometry() { TargetArrowhead = new Arrowhead() }; nodeA0.AddOutEdge(edgeA0A01); nodeA01.AddInEdge(edgeA0A01); graph.Edges.Add(edgeA0A01); var edgeA01A02 = new Edge(nodeA01, nodeA02); edgeA01A02.EdgeGeometry = new EdgeGeometry() { TargetArrowhead = new Arrowhead() }; nodeA01.AddOutEdge(edgeA01A02); nodeA02.AddInEdge(edgeA01A02); graph.Edges.Add(edgeA01A02); var edgeA02A03 = new Edge(nodeA02, nodeA03); edgeA02A03.EdgeGeometry = new EdgeGeometry() { TargetArrowhead = new Arrowhead() }; nodeA02.AddOutEdge(edgeA02A03); nodeA03.AddInEdge(edgeA02A03); graph.Edges.Add(edgeA02A03); return graph; }
public static GeometryGraph CreateSimple() { GeometryGraph graph = new GeometryGraph(); var nodeA0 = new Node(); graph.Nodes.Add(nodeA0); var nodeA1 = new Node(); graph.Nodes.Add(nodeA1); graph.RootCluster.AddChild(nodeA0); var cluster = new Cluster(); graph.RootCluster.AddChild(cluster); cluster.AddChild(nodeA1); // This is where I add the edge connecting to a cluster. var edgeA0cluster = new Edge(nodeA0, cluster); edgeA0cluster.EdgeGeometry = new EdgeGeometry() { TargetArrowhead = new Arrowhead() }; nodeA0.AddOutEdge(edgeA0cluster); cluster.AddInEdge(edgeA0cluster); graph.Edges.Add(edgeA0cluster); return graph; }