private void LayoutNode(GraphNode node) { if (node.moveable) { double dx = node.dx; double dy = node.dy; // The damper slows things down. It cuts down jiggling at the last moment, and optimizes // 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. dx *= _damper; dy *= _damper; // Slow down, but dont stop. Nodes in motion store momentum. This helps when the force // on a node is very low, but you still want to get optimal layout. node.dx = dx / 2; node.dy = dy / 2; // How far did the node actually move? double distanceMoved = Math.Sqrt(dx * dx + dy * dy); // Don't move faster then 30 units at a time. // Stops severed nodes from flying away? node.x = node.x + Math.Max(-30, Math.Min(30, dx)); node.y = node.y + Math.Max(-30, Math.Min(30, dy)); _intermediateMaxMotion = Math.Max(distanceMoved, _intermediateMaxMotion); } }
public void AddNode(GraphNode node) { _nodes.Add(node); if (_updating == false) { RaiseChangedEvent(); } else { _updated = true; } }
private void RemoveOverlap(GraphNode node1, GraphNode node2) { double dx = 0; double dy = 0; double vx = node1.x - node2.x; double vy = node1.y - node2.y; double distance = vx * vx + vy * vy; // TODO: 36 should be a property instead of hardcoded // This is the radius of a node. if (distance < 36 * 36 * 2) { // If two nodes are right on top of each other, separate them // apart randomly dx = Math.Random(); dy = Math.Random(); } else if (distance < 360000) { // 600 * 600, because we don't want deleted nodes to fly too far away // If it was sqrt(len) then a single node surrounded by many others will // 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' dx = vx / distance; dy = vy / distance; } double totalRepulsion = DefaultRepulsion * DefaultRepulsion / 100; double factor = totalRepulsion * _rigidity; node1.dx += dx * factor; node1.dy += dy * factor; node2.dx -= dx * factor; node2.dy -= dy * factor; }
public GraphEdge(GraphNode fromNode, GraphNode toNode, int length) { _fromNode = fromNode; _toNode = toNode; _length = length; }
public void RemoveNode(GraphNode node) { foreach (GraphEdge edge in node.Edges) { RemoveEdge(edge); } _nodes.Remove(node); if (_updating == false) { RaiseChangedEvent(); } else { _updated = true; } }