protected static void AddVertexRange_Throws_Clusters_Test <TEdge>(
            ClusteredAdjacencyGraph <TestVertex, TEdge> graph)
            where TEdge : IEdge <TestVertex>
        {
            AssertNoVertex(graph);

            // ReSharper disable once AssignNullToNotNullAttribute
            Assert.Throws <ArgumentNullException>(() => graph.AddVertexRange(null));
            AssertNoVertex(graph);

            // Vertex 1, 2, 3
            var vertex1 = new TestVertex("1");
            var vertex3 = new TestVertex("3");

            Assert.Throws <ArgumentNullException>(() => graph.AddVertexRange(new[] { vertex1, null, vertex3 }));
            AssertNoVertex(graph);
        }
Exemple #2
0
        public void GenerateSameDot()
        {
            var graph = new AdjacencyGraph <int, Edge <int> >();

            // Empty graph
            TestGenerate(graph);

            // Only vertices
            graph.AddVertexRange(new[] { 1, 2 });
            TestGenerate(graph);

            // With edges
            graph.AddVerticesAndEdgeRange(new[]
            {
                new Edge <int>(1, 2),
                new Edge <int>(2, 3),
                new Edge <int>(3, 1)
            });
            TestGenerate(graph);

            // With no cluster
            var clusteredGraph = new ClusteredAdjacencyGraph <int, Edge <int> >(graph);

            TestGenerate(clusteredGraph);

            // With clusters
            ClusteredAdjacencyGraph <int, Edge <int> > subGraph1 = clusteredGraph.AddCluster();

            subGraph1.AddVertexRange(new[] { 4, 5 });
            ClusteredAdjacencyGraph <int, Edge <int> > subGraph2 = clusteredGraph.AddCluster();

            subGraph2.AddVerticesAndEdge(new Edge <int>(1, 6));
            TestGenerate(clusteredGraph);

            #region Local function

            void TestGenerate <TVertex, TEdge>(IEdgeListGraph <TVertex, TEdge> g)
                where TEdge : IEdge <TVertex>
            {
                var    algorithm    = new GraphvizAlgorithm <TVertex, TEdge>(g);
                string generatedDot = algorithm.Generate();

                Assert.IsNotEmpty(generatedDot);

                var dotEngine = new TestDotEngine {
                    ExpectedDot = generatedDot
                };

                // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
                algorithm.Generate(dotEngine, "NotSaved.dot");
            }

            #endregion
        }
        protected static void AddVertexRange_Clusters_Test <TEdge>(
            ClusteredAdjacencyGraph <TestVertex, TEdge> graph1,
            ClusteredAdjacencyGraph <TestVertex, TEdge> parent2,
            ClusteredAdjacencyGraph <TestVertex, TEdge> graph2)
            where TEdge : IEdge <TestVertex>
        {
            AssertNoVertex(graph1);

            // Graph without parent
            // Vertex 1, 2, 3
            var vertex1 = new TestVertex("1");
            var vertex2 = new TestVertex("2");
            var vertex3 = new TestVertex("3");

            Assert.AreEqual(3, graph1.AddVertexRange(new[] { vertex1, vertex2, vertex3 }));
            AssertHasVertices(graph1, new[] { vertex1, vertex2, vertex3 });

            // Vertex 1, 4
            var vertex4 = new TestVertex("4");

            Assert.AreEqual(1, graph1.AddVertexRange(new[] { vertex1, vertex4 }));
            AssertHasVertices(graph1, new[] { vertex1, vertex2, vertex3, vertex4 });

            // Graph with parent
            AssertNoVertex(parent2);
            AssertNoVertex(graph2);

            // Vertex 1, 2, 3
            Assert.AreEqual(3, graph2.AddVertexRange(new[] { vertex1, vertex2, vertex3 }));
            AssertHasVertices(parent2, new[] { vertex1, vertex2, vertex3 });
            AssertHasVertices(graph2, new[] { vertex1, vertex2, vertex3 });

            // Vertex 1, 4
            Assert.AreEqual(1, parent2.AddVertexRange(new[] { vertex1, vertex4 }));
            AssertHasVertices(parent2, new[] { vertex1, vertex2, vertex3, vertex4 });
            AssertHasVertices(graph2, new[] { vertex1, vertex2, vertex3 });

            Assert.AreEqual(1, graph2.AddVertexRange(new[] { vertex1, vertex4 }));
            AssertHasVertices(parent2, new[] { vertex1, vertex2, vertex3, vertex4 });
            AssertHasVertices(graph2, new[] { vertex1, vertex2, vertex3, vertex4 });
        }
        protected static void RemoveEdgeIf_Clusters_Test(
            [NotNull] ClusteredAdjacencyGraph <int, Edge <int> > graph)
        {
            var edge12    = new Edge <int>(1, 2);
            var edge13    = new Edge <int>(1, 3);
            var edge13Bis = new Edge <int>(1, 3);
            var edge14    = new Edge <int>(1, 4);
            var edge24    = new Edge <int>(2, 4);
            var edge31    = new Edge <int>(3, 1);
            var edge33    = new Edge <int>(3, 3);

            graph.AddVertexRange(new[] { 1, 2, 3, 4 });
            graph.AddEdgeRange(new[] { edge12, edge13, edge13Bis, edge14, edge24, edge31, edge33 });

            Assert.AreEqual(0, graph.RemoveEdgeIf(edge => edge.Target == 5));

            Assert.AreEqual(2, graph.RemoveEdgeIf(edge => edge.Source == 3));
            AssertHasVertices(graph, new[] { 1, 2, 3, 4 });
            AssertHasEdges(graph, new[] { edge12, edge13, edge13Bis, edge14, edge24 });

            Assert.AreEqual(5, graph.RemoveEdgeIf(edge => true));
            AssertHasVertices(graph, new[] { 1, 2, 3, 4 });
            AssertNoEdge(graph);
        }
        protected static void RemoveVertex_Clusters_Test(
            [NotNull] ClusteredAdjacencyGraph <int, Edge <int> > graph)
        {
            var edge12 = new Edge <int>(1, 2);
            var edge13 = new Edge <int>(1, 3);
            var edge14 = new Edge <int>(1, 4);
            var edge24 = new Edge <int>(2, 4);
            var edge31 = new Edge <int>(3, 1);
            var edge33 = new Edge <int>(3, 3);

            graph.AddVerticesAndEdgeRange(new[] { edge12, edge13, edge14, edge24, edge31, edge33 });

            Assert.IsFalse(graph.RemoveVertex(5));

            Assert.IsTrue(graph.RemoveVertex(3));
            AssertHasVertices(graph, new[] { 1, 2, 4 });
            AssertHasEdges(graph, new[] { edge12, edge14, edge24 });

            Assert.IsTrue(graph.RemoveVertex(1));
            AssertHasVertices(graph, new[] { 2, 4 });
            AssertHasEdges(graph, new[] { edge24 });

            Assert.IsTrue(graph.RemoveVertex(2));
            AssertHasVertices(graph, new[] { 4 });
            AssertNoEdge(graph);

            Assert.IsTrue(graph.RemoveVertex(4));
            AssertEmptyGraph(graph);


            // With cluster
            ClusteredAdjacencyGraph <int, Edge <int> > cluster1 = graph.AddCluster();
            ClusteredAdjacencyGraph <int, Edge <int> > cluster2 = graph.AddCluster();
            ClusteredAdjacencyGraph <int, Edge <int> > cluster3 = graph.AddCluster();

            cluster1.AddVertexRange(new[] { 1, 2 });
            AssertHasVertices(cluster1, new[] { 1, 2 });

            cluster2.AddVertexRange(new[] { 1, 2, 4 });
            AssertHasVertices(cluster2, new[] { 1, 2, 4 });

            cluster3.AddVertex(2);
            AssertHasVertices(cluster3, new[] { 2 });

            graph.AddVertexRange(new[] { 1, 2, 3, 4 });
            AssertHasVertices(graph, new[] { 1, 2, 3, 4 });


            graph.RemoveVertex(2);
            AssertHasVertices(graph, new[] { 1, 3, 4 });
            AssertHasVertices(cluster1, new[] { 1 });
            AssertHasVertices(cluster2, new[] { 1, 4 });
            AssertNoVertex(cluster3);

            graph.RemoveVertex(1);
            AssertHasVertices(graph, new[] { 3, 4 });
            AssertNoVertex(cluster1);
            AssertHasVertices(cluster2, new[] { 4 });
            AssertNoVertex(cluster3);

            graph.RemoveVertex(3);
            AssertHasVertices(graph, new[] { 4 });
            AssertNoVertex(cluster1);
            AssertHasVertices(cluster2, new[] { 4 });
            AssertNoVertex(cluster3);

            graph.RemoveVertex(4);
            AssertNoVertex(graph);
            AssertNoVertex(cluster1);
            AssertNoVertex(cluster2);
            AssertNoVertex(cluster3);
        }
