我在d3中获得了堆叠条,需要向其添加工具提示。我很难弄清楚鼠标在哪个栏中,我该如何确定鼠标在哪个栏中?
group.enter().append("g")
.classed("layer", true)
.attr("fill", d => z(d.key))
.on("mouseover", function(d) {
var num = d.key == "xkey" ? d[4][1] : d[4][1] - d[4][0]
tip.html("<p>" + d.key + " " + num + "</p>")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px")
.style("visibility", "visible")
})
.on("mouseout", function(d) {
tip.style("visibility", "hidden")
});
现在我只是硬编码以显示最后一个小节的数据。也许我可以玩xScale和事件的x位置?还是这不是D3的方法?
建议您在bars
上触发事件,而不是在组上触发鼠标悬停事件。原因是您在组上的data
绑定对于男性和女性是堆叠的,因此无法为您提供小节类型,即Relations
。但是,在bars
中,如果您将鼠标悬停功能中的console.log(d)
,则可以清楚地看到相应的d.data.Relations
。
但是,现在代替单个数字,您将得到一个数组,例如[0,70]
当您将鼠标悬停在女性上时,[60,130]
当您将鼠标悬停在男性上时以获取2002年和“其他” Relations
的数据。该数组的工作方式是第一个值为当前值,而第二个值为总计。我们可以将此值与d.data
中的值进行比较,以评估它是针对性别还是男性。因此,如果d[1]
等于numF
,即+d.data.Female
的值,则它是女性,但如果d[1]
等于numF+numM
,即(+d.data.Male) + (+d.data.Female)
的值之和,则它是雄性,因为在这种情况下,由于keys
的顺序为["Female","Male"]
,因此雄性堆叠在雌性的顶部。
bars.enter().append("rect")
.attr("width", xScale.bandwidth())
.merge(bars)
.on("mouseover", function(d) {
console.log(d);
// get number of females
let numF = +d.data.Female;
// get number of males
let numM = +d.data.Male;
// get the Relations
let Relations = d.data.Relations;
// Evaluate the gender by comparing the mouseover data value for d[1] to the numF for 'Female'
// or
// numF+numM
let gender,value;
if (d[1] === numF){
gender = 'Female';
value = numF;
}else if (d[1] === numF+numM) {
gender = 'Male';
value = numM;
}
//produce the tooltip
tip.html("<p>" +Relations + "<br>" + gender + ": " + value + "</p>")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px")
.style("visibility", "visible");
})
.on("mouseout", function(d) {
tip.style("visibility", "hidden");
})
.transition().duration(speed)
.attr("x", d => xScale(d.data.Relations))
.attr("y", d => yScale(d[1]))
.attr("height", d => yScale(d[0]) - yScale(d[1]));
[注意,当我在Relations
和Gender: number
之间添加a时,必须更改工具提示的css,使其稍高一些。
P.S。为了清晰起见,我还清理了一些代码,例如分号,并将<svg>
和工具提示<div>
放在<body>
内,而不是在其外。