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.");
        }
示例#3
0
        /// <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);
        }
示例#4
0
        /// <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);
        }
示例#5
0
        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
            
        }
示例#7
0
        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;
        }
示例#10
0
        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;
        }
示例#11
0
        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;
        }