Force graph with different size nodes.

7,950 views
Skip to first unread message

ben palmer

unread,
May 11, 2012, 9:10:18 AM5/11/12
to d3...@googlegroups.com
Has anyone seen an example of a d3 force graph where the node size is
not uniform (i.e. a per node repulsion charge).

If not I will try myself, unless that is madness.

Cheers Ben

Lukáš Beránek

unread,
May 11, 2012, 9:13:24 AM5/11/12
to d3...@googlegroups.com
Hi Ben,

there is a plenty of examples included int the d3 package on github, many more in the wiki on github ( RTFM :-) ) and also googling would bring some pretty examples and more.

Lukas

Dne 11.5.2012 15:10, ben palmer napsal(a):

ben palmer

unread,
May 11, 2012, 9:15:21 AM5/11/12
to d3...@googlegroups.com
I have looked, all the ones I have seen have uniform node size, did I miss some?

Lukáš Beránek

unread,
May 11, 2012, 9:21:13 AM5/11/12
to d3...@googlegroups.com
Untli I am missing something, these nodes do not look the same to me in any angle of view. What do you mean by node size? If you mean the node radius, then it is definitely different for each node, based on its value.

You surely can use something like this:

node.enter()
        .append("svg:circle")
        .attr("class", function(d){ return "circle type"+d.type})
        .attr("r", function(d) { return d.radius })//here the svg:circle radius is set based on the data vaules, do your magic HERE
        .on("mouseover", fade(.1, true))
        .on("mouseout", normalizeNodesAndRemoveLabels())
        .on("click", openLink())
In case that this is what you had in mind.


Dne 11.5.2012 15:15, ben palmer napsal(a):

ben palmer

unread,
May 11, 2012, 9:35:01 AM5/11/12
to d3...@googlegroups.com
Thank you, but that is a visual change, which means it will result in
nodes overlapping.
I should explain better, I want a per node repulsion charge (dependant
upon its size), so that the force graph layout will attempt to move
give larger nodes more space (thus visually separating them). From my
reading of the d3 wiki a universal repulsion charge exists, where as I
want it per node.

arbor.js supports this as the nodes 'mass' attribute "the node’s
resistance to movement and repulsive power", I am looking to do the
same in d3.js

Cheers Ben

Lukáš Beránek

unread,
May 11, 2012, 9:42:14 AM5/11/12
to d3...@googlegroups.com
In this case, you would want to see this Mike's talk where he mentions multiple focis and algorithms for collision detecting based on the node's radius. You can set node radius when creating it and the collision algo would add more padding to it, forcing it to separate from others. Take a look on the previous example with grants in my first post. When you toggle buttons you will see how the nodes are attracted to different foci places.

Hope this helps.



Dne 11.5.2012 15:35, ben palmer napsal(a):

Elijah Meeks

unread,
May 11, 2012, 12:51:27 PM5/11/12
to d3...@googlegroups.com
I've been experimenting with making force.linkDistance a function of the source and target node's weight, so that a stronger weight will pull nodes closer, and it shows some promise:

linkramp=d3.scale.linear().domain([2,10,40]).range([50,100,300]).clamp(true);

force = d3.layout.force()
.gravity(.05)
.linkDistance(function (d) {return linkramp(d.source.weight + d.target.weight)})
.charge(-200)
.size([w, h]);

Obviously, you'd probably want a more interesting metric than raw degree, but it's a good, dynamic place to start. There's also linkStrength, but I haven't seen much effect from changing that.

Mike Bostock

unread,
May 12, 2012, 9:33:16 PM5/12/12
to d3...@googlegroups.com
You can define the layout's charge property as a function rather than
a constant. It's not really mentioned in the documentation, but it's
supported:

https://github.com/mbostock/d3/wiki/Force-Layout#wiki-charge
https://github.com/mbostock/d3/blob/master/src/layout/force.js#L226-229

For example, if your nodes have a radius property, you might say:

force.charge(function(d) { return -d.radius * d.radius; })

Mike

mawksey

unread,
May 13, 2012, 3:18:35 AM5/13/12
to d3-js
The charge function is also used in Jim Vallandingham's Creating
Animated Bubble Charts in D3 http://vallandingham.me/bubble_charts_in_d3.html
(see section on bubble collision detection)

Written in coffee script as
charge: (d) ->
-Math.pow(d.radius, 2.0) / 8

Martin

ben palmer

unread,
May 13, 2012, 8:22:57 AM5/13/12
to d3...@googlegroups.com
Thank you all for you helpful suggestions.
Following Lukáš and Elijah informative comments I was achieving some
good results by tweaking the d3 force repulse function, but I think
using a force.charge function is much better, combined with a
collision avoidance pass, and I think I will have a good result.

I will also use the link strength function to convey a links strength
value, this being to rpereset encode quite a bit of information into
the layout itself.

Cheers Ben
Reply all
Reply to author
Forward
0 new messages