您没有正确使用 selection.on() 方法。为了对事件执行某些操作,您需要为该方法提供第二个参数:描述对事件采取的操作的函数:
D3v6+
.on("mouseover", function(event, datum) { ... })
D3v5 及之前
.on("mouseover", function(datum, index, nodes) { ... })
在所有版本的 D3 中,this 将是目标元素(除非使用 arrow notation)。数据是绑定到目标元素的数据,数组中的一项传递给 selection.data()。
如果您只提供一个参数,它将返回分配给该事件的当前事件处理函数。在您的情况下,您可能还没有这样做(因为您正在尝试这样做),因此.on("mouseover").style(...) 将返回诸如“找不到 null 的属性样式”之类的错误,因为 .on("mouseover") 将返回 null : 没有分配给该事件返回的事件处理函数。
因此,要使用某些逻辑突出显示鼠标悬停时的节点,以便我们可以为不同的节点产生不同的结果,我们可以使用类似的东西:
selection.on("mouseover", function(event, datum) {
if(datum.property == "someValue") {
d3.select(this).style("text-decoration","underline");
}
})
.on("mouseout", function(event,datum) {
d3.select(this).style("text-decoration","none");
})
if 语句可以替换为您喜欢的任何逻辑。
我看到你可能在使用分层布局生成器,D3 的分层布局生成器将原始数据的属性嵌套到数据属性中,这样布局属性和非布局属性就不会发生冲突,所以 datum.property可能位于 datum.data.property(如果遇到问题,请记录数据)。
var svg = d3.select("body")
.append("svg");
var data = [
"Underline on mouse",
"Never underline"
];
svg.selectAll("text")
.data(data)
.enter()
.append("text")
.attr("x", 20)
.attr("y", (d,i)=>i*50+40)
.text(d=>d)
.on("mouseover", function(event, datum) {
if(datum == "Underline on mouse") {
d3.select(this).style("text-decoration","underline");
}
})
.on("mouseout", function(event,datum) {
d3.select(this).style("text-decoration","none");
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>