Example #1
0
		/// <summary>Default ctor</summary>
		public Graph()
		{
			_NodeRegistry = 0;
			_Nodes = new List<Node>();
			_Edges = new List<Edge>();
			DragNode = null;
		}
Example #2
0
		/// <summary>Creates a new node and adds it to the graph </summary>
		/// <param name="label">Label of the new node</param>
		/// <param name="magnet">Movement speed</param>
		/// <returns>the newly created node</returns>
		public Node AddNode(string label, double magnet = 60.0)
		{
			Node result = FindNode(label);
			if (result != null)	// already existing
				return result;

			result = new Node(++_NodeRegistry, label, magnet);
			_Nodes.Add(result);
			return result;
		}
Example #3
0
		/// <summary>Initialization ctor</summary>
		/// <param name="from">Node where this edge begins</param>
		/// <param name="to">Node where this edge ends</param>
		/// <param name="len">Virtual length of this edge</param>
		public Edge(Node from, Node to, double len = 40.0)
		{
			From   = from;
			To     = to;
			Length = len;
		}
Example #4
0
		/// <summary>Creates a new egde and adds it to the graph</summary>
		/// <param name="from">Starting node</param>
		/// <param name="to">Ending node</param>
		/// <returns>the newly created edge</returns>
		public Edge AddEdge(Node from, Node to)
		{
			Edge result = new Edge(from, to);
			_Edges.Add(result);
			return result;
		}
Example #5
0
		private void ForAllNodePairs(Node n1, Node n2)
		{
			double dx = 0;
			double dy = 0;
			double vx = n1.x - n2.x;
			double vy = n1.y - n2.y;
			double len = vx * vx + vy * vy; //so it's length squared

			if (len == 0)
			{
				Random rand = new Random();
				dx = rand.NextDouble(); //If two nodes are right on top of each other, randomly separate
				dy = rand.NextDouble();
			}
			else if (len < 600 * 600)
			{					// 600, because we don't want deleted nodes to fly too far away
				dx = vx / len;  // If it was sqrt(len) then a single node surrounded by many others will
				dy = vy / len;  // always look like a circle.  This might look good at first, but I think
				// it makes large graphs look ugly + it contributes to oscillation.  A
				// linear function does not fall off fast enough, so you get rough edges
				// in the 'force field'
			}

			double repSum = n1.repulsion * n2.repulsion / 100;

			n1.dx += dx * repSum * rigidity;
			n1.dy += dy * repSum * rigidity;

			n2.dx -= dx * repSum * rigidity;
			n2.dy -= dy * repSum * rigidity; 
		}
Example #6
0
		private void ForAllNodes(Node node)
		{
			double dx = node.dx;
			double dy = node.dy;
			dx *= damper;  //The damper slows things down.  It cuts down jiggling at the last moment, and optimizes
			dy *= damper;  //layout.  As an experiment, get rid of the damper in these lines, and make a
			//long straight line of nodes.  It wiggles too much and doesn't straighten out.

			node.dx = dx / 2;   //Slow down, but don't stop.  Nodes in motion store momentum.  This helps when the force
			node.dy = dy / 2;   //on a node is very low, but you still want to get optimal layout.

			double distMoved = Math.Sqrt(dx * dx + dy * dy); //how far did the node actually move?

			if (!node.IsFixed)
			{
				node.x += Math.Max(-30, Math.Min(30, dx));	//don't move faster then 30 units at a time.
				node.y += Math.Max(-30, Math.Min(30, dy));	//I forget when this is important.  Stopping severed nodes from
				//flying away?
			}
			maxMotionA = Math.Max(distMoved, maxMotionA);
		}