简体   繁体   中英

Dispatching drag-end event

I want to programmatically fire the "end" event of d3-drag. I have some circles and have the drag-handling of them implemented like so:

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

Now, later in my code, I would like to trigger the "end" part of this programmatically.

I have already tried something like this:

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

If you don't need to generate any actual event data, and I understand the question correctly, you can do this relatively easily without d3.dispatch directly. The below will give you this and the node data itself (in d3v5 it will also give you i and nodes ).

D3v5 and earlier

In d3v5 and earlier, the signatures for a function passed to selection.each() and drag.on() were the same. In this case you can easily assign the function to a variable and pass it to both. Alternatively, you could access the drag event function with drag.on("typeName") .

Here's a quick example:

 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 dx; }) .attr("cy", function(d) { return dy; }) .attr("fill", function(d,i) { return ["steelblue","crimson"][i] }) var drag = d3.drag() .on("drag", function(d) { dx = d3.event.x; dy = d3.event.y; d3.select(this) .attr("cx", dx) .attr("cy", dy); }) .on("end", function(d) { console.log(d.x+","+dy); 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

In d3v6 the signatures of functions passed to selection.each() and drag.on() are different. The datum is the first parameter of the former and the second parameter of the latter. So we could use Function.apply() within selection.each() to trigger the end function and pass the proper this and d while passing null for the event data.

 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 dx; }) .attr("cy", function(d) { return dy; }) .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+","+dy); d3.select(this) .transition() .attr("r", 30) .transition() .attr("r", 10); } function drag(event,d) { dx = event.x; dy = event.y; d3.select(this) .attr("cx", dx) .attr("cy", dy); }
 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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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