自定义force.drag在悬停时丢失粘性节点

时间:2014-04-03 15:46:39

标签: javascript d3.js drag force-layout

如果您自定义强制布局拖动,/ src /layout / force.js中的d3.js源会提前返回:

  force.drag = function() {
    if (!drag) drag = d3.behavior.drag()
        .origin(d3_identity)
        .on("dragstart.force", d3_layout_forceDragstart)
        .on("drag.force", dragmove)
        .on("dragend.force", d3_layout_forceDragend);

    if (!arguments.length) return drag;

    this.on("mouseover.force", d3_layout_forceMouseover)
        .on("mouseout.force", d3_layout_forceMouseout)
        .call(drag);

  };

模拟运行时会跳过粘滞的悬停代码。您可以在此演示http://bl.ocks.org/mbostock/3750558上看到它。当你让模拟移动很多并尝试通过将节点悬停在节点上来停止它时,它们就不再停止了。

我正在努力解决这个问题:

force.drag()
   .on('dragstart', function(d) {
      //...
   })
   .on('dragend', function(d) {
      //...
   }) ;

//...

node.call(force.drag);

此代码将首先调用force.drag的早期返回版本,以便您可以侦听事件,然后调用默认版本以获得额外的鼠标行为。第二个调用会跳过拖动事件部分,因为它已经注册了,这对于这种情况来说意外是好的。

以下是我想要使用的代码,但您将在悬停功能上丢失粘性节点:

var drag = force.drag()
   .on('dragstart', function(d) {
      //...
   })
   .on('dragend', function(d) {
      //...
   }) ;

//...

node.call(drag);

我之所以不使用自己的d3.behavior.drag,是因为我想尽可能多地使用力布局的固定处理。

当您想要自定义拖动时,是否有人知道为什么代码会提前返回?我的解决方法对于未来的力阻力变化非常脆弱。不幸的是,将回归移到底部可能会破坏一些人的模拟。

1 个答案:

答案 0 :(得分:1)

force.drag函数的后半部分通过建立侦听器将拖动行为附加到一组元素。当你在没有任何参数的情况下调用它时,这不是一个选择,代码也不会做你想要的(并且很可能会给你一个错误)。因此,如果没有任何内容可以附加监听器,它会检查并返回。