public EfficientSugiyamaLayoutAlgorithm( TGraph visitedGraph, EfficientSugiyamaLayoutParameters parameters, IDictionary <TVertex, Size> vertexSizes) : this(visitedGraph, parameters, null, vertexSizes) { }
public EfficientSugiyamaLayoutAlgorithm( TGraph visitedGraph, EfficientSugiyamaLayoutParameters parameters, IDictionary <TVertex, Point> vertexPositions, IDictionary <TVertex, Size> vertexSizes) : base(visitedGraph, vertexPositions, parameters) { _vertexSizes = vertexSizes; }
/// <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); EfficientSugiyamaLayoutParameters efficientSugiyamaLayoutParameters = new EfficientSugiyamaLayoutParameters(); IDictionary<string, Vector> nodePositions = GraphSharpUtility.GetNodePositions(graph); IDictionary<string, Size> nodeSizes = GraphSharpUtility.GetNodeSizes(graph); EfficientSugiyamaLayoutAlgorithm<string, Edge<string>, AdjacencyGraph<string, Edge<string>>> efficientSugiyamaLayoutAlgorithm = new EfficientSugiyamaLayoutAlgorithm<string, Edge<string>, AdjacencyGraph<string, Edge<string>>>(adjacencyGraph, efficientSugiyamaLayoutParameters, nodePositions, nodeSizes); efficientSugiyamaLayoutAlgorithm.Compute(); GraphSharpUtility.SetNodePositions(graph, efficientSugiyamaLayoutAlgorithm.VertexPositions); }
public ProjectDependenciesGraphLayoutControl() { InitializeComponent(); graphLayout.LayoutAlgorithmType = "EfficientSugiyama"; graphLayout.HighlightAlgorithmType = "Simple"; var layoutParameters = new EfficientSugiyamaLayoutParameters(); layoutParameters.EdgeRouting = SugiyamaEdgeRoutings.Traditional; layoutParameters.MinimizeEdgeLength = false; layoutParameters.OptimizeWidth = false; graphLayout.LayoutParameters = layoutParameters; }
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; }