我有一个折线图,正尝试将HTML添加到图例的鼠标悬停/工具提示上。我想遍历数组(full_names),以便在第一条图例行的工具提示中显示“ full_names [0]”,在第二条图例行的工具提示中显示“ full_names [1]”,等等。当前,它们都显示“ full_names [0 ]”。为什么我的full_names无法正确循环?
id_list也是我循环遍历的数组,以便顺序分配id。
我的传说:
var lineLegend = svg.selectAll(".lineLegend").data(id_list)
.enter().append("g")
.attr("class", "lineLegend")
.attr("id", function (d, i) { return id_list[i % id_list.length]
})
.attr("transform", function (d, i) {
return "translate(" + width + "," + (i * 20) + ")";
})
.on("click", function (id) {
var this_chart = d3.select("#temperature_graph")
var liney = this_chart.select("#" + id)
var alldots = this_chart.selectAll("." + id)
var isActive = liney.classed("active");
var dotsActive = alldots.classed("active")
console.log(liney)
liney.classed("active", !isActive);
alldots.classed("active", !dotsActive)
})
.on("mouseover", function (i) {
div.transition()
.duration(100)
.style("opacity", .9);
我想在这里遍历数组(全名):
div.html( function (d, i) { return full_names[i % full_names.length]})
.style('color', '#404040')
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
其余:
.on("mouseout", function (d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
lineLegend.append("text").text(function (d) {
return d;}).attr("transform",
"translate(-94,15)").style("font-family", "Sans-
Serif").style('fill', '#5a5a5a'); //align texts with boxes
lineLegend.append("rect")
.attr("fill", function (d, i) { return colors[i %
colors.length] })
.attr("width", 12).attr("height", 10).attr("transform",
"translate(-32,4)").attr("rx", "3");
我认为我的阵列可能存在范围问题?如图所示,我可以正确遍历id_list,而不是full_names。这两个变量都在同一位置创建。那是因为id_list包含在我的var linelegend中吗?
非常感谢!!
答案 0 :(得分:2)
这里的问题是这样的:i
匿名函数中的html()
指向div
的索引,它将始终为0。取而代之的是,您想要获取您将鼠标悬停在lineLegend
的索引上。
这里有一些简短的例子。现在,您正在执行此操作:
lineLegend.on("mouseover", function(d,i){
tooltip.html(function(d,i){
//here, 'i' is the index of the 'tooltip', always 0.
});
});
如您所见,外部匿名函数中的索引与内部匿名函数中的索引不同。
应该是:
lineLegend.on("mouseover", function(d,i){
tooltip.html(function(){
//here, 'i' is the index of the 'lineLegend'.
});
});
或者,如果您想在html()
匿名函数中使用参数,请给它们指定其他名称:
应该是:
lineLegend.on("mouseover", function(d,i){
tooltip.html(function(e,j){//no 'i' here
//here, 'i' is the 'lineLegend' index and 'j' the tooltip index
});
});
这是一些演示。首先,使用错误的i
,您可以看到“工具提示”始终显示name1
:
var fullNames = ["name1", "name2", "name3"];
var tooltip = d3.select("#tooltip");
var p = d3.select("body")
.selectAll(null)
.data(["foo", "bar", "baz"])
.enter()
.append("p")
.text(String);
p.on("mouseover", function(d, i) {
tooltip.html(function(d, i) {
return fullNames[i]
})
})
#tooltip {
width: 100%;
background-color: wheat;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="tooltip">Tooltip</div>
现在使用相同的代码,引用正确的i
:
var fullNames = ["name1", "name2", "name3"];
var tooltip = d3.select("#tooltip");
var p = d3.select("body")
.selectAll(null)
.data(["foo", "bar", "baz"])
.enter()
.append("p")
.text(String);
p.on("mouseover", function(d, i) {
tooltip.html(function() {
return fullNames[i]
})
})
#tooltip {
width: 100%;
background-color: wheat;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="tooltip">Tooltip</div>
最后,一个建议:不要做您想做的事(使用元素的索引来获取另一个数组中的值),这不是惯用的D3。只需绑定数据。这样一来,事情就很清楚了,不会意外中断。