Exemple #6
0
        public void FormatHandlers()
        {
            var graph     = new AdjacencyGraph <int, Edge <int> >();
            var algorithm = new GraphvizAlgorithm <int, Edge <int> >(graph);

            algorithm.FormatVertex  += NoVertexOnFormatVertex;
            algorithm.FormatEdge    += NoEdgeOnFormatEdge;
            algorithm.FormatCluster += NoClusterOnFormatCluster;

            // Empty graph
            algorithm.Generate();

            // Only vertices
            graph.AddVertexRange(new[] { 1, 2 });
            algorithm = new GraphvizAlgorithm <int, Edge <int> >(graph);
            List <int> notFormattedVertices = RegisterOnFormatVertex(algorithm, graph.Vertices);

            algorithm.FormatEdge    += NoEdgeOnFormatEdge;
            algorithm.FormatCluster += NoClusterOnFormatCluster;

            algorithm.Generate();

            CollectionAssert.IsEmpty(notFormattedVertices);

            // With edges
            graph.AddVerticesAndEdgeRange(new[]
            {
                new Edge <int>(1, 2),
                new Edge <int>(2, 3),
                new Edge <int>(3, 1)
            });
            algorithm            = new GraphvizAlgorithm <int, Edge <int> >(graph);
            notFormattedVertices = RegisterOnFormatVertex(algorithm, graph.Vertices);
            List <Edge <int> > notFormattedEdges = RegisterOnFormatEdge(algorithm, graph.Edges);

            algorithm.FormatCluster += NoClusterOnFormatCluster;

            algorithm.Generate();

            CollectionAssert.IsEmpty(notFormattedVertices);
            CollectionAssert.IsEmpty(notFormattedEdges);

            // With no cluster
            var clusteredGraph = new ClusteredAdjacencyGraph <int, Edge <int> >(graph);

            algorithm                = new GraphvizAlgorithm <int, Edge <int> >(clusteredGraph);
            notFormattedVertices     = RegisterOnFormatVertex(algorithm, clusteredGraph.Vertices);
            notFormattedEdges        = RegisterOnFormatEdge(algorithm, clusteredGraph.Edges);
            algorithm.FormatCluster += NoClusterOnFormatCluster;

            algorithm.Generate();

            CollectionAssert.IsEmpty(notFormattedVertices);
            CollectionAssert.IsEmpty(notFormattedEdges);

            // With clusters
            ClusteredAdjacencyGraph <int, Edge <int> > subGraph1 = clusteredGraph.AddCluster();

            subGraph1.AddVertexRange(new[] { 4, 5 });
            ClusteredAdjacencyGraph <int, Edge <int> > subGraph2 = clusteredGraph.AddCluster();

            subGraph2.AddVerticesAndEdge(new Edge <int>(1, 6));
            algorithm            = new GraphvizAlgorithm <int, Edge <int> >(clusteredGraph);
            notFormattedVertices = RegisterOnFormatVertex(algorithm, clusteredGraph.Vertices);
            notFormattedEdges    = RegisterOnFormatEdge(algorithm, clusteredGraph.Edges);
            List <IVertexAndEdgeListGraph <int, Edge <int> > > notFormattedClusters = RegisterOnFormatCluster(
                algorithm,
                new[] { subGraph1, subGraph2 });

            algorithm.Generate();

            CollectionAssert.IsEmpty(notFormattedVertices);
            CollectionAssert.IsEmpty(notFormattedEdges);
            CollectionAssert.IsEmpty(notFormattedClusters);

            #region Local functions

            void NoVertexOnFormatVertex(object sender, FormatVertexEventArgs <int> args)
            {
                Assert.Fail($"{nameof(GraphvizAlgorithm<object, Edge<object>>.FormatVertex)} called while no vertex in graph.");
            }

            List <TVertex> RegisterOnFormatVertex <TVertex, TEdge>(GraphvizAlgorithm <TVertex, TEdge> algo, IEnumerable <TVertex> vertices)
                where TEdge : IEdge <TVertex>
            {
                var verticesList = new List <TVertex>(vertices);

                algo.FormatVertex += (sender, args) =>
                {
                    Assert.IsTrue(verticesList.Remove(args.Vertex));
                };
                return(verticesList);
            }

            void NoEdgeOnFormatEdge(object sender, FormatEdgeEventArgs <int, Edge <int> > args)
            {
                Assert.Fail($"{nameof(GraphvizAlgorithm<object, Edge<object>>.FormatEdge)} called while no edge in graph.");
            }

            List <TEdge> RegisterOnFormatEdge <TVertex, TEdge>(GraphvizAlgorithm <TVertex, TEdge> algo, IEnumerable <TEdge> edges)
                where TEdge : IEdge <TVertex>
            {
                var edgeList = new List <TEdge>(edges);

                algo.FormatEdge += (sender, args) =>
                {
                    Assert.IsTrue(edgeList.Remove(args.Edge));
                };
                return(edgeList);
            }

            void NoClusterOnFormatCluster(object sender, FormatClusterEventArgs <int, Edge <int> > args)
            {
                Assert.Fail($"{nameof(GraphvizAlgorithm<object, Edge<object>>.FormatCluster)} called while no cluster in graph.");
            }

            List <IVertexAndEdgeListGraph <TVertex, TEdge> > RegisterOnFormatCluster <TVertex, TEdge>(GraphvizAlgorithm <TVertex, TEdge> algo, IEnumerable <IVertexAndEdgeListGraph <TVertex, TEdge> > clusters)
                where TEdge : IEdge <TVertex>
            {
                var clusterList = new List <IVertexAndEdgeListGraph <TVertex, TEdge> >(clusters);

                algo.FormatCluster += (sender, args) =>
                {
                    Assert.IsTrue(clusterList.Remove(args.Cluster));
                };
                return(clusterList);
            }

            #endregion
        }
