我试图从csv文件中获得的一些数据创建坐标图。 X / Y轴的转换工作得很好,圆圈(或更确切地说是圆点)被绘制,但是鼠标悬停工具提示总是显示最后的值(或者更确切地说,即使工具提示应该在我的数组中,最后的值+1也是如此用数组的当前值设置。
经度和海拔高度是我的两个数组名称
var svgContainer = d3.select("body").append("svg")
.attr("width", 700)
.attr("height", 250)
.style("border", "1px solid black");
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
for (i = 0; i < longitude.length; i++) {
var circleSelection = svgContainer.append("circle")
.attr("cx", longitude[i])
.attr("cy", altitude[i])
.attr("r", 2)
.style("fill", "purple")
.on("mouseover", function(d) {
div.transition()
.duration(200)
.style("opacity", .9);
div .html("X: " + longitude[i] + " Y: " + altitude[i])
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
}
这里有css,但我怀疑在这里可以找到问题
<style>
div.tooltip {
position: absolute;
text-align: center;
width: 60px;
height: 28px;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
非常感谢每一条线索
答案 0 :(得分:1)
作为一般规则:不要使用循环来附加D3代码中的元素。不仅这不是惯用的D3,更重要的是,事情会破裂(正如你现在所看到的那样)。
在此之前,这里解释了为什么所有值都相同:JavaScript closure inside loops – simple practical example
让我们看看这个,将鼠标悬停在任何一个圈子上:
var data = ["foo", "bar", "baz"];
var svg = d3.select("svg");
for (var i = 0; i < data.length; i++) {
svg.append("circle")
.attr("cy", 75)
.attr("cx", 50 + i * 100)
.attr("r", 20)
.attr("fill", "teal")
.on("mouseover", function() {
console.log(data[i - 1])
})
}
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
&#13;
使用let
:
var data = ["foo", "bar", "baz"];
var svg = d3.select("svg");
for (let i = 0; i < data.length; i++) {
svg.append("circle")
.attr("cy", 75)
.attr("cx", 50 + i * 100)
.attr("r", 20)
.attr("fill", "teal")
.on("mouseover", function() {
console.log(data[i])
})
}
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
&#13;
但是,即使使用let
提供了正确的结果, 也不是一个好的解决方案,因为您没有绑定任何数据。
最佳解决方案是:使用D3&#34;输入&#34;选择,将数据绑定到元素:
var data = ["foo", "bar", "baz"];
var svg = d3.select("svg");
svg.selectAll(null)
.data(data)
.enter()
.append("circle")
.attr("cy", 75)
.attr("cx", function(d, i) {
return 50 + i * 100
})
.attr("r", 20)
.attr("fill", "teal")
.on("mouseover", function(d) {
console.log(d)
})
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
&#13;