Retrieve Dom Target from Drag Callback When 'This' Is Not Available

Retrieve DOM target from drag callback when `this` is not available

Use the second and the third arguments together to get this when this is not available:

d3.drag().on(typename, function(d, i, n) {
//here, 'this' is simply n[i]
})

For a detailed explanation, have a look at the article below that I wrote to deal with this in arrow functions. The issue is different from yours, but the explanation is the same.

Here is a basic demo, try to drag a circle and look at the console:

var data = d3.range(5)var svg = d3.select("body")  .append("svg")  .attr("width", 400)  .attr("height", 100);var circle = svg.selectAll(null)  .data(data)  .enter()  .append("circle")  .attr("cy", 50)  .attr("cx", function(d) {    return 50 + 50 * d  })  .attr("r", 10)  .attr("fill", "tan")  .attr("stroke", "black")  .call(d3.drag()    .on("start", function(d, i, n) {      console.log(JSON.stringify(n[i]))    }))
<script src="https://d3js.org/d3.v4.min.js"></script>

D3.js v6.2 - get data index in listener function - selection.on('click', listener)

The Observable notebook on the new features in d3-selection 2.0 suggests using a local variable to preserve the index:

Listeners are no longer passed the selected element’s index (i) or siblings (nodes). These were rarely used, had confusing behavior if elements were re-selected, and could cause memory leaks. If you need them, bake them into the element’s data or use a local variable instead.

This can be done with little effort along the following lines:

let data = [2,5,8,9]

const index = d3.local(); // Local variable for storing the index.

d3.select("body").selectAll("p")
.data(data)
.enter()
.append("p")
.text(d=>d)
.each(function(d, i) {
index.set(this, i); // Store index in local variable.
})
.on("mouseover", function(e,d,i){
console.log(d);
console.log(index.get(this)); // Get index from local variable.
});
<script src="https://d3js.org/d3.v6.min.js"></script>


Related Topics



Leave a reply



Submit