Beispiel #1
0
        /// <summary>
        /// Creates a forest of unbalanced trees and applies a radial layout.
        /// </summary>
        /// <param name="diagram">The diagram.</param>
        /// <param name="specs">The specs.</param>
        private void RandomRadialForest(RadDiagram diagram, GraphGenerationSpecifications specs)
        {
            this.diagram.Clear();
            Dictionary <Node, RadDiagramShape>      nodeMap;
            Dictionary <Edge, RadDiagramConnection> edgeMap;
            var g        = this.diagram.CreateDiagram(GraphExtensions.CreateRandomGraph(250, 4, true), out nodeMap, out edgeMap, GraphExtensions.CreateShape, this.RandomSizeCheck.IsChecked.HasValue && this.RandomSizeCheck.IsChecked.Value);
            var settings = new TreeLayoutSettings
            {
                TreeLayoutType                  = TreeLayoutType.RadialTree,
                HorizontalSeparation            = this.HorizontalSeparationSlider.Value,
                VerticalSeparation              = this.VerticalSeparationSlider.Value,
                UnderneathHorizontalOffset      = this.UnderneathHorizontalOffsetSlider.Value,
                UnderneathVerticalSeparation    = this.UnderneathVerticalOffsetSlider.Value,
                KeepComponentsInOneRadialLayout = true,
                RadialSeparation                = 45d
            };
            var center = g.FindNode(0);

            settings.Roots.Add(nodeMap[center]);
            var layout = new TreeLayout();

            layout.Layout(this.diagram, settings);
            this.diagram.AutoFit();
            //Colorize(g, nodeMap, center);
        }
Beispiel #2
0
        /// <summary>
        /// Creates a tree which grows symmetrically.
        /// </summary>
        /// <param name="diagram">The diagram.</param>
        /// <param name="specs">The specs.</param>
        private void BalancedRadialTree(RadDiagram diagram, GraphGenerationSpecifications specs)
        {
            this.diagram.Clear();
            Dictionary <Node, RadDiagramShape>      nodeMap;
            Dictionary <Edge, RadDiagramConnection> edgeMap;

            // the algorithm to create a balanced tree is quite straighforward
            var g = this.diagram.CreateDiagram(GraphExtensions.CreateBalancedTree(), out nodeMap, out edgeMap, GraphExtensions.CreateShape, this.RandomSizeCheck.IsChecked.HasValue && this.RandomSizeCheck.IsChecked.Value);

            // the result is best displayed with the radial tree layout
            var settings = new TreeLayoutSettings
            {
                TreeLayoutType               = TreeLayoutType.RadialTree,
                HorizontalSeparation         = this.HorizontalSeparationSlider.Value,
                VerticalSeparation           = this.VerticalSeparationSlider.Value,
                UnderneathHorizontalOffset   = this.UnderneathHorizontalOffsetSlider.Value,
                UnderneathVerticalSeparation = this.UnderneathVerticalOffsetSlider.Value,
                StartRadialAngle             = Math.PI,
                // use a specific angle rather than the full 360° to show one of the layout's (hidden) gem
                EndRadialAngle = 3.47 * Math.PI / 2
            };
            var center = g.FindNode(-1);

            settings.Roots.Add(nodeMap[center]);
            var layout = new TreeLayout();

            layout.Layout(this.diagram, settings);

            // center and size autimagically
            this.diagram.AutoFit();

            // you can colorize the shapes, if you wish
            // this.Colorize(g, nodeMap, center);
        }
