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)它有一个完全不同的阻力特性模块,其中包括一个惯性方法,该方法已经消失。。。