D3.js: Remove force.drag from a selection

2019-01-09 13:07发布

问题:

I have a (rather simple) question: How to "un-call" force.drag on a selection made by D3.js? Let's say I created a set of elements and called "call" on it, giving it the drag-callback of a force-directed layout. That looked like this:

    d3.selectAll('rect').call(force.drag);

Now it shall be possible to remove that behavior from some of the nodes later on. My approaches included resetting various listeners, such as 'click', 'drag' etc. using

    d3.select('rect#no-drag').on('click', null);

None of them worked. Does anybody know how to remove the callback?

回答1:

You are close. The drag event is initiated by a mousedown event with a namespace called drag. See: https://github.com/mbostock/d3/blob/master/src/behavior/drag.js#L5

So, to remove this you could do:

d3.select('rect#no-drag').on('mousedown.drag', null);


回答2:

This question isn't asking how to have fine grained control on the drag element, but I came here looking for how to toggle the drag on/off based on conditions, and the asker also asked how to get the drag back after removing it in the comments.

Thus, for anyone looking for how to conditionally allow the drag event, use drag.filter.

drag.filter takes a callback that needs to return a boolean. If the callback returns true, the drag happens, otherwise the drag doesn't trigger.

This is much cleaner than removing the drag from the selection and then trying to re-apply it.



回答3:

This line somehow it's not mobile compatible (chrome/android)

d3.select('rect#no-drag').on('mousedown.drag', null);