Пример #1
0
		public void RouteEdges(PositionedGraph posGraph)
		{
			Dictionary<PositionedEdge, RoutedEdge> routedEdges = router.RouteEdges(posGraph.Nodes, posGraph.Edges);
			foreach (var edgePair in routedEdges) {
				SetEdgeSplinePoints(edgePair.Key, edgePair.Value);
			}
		}
Пример #2
0
        // Expanded is passed so that the correct ContentNodes are expanded in the PositionedNode
        PositionedGraph BuildPositionedGraph(ObjectGraph objectGraph, Expanded expanded)
        {
            var positionedNodeFor = new Dictionary <ObjectGraphNode, PositionedNode>();
            var positionedGraph   = new PositionedGraph();

            // create empty PositionedNodes
            foreach (ObjectGraphNode objectNode in objectGraph.ReachableNodes)
            {
                var posNode = new PositionedNode(objectNode, expanded);
                posNode.MeasureVisualControl();
                positionedGraph.AddNode(posNode);
                positionedNodeFor[objectNode] = posNode;
            }

            // create edges
            foreach (PositionedNode posNode in positionedGraph.Nodes)
            {
                foreach (PositionedNodeProperty property in posNode.Properties)
                {
                    if (property.ObjectGraphProperty.TargetNode != null)
                    {
                        ObjectGraphNode targetObjectNode = property.ObjectGraphProperty.TargetNode;
                        PositionedNode  edgeTarget       = positionedNodeFor[targetObjectNode];
                        property.Edge = new PositionedEdge {
                            Name = property.Name, Source = property, Target = edgeTarget
                        };
                    }
                }
            }
            positionedGraph.Root = positionedNodeFor[objectGraph.Root];
            return(positionedGraph);
        }
Пример #3
0
		// Expanded is passed so that the correct ContentNodes are expanded in the PositionedNode
		PositionedGraph BuildPositionedGraph(ObjectGraph objectGraph, Expanded expanded)
		{
			var positionedNodeFor = new Dictionary<ObjectGraphNode, PositionedNode>();
			var positionedGraph = new PositionedGraph();
			
			// create empty PositionedNodes
			foreach (ObjectGraphNode objectNode in objectGraph.ReachableNodes) {
				var posNode = new PositionedNode(objectNode, expanded);
				posNode.MeasureVisualControl();
				positionedGraph.AddNode(posNode);
				positionedNodeFor[objectNode] = posNode;
			}
			
			// create edges
			foreach (PositionedNode posNode in positionedGraph.Nodes)
			{
				foreach (PositionedNodeProperty property in posNode.Properties)	{
					if (property.ObjectGraphProperty.TargetNode != null) {
						ObjectGraphNode targetObjectNode = property.ObjectGraphProperty.TargetNode;
						PositionedNode edgeTarget = positionedNodeFor[targetObjectNode];
						property.Edge = new PositionedEdge {
							Name = property.Name, Source = property, Target = edgeTarget
						};
					}
				}
			}
			positionedGraph.Root = positionedNodeFor[objectGraph.Root];
			return positionedGraph;
		}
Пример #4
0
		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;
		}
Пример #5
0
		Dictionary<int, PositionedNode> BuildHashToNodeMap(PositionedGraph graph)
		{
			var hashToNodeMap = new Dictionary<int, PositionedNode>();
			foreach (PositionedNode node in graph.Nodes) {
				hashToNodeMap[node.ObjectNode.HashCode] = node;
			}
			return hashToNodeMap;
		}
Пример #6
0
        /// <summary>
        /// Calculates diff between 2 <see cref="PositionedGraph"/>s.
        /// The <see cref="GraphDiff"/> describes a matching between nodes in the graphs, added and removed nodes.
        /// </summary>
        public GraphDiff MatchGraphs(PositionedGraph oldGraph, PositionedGraph newGraph)
        {
            if (oldGraph == null)
            {
                if (newGraph == null)
                {
                    return(new GraphDiff());
                }
                else
                {
                    GraphDiff addAllDiff = new GraphDiff();
                    foreach (PositionedNode newNode in newGraph.Nodes)
                    {
                        addAllDiff.SetAdded(newNode);
                    }
                    return(addAllDiff);
                }
            }
            else if (newGraph == null)
            {
                GraphDiff removeAllDiff = new GraphDiff();
                foreach (PositionedNode oldNode in oldGraph.Nodes)
                {
                    removeAllDiff.SetRemoved(oldNode);
                }
                return(removeAllDiff);
            }
            // none of the graphs is null

            GraphDiff diff = new GraphDiff();

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

            foreach (PositionedNode oldNode in oldGraph.Nodes)
            {
                PositionedNode matchingNode = MatchNode(oldNode, newNodeForHashCode);

                if (matchingNode != null)
                {
                    diff.SetMatching(oldNode, matchingNode);
                    newNodeMatched[matchingNode] = true;
                }
                else
                {
                    diff.SetRemoved(oldNode);
                }
            }
            foreach (PositionedNode newNode in newGraph.Nodes)
            {
                if (!newNodeMatched.ContainsKey(newNode))
                {
                    diff.SetAdded(newNode);
                }
            }
            return(diff);
        }
