I'm trying to position entities visualy to show their relationships to each other. It looks like for automatic graph layout, the spring algorithm would suit my needs. I'd like to implement this in silverlight using c#, so I'm looking for code samples, or links to good explanations of the theory. Any help appreciated
+1
A:
I have not used any of these examples but I believe they will be of use to you.
- Silverlight diagramming with spring embedder layout [demo]
- Silverlight Bag of tricks
- A Silverlight graph visualizer (updated)
There is also a similar (duplicate?) question here: Graph visualisation in Silverlight
spoon16
2009-08-25 04:28:27
+4
A:
I wrote some code awhile ago to perform dynamic graph layouts using C# and XNA (full source available upon request).
Here are some of the critical functions:
public void UpdateNodes()
{
for (int i = 0; i < nodes.Count; i++)
{
Vector2 netForce = Vector2.Zero;
foreach (Node otherNode in nodes)
{
if (otherNode != nodes[i])
{
netForce += CoulombRepulsion(nodes[i], otherNode); //calculate repulsion for all nodes
if (nodes[i].links.Contains(otherNode))
{
netForce += HookeAttraction(nodes[i], otherNode); //only calc attraction for linked nodes
}
}
}
nodes[i].Velocity += netForce;
nodes[i].Velocity *= .99f;
nodes[i].Position += nodes[i].Velocity;
}
}
public Vector2 HookeAttraction(Node node1, Node node2) //ON node1 BY node2
{
Vector2 direction = Vector2.Subtract(node2.Position, node1.Position);
direction.Normalize();
return hookeConst* node2.Mass * Vector2.Distance(node1.Position, node2.Position) * direction;
}
public Vector2 GravAttraction(Node node1, Node node2) //ON node1 BY node2
{
Vector2 direction = Vector2.Subtract(node2.Position, node1.Position);
direction.Normalize();
return gravConst * node2.Mass * Vector2.DistanceSquared(node1.Position, node2.Position) * direction;
}
Pick the two constants based on how fast you want the graph to converge. I used these:
private const float hookeConst = .000005f;
private const float gravConst = .00000001f;
That code is pretty self-explanatory, but feel free to ask if you need anything. Basically, call the UpdateNodes() function in a loop, and your graph will converge on its minimal-energy state.
Preetum Nakkiran
2009-08-25 04:40:30
Just a note: that "nodes[i].Velocity *= .99f;" is a dampening constant to make your graph converge more easily. Decrease that value for less "springyness."
Preetum Nakkiran
2009-08-25 04:43:41
I'd like the source... [email protected]
spoon16
2009-08-25 04:46:42
sure, here it is (as a zipped project): http://staff.arson-media.com/preetum/uploads/springForceV0.zipNote that I wrote this code *quite* awhile ago, so there are some unnecessarily obfuscated regions (like the region marked "mouseStuff" in the update loop).Nevertheless, all the important components are present and functional. (There's some interactivity with the mouse, as well)
Preetum Nakkiran
2009-08-25 05:22:40
Great post! Thanks. If you wouldn't mind, can you send the source to flowunderstack at gmail.com
Jeremy
2009-08-25 17:18:36
The above link is dead - is there a live version somewhere?
gt
2010-08-06 12:31:25
sure, sorry 'bout that: http://nakkiran.org/uploads/f/springForceV0.zip
Preetum Nakkiran
2010-09-02 01:53:13
A:
Hi Jeremy,
have you found a solution. Got the same problem and searching for a good tutorial or sample code. thank you.
greetings,
chris
chris
2010-09-01 18:04:35
Not yet. My project has been put on the side for a little bit, but I'll probably revisit it soon. See spoon15's answer though, there are a few links which have some good samples.
Jeremy
2010-09-01 19:43:55