private Microsoft.Msagl.Core.Layout.LayoutAlgorithmSettings GivePresetSettings(int i) { if (i == 0) { var settings = new Microsoft.Msagl.Layout.Layered.SugiyamaLayoutSettings(); return(settings); } if (i == 1) { var settings = new Microsoft.Msagl.Layout.Incremental.FastIncrementalLayoutSettings(); settings.RepulsiveForceConstant = 1.0; return(settings); } if (i == 2) { var settings = new Microsoft.Msagl.Layout.Incremental.FastIncrementalLayoutSettings(); settings.RepulsiveForceConstant = 30.0; return(settings); } if (i == 3) { var settings = new Microsoft.Msagl.Layout.Incremental.FastIncrementalLayoutSettings(); settings.RepulsiveForceConstant = 100.0; return(settings); } return(null); }
private void LayoutLinkedShapes(Graph graph, out Microsoft.Msagl.Core.Layout.GeometryGraph geometry) { var geomGraph = new Microsoft.Msagl.Core.Layout.GeometryGraph(); var layoutSettings = new Microsoft.Msagl.Layout.Layered.SugiyamaLayoutSettings(); Microsoft.Msagl.Core.Layout.Node EnsureNode(Node node) { var res = geomGraph.Nodes.FirstOrDefault(n => n.UserData == node); if (res == null) { var geomNode = new Microsoft.Msagl.Core.Layout.Node( Microsoft.Msagl.Core.Geometry.Curves.CurveFactory.CreateRectangle( ShapeSize, ShapeSize, new Microsoft.Msagl.Core.Geometry.Point() ), node ); geomGraph.Nodes.Add(geomNode); return(geomNode); } return(res); } foreach (var l in graph.Links) { var n1 = EnsureNode(l.Node1); var n2 = EnsureNode(l.Node2); var e = new Microsoft.Msagl.Core.Layout.Edge(n1, n2); geomGraph.Edges.Add(e); } LayoutHelpers.CalculateLayout(geomGraph, layoutSettings, null); foreach (var kv in nodesAndShapes) { var pos = geomGraph.Nodes.FirstOrDefault(n => n.UserData == kv.Key)?.Center; if (pos.HasValue) { kv.Value.X = (int)pos.Value.X + ShapeSize; kv.Value.Y = Diagram.Height - (int)pos.Value.Y + ShapeSize / 2; } } geometry = geomGraph; }
private MSAGL.Core.Layout.GeometryGraph CreateMsaglGraph(DirectedGraphLayout layout_diagram) { var mg_graph = new MSAGL.Core.Layout.GeometryGraph(); // Create the nodes in MSAGL foreach (var layout_shape in layout_diagram.Shapes) { var nodesize = this.ToMGCoordinates(layout_shape.Size ?? this.LayoutOptions.DefaultShapeSize); var node_user_data = new NodeUserData(layout_shape.ID, layout_shape); var center = new MSAGL.Core.Geometry.Point(); var rectangle = MSAGL.Core.Geometry.Curves.CurveFactory.CreateRectangle(nodesize.Width, nodesize.Height, center); var mg_node = new MSAGL.Core.Layout.Node(rectangle, node_user_data); mg_graph.Nodes.Add(mg_node); } this.validate_connectors(layout_diagram); var mg_coordinates = this.ToMGCoordinates(this.DefaultBezierConnectorLabelBoxSize); var map_id_to_ud = new Dictionary <string, MSAGL.Core.Layout.Node>(); foreach (var n in mg_graph.Nodes) { var ud = (NodeUserData)n.UserData; if (ud != null) { map_id_to_ud[ud.ID] = n; } } // Create the MG Connectors foreach (var layout_connector in layout_diagram.Connectors) { if (layout_connector.From == null) { throw new ArgumentException("Connector's From node is null"); } if (layout_connector.To == null) { throw new ArgumentException("Connector's To node is null"); } var from_node = map_id_to_ud[layout_connector.From.ID]; var to_node = map_id_to_ud[layout_connector.To.ID]; var new_edge = new MSAGL.Core.Layout.Edge(from_node, to_node); // TODO: MSAGL //new_edge.ArrowheadAtTarget = false; new_edge.UserData = new NodeUserData(layout_connector.ID, layout_connector); mg_graph.Edges.Add(new_edge); new_edge.Label = new MSAGL.Core.Layout.Label(mg_coordinates.Width, mg_coordinates.Height, new_edge); } var geom_graph_components = MSAGL.Core.Layout.GraphConnectedComponents.CreateComponents(mg_graph.Nodes, mg_graph.Edges); var settings = new MSAGL.Layout.Layered.SugiyamaLayoutSettings(); foreach (var subgraph in geom_graph_components) { var layout = new Microsoft.Msagl.Layout.Layered.LayeredLayout(subgraph, settings); subgraph.Margins = settings.NodeSeparation / 2; layout.Run(); } // Pack the graphs using Golden Aspect Ratio MSAGL.Layout.MDS.MdsGraphLayout.PackGraphs(geom_graph_components, settings); //Update the graphs bounding box mg_graph.UpdateBoundingBox(); this._mg_bb = new VA.Drawing.Rectangle( mg_graph.BoundingBox.Left, mg_graph.BoundingBox.Bottom, mg_graph.BoundingBox.Right, mg_graph.BoundingBox.Top); this._layout_bb = new VA.Drawing.Rectangle(0, 0, this._mg_bb.Width, this._mg_bb.Height) .Multiply(this.ScaleToDocument, this.ScaleToDocument); return(mg_graph); }
protected override void OnValueChanged(ModelRoot element, LayoutAlgorithm oldValue, LayoutAlgorithm newValue) { base.OnValueChanged(element, oldValue, newValue); if (!element.Store.InUndoRedoOrRollback) { // if this is the first time we've been here, cache what's alread there if (oldValue != LayoutAlgorithm.Default && !settingsCache.ContainsKey(oldValue) && element.LayoutAlgorithmSettings != null) { settingsCache[oldValue] = element.LayoutAlgorithmSettings; } // use the prior settings for this layout type if available if (newValue != LayoutAlgorithm.Default && settingsCache.ContainsKey(newValue)) { element.LayoutAlgorithmSettings = settingsCache[newValue]; } else { // if not, set some defaults that make sense in our context switch (newValue) { case LayoutAlgorithm.Default: element.LayoutAlgorithmSettings = null; return; case LayoutAlgorithm.FastIncremental: FastIncrementalLayoutSettings fastIncrementalLayoutSettings = new FastIncrementalLayoutSettings(); element.LayoutAlgorithmSettings = fastIncrementalLayoutSettings; break; case LayoutAlgorithm.MDS: MdsLayoutSettings mdsLayoutSettings = new MdsLayoutSettings(); mdsLayoutSettings.ScaleX = 1; mdsLayoutSettings.ScaleY = 1; mdsLayoutSettings.AdjustScale = true; mdsLayoutSettings.RemoveOverlaps = true; element.LayoutAlgorithmSettings = mdsLayoutSettings; break; case LayoutAlgorithm.Ranking: RankingLayoutSettings rankingLayoutSettings = new RankingLayoutSettings(); rankingLayoutSettings.ScaleX = 1; rankingLayoutSettings.ScaleY = 1; element.LayoutAlgorithmSettings = rankingLayoutSettings; break; case LayoutAlgorithm.Sugiyama: SugiyamaLayoutSettings sugiyamaLayoutSettings = new SugiyamaLayoutSettings { LayerSeparation = 1, MinNodeHeight = 1, MinNodeWidth = 1 }; element.LayoutAlgorithmSettings = sugiyamaLayoutSettings; break; } element.LayoutAlgorithmSettings.ClusterMargin = 1; element.LayoutAlgorithmSettings.NodeSeparation = 1; element.LayoutAlgorithmSettings.EdgeRoutingSettings.Padding = .3; element.LayoutAlgorithmSettings.EdgeRoutingSettings.PolylinePadding = 1.5; element.LayoutAlgorithmSettings.EdgeRoutingSettings.EdgeRoutingMode = EdgeRoutingMode.StraightLine; settingsCache[newValue] = element.LayoutAlgorithmSettings; } } }
private void Layout() { try { var scenes = Controller.Instance.ChapterList.getSelectedChapterDataControl().getScenesList(); // Layout algorithm var settings = new Microsoft.Msagl.Layout.Layered.SugiyamaLayoutSettings(); settings.MaxAspectRatioEccentricity = 1.6; settings.NodeSeparation = 10; settings.PackingMethod = PackingMethod.Compact; // Graph GeometryGraph graph = new GeometryGraph(); graph.BoundingBox = new Microsoft.Msagl.Core.Geometry.Rectangle(0, 0, SpaceWidth, SpaceHeight); graph.UpdateBoundingBox(); Dictionary <SceneDataControl, Node> sceneToNode = new Dictionary <SceneDataControl, Node>(); Dictionary <UniRx.Tuple <Node, Node>, bool> present = new Dictionary <UniRx.Tuple <Node, Node>, bool>(); foreach (var scene in scenes.getScenes()) { sizes.Remove(scene.getPreviewBackground()); var rect = GetSceneRect(scene); var node = new Node(CurveFactory.CreateRectangle(rect.width, rect.height, new Point()), scene.getId()); graph.Nodes.Add(node); sceneToNode.Add(scene, node); } foreach (var scene in scenes.getScenes()) { var node = sceneToNode[scene]; foreach (var exit in scene.getExitsList().getExits()) { var index = scenes.getSceneIndexByID(exit.getNextSceneId()); // If the exit points to a cutscene it normally is out of the array if (index < 0 || index >= scenes.getScenes().Count) { continue; } var nextScene = scenes.getScenes()[index]; var t = new UniRx.Tuple <Node, Node>(node, sceneToNode[nextScene]); if (!present.ContainsKey(t)) { present.Add(t, true); graph.Edges.Add(new Edge(node, sceneToNode[nextScene])); var exitOrigin = GetExitArea(scene, exit).ToRect().center; var originRect = GetSceneRect(scene); var pos = exitOrigin - originRect.position; pos.x = Mathf.Clamp01(pos.x / originRect.width); pos.y = Mathf.Clamp01(pos.y / originRect.height); // Positioning constraints if (pos.x < 0.3) { settings.AddLeftRightConstraint(t.Item2, t.Item1); } if (pos.x > 0.7) { settings.AddLeftRightConstraint(t.Item1, t.Item2); } } } } // Do the layouting LayoutHelpers.CalculateLayout(graph, settings, null); // Extract the results var graphRect = new Rect((float)graph.Left, (float)graph.Bottom, (float)graph.Width, (float)graph.Height); var canvasRect = new Rect(0, 0, SpaceWidth, SpaceHeight); foreach (var scene in scenes.getScenes()) { var n = sceneToNode[scene]; positions[scene.getId()] = TransformPoint(new Vector2((float)(n.Center.X - n.Width / 2f), (float)(n.Center.Y + n.Height / 2f)), graphRect, canvasRect, true); // Update in the project data var id = GetScenePropertyId(Controller.Instance.SelectedChapterDataControl, scene); ProjectConfigData.setProperty(id + ".X", ((int)positions[scene.getId()].x).ToString()); ProjectConfigData.setProperty(id + ".Y", ((int)positions[scene.getId()].y).ToString()); } } catch (Exception ex) { Debug.LogError(ex.Message + " : " + ex.StackTrace); } }
private MSAGL.Core.Layout.GeometryGraph _create_msagl_graph(DirectedGraphLayout dglayout) { var msagl_graph = new MSAGL.Core.Layout.GeometryGraph(); // Create the nodes in MSAGL foreach (var layout_shape in dglayout.Nodes) { var nodesize = this._to_mg_coordinates(layout_shape.Size ?? this.LayoutOptions.DefaultShapeSize); var node_user_data = new ElementUserData(layout_shape.ID, layout_shape); var center = new MSAGL.Core.Geometry.Point(); var rectangle = MSAGL.Core.Geometry.Curves.CurveFactory.CreateRectangle(nodesize.Width, nodesize.Height, center); var mg_node = new MSAGL.Core.Layout.Node(rectangle, node_user_data); msagl_graph.Nodes.Add(mg_node); } this.validate_connectors(dglayout); var mg_coordinates = this._to_mg_coordinates(this.DefaultBezierConnectorLabelBoxSize); var map_id_to_ud = new Dictionary <string, MSAGL.Core.Layout.Node>(); foreach (var n in msagl_graph.Nodes) { var ud = (ElementUserData)n.UserData; if (ud != null) { map_id_to_ud[ud.ID] = n; } } // Create the MG Connectors foreach (var layout_connector in dglayout.Edges) { if (layout_connector.From == null) { throw new ArgumentException("Connector's From node is null"); } if (layout_connector.To == null) { throw new ArgumentException("Connector's To node is null"); } var from_node = map_id_to_ud[layout_connector.From.ID]; var to_node = map_id_to_ud[layout_connector.To.ID]; var new_edge = new MSAGL.Core.Layout.Edge(from_node, to_node); // TODO: MSAGL //new_edge.ArrowheadAtTarget = false; new_edge.UserData = new ElementUserData(layout_connector.ID, layout_connector); msagl_graph.Edges.Add(new_edge); new_edge.Label = new MSAGL.Core.Layout.Label(mg_coordinates.Width, mg_coordinates.Height, new_edge); } var msagl_graphs = MSAGL.Core.Layout.GraphConnectedComponents.CreateComponents(msagl_graph.Nodes, msagl_graph.Edges); var msagl_sugiyamasettings = new MSAGL.Layout.Layered.SugiyamaLayoutSettings(); if (this.LayoutOptions.Direction == MsaglDirection.TopToBottom) { // do nothing } else if (this.LayoutOptions.Direction == MsaglDirection.BottomToTop) { msagl_sugiyamasettings.Transformation = MSAGL.Core.Geometry.Curves.PlaneTransformation.Rotation(Math.PI); } else if (this.LayoutOptions.Direction == MsaglDirection.LeftToRight) { msagl_sugiyamasettings.Transformation = MSAGL.Core.Geometry.Curves.PlaneTransformation.Rotation(Math.PI / 2); } else if (this.LayoutOptions.Direction == MsaglDirection.RightToLeft) { msagl_sugiyamasettings.Transformation = MSAGL.Core.Geometry.Curves.PlaneTransformation.Rotation(-Math.PI / 2); } else { throw new System.ArgumentOutOfRangeException(); } foreach (var subgraph in msagl_graphs) { var layout = new Microsoft.Msagl.Layout.Layered.LayeredLayout(subgraph, msagl_sugiyamasettings); subgraph.Margins = msagl_sugiyamasettings.NodeSeparation / 2; layout.Run(); } // Pack the graphs using Golden Aspect Ratio MSAGL.Layout.MDS.MdsGraphLayout.PackGraphs(msagl_graphs, msagl_sugiyamasettings); //Update the graphs bounding box msagl_graph.UpdateBoundingBox(); this._msagl_bb = new VA.Geometry.Rectangle( msagl_graph.BoundingBox.Left, msagl_graph.BoundingBox.Bottom, msagl_graph.BoundingBox.Right, msagl_graph.BoundingBox.Top); this._visio_bb = new VA.Geometry.Rectangle(0, 0, this._msagl_bb.Width, this._msagl_bb.Height) .Multiply(this._scale_to_document, this._scale_to_document); return(msagl_graph); }