/// <summary> /// Draws <see cref="PositionedGraph"></see> on Canvas. /// </summary> /// <param name="posGraph">Graph to draw.</param> /// <param name="canvas">Destination Canvas.</param> 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); } // draw edges foreach (PositionedEdge edge in posGraph.Edges) { addEdgeToCanvas(edge); } edgeTooltip.Visibility = Visibility.Hidden; edgeTooltip.Background = Brushes.White; canvas.Children.Add(edgeTooltip); }
void RegisterExpandCollapseEvents(PositionedGraph posGraph) { foreach (var node in posGraph.Nodes) { node.PropertyExpanded += new EventHandler <PositionedPropertyEventArgs>(node_PropertyExpanded); node.PropertyCollapsed += new EventHandler <PositionedPropertyEventArgs>(node_PropertyCollapsed); node.ContentNodeExpanded += new EventHandler <ContentNodeEventArgs>(node_ContentNodeExpanded); node.ContentNodeCollapsed += new EventHandler <ContentNodeEventArgs>(node_ContentNodeCollapsed); } }
void LayoutGraph(ObjectGraph graph) { this.oldPosGraph = this.currentPosGraph; Log.Debug("Debugger visualizer: Calculating graph layout"); var layoutDirection = layoutViewModel.SelectedEnumValue; this.currentPosGraph = new TreeLayout(layoutDirection).CalculateLayout(graph, expanded); Log.Debug("Debugger visualizer: Graph layout done"); RegisterExpandCollapseEvents(this.currentPosGraph); var graphDiff = new GraphMatcher().MatchGraphs(oldPosGraph, currentPosGraph); Log.Debug("Debugger visualizer: starting graph animation"); this.graphDrawer.StartAnimation(oldPosGraph, currentPosGraph, graphDiff); }
/// <summary> /// Draws <see cref="PositionedGraph"></see> on Canvas. /// </summary> /// <param name="posGraph">Graph to draw.</param> /// <param name="canvas">Destination Canvas.</param> public void Draw(PositionedGraph posGraph) { canvas.Children.Clear(); // draw nodes foreach (PositionedNode node in posGraph.Nodes) { AddNodeToCanvas(node); } // draw edges foreach (PositionedEdge edge in posGraph.Edges) { AddEdgeToCanvas(edge); } edgeTooltip.Visibility = Visibility.Hidden; edgeTooltip.Background = Brushes.White; canvas.Children.Add(edgeTooltip); }
void layoutGraph(ObjectGraph graph) { if (this.oldPosGraph != null) { foreach (var oldNode in this.oldPosGraph.Nodes) { // controls from old graph would be garbage collected, reuse them NodeControlCache.Instance.ReturnForReuse(oldNode.NodeVisualControl); } } this.oldPosGraph = this.currentPosGraph; ICSharpCode.Core.LoggingService.Debug("Debugger visualizer: Calculating graph layout"); this.currentPosGraph = this.layouter.CalculateLayout(graph, layoutViewModel.SelectedEnumValue, this.expanded); ICSharpCode.Core.LoggingService.Debug("Debugger visualizer: Graph layout done"); registerExpandCollapseEvents(this.currentPosGraph); var graphDiff = new GraphMatcher().MatchGraphs(oldPosGraph, currentPosGraph); ICSharpCode.Core.LoggingService.Debug("Debugger visualizer: starting graph animation"); this.graphDrawer.StartAnimation(oldPosGraph, currentPosGraph, graphDiff); //this.graphDrawer.Draw(this.currentPosGraph); // buggy layout with NodeControlCache }
void LayoutGraph(ObjectGraph graph) { if (this.oldPosGraph != null) { foreach (var oldNode in this.oldPosGraph.Nodes) { // controls from old graph would be garbage collected, reuse them NodeControlCache.Instance.ReturnForReuse(oldNode.NodeVisualControl); } } this.oldPosGraph = this.currentPosGraph; Log.Debug("Debugger visualizer: Calculating graph layout"); var layoutDirection = layoutViewModel.SelectedEnumValue; this.currentPosGraph = new TreeLayout(layoutDirection).CalculateLayout(graph, expanded); Log.Debug("Debugger visualizer: Graph layout done"); RegisterExpandCollapseEvents(this.currentPosGraph); var graphDiff = new GraphMatcher().MatchGraphs(oldPosGraph, currentPosGraph); Log.Debug("Debugger visualizer: starting graph animation"); this.graphDrawer.StartAnimation(oldPosGraph, currentPosGraph, graphDiff); }
/// <summary> /// Starts animation from oldGraph to newGraph. /// </summary> /// <param name="oldGraph"></param> /// <param name="newGraph"></param> /// <param name="diff"></param> public void StartAnimation(PositionedGraph oldGraph, PositionedGraph newGraph, GraphDiff diff) { // 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; if (oldGraph == null) { Draw(newGraph); return; } var durationMove = new Duration(TimeSpan.FromSeconds(animationDurationSeconds)); var durationFade = durationMove; DoubleAnimation fadeOutAnim = new DoubleAnimation(1.0, 0.0, durationFade); DoubleAnimation fadeInAnim = new DoubleAnimation(0.0, 1.0, durationFade); foreach (UIElement drawing in canvas.Children) { var arrow = drawing as Path; if (arrow != null) { arrow.BeginAnimation(UIElement.OpacityProperty, fadeOutAnim); } } foreach (PositionedEdge edge in newGraph.Edges) { AddEdgeToCanvas(edge).BeginAnimation(UIElement.OpacityProperty, fadeInAnim); } foreach (PositionedNode removedNode in diff.RemovedNodes) { removedNode.NodeVisualControl.BeginAnimation(UIElement.OpacityProperty, fadeOutAnim); } foreach (PositionedNode addedNode in diff.AddedNodes) { AddNodeToCanvas(addedNode).BeginAnimation(UIElement.OpacityProperty, fadeInAnim); } bool first = true; foreach (PositionedNode node in diff.ChangedNodes) { var newNode = diff.GetMatchingNewNode(node); PointAnimation anim = new PointAnimation(); if (first) { anim.Completed += (o, e) => { Draw(newGraph); if (oldGraph != null) { foreach (var oldNode in oldGraph.Nodes) { oldNode.ReleaseNodeVisualControl(); } } }; first = false; } anim.From = node.LeftTop; anim.To = newNode.LeftTop; anim.DecelerationRatio = 0.3; anim.AccelerationRatio = 0.3; anim.Duration = durationMove; node.NodeVisualControl.BeginAnimation(CanvasLocationAdapter.LocationProperty, anim); } }
/// <summary> /// Starts animation from oldGraph to newGraph. /// </summary> /// <param name="oldGraph"></param> /// <param name="newGraph"></param> /// <param name="diff"></param> 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(); } } } } this.canvas.Width = newGraph.BoundingRect.Width; this.canvas.Height = newGraph.BoundingRect.Height; if (oldGraph == null) { Draw(newGraph); return; } double seconds = 0.5; var durationMove = new Duration(TimeSpan.FromSeconds(seconds)); var durationFade = durationMove; DoubleAnimation fadeOutAnim = new DoubleAnimation(1.0, 0.0, durationFade); DoubleAnimation fadeInAnim = new DoubleAnimation(0.0, 1.0, durationFade); foreach (UIElement drawing in canvas.Children) { var arrow = drawing as Path; if (arrow != null) { arrow.BeginAnimation(UIElement.OpacityProperty, fadeOutAnim); } } foreach (PositionedEdge edge in newGraph.Edges) { addEdgeToCanvas(edge).BeginAnimation(UIElement.OpacityProperty, fadeInAnim); } foreach (PositionedGraphNode removedNode in diff.RemovedNodes) { removedNode.NodeVisualControl.BeginAnimation(UIElement.OpacityProperty, fadeOutAnim); } foreach (PositionedGraphNode addedNode in diff.AddedNodes) { addNodeToCanvas(addedNode).BeginAnimation(UIElement.OpacityProperty, fadeInAnim); } bool first = true; foreach (PositionedGraphNode node in diff.ChangedNodes) { var newNode = diff.GetMatchingNewNode(node); PointAnimation anim = new PointAnimation(); if (first) { anim.Completed += new EventHandler((o, e) => { Draw(newGraph); }); first = false; } anim.From = node.LeftTop; anim.To = newNode.LeftTop; anim.DecelerationRatio = 0.3; anim.AccelerationRatio = 0.3; anim.Duration = durationMove; node.NodeVisualControl.BeginAnimation(CanvasLocationAdapter.LocationProperty, anim); } }