Browse Source

Tree layout is determined by BFS rather than DFS.

pull/15/head
mkonicek 15 years ago
parent
commit
bbf3053188
  1. 47
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeLayout.cs

47
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeLayout.cs

@ -78,31 +78,48 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
void CalculateLayout(PositionedGraph positionedGraph) void CalculateLayout(PositionedGraph positionedGraph)
{ {
HashSet<PositionedNode> seenNodes = new HashSet<PositionedNode>(); // impose a tree structure on the graph
HashSet<PositionedEdge> treeEdges = new HashSet<PositionedEdge>(); HashSet<PositionedEdge> treeEdges = DetermineTreeEdges(positionedGraph.Root);
// first layout pass // first layout pass
CalculateSubtreeSizes(positionedGraph.Root, seenNodes, treeEdges); CalculateSubtreeSizesRecursive(positionedGraph.Root, treeEdges);
// second layout pass // second layout pass
CalculateNodePosRecursive(positionedGraph.Root, treeEdges, MarginTop, MarginBottom); CalculateNodePosRecursive(positionedGraph.Root, treeEdges, MarginTop, MarginBottom);
} }
// determines which edges are tree edges, and calculates subtree size for each node
private void CalculateSubtreeSizes(PositionedNode root, HashSet<PositionedNode> seenNodes, HashSet<PositionedEdge> treeEdges) HashSet<PositionedEdge> DetermineTreeEdges(PositionedNode root)
{ {
var treeEdges = new HashSet<PositionedEdge>();
var seenNodes = new HashSet<PositionedNode>();
var q = new Queue<PositionedNode>();
q.Enqueue(root);
seenNodes.Add(root); seenNodes.Add(root);
double subtreeSize = 0;
foreach (var property in root.Properties) { while (q.Count > 0) {
var edge = property.Edge; var node = q.Dequeue();
if (edge != null) { foreach (var property in node.Properties) {
var targetNode = edge.Target; var edge = property.Edge;
if (!seenNodes.Contains(targetNode)) { if (edge != null && edge.Target != null) {
// when we come to a node for the first time, we declare the incoming edge a tree edge if (!seenNodes.Contains(edge.Target)) {
treeEdges.Add(edge); treeEdges.Add(edge);
CalculateSubtreeSizes(targetNode, seenNodes, treeEdges); seenNodes.Add(edge.Target);
subtreeSize += targetNode.SubtreeSize; q.Enqueue(edge.Target);
}
} }
} }
} }
return treeEdges;
}
void CalculateSubtreeSizesRecursive(PositionedNode root, HashSet<PositionedEdge> treeEdges)
{
double subtreeSize = 0;
foreach (var child in TreeChildNodes(root, treeEdges)) {
CalculateSubtreeSizesRecursive(child, treeEdges);
// just sum up the sizes of children
subtreeSize += child.SubtreeSize;
}
root.SubtreeSize = Math.Max(GetLateralSizeWithMargin(root), subtreeSize); root.SubtreeSize = Math.Max(GetLateralSizeWithMargin(root), subtreeSize);
} }

Loading…
Cancel
Save