d3.js linkStrength influence on linkDistance in a force graph

后端 未结 2 1135
鱼传尺愫
鱼传尺愫 2021-01-15 06:00

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. <

相关标签:
2条回答
  • 2021-01-15 06:41

    The link strength sets the rigidity of the links, not the distance between the nodes (force layout doc). The distance of the nodes from each other is controlled by their charge. You can make the charge of a node dynamic like so:

    var force = d3.layout.force()
            .nodes(nodes)
            .theta(0.1)
            .charge(function (d) {
                return -(d.radius * d.radius * 0.125);
            })
            .gravity(0.1)
            .size([width, height])
            .on("tick", tick)
            .start();
    

    A working example that uses this technique: vizz.ly

    0 讨论(0)
  • 2021-01-15 06:46

    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.

    0 讨论(0)
提交回复
热议问题