コード例 #1
0
        public void TestReadDotFile()
        {
            RootGraph root  = RootGraph.FromDotString(@"
digraph test {
    A;
    B;
    B -> B;
    A -> B[name = edgename];
    A -> B[name = edgename];
    A -> B[name = edgename];
}
");
            var       edges = root.Edges().ToList();
            var       names = edges.Select(e => e.GetName());

            // This results in ,,, strangely enough
            // There seems to be no way to influence the edge name from dot
            Console.WriteLine(string.Join(", ", names));

            // However, it is strange that all edges seem to have te same name, namely ""
            // According to the documentation, the name is used to distinguish between multiedges
            var A = root.GetNode("A");
            var B = root.GetNode("B");

            Assert.AreEqual(3, A.EdgesOut().Count());

            // The documentation seem to be correct for edges that are added through the C interface
            root.GetOrAddEdge(A, B, "");
            root.GetOrAddEdge(A, B, "");
            root.GetOrAddEdge(A, B, "");
            Assert.AreEqual(4, A.EdgesOut().Count());
        }
コード例 #2
0
        public void TestEdgesInSubgraphs()
        {
            RootGraph graph = Utils.CreateUniqueTestGraph();
            Node      node  = graph.GetOrAddNode("node");
            Edge      edge  = graph.GetOrAddEdge(node, node, "edge 1");

            SubGraph subgraph                = graph.GetOrAddSubgraph("sub graph");
            Node     subnode                 = subgraph.GetOrAddNode("subnode");
            Edge     subedge_between_node    = subgraph.GetOrAddEdge(node, node, "edge 2");
            Edge     subedge_between_subnode = subgraph.GetOrAddEdge(subnode, subnode, "edge 3");
            Edge     edge_between_subnode    = graph.GetOrAddEdge(subnode, subnode, "edge 4");

            Assert.True(graph.Contains(edge));
            Assert.True(graph.Contains(subedge_between_node));
            Assert.True(graph.Contains(subedge_between_subnode));
            Assert.True(graph.Contains(edge_between_subnode));

            Assert.False(subgraph.Contains(edge));
            Assert.True(subgraph.Contains(subedge_between_node));
            Assert.True(subgraph.Contains(subedge_between_subnode));
            Assert.False(subgraph.Contains(edge_between_subnode));

            // Conclusion:
            // Subgraphs can contain edges, independently of their endpoints.
            // This affects enumeration as follows:
            Assert.AreEqual(2, node.EdgesOut(graph).Count());
            Assert.AreEqual(1, node.EdgesOut(subgraph).Count());
            Assert.AreEqual(2, subnode.EdgesOut(graph).Count());
            Assert.AreEqual(1, subnode.EdgesOut(subgraph).Count());
        }
コード例 #3
0
        public void TestDeletions()
        {
            RootGraph root = Utils.CreateUniqueTestGraph();

            Node tail  = root.GetOrAddNode("1");
            Node head  = root.GetOrAddNode("2");
            Node other = root.GetOrAddNode("3");

            Edge edge    = root.GetOrAddEdge(tail, head, "edge");
            Edge tailout = root.GetOrAddEdge(tail, other, "tailout");
            Edge headout = root.GetOrAddEdge(head, other, "headout");
            Edge tailin  = root.GetOrAddEdge(other, tail, "tailin");
            Edge headin  = root.GetOrAddEdge(other, head, "headin");

            Assert.IsTrue(root.Equals(root.MyRootGraph));
            Assert.IsTrue(root.Equals(tail.MyRootGraph));
            Assert.IsTrue(root.Equals(edge.MyRootGraph));

            Assert.AreEqual(3, tail.TotalDegree());
            Assert.AreEqual(3, head.TotalDegree());
            Assert.AreEqual(3, root.Nodes().Count());

            root.Delete(edge);

            Assert.AreEqual(2, tail.TotalDegree());
            Assert.AreEqual(2, head.TotalDegree());
            Assert.AreEqual(3, root.Nodes().Count());

            root.Delete(tail);

            Assert.AreEqual(2, root.Nodes().Count());
            Assert.AreEqual(2, other.TotalDegree());
        }
コード例 #4
0
        public void StringEscaping()
        {
            RootGraph root = RootGraph.CreateNew("Graph with escaped strings", GraphType.Directed);

            Node.IntroduceAttribute(root, "label", "\\N");
            Node nodeA = root.GetOrAddNode("A");

            // Several characters and character sequences can have special meanings in labels, like \N.
            // When you want to have a literal string in a label, we provide a convenience function for you to do just that.
            nodeA.SetAttribute("label", CGraphThing.EscapeLabel("Some string literal \\N \\n |}>"));

            root.ComputeLayout();

            // When defining portnames, some characters, like ':' and '|', are not allowed and they can't be escaped either.
            // This can be troubling if you have an externally defined ID for such a port.
            // We provide a function that maps strings to valid portnames.
            var  somePortId    = "port id with :| special characters";
            var  validPortName = Edge.ConvertUidToPortName(somePortId);
            Node nodeB         = root.GetOrAddNode("B");

            nodeB.SafeSetAttribute("shape", "record", "");
            nodeB.SafeSetAttribute("label", $"<{validPortName}>1|2", "\\N");

            // The function makes sure different strings don't accidentally map onto the same portname
            Assert.That(Edge.ConvertUidToPortName(":"), Is.Not.EqualTo(Edge.ConvertUidToPortName("|")));
        }
コード例 #5
0
        public void GraphConstruction()
        {
            // You can programmatically construct graphs as follows
            RootGraph root = RootGraph.CreateNew("Some Unique Identifier", GraphType.Directed);

            // The node names are unique identifiers within a graph in Graphviz
            Node nodeA = root.GetOrAddNode("A");
            Node nodeB = root.GetOrAddNode("B");
            Node nodeC = root.GetOrAddNode("C");
            Node nodeD = root.GetOrAddNode("D");

            // The edge name is only unique between two nodes
            Edge edgeAB        = root.GetOrAddEdge(nodeA, nodeB, "Some edge name");
            Edge edgeBC        = root.GetOrAddEdge(nodeB, nodeC, "Some edge name");
            Edge anotherEdgeBC = root.GetOrAddEdge(nodeB, nodeC, "Another edge name");

            // We can attach attributes to nodes, edges and graphs to store information and instruct
            // graphviz by specifying layout parameters. At the moment we only support string
            // attributes. Cgraph assumes that all objects of a given kind (graphs/subgraphs, nodes,
            // or edges) have the same attributes. The attributes first have to be introduced for a
            // certain kind, before we can use it.
            Node.IntroduceAttribute(root, "my attribute", "defaultvalue");
            nodeA.SetAttribute("my attribute", "othervalue");

            // To introduce and set an attribute at the same time, there are convenience wrappers
            edgeAB.SafeSetAttribute("color", "red", "black");
            edgeBC.SafeSetAttribute("arrowsize", "2.0", "1.0");

            // We can simply export this graph to a text file in dot format
            root.ToDotFile(TestContext.CurrentContext.TestDirectory + "/out.dot");
        }
コード例 #6
0
        public void TestTopologicalEqualsCloneWithSubgraphs(int nodes, int degree)
        {
            var root          = CreateRandomConnectedGraph(nodes * SizeMultiplier, degree);
            var nodeSelection = new HashSet <Node>(root.Nodes().Take(nodes / 2));
            var sub           = root.AddSubgraphFromNodes("sub", nodeSelection);

            var subNodeCount   = sub.Nodes().Count();
            var nodeSelection2 = new HashSet <Node>(sub.Nodes().Take(subNodeCount / 2));
            var sub2           = root.AddSubgraphFromNodes("sub2", nodeSelection2);

            var edgeCount     = sub2.Edges().Count();
            var edgeSelection = new HashSet <Edge>(sub.Edges().Take(edgeCount / 2));
            var sub3          = root.AddSubgraphFromEdgeSet("sub3", edgeSelection);

            RootGraph subclone = sub.Clone("subclone");

            Assert.IsTrue(GraphComparer.CheckTopologicallyEquals(sub, subclone, Log));
            Assert.IsFalse(GraphComparer.CheckTopologicallyEquals(sub, root, Log));
            Assert.IsFalse(GraphComparer.CheckTopologicallyEquals(sub, sub2, Log));
            Assert.IsFalse(GraphComparer.CheckTopologicallyEquals(sub, sub3, Log));

            RootGraph sub2clone = sub2.Clone("sub2clone");

            Assert.IsTrue(GraphComparer.CheckTopologicallyEquals(sub2, sub2clone, Log));
            Assert.IsFalse(GraphComparer.CheckTopologicallyEquals(sub2, root, Log));
            Assert.IsFalse(GraphComparer.CheckTopologicallyEquals(sub2, sub, Log));
            Assert.IsFalse(GraphComparer.CheckTopologicallyEquals(sub2, sub3, Log));

            RootGraph sub3clone = sub3.Clone("sub3clone");

            Assert.IsTrue(GraphComparer.CheckTopologicallyEquals(sub3, sub3clone, Log));
            Assert.IsFalse(GraphComparer.CheckTopologicallyEquals(sub3, root, Log));
            Assert.IsFalse(GraphComparer.CheckTopologicallyEquals(sub3, sub, Log));
            Assert.IsFalse(GraphComparer.CheckTopologicallyEquals(sub3, sub2, Log));
        }
コード例 #7
0
        public static RootGraph CreateRandomConnectedGraph(int size, double out_degree)
        {
            RootGraph root = CreateUniqueTestGraph();

            // First generate a star of requested size
            Node centernode = root.GetOrAddNode(0.ToString());

            for (int i = 1; i < size; i++)
            {
                var node = root.GetOrAddNode(i.ToString());
                _ = root.GetOrAddEdge(centernode, node, $"{0} to {i}");
            }

            // For each node pick requested number of random neighbors
            for (int i = 0; i < size; i++)
            {
                // We already have one out edge for each node
                for (int x = 0; x < out_degree - 2; x++)
                {
                    var node     = root.GetNode(i.ToString());
                    int j        = rand.Next(size - 1);
                    var neighbor = root.GetNode(j.ToString());
                    _ = root.GetOrAddEdge(node, neighbor, $"{i} to {j}");
                }
            }

            return(root);
        }
コード例 #8
0
        public void TestAttributeDefaults()
        {
            {
                RootGraph root = Utils.CreateUniqueTestGraph();
                Node.IntroduceAttribute(root, "label", "");
                Node nodeA = root.GetOrAddNode("A");
                Node nodeB = root.GetOrAddNode("B");
                nodeA.SetAttribute("label", "1");
                Assert.AreEqual("1", nodeA.GetAttribute("label"));
                Assert.AreEqual("", nodeB.GetAttribute("label"));
                root.ToDotFile(TestContext.CurrentContext.TestDirectory + "/out.gv");
            }

            {
                var  root  = RootGraph.FromDotFile(TestContext.CurrentContext.TestDirectory + "/out.gv");
                Node nodeA = root.GetNode("A");
                Node nodeB = root.GetNode("B");
                Assert.AreEqual("1", nodeA.GetAttribute("label"));
                Assert.AreEqual("", nodeB.GetAttribute("label"));

                root.ComputeLayout();
                Assert.AreEqual("1", nodeA.GetAttribute("label"));
                Assert.AreEqual("", nodeB.GetAttribute("label"));
                root.ToSvgFile(TestContext.CurrentContext.TestDirectory + "/out.svg");
            }
            // The empty label default is not exported, but that appears to be no problem here. The
            // default seems to become the empty string. However, dot.exe gives a different result.
            // When applying dot.exe on out.gv the default label is set to \N, which gives different
            // results entirely.
            // Related issue: https://gitlab.com/graphviz/graphviz/-/issues/1887
        }
コード例 #9
0
        public void TestReadDotFile()
        {
            RootGraph root  = RootGraph.FromDotString(@"
digraph test {
    A;
    B;
    B -> B;
    A -> B[key = edgename];
    A -> B;
    A -> B;
}
");
            var       edges = root.Edges().ToList();
            var       names = edges.Select(e => e.GetName());

            // The attribute 'key' maps to the edgename
            Assert.IsTrue(names.Any(n => n == "edgename"));
            Assert.IsTrue(names.All(n => n == "edgename" || string.IsNullOrEmpty(n)));

            // However, it is strange that the other two edges both seem to have the same name, namely ""
            // According to the documentation, the name is used to distinguish between multi-edges
            var A = root.GetNode("A");
            var B = root.GetNode("B");

            Assert.AreEqual(3, A.EdgesOut().Count());

            // The documentation seem to be correct for edges that are added through the C interface
            _ = root.GetOrAddEdge(A, B, "");
            Assert.AreEqual(4, A.EdgesOut().Count());
            _ = root.GetOrAddEdge(A, B, "");
            Assert.AreEqual(4, A.EdgesOut().Count());
        }
コード例 #10
0
        public void Layouting()
        {
            // If we have a given dot file, we can also simply read it back in
            RootGraph root = RootGraph.FromDotFile(TestContext.CurrentContext.TestDirectory + "/out.dot");

            // Let's have graphviz compute a dot layout for us
            root.ComputeLayout();

            // We can export this to svg
            root.ToSvgFile(TestContext.CurrentContext.TestDirectory + "/dot_out.svg");

            // Or programatically read out the layout attributes
            Node   nodeA    = root.GetNode("A");
            PointF position = nodeA.Position();

            Assert.AreEqual("{X=43, Y=192.1739}", position.ToString());

            // Like a bounding box of an object
            RectangleF nodeboundingbox = nodeA.BoundingBox();

            Assert.AreEqual("{X=16,Y=171.3391,Width=54,Height=41.66957}", nodeboundingbox.ToString());

            // Or splines between nodes
            Node nodeB = root.GetNode("B");
            Edge edge  = root.GetEdge(nodeA, nodeB, "Some edge name");

            PointF[] spline               = edge.FirstSpline();
            string   splineString         = string.Join(", ", spline.Select(p => p.ToString()));
            string   expectedSplineString = "{X=0, Y=0}, {X=43, Y=171.29}, {X=43, Y=163.45},"
                                            + " {X=43, Y=154.26}, {X=43, Y=145.63}";

            Assert.AreEqual(expectedSplineString, splineString);

            GraphvizLabel nodeLabel = nodeA.GetLabel();

            Assert.AreEqual("{X=36.25977,Y=181.4415,Width=13.48047,Height=21.46484}",
                            nodeLabel.BoundingBox().ToString());
            Assert.AreEqual("Times-Roman", nodeLabel.FontName().ToString());

            SubGraph   cluster      = root.GetSubgraph("cluster_1");
            RectangleF clusterbox   = cluster.BoundingBox();
            RectangleF rootgraphbox = root.BoundingBox();

            Assert.AreEqual("{X=8,Y=8,Width=70,Height=135.34}", clusterbox.ToString());
            Assert.AreEqual("{X=0,Y=0,Width=142,Height=213.01}", rootgraphbox.ToString());

            // Once all layout information is obtained from the graph, the resources should be
            // reclaimed. To do this, the application should call the cleanup routine associated
            // with the layout algorithm used to draw the graph. This is done by a call to
            // FreeLayout(). A given graph can be laid out multiple times. The application, however,
            // must clean up the earlier layout's information with a call to FreeLayout before
            // invoking a new layout function.
            root.FreeLayout();

            // We can use layout engines other than dot by explicitly passing the engine we want
            root.ComputeLayout(LayoutEngines.Neato);
            root.ToSvgFile(TestContext.CurrentContext.TestDirectory + "/neato_out.svg");
        }
コード例 #11
0
        public void TestNodeAndGraphWithSameName()
        {
            RootGraph root = Utils.CreateUniqueTestGraph();
            SubGraph  sub  = root.GetOrAddSubgraph("name");
            Node      node = sub.GetOrAddNode("name");

            Assert.True(root.Contains(sub));
            Assert.True(sub.Contains(node));
        }
コード例 #12
0
        public void TestEdgeContraction()
        {
            //NativeMethods.AllocConsole();
            RootGraph root  = Utils.CreateUniqueTestGraph();
            Node      tail  = root.GetOrAddNode("x");
            Node      head  = root.GetOrAddNode("xx");
            Node      other = root.GetOrAddNode("xxx");

            Edge contracted      = root.GetOrAddEdge(tail, head, "tocontract");
            Edge parallel        = root.GetOrAddEdge(tail, head, "parallel");
            Edge counterparallel = root.GetOrAddEdge(head, tail, "counterparallel");
            Edge tailout         = root.GetOrAddEdge(tail, other, "tailout");
            Edge headout         = root.GetOrAddEdge(head, other, "headout");
            Edge tailin          = root.GetOrAddEdge(other, tail, "tailin");
            Edge headin          = root.GetOrAddEdge(other, head, "headin");

            foreach (Node n in root.Nodes())
            {
                n.SafeSetAttribute("label", n.GetName(), "no");
                n.SafeSetAttribute("fontname", "Arial", "Arial");
                foreach (Edge e in n.EdgesOut())
                {
                    e.SafeSetAttribute("label", e.GetName(), "no");
                    e.SafeSetAttribute("fontname", "Arial", "Arial");
                }
            }


            Assert.AreEqual(5, tail.TotalDegree());
            Assert.AreEqual(5, head.TotalDegree());
            Assert.AreEqual(3, root.Nodes().Count());

            Node contraction = root.Contract(contracted, "contraction result");

            foreach (Node n in root.Nodes())
            {
                n.SafeSetAttribute("label", n.GetName(), "no");
                n.SafeSetAttribute("fontname", "Arial", "Arial");
                foreach (Edge e in n.EdgesOut())
                {
                    e.SafeSetAttribute("label", e.GetName(), "no");
                    e.SafeSetAttribute("fontname", "Arial", "Arial");
                }
            }

            //Console.Read();
            Assert.AreEqual(2, root.Nodes().Count());
            Assert.AreEqual(2, contraction.InDegree());
            Assert.AreEqual(2, contraction.OutDegree());
            Assert.AreEqual(2, other.InDegree());
            Assert.AreEqual(2, other.OutDegree());
        }
コード例 #13
0
        public void Layouting()
        {
            // If we have a given dot file (in this case the one we generated above), we can also read it back in
            RootGraph root = RootGraph.FromDotFile(TestContext.CurrentContext.TestDirectory + "/out.dot");

            // Let's have graphviz compute a dot layout for us
            root.ComputeLayout();

            // We can export this to svg
            root.ToSvgFile(TestContext.CurrentContext.TestDirectory + "/dot_out.svg");

            // Or programatically read out the layout attributes
            Node   nodeA    = root.GetNode("A");
            PointF position = nodeA.Position();

            Utils.AssertPattern(@"{X=[\d.]+, Y=[\d.]+}", position.ToString());

            // Like a bounding box of an object
            RectangleF nodeboundingbox = nodeA.BoundingBox();

            Utils.AssertPattern(@"{X=[\d.]+,Y=[\d.]+,Width=[\d.]+,Height=[\d.]+}", nodeboundingbox.ToString());

            // Or splines between nodes
            Node nodeB = root.GetNode("B");
            Edge edge  = root.GetEdge(nodeA, nodeB, "Some edge name");

            PointF[] spline                = edge.FirstSpline();
            string   splineString          = string.Join(", ", spline.Select(p => p.ToString()));
            string   expectedSplinePattern =
                @"{X=[\d.]+, Y=[\d.]+}, {X=[\d.]+, Y=[\d.]+}, {X=[\d.]+, Y=[\d.]+},"
                + @" {X=[\d.]+, Y=[\d.]+}, {X=[\d.]+, Y=[\d.]+}";

            Utils.AssertPattern(expectedSplinePattern, splineString);

            GraphvizLabel nodeLabel = nodeA.GetLabel();

            Utils.AssertPattern(@"{X=[\d.]+,Y=[\d.]+,Width=[\d.]+,Height=[\d.]+}",
                                nodeLabel.BoundingBox().ToString());
            Utils.AssertPattern(@"Times-Roman", nodeLabel.FontName().ToString());

            // Once all layout information is obtained from the graph, the resources should be
            // reclaimed. To do this, the application should call the cleanup routine associated
            // with the layout algorithm used to draw the graph. This is done by a call to
            // FreeLayout(). A given graph can be laid out multiple times. The application, however,
            // must clean up the earlier layout's information with a call to FreeLayout before
            // invoking a new layout function.
            root.FreeLayout();

            // We can use layout engines other than dot by explicitly passing the engine we want
            root.ComputeLayout(LayoutEngines.Neato);
            root.ToSvgFile(TestContext.CurrentContext.TestDirectory + "/neato_out.svg");
        }
コード例 #14
0
        public void TestLabelEscaping(bool escape)
        {
            string label1 = "|";
            string label2 = @"\N\n\L";
            string label3 = "3";

            if (escape)
            {
                label1 = CGraphThing.EscapeLabel(label1);
                label2 = CGraphThing.EscapeLabel(label2);
            }

            {
                RootGraph root  = CreateUniqueTestGraph();
                Node      node1 = root.GetOrAddNode("1");
                node1.SafeSetAttribute("shape", "record", "");
                node1.SafeSetAttribute("label", label1, "");
                Node node2 = root.GetOrAddNode("2");
                node2.SafeSetAttribute("label", label2, "");
                Node node3 = root.GetOrAddNode("3");
                node3.SafeSetAttribute("label", label3, "");
                root.ToDotFile(GetTestFilePath("out.gv"));
            }

            {
                var root = RootGraph.FromDotFile(GetTestFilePath("out.gv"));

                Node node1 = root.GetNode("1");
                Assert.That(node1.GetAttribute("label"), Is.EqualTo(label1));
                Node node2 = root.GetNode("2");
                Assert.That(node2.GetAttribute("label"), Is.EqualTo(label2));
                Node node3 = root.GetNode("3");
                Assert.That(node3.GetAttribute("label"), Is.EqualTo(label3));

                root.ComputeLayout();
                root.ToSvgFile(GetTestFilePath("out.svg"));
                root.ToDotFile(GetTestFilePath("out.dot"));

                var rects = node1.GetRecordRectangles();
                if (escape)
                {
                    Assert.That(rects.Count, Is.EqualTo(1));
                    Assert.That(node2.BoundingBox().Height, Is.EqualTo(node3.BoundingBox().Height));
                }
                else
                {
                    Assert.That(rects.Count, Is.EqualTo(2));
                    Assert.That(node2.BoundingBox().Height, Is.Not.EqualTo(node3.BoundingBox().Height));
                }
            }
        }
コード例 #15
0
        public void Records()
        {
            RootGraph root  = RootGraph.CreateNew("Graph with records", GraphType.Directed);
            Node      nodeA = root.GetOrAddNode("A");

            nodeA.SafeSetAttribute("shape", "record", "");
            nodeA.SafeSetAttribute("label", "1|2|3|{4|5}|6|{7|8|9}", "\\N");

            root.ComputeLayout();

            // The order of the list matches the order in which the labels occur in the label string above.
            var rects = nodeA.GetRecordRectangles().ToList();

            Assert.That(rects.Count, Is.EqualTo(9));
        }
コード例 #16
0
        public void TestEmptyRecordShapes()
        {
            RootGraph root  = CreateUniqueTestGraph();
            Node      nodeA = root.GetOrAddNode("A");

            nodeA.SafeSetAttribute("shape", "record", "");
            nodeA.SafeSetAttribute("label", "||||", "");

            root.ComputeLayout();

            var rects = nodeA.GetRecordRectangles().ToList();

            Assert.That(rects.Count, Is.EqualTo(5));
            root.ToSvgFile(GetTestFilePath("out.svg"));
        }
コード例 #17
0
        public void TestRecordShapeOrder()
        {
            RootGraph root  = CreateUniqueTestGraph();
            Node      nodeA = root.GetOrAddNode("A");

            nodeA.SafeSetAttribute("shape", "record", "");
            nodeA.SafeSetAttribute("label", "1|2|3|{4|5}|6|{7|8|9}", "\\N");

            root.ComputeLayout();

            var rects = nodeA.GetRecordRectangles().ToList();

            // Because Graphviz uses a lower-left originated coordinate system, we need to flip the y coordinates
            Utils.AssertOrder(rects, r => (r.Left, -r.Top));
            Assert.That(rects.Count, Is.EqualTo(9));
        }
コード例 #18
0
        public void TestPortNameConversion(bool escape)
        {
            string port1 = ">|<";
            string port2 = "B";

            if (escape)
            {
                port1 = Edge.ConvertUidToPortName(port1);
                port2 = Edge.ConvertUidToPortName(port2);
            }
            string label = $"{{<{port1}>1|<{port2}>2}}";

            {
                RootGraph root = CreateUniqueTestGraph();
                Node      node = root.GetOrAddNode("N");
                node.SafeSetAttribute("shape", "record", "");
                node.SafeSetAttribute("label", label, "");
                Edge edge = root.GetOrAddEdge(node, node, "");
                edge.SafeSetAttribute("tailport", port1 + ":n", "");
                edge.SafeSetAttribute("headport", port2 + ":s", "");
                root.ToDotFile(GetTestFilePath("out.gv"));
            }

            {
                var root = RootGraph.FromDotFile(GetTestFilePath("out.gv"));

                Node node = root.GetNode("N");
                Assert.That(node.GetAttribute("label"), Is.EqualTo(label));
                Edge edge = root.Edges().First();
                Assert.That(edge.GetAttribute("tailport"), Is.EqualTo(port1 + ":n"));
                Assert.That(edge.GetAttribute("headport"), Is.EqualTo(port2 + ":s"));

                root.ComputeLayout();
                root.ToSvgFile(GetTestFilePath("out.svg"));
                root.ToDotFile(GetTestFilePath("out.dot"));

                var rects = node.GetRecordRectangles();
                if (escape)
                {
                    Assert.That(rects.Count, Is.EqualTo(2));
                }
                else
                {
                    Assert.That(rects.Count, Is.EqualTo(3));
                }
            }
        }
コード例 #19
0
        public void TestSelfLoopEnumeration()
        {
            RootGraph graph    = Utils.CreateUniqueTestGraph();
            Node      node     = graph.GetOrAddNode("node 1");
            Node      node2    = graph.GetOrAddNode("node 2");
            Edge      edgein   = graph.GetOrAddEdge(node2, node, "in");
            Edge      edgeout  = graph.GetOrAddEdge(node, node2, "out");
            Edge      edgeself = graph.GetOrAddEdge(node, node, "self");

            Assert.AreEqual(2, node.InDegree());
            Assert.AreEqual(2, node.OutDegree());
            Assert.AreEqual(4, node.TotalDegree());

            Assert.AreEqual(2, node.EdgesIn().Count());
            Assert.AreEqual(2, node.EdgesOut().Count());
            Assert.AreEqual(3, node.Edges().Count());
        }
コード例 #20
0
        public void TestCopyAttributes()
        {
            RootGraph root = Utils.CreateUniqueTestGraph();
            Node      n1   = root.GetOrAddNode("1");

            Node.IntroduceAttribute(root, "test", "foo");
            Assert.AreEqual("foo", n1.GetAttribute("test"));
            n1.SetAttribute("test", "bar");
            Assert.AreEqual("bar", n1.GetAttribute("test"));

            RootGraph root2 = Utils.CreateUniqueTestGraph();
            Node      n2    = root2.GetOrAddNode("2");

            Assert.AreEqual(null, n2.GetAttribute("test"));
            Assert.AreEqual(0, n1.CopyAttributesTo(n2));
            Assert.AreEqual("bar", n2.GetAttribute("test"));
        }
コード例 #21
0
        public void TestCreateNestedStructures()
        {
            // Documentation:
            // Subgraphs are an important construct in Cgraph.They are intended for organizing subsets of
            // graph objects and can be used interchangeably with top - level graphs in almost all Cgraph
            // functions.  A subgraph may contain any nodes or edges of its parent. (When an edge is
            // inserted in a subgraph, its nodes are also implicitly inserted if necessary.Similarly,
            // insertion of a node or edge automatically implies insertion in all containing subgraphs up
            // to the root.) Subgraphs of a graph form a hierarchy(a tree).Cgraph has functions to
            // create, search, and iterate over subgraphs.

            // Conclusion: the hierarchical tree structure is maintained in a sane way across all
            // operations we can do w.r.t. subgraphs.


            // If a node is created in a subgraph, it should also be contained in all supergraphs
            RootGraph graph        = Utils.CreateUniqueTestGraph();
            SubGraph  supergraph   = graph.GetOrAddSubgraph("level 1");
            string    subgraphname = "level 2";
            SubGraph  subgraph     = supergraph.GetOrAddSubgraph(subgraphname);
            string    nodename     = "test node";
            Node      node         = subgraph.GetOrAddNode(nodename);

            // Node must be contained in super graph
            Assert.True(node.MyRootGraph.Equals(graph));
            Assert.True(supergraph.Contains(node));
            Assert.True(supergraph.Nodes().Contains(node));
            Assert.NotNull(supergraph.GetNode(nodename));
            // Node must be contained in root graph
            Assert.True(graph.Contains(node));
            Assert.True(graph.Nodes().Contains(node));
            Assert.NotNull(graph.GetNode(nodename));

            // Subgraph must be contained in super graph
            Assert.True(supergraph.Contains(subgraph));
            Assert.True(supergraph.Descendants().Contains(subgraph));
            Assert.NotNull(supergraph.GetSubgraph(subgraphname));
            // Subgraph must be contained in root graph
            Assert.True(graph.Contains(subgraph));
            Assert.True(graph.Descendants().Contains(subgraph));
            // Subgraph cannot be obtained in the following way:
            //graph.GetSubgraph(subgraphname)
            Assert.Null(graph.GetSubgraph(subgraphname));
            // Use a utility function instead:
            Assert.NotNull(graph.GetDescendantByName(subgraphname));
        }
コード例 #22
0
        public void TestCopyToNewRoot()
        {
            RootGraph root = Utils.CreateUniqueTestGraph();
            Node      n1   = root.GetOrAddNode("1");

            Node.IntroduceAttribute(root, "test", "foo");
            Assert.AreEqual("foo", n1.GetAttribute("test"));
            n1.SetAttribute("test", "bar");
            Assert.AreEqual("bar", n1.GetAttribute("test"));

            RootGraph root2 = Utils.CreateUniqueTestGraph();

            Node.IntroduceAttribute(root2, "test", "foo");
            Node n2 = n1.CopyToOtherRoot(root2);

            Assert.AreEqual("1", n2.GetName());
            Assert.AreEqual("bar", n2.GetAttribute("test"));
        }
コード例 #23
0
    private void InitMetaData()
    {
        var       rootText  = Resources.Load <TextAsset>("meta/root" + SceneManager.GetActiveScene().name);
        var       docStream = new StringReader(rootText.text);
        RootGraph root      = RootGraph.Construct(docStream);

        foreach (var clip in root.Clips)
        {
            //load clip
            var      clipText      = Resources.Load <TextAsset>("meta/" + clip.Path);
            var      clipDocStream = new StringReader(clipText.text);
            ClipTree clipGraph     = ClipTree.Construct(clipDocStream);
            var      ser           = new YamlDotNet.Serialization.Serializer();

            clipGraphs.Add(clip.Name, clipGraph);
            var midiFile = Resources.Load <TextAsset>("clips/" + clipGraph.Midi);
            Debug.Log(clipGraph.Midi);

            AudioSource audioSource = AddAudioSourceToScene(clipGraph.Audio);

            //parse midi
            Midi midi = new MidiParser().Parse(midiFile.bytes);
            //debug
            Debug.Log(midi.Tracks[2].Bpm);
            foreach (var msg in midi.Tracks[2].Messages)
            {
                Debug.Log(msg);
            }
            Debug.Log(ser.Serialize(clipGraph));
            clips.Add(clip.Name, new Assets.Core.Clip(audioSource, midi));
        }
        foreach (var graph in root.Scriptgraphs)
        {
            var graphText = Resources.Load <TextAsset>("meta/" + graph.Path);
            Debug.Log(graphText);
            var        graphDocStream = new StringReader(graphText.text);
            ScriptTree scriptGraph    = ScriptTree.Construct(graphDocStream);
            var        ser            = new YamlDotNet.Serialization.Serializer();

            scriptGraphs.Add(graph.Name, scriptGraph);
            Debug.Log("Constructed a script graph : " + graph.Name);
            Debug.Log(ser.Serialize(scriptGraph));
        }
    }
コード例 #24
0
        public void TestHtmlLabelsDefault()
        {
            RootGraph    root     = CreateUniqueTestGraph();
            const string labelKey = "label";

            Node.IntroduceAttributeHtml(root, labelKey, "<html default>");

            Node n1 = root.GetOrAddNode("1");
            Node n2 = root.GetOrAddNode("2");
            Node n3 = root.GetOrAddNode("3");

            n1.SetAttribute(labelKey, "plain 1");
            n2.SetAttributeHtml(labelKey, "<html 2>");

            var result = root.ToDotString();

            Assert.That(result, Does.Contain("\"plain 1\""));
            AssertContainsHtml(result, "<html 2>");
            AssertContainsHtml(result, "<html default>");
        }
コード例 #25
0
        public void TestEdgeEquals()
        {
            RootGraph graph = Utils.CreateUniqueTestGraph();
            Node      node  = graph.GetOrAddNode("node 1");
            Node      node2 = graph.GetOrAddNode("node 2");
            Node      node3 = graph.GetOrAddNode("node 3");
            Edge      edge  = graph.GetOrAddEdge(node, node, "edge 1");
            Edge      edge2 = graph.GetOrAddEdge(node, node, "edge 2");
            Edge      edge3 = graph.GetOrAddEdge(node, node2, "edge 3");
            Edge      edge4 = graph.GetOrAddEdge(node2, node3, "edge 4");

            Assert.AreEqual(edge, edge);
            Assert.AreNotEqual(edge, edge2);
            Assert.AreNotEqual(edge, edge3);
            Assert.AreNotEqual(edge, edge4);
            Assert.AreEqual(edge.GetHashCode(), edge.GetHashCode());
            Assert.AreNotEqual(edge.GetHashCode(), edge2.GetHashCode());
            Assert.AreNotEqual(edge.GetHashCode(), edge3.GetHashCode());
            Assert.AreNotEqual(edge.GetHashCode(), edge4.GetHashCode());
        }
コード例 #26
0
        public void TestAttributeIntroduction()
        {
            RootGraph root = Utils.CreateUniqueTestGraph();

            Graph.IntroduceAttribute(root, "test", "default");
            root.SetAttribute("test", "1");
            Assert.AreEqual("1", root.GetAttribute("test"));
            Graph.IntroduceAttribute(root, "test", "default");
            // Now the value has been reset!
            Assert.AreEqual("default", root.GetAttribute("test"));

            // This is not the case for nodes
            Node node = root.GetOrAddNode("nodename");

            Node.IntroduceAttribute(root, "test", "default");
            node.SetAttribute("test", "1");
            Assert.AreEqual("1", node.GetAttribute("test"));
            Node.IntroduceAttribute(root, "test", "default");
            Assert.AreEqual("1", node.GetAttribute("test"));
        }
コード例 #27
0
        // Use only in editor mode
        public static void SaveScripts(string name, ScriptTree tree)
        {
            var       rootText    = Resources.Load <TextAsset>("meta/root");
            var       docStream   = new StringReader(rootText.text);
            RootGraph root        = RootGraph.Construct(docStream);
            var       scriptGraph = root.Scriptgraphs.Find(sg => sg.Name == name);
            string    fullPath    = path + scriptGraph.Path + ".yaml";
            var       sr          = new YamlDotNet.Serialization.SerializerBuilder()
                                    .WithNamingConvention(new YamlDotNet.Serialization.NamingConventions.CamelCaseNamingConvention())
                                    .Build();

            using (FileStream fs = new FileStream(fullPath, FileMode.Create))
            {
                using (StreamWriter writer = new StreamWriter(fs))
                {
                    writer.Write(sr.Serialize(tree));
                }
            }
            UnityEditor.AssetDatabase.Refresh();
        }
コード例 #28
0
        public void TestReadDotFile()
        {
            RootGraph root = RootGraph.FromDotString(@"
digraph test {
    A;
    B;
    B -> B;
    A -> B[name = edgename];
    A -> B[name = edgename];
    A -> B[name = edgename];
}
");
            var       A    = root.GetNode("A");

            Assert.AreEqual(3, A.EdgesOut().Count());

            var B = root.GetNode("B");

            _ = root.GetOrAddEdge(A, B, "");
            Assert.AreEqual(4, A.EdgesOut().Count());
        }
コード例 #29
0
        public void TestNonStrictGraph()
        {
            RootGraph graph = Utils.CreateUniqueTestGraph();

            Assert.False(graph.IsStrict());
            Assert.False(graph.IsUndirected());
            Assert.True(graph.IsDirected());

            Node node  = graph.GetOrAddNode("node 1");
            Node node2 = graph.GetOrAddNode("node 2");

            Edge edge  = graph.GetOrAddEdge(node, node, "edge 1");
            Edge edge2 = graph.GetOrAddEdge(node, node, "edge 2");

            Assert.AreNotEqual(edge.GetName(), edge2.GetName());

            Edge edge3 = graph.GetOrAddEdge(node, node2, "edge 3");
            Edge edge4 = graph.GetOrAddEdge(node, node2, "edge 4");

            Assert.AreNotEqual(edge3.GetName(), edge4.GetName());
        }
コード例 #30
0
        public void Clusters()
        {
            RootGraph root  = RootGraph.CreateNew("Graph with clusters", GraphType.Directed);
            Node      nodeA = root.GetOrAddNode("A");
            Node      nodeB = root.GetOrAddNode("B");
            Node      nodeC = root.GetOrAddNode("C");
            Node      nodeD = root.GetOrAddNode("D");

            // When a subgraph name is prefixed with cluster,
            // the dot layout engine will render it as a box around the containing nodes.
            SubGraph cluster1 = root.GetOrAddSubgraph("cluster_1");

            cluster1.AddExisting(nodeB);
            cluster1.AddExisting(nodeC);
            SubGraph cluster2 = root.GetOrAddSubgraph("cluster_2");

            cluster2.AddExisting(nodeD);

            // COMPOUND EDGES
            // Graphviz does not really support edges from and to clusters. However, by adding an
            // invisible dummynode and setting the ltail or lhead attributes of an edge this
            // behavior can be faked. Graphviz will then draw an edge to the dummy node but clip it
            // at the border of the cluster. We provide convenience methods for this.
            // To enable this feature, Graphviz requires us to set the "compound" attribute to "true".
            Graph.IntroduceAttribute(root, "compound", "true"); // Allow lhead/ltail
            // The boolean indicates whether the dummy node should take up any space. When you pass
            // false and you have a lot of edges, the edges may start to overlap a lot.
            _ = root.GetOrAddEdge(nodeA, cluster1, false, "edge to a cluster");
            _ = root.GetOrAddEdge(cluster1, nodeD, false, "edge from a cluster");
            _ = root.GetOrAddEdge(cluster1, cluster1, false, "edge between clusters");

            root.ComputeLayout();

            SubGraph   cluster      = root.GetSubgraph("cluster_1");
            RectangleF clusterbox   = cluster.BoundingBox();
            RectangleF rootgraphbox = root.BoundingBox();

            Utils.AssertPattern(@"{X=[\d.]+,Y=[\d.]+,Width=[\d.]+,Height=[\d.]+}", clusterbox.ToString());
            Utils.AssertPattern(@"{X=[\d.]+,Y=[\d.]+,Width=[\d.]+,Height=[\d.]+}", rootgraphbox.ToString());
        }
コード例 #31
0
        public Form2()
        {
            InitializeComponent();
            /*
            string DotFilePath = String.Format(@"C:\Users\Zenith\AppData\Roaming\HNClusterUI\HNClusterUI\1.0.0.0\DOTFILE - Copy - Copy.dot");
            //graph.ToDotFile(DotFilePath);

            DOT dotfile2 = new DOT();
            string DotFile1 = File.ReadAllText(DotFilePath);
            string svg2 = dotfile2.ToSvg(DotFile1);
            return;*/

            this.MouseWheel += new System.Windows.Forms.MouseEventHandler(Form2_MouseWheel);
            this.KeyDown += Form2_KeyDown_KeyUp;
            this.KeyUp += Form2_KeyDown_KeyUp;
            this.KeyPreview = true;
            webBrowser1.WebBrowserShortcutsEnabled = false;
            webBrowser1.IsWebBrowserContextMenuEnabled = false;
            webBrowser1.PreviewKeyDown += webBrowser1_PreviewKeyDown;
            Control c = webBrowser1;
            c.KeyDown += Form2_KeyDown_KeyUp;
            c.KeyUp += Form2_KeyDown_KeyUp;
            //c.Enabled = false;
            /*
            foreach (Control control in this.Controls)
            {
                control.KeyDown += new KeyEventHandler(Form2_KeyDown_KeyUp);
                control.KeyUp += new KeyEventHandler(Form2_KeyDown_KeyUp);
                //control.KeyPress += new KeyEventHandler(Form2_KeyDown_KeyUp);
            }*/

            graph = new Xglore.Plugin.Graphviz.RootGraph("Clusters", false, false);
            string MainNode = " _3D.P–r,i:nt–ing'L13_01111111101-- 010Noro–Frenkel_law_of_corresponding___stat&es+ ";
            AddNode(MainNode);

            AddNode("0");
            AddNode("00");
            AddNode("000");
            AddNode("001");
            AddNode("01");
            AddNode("010");
            AddNode("011");

            AddNode("1");
            AddNode("10");
            AddNode("100");
            AddNode("101");
            AddNode("11");
            AddNode("110");
            AddNode("111");

            AddEdge(MainNode, "0");
            AddEdge(MainNode, "1");

            AddEdge("0", "00");
            AddEdge("00", "000");
            AddEdge("00", "001");
            AddEdge("0", "01");
            AddEdge("01", "010");
            AddEdge("01", "011");
            AddEdge("1", "10");
            AddEdge("10", "100");
            AddEdge("10", "101");
            AddEdge("1", "11");
            AddEdge("11", "110");
            AddEdge("11", "111");

            for (int i = 0; i < 10; ++i)
            {
                AddNode(i.ToString());
            }

            for (int x = 0; x < 10; ++x)
            {
                for (int y = x; y < 10; ++y)
                {
                    if (x != y)
                    AddEdge(x.ToString(), y.ToString());
                }
            }

            string dotPath = String.Format("{0}\\DOTFILE.dot", Application.UserAppDataPath);
            graph.ToDotFile(dotPath);

            DOT dotfile = new DOT();
            string strBlah3 = System.IO.File.ReadAllText(dotPath);

            string svg = dotfile.ToSvg(strBlah3);

            System.IO.File.WriteAllText(String.Format("{0}\\SVG.svg", Application.UserAppDataPath), svg);

            //webBrowser1.Url = new Uri(@"C:\Users\Zenith\Documents\GitHub\Wikipedia-Clustering\HNCluster\HNCluster\bin\Debug\" + "SVG.svg");
            Uri url = new Uri(String.Format("{0}\\SVG.svg", Application.UserAppDataPath));
            webBrowser1.Url = url;
            XDocument doc = XDocument.Parse(svg);
            SVGFile = (XElement)doc.LastNode;
            //SVGFile = XDocument.Parse(svg).Element("svg");
            this.Focus();
        }
コード例 #32
0
 public GraphDisplay()
 {
     InitializeComponent();
     graph = new RootGraph("Clusters", true, true);
     url = new Uri(SVGFilePath);
 }