Beispiel #3
0
        /// <summary>
        /// Creates a specific graph to show the shortest path between two nodes.
        /// </summary>
        /// <param name="obj">The diagram.</param>
        /// <param name="specs">The specs.</param>
        private void ShortestPath(RadDiagram obj, GraphGenerationSpecifications specs)
        {
            this.diagram.Clear();
            Dictionary <Node, RadDiagramShape>      nodeMap;
            Dictionary <Edge, RadDiagramConnection> edgeMap;
            var g = this.diagram.CreateDiagram(new List <string> {
                "1,2", "2,3", "1,4", "4,5", "5,3", "1,6", "6,7", "7,8", "8,3", "3,9", "9,10", "10,11"
            }, out nodeMap, out edgeMap, GraphExtensions.CreateShape, this.RandomSizeCheck.IsChecked.HasValue && this.RandomSizeCheck.IsChecked.Value);

            // Dijkstra's algorithm will give you the shortest path
            var path = g.DijkstraShortestPath(1, 11);

            if (path != null)
            {
                this.Highlight(path, nodeMap, edgeMap, this.HighlighBrush);
            }

            // the node map gives us the shape from a node and we want to have the "1" node at the root of the tree
            var nodeOne  = g.FindNode(1);
            var shapeOne = nodeMap[nodeOne];
            var settings = new TreeLayoutSettings
            {
                TreeLayoutType       = TreeLayoutType.TreeDown,
                VerticalSeparation   = 50d,
                HorizontalSeparation = 80d,
            };

            // specifying the root (or roots if we have a forest) can be done using the Roots property like so
            settings.Roots.Add(shapeOne);
            diagram.Layout(LayoutType.Tree, settings);
        }
Beispiel #4
0
        /// <summary>
        /// Creates a random connected graph and displayes a (non-unique) spanning tree using Prim's algorithm.
        /// </summary>
        /// <param name="diagram">The diagram.</param>
        /// <param name="specs">The specs.</param>
        private void Prims(RadDiagram diagram, GraphGenerationSpecifications specs)
        {
            diagram.Clear();
            Dictionary <Node, RadDiagramShape>      nodeMap;
            Dictionary <Edge, RadDiagramConnection> edgeMap;
            var randomConnectedGraph = GraphExtensions.CreateRandomConnectedGraph(10);
            var root = randomConnectedGraph.FindTreeRoot();
            var g    = diagram.CreateDiagram(randomConnectedGraph, out nodeMap, out edgeMap, GraphExtensions.CreateShape, specs.RandomShapeSize);

            // making it undirected will reach all the nodes since the random graph is connected
            g.IsDirected = false;
            var tree = g.PrimsSpanningTree(root);

            if (tree != null)
            {
                this.Highlight(tree, nodeMap, edgeMap, this.HighlighBrush);
            }
            var settings = new TreeLayoutSettings
            {
                TreeLayoutType       = TreeLayoutType.TreeDown,
                VerticalSeparation   = 50d,
                HorizontalSeparation = 80d,
            };

            diagram.Layout(LayoutType.Tree, settings);
        }
Beispiel #5
0
        /// <summary>
        /// Creates a specific diagram and highlight the longest path found through the graph analysis.
        /// </summary>
        /// <param name="diagram">The diagram.</param>
        /// <param name="specs">The specs.</param>
        private void LongestPath(RadDiagram diagram, GraphGenerationSpecifications specs)
        {
            diagram.Clear();
            Dictionary <Node, RadDiagramShape>      nodeMap;
            Dictionary <Edge, RadDiagramConnection> edgeMap;

            // this creates the specific graph
            var g = this.diagram.CreateDiagram(new List <string> {
                "1,2", "2,3", "2,4", "3,5", "4,5", "5,6", "2,7", "7,8", "8,9", "9,10", "10,6", "20,21", "21,22", "20,25"
            }, out nodeMap, out edgeMap, GraphExtensions.CreateShape, this.RandomSizeCheck.IsChecked.HasValue && this.RandomSizeCheck.IsChecked.Value);

            // note that this works on disconnected graphs as well as on connected ones
            var path = g.FindLongestPath();

            // highlight the longest path if one is found
            if (path != null)
            {
                this.Highlight(path, nodeMap, edgeMap, this.HighlighBrush);
            }

            // use a layout which displays the result best
            diagram.Layout(LayoutType.Tree, new TreeLayoutSettings
            {
                TreeLayoutType       = TreeLayoutType.TreeUp,
                VerticalSeparation   = 80d,
                HorizontalSeparation = 50d
            });
        }
