繁体   English   中英

d3.js节点在强制布局中快速拖动时“跳回”

[英]d3.js Node “jumps back” on fast drag in force layout

我正在使用零重力和电荷值的力布局:

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 + ")";
});
        }

有一个圆圈。 问题是当我快速拖动时,圆圈“跳回”。 任何帮助,将不胜感激。 谢谢。

CodePen: http ://codepen.io/vanquang9387/pen/gpLpGE?edit = 001

脏修复

改变这个......

.friction(0.9)

对...

.friction(0)

背景

在d3中的force layout模块内部,有一个force.tick方法,在每个动画帧之前调用。 这是重新计算节点位置的位置。 对链路进行了计算,其中考虑了链路strengthweights和目标linkDistance ; gravity计算,它是每个节点距布局中心的距离的函数; 以及基于chargecharge chargeDistance和节点的相对位置的电荷计算。 还有friction计算。 所有这些 - 除了friction计算 - 都考虑了布局( alpha )的当前“温度”,这实际上只是一个指数衰减值,它是自布局开始以来经过了多少滴答的函数。

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

friction不是真正的“摩擦”,它更像是WIKI中解释的速度衰减, friction计算是通过将节点移动到前一刻度结束时的位置来保持节点的速度( pxpy ) 。 移开的距离与每个节点的速度成比例,该速度基于( pxpy )与当前tick前一步骤(链接,电荷和重力)计算的位置之间的距离(实际上它更多一点)比那更复杂,因为电荷计算实际上是“非因果”并且改变了以前的位置,但这并不影响摩擦计算的原理)。

在拖,( pxpy )与由每拖动行为鼠标位置更新的mousemove 然后 ,在下一个刻度线上,这些值将复制到力布局中的( xy )。 因此,在拖动过程中, 前一个位置实际上是当前位置,反之亦然! 因此,当阻力结束时,摩擦计算中使用的速度与其实际速度方向相反 ,因此friction计算试图保持这个......这就是它向后跳跃的原因。

死停

我的下一步行动是找到一种在dragend事件处理程序中将( pxpy )设置为( xy )的dragend
比如这样......

  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,节点也会在dragend之后停止。
顺便说一下,你不需要根据代码的当前状态来保留this上下文,但无论如何,我认为这是一个好习惯。 谁知道未来将会带来什么;)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM