internal static void ShowRectangles(IEnumerable <VariableDef> variableDefs, IEnumerable <ClusterDef> clusterDefs) { if (!ShowRects) { return; } #if TEST_MSAGL var variableDebugCurves = new List <DebugCurve>(); var clusterDebugCurves = new List <DebugCurve>(); if (variableDefs != null) { variableDebugCurves.AddRange(variableDefs.Select(v => new Rectangle(v.Left, v.Top, v.Right, v.Bottom)).Select( rect => new DebugCurve(0.1, "black", CurveFactory.CreateRectangle(rect)))); } if (clusterDefs != null) { clusterDebugCurves.AddRange(clusterDefs.Select(v => new Rectangle(v.Left, v.Top, v.Right, v.Bottom)).Select( rect => new DebugCurve(0.1, "green", CurveFactory.CreateRectangle(rect)))); } System.Diagnostics.Debug.WriteLine("ShowRectangles: there are {0} variables and {1} clusters", variableDebugCurves.Count, clusterDebugCurves.Count); SugiyamaLayoutSettings.ShowDebugCurvesEnumeration(variableDebugCurves.Concat(clusterDebugCurves)); #else // TEST_MSAGL System.Diagnostics.Debug.WriteLine("-show* options require TEST mode"); #endif // TEST_MSAGL }
static void TransferVerticalConstraints(VerticalConstraintsForLayeredLayout verticalConstraints, SugiyamaLayoutSettings sugiyamaLayoutSettings) { foreach (Node node in verticalConstraints._minLayerOfDrawingGraph) { CheckGeomNode(node); sugiyamaLayoutSettings.PinNodesToMinLayer(node.GeometryNode); } foreach (Node node in verticalConstraints._maxLayerOfDrawingGraph) { CheckGeomNode(node); sugiyamaLayoutSettings.PinNodesToMaxLayer(node.GeometryNode); } foreach (var couple in verticalConstraints.SameLayerConstraints) { CheckGeomNode(couple.Item1); CheckGeomNode(couple.Item2); sugiyamaLayoutSettings.PinNodesToSameLayer(couple.Item1.GeometryNode, couple.Item2.GeometryNode); } foreach (var couple in verticalConstraints.UpDownConstraints) { CheckGeomNode(couple.Item1); CheckGeomNode(couple.Item2); sugiyamaLayoutSettings.AddUpDownConstraint(couple.Item1.GeometryNode, couple.Item2.GeometryNode); } }
// Abstract the creation of the GeometryGraph and the node.CreateBoundary calls away in // a single call on the Diagram. public void Run() { drawingGraph.CreateGeometryGraph(); foreach (var node in drawingGraph.Nodes) { if (node is LabeledNode ln) { ln.CreateBoundary(); } } var routingSettings = new Microsoft.Msagl.Core.Routing.EdgeRoutingSettings { UseObstacleRectangles = true, BendPenalty = 100, EdgeRoutingMode = Microsoft.Msagl.Core.Routing.EdgeRoutingMode.StraightLine }; var settings = new SugiyamaLayoutSettings { ClusterMargin = 50, PackingAspectRatio = 3, PackingMethod = Microsoft.Msagl.Core.Layout.PackingMethod.Columns, RepetitionCoefficientForOrdering = 0, EdgeRoutingSettings = routingSettings, NodeSeparation = 50, LayerSeparation = 150 }; LayoutHelpers.CalculateLayout(drawingGraph.GeometryGraph, settings, null); _run(); }
static void ProcessSugiamaLayout(GeometryGraph geometryGraph, SugiyamaLayoutSettings sugiyamaLayoutSettings, CancelToken cancelToken) { PlaneTransformation originalTransform; var transformIsNotIdentity = HandleTransformIsNotIdentity(geometryGraph, sugiyamaLayoutSettings, out originalTransform); if (geometryGraph.RootCluster.Clusters.Any()) { PrepareGraphForInitialLayoutByCluster(geometryGraph, sugiyamaLayoutSettings); var initialBc = new InitialLayoutByCluster( geometryGraph, //use different settings per each Cluster if available c => sugiyamaLayoutSettings.ClusterSettings.ContainsKey(c.UserData) ? sugiyamaLayoutSettings.ClusterSettings[c.UserData] : sugiyamaLayoutSettings); initialBc.Run(cancelToken); //route the rest of the edges, those between the clusters var edgesToRoute = sugiyamaLayoutSettings.EdgeRoutingSettings.EdgeRoutingMode == EdgeRoutingMode.SplineBundling ? geometryGraph.Edges.ToArray() : geometryGraph.Edges.Where(e => e.Curve == null).ToArray(); RouteAndLabelEdges(geometryGraph, sugiyamaLayoutSettings, edgesToRoute, 0, cancelToken); } else { geometryGraph.AlgorithmData = SugiyamaLayoutSettings.CalculateLayout(geometryGraph, sugiyamaLayoutSettings, cancelToken); } if (transformIsNotIdentity) { sugiyamaLayoutSettings.Transformation = originalTransform; } PostRunTransform(geometryGraph, sugiyamaLayoutSettings); }
public void VisualizeNeuralNetToFile(string neuralNetPicFilePath) { FastIncrementalLayoutSettings fastSettings = new FastIncrementalLayoutSettings { AvoidOverlaps = true, NodeSeparation = 30, RouteEdges = true }; SugiyamaLayoutSettings settings = new SugiyamaLayoutSettings { FallbackLayoutSettings = fastSettings }; m_opsViz.LayoutAlgorithmSettings = settings; Microsoft.Msagl.GraphViewerGdi.GraphRenderer renderer = new Microsoft.Msagl.GraphViewerGdi.GraphRenderer(m_opsViz); renderer.CalculateLayout(); System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap((int)m_opsViz.Width, (int)m_opsViz.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb); renderer.Render(bitmap); bitmap.Save(neuralNetPicFilePath); bitmap.Dispose(); }
public void ConstraintWithTransformation() { Random random = new Random(999); GeometryGraph graph = GraphGenerator.GenerateOneSimpleGraph(); GraphGenerator.SetRandomNodeShapes(graph, random); SugiyamaLayoutSettings settings = new SugiyamaLayoutSettings(); //layer direction to be left to right settings.Transformation = PlaneTransformation.Rotation(Math.PI / 2); List <Node> nodes = graph.Nodes.ToList(); settings.AddUpDownConstraint(nodes[0], nodes[1]); settings.AddLeftRightConstraint(nodes[3], nodes[4]); settings.AddUpDownVerticalConstraint(nodes[0], nodes[3]); settings.AddSameLayerNeighbors(nodes[2], nodes[4]); LayeredLayout layeredLayout = new LayeredLayout(graph, settings); layeredLayout.Run(); ShowGraphInDebugViewer(graph); SugiyamaValidation.ValidateUpDownConstraint(nodes[0], nodes[1]); SugiyamaValidation.ValidateLeftRightConstraint(nodes[3], nodes[4]); SugiyamaValidation.ValidateUpDownVerticalConstraint(nodes[0], nodes[3]); SugiyamaValidation.ValidateNeighborConstraint(graph, nodes[2], nodes[4], settings); }
public frmGraphView() { //--------------------------------------------------------------------------------------- //Remove Debug Asserts from Graph Tool - may have adverse side effects elsewhere though!! Debug.Listeners.Clear(); //--------------------------------------------------------------------------------------- mdsLayoutSettings = new MdsLayoutSettings(); sugiyamaSettings = new SugiyamaLayoutSettings(); InitializeComponent(); SuspendLayout(); viewer.Dock = DockStyle.Fill; //Mouse Double Click Handler viewer.MouseDoubleClick += Viewer_MouseDoubleClick; //Mouse over / Object select Handler viewer.ObjectUnderMouseCursorChanged += Viewer_ObjectUnderMouseCursorChanged; //Key Press handler viewer.KeyPress += Viewer_KeyPress; viewer.KeyDown += Viewer_KeyDown; viewer.KeyUp += Viewer_KeyUp; //Add viewer Controls.Add(viewer); //Make it dock under the top panel viewer.BringToFront(); viewer.OutsideAreaBrush = new SolidBrush(Color.White); ResumeLayout(); }
static void TransformCurves(GeometryGraph geometryGraph, SugiyamaLayoutSettings settings) { PlaneTransformation transformation = settings.Transformation; geometryGraph.BoundingBox = new Rectangle(transformation * geometryGraph.LeftBottom, transformation * geometryGraph.RightTop); foreach (Edge e in geometryGraph.Edges) { if (e.Label != null) { e.Label.Center = transformation * e.Label.Center; } if (e.Curve != null) { e.Curve = e.Curve.Transform(transformation); var eg = e.EdgeGeometry; if (eg.SourceArrowhead != null) { eg.SourceArrowhead.TipPosition = transformation * eg.SourceArrowhead.TipPosition; } if (eg.TargetArrowhead != null) { eg.TargetArrowhead.TipPosition = transformation * eg.TargetArrowhead.TipPosition; } TransformUnderlyingPolyline(e, settings); } } }
static bool HandleTransformIsNotIdentity(GeometryGraph geometryGraph, SugiyamaLayoutSettings sugiyamaLayoutSettings, out PlaneTransformation originalTransform) { var transformIsNotIdentity = !sugiyamaLayoutSettings.Transformation.IsIdentity; originalTransform = sugiyamaLayoutSettings.Transformation; if (transformIsNotIdentity) { var m = sugiyamaLayoutSettings.Transformation.Inverse; foreach (Node n in geometryGraph.Nodes) { n.Transform(m); } //calculate new label widths and heights foreach (Edge e in geometryGraph.Edges) { if (e.Label != null) { e.OriginalLabelWidth = e.Label.Width; e.OriginalLabelHeight = e.Label.Height; var r = new Rectangle(m * new Point(0, 0), m * new Point(e.Label.Width, e.Label.Height)); e.Label.Width = r.Width; e.Label.Height = r.Height; } } } sugiyamaLayoutSettings.Transformation = PlaneTransformation.UnitTransformation; //restore it later return(transformIsNotIdentity); }
static void ProcessSugiamaLayout(GeometryGraph geometryGraph, SugiyamaLayoutSettings sugiyamaLayoutSettings, CancelToken cancelToken) { PlaneTransformation originalTransform; var transformIsNotIdentity = HandleTransformIsNotIdentity(geometryGraph, sugiyamaLayoutSettings, out originalTransform); if (geometryGraph.RootCluster.Clusters.Any()) { PrepareGraphForInitialLayoutByCluster(geometryGraph, sugiyamaLayoutSettings); var initialBc = new InitialLayoutByCluster(geometryGraph, a => sugiyamaLayoutSettings); initialBc.Run(cancelToken); //route the rest of the edges, those between the clusters RouteAndLabelEdges(geometryGraph, sugiyamaLayoutSettings, geometryGraph.Edges.Where(e => e.Curve == null).ToArray()); } else { geometryGraph.AlgorithmData = SugiyamaLayoutSettings.CalculateLayout(geometryGraph, sugiyamaLayoutSettings, cancelToken); } if (transformIsNotIdentity) { sugiyamaLayoutSettings.Transformation = originalTransform; } PostRunTransform(geometryGraph, sugiyamaLayoutSettings); }
public void NodeShapeChange() { // Setup string filePath = Path.Combine(this.TestContext.TestDir, "Out\\Dots", "chat.dot"); GeometryGraph graph = this.LoadGraph(filePath); var settings = new SugiyamaLayoutSettings(); // Initial layout LayeredLayout layeredLayout = new LayeredLayout(graph, settings); layeredLayout.Run(); SortedList <double, SortedList <double, Node> > originalLayers = SugiyamaValidation.GetLayers(graph, true); // Incremental layout List <Node> nodes = graph.Nodes.ToList(); for (int i = 0; i < nodes.Count; i++) { // Resize a node Node node = nodes[i]; node.BoundaryCurve = node.BoundaryCurve.ScaleFromOrigin(2.0, 2.0); // Run incremental layout LayeredLayout.IncrementalLayout(graph, node); // Verify - the layering and ordering of nodes should not have changed. SortedList <double, SortedList <double, Node> > newLayers = SugiyamaValidation.GetLayers(graph, true); VerifyLayersAreEqual(originalLayers, newLayers); } }
private static void LayoutAndValidate(GeometryGraph graph, SugiyamaLayoutSettings settings, double nodeSeparation, double layerSeparation, LayerDirection direction) { settings.NodeSeparation = nodeSeparation; switch (direction) { case LayerDirection.None: case LayerDirection.TopToBottom: break; case LayerDirection.BottomToTop: settings.Transformation = PlaneTransformation.Rotation(Math.PI); break; case LayerDirection.LeftToRight: settings.Transformation = PlaneTransformation.Rotation(Math.PI / 2); break; case LayerDirection.RightToLeft: settings.Transformation = PlaneTransformation.Rotation(-Math.PI / 2); break; } settings.LayerSeparation = layerSeparation; LayeredLayout layeredLayout = new LayeredLayout(graph, settings); layeredLayout.Run(); ShowGraphInDebugViewer(graph); // SugiyamaValidation.ValidateGraph(graph, settings); }
void LayoutOneComponent(GeometryGraph component) { PrepareGraphForLayout(component); if (component.RootCluster.Clusters.Any()) { var layoutSettings = new SugiyamaLayoutSettings { FallbackLayoutSettings = new FastIncrementalLayoutSettings { AvoidOverlaps = true }, NodeSeparation = lgLayoutSettings.NodeSeparation, LayerSeparation = lgLayoutSettings.NodeSeparation, EdgeRoutingSettings = lgLayoutSettings.EdgeRoutingSettings, LayeringOnly = true }; var initialBc = new InitialLayoutByCluster(component, a => layoutSettings); initialBc.Run(); } else { LayoutHelpers.CalculateLayout(component, GetMdsLayoutSettings(), cancelToken); } var box = component.BoundingBox; box.Pad(lgLayoutSettings.NodeSeparation / 2); component.BoundingBox = box; }
static void PostRunTransform(GeometryGraph geometryGraph, SugiyamaLayoutSettings settings) { bool transform = !settings.Transformation.IsIdentity; if (transform) { foreach (Node n in geometryGraph.Nodes) { n.Transform(settings.Transformation); } foreach (var n in geometryGraph.RootCluster.AllClustersDepthFirst()) { n.Transform(settings.Transformation); if (n.BoundaryCurve != null) { n.RectangularBoundary.Rect = n.BoundaryCurve.BoundingBox; } } //restore labels widths and heights foreach (Edge e in geometryGraph.Edges) { if (e.Label != null) { e.Label.Width = e.OriginalLabelWidth; e.Label.Height = e.OriginalLabelHeight; } } TransformCurves(geometryGraph, settings); } geometryGraph.UpdateBoundingBox(); }
public void MinimumSizeIsRespected() { // Setup string filePath = Path.Combine(this.TestContext.TestDir, "Out\\Dots", "chat.dot"); GeometryGraph graph = this.LoadGraph(filePath); const double DesiredHeight = 100000; const double DesiredWidth = 100000; SugiyamaLayoutSettings settings = new SugiyamaLayoutSettings(); settings.MinimalHeight = DesiredHeight; settings.MinimalWidth = DesiredWidth; // Execute LayeredLayout layeredLayout = new LayeredLayout(graph, settings); layeredLayout.Run(); // Verify the graph is the correct size Assert.IsTrue(DesiredHeight < graph.Height, "Graph height should be the minimal height."); Assert.IsTrue(DesiredWidth < graph.Width, "Graph width should be the minimal width."); // Verify the nodes were spread apart to fill the space Rectangle nodeBounds = new Rectangle(graph.Nodes.Select(n => n.BoundingBox)); Assert.IsTrue(DesiredWidth < nodeBounds.Height, "The graph nodes weren't scaled vertically to fill the space."); Assert.IsTrue(DesiredWidth < nodeBounds.Width, "The graph nodes weren't scaled horizontally to fill the space."); }
public void LayeredLayoutOrientationByCluster() { var clusteredGraph = CreateClusteredGraph(padding: 1); foreach (var e in clusteredGraph.Edges) { e.Labels.Add(new Label(40, 10, e)); } var defaultSettings = new SugiyamaLayoutSettings { NodeSeparation = 5, PackingAspectRatio = 1.3, LayerSeparation = 5 }; var settings = new Dictionary <Cluster, LayoutAlgorithmSettings>(); foreach (var c in clusteredGraph.RootCluster.Clusters) { var localSettings = (SugiyamaLayoutSettings)defaultSettings.Clone(); localSettings.Transformation = PlaneTransformation.Rotation(Math.PI / 2); settings[c] = localSettings; } var layout = new InitialLayoutByCluster(clusteredGraph, c => settings.ContainsKey(c) ? settings[c] : defaultSettings); double progress = 0.0; EnableDebugViewer(); EventHandler <ProgressChangedEventArgs> handler = (s, e) => progress = e.RatioComplete; try { layout.ProgressChanged += handler; layout.Run(); } finally { layout.ProgressChanged -= handler; } double aspectRatio = clusteredGraph.BoundingBox.Width / clusteredGraph.BoundingBox.Height; //Assert.AreEqual(1.0, progress, "Progress was never reported as 100%. Last update was at " + progress + "%"); //var router = new SplineRouter(clusteredGraph, settings.Padding, settings.Padding/2.1, Math.PI/6); //router.Run(); ShowGraphInDebugViewer(clusteredGraph); // lots of components in this graph, it gets pretty close to the ideal aspect ratio Assert.AreEqual(defaultSettings.PackingAspectRatio, aspectRatio, 0.2, "Difference between actual and desired aspect ratios too large"); foreach (var e in clusteredGraph.Edges) { if (e.Source.ClusterParents.Contains(clusteredGraph.RootCluster) || e.Target.ClusterParents.Contains(clusteredGraph.RootCluster)) { Assert.IsTrue(e.Source.Center.Y > e.Target.Center.Y, "Top level edges should be vertical"); } else { Assert.IsTrue(e.Source.Center.X < e.Target.Center.X, "Nested edges should be horizontal"); } } }
internal PhyloTreeLayoutCalclulation(PhyloTree phyloTreeP, SugiyamaLayoutSettings settings, BasicGraph <Node, IntEdge> intGraphP, Database dataBase) { this.dataBase = dataBase; this.tree = phyloTreeP; this.LayoutSettings = settings; this.intGraph = intGraphP; originalNodeToGridLayerIndices = new int[intGraph.Nodes.Count]; }
public void LatticeGraphTests() { GeometryGraph graph = GraphGenerator.GenerateSquareLattice(20); SugiyamaLayoutSettings settings = new SugiyamaLayoutSettings(); GraphGenerator.SetRandomNodeShapes(graph, random); WriteLine("Trying Lattice Graph with Top to Down layer direction"); LayoutAndValidate(graph, settings); }
public void DisjointGraphTests() { GeometryGraph graph = GraphGenerator.GenerateGraphWithSameSubgraphs(3, 6); SugiyamaLayoutSettings settings = new SugiyamaLayoutSettings(); GraphGenerator.SetRandomNodeShapes(graph, random); WriteLine("Trying Disjoint Graph with Left To Right layer direction"); LayoutAndValidate(graph, settings, 32, 25, LayerDirection.LeftToRight); }
public void CircleGraphTests() { GeometryGraph graph = GraphGenerator.GenerateCircle(10); SugiyamaLayoutSettings settings = new SugiyamaLayoutSettings(); GraphGenerator.SetRandomNodeShapes(graph, random); WriteLine("Trying Circle Graph with Top to Down layer direction"); LayoutAndValidate(graph, settings, 18, 10); }
static void PrepareGraphForInitialLayoutByCluster(GeometryGraph geometryGraph, SugiyamaLayoutSettings sugiyamaLayoutSettings) { foreach (var cluster in geometryGraph.RootCluster.AllClustersDepthFirst()) { if (cluster.RectangularBoundary == null) { cluster.RectangularBoundary = new RectangularClusterBoundary() { TopMargin = 10 } } ; if (cluster.BoundaryCurve == null) { cluster.BoundaryCurve = new RoundedRect(new Rectangle(0, 0, 10, 10), 3, 3); } } foreach (var edge in geometryGraph.Edges) { edge.Curve = null; if (edge.SourcePort == null) { var e = edge; #if SHARPKIT // Lambdas bind differently in JS edge.SourcePort = ((Func <Edge, RelativeFloatingPort>)(ed => new RelativeFloatingPort(() => ed.Source.BoundaryCurve, () => ed.Source.Center)))(e); #else edge.SourcePort = new RelativeFloatingPort(() => e.Source.BoundaryCurve, () => e.Source.Center); #endif } if (edge.TargetPort == null) { var e = edge; #if SHARPKIT // Lambdas bind differently in JS edge.TargetPort = ((Func <Edge, RelativeFloatingPort>)(ed => new RelativeFloatingPort(() => ed.Target.BoundaryCurve, () => ed.Target.Center)))(e); #else edge.TargetPort = new RelativeFloatingPort(() => e.Target.BoundaryCurve, () => e.Target.Center); #endif } } if (sugiyamaLayoutSettings.FallbackLayoutSettings == null) { sugiyamaLayoutSettings.FallbackLayoutSettings = new FastIncrementalLayoutSettings() { AvoidOverlaps = true } } ; AddOrphanNodesToRootCluster(geometryGraph); }
static void TransformUnderlyingPolyline(Edge e, SugiyamaLayoutSettings settings) { if (e.UnderlyingPolyline != null) { for (Site s = e.UnderlyingPolyline.HeadSite; s != null; s = s.Next) { s.Point = settings.Transformation * s.Point; } } }
internal void RecalculateLayout() { var settings = new SugiyamaLayoutSettings { Transformation = PlaneTransformation.Rotation(Math.PI / 2), EdgeRoutingSettings = { EdgeRoutingMode = EdgeRoutingMode.Spline } }; var layout = new LayeredLayout(graph, settings); layout.Run(); }
/// <summary> /// Default constructor /// </summary> public GViewer() { mdsLayoutSettings = new MdsLayoutSettings() { RunInParallel = this.AsyncLayout }; sugiyamaSettings = new SugiyamaLayoutSettings(); // This call is required by the Windows.Forms Form Designer. InitializeComponent(); BackwardEnabled = false; ForwardEnabled = false; toolbar.MouseMove += ToolBarMouseMoved; Assembly a = Assembly.GetExecutingAssembly(); foreach (string r in a.GetManifestResourceNames()) { if (r.Contains("hmove.cur")) { panGrabCursor = new Cursor(a.GetManifestResourceStream(r)); } else if (r.Contains("oph.cur")) { panOpenCursor = new Cursor(a.GetManifestResourceStream(r)); } } originalCursor = Cursor; panButton.Checked = false; windowZoomButton.Checked = false; layoutSettingsButton.ToolTipText = "Configures the layout algorithm settings"; undoButton.ToolTipText = "Undo layout editing"; redoButton.ToolTipText = "Redo layout editing"; forwardButton.ToolTipText = "Forward"; panButton.ToolTipText = panButton.Checked ? panButtonToolTipText : PanButtonDisabledToolTipText; windowZoomButton.ToolTipText = windowZoomButton.Checked ? WindowZoomButtonToolTipText : windowZoomButtonDisabledToolTipText; InitDrawingLayoutEditor(); toolbar.Invalidate(); SuspendLayout(); InitPanel(); Controls.Add(toolbar); ResumeLayout(); }
public void Layout(NetworkViewModel network) { if (network == null || network.Nodes.Count <= 0) { return; } GeometryGraph graph = new GeometryGraph(); Dictionary <NodeViewModel, Microsoft.Msagl.Core.Layout.Node> layoutLookup = new Dictionary <NodeViewModel, Microsoft.Msagl.Core.Layout.Node>(); const double nodeWidth = 230; const double nodeHeight = 100; const double spacingHorizontal = 90; const double spacingVertical = 60; // build collection of all nodes foreach (NodeViewModel node in network.Nodes.Items) { ICurve box = CurveFactory.CreateRectangle(nodeWidth, nodeHeight, new Microsoft.Msagl.Core.Geometry.Point()); Microsoft.Msagl.Core.Layout.Node layoutNode = new Microsoft.Msagl.Core.Layout.Node(box) { UserData = node }; layoutLookup.Add(node, layoutNode); graph.Nodes.Add(layoutNode); } foreach (ConnectionViewModel items in network.Connections.Items) { Microsoft.Msagl.Core.Layout.Node inNode = layoutLookup[items.Input.Parent]; Microsoft.Msagl.Core.Layout.Node outNode = layoutLookup[items.Output.Parent]; Edge edge = new Edge(inNode, outNode); graph.Edges.Add(edge); } // perform layout operation SugiyamaLayoutSettings settings = new SugiyamaLayoutSettings { Transformation = PlaneTransformation.Rotation(-90 * (Math.PI / 180)), // left to right NodeSeparation = spacingHorizontal, LayerSeparation = spacingVertical, }; LayeredLayout layeredLayout = new LayeredLayout(graph, settings); layeredLayout.Run(); // apply the node positions to the real graph foreach (KeyValuePair <NodeViewModel, Microsoft.Msagl.Core.Layout.Node> node in layoutLookup) { node.Key.Position = new Point(node.Value.BoundingBox.Center.X, node.Value.BoundingBox.Center.Y); } }
private void RunLayout() { var settings = new SugiyamaLayoutSettings { Transformation = PlaneTransformation.Rotation(Math.PI / 2), EdgeRoutingSettings = { EdgeRoutingMode = mode }, }; var layout = new LayeredLayout(graph, settings); layout.Run(); }
public void SimpleGraphTests() { GeometryGraph graph = GraphGenerator.GenerateOneSimpleGraph(); SugiyamaLayoutSettings settings = new SugiyamaLayoutSettings(); GraphGenerator.SetRandomNodeShapes(graph, random); WriteLine("Trying Simple Graph with Top to Down layer direction"); LayoutAndValidate(graph, settings); GraphGenerator.SetRandomNodeShapes(graph, random); WriteLine("Trying Simple Graph with Left to Right layer direction"); LayoutAndValidate(graph, settings, LayerDirection.LeftToRight); }
public void TreeGraphTests() { GeometryGraph graph = GraphGenerator.GenerateFullTree(10, 3); SugiyamaLayoutSettings settings = new SugiyamaLayoutSettings(); GraphGenerator.SetRandomNodeShapes(graph, random); WriteLine("Trying Tree Graph with Right to Left layer direction"); LayoutAndValidate(graph, settings, LayerDirection.RightToLeft); GraphGenerator.SetRandomNodeShapes(graph, random); WriteLine("Trying Tree Graph with Bottom to Top layer direction"); LayoutAndValidate(graph, settings, LayerDirection.BottomToTop); }
public void FullyConnectedGraphTests() { GeometryGraph graph = GraphGenerator.GenerateFullyConnectedGraph(20); SugiyamaLayoutSettings settings = new SugiyamaLayoutSettings(); GraphGenerator.SetRandomNodeShapes(graph, random); WriteLine("Trying Fully Connected Graph with Bottom to Top layer direction"); LayoutAndValidate(graph, settings, LayerDirection.BottomToTop); GraphGenerator.SetRandomNodeShapes(graph, random); WriteLine("Trying Fully Connected Graph with Left to Right layer direction"); LayoutAndValidate(graph, settings, LayerDirection.LeftToRight); }
/// <summary> /// Check whether two nodes on the same layer /// </summary> /// <returns>True if they are on the same layer</returns> private static bool OnSameLayer(Node node, Node node2, SugiyamaLayoutSettings settings) { PlaneTransformation transformation = settings.Transformation; if (IsVerticallyLayered(transformation)) { return(Math.Abs(node.Center.Y - node2.Center.Y) <= Tolerance); } else { return(Math.Abs(node.Center.X - node2.Center.X) <= Tolerance); } }