private void CalculateInitialY(DependencyViewerNode.NodeInputSide treeSide) { TreeLayout.ForeachNode_PostOrderTraversal(_refTargetNode, treeSide, (data) => { var node = data.currentNode; if (node.IsLeaf(data.TreeSide)) { if (node.IsFirstSibling(data.TreeSide)) { node.SetPositionY(0); } else { var previousSibling = node.GetPreviousSibling(data.TreeSide); node.SetPositionY(previousSibling.Position.y + previousSibling.GetHeight() + DependencyViewerGraphDrawer.DistanceBetweenNodes.y); } } else if (node.GetNumChildren(data.TreeSide) == 1) { if (node.IsFirstSibling(data.TreeSide)) { node.SetPositionY(node.GetChildren(data.TreeSide)[0].Position.y); } else { var previousSibling = node.GetPreviousSibling(data.TreeSide); node.SetPositionY(previousSibling.Position.y + previousSibling.GetHeight() + DependencyViewerGraphDrawer.DistanceBetweenNodes.y); node.Mod = node.Position.y - node.GetChildren(data.TreeSide)[0].Position.y; } } else { var prevChild = node.GetFirstChild(data.TreeSide); var nextChild = node.GetLastChild(data.TreeSide); float mid = (nextChild.Position.y - prevChild.Position.y) / 2; if (node.IsFirstSibling(data.TreeSide)) { node.SetPositionY(mid); } else { node.SetPositionY(node.GetPreviousSibling(data.TreeSide).Position.y + node.GetHeight() + DependencyViewerGraphDrawer.DistanceBetweenNodes.y); node.Mod = node.Position.y - mid; } } if (node.GetNumChildren(data.TreeSide) > 0 && !node.IsFirstSibling(data.TreeSide)) { CheckForConflicts(node, data.depth, data.TreeSide); } }); }
/// <summary> /// Arranges a tree on diagram to look pretty /// </summary> /// <param name="diagramView">DiagramView to arrange</param> private void Arrange(DiagramView diagramView) { var layout = new TreeLayout { KeepRootPosition = true, Direction = TreeLayoutDirections.TopToBottom }; layout.Arrange(diagramView.Diagram); diagramView.Diagram.ResizeToFitItems(5); diagramView.ZoomToFit(); }
private void OnWindowLoaded(object sender, RoutedEventArgs e) { // still not sure if this is needed TreeLayout layout = new TreeLayout(); layout.Type = TreeLayoutType.Centered; layout.LinkStyle = TreeLayoutLinkType.Cascading3; layout.Direction = TreeLayoutDirections.TopToBottom; layout.KeepRootPosition = false; layout.LevelDistance = 40; layout.Arrange(diagram); }
public OrgChartExample() { InitializeComponent(); this.GetViewModelAndBindForEvents(); this.Loaded += this.OnOrgChartExampleLoaded; this.BindComboBoxes(); // Sets the OrgTreeRouter as default router. this.diagram.RoutingService.Router = this.viewModel.Router; // Creates the Laoyou object which layouts the shapes. this.treeLayout = new TreeLayout(); this.BindOrgTreeView(); }
/// <summary> /// Creates and configures the graph that is used for the placer configuration preview. /// </summary> private void SetupPreview() { IGraph graph = previewControl.Graph; DictionaryMapper <INode, bool> assistantMap = graph.MapperRegistry.CreateMapper <INode, bool>(AssistantNodePlacer.AssistantNodeDpKey); graph.NodeDefaults.Size = new SizeD(40, 30); graph.NodeDefaults.Style = new ShinyPlateNodeStyle { Brush = Brushes.LightGray, Insets = new InsetsD(5), DrawShadow = false, Pen = Pens.Black }; var rootStyle = new ShinyPlateNodeStyle { Brush = Brushes.Red, Insets = new InsetsD(5), Pen = Pens.Black, DrawShadow = false }; var assistantStyle = new ShinyPlateNodeStyle { Brush = Brushes.LightGray, Insets = new InsetsD(5), Pen = new Pen(Brushes.Black, 1) { DashStyle = DashStyles.Dash }, DrawShadow = false }; INode root = graph.CreateNode(); graph.SetStyle(root, rootStyle); INode n1 = graph.CreateNode(); graph.SetStyle(n1, assistantStyle); assistantMap[n1] = true; INode n2 = graph.CreateNode(); INode n3 = graph.CreateNode(); INode n4 = graph.CreateNode(); INode n5 = graph.CreateNode(new RectD(0, 0, 60, 30)); graph.CreateEdge(root, n1); graph.CreateEdge(root, n2); graph.CreateEdge(root, n3); graph.CreateEdge(root, n4); graph.CreateEdge(root, n5); previewLayout = new TreeLayout(); }
/// <inheritdoc /> protected override ILayoutAlgorithm CreateConfiguredLayout(GraphControl graphControl) { MultiStageLayout layout; switch (LayoutStyleItem) { default: case EnumStyle.Default: layout = ConfigureDefaultLayout(); break; case EnumStyle.Classic: layout = ConfigureClassicLayout(); break; case EnumStyle.HorizontalVertical: layout = new TreeLayout(); break; case EnumStyle.Compact: layout = ConfigureCompactLayout(graphControl); break; } layout.ParallelEdgeRouterEnabled = false; ((ComponentLayout)layout.ComponentLayout).Style = ComponentArrangementStyles.MultiRows; layout.SubgraphLayoutEnabled = ActOnSelectionOnlyItem; layout.PrependStage(CreateTreeReductionStage()); var placeLabels = EdgeLabelingItem == EnumEdgeLabeling.Integrated || EdgeLabelingItem == EnumEdgeLabeling.Generic; // required to prevent WrongGraphStructure exception which may be thrown by TreeLayout if there are edges // between group nodes layout.PrependStage(new HandleEdgesBetweenGroupsStage(placeLabels)); if (EdgeLabelingItem == EnumEdgeLabeling.Generic) { layout.LabelingEnabled = true; layout.Labeling = new GenericLabeling { PlaceEdgeLabels = true, PlaceNodeLabels = false, ReduceAmbiguity = ReduceAmbiguityItem }; } AddPreferredPlacementDescriptor(graphControl.Graph, LabelPlacementAlongEdgeItem, LabelPlacementSideOfEdgeItem, LabelPlacementOrientationItem, LabelPlacementDistanceItem); return(layout); }
private void rearrange(ShapeNode rootNode) { if (treeLayout == null) { treeLayout = new TreeLayout(rootNode, TreeLayoutType.Centered, false, TreeLayoutLinkType.Rounded, TreeLayoutDirections.TopToBottom, 10, 5, true, new SizeF(10, 10)); } treeLayout.Arrange(treeDiagram); }
private void MakeTree() { if (_patriarch == null) { var ged = LoadGEDFromStream(gedcom); _patriarch = ged.PersonById("I1"); } var tree = TreeBuild.BuildTree(treePanel21, _settings, _patriarch); var nodeExtentProvider = new NodeExtents(); var treeLayout = new TreeLayout <ITreeData>(tree, nodeExtentProvider, _settings, false); treePanel21.Boxen = treeLayout; }
public OrgChartExample() { this.PopulateConnectorCollections(); InitializeComponent(); this.GetViewModelAndBindForEvents(); this.Loaded += this.OnOrgChartExampleLoaded; this.Unloaded += this.OnOrgChartExampleUnloaded; this.BindComboBoxes(); this.diagram.RoutingService.Router = this.viewModel.Router; this.treeLayout = new TreeLayout(); this.BindOrgTreeView(); DragDropManager.AddDragDropCompletedHandler(this.diagram, this.OnDragDropCompleted, true); DragDropManager.AddGiveFeedbackHandler(this.diagram, new Windows.DragDrop.GiveFeedbackEventHandler(OnGiveFeedBack), true); this.actionDelayer = new ActionDelayer(); }
/// <summary> /// Updates the layout. /// </summary> private async Task SaveLayoutAsync(AppDbContext db, TreeLayoutVM tree, TreeLayout layout) { using var conn = db.GetConnection(); await conn.ExecuteAsync( @"INSERT INTO ""TreeLayouts"" (""Id"", ""LayoutJson"", ""GenerationDate"") VALUES (@Id, @LayoutJson, @GenerationDate)", layout ); // sic! dapper generates incorrect query for "GUID IN (@GUIDS)" with parameters foreach (var batch in tree.Persons.Select(x => x.Id).PartitionBySize(100)) { var ids = batch.Select(x => $"'{x}'").JoinString(", "); await conn.ExecuteAsync($@"UPDATE ""Pages"" SET ""TreeLayoutId"" = '{layout.Id}' WHERE ""Id"" IN ({ids})"); } }
private static ILayoutAlgorithm CreateTreeLayout() { var reductionStage = new TreeReductionStage { NonTreeEdgeRouter = new NonTreeEdgeRouterStage(), NonTreeEdgeSelectionKey = LayoutKeys.AffectedEdgesDpKey }; var treeLayout = new TreeLayout { IntegratedEdgeLabeling = true }; treeLayout.PrependStage(reductionStage); DisableAutoFlipping(treeLayout); return(treeLayout); }
private void SetupLayouts() { // create TreeLayout var treeLayout = new TreeLayout { LayoutOrientation = LayoutOrientation.LeftToRight }; treeLayout.PrependStage(new FixNodeLayoutStage()); layouts.Add(treeLayout); layoutMapper["Tree"] = treeLayout; layoutComboBox.Items.Add("Tree"); // create BalloonLayout var balloonLayout = new BalloonLayout { FromSketchMode = true, CompactnessFactor = 1.0, AllowOverlaps = true }; balloonLayout.PrependStage(new FixNodeLayoutStage()); layouts.Add(balloonLayout); layoutMapper["Balloon"] = balloonLayout; layoutComboBox.Items.Add("Balloon"); // create OrganicLayout var organicLayout = new OrganicLayout { MinimumNodeDistance = 40, Deterministic = true }; organicLayout.PrependStage(new FixNodeLayoutStage()); layouts.Add(organicLayout); layoutMapper["Organic"] = organicLayout; layoutComboBox.Items.Add("Organic"); // create OrthogonalLayout var orthogonalLayout = new OrthogonalLayout(); orthogonalLayout.PrependStage(new FixNodeLayoutStage()); layouts.Add(orthogonalLayout); layoutMapper["Orthogonal"] = orthogonalLayout; layoutComboBox.Items.Add("Orthogonal"); // set it as initial value currentLayout = treeLayout; layoutComboBox.SelectedIndex = 0; }
private void Show() { int treeIndex = 0; double prevMaxY = 0; foreach (var tree in _trees) { var visNodeTable = _visNodeTables[treeIndex]; //Layout var layout = new TreeLayout(tree, visNodeTable) { NodeMarginHorizontal = 60, NodeMarginVertical = 150 }; layout.Layout(); foreach (var visItem in visNodeTable.Items) { visItem.X += 10; visItem.Y += 50 + prevMaxY; } prevMaxY = visNodeTable.Items.Max(item => item.Y); foreach (var visItem in visNodeTable.Items) { IVisualItem visParentItem; var visEdge = GetEdgeVisItem(visItem, out visParentItem); if (visEdge != null) { visEdge.X1 = visItem.X; visEdge.Y1 = visItem.Y; visEdge.X2 = visParentItem.X; visEdge.Y2 = visParentItem.Y; } } treeIndex++; } //Interactions InitInteractions(); //Show _app = new Application(); _app.Run(_window); //_window.Show(); Console.ReadKey(); }
private void TreePerson(Person val) { var config = TreeConfiguration.LoadConfig(); config.MaxDepth = (int)spinMaxGen.Value; var tree = TreeBuild.BuildTree(treePanel1, config, val); // create the NodeExtentProvider for TextInBox nodes var nodeExtentProvider = new NodeExtents(); // create the layout var treeLayout = new TreeLayout <ITreeData>(tree, nodeExtentProvider, config, !tree.getRoot().IsReal); treePanel1.Boxen = treeLayout; }
private MultiStageLayout ConfigureCompactLayout(GraphControl graphControl) { var layout = new TreeLayout(); var aspectRatioNodePlacer = new AspectRatioNodePlacer(); if (graphControl != null && ArUseViewAspectRatioItem) { var size = graphControl.InnerSize; aspectRatioNodePlacer.AspectRatio = size.Width / size.Height; } else { aspectRatioNodePlacer.AspectRatio = CompactPreferredAspectRatioItem; } aspectRatioNodePlacer.HorizontalDistance = ArHorizontalSpaceItem; aspectRatioNodePlacer.VerticalDistance = ArVerticalSpaceItem; layout.DefaultNodePlacer = aspectRatioNodePlacer; return layout; }
public void SetTree(Tree root) { if (root != null) { treeLayout = new TreeLayout <Tree>(new TreeLayoutAdaptor(root), new VariableExtentProvide(this), new DefaultConfiguration <Tree>(gapBetweenLevels, gapBetweenNodes)); // Let the UI display this new AST. UpdatePreferredSize(); } else { treeLayout = null; Invalidate(); } }
/// <summary> /// Handles the OnClick event of the TreeLayoutButton control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param> private void TreeLayoutButton_OnClick(object sender, RoutedEventArgs e) { var settings = new TreeLayoutSettings { TreeLayoutType = this.GetTreeLayoutType(), HorizontalSeparation = this.HorizontalSeparationSlider.Value, VerticalSeparation = this.VerticalSeparationSlider.Value, UnderneathHorizontalOffset = this.UnderneathHorizontalOffsetSlider.Value, UnderneathVerticalSeparation = this.UnderneathVerticalOffsetSlider.Value, KeepComponentsInOneRadialLayout = true, RadialSeparation = this.RadialSeparationSlider.Value, RadialFirstLEvelSeparation = this.RadialFirstLevelSeparationSlider.Value }; var layout = new TreeLayout(); settings.Roots.Add(this.diagram.Items[1] as IShape); layout.Layout(this.diagram, settings); this.diagram.AutoFit(); }
/// <summary> /// Creates a balanced radial forest. /// </summary> /// <param name="diagram">The diagram.</param> /// <param name="specs">The specs.</param> public static void BalancedRadialForest(this RadDiagram diagram, GraphGenerationSpecifications specs) { diagram.Clear(); Dictionary<Node, RadDiagramShape> nodeMap; Dictionary<Edge, RadDiagramConnection> edgeMap; var g = diagram.CreateDiagram(CreateBalancedForest(), out nodeMap, out edgeMap, CreateShape, specs.RandomShapeSize); var settings = new TreeLayoutSettings { TreeLayoutType = specs.TreeType, HorizontalSeparation = specs.HorizontalSeparation, VerticalSeparation = specs.VerticalSeparation, UnderneathHorizontalOffset = specs.UnderneathHorizontalOffset, UnderneathVerticalSeparation = specs.UnderneathVerticalSeparation, KeepComponentsInOneRadialLayout = specs.KeepComponentsInOneRadialLayout }; var center = g.FindNode(1); settings.Roots.Add(nodeMap[center]); var layout = new TreeLayout(); layout.Layout(diagram, settings); diagram.AutoFit(); }
private void CheckForConflicts(DependencyViewerNode node, int depth, DependencyViewerNode.NodeInputSide treeSide) { float minDistance = node.GetHeight() + DependencyViewerGraphDrawer.DistanceBetweenNodes.y; float shiftValue = 0.0f; var nodeContour = new Dictionary <int, float>(); TreeLayout.GetStartContour(node, depth, treeSide, 0, ref nodeContour); var sibling = node.GetFirstSibling(treeSide); while (sibling != null && sibling != node) { var siblingContour = new Dictionary <int, float>(); TreeLayout.GetEndContour(sibling, depth, treeSide, 0, ref siblingContour); int maxContourDepth = Mathf.Min(siblingContour.Keys.Max(), nodeContour.Keys.Max()); for (int level = depth + 1; level <= maxContourDepth; ++level) { float distance = nodeContour[level] - siblingContour[level]; if (distance + shiftValue < minDistance) { shiftValue = minDistance - distance; } } if (shiftValue > 0) { node.SetPositionY(node.Position.y + shiftValue); node.Mod += shiftValue; CenterNodesBetween(node, sibling, treeSide, depth); shiftValue = 0; } sibling = sibling.GetNextSibling(treeSide); } }
/// <summary> /// Creates a balanced radial forest. /// </summary> /// <param name="diagram">The diagram.</param> /// <param name="specs">The specs.</param> public static void BalancedRadialForest(this RadDiagram diagram, GraphGenerationSpecifications specs) { diagram.Clear(); Dictionary <Node, RadDiagramShape> nodeMap; Dictionary <Edge, RadDiagramConnection> edgeMap; var g = diagram.CreateDiagram(CreateBalancedForest(), out nodeMap, out edgeMap, CreateShape, specs.RandomShapeSize); var settings = new TreeLayoutSettings { TreeLayoutType = specs.TreeType, HorizontalSeparation = specs.HorizontalSeparation, VerticalSeparation = specs.VerticalSeparation, UnderneathHorizontalOffset = specs.UnderneathHorizontalOffset, UnderneathVerticalSeparation = specs.UnderneathVerticalSeparation, KeepComponentsInOneRadialLayout = specs.KeepComponentsInOneRadialLayout }; var center = g.FindNode(1); settings.Roots.Add(nodeMap[center]); var layout = new TreeLayout(); layout.Layout(diagram, settings); diagram.AutoFit(); }
public void LayoutWithChildren(TreeLayout layout) { element.Layout(this); float y = transform.position.y - element.GetLayoutHeight(); Vector3 next = new Vector3(transform.position.x, y, transform.position.z); if (children.Count == 0) { return; } else { for (int i = 0; i < children.Count; i++) { children[i].transform.position = next; next = new Vector3(next.x + children[i].GetLayoutWidth(), next.y, next.z); children[i].LayoutWithChildren(layout); } } }
private void AdjustRouteForAngleChange(TreeVertex parent, TreeVertex child) { double angle = TreeLayout.OrthoAngle(parent); double childangle = TreeLayout.OrthoAngle(child); if (angle == childangle) { return; } double layerspacing = TreeLayout.ComputeLayerSpacing(parent); Rect pb = parent.Node.Bounds; Rect cb = child.Node.Bounds; // but maybe an Angle change causes the child node not to be adjacent to the layer // separating it with the parent node; only need to do anything if that's the case if ((angle == 0 && cb.Left - pb.Right < layerspacing + 1) || (angle == 90 && cb.Top - pb.Bottom < layerspacing + 1) || (angle == 180 && pb.Left - cb.Right < layerspacing + 1) || (angle == 270 && pb.Top - cb.Bottom < layerspacing + 1)) { return; } Route s = this.Route; s.UpdatePoints(); bool bezier = s.Curve == LinkCurve.Bezier; bool ortho = s.Orthogonal; if (angle == 0) { double x = pb.Right + layerspacing / 2; if (bezier) // curved segments { if (s.PointsCount == 4) { double y = s.GetPoint(3).Y; s.SetPoint(1, new Point(x - 20, s.GetPoint(1).Y)); s.InsertPoint(2, new Point(x - 20, y)); s.InsertPoint(3, new Point(x, y)); s.InsertPoint(4, new Point(x + 20, y)); s.SetPoint(5, new Point(s.GetPoint(5).X, y)); } } else if (ortho) { if (s.PointsCount == 6) { s.SetPoint(2, new Point(x, s.GetPoint(2).Y)); s.SetPoint(3, new Point(x, s.GetPoint(3).Y)); } } else { if (s.PointsCount == 4) { s.InsertPoint(2, new Point(x, s.GetPoint(2).Y)); } else if (s.PointsCount == 3) { s.SetPoint(1, new Point(x, s.GetPoint(2).Y)); } else if (s.PointsCount == 2) { s.InsertPoint(1, new Point(x, s.GetPoint(1).Y)); } } } else if (angle == 90) { double y = pb.Bottom + layerspacing / 2; if (bezier) // curved segments { if (s.PointsCount == 4) { double x = s.GetPoint(3).X; s.SetPoint(1, new Point(s.GetPoint(1).X, y - 20)); s.InsertPoint(2, new Point(x, y - 20)); s.InsertPoint(3, new Point(x, y)); s.InsertPoint(4, new Point(x, y + 20)); s.SetPoint(5, new Point(x, s.GetPoint(5).Y)); } } else if (ortho) { if (s.PointsCount == 6) { s.SetPoint(2, new Point(s.GetPoint(2).X, y)); s.SetPoint(3, new Point(s.GetPoint(3).X, y)); } } else { if (s.PointsCount == 4) { s.InsertPoint(2, new Point(s.GetPoint(2).X, y)); } else if (s.PointsCount == 3) { s.SetPoint(1, new Point(s.GetPoint(2).X, y)); } else if (s.PointsCount == 2) { s.InsertPoint(1, new Point(s.GetPoint(1).X, y)); } } } else if (angle == 180) { double x = pb.Left - layerspacing / 2; if (bezier) // curved segments { if (s.PointsCount == 4) { double y = s.GetPoint(3).Y; s.SetPoint(1, new Point(x + 20, s.GetPoint(1).Y)); s.InsertPoint(2, new Point(x + 20, y)); s.InsertPoint(3, new Point(x, y)); s.InsertPoint(4, new Point(x - 20, y)); s.SetPoint(5, new Point(s.GetPoint(5).X, y)); } } else if (ortho) { if (s.PointsCount == 6) { s.SetPoint(2, new Point(x, s.GetPoint(2).Y)); s.SetPoint(3, new Point(x, s.GetPoint(3).Y)); } } else { if (s.PointsCount == 4) { s.InsertPoint(2, new Point(x, s.GetPoint(2).Y)); } else if (s.PointsCount == 3) { s.SetPoint(1, new Point(x, s.GetPoint(2).Y)); } else if (s.PointsCount == 2) { s.InsertPoint(1, new Point(x, s.GetPoint(1).Y)); } } } else if (angle == 270) { double y = pb.Top - layerspacing / 2; if (bezier) // curved segments { if (s.PointsCount == 4) { double x = s.GetPoint(3).X; s.SetPoint(1, new Point(s.GetPoint(1).X, y + 20)); s.InsertPoint(2, new Point(x, y + 20)); s.InsertPoint(3, new Point(x, y)); s.InsertPoint(4, new Point(x, y - 20)); s.SetPoint(5, new Point(x, s.GetPoint(5).Y)); } } else if (ortho) { if (s.PointsCount == 6) { s.SetPoint(2, new Point(s.GetPoint(2).X, y)); s.SetPoint(3, new Point(s.GetPoint(3).X, y)); } } else { if (s.PointsCount == 4) { s.InsertPoint(2, new Point(s.GetPoint(2).X, y)); } else if (s.PointsCount == 3) { s.SetPoint(1, new Point(s.GetPoint(2).X, y)); } else if (s.PointsCount == 2) { s.InsertPoint(1, new Point(s.GetPoint(1).X, y)); } } } }
public void Render(IVisio.Application app) { var orgchartdrawing = this; if (orgchartdrawing == null) { throw new System.ArgumentNullException(nameof(orgchartdrawing)); } if (app == null) { throw new System.ArgumentNullException(nameof(app)); } if (orgchartdrawing.OrgCharts.Count < 1) { throw new System.ArgumentException("orgchart must have at least one root"); } foreach (var root in orgchartdrawing.OrgCharts) { if (root == null) { throw new System.ArgumentException("Org chart has root node set to null"); } } var ver = Application.ApplicationHelper.GetVersion(app); int majorver = ver.Major; bool is_visio_2013 = majorver >= 15; const string orgchart_vst = "orgch_u.vst"; string orgchart_master_node_name = is_visio_2013 ? "Position Belt" : "Position"; const string dyncon_master_name = "Dynamic connector"; const double border_width = 0.5; var doc_node = new Dom.Document(orgchart_vst, IVisio.VisMeasurementSystem.visMSUS); var trees = new List <IList <Node <object> > >(); foreach (var root in orgchartdrawing.OrgCharts) { // Construct a layout tree from the hierarchy var treenodes = GenTreeOps.Algorithms.CopyTree( orgchartdrawing.OrgCharts[0], n => n.Children, n => this.node_to_layout_node(n), (p, c) => p.AddChild(c)); trees.Add(treenodes); // Perform the layout var layout = new TreeLayout <object>(); layout.Options.Direction = this.map_direction2(this.LayoutOptions.Direction); layout.Options.LevelSeparation = 1; layout.Options.SiblingSeparation = 0.25; layout.Options.SubtreeSeparation = 1; layout.Root.AddChild(treenodes[0]); layout.PerformLayout(); // Render the Document in Visio var bb = layout.GetBoundingBoxOfTree(); // vis.ActiveWindow.ShowConnectPoints = 0; var page_node = new Dom.Page(); doc_node.Pages.Add(page_node); // fixup the nodes so that they render on the page foreach (var i in treenodes) { i.Position = i.Position.Add(border_width, border_width); } var centerpoints = new Drawing.Point[treenodes.Count]; foreach (int i in Enumerable.Range(0, treenodes.Count)) { centerpoints[i] = treenodes[i].Rect.Center; } // TODO: Add support for Left to right , Right to Left, and Bottom to Top Layouts var vmasters = centerpoints .Select(centerpoint => page_node.Shapes.Drop(orgchart_master_node_name, null, centerpoint)) .ToList(); // For each OrgChart object, attach the shape that corresponds to it foreach (int i in Enumerable.Range(0, treenodes.Count)) { var orgnode = (Node)treenodes[i].Data; orgnode.DOMNode = vmasters[i]; vmasters[i].Cells.XFormWidth = treenodes[i].Size.Width; vmasters[i].Cells.XFormHeight = treenodes[i].Size.Height; } if (this.LayoutOptions.UseDynamicConnectors) { var orgchart_nodes = treenodes.Select(tn => tn.Data).Cast <Node>(); foreach (var parent in orgchart_nodes) { foreach (var child in parent.Children) { var parent_shape = (Dom.BaseShape)parent.DOMNode; var child_shape = (Dom.BaseShape)child.DOMNode; var connector = page_node.Shapes.Connect(dyncon_master_name, null, parent_shape, child_shape); } } } else { foreach (var connection in layout.EnumConnections()) { var bez = layout.GetConnectionBezier(connection); page_node.Shapes.DrawBezier(bez); } } // Set the Text Labels on each Org node foreach (int i in Enumerable.Range(0, treenodes.Count)) { var orgnode = (Node)treenodes[i].Data; var shape = (Dom.BaseShape)orgnode.DOMNode; shape.Text = new VisioAutomation.Models.Text.TextElement(orgnode.Text); } var page_size_with_border = bb.Size.Add(border_width * 2, border_width * 2.0); page_node.Size = page_size_with_border; page_node.ResizeToFit = true; page_node.ResizeToFitMargin = new Drawing.Size(border_width * 2, border_width * 2.0); } // finish handling root node var doc = doc_node.Render(app); foreach (var treenodes in trees) { var orgnodes = treenodes.Select(i => i.Data).Cast <Node>(); var orgnodes_with_urls = orgnodes.Where(n => n.URL != null); var all_urls = orgnodes_with_urls.Select(n => new { orgnode = n, shape = (Dom.BaseShape)n.DOMNode, url = n.URL.Trim() }); foreach (var url in all_urls) { var hlink = url.orgnode.VisioShape.Hyperlinks.Add(); hlink.Name = "Row_1"; hlink.Address = url.orgnode.URL; } // Attach all the orgchart nodes to the Visio shapes that were created foreach (int i in Enumerable.Range(0, treenodes.Count)) { var orgnode = (Node)treenodes[i].Data; var shape = (Dom.BaseShape)orgnode.DOMNode; orgnode.VisioShape = shape.VisioShape; } } }
//tree specific properties /// <summary> /// Commits the position of the link to the corresponding Link. /// </summary> /// <remarks> /// This routes the Link's Route. /// </remarks> public override void CommitPosition() { Route s = this.Route; if (s == null) { return; } if (s.Routing == LinkRouting.AvoidsNodes) { return; } TreeLayout layout = this.Network.Layout; TreeVertex parent; TreeVertex child; switch (layout.Path) { case TreePath.Destination: parent = this.FromVertex; child = this.ToVertex; break; case TreePath.Source: parent = this.ToVertex; child = this.FromVertex; break; default: throw new InvalidOperationException("Unhandled Path value " + layout.Path.ToString()); } if (parent == null || child == null) { return; } Point p = this.RelativePoint; if (p.X == 0 && p.Y == 0 && !parent.RouteFirstRow) // no rows { AdjustRouteForAngleChange(parent, child); return; } bool firstrow = (p.X == 0 && p.Y == 0 && parent.RouteFirstRow); Node node = parent.Node; Rect nodebounds = node.Bounds; double angle = TreeLayout.OrthoAngle(parent); double layerspacing = TreeLayout.ComputeLayerSpacing(parent); double rowspacing = parent.RowSpacing; s.UpdatePoints(); bool bezier = s.Curve == LinkCurve.Bezier; bool ortho = s.Orthogonal; int idx; Point prev; Point next; Point last; if (ortho || bezier) { idx = 2; while (s.PointsCount > 4) { s.RemovePoint(2); } prev = s.GetPoint(1); next = s.GetPoint(2); } else { idx = 1; while (s.PointsCount > 3) { s.RemovePoint(1); } prev = s.GetPoint(0); next = s.GetPoint(s.PointsCount - 1); } last = s.GetPoint(s.PointsCount - 1); if (angle == 0) { double c; if (parent.Alignment == TreeAlignment.End) { // route around at Y coordinate relative to the bottom of the parent node c = nodebounds.Bottom + p.Y; // try to keep the links straight from the parent node -- consider room from RowIndent and NodeIndent if (p.Y == 0 && prev.Y > last.Y + parent.RowIndent) { c = Math.Min(c, Math.Max(prev.Y, c - TreeLayout.ComputeNodeIndent(parent))); } } else if (parent.Alignment == TreeAlignment.Start) { // route around at Y coordinate relative to the top of the parent node c = nodebounds.Top + p.Y; // try to keep the links straight from the parent node -- consider room from RowIndent and NodeIndent if (p.Y == 0 && prev.Y < last.Y - parent.RowIndent) { c = Math.Max(c, Math.Min(prev.Y, c + TreeLayout.ComputeNodeIndent(parent))); } } else if (parent.RouteAroundCentered || (parent.RouteAroundLastParent && parent.MaxGenerationCount == 1)) { c = nodebounds.Top - parent.SubtreeOffset.Y + p.Y; } else { c = nodebounds.Y + nodebounds.Height / 2 + p.Y; } if (bezier) // curved segments { if (!firstrow) { // add a straight curve at Y-coord C s.InsertPoint(idx, new Point(prev.X, c)); idx++; s.InsertPoint(idx, new Point(nodebounds.Right + layerspacing, c)); idx++; s.InsertPoint(idx, new Point(nodebounds.Right + layerspacing + (p.X - rowspacing) / 3, c)); idx++; s.InsertPoint(idx, new Point(nodebounds.Right + layerspacing + (p.X - rowspacing) * 2 / 3, c)); idx++; } else { s.InsertPoint(idx, new Point(nodebounds.Right + layerspacing + (p.X - rowspacing), c)); idx++; } s.InsertPoint(idx, new Point(nodebounds.Right + layerspacing + (p.X - rowspacing), c)); idx++; s.InsertPoint(idx, new Point(next.X, c)); idx++; } else // straight line segments { if (ortho) { s.InsertPoint(idx, new Point(nodebounds.Right + layerspacing / 2, prev.Y)); idx++; } s.InsertPoint(idx, new Point(nodebounds.Right + layerspacing / 2, c)); idx++; s.InsertPoint(idx, new Point(nodebounds.Right + layerspacing + p.X - (ortho ? rowspacing / 2 : rowspacing), c)); idx++; if (ortho) { s.InsertPoint(idx, new Point(s.GetPoint(idx - 1).X, next.Y)); idx++; } } } else if (angle == 90) { double c; if (parent.Alignment == TreeAlignment.End) { c = nodebounds.Right + p.X; if (p.X == 0 && prev.X > last.X + parent.RowIndent) { c = Math.Min(c, Math.Max(prev.X, c - TreeLayout.ComputeNodeIndent(parent))); } } else if (parent.Alignment == TreeAlignment.Start) { c = nodebounds.Left + p.X; if (p.X == 0 && prev.X < last.X - parent.RowIndent) { c = Math.Max(c, Math.Min(prev.X, c + TreeLayout.ComputeNodeIndent(parent))); } } else if (parent.RouteAroundCentered || (parent.RouteAroundLastParent && parent.MaxGenerationCount == 1)) { c = nodebounds.Left - parent.SubtreeOffset.X + p.X; } else { c = nodebounds.X + nodebounds.Width / 2 + p.X; } if (bezier) { if (!firstrow) { s.InsertPoint(idx, new Point(c, prev.Y)); idx++; s.InsertPoint(idx, new Point(c, nodebounds.Bottom + layerspacing)); idx++; s.InsertPoint(idx, new Point(c, nodebounds.Bottom + layerspacing + (p.Y - rowspacing) / 3)); idx++; s.InsertPoint(idx, new Point(c, nodebounds.Bottom + layerspacing + (p.Y - rowspacing) * 2 / 3)); idx++; } else { s.InsertPoint(idx, new Point(c, nodebounds.Bottom + layerspacing + (p.Y - rowspacing))); idx++; } s.InsertPoint(idx, new Point(c, nodebounds.Bottom + layerspacing + (p.Y - rowspacing))); idx++; s.InsertPoint(idx, new Point(c, next.Y)); idx++; } else { if (ortho) { s.InsertPoint(idx, new Point(prev.X, nodebounds.Bottom + layerspacing / 2)); idx++; } s.InsertPoint(idx, new Point(c, nodebounds.Bottom + layerspacing / 2)); idx++; s.InsertPoint(idx, new Point(c, nodebounds.Bottom + layerspacing + p.Y - (ortho ? rowspacing / 2 : rowspacing))); idx++; if (ortho) { s.InsertPoint(idx, new Point(next.X, s.GetPoint(idx - 1).Y)); idx++; } } } else if (angle == 180) { double c; if (parent.Alignment == TreeAlignment.End) { c = nodebounds.Bottom + p.Y; if (p.Y == 0 && prev.Y > last.Y + parent.RowIndent) { c = Math.Min(c, Math.Max(prev.Y, c - TreeLayout.ComputeNodeIndent(parent))); } } else if (parent.Alignment == TreeAlignment.Start) { c = nodebounds.Top + p.Y; if (p.Y == 0 && prev.Y < last.Y - parent.RowIndent) { c = Math.Max(c, Math.Min(prev.Y, c + TreeLayout.ComputeNodeIndent(parent))); } } else if (parent.RouteAroundCentered || (parent.RouteAroundLastParent && parent.MaxGenerationCount == 1)) { c = nodebounds.Top - parent.SubtreeOffset.Y + p.Y; } else { c = nodebounds.Y + nodebounds.Height / 2 + p.Y; } if (bezier) { if (!firstrow) { s.InsertPoint(idx, new Point(prev.X, c)); idx++; s.InsertPoint(idx, new Point(nodebounds.Left - layerspacing, c)); idx++; s.InsertPoint(idx, new Point(nodebounds.Left - layerspacing + (p.X + rowspacing) / 3, c)); idx++; s.InsertPoint(idx, new Point(nodebounds.Left - layerspacing + (p.X + rowspacing) * 2 / 3, c)); idx++; } else { s.InsertPoint(idx, new Point(nodebounds.Left - layerspacing + (p.X + rowspacing), c)); idx++; } s.InsertPoint(idx, new Point(nodebounds.Left - layerspacing + (p.X + rowspacing), c)); idx++; s.InsertPoint(idx, new Point(next.X, c)); idx++; } else { if (ortho) { s.InsertPoint(idx, new Point(nodebounds.Left - layerspacing / 2, prev.Y)); idx++; } s.InsertPoint(idx, new Point(nodebounds.Left - layerspacing / 2, c)); idx++; s.InsertPoint(idx, new Point(nodebounds.Left - layerspacing + p.X + (ortho ? rowspacing / 2 : rowspacing), c)); idx++; if (ortho) { s.InsertPoint(idx, new Point(s.GetPoint(idx - 1).X, next.Y)); idx++; } } } else if (angle == 270) { double c; if (parent.Alignment == TreeAlignment.End) { c = nodebounds.Right + p.X; if (p.X == 0 && prev.X > last.X + parent.RowIndent) { c = Math.Min(c, Math.Max(prev.X, c - TreeLayout.ComputeNodeIndent(parent))); } } else if (parent.Alignment == TreeAlignment.Start) { c = nodebounds.Left + p.X; if (p.X == 0 && prev.X < last.X - parent.RowIndent) { c = Math.Max(c, Math.Min(prev.X, c + TreeLayout.ComputeNodeIndent(parent))); } } else if (parent.RouteAroundCentered || (parent.RouteAroundLastParent && parent.MaxGenerationCount == 1)) { c = nodebounds.Left - parent.SubtreeOffset.X + p.X; } else { c = nodebounds.X + nodebounds.Width / 2 + p.X; } if (bezier) { if (!firstrow) { s.InsertPoint(idx, new Point(c, prev.Y)); idx++; s.InsertPoint(idx, new Point(c, nodebounds.Top - layerspacing)); idx++; s.InsertPoint(idx, new Point(c, nodebounds.Top - layerspacing + (p.Y + rowspacing) / 3)); idx++; s.InsertPoint(idx, new Point(c, nodebounds.Top - layerspacing + (p.Y + rowspacing) * 2 / 3)); idx++; } else { s.InsertPoint(idx, new Point(c, nodebounds.Top - layerspacing + (p.Y + rowspacing))); idx++; } s.InsertPoint(idx, new Point(c, nodebounds.Top - layerspacing + (p.Y + rowspacing))); idx++; s.InsertPoint(idx, new Point(c, next.Y)); idx++; } else { if (ortho) { s.InsertPoint(idx, new Point(prev.X, nodebounds.Top - layerspacing / 2)); idx++; } s.InsertPoint(idx, new Point(c, nodebounds.Top - layerspacing / 2)); idx++; s.InsertPoint(idx, new Point(c, nodebounds.Top - layerspacing + p.Y + (ortho ? rowspacing / 2 : rowspacing))); idx++; if (ortho) { s.InsertPoint(idx, new Point(next.X, s.GetPoint(idx - 1).Y)); idx++; } } } else { throw new InvalidOperationException("Invalid angle " + angle.ToString(System.Globalization.CultureInfo.InvariantCulture)); } }
protected override LayoutData CreateConfiguredLayoutData(GraphControl graphControl, ILayoutAlgorithm layout) { var layoutData = new HierarchicLayoutData(); var incrementalLayout = SelectedElementsIncrementallyItem; var selection = graphControl.Selection; var selectedElements = selection.SelectedEdges.Any() || selection.SelectedNodes.Any(); if (incrementalLayout && selectedElements) { // configure the mode var ihf = ((HierarchicLayout)layout).CreateIncrementalHintsFactory(); layoutData.IncrementalHints.Delegate = item => { // Return the correct hint type for each model item that appears in one of these sets if (item is INode && selection.IsSelected(item)) { return(ihf.CreateLayerIncrementallyHint(item)); } if (item is IEdge && selection.IsSelected(item)) { return(ihf.CreateSequenceIncrementallyHint(item)); } return(null); }; } if (RankingPolicyItem == LayeringStrategy.Bfs) { layoutData.BfsLayererCoreNodes.Delegate = selection.IsSelected; } if (GridEnabledItem) { var nld = ((HierarchicLayout)layout).NodeLayoutDescriptor; layoutData.NodeLayoutDescriptors.Delegate = node => { var descriptor = new NodeLayoutDescriptor(); descriptor.LayerAlignment = nld.LayerAlignment; descriptor.MinimumDistance = nld.MinimumDistance; descriptor.MinimumLayerHeight = nld.MinimumLayerHeight; descriptor.NodeLabelMode = nld.NodeLabelMode; // anchor nodes on grid according to their alignment within the layer descriptor.GridReference = new YPoint(0.0, (nld.LayerAlignment - 0.5) * node.Layout.Height); descriptor.PortAssignment = this.GridPortAssignmentItem; return(descriptor); }; } if (EdgeDirectednessItem) { layoutData.EdgeDirectedness.Delegate = edge => { if (edge.Style is IArrowOwner && !Equals(((IArrowOwner)edge.Style).TargetArrow, Arrows.None)) { return(1); } return(0); }; } if (EdgeThicknessItem) { layoutData.EdgeThickness.Delegate = edge => { var style = edge.Style as PolylineEdgeStyle; if (style != null) { return(style.Pen.Thickness); } return(1); }; } if (SubComponentsItem) { // layout all siblings with label 'TL' separately with tree layout var treeLayout = new TreeLayout { DefaultNodePlacer = new LeftRightNodePlacer() }; foreach (var listOfNodes in FindSubComponents(graphControl.Graph, "TL")) { layoutData.SubComponents.Add(treeLayout).Items = listOfNodes; } // layout all siblings with label 'HL' separately with hierarchical layout var hierarchicLayout = new HierarchicLayout { LayoutOrientation = LayoutOrientation.LeftToRight }; foreach (var listOfNodes in FindSubComponents(graphControl.Graph, "HL")) { layoutData.SubComponents.Add(hierarchicLayout).Items = listOfNodes; } // layout all siblings with label 'OL' separately with organic layout var organicLayout = new OrganicLayout { PreferredEdgeLength = 100, Deterministic = true }; foreach (var listOfNodes in FindSubComponents(graphControl.Graph, "OL")) { layoutData.SubComponents.Add(organicLayout).Items = listOfNodes; } } if (HighlightCriticalPath) { // highlight the longest path in the graph as critical path // since the longest path algorithm only works for acyclic graphs, // feedback edges and self loops have to be excluded here var feedbackEdgeSetResult = new FeedbackEdgeSet().Run(graphControl.Graph); var longestPath = new LongestPath { SubgraphEdges = { Excludes = { Delegate = edge => feedbackEdgeSetResult.FeedbackEdgeSet.Contains(edge) || edge.IsSelfloop() } } }.Run(graphControl.Graph); if (longestPath.Edges.Any()) { layoutData.CriticalEdgePriorities.Delegate = edge => { if (longestPath.Edges.Contains(edge)) { return(10); } return(1); }; } } if (AutomaticBusRouting) { var allBusNodes = new HashSet <INode>(); foreach (var node in graphControl.Graph.Nodes) { if (!graphControl.Graph.IsGroupNode(node) && !allBusNodes.Contains(node)) { // search for good opportunities for bus structures rooted at this node if (graphControl.Graph.InDegree(node) >= 4) { var busDescriptor = new BusDescriptor(); var busEdges = GetBusEdges(graphControl.Graph, node, allBusNodes, graphControl.Graph.InEdgesAt(node)); if (busEdges.Any()) { layoutData.Buses.Add(busDescriptor).Items = busEdges; } } if (graphControl.Graph.OutDegree(node) >= 4) { var busDescriptor = new BusDescriptor(); var busEdges = GetBusEdges(graphControl.Graph, node, allBusNodes, graphControl.Graph.OutEdgesAt(node)); if (busEdges.Any()) { layoutData.Buses.Add(busDescriptor).Items = busEdges; } } } } } return(layoutData.CombineWith( CreateLabelingLayoutData( graphControl.Graph, LabelPlacementAlongEdgeItem, LabelPlacementSideOfEdgeItem, LabelPlacementOrientationItem, LabelPlacementDistanceItem ) )); }
private MultiStageLayout ConfigureDefaultLayout() { var layout = new TreeLayout(); layout.LayoutOrientation = NodePlacerItem == EnumNodePlacer.AspectRatio ? LayoutOrientation.TopToBottom : DefaultLayoutOrientationItem; RootAlignment rootAlignment1 = RootAlignment.Center; RotatableNodePlacerBase.RootAlignment rootAlignment2 = RotatableNodePlacerBase.RootAlignment.Center; switch (RootAlignmentItem) { case EnumRootAlignment.Center: rootAlignment1 = RootAlignment.Center; rootAlignment2 = RotatableNodePlacerBase.RootAlignment.Center; break; case EnumRootAlignment.Median: rootAlignment1 = RootAlignment.Median; rootAlignment2 = RotatableNodePlacerBase.RootAlignment.Median; break; case EnumRootAlignment.Left: rootAlignment1 = RootAlignment.Leading; rootAlignment2 = RotatableNodePlacerBase.RootAlignment.Left; break; case EnumRootAlignment.Leading: rootAlignment1 = RootAlignment.LeadingOffset; rootAlignment2 = RotatableNodePlacerBase.RootAlignment.Leading; break; case EnumRootAlignment.Right: rootAlignment1 = RootAlignment.Trailing; rootAlignment2 = RotatableNodePlacerBase.RootAlignment.Right; break; case EnumRootAlignment.Trailing: rootAlignment1 = RootAlignment.TrailingOffset; rootAlignment2 = RotatableNodePlacerBase.RootAlignment.Trailing; break; } var allowMultiParents = AllowMultiParentsItem; switch (NodePlacerItem) { case EnumNodePlacer.Default: layout.DefaultNodePlacer = new DefaultNodePlacer { HorizontalDistance = SpacingItem, VerticalDistance = SpacingItem, RootAlignment = rootAlignment1 }; layout.MultiParentAllowed = allowMultiParents; break; case EnumNodePlacer.Simple: layout.DefaultNodePlacer = new SimpleNodePlacer { Spacing = SpacingItem, RootAlignment = rootAlignment2 }; break; case EnumNodePlacer.Bus: layout.DefaultNodePlacer = new BusNodePlacer { Spacing = SpacingItem, }; layout.MultiParentAllowed = allowMultiParents; break; case EnumNodePlacer.DoubleLine: layout.DefaultNodePlacer = new DoubleLineNodePlacer { Spacing = SpacingItem, RootAlignment = rootAlignment2 }; break; case EnumNodePlacer.LeftRight: layout.DefaultNodePlacer = new LeftRightNodePlacer { Spacing = SpacingItem }; layout.MultiParentAllowed = allowMultiParents; break; case EnumNodePlacer.Layered: layout.DefaultNodePlacer = new LayeredNodePlacer { Spacing = SpacingItem, LayerSpacing = SpacingItem, RootAlignment = rootAlignment2 }; break; case EnumNodePlacer.AspectRatio: layout.DefaultNodePlacer = new AspectRatioNodePlacer { HorizontalDistance = SpacingItem, VerticalDistance = SpacingItem, AspectRatio = NodePlacerAspectRatioItem }; break; case EnumNodePlacer.Dendrogram: layout.DefaultNodePlacer = new DendrogramNodePlacer { MinimumRootDistance = SpacingItem, MinimumSubtreeDistance = SpacingItem, }; layout.MultiParentAllowed = allowMultiParents; break; case EnumNodePlacer.Grid: layout.DefaultNodePlacer = new GridNodePlacer { Spacing = SpacingItem, RootAlignment = rootAlignment2 }; break; case EnumNodePlacer.Compact: layout.DefaultNodePlacer = new CompactNodePlacer { HorizontalDistance = SpacingItem, VerticalDistance = SpacingItem, PreferredAspectRatio = NodePlacerAspectRatioItem }; break; } layout.DefaultPortAssignment = new DefaultPortAssignment(PortAssignmentItem); layout.GroupingSupported = true; return(layout); }
private void SetupLayouts() { //using hierarchical layout style HierarchicLayout hierarchicLayout = new HierarchicLayout(); hierarchicLayout.EdgeLayoutDescriptor.RoutingStyle = new yWorks.Layout.Hierarchic.RoutingStyle( yWorks.Layout.Hierarchic.EdgeRoutingStyle.Orthogonal); CurrentLayout = hierarchicLayout; layouts.Add("Hierarchic", hierarchicLayout); //using organic layout style OrganicLayout organic = new OrganicLayout { QualityTimeRatio = 1.0, NodeOverlapsAllowed = false, NodeEdgeOverlapAvoided = true, MinimumNodeDistance = 10, PreferredEdgeLength = 50, }; layouts.Add("Organic", organic); //using orthogonal layout style OrthogonalLayout orthogonal = new OrthogonalLayout { GridSpacing = 15, OptimizePerceivedBends = true }; layouts.Add("Orthogonal", orthogonal); //using circular layout style CircularLayout circular = new CircularLayout(); circular.BalloonLayout.MinimumEdgeLength = 50; circular.BalloonLayout.CompactnessFactor = 0.1; layouts.Add("Circular", circular); // a tree layout algorithm TreeLayout treeLayout = new TreeLayout { ConsiderNodeLabels = true }; treeLayout.AppendStage(new TreeReductionStage() { NonTreeEdgeRouter = new OrganicEdgeRouter(), NonTreeEdgeSelectionKey = OrganicEdgeRouter.AffectedEdgesDpKey, }); layouts.Add("Tree", treeLayout); //using Polyline Router var polylineRouter = new EdgeRouter { Grid = new Grid(0, 0, 10), PolylineRouting = true, Rerouting = true }; polylineRouter.DefaultEdgeLayoutDescriptor.PenaltySettings.BendPenalty = 3; polylineRouter.DefaultEdgeLayoutDescriptor.PenaltySettings.EdgeCrossingPenalty = 5; layouts.Add("Polyline Edge Router", polylineRouter); }
public void ExecuteLayout(Type type, bool resize) { bool suspend = this.Suspended; if (!suspend) { this.SuspendEvents = true; this.Suspend(); } // Create Layout Graph Graph graph = new Graph(); graph.AddDiagram(this); // Layout layout = null; if (type == typeof(TreeLayout)) { TreeLayout treeLayout = new TreeLayout(); treeLayout.Direction = TreeLayoutSettings.Default.Direction; treeLayout.LevelDistance = TreeLayoutSettings.Default.LevelDistance; treeLayout.OrthogonalLayoutStyle = TreeLayoutSettings.Default.OrthogonalLayoutStyle; treeLayout.RootSelection = TreeLayoutSettings.Default.RootSelection; treeLayout.SiblingDistance = TreeLayoutSettings.Default.SiblingDistance; treeLayout.SubtreeDistance = TreeLayoutSettings.Default.SubtreeDistance; treeLayout.TreeDistance = TreeLayoutSettings.Default.TreeDistance; layout = treeLayout; } else if (type == typeof(OrthogonalLayout)) { OrthogonalLayout orthogonalLayout = new OrthogonalLayout(); orthogonalLayout.ConnectedComponentDistance = OrthogonalLayoutSettings.Default.ConnectedComponentDistance; orthogonalLayout.CrossingQuality = OrthogonalLayoutSettings.Default.CrossingQuality; orthogonalLayout.Distance = OrthogonalLayoutSettings.Default.Distance; orthogonalLayout.Overhang = OrthogonalLayoutSettings.Default.Overhang; layout = orthogonalLayout; } else if (type == typeof(HierarchicalLayout)) { HierarchicalLayout hierarchicalLayout = new HierarchicalLayout(); hierarchicalLayout.ConnectedComponentDistance = HierarchicalLayoutSettings.Default.ConnectedComponentDistance; hierarchicalLayout.Direction = HierarchicalLayoutSettings.Default.Direction; hierarchicalLayout.LayerDistance = HierarchicalLayoutSettings.Default.LayerDistance; hierarchicalLayout.ObjectDistance = HierarchicalLayoutSettings.Default.ObjectDistance; hierarchicalLayout.RespectLayer = HierarchicalLayoutSettings.Default.RespectLayer; layout = hierarchicalLayout; } else if (type == typeof(ForceDirectedLayout)) { ForceDirectedLayout forceDirectedLayout = new ForceDirectedLayout(); forceDirectedLayout.ConnectedComponentDistance = ForcedDirectLayoutSettings.Default.ConnectedComponentDistance; forceDirectedLayout.Quality = ForcedDirectLayoutSettings.Default.Quality; forceDirectedLayout.Tuning = ForcedDirectLayoutSettings.Default.TuningType; layout = forceDirectedLayout; } else if (type == typeof(CircularLayout)) { CircularLayout circularLayout = new CircularLayout(); circularLayout.CircleDistance = CircularLayoutSettings.Default.CircleDistance; circularLayout.ConnectedComponentDistance = CircularLayoutSettings.Default.ConnectedComponentDistance; circularLayout.LayerDistance = CircularLayoutSettings.Default.LayerDistance; circularLayout.ObjectDistance = CircularLayoutSettings.Default.ObjectDistance; layout = circularLayout; } // if (layout != null) { // Do Layout layout.DoLayout(graph); // Apply if Layout Succeeded if (layout.Status == LayoutStatus.Success) { // Resize Diagram RectangleF rectangle = graph.TotalArea(); rectangle.Inflate(50, 50); if (resize) { this.DiagramSize = rectangle.Size.ToSize(); } graph.ScaleToFit(this.DiagramSize); // Apply Layout graph.Apply(this); } } if (!suspend) { this.Resume(); this.SuspendEvents = false; this.Refresh(); } }
void Canvas_Loaded(object sender, RoutedEventArgs e) { TreeLayout.SwitchOn(); TreeLayout.LayoutDiagram(xCaseDrawComponent.Canvas); }
protected override LayoutData CreateConfiguredLayoutData(GraphControl graphControl, ILayoutAlgorithm layout) { var layoutData = new HierarchicLayoutData(); var incrementalLayout = SelectedElementsIncrementallyItem; var selection = graphControl.Selection; var selectedElements = selection.SelectedEdges.Any() || selection.SelectedNodes.Any(); if (incrementalLayout && selectedElements) { // configure the mode var ihf = ((HierarchicLayout)layout).CreateIncrementalHintsFactory(); layoutData.IncrementalHints.Delegate = item => { // Return the correct hint type for each model item that appears in one of these sets if (item is INode && selection.IsSelected(item)) { return(ihf.CreateLayerIncrementallyHint(item)); } if (item is IEdge && selection.IsSelected(item)) { return(ihf.CreateSequenceIncrementallyHint(item)); } return(null); }; } if (RankingPolicyItem == LayeringStrategy.Bfs) { layoutData.BfsLayererCoreNodes.Delegate = selection.IsSelected; } if (GridEnabledItem) { var nld = ((HierarchicLayout)layout).NodeLayoutDescriptor; layoutData.NodeLayoutDescriptors.Delegate = node => { var descriptor = new NodeLayoutDescriptor(); descriptor.LayerAlignment = nld.LayerAlignment; descriptor.MinimumDistance = nld.MinimumDistance; descriptor.MinimumLayerHeight = nld.MinimumLayerHeight; descriptor.NodeLabelMode = nld.NodeLabelMode; // anchor nodes on grid according to their alignment within the layer descriptor.GridReference = new YPoint(0.0, (nld.LayerAlignment - 0.5) * node.Layout.Height); descriptor.PortAssignment = this.GridPortAssignmentItem; return(descriptor); }; } if (EdgeDirectednessItem) { layoutData.EdgeDirectedness.Delegate = edge => { if (edge.Style is IArrowOwner && !Equals(((IArrowOwner)edge.Style).TargetArrow, Arrows.None)) { return(1); } return(0); }; } if (EdgeThicknessItem) { layoutData.EdgeThickness.Delegate = edge => { var style = edge.Style as PolylineEdgeStyle; if (style != null) { return(style.Pen.Width); } return(1); }; } if (SubComponentsItem) { var treeLayout = new TreeLayout { DefaultNodePlacer = new LeftRightNodePlacer() }; layoutData.SubComponents.Add(treeLayout).Delegate = node => node.Labels.Any() && node.Labels.First().Text == "TL"; var hierarchicLayout = new HierarchicLayout { LayoutOrientation = LayoutOrientation.LeftToRight }; layoutData.SubComponents.Add(hierarchicLayout).Delegate = node => node.Labels.Any() && node.Labels.First().Text == "HL"; var organicLayout = new OrganicLayout { PreferredEdgeLength = 100, Deterministic = true }; layoutData.SubComponents.Add(organicLayout).Delegate = node => node.Labels.Any() && node.Labels.First().Text == "OL"; } if (BusesItem) { // Group edges ending at a node with the label "Bus" into a bus layoutData.Buses.Add(new BusDescriptor()).Delegate = edge => edge.GetTargetNode().Labels.Count > 0 && edge.GetTargetNode().Labels[0].Text == "Bus"; } return(layoutData); }
/// <summary> /// Creates a tree which grows symmetrically. /// </summary> /// <param name="diagram">The diagram.</param> /// <param name="specs">The specs.</param> private void BalancedRadialTree(RadDiagram diagram, GraphGenerationSpecifications specs) { this.diagram.Clear(); Dictionary<Node, RadDiagramShape> nodeMap; Dictionary<Edge, RadDiagramConnection> edgeMap; // the algorithm to create a balanced tree is quite straighforward var g = this.diagram.CreateDiagram(GraphExtensions.CreateBalancedTree(), out nodeMap, out edgeMap, GraphExtensions.CreateShape, this.RandomSizeCheck.IsChecked.HasValue && this.RandomSizeCheck.IsChecked.Value); // the result is best displayed with the radial tree layout var settings = new TreeLayoutSettings { TreeLayoutType = TreeLayoutType.RadialTree, HorizontalSeparation = this.HorizontalSeparationSlider.Value, VerticalSeparation = this.VerticalSeparationSlider.Value, UnderneathHorizontalOffset = this.UnderneathHorizontalOffsetSlider.Value, UnderneathVerticalSeparation = this.UnderneathVerticalOffsetSlider.Value, StartRadialAngle = Math.PI, // use a specific angle rather than the full 360° to show one of the layout's (hidden) gem EndRadialAngle = 3.47 * Math.PI / 2 }; var center = g.FindNode(-1); settings.Roots.Add(nodeMap[center]); var layout = new TreeLayout(); layout.Layout(this.diagram, settings); // center and size autimagically this.diagram.AutoFit(); // you can colorize the shapes, if you wish // this.Colorize(g, nodeMap, center); }
void updateLayout() { TreeLayout.LayoutDiagram(this); }
public void BindToDiagram(Diagram diagram, ModelController modelController) { PropertyPath propertyPath = new PropertyPath("Caption"); Binding titleBinding = new Binding { Source = diagram, Path = propertyPath }; SetBinding(TitleProperty, titleBinding); // bound view to controller and controller to model DiagramController = new DiagramController(diagram, modelController); ModelController = modelController; xCaseDrawComponent.Canvas.Controller = DiagramController; try { Mouse.SetCursor(Cursors.Wait); #region load items on the diagram List <Element> alreadyProcessed = new List <Element>(); RegistrationSet registrationSet; if (diagram is PIMDiagram) { registrationSet = MainWindow.PIMRepresentantsSet; /* Elements in PIM diagram are loaded in the order of their LoadPriority in registration set */ foreach (RepresentantRegistration registration in registrationSet.OrderBy(reg => reg.LoadPriority)) { foreach (KeyValuePair <Element, ViewHelper> pair in diagram.DiagramElements) { if (!alreadyProcessed.Contains(pair.Key) && registration.ModelElementType.IsInstanceOfType(pair.Key)) { diagram.NotifyElementAdded(this, pair.Key, pair.Value); alreadyProcessed.Add(pair.Key); } } } } else { /* order of the elements in PSM diagram is more complex, an ordering function * is called to order the elements (basically BFS) */ TreeLayout.SwitchOff(); IList <Element> ordered; if (PSMTree.ReturnElementsInPSMOrder(((PSMDiagram)diagram).Roots, out ordered, true)) { foreach (Element element in ordered) { diagram.NotifyElementAdded(this, element, diagram.DiagramElements[element]); } foreach (Comment comment in diagram.DiagramElements.Keys.OfType <Comment>()) { diagram.NotifyElementAdded(this, comment, diagram.DiagramElements[comment]); } foreach (PSMDiagramReference psmDiagramReference in diagram.DiagramElements.Keys.OfType <PSMDiagramReference>()) { diagram.NotifyElementAdded(this, psmDiagramReference, diagram.DiagramElements[psmDiagramReference]); } } xCaseDrawComponent.Canvas.Loaded += Canvas_Loaded; } #endregion } finally { Mouse.SetCursor(Cursors.Arrow); } }
/// <summary> /// Creates a forest of unbalanced trees and applies a radial layout. /// </summary> /// <param name="diagram">The diagram.</param> /// <param name="specs">The specs.</param> private void RandomRadialForest(RadDiagram diagram, GraphGenerationSpecifications specs) { this.diagram.Clear(); Dictionary<Node, RadDiagramShape> nodeMap; Dictionary<Edge, RadDiagramConnection> edgeMap; var g = this.diagram.CreateDiagram(GraphExtensions.CreateRandomGraph(250, 4, true), out nodeMap, out edgeMap, GraphExtensions.CreateShape, this.RandomSizeCheck.IsChecked.HasValue && this.RandomSizeCheck.IsChecked.Value); var settings = new TreeLayoutSettings { TreeLayoutType = TreeLayoutType.RadialTree, HorizontalSeparation = this.HorizontalSeparationSlider.Value, VerticalSeparation = this.VerticalSeparationSlider.Value, UnderneathHorizontalOffset = this.UnderneathHorizontalOffsetSlider.Value, UnderneathVerticalSeparation = this.UnderneathVerticalOffsetSlider.Value, KeepComponentsInOneRadialLayout = true, RadialSeparation = 45d }; var center = g.FindNode(0); settings.Roots.Add(nodeMap[center]); var layout = new TreeLayout(); layout.Layout(this.diagram, settings); this.diagram.AutoFit(); //Colorize(g, nodeMap, center); }