// determines which edges are tree edges, and calculates subtree size for each node private void calculateSubtreeSizes(TreeGraphNode root) { seenNodes.Add(root); double subtreeSize = 0; foreach (PositionedNodeProperty property in root.Properties) { var edge = property.Edge as TreeGraphEdge; // we know that these egdes are TreeEdges if (edge != null) { var neigborNode = (TreeGraphNode)edge.Target; if (seenNodes.Contains(neigborNode)) { edge.IsTreeEdge = false; } else { edge.IsTreeEdge = true; calculateSubtreeSizes(neigborNode); subtreeSize += neigborNode.SubtreeSize; } } } root.Measure(); root.SubtreeSize = Math.Max(root.LateralSizeWithMargin, subtreeSize); }
/// <summary> /// Given SubtreeSize for each node, positions the nodes, in a left-to-right or top-to-bottom fashion. /// </summary> /// <param name="node"></param> /// <param name="lateralStart"></param> /// <param name="mainStart"></param> private void calculateNodePosRecursive(TreeGraphNode node, double lateralStart, double mainStart) { double childsSubtreeSize = node.Childs.Sum(child => child.SubtreeSize); // center this node double center = node.ChildEdges.Count() == 0 ? 0 : 0.5 * (childsSubtreeSize - (node.LateralSizeWithMargin)); if (center < 0) { // if root is larger than subtree, it would be shifted below lateralStart // -> make whole layout start at lateralStart lateralStart -= center; } // design alternatives // node.MainPos += center; // used this // Adapt(node).PosLateral += center; // TreeNodeAdapterLR + TreeNodeAdapterTB // SetMainPos(node, GetMainPos(node) + 10) // TreeNodeAdapterLR + TreeNodeAdapterTB, no creation node.LateralCoord += lateralStart + center; node.MainCoord = mainStart; double childLateral = lateralStart; double childsMainFixed = node.MainCoord + node.MainSizeWithMargin; foreach (TreeGraphNode child in node.Childs) { calculateNodePosRecursive(child, childLateral, childsMainFixed); childLateral += child.SubtreeSize; } }
private TreeGraphNode createNewTreeGraphNode(ObjectGraphNode objectGraphNode) { var newGraphNode = TreeGraphNode.Create(this.layoutDirection, objectGraphNode); newGraphNode.HorizontalMargin = horizNodeMargin; newGraphNode.VerticalMargin = vertNodeMargin; return(newGraphNode); }
private PositionedGraph buildTreeGraph(ObjectGraph objectGraph, Expanded expanded) { var resultGraph = new PositionedGraph(); // create empty PosNodes foreach (ObjectGraphNode objectGraphNode in objectGraph.ReachableNodes) { TreeGraphNode posNode = createNewTreeGraphNode(objectGraphNode); resultGraph.AddNode(posNode); treeNodeFor[objectGraphNode] = posNode; posNode.InitContentFromObjectNode(expanded); } // create edges foreach (PositionedGraphNode posNode in resultGraph.Nodes) { // create edges outgoing from this posNode foreach (PositionedNodeProperty property in posNode.Properties) { //property.IsPropertyExpanded = expanded.Expressions.IsExpanded(property.Expression); if (property.ObjectGraphProperty.TargetNode != null) { ObjectGraphNode targetObjectNode = property.ObjectGraphProperty.TargetNode; PositionedGraphNode edgeTarget = treeNodeFor[targetObjectNode]; property.Edge = new TreeGraphEdge { IsTreeEdge = false, Name = property.Name, Source = property, Target = edgeTarget }; } } } resultGraph.Root = treeNodeFor[objectGraph.Root]; return(resultGraph); }