Пример #7
0
        public void RouteEdges(PositionedGraph posGraph)
        {
            Dictionary <PositionedEdge, RoutedEdge> routedEdges = router.RouteEdges(posGraph.Nodes, posGraph.Edges);

            foreach (var edgePair in routedEdges)
            {
                SetEdgeSplinePoints(edgePair.Key, edgePair.Value);
            }
        }
Пример #8
0
        void CalculateLayout(PositionedGraph positionedGraph)
        {
            // impose a tree structure on the graph
            HashSet <PositionedEdge> treeEdges = DetermineTreeEdges(positionedGraph.Root);

            // first layout pass
            CalculateSubtreeSizesRecursive(positionedGraph.Root, treeEdges);
            // second layout pass
            CalculateNodePosRecursive(positionedGraph.Root, treeEdges, MarginTop, MarginBottom);
        }
Пример #9
0
        Dictionary <int, PositionedNode> BuildHashToNodeMap(PositionedGraph graph)
        {
            var hashToNodeMap = new Dictionary <int, PositionedNode>();

            foreach (PositionedNode node in graph.Nodes)
            {
                hashToNodeMap[node.ObjectNode.HashCode] = node;
            }
            return(hashToNodeMap);
        }
Пример #10
0
		public PositionedGraph RouteEdges(PositionedGraph posGraph)
		{
			List<RoutedEdge> routedEdges = router.RouteEdges(posGraph.Nodes, posGraph.Edges);
			int i = 0;
			// assume routedEdges come in the same order as posGraph.Edges
			foreach (var edge in posGraph.Edges) {
				SetEdgeSplinePoints(edge, routedEdges[i]);
				i++;
			}
			return posGraph;
		}
Пример #11
0
		public GraphDiff MatchGraphs(PositionedGraph oldGraph, PositionedGraph newGraph)
		{
			if (oldGraph == null)
			{
				if (newGraph == null)
				{
					return new GraphDiff();
				}
				else
				{
					GraphDiff addAllDiff = new GraphDiff();
					foreach	(PositionedGraphNode newNode in newGraph.Nodes)
						addAllDiff.SetAdded(newNode);
					return addAllDiff;
				}
			}
			else if (newGraph == null)
			{
				GraphDiff removeAllDiff = new GraphDiff();
				foreach	(PositionedGraphNode 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>();
			
			foreach	(PositionedGraphNode oldNode in oldGraph.Nodes)
			{
				PositionedGraphNode matchingNode = matchNode(oldNode, newNodeForHashCode);
				if (matchingNode != null)
				{
					diff.SetMatching(oldNode, matchingNode);
					newNodeMatched[matchingNode] = true;
				}
				else
				{
					diff.SetRemoved(oldNode);
				}
			}
			foreach	(PositionedGraphNode newNode in newGraph.Nodes)
			{
				if (!newNodeMatched.ContainsKey(newNode))
				{
					diff.SetAdded(newNode);
				}
			}
			
			return diff;
		}
Пример #12
0
        public PositionedGraph RouteEdges(PositionedGraph posGraph)
        {
            List <RoutedEdge> routedEdges = router.RouteEdges(posGraph.Nodes, posGraph.Edges);
            int i = 0;

            // assume routedEdges come in the same order as posGraph.Edges
            foreach (var edge in posGraph.Edges)
            {
                SetEdgeSplinePoints(edge, routedEdges[i]);
                i++;
            }
            return(posGraph);
        }
Пример #13
0
        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);
        }
		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);
		}
Пример #15
0
		/// <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);
			}
		}
Пример #16
0
		/// <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);
		}
Пример #17
0
		void CalculateLayout(PositionedGraph positionedGraph)
		{
			// impose a tree structure on the graph
			HashSet<PositionedEdge> treeEdges = DetermineTreeEdges(positionedGraph.Root);
			// first layout pass
			CalculateSubtreeSizesRecursive(positionedGraph.Root, treeEdges);
			// second layout pass
			CalculateNodePosRecursive(positionedGraph.Root, treeEdges, MarginTop, MarginBottom);
		}
		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);
		}
Пример #19
0
		/// <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);
			}
		}
Пример #20
0
		/// <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 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 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);
			}
		}