D3.js v6.2 - 在监听器函数中获取数据索引 - selection.on('click', listener)



在以前的版本中,可以通过以下方式检索索引iselection.on("click", function(d,i){...}

然而,在最新版本中,这似乎不再有效,因为第一个参数始终是事件对象。如何在侦听器函数中获取数据的索引?

let data = [2,5,8,9]
d3.select("body").selectAll("p")
.data(data)
.enter()
.append("p")
.text(d=>d)
.on("mouseover", function(e,d,i){
//console.log(e); --> event
console.log(d); 
console.log(i);
// i should be the index of the hovered element
})
<script src="https://d3js.org/d3.v6.min.js"></script>

当指定的事件被调度到选定的元素上时,指定的监听器将被评估为该元素,并被传递当前事件(event(和当前数据(d(,将其作为当前DOM元素(event.currentTarget(。

官方文档:https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_on

关于d3 selection 2.0中新功能的Observable笔记本建议使用局部变量来保留索引:

Listener不再传递选定元素的索引(i(或同级节点(节点。这些元素很少使用,如果重新选择元素,则会出现令人困惑的行为,并可能导致内存泄漏。如果需要它们,请将它们烘焙到元素的数据中,或者使用局部变量。

这可以通过以下几条线毫不费力地完成:

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>

注意,尽管为了清楚起见,上面的示例使用了对.each()的单独调用,但为了简洁和性能起见,这也可以在对.text()的现有调用中进行。

恐怕这次更新中删除了索引。如果你正在寻找一个,最简单的方法是将其作为属性附加到数据中(例如.data(data.map((d,i) => ({ value: d, i: i })))(,或者在你所拥有的节点选择中查找索引:

let data = [2,5,8,9]
const p = d3.select("body").selectAll("p")
.data(data)
.enter()
.append("p")
.text(d=>d)
.on("mouseover", function(e,d){
console.log(d); 
console.log(p.nodes().indexOf(this));
})
<script src="https://d3js.org/d3.v6.min.js"></script>

最新更新