【问题标题】:Dispatching drag-end event调度拖尾事件
【发布时间】:2020-10-29 14:48:36
【问题描述】:

我想以编程方式触发 d3-drag 的“结束”事件。 我有一些圈子,它们的拖动处理是这样实现的:

...
.call(d3.drag()
     .on("drag", function () {...})
     .on("end", function () {...})
)

现在,稍后在我的代码中,我想以编程方式触发“结束”部分。

我已经尝试过这样的事情:

d3.select("#myID").dispatch("end");
d3.select("#myID").dispatch("dragend");
d3.select("#myID").call(d3.drag().dispatch("end"));

【问题讨论】:

  • 您需要将任何特定的事件信息传递给函数,还是只需要在指定的选择上运行?
  • 该函数在选择这些圆圈时运行,并使用“this”来引用拖动的圆圈和圆圈的数据/位置

标签: javascript d3.js event-dispatching


【解决方案1】:

如果您不需要生成任何实际的事件数据,并且我正确理解了这个问题,那么您可以相对轻松地执行此操作,而无需直接使用 d3.dispatch。下面将为您提供 this 和节点数据本身(在 d3v5 中,它还将为您提供 inodes)。

D3v5 及更早版本

在 d3v5 和更早版本中,传递给 selection.each()drag.on() 的函数的签名是相同的。在这种情况下,您可以轻松地将函数分配给变量并将其传递给两者。或者,您可以使用drag.on("typeName") 访问拖动事件功能。

这是一个简单的例子:

var svg = d3.select("body")
  .append("svg")
  .attr("width",500)
  .attr("height",300);
  
var data = [{x:40,y:100},{x:250,y:100}];

var circles = svg.selectAll(null)
  .data(data)
  .enter()
  .append("circle")
  .attr("r", 10)
  .attr("cx", function(d) { return d.x; })
  .attr("cy", function(d) { return d.y; })
  .attr("fill", function(d,i) {
    return ["steelblue","crimson"][i]
  })

var drag = d3.drag()
  .on("drag", function(d) {
    d.x = d3.event.x; d.y = d3.event.y;
    d3.select(this)
      .attr("cx", d.x)
      .attr("cy", d.y);
  })
  .on("end", function(d) {
     console.log(d.x+","+d.y);
     d3.select(this)
       .transition()
       .attr("r", 30)
       .transition()
       .attr("r", 10);
  })
  
circles.call(drag);

d3.select("button").on("click", function() {
  var circle = d3.select("circle")
    .each(drag.on("end"));
})
circle {
   cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<button>Trigger Drag End On Blue Circle</button>

D3v6

在 d3v6 中,传递给 selection.each()drag.on() 的函数的签名是不同的。数据是前者的第一个参数,后者的第二个参数。所以我们可以在selection.each()中使用Function.apply()来触发结束函数,并传递正确的thisd,同时传递null作为事件数据。

var svg = d3.select("body")
  .append("svg")
  .attr("width",500)
  .attr("height",300);
  
var data = [{x:40,y:100},{x:250,y:100}];

var circles = svg.selectAll(null)
  .data(data)
  .enter()
  .append("circle")
  .attr("r", 10)
  .attr("cx", function(d) { return d.x; })
  .attr("cy", function(d) { return d.y; })
  .attr("fill", function(d,i) {
    return ["steelblue","crimson"][i]
  })

var drag = d3.drag()
  .on("drag", drag)
  .on("end", dragend)

circles.call(drag);

d3.select("button").on("click", function() {
   var circle = d3.select("circle")
    .each(function(d) { 
       dragend.apply(this,[null,d]) 
    })
})


function dragend(event,d) {
  console.log(d.x+","+d.y);
  d3.select(this)
    .transition()
    .attr("r", 30)
    .transition()
    .attr("r", 10);
}
function drag(event,d) {
  d.x = event.x; d.y = event.y;
  d3.select(this)
    .attr("cx", d.x)
    .attr("cy", d.y);
}
circle {
   cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.0.0/d3.min.js"></script>
<button>Trigger Drag End On Blue Circle</button>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-02
    • 2012-01-28
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 2020-06-21
    • 2018-12-10
    • 1970-01-01
    相关资源
    最近更新 更多