Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
208 views
in Technique[技术] by (71.8m points)

javascript - d3.js linkStrength influence on linkDistance in a force graph

I'm working on a graph to show relations between different nodes. The closer related the nodes are (according to business logic), the closer together the nodes should be.

I noticed that some links with the linkStrength of .1 are shorter (that is what I wanted to achieve) and some others with the same strength are longer than the ones with the linkStength of 1. From a documentation about the force layout parameters I now found this quote:

The default linkStrength value is 1.0, which maintains the full effect of linkDistance. By setting the value of linkStrength less than 1, though, the distance constraint can be relaxed.

Does that mean that if I was to set linkDistance to 150, the links with linkStrength(1.0) will be closer to 150 than the ones with linkStrength(.1)? And if yes, do they need to be shorter, longer or doesn't that matter at all? Because I was kind of surprised about the layout.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To cut a long story short: when using D3's force layout there is no built-in way to enforce a fixed length of the links. The force layout is inherently dynamic and setting values for force.linkDistance() and force.linkStrength() introduces just another force to the set of calculations carried out on each iteration, i.e. each tick, while the force layout is running.

There are three forces calculated on each tick:

1. Link length. The first force to be calculated is the adjustment for link lengths set via the above mentioned methods. This is done in a loop for each link and, looking at the source, this comes down to essentially one line of code:

l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l;

With l calculated to be the Euclidean distance between the link's source node and target node, the desired link distance distances[i] and the link's strengths[i] this line determines how to pull both nodes together or push them apart to approximate the link distance set via force.linkDistance(). It's easy to see, that the link strength has a linear effect on the resulting force. Contrary to the API documentation, though, which defines the valid range for the strength to be in the interval [0,1], the source code does not impose any restrictions on the value set by force.linkStrength().

2. Gravity. The second force to be calculated will take into account gravitational forces on each node.

3. Charge. Lastly, the mutual forces of the nodes' charges are calculated.

Because the effects of all the calculated forces are superimposed and will add up to the resulting movement of each node for a given tick, it becomes clear, that the link length is only one part of the entire computation. The other two forces may weaken or even reverse its effect.

As for your question

Does that mean that if I was to set linkDistance to 150, the links with linkStrength(1.0) will be closer to 150 than the ones with linkStrength(.1)?

The outcome depends largely on the setup of the force layout's parameters and the distribution of the nodes, and still no guarantee is made regarding the final lengths of the links.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...