Beispiel #6
0
        /// <summary>
        /// Creates a specific graph which has some obvious cycles and lets the graph analysis highlight them, thus confirming the cycles
        /// which can be easily found manually. The analysis goes of course beyond what the human eye can see and would find cycles in an arbitrary graph.
        /// </summary>
        /// <param name="diagram">The diagram.</param>
        /// <param name="specs">The specs.</param>
        private void Cycles(RadDiagram diagram, GraphGenerationSpecifications specs)
        {
            diagram.Clear();
            Dictionary <Node, RadDiagramShape>      nodeMap;
            Dictionary <Edge, RadDiagramConnection> edgeMap;
            var g = diagram.CreateDiagram(new List <string> {
                "1,2", "3,1", "2,4", "4,3", "4,5", "10,11", "11,12", "12,10"
            }, out nodeMap,
                                          out edgeMap, specs.CreateShape, specs.RandomShapeSize);
            var cycles = g.FindCycles();

            if (cycles.Count > 0)
            {
                foreach (var cycle in cycles)
                {
                    var path = new GraphPath <Node, Edge>();
                    cycle.ToList().ForEach(path.AddNode);
                    this.Highlight(path, nodeMap, edgeMap, specs.HighlightBrush);
                }
            }
            diagram.Layout(LayoutType.Tree, new TreeLayoutSettings
            {
                TreeLayoutType       = TreeLayoutType.TreeRight,
                VerticalSeparation   = 50d,
                HorizontalSeparation = 80d
            });
        }
Beispiel #7
0
 public static void CreateGraph(this RadDiagram diagram, GraphGenerationSpecifications specs, CreateShapeDelegate createShape)
 {
     diagram.Clear();
     if (specs.Connections)
     {
         var g = specs.Connected ? GraphExtensions.CreateRandomConnectedGraph(specs.NodeCount, 4, specs.TreeGraph) : GraphExtensions.CreateRandomGraph(specs.NodeCount, 4, specs.TreeGraph);
         diagram.CreateDiagram(g, GraphExtensions.CreateShape, specs.RandomShapeSize);
     }
     else
     {
         for (var i = 0; i < specs.NodeCount; i++)
         {
             var shape = createShape(new Node(i, false), specs.RandomShapeSize);
             diagram.AddShape(shape);
         }
     }
 }
Beispiel #8
0
 /// <summary>
 /// Creates a balanced radial forest.
 /// </summary>
 /// <param name="diagram">The diagram.</param>
 /// <param name="specs">The specs.</param>
 public static void BalancedRadialForest(this RadDiagram diagram, GraphGenerationSpecifications specs)
 {
     diagram.Clear();
     Dictionary<Node, RadDiagramShape> nodeMap;
     Dictionary<Edge, RadDiagramConnection> edgeMap;
     var g = diagram.CreateDiagram(CreateBalancedForest(), out nodeMap, out edgeMap, CreateShape, specs.RandomShapeSize);
     var settings = new TreeLayoutSettings
     {
         TreeLayoutType = specs.TreeType,
         HorizontalSeparation = specs.HorizontalSeparation,
         VerticalSeparation = specs.VerticalSeparation,
         UnderneathHorizontalOffset = specs.UnderneathHorizontalOffset,
         UnderneathVerticalSeparation = specs.UnderneathVerticalSeparation,
         KeepComponentsInOneRadialLayout = specs.KeepComponentsInOneRadialLayout
     };
     var center = g.FindNode(1);
     settings.Roots.Add(nodeMap[center]);
     var layout = new TreeLayout();
     layout.Layout(diagram, settings);
     diagram.AutoFit();
 }
