我正在尝试向图表中的条形图添加一个事件。我尝试了下面这个函数
,但是使用这个函数,无论我点击哪个栏,它总是返回数组
中的最后一个key
>.
我的猜测是这与异步有关,因为它返回最后一个key
值。
for (var key in data) {
bar = bars.append('rect')
.attr('class', 'bar')
.attr('x', (dimensions.width / data.length) * currentId + 41)
.attr('y', 100 - data[key] + 10).attr('height', data[key])
.attr('width', dimensions.width / data.length)
.attr('fill', '#4682B4')
.on('click', (bar = key) => {
console.log(key) //Always returns the same key
});
currentId++;
}
我还尝试复制数组包含的键之一并制作如下 if 语句:
console.log(key === 1 ? true : false);
这将返回 true
和 false
,正如它应该的那样。我认为这与异步有关的另一个原因。
我的基本问题是;
我怎样才能在这个栏上创建一个点击事件来返回正确的key
最佳答案
首先:这不是在 D3 中添加事件的惯用方式。作为一般规则,当您编写 D3 代码时,通常不需要任何类型的循环。当然,我们有时会使用循环,但只是在非常具体的情况下并解决非常具体的问题。因此,D3 代码中 98.57% 的循环都是不必要的(来源:FakeData Inc.),无论是 for...in
、for...of
或一个简单的 for
循环。
话虽这么说,让我们看看这里发生了什么。
您真正的问题与 D3 或异步代码无关。实际上,您的问题可以通过这个优秀的答案来解释:JavaScript closure inside loops – simple practical example (不过,我会避免将其作为重复项关闭)。
读完上面链接中的答案后,我们来看两个演示。
第一个,使用var
。请点击圆圈:
var data = [{
name: "foo",
value: 1
}, {
name: "bar",
value: 2
}, {
name: "baz",
value: 3
}];
var svg = d3.select("svg");
for (var key in data) {
var foo = key;//look at the var here
circle = svg.append("circle")
.attr("cy", 50)
.attr("fill", "teal")
.attr("cx", d=> 20 + key*50)
.attr("r", 15)
.on('click', () => {
console.log(foo)
});
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
现在再一个,使用let
,请点击圆圈并比较结果:
var data = [{
name: "foo",
value: 1
}, {
name: "bar",
value: 2
}, {
name: "baz",
value: 3
}];
var svg = d3.select("svg");
for (var key in data) {
let foo = key;//look at the let here
circle = svg.append("circle")
.attr("cy", 50)
.attr("fill", "teal")
.attr("cx", d=> 20 + key*50)
.attr("r", 15)
.on('click', () => {
console.log(foo)
});
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
关于javascript - D3 - 将事件添加到酒吧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43629106/