Exemple #7
0
        public void GenerateWithFormats()
        {
            var graph = new AdjacencyGraph <int, Edge <int> >();

            graph.AddVerticesAndEdgeRange(new[]
            {
                new Edge <int>(1, 2),
                new Edge <int>(1, 3),
                new Edge <int>(3, 2),
                new Edge <int>(3, 4),
                new Edge <int>(4, 6),
                new Edge <int>(5, 2),
                new Edge <int>(5, 5)
            });
            graph.AddVertex(7);
            var clusteredGraph = new ClusteredAdjacencyGraph <int, Edge <int> >(graph);
            ClusteredAdjacencyGraph <int, Edge <int> > subGraph1 = clusteredGraph.AddCluster();

            subGraph1.AddVertexRange(new[] { 8, 9, 10 });
            ClusteredAdjacencyGraph <int, Edge <int> > subGraph2 = clusteredGraph.AddCluster();

            subGraph2.AddVerticesAndEdgeRange(new[]
            {
                new Edge <int>(11, 12),
                new Edge <int>(11, 13),
                new Edge <int>(12, 13)
            });

            var algorithm = new GraphvizAlgorithm <int, Edge <int> >(clusteredGraph);

            algorithm.GraphFormat.Name             = "MyGraph";
            algorithm.GraphFormat.NodeSeparation   = 2;
            algorithm.GraphFormat.FontColor        = GraphvizColor.Red;
            algorithm.CommonVertexFormat.Url       = "https://myurl.com";
            algorithm.CommonVertexFormat.FillColor = GraphvizColor.LightYellow;
            algorithm.CommonVertexFormat.Style     = GraphvizVertexStyle.Filled;
            algorithm.CommonEdgeFormat.Direction   = GraphvizEdgeDirection.Back;
            algorithm.CommonEdgeFormat.ToolTip     = "Edge";

            algorithm.FormatCluster += (sender, args) =>
            {
                args.GraphFormat.Label = args.Cluster == subGraph1
                    ? "Only Vertices cluster"
                    : "Triangle cluster";
            };

            algorithm.FormatVertex += (sender, args) =>
            {
                if (args.Vertex == 2 || args.Vertex == 11)
                {
                    args.VertexFormat.Label = "Special Node";
                }
            };

            algorithm.FormatEdge += (sender, args) =>
            {
                if (args.Edge.Source == args.Edge.Target)
                {
                    args.EdgeFormat.StrokeColor = GraphvizColor.Gold;
                }
            };

            string dot         = algorithm.Generate();
            string expectedDot = "digraph MyGraph {" + Environment.NewLine
                                 + "fontcolor=\"#FF0000FF\"; nodesep=2;" + Environment.NewLine
                                 + "node [style=filled, fillcolor=\"#FFFFE0FF\", URL=\"https://myurl.com\"];" + Environment.NewLine
                                 + "edge [dir=back, tooltip=\"Edge\"];" + Environment.NewLine
                                 + "subgraph cluster1 {" + Environment.NewLine
                                 + "label=\"Only Vertices cluster\"" + Environment.NewLine
                                 + "7 [label=\"8\"];" + Environment.NewLine
                                 + "8 [label=\"9\"];" + Environment.NewLine
                                 + "9 [label=\"10\"];" + Environment.NewLine
                                 + "}" + Environment.NewLine
                                 + "subgraph cluster2 {" + Environment.NewLine
                                 + "label=\"Triangle cluster\"" + Environment.NewLine
                                 + "10 [label=\"Special Node\"];" + Environment.NewLine
                                 + "11 [label=\"12\"];" + Environment.NewLine
                                 + "12 [label=\"13\"];" + Environment.NewLine
                                 + "10 -> 11;" + Environment.NewLine
                                 + "10 -> 12;" + Environment.NewLine
                                 + "11 -> 12;" + Environment.NewLine
                                 + "}" + Environment.NewLine
                                 + "0 [label=\"1\"];" + Environment.NewLine
                                 + "1 [label=\"Special Node\"];" + Environment.NewLine
                                 + "2 [label=\"3\"];" + Environment.NewLine
                                 + "3 [label=\"4\"];" + Environment.NewLine
                                 + "4 [label=\"6\"];" + Environment.NewLine
                                 + "5 [label=\"5\"];" + Environment.NewLine
                                 + "6 [label=\"7\"];" + Environment.NewLine
                                 + "0 -> 1;" + Environment.NewLine
                                 + "0 -> 2;" + Environment.NewLine
                                 + "2 -> 1;" + Environment.NewLine
                                 + "2 -> 3;" + Environment.NewLine
                                 + "3 -> 4;" + Environment.NewLine
                                 + "5 -> 1;" + Environment.NewLine
                                 + "5 -> 5 [color=\"#FFD700FF\"];" + Environment.NewLine
                                 + "}";

            Assert.AreEqual(expectedDot, dot);
        }