Beispiel #9
0
        /// <summary>
        /// Creates a balanced radial forest.
        /// </summary>
        /// <param name="diagram">The diagram.</param>
        /// <param name="specs">The specs.</param>
        public static void BalancedRadialForest(this RadDiagram diagram, GraphGenerationSpecifications specs)
        {
            diagram.Clear();
            Dictionary <Node, RadDiagramShape>      nodeMap;
            Dictionary <Edge, RadDiagramConnection> edgeMap;
            var g        = diagram.CreateDiagram(CreateBalancedForest(), out nodeMap, out edgeMap, CreateShape, specs.RandomShapeSize);
            var settings = new TreeLayoutSettings
            {
                TreeLayoutType                  = specs.TreeType,
                HorizontalSeparation            = specs.HorizontalSeparation,
                VerticalSeparation              = specs.VerticalSeparation,
                UnderneathHorizontalOffset      = specs.UnderneathHorizontalOffset,
                UnderneathVerticalSeparation    = specs.UnderneathVerticalSeparation,
                KeepComponentsInOneRadialLayout = specs.KeepComponentsInOneRadialLayout
            };
            var center = g.FindNode(1);

            settings.Roots.Add(nodeMap[center]);
            var layout = new TreeLayout();

            layout.Layout(diagram, settings);
            diagram.AutoFit();
        }
Beispiel #10
0
 /// <summary>
 /// Creates a forest of balanced radial tree and applies a radial layout.
 /// </summary>
 /// <param name="diagram">The diagram.</param>
 /// <param name="specs">The specs.</param>
 private static void BalancedRadialForest(RadDiagram diagram, GraphGenerationSpecifications specs)
 {
     specs.TreeType = TreeLayoutType.RadialTree;
     specs.KeepComponentsInOneRadialLayout = true;
     diagram.BalancedRadialForest(specs);
 }
Beispiel #11
0
 public static void CreateGraph(this RadDiagram diagram, GraphGenerationSpecifications specs, CreateShapeDelegate createShape)
 {
     diagram.Clear();
     if (specs.Connections)
     {
         var g = specs.Connected ? GraphExtensions.CreateRandomConnectedGraph(specs.NodeCount, 4, specs.TreeGraph) : GraphExtensions.CreateRandomGraph(specs.NodeCount, 4, specs.TreeGraph);
         diagram.CreateDiagram(g, GraphExtensions.CreateShape, specs.RandomShapeSize);
     }
     else
     {
         for (var i = 0; i < specs.NodeCount; i++)
         {
             var shape = createShape(new Node(i, false), specs.RandomShapeSize, null);
             diagram.AddShape(shape);
         }
     }
 }
Beispiel #12
0
 /// <summary>
 /// Creates a specific graph which has some obvious cycles and lets the graph analysis highlight them, thus confirming the cycles
 /// which can be easily found manually. The analysis goes of course beyond what the human eye can see and would find cycles in an arbitrary graph.
 /// </summary>
 /// <param name="diagram">The diagram.</param>
 /// <param name="specs">The specs.</param>
 private void Cycles(RadDiagram diagram, GraphGenerationSpecifications specs)
 {
     diagram.Clear();
     Dictionary<Node, RadDiagramShape> nodeMap;
     Dictionary<Edge, RadDiagramConnection> edgeMap;
     var g = diagram.CreateDiagram(new List<string> { "1,2", "3,1", "2,4", "4,3", "4,5", "10,11", "11,12", "12,10" }, out nodeMap,
         out edgeMap, specs.CreateShape, specs.RandomShapeSize);
     var cycles = g.FindCycles();
     if (cycles.Count > 0)
     {
         foreach (var cycle in cycles)
         {
             var path = new GraphPath<Node, Edge>();
             cycle.ToList().ForEach(path.AddNode);
             this.Highlight(path, nodeMap, edgeMap, specs.HighlightBrush);
         }
     }
     diagram.Layout(LayoutType.Tree, new TreeLayoutSettings
                                         {
                                             TreeLayoutType = TreeLayoutType.TreeRight,
                                             VerticalSeparation = 50d,
                                             HorizontalSeparation = 80d
                                         });
 }
