d3.js中linkStrength对力导向图中linkDistance的影响

3
我正在制作一个图表,展示不同节点之间的关系。根据业务逻辑,节点间关系越密切,节点间距离应该越近。
我发现一些链接的linkStrength为0.1,距离“更近”(这正是我想要的),而另一些具有相同强度的链接却比linkStrength为1的那些链接“更远”。从有关力布局参数的文档中,我找到了这段话:
默认的linkStrength值是1.0,这保持了linkDistance完整的效果。但是,通过将linkStrength的值设置小于1,可以放松距离约束。
这是否意味着,如果我将linkDistance设置为150,那么linkStrength(1.0)的链接会比linkStrength(.1)的链接更接近150呢?如果是这样,它们需要更短、更长还是长度无所谓?因为我对布局感到有些惊讶。

我不完全确定你关于距离的说法是否正确,但我倾向于说是。然而,我确信当linkStrength变小时,边缘更容易受到节点电荷和力图的“重力”的影响。节点根据它们的电荷相互吸引或排斥。 - ocket-san
2个回答

8
简而言之:使用D3的力导向布局时,没有内置的方法来强制固定链接长度。力导向布局本质上是动态的,设置force.linkDistance()force.linkStrength()的值只会在每次迭代(即每个tick)中引入另一个力量,而此时力导向布局正在运行。
每个tick计算三个力量:

1. 链接长度首先要计算的是通过上述方法设置的链接长度调整。这是针对每个链接进行循环计算的,并且从源代码来看,这基本上只需要一行代码:

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

使用计算得出的l作为连接源节点和目标节点之间的欧几里得距离,加上期望的连接距离distances[i]和连接的strengths[i],该行确定如何将两个节点拉在一起或推开它们以近似通过force.linkDistance()设置的连接距离。很容易看出,连接强度对结果力量有线性影响。与 API 文档相反,API 定义了强度的有效范围为区间[0,1],但源代码不会对由force.linkStrength()设置的值施加任何限制。 2. 引力第二个要计算的力将考虑每个节点上的引力

3. 计算电荷 最后,节点的电荷之间的相互作用力被计算出来。

由于所有计算出来的力的效应都会叠加起来,形成每个节点在给定时间内的运动结果,因此很明显,链接长度只是整个计算的一部分。其他两个力可能会削弱或甚至扭转它的效果。

至于您的问题

那是否意味着如果我将linkDistance设置为150,具有linkStrength(1.0)的链接将比具有linkStrength(0.1)的链接更接近150?

结果在很大程度上取决于力布局参数的设置和节点的分布,并且仍然不能保证链接的最终长度。


2
链接强度设置了链接的刚度,而不是节点之间的距离(力导向布局文档)。节点之间的距离由它们的电荷控制。您可以像这样使节点的电荷动态化:
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();

一个使用这种技术的工作示例:vizz.ly

你能否更新这个语法以适应v4?我在这里有一个相关的问题 https://dev59.com/G1kS5IYBdhLWcg3w-KpF?noredirect=1#comment65826858_39244186 - dcsan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接