Javascript d3:多焦点部队关键代码组件理解

Javascript d3:多焦点部队关键代码组件理解,javascript,svg,d3.js,force-layout,Javascript,Svg,D3.js,Force Layout,多焦点力的真正魔力在这里完成 function tick(e) { var k = .1 * e.alpha; // Push nodes toward their designated focus. nodes.forEach(function(o, i) { o.y += (foci[o.id].y - o.y) * k; o.x += (foci[o.id].x - o.x) * k; }); node.attr(

多焦点力的真正魔力在这里完成

function tick(e) {
    var k = .1 * e.alpha;

    // Push nodes toward their designated focus.
    nodes.forEach(function(o, i) {
        o.y += (foci[o.id].y - o.y) * k;
        o.x += (foci[o.id].x - o.x) * k;
    });

    node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
}   
但我希望能澄清一下到底发生了什么

我认为,alpha是一种力法,它控制力停止的速率,接受[0,1]范围内的值——越高的值会导致力减速到停止,速度越慢,速度越快

然后,我们迭代原始数组,并通过焦点的x和y分量k*增加x和y位置(它们最初不存在,因此在该forEach循环的第一次迭代中首次分配)

最终,它们将总是朝着指定的x和y位置移动,但是我们如何保证我们根据k值(它本身是基于alpha的)将它们移到那里呢?节点沿x轴和y轴移动的范围是否由.1常量控制?将该值设置得更高/更低意味着更多/更少地向焦点漂移

最后,我们为什么要变换节点?我会理解的

attr(“cx”,函数(d){returnd.x})和y的相同。为什么要转变

谢谢你

jfiddle-


更新:我怀疑我问题的最后一部分,为什么要变换节点,是因为我们移动的是g元素而不是圆元素,并且我们不能在g元素上使用cx和cy。仍然不确定我们为什么要将它们转换为d.x和d.y,这会不会将它们从任意指定的d.x和d.y值移动到有效的两倍位置?(如果我们从[10,10]开始,然后翻译另一个[10,10],我们将在[20,20]?)结束。

动画由
alpha
驱动。这是一个几何级数,总是相同的:在
.start()
中设置为0.1,并在每个刻度处乘以0.99,动画在小于0.005时停止

alpha: 0.0990
alpha: 0.0980
alpha: 0.0970
alpha: 0.0961
alpha: 0.0951
alpha: 0.0941
……等等

force.tick = function() {
    if ((alpha *= .99) < .005) {
        event.end({
            type: "end",
            alpha: alpha = 0
        });
        return true;
    }
    //other code...
};
在上面的,
forEach
语句中,如果元素y位置大于焦点y位置,那么它将得到一个较小的y,与x位置类似。这意味着它们将以与其距离成比例的速度向焦点移动。比例常数
k
0.1*alpha
,随着动画的进行,该比例常数从
k=0.1*0.1
几何递减为
k=0.1*0.005
。最终位置是其初始位置和
k
以及其他重力、电荷和摩擦力的函数

这些节点是
g
元素,除了其子元素的引用(定位上下文)之外,没有其他定位。这是containing
svg
元素的原点(左上角),它的位置是页面流和CSS定位的结果。
g
元素的定位上下文可以通过它们的transform属性进行更改,这将由它们的所有子元素继承。如果没有g元素,圆圈和文本元素都必须分开放置,这样工作就会以这种方式减半。如果没有转换,所有的圆和文本都将定位在
svg
元素的左上角

每个记号计算的新位置是绝对值,而不是值的变化

节点位置的变化是
(foci[o.id].y-o.y)*k
,这会将它们移向它们的焦点。该值被“添加”到现有值中(尽管可能为负值),并存储在节点基准面(
o.x
o.y
)上,该语句

node.attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; });

使用新的数据(
d
)更新翻译,它仍然相对于
svg
原点。它是一种转换,而不是移动,因此它不会相对于当前位置进行转换,而是相对于
svg
元素原点(即
g
的定位上下文)更改转换。因此,如果我们从[10,10]开始,新的计算是[10,10],那么相对于
svg
定位上下文,位置将保持在[10,10]。

感谢您的澄清。
node.attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; });