Beispiel #13
0
        /// <summary>
        /// Creates a specific diagram and highlight the longest path found through the graph analysis.
        /// </summary>
        /// <param name="diagram">The diagram.</param>
        /// <param name="specs">The specs.</param>
        private void LongestPath(RadDiagram diagram, GraphGenerationSpecifications specs)
        {
            diagram.Clear();
            Dictionary<Node, RadDiagramShape> nodeMap;
            Dictionary<Edge, RadDiagramConnection> edgeMap;

            // this creates the specific graph
            var g = this.diagram.CreateDiagram(new List<string> { "1,2", "2,3", "2,4", "3,5", "4,5", "5,6", "2,7", "7,8", "8,9", "9,10", "10,6", "20,21", "21,22", "20,25" }, out nodeMap, out edgeMap, GraphExtensions.CreateShape, this.RandomSizeCheck.IsChecked.HasValue && this.RandomSizeCheck.IsChecked.Value);

            // note that this works on disconnected graphs as well as on connected ones
            var path = g.FindLongestPath();

            // highlight the longest path if one is found
            if (path != null) this.Highlight(path, nodeMap, edgeMap, this.HighlighBrush);

            // use a layout which displays the result best
            diagram.Layout(LayoutType.Tree, new TreeLayoutSettings
            {
                TreeLayoutType = TreeLayoutType.TreeUp,
                VerticalSeparation = 80d,
                HorizontalSeparation = 50d
            });
        }
Beispiel #14
0
        /// <summary>
        /// Creates a random connected graph and displayes a (non-unique) spanning tree using Prim's algorithm.
        /// </summary>
        /// <param name="diagram">The diagram.</param>
        /// <param name="specs">The specs.</param>
        private void Prims(RadDiagram diagram, GraphGenerationSpecifications specs)
        {
            diagram.Clear();
            Dictionary<Node, RadDiagramShape> nodeMap;
            Dictionary<Edge, RadDiagramConnection> edgeMap;
            var randomConnectedGraph = GraphExtensions.CreateRandomConnectedGraph(10);
            var root = randomConnectedGraph.FindTreeRoot();
            var g = diagram.CreateDiagram(randomConnectedGraph, out nodeMap, out edgeMap, GraphExtensions.CreateShape, specs.RandomShapeSize);

            // making it undirected will reach all the nodes since the random graph is connected
            g.IsDirected = false;
            var tree = g.PrimsSpanningTree(root);
            if (tree != null) this.Highlight(tree, nodeMap, edgeMap, this.HighlighBrush);
            var settings = new TreeLayoutSettings
            {
                TreeLayoutType = TreeLayoutType.TreeDown,
                VerticalSeparation = 50d,
                HorizontalSeparation = 80d,
            };
            diagram.Layout(LayoutType.Tree, settings);
        }
Beispiel #15
0
 /// <summary>
 /// Creates a forest of unbalanced trees and applies a radial layout.
 /// </summary>
 /// <param name="diagram">The diagram.</param>
 /// <param name="specs">The specs.</param>
 private void RandomRadialForest(RadDiagram diagram, GraphGenerationSpecifications specs)
 {
     this.diagram.Clear();
     Dictionary<Node, RadDiagramShape> nodeMap;
     Dictionary<Edge, RadDiagramConnection> edgeMap;
     var g = this.diagram.CreateDiagram(GraphExtensions.CreateRandomGraph(250, 4, true), out nodeMap, out edgeMap, GraphExtensions.CreateShape, this.RandomSizeCheck.IsChecked.HasValue && this.RandomSizeCheck.IsChecked.Value);
     var settings = new TreeLayoutSettings
     {
         TreeLayoutType = TreeLayoutType.RadialTree,
         HorizontalSeparation = this.HorizontalSeparationSlider.Value,
         VerticalSeparation = this.VerticalSeparationSlider.Value,
         UnderneathHorizontalOffset = this.UnderneathHorizontalOffsetSlider.Value,
         UnderneathVerticalSeparation = this.UnderneathVerticalOffsetSlider.Value,
         KeepComponentsInOneRadialLayout = true,
         RadialSeparation = 45d
     };
     var center = g.FindNode(0);
     settings.Roots.Add(nodeMap[center]);
     var layout = new TreeLayout();
     layout.Layout(this.diagram, settings);
     this.diagram.AutoFit();
     //Colorize(g, nodeMap, center);
 }
