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

Customizing force.drag loses sticky nodes on hover

本文关键字:节点 悬停 force drag 自定义      更新时间:2023-09-26
/

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,是因为我想尽可能多地使用力布局的 d.fixed 处理。

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

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