在以前的版本中,可以通过以下方式检索索引i
:selection.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>