private void DoGraphAutoLayout(object o) { if (Model.Nodes.Count == 0) { return; } var graph = new GraphLayout.Graph(); var models = new Dictionary <ModelBase, UndoRedoRecorder.UserAction>(); foreach (NodeModel x in Model.Nodes) { graph.AddNode(x.GUID, x.Width, x.Height, x.Y); models.Add(x, UndoRedoRecorder.UserAction.Modification); } foreach (ConnectorModel x in Model.Connectors) { graph.AddEdge(x.Start.Owner.GUID, x.End.Owner.GUID, x.Start.Center.Y, x.End.Center.Y); models.Add(x, UndoRedoRecorder.UserAction.Modification); } Model.RecordModelsForModification(new List <ModelBase>(Model.Nodes)); // Sugiyama algorithm steps graph.RemoveCycles(); graph.AssignLayers(); graph.OrderNodes(); // Assign coordinates to node models graph.NormalizeGraphPosition(); foreach (var x in Model.Nodes) { var id = x.GUID; x.X = graph.FindNode(id).X; x.Y = graph.FindNode(id).Y; x.ReportPosition(); } // Fit view to the new graph layout DynamoSelection.Instance.ClearSelection(); ResetFitViewToggle(null); FitViewInternal(); }
/// <summary> /// This function calls the graph layout algorithm methods. /// </summary> /// <param name="graph">The subgraph to be processed.</param> /// <param name="isGroupLayout">True if all selected models are groups.</param> private static void RunLayoutSubgraph(GraphLayout.Graph graph, bool isGroupLayout) { // Select relevant nodes graph.Nodes.ToList().ForEach(x => x.IsSelected = true); // Save subgraph position before running the layout graph.RecordInitialPosition(); // Sugiyama algorithm steps graph.RemoveCycles(); graph.AssignLayers(); graph.OrderNodes(); // Node and graph positioning graph.DistributeNodePosition(); graph.SetGraphPosition(isGroupLayout); // Reset layer information and deselect nodes graph.ResetLayers(); graph.Nodes.ToList().ForEach(x => x.IsSelected = false); }
private void DoGraphAutoLayout(object o) { if (Model.Nodes.Count() == 0) { return; } var graph = new GraphLayout.Graph(); var models = new Dictionary <ModelBase, UndoRedoRecorder.UserAction>(); foreach (AnnotationModel x in Model.Annotations) { // Treat a group as a graph layout node/vertex graph.AddNode(x.GUID, x.Width, x.Height, x.Y); models.Add(x, UndoRedoRecorder.UserAction.Modification); } foreach (NodeModel x in Model.Nodes) { AnnotationModel group = Model.Annotations.Where( s => s.SelectedModels.Contains(x)).ToList().FirstOrDefault(); // Do not process nodes within groups if (group == null) { graph.AddNode(x.GUID, x.Width, x.Height, x.Y); models.Add(x, UndoRedoRecorder.UserAction.Modification); } } foreach (ConnectorModel x in Model.Connectors) { AnnotationModel startGroup = null, endGroup = null; startGroup = Model.Annotations.Where( s => s.SelectedModels.Contains(x.Start.Owner)).ToList().FirstOrDefault(); endGroup = Model.Annotations.Where( s => s.SelectedModels.Contains(x.End.Owner)).ToList().FirstOrDefault(); // Connector does not belong to any group if ((startGroup == null) && (endGroup == null)) { graph.AddEdge(x.Start.Owner.GUID, x.End.Owner.GUID, x.Start.Center.Y, x.End.Center.Y); } // Connector starts from a node within a group else if ((startGroup != null) && (endGroup == null)) { graph.AddEdge(startGroup.GUID, x.End.Owner.GUID, x.Start.Center.Y, x.End.Center.Y); } // Connector ends at a node within a group else if ((startGroup == null) && (endGroup != null)) { graph.AddEdge(x.Start.Owner.GUID, endGroup.GUID, x.Start.Center.Y, x.End.Center.Y); } models.Add(x, UndoRedoRecorder.UserAction.Modification); } // Support undo for graph layout command WorkspaceModel.RecordModelsForModification(new List <ModelBase>(Model.Nodes), Model.UndoRecorder); // Sugiyama algorithm steps graph.RemoveCycles(); graph.AssignLayers(); graph.OrderNodes(); graph.NormalizeGraphPosition(); // Assign coordinates to nodes inside groups foreach (var x in Model.Annotations) { var id = x.GUID; double deltaX = graph.FindNode(id).X - x.X; double deltaY = graph.FindNode(id).Y - x.Y; foreach (var n in x.SelectedModels) { n.X += deltaX; n.Y += deltaY; n.ReportPosition(); } } // Assign coordinates to nodes outside groups foreach (var x in Model.Nodes) { var n = graph.FindNode(x.GUID); if (n != null) { x.X = n.X; x.Y = n.Y; x.ReportPosition(); } } // Fit view to the new graph layout DynamoSelection.Instance.ClearSelection(); ResetFitViewToggle(null); FitViewInternal(); }
private void DoGraphAutoLayout(object o) { if (Model.Nodes.Count == 0) return; var graph = new GraphLayout.Graph(); var models = new Dictionary<ModelBase, UndoRedoRecorder.UserAction>(); foreach (NodeModel x in Model.Nodes) { graph.AddNode(x.GUID, x.Width, x.Height, x.Y); models.Add(x, UndoRedoRecorder.UserAction.Modification); } foreach (ConnectorModel x in Model.Connectors) { graph.AddEdge(x.Start.Owner.GUID, x.End.Owner.GUID, x.Start.Center.Y, x.End.Center.Y); models.Add(x, UndoRedoRecorder.UserAction.Modification); } Model.RecordModelsForModification(new List<ModelBase>(Model.Nodes)); // Sugiyama algorithm steps graph.RemoveCycles(); graph.AssignLayers(); graph.OrderNodes(); // Assign coordinates to node models graph.NormalizeGraphPosition(); foreach (var x in Model.Nodes) { var id = x.GUID; x.X = graph.FindNode(id).X; x.Y = graph.FindNode(id).Y; x.ReportPosition(); } // Fit view to the new graph layout DynamoSelection.Instance.ClearSelection(); ResetFitViewToggle(null); FitViewInternal(); }
private void DoGraphAutoLayout(object o) { if (Model.Nodes.Count() == 0) return; var graph = new GraphLayout.Graph(); var models = new Dictionary<ModelBase, UndoRedoRecorder.UserAction>(); foreach (AnnotationModel x in Model.Annotations) { // Treat a group as a graph layout node/vertex graph.AddNode(x.GUID, x.Width, x.Height, x.Y); models.Add(x, UndoRedoRecorder.UserAction.Modification); } foreach (NodeModel x in Model.Nodes) { AnnotationModel group = Model.Annotations.Where( s => s.SelectedModels.Contains(x)).ToList().FirstOrDefault(); // Do not process nodes within groups if (group == null) { graph.AddNode(x.GUID, x.Width, x.Height, x.Y); models.Add(x, UndoRedoRecorder.UserAction.Modification); } } foreach (ConnectorModel x in Model.Connectors) { AnnotationModel startGroup = null, endGroup = null; startGroup = Model.Annotations.Where( s => s.SelectedModels.Contains(x.Start.Owner)).ToList().FirstOrDefault(); endGroup = Model.Annotations.Where( s => s.SelectedModels.Contains(x.End.Owner)).ToList().FirstOrDefault(); // Connector does not belong to any group if ((startGroup == null) && (endGroup == null)) graph.AddEdge(x.Start.Owner.GUID, x.End.Owner.GUID, x.Start.Center.Y, x.End.Center.Y); // Connector starts from a node within a group else if ((startGroup != null) && (endGroup == null)) graph.AddEdge(startGroup.GUID, x.End.Owner.GUID, x.Start.Center.Y, x.End.Center.Y); // Connector ends at a node within a group else if ((startGroup == null) && (endGroup != null)) graph.AddEdge(x.Start.Owner.GUID, endGroup.GUID, x.Start.Center.Y, x.End.Center.Y); models.Add(x, UndoRedoRecorder.UserAction.Modification); } // Support undo for graph layout command WorkspaceModel.RecordModelsForModification(new List<ModelBase>(Model.Nodes), Model.UndoRecorder); // Sugiyama algorithm steps graph.RemoveCycles(); graph.AssignLayers(); graph.OrderNodes(); graph.NormalizeGraphPosition(); // Assign coordinates to nodes inside groups foreach (var x in Model.Annotations) { var id = x.GUID; double deltaX = graph.FindNode(id).X - x.X; double deltaY = graph.FindNode(id).Y - x.Y; foreach (var n in x.SelectedModels) { n.X += deltaX; n.Y += deltaY; n.ReportPosition(); } } // Assign coordinates to nodes outside groups foreach (var x in Model.Nodes) { var n = graph.FindNode(x.GUID); if (n != null) { x.X = n.X; x.Y = n.Y; x.ReportPosition(); } } // Fit view to the new graph layout DynamoSelection.Instance.ClearSelection(); ResetFitViewToggle(null); FitViewInternal(); }