Javascript d3.js节点";“向后跳”;关于强制布局中的快速拖动

Javascript d3.js节点";“向后跳”;关于强制布局中的快速拖动,javascript,d3.js,Javascript,D3.js,我使用的是重力和电荷值为零的力布局: var force = d3.layout.force() .gravity(0) .charge(0) .friction(0.9) .linkDistance(250) .linkStrength(1) .size([width, height]) .on("tick", tick); function tick(e) { d.y = Math.max(d.radius, Math.min

我使用的是重力和电荷值为零的力布局:

var force = d3.layout.force()
    .gravity(0)
    .charge(0)
    .friction(0.9)
    .linkDistance(250)
    .linkStrength(1)
    .size([width, height])
    .on("tick", tick);

function tick(e) {
    d.y = Math.max(d.radius, Math.min(height - d.radius, d.y));
    d.x = Math.max(d.radius, Math.min(width - d.radius, d.x));

    return "translate(" + d.x + "," + d.y + ")";
});
        }
有一个圆圈。问题是当我快速拖动时,圆圈“向后跳”。任何帮助都将不胜感激。谢谢

代码笔:

脏修复 改变这个

.friction(0.9)
.friction(0)
对此

.friction(0.9)
.friction(0)
背景 在d3中的force layout模块中,有一个
force.tick
方法,在每个动画帧之前调用该方法。这是重新计算节点位置的位置。链路的计算考虑了链路
强度
权重
和目标
链路距离
;重力计算是每个节点距布局中心距离的函数;以及基于
电荷
电荷距离
和节点的相对位置的电荷计算。还有一个摩擦力的计算。除摩擦计算外,所有这些都考虑了布局的当前“温度”(
alpha
),这实际上只是一个指数衰减值,是自布局启动以来经过的滴答数的函数

这些计算按顺序应用于布局的所有元素,每个步骤的输入位置是前一步的输出。但是,对于摩擦力计算,“固定”节点的处理方式不同,并且拖动的节点通过拖动行为固定

摩擦力
不是真正的“摩擦力”,它更像中解释的速度衰减,
摩擦力
计算的目的是通过将节点从上一个记号结束时的位置移开(
px
py
)来保持节点的速度。移动的距离与每个节点的速度成正比,该速度基于(
px
py
)和当前
勾选中先前步骤(链接、电荷和重力)计算的位置之间的距离(事实上,它比这稍微复杂一点,因为电荷计算实际上是“非因果”的,并且改变了先前的位置,但这并不影响摩擦力计算的原理)

在拖动过程中,(
px
py
)通过每个
mousemove
上的拖动行为用鼠标位置更新。然后,在下一次勾选时,将这些值复制到(
x
y
)在力布局中。因此,在拖动过程中,前一个位置实际上是当前位置,反之亦然!因此,当拖动结束时,摩擦力计算中使用的速度与实际速度的方向相反,因此
摩擦力
计算试图保持这一点…这就是它向后跳的原因

止动块 我的下一步是找到一种方法,在
dragend
事件处理程序中将(
px
py
)设置为(
x
y
) 像这样的例子

  var stdDragEnd = force.drag().on("dragend.force");
  force.drag().on("dragend.force", myDragEnd);
  function myDragEnd(d) {
    d.px = d.x; d.py = d.y;
    stdDragEnd.call(this, d)
  }
您可以将其放在已定义
force
变量的代码中的任何位置。其想法是挂钩标准行为,而不是替换它

现在,即使将“摩擦力”设置为1.0,节点也将在拖动后停止运行。

顺便说一句,你不需要根据代码的当前状态来保存
这个
上下文,但无论如何,我想这是一个很好的实践。谁知道未来会带来什么呢(lah;)

你能提供一个JSFIDLE吗?@thisonegy:我不能让它在共享方面与JSFIDLE一起工作。我已经更新了代码笔链接。谢谢你,好像有用。但是,当我添加更多的节点和链接并且带有负电荷值时,这将减慢运动。是吗?谢谢你的详细解释。我正在尝试dragend事件。非常感谢您的帮助。但现在我想做一个惯性阻力,而不是“死挡”。与其他节点和链接类似:我认为很难实现:(@Quang,这是一个新问题。你只是问了一个关于跳回的问题,我回答了这个问题,所以如果你接受我的回答并问一个新问题会更好。我也会帮你…@Quang,顺便说一句,你给出的链接使用的是旧版本(3.2.2)它有一个完全不同的阻力特性模块,其中包括一个惯性方法,该方法已经消失。。。