Skip to content
This repository has been archived by the owner on Oct 16, 2020. It is now read-only.

Commit

Permalink
Object graph - simplified layout code.
Browse files Browse the repository at this point in the history
  • Loading branch information
mkonicek committed Mar 12, 2011
1 parent 4897789 commit 550e862
Show file tree
Hide file tree
Showing 18 changed files with 344 additions and 492 deletions.
8 changes: 2 additions & 6 deletions src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -315,15 +315,11 @@
<Compile Include="Visualizers\Graph\Layout\GraphMatcher.cs" />
<Compile Include="Visualizers\Graph\Layout\PositionedEdge.cs" />
<Compile Include="Visualizers\Graph\Layout\PositionedGraph.cs" />
<Compile Include="Visualizers\Graph\Layout\PositionedGraphNode.cs" />
<Compile Include="Visualizers\Graph\Layout\PositionedNode.cs" />
<Compile Include="Visualizers\Graph\Layout\PositionedNodeProperty.cs" />
<Compile Include="Visualizers\Graph\Layout\PositionedPropertyEventArgs.cs" />
<Compile Include="Visualizers\Graph\Layout\Tree\LayoutDirection.cs" />
<Compile Include="Visualizers\Graph\Layout\Tree\TreeEdge.cs" />
<Compile Include="Visualizers\Graph\Layout\Tree\TreeLayouter.cs" />
<Compile Include="Visualizers\Graph\Layout\Tree\TreeGraphNode.cs" />
<Compile Include="Visualizers\Graph\Layout\Tree\TreeGraphNodeLR.cs" />
<Compile Include="Visualizers\Graph\Layout\Tree\TreeGraphNodeTB.cs" />
<Compile Include="Visualizers\Graph\Layout\Tree\TreeLayout.cs" />
<Compile Include="Visualizers\Graph\ObjectGraph\ObjectGraph.cs" />
<Compile Include="Visualizers\Graph\ObjectGraph\ObjectGraphBuilder.cs" />
<Compile Include="Visualizers\Graph\ObjectGraph\ObjectGraphNode.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
namespace Debugger.AddIn.Visualizers.Graph
{
/// <summary>
/// Draws <see cref="PositionedGraph"></see> on Canvas.
/// Draws <see cref="PositionedGraph" /> on Canvas.
/// Keeps the last displayed graph and does a smooth transition into the new graph.
/// </summary>
public class GraphDrawer
{
Expand All @@ -41,11 +42,10 @@ public void StartAnimation(PositionedGraph oldGraph, PositionedGraph newGraph, G
{
// 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)
{
if (oldGraph == null) {
Draw(newGraph);
return;
}
Expand All @@ -57,38 +57,31 @@ public void StartAnimation(PositionedGraph oldGraph, PositionedGraph newGraph, G
DoubleAnimation fadeOutAnim = new DoubleAnimation(1.0, 0.0, durationFade);
DoubleAnimation fadeInAnim = new DoubleAnimation(0.0, 1.0, durationFade);

foreach (UIElement drawing in canvas.Children)
{
foreach (UIElement drawing in canvas.Children) {
var arrow = drawing as Path;
if (arrow != null)
{
if (arrow != null) {
arrow.BeginAnimation(UIElement.OpacityProperty, fadeOutAnim);
}
}

foreach (PositionedEdge edge in newGraph.Edges)
{
addEdgeToCanvas(edge).BeginAnimation(UIElement.OpacityProperty, fadeInAnim);
foreach (PositionedEdge edge in newGraph.Edges) {
AddEdgeToCanvas(edge).BeginAnimation(UIElement.OpacityProperty, fadeInAnim);
}

foreach (PositionedGraphNode removedNode in diff.RemovedNodes)
{
foreach (PositionedNode removedNode in diff.RemovedNodes) {
removedNode.NodeVisualControl.BeginAnimation(UIElement.OpacityProperty, fadeOutAnim);
}

foreach (PositionedGraphNode addedNode in diff.AddedNodes)
{
addNodeToCanvas(addedNode).BeginAnimation(UIElement.OpacityProperty, fadeInAnim);
foreach (PositionedNode addedNode in diff.AddedNodes) {
AddNodeToCanvas(addedNode).BeginAnimation(UIElement.OpacityProperty, fadeInAnim);
}

bool first = true;
foreach (PositionedGraphNode node in diff.ChangedNodes)
{
foreach (PositionedNode node in diff.ChangedNodes) {
var newNode = diff.GetMatchingNewNode(node);

PointAnimation anim = new PointAnimation();
if (first)
{
if (first) {
anim.Completed += new EventHandler((o, e) => { Draw(newGraph); });
first = false;
}
Expand All @@ -111,29 +104,14 @@ public void Draw(PositionedGraph posGraph)
{
canvas.Children.Clear();

/*try
{
// why do the controls disappear?
var n1 = posGraph.Nodes.First().NodeVisualControl;
var n2 = posGraph.Nodes.Skip(1).First().NodeVisualControl;
var n3 = posGraph.Nodes.Skip(2).First().NodeVisualControl;
if (n1 == n2 || n1 == n3 || n2 == n3)
{
ClearCanvas();
}
}
catch{}*/

// draw nodes
foreach (PositionedGraphNode node in posGraph.Nodes)
{
addNodeToCanvas(node);
foreach (PositionedNode node in posGraph.Nodes) {
AddNodeToCanvas(node);
}

// draw edges
foreach (PositionedEdge edge in posGraph.Edges)
{
addEdgeToCanvas(edge);
foreach (PositionedEdge edge in posGraph.Edges) {
AddEdgeToCanvas(edge);
}

edgeTooltip.Visibility = Visibility.Hidden;
Expand All @@ -149,21 +127,21 @@ public void ClearCanvas()
canvas.Children.Clear();
}

private PositionedGraphNodeControl addNodeToCanvas(PositionedGraphNode node)
PositionedGraphNodeControl AddNodeToCanvas(PositionedNode node)
{
canvas.Children.Add(node.NodeVisualControl);
Canvas.SetLeft(node.NodeVisualControl, node.Left);
Canvas.SetTop(node.NodeVisualControl, node.Top);
return node.NodeVisualControl;
}

private Path addEdgeToCanvas(PositionedEdge edge)
Path AddEdgeToCanvas(PositionedEdge edge)
{
PathFigure edgeSplineFigure = createEdgeSpline(edge);
PathFigure edgeSplineFigure = CreateEdgeSpline(edge);

PathGeometry geometryVisible = new PathGeometry();
geometryVisible.Figures.Add(edgeSplineFigure);
geometryVisible.Figures.Add(createEdgeArrow(edge));
geometryVisible.Figures.Add(CreateEdgeArrow(edge));

Path pathVisible = new Path();
pathVisible.Stroke = Brushes.Black;
Expand Down Expand Up @@ -210,7 +188,7 @@ private Path addEdgeToCanvas(PositionedEdge edge)
return pathVisible;
}

private PathFigure createEdgeSpline(PositionedEdge edge)
PathFigure CreateEdgeSpline(PositionedEdge edge)
{
PathFigure figure = new PathFigure();
figure.IsClosed = false;
Expand All @@ -225,7 +203,7 @@ private PathFigure createEdgeSpline(PositionedEdge edge)
return figure;
}

private PathFigure createEdgeArrow(PositionedEdge edge)
PathFigure CreateEdgeArrow(PositionedEdge edge)
{
Point splineEndPoint = edge.SplinePoints[edge.SplinePoints.Count - 1];
Point splineEndHandlePoint = edge.SplinePoints[edge.SplinePoints.Count - 2];
Expand All @@ -240,14 +218,14 @@ private PathFigure createEdgeArrow(PositionedEdge edge)
arrowFigure.IsFilled = true;

arrowFigure.StartPoint = splineEndPoint; // arrow tip
Vector tangent2 = rotate90(tangent);
Vector tangent2 = Rotate90(tangent);
arrowFigure.Segments.Add(new LineSegment(basePoint + tangent2 * 0.15, true));
arrowFigure.Segments.Add(new LineSegment(basePoint - tangent2 * 0.15, true));

return arrowFigure;
}

private static Vector rotate90(Vector v)
static Vector Rotate90(Vector v)
{
// (x, y) -> (y, -x)
double t = v.X;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
/// </summary>
public class ContentNode : Utils.ITreeNode<ContentNode>
{
public ContentNode(PositionedGraphNode containingNode, ContentNode parent)
public ContentNode(PositionedNode containingNode, ContentNode parent)
{
if (containingNode == null)
throw new ArgumentNullException("containingNode");
Expand Down Expand Up @@ -74,11 +74,11 @@ public string Path
private List<ContentNode> children = new List<ContentNode>();
public List<ContentNode> Children { get { return this.children; } }

PositionedGraphNode containingNode;
PositionedNode containingNode;
/// <summary>
/// PositionedGraphNode that contains this PropertyNodeViewModel.
/// </summary>
public PositionedGraphNode ContainingNode
public PositionedNode ContainingNode
{
get { return this.containingNode; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class ContentPropertyNode : ContentNode, IEvaluate
{
PositionedNodeProperty positionedProperty;

public ContentPropertyNode(PositionedGraphNode containingNode, ContentNode parent)
public ContentPropertyNode(PositionedNode containingNode, ContentNode parent)
: base(containingNode, parent)
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
/// </summary>
public class GraphDiff
{
private List<PositionedGraphNode> addedNodes = new List<PositionedGraphNode>();
private List<PositionedGraphNode> deletedNodes = new List<PositionedGraphNode>();
private List<PositionedGraphNode> changedNodes = new List<PositionedGraphNode>();
private Dictionary<PositionedGraphNode, PositionedGraphNode> matching = new Dictionary<PositionedGraphNode, PositionedGraphNode>();
private List<PositionedNode> addedNodes = new List<PositionedNode>();
private List<PositionedNode> deletedNodes = new List<PositionedNode>();
private List<PositionedNode> changedNodes = new List<PositionedNode>();
private Dictionary<PositionedNode, PositionedNode> matching = new Dictionary<PositionedNode, PositionedNode>();

/// <summary>
/// Nodes in the new graph that were added.
/// </summary>
public IList<PositionedGraphNode> AddedNodes
public IList<PositionedNode> AddedNodes
{
get { return addedNodes.AsReadOnly(); }
}

/// <summary>
/// Nodes in the old graph that were removed.
/// </summary>
public IList<PositionedGraphNode> RemovedNodes
public IList<PositionedNode> RemovedNodes
{
get { return deletedNodes.AsReadOnly(); }
}
Expand All @@ -38,27 +38,27 @@ public IList<PositionedGraphNode> RemovedNodes
/// Nodes in the old graph that were chaged.
/// These have matching new nodes, which can be obtained by <see cref="GetMatchingNewNode"/>.
/// </summary>
public IList<PositionedGraphNode> ChangedNodes
public IList<PositionedNode> ChangedNodes
{
get { return changedNodes.AsReadOnly(); }
}

public PositionedGraphNode GetMatchingNewNode(PositionedGraphNode oldNode)
public PositionedNode GetMatchingNewNode(PositionedNode oldNode)
{
return matching.GetValue(oldNode);
}

internal void SetAdded(PositionedGraphNode addedNode)
internal void SetAdded(PositionedNode addedNode)
{
addedNodes.Add(addedNode);
}

internal void SetRemoved(PositionedGraphNode removeddNode)
internal void SetRemoved(PositionedNode removeddNode)
{
deletedNodes.Add(removeddNode);
}

internal void SetMatching(PositionedGraphNode matchFrom, PositionedGraphNode matchTo)
internal void SetMatching(PositionedNode matchFrom, PositionedNode matchTo)
{
matching[matchFrom] = matchTo;
changedNodes.Add(matchFrom);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,28 @@ public GraphDiff MatchGraphs(PositionedGraph oldGraph, PositionedGraph newGraph)
else
{
GraphDiff addAllDiff = new GraphDiff();
foreach (PositionedGraphNode newNode in newGraph.Nodes)
foreach (PositionedNode newNode in newGraph.Nodes)
addAllDiff.SetAdded(newNode);
return addAllDiff;
}
}
else if (newGraph == null)
{
GraphDiff removeAllDiff = new GraphDiff();
foreach (PositionedGraphNode oldNode in oldGraph.Nodes)
foreach (PositionedNode oldNode in oldGraph.Nodes)
removeAllDiff.SetRemoved(oldNode);
return removeAllDiff;
}

// none of the graphs is null
GraphDiff diff = new GraphDiff();

Dictionary<int, PositionedGraphNode> newNodeForHashCode = buildHashToNodeMap(newGraph);
Dictionary<PositionedGraphNode, bool> newNodeMatched = new Dictionary<PositionedGraphNode, bool>();
Dictionary<int, PositionedNode> newNodeForHashCode = buildHashToNodeMap(newGraph);
Dictionary<PositionedNode, bool> newNodeMatched = new Dictionary<PositionedNode, bool>();

foreach (PositionedGraphNode oldNode in oldGraph.Nodes)
foreach (PositionedNode oldNode in oldGraph.Nodes)
{
PositionedGraphNode matchingNode = matchNode(oldNode, newNodeForHashCode);
PositionedNode matchingNode = matchNode(oldNode, newNodeForHashCode);
if (matchingNode != null)
{
diff.SetMatching(oldNode, matchingNode);
Expand All @@ -59,7 +59,7 @@ public GraphDiff MatchGraphs(PositionedGraph oldGraph, PositionedGraph newGraph)
diff.SetRemoved(oldNode);
}
}
foreach (PositionedGraphNode newNode in newGraph.Nodes)
foreach (PositionedNode newNode in newGraph.Nodes)
{
if (!newNodeMatched.ContainsKey(newNode))
{
Expand All @@ -70,19 +70,19 @@ public GraphDiff MatchGraphs(PositionedGraph oldGraph, PositionedGraph newGraph)
return diff;
}

private Dictionary<int, PositionedGraphNode> buildHashToNodeMap(PositionedGraph graph)
private Dictionary<int, PositionedNode> buildHashToNodeMap(PositionedGraph graph)
{
var hashToNodeMap = new Dictionary<int, PositionedGraphNode>();
foreach (PositionedGraphNode node in graph.Nodes)
var hashToNodeMap = new Dictionary<int, PositionedNode>();
foreach (PositionedNode node in graph.Nodes)
{
hashToNodeMap[node.ObjectNode.HashCode] = node;
}
return hashToNodeMap;
}

private PositionedGraphNode matchNode(PositionedGraphNode oldNode, Dictionary<int, PositionedGraphNode> newNodeMap)
private PositionedNode matchNode(PositionedNode oldNode, Dictionary<int, PositionedNode> newNodeMap)
{
PositionedGraphNode newNodeFound = newNodeMap.GetValue(oldNode.ObjectNode.HashCode);
PositionedNode newNodeFound = newNodeMap.GetValue(oldNode.ObjectNode.HashCode);
if ((newNodeFound != null) && isSameAddress(oldNode, newNodeFound))
{
return newNodeFound;
Expand All @@ -93,7 +93,7 @@ private PositionedGraphNode matchNode(PositionedGraphNode oldNode, Dictionary<in
}
}

private bool isSameAddress(PositionedGraphNode node1, PositionedGraphNode node2)
private bool isSameAddress(PositionedNode node1, PositionedNode node2)
{
return node1.ObjectNode.PermanentReference.GetObjectAddress() == node2.ObjectNode.PermanentReference.GetObjectAddress();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
/// <summary>
/// Edge with position information.
/// </summary>
public class PositionedEdge : NamedEdge<PositionedNodeProperty, PositionedGraphNode>, SplineRouting.IEdge
public class PositionedEdge : NamedEdge<PositionedNodeProperty, PositionedNode>, SplineRouting.IEdge
{
private IList<Point> splinePoints = new List<Point>();
/// <summary>
Expand Down
Loading

0 comments on commit 550e862

Please sign in to comment.