public SugiyamaLayoutAlgorithm( TGraph visitedGraph, IDictionary <TVertex, Size> vertexSizes, SugiyamaLayoutParameters parameters, Func <TEdge, EdgeTypes> edgePredicate) : this(visitedGraph, vertexSizes, null, parameters, edgePredicate) { }
/// <summary> /// Performs the actual layout algorithm. /// </summary> /// <param name="graph">The object containing the graph data</param> /// <param name="rootNode">Root node</param> protected override void PerformLayout(GraphMapData graph, INode rootNode) { AdjacencyGraph<string, Edge<string>> adjacencyGraph = GraphSharpUtility.GetAdjacencyGraph(graph); IDictionary<string, Size> nodeSizes = GraphSharpUtility.GetNodeSizes(graph); IDictionary<string, Vector> nodePositions = GraphSharpUtility.GetNodePositions(graph); SugiyamaLayoutParameters sugiyamaLayoutParameters = new SugiyamaLayoutParameters(); SugiyamaLayoutAlgorithm<string, Edge<string>, AdjacencyGraph<string, Edge<string>>> sugiyamaLayoutAlgorithm = new SugiyamaLayoutAlgorithm<string, Edge<string>, AdjacencyGraph<string, Edge<string>>>(adjacencyGraph, nodeSizes, nodePositions, sugiyamaLayoutParameters, GetEdgeType); sugiyamaLayoutAlgorithm.Compute(); GraphSharpUtility.SetNodePositions(graph, sugiyamaLayoutAlgorithm.VertexPositions); }
public SugiyamaLayoutAlgorithm( TGraph visitedGraph, IDictionary <TVertex, Size> vertexSizes, SugiyamaLayoutParameters parameters, Func <TEdge, EdgeTypes> edgePredicate) : this(visitedGraph, vertexSizes, null, parameters, edgePredicate) { Contract.Requires(edgePredicate != null); Contract.Requires(vertexSizes != null); Contract.Requires(parameters == null || Parameters.HorizontalGap >= 0); Contract.Requires(parameters == null || Parameters.VerticalGap >= 0); }
public SugiyamaLayoutAlgorithm( TGraph visitedGraph, IDictionary <TVertex, Size> vertexSizes, IDictionary <TVertex, Point> vertexPositions, SugiyamaLayoutParameters parameters, Func <TEdge, EdgeTypes> edgePredicate) : base(visitedGraph, vertexPositions, parameters) { _edgePredicate = edgePredicate; EdgeRoutes = new Dictionary <TEdge, Point[]>(); ConvertGraph(vertexSizes); }
public SugiyamaLayoutAlgorithm( TGraph visitedGraph, IDictionary <TVertex, Size> vertexSizes, IDictionary <TVertex, Point> vertexPositions, SugiyamaLayoutParameters parameters, Func <TEdge, EdgeTypes> edgePredicate) : base(visitedGraph, vertexPositions, parameters) { Contract.Requires(edgePredicate != null); Contract.Requires(vertexSizes != null); _edgePredicate = edgePredicate; EdgeRoutes = new Dictionary <TEdge, IList <Point> >(); ConvertGraph(vertexSizes); }
public void RefineLayout(int iterations) { // Prepare state for algorithm. BidirectionalGraph<string, IEdge<string>> graph = new BidirectionalGraph<string, IEdge<string>>(false); Dictionary<string, Point> positions = new Dictionary<string, Point>(); // Anything to do? if (BayesianNetwork.VariablesOrdered.Any() == false) { this.Positions = new Dictionary<string, Point>(); IterationCount += iterations; return; } Random random = new Random(0); foreach (var rv in BayesianNetwork.VariablesOrdered) { graph.AddVertex(rv.Name); foreach (var child in rv.Children.Select(c => BayesianNetwork.GetVariable(c))) { graph.AddVertex(child.Name); graph.AddEdge(new Edge<string>(rv.Name, child.Name)); } // If we have no existing layout yet, lets try to prime the // alg by putting pure parents at top and pure children at // bottom. if (Positions.Count != 0) { // We have existing layout. Start with it but add slight // randomness. Point positionNoised; if (Positions.ContainsKey(rv.Name)) { positionNoised = Positions[rv.Name]; } else { positionNoised = new Point(); } positionNoised.X += (random.NextDouble() - 0.5) * 0.01; positionNoised.Y += (random.NextDouble() - 0.5) * 0.01; positions[rv.Name] = positionNoised; } } // Initialize algorithm. var layoutAlgorithms = new StandardLayoutAlgorithmFactory<string, IEdge<string>, IBidirectionalGraph<string, IEdge<string>>>(); var layoutContext = new LayoutContext<string, IEdge<string>, IBidirectionalGraph<string, IEdge<string>>>( graph, positions, _sizes, LayoutMode.Simple); ILayoutAlgorithm<string, IEdge<string>, IBidirectionalGraph<string, IEdge<string>>> layoutAlgorithm; var algorithm = this._options.Algorithm; // Hack: SugiyamaEfficient breaks if no edges. if (algorithm == NetworkLayoutOptions.AlgorithmEnum.KK || graph.Edges.Count() == 0) { var layoutParameters = new KKLayoutParameters(); layoutParameters.Height = 1000; layoutParameters.Width = 1000; layoutParameters.MaxIterations = iterations; layoutParameters.LengthFactor = 1.35; layoutParameters.K *= 10.1; layoutParameters.AdjustForGravity = false; layoutAlgorithm = layoutAlgorithms.CreateAlgorithm("KK", layoutContext, layoutParameters); } else if (algorithm == NetworkLayoutOptions.AlgorithmEnum.SugiyamaEfficient) { var layoutParameters = new EfficientSugiyamaLayoutParameters(); layoutParameters.MinimizeEdgeLength = true; layoutParameters.OptimizeWidth = true; layoutParameters.WidthPerHeight = 1.65; layoutParameters.VertexDistance = this._options.NodeSeparationTarget; layoutParameters.LayerDistance = 5.0; layoutAlgorithm = layoutAlgorithms.CreateAlgorithm("EfficientSugiyama", layoutContext, layoutParameters); } else if (algorithm == NetworkLayoutOptions.AlgorithmEnum.Sugiyama) { var layoutParameters = new SugiyamaLayoutParameters(); layoutParameters.MaxWidth = 1024; layoutParameters.VerticalGap = 1.0f; layoutParameters.DirtyRound = true; layoutAlgorithm = layoutAlgorithms.CreateAlgorithm("Sugiyama", layoutContext, layoutParameters); } else if (algorithm == NetworkLayoutOptions.AlgorithmEnum.CompoundFDP) { var layoutParameters = new CompoundFDPLayoutParameters(); layoutParameters.GravitationFactor = 0.8; layoutParameters.IdealEdgeLength = 30; layoutParameters.RepulsionConstant = 300; layoutAlgorithm = layoutAlgorithms.CreateAlgorithm("CompoundFDP", layoutContext, layoutParameters); } else { throw new InvalidOperationException("Unknown layout."); } // Compute. layoutAlgorithm.Compute(); // Store Results. this.Positions = layoutAlgorithm.VertexPositions.ToDictionary( (kvp) => kvp.Key, (kvp) => kvp.Value ); // Done. IterationCount += iterations; }
private void CreateAndRunSugiyamaLayout(Dictionary<DiagramShape, Size> sizeDictionary, BidirectionalGraph<DiagramShape, IEdge<DiagramShape>> graph, SugiyamaLayoutParameters parameters) { layoutAlgorithm = new SugiyamaLayoutAlgorithm<DiagramShape, IEdge<DiagramShape>, IBidirectionalGraph<DiagramShape, IEdge<DiagramShape>>>( graph, sizeDictionary, parameters, e => EdgeTypes.Hierarchical); layoutAlgorithm.Compute(); }