Beispiel #16
0
 /// <summary>
 /// Creates a forest of balanced radial tree and applies a radial layout.
 /// </summary>
 /// <param name="diagram">The diagram.</param>
 /// <param name="specs">The specs.</param>
 private static void BalancedRadialForest(RadDiagram diagram, GraphGenerationSpecifications specs)
 {
     specs.TreeType = TreeLayoutType.RadialTree;
     specs.KeepComponentsInOneRadialLayout = true;
     diagram.BalancedRadialForest(specs);
 }
Beispiel #17
0
        /// <summary>
        /// Creates a specific graph to show the shortest path between two nodes. 
        /// </summary>
        /// <param name="obj">The diagram.</param>
        /// <param name="specs">The specs.</param>
        private void ShortestPath(RadDiagram obj, GraphGenerationSpecifications specs)
        {
            this.diagram.Clear();
            Dictionary<Node, RadDiagramShape> nodeMap;
            Dictionary<Edge, RadDiagramConnection> edgeMap;
            var g = this.diagram.CreateDiagram(new List<string> { "1,2", "2,3", "1,4", "4,5", "5,3", "1,6", "6,7", "7,8", "8,3", "3,9", "9,10", "10,11" }, out nodeMap, out edgeMap, GraphExtensions.CreateShape, this.RandomSizeCheck.IsChecked.HasValue && this.RandomSizeCheck.IsChecked.Value);

            // Dijkstra's algorithm will give you the shortest path
            var path = g.DijkstraShortestPath(1, 11);
            if (path != null) this.Highlight(path, nodeMap, edgeMap, this.HighlighBrush);

            // the node map gives us the shape from a node and we want to have the "1" node at the root of the tree
            var nodeOne = g.FindNode(1);
            var shapeOne = nodeMap[nodeOne];
            var settings = new TreeLayoutSettings
            {
                TreeLayoutType = TreeLayoutType.TreeDown,
                VerticalSeparation = 50d,
                HorizontalSeparation = 80d,
            };
            // specifying the root (or roots if we have a forest) can be done using the Roots property like so
            settings.Roots.Add(shapeOne);
            diagram.Layout(LayoutType.Tree, settings);
        }
Beispiel #18
0
        /// <summary>
        /// Creates a tree which grows symmetrically.
        /// </summary>
        /// <param name="diagram">The diagram.</param>
        /// <param name="specs">The specs.</param>
        private void BalancedRadialTree(RadDiagram diagram, GraphGenerationSpecifications specs)
        {
            this.diagram.Clear();
            Dictionary<Node, RadDiagramShape> nodeMap;
            Dictionary<Edge, RadDiagramConnection> edgeMap;

            // the algorithm to create a balanced tree is quite straighforward
            var g = this.diagram.CreateDiagram(GraphExtensions.CreateBalancedTree(), out nodeMap, out edgeMap, GraphExtensions.CreateShape, this.RandomSizeCheck.IsChecked.HasValue && this.RandomSizeCheck.IsChecked.Value);

            // the result is best displayed with the radial tree layout
            var settings = new TreeLayoutSettings
            {
                TreeLayoutType = TreeLayoutType.RadialTree,
                HorizontalSeparation = this.HorizontalSeparationSlider.Value,
                VerticalSeparation = this.VerticalSeparationSlider.Value,
                UnderneathHorizontalOffset = this.UnderneathHorizontalOffsetSlider.Value,
                UnderneathVerticalSeparation = this.UnderneathVerticalOffsetSlider.Value,
                StartRadialAngle = Math.PI,
                // use a specific angle rather than the full 360° to show one of the layout's (hidden) gem
                EndRadialAngle = 3.47 * Math.PI / 2
            };
            var center = g.FindNode(-1);
            settings.Roots.Add(nodeMap[center]);
            var layout = new TreeLayout();

            layout.Layout(this.diagram, settings);

            // center and size autimagically
            this.diagram.AutoFit();

            // you can colorize the shapes, if you wish
            // this.Colorize(g, nodeMap, center);
        }