diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/GraphDrawer.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/GraphDrawer.cs index fd3fef5285..5cdbd35819 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/GraphDrawer.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/GraphDrawer.cs @@ -39,22 +39,10 @@ namespace Debugger.AddIn.Visualizers.Graph /// public void StartAnimation(PositionedGraph oldGraph, PositionedGraph newGraph, GraphDiff diff) { - if (oldGraph != null) - { - foreach (var oldNode in oldGraph.Nodes) - { - foreach (var newNode in newGraph.Nodes) - { - if (oldNode.NodeVisualControl == newNode.NodeVisualControl) - { - ClearCanvas(); - } - } - } - } + // account for that the visual controls could have been reused (we are not reusing controls now - NodeControlCache does nothing) - this.canvas.Width = newGraph.BoundingRect.Width; - this.canvas.Height = newGraph.BoundingRect.Height; +// this.canvas.Width = newGraph.BoundingRect.Width; +// this.canvas.Height = newGraph.BoundingRect.Height; if (oldGraph == null) { @@ -113,7 +101,7 @@ namespace Debugger.AddIn.Visualizers.Graph node.NodeVisualControl.BeginAnimation(CanvasLocationAdapter.LocationProperty, anim); } } - + /// /// Draws on Canvas. /// diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml index b98afd7a11..639d04145f 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml @@ -13,7 +13,11 @@ - + + @@ -51,8 +55,7 @@ @@ -98,6 +101,6 @@ - + \ No newline at end of file diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs index 82cc413a2c..b6633bd5cb 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs @@ -59,16 +59,15 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing { this.root = value; this.view = getInitialView(this.root); - // data virtualization, PropertyNodeViewModel implements IEvaluate + // data virtualization, ContentPropertyNode implements IEvaluate this.listView.ItemsSource = new VirtualizingObservableCollection(this.view); - int maxLen = this.view.MaxOrDefault(contentNode => { return contentNode.Name.Length; }, 0); + /*int maxLen = this.view.MaxOrDefault(contentNode => { return contentNode.Name.Length; }, 0); int spaces = Math.Max((int)(maxLen * 1.8 - 3), 0); string addedSpaces = StringHelper.Repeat(' ', spaces); - GridView gv = listView.View as GridView; // hack - autosize Name column - gv.Columns[1].Header = "Name" + addedSpaces; + gv.Columns[1].Header = "Name" + addedSpaces;*/ //AutoSizeColumns(); diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/GraphEdgeRouter.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/GraphEdgeRouter.cs index 7541deae9f..8a4ca5c266 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/GraphEdgeRouter.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/GraphEdgeRouter.cs @@ -21,7 +21,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout { } - public PositionedGraph RouteEdges(PositionedGraph posGraph) + public void RouteEdges(PositionedGraph posGraph) { List routedEdges = router.RouteEdges(posGraph.Nodes, posGraph.Edges); int i = 0; @@ -30,7 +30,6 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout SetEdgeSplinePoints(edge, routedEdges[i]); i++; } - return posGraph; } void SetEdgeSplinePoints(PositionedEdge edge, RoutedEdge routedEdge) diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeLayouter.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeLayouter.cs index 1e6c46d48b..2607ed7950 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeLayouter.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeLayouter.cs @@ -17,10 +17,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout private static readonly double horizNodeMargin = 30; private static readonly double vertNodeMargin = 30; - private LayoutDirection layoutDirection = LayoutDirection.TopBottom; - - HashSet seenNodes = new HashSet(); - Dictionary treeNodeFor = new Dictionary(); + GraphEdgeRouter edgeRouter = new GraphEdgeRouter(); public TreeLayouter() { @@ -33,113 +30,89 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout /// public PositionedGraph CalculateLayout(ObjectGraph objectGraph, LayoutDirection direction, Expanded expanded) { - layoutDirection = direction; - - treeNodeFor = new Dictionary(); - seenNodes = new HashSet(); - - //TreeGraphNode tree = buildTreeRecursive(objectGraph.Root, expandedNodes); - - // convert ObjectGraph to PositionedGraph with TreeEdges - var resultGraph = buildTreeGraph(objectGraph, expanded); - // first layout pass - calculateSubtreeSizes((TreeGraphNode)resultGraph.Root); - // second layout pass - calculateNodePosRecursive((TreeGraphNode)resultGraph.Root, 0, 0); - - //var neatoRouter = new NeatoEdgeRouter(); - //resultGraph = neatoRouter.CalculateEdges(resultGraph); - resultGraph = new GraphEdgeRouter().RouteEdges(resultGraph); + var positionedGraph = BuildPositionedGraph(objectGraph, direction, expanded); + CalculateLayout(positionedGraph); + this.edgeRouter.RouteEdges(positionedGraph); - return resultGraph; + return positionedGraph; } - private PositionedGraph buildTreeGraph(ObjectGraph objectGraph, Expanded expanded) + PositionedGraph BuildPositionedGraph(ObjectGraph objectGraph, LayoutDirection direction, Expanded expanded)// Expanded is passed so that the correct ContentNodes are expanded in the PositionedNode { + var treeNodeFor = new Dictionary(); var resultGraph = new PositionedGraph(); - // create empty PosNodes - foreach (ObjectGraphNode objectGraphNode in objectGraph.ReachableNodes) - { - TreeGraphNode posNode = createNewTreeGraphNode(objectGraphNode); + // create empty PositionedNodes + foreach (ObjectGraphNode objectGraphNode in objectGraph.ReachableNodes) { + TreeGraphNode posNode = TreeGraphNode.Create(direction, objectGraphNode); + posNode.InitContentFromObjectNode(expanded); + posNode.HorizontalMargin = horizNodeMargin; + posNode.VerticalMargin = vertNodeMargin; 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) - { + foreach (PositionedNodeProperty property in posNode.Properties) { + 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 }; + property.Edge = new TreeGraphEdge + { IsTreeEdge = false, Name = property.Name, Source = property, Target = edgeTarget }; } } } - resultGraph.Root = treeNodeFor[objectGraph.Root]; return resultGraph; } + + void CalculateLayout(PositionedGraph resultGraph) + { + HashSet seenNodes = new HashSet(); + // first layout pass + CalculateSubtreeSizes((TreeGraphNode)resultGraph.Root, seenNodes); + // second layout pass + CalculateNodePosRecursive((TreeGraphNode)resultGraph.Root, 0, 0); + } // determines which edges are tree edges, and calculates subtree size for each node - private void calculateSubtreeSizes(TreeGraphNode root) + private void CalculateSubtreeSizes(TreeGraphNode root, HashSet seenNodes) { seenNodes.Add(root); double subtreeSize = 0; - foreach (PositionedNodeProperty property in root.Properties) - { + foreach (PositionedNodeProperty property in root.Properties) { var edge = property.Edge as TreeGraphEdge; // we know that these egdes are TreeEdges - if (edge != null) - { + if (edge != null) { var neigborNode = (TreeGraphNode)edge.Target; - if (seenNodes.Contains(neigborNode)) - { + if (seenNodes.Contains(neigborNode)) { edge.IsTreeEdge = false; - } - else - { + } else { edge.IsTreeEdge = true; - calculateSubtreeSizes(neigborNode); + CalculateSubtreeSizes(neigborNode, seenNodes); subtreeSize += neigborNode.SubtreeSize; } } } - root.Measure(); root.SubtreeSize = Math.Max(root.LateralSizeWithMargin, subtreeSize); } - private TreeGraphNode createNewTreeGraphNode(ObjectGraphNode objectGraphNode) - { - var newGraphNode = TreeGraphNode.Create(this.layoutDirection, objectGraphNode); - newGraphNode.HorizontalMargin = horizNodeMargin; - newGraphNode.VerticalMargin = vertNodeMargin; - return newGraphNode; - } - /// /// Given SubtreeSize for each node, positions the nodes, in a left-to-right or top-to-bottom fashion. /// /// /// /// - private void calculateNodePosRecursive(TreeGraphNode node, double lateralStart, double mainStart) + 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 (center < 0) { // if root is larger than subtree, it would be shifted below lateralStart // -> make whole layout start at lateralStart lateralStart -= center; @@ -155,9 +128,8 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout double childLateral = lateralStart; double childsMainFixed = node.MainCoord + node.MainSizeWithMargin; - foreach (TreeGraphNode child in node.Childs) - { - calculateNodePosRecursive(child, childLateral, childsMainFixed); + foreach (TreeGraphNode child in node.Childs) { + CalculateNodePosRecursive(child, childLateral, childsMainFixed); childLateral += child.SubtreeSize; } } diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/NodeControlCache.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/NodeControlCache.cs index 7fc4bb34ec..15a30d025c 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/NodeControlCache.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/NodeControlCache.cs @@ -25,7 +25,8 @@ namespace Debugger.AddIn.Visualizers.Graph public void ReturnForReuse(PositionedGraphNodeControl controlToReuse) { - controls.Push(controlToReuse); + // not used now, avoid leaking! + //controls.Push(controlToReuse); } public PositionedGraphNodeControl GetNodeControl()