D3 - 将事件添加到栏中

时间:2017-04-26 08:43:14

标签: javascript events d3.js

我正在尝试向图表中的栏添加一个事件。我尝试了这个function,但是使用此功能,无论我点击哪个栏,它总是会返回key中的最后一个array

我的猜测是这与异步有关,因为它返回最后的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);

这将完全按照原样返回truefalse。我认为这与async有关的另一个原因。

我的基本问题是; 如何在此栏上点击活动,返回正确的key

1 个答案:

答案 0 :(得分:2)

在此之前:这是在D3中添加事件的惯用方式。作为一般规则,当您编写D3代码时,通常不需要任何类型的循环。当然,我们有时使用循环,但在非常特定的情况下,并解决非常具体的问题。因此,D3代码中找到的98.57%的循环是不必要的(来源:FakeData Inc.),无论是for...infor...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>
&#13;
&#13;
&#13;

现在另一个,使用let,请点击圈子并比较结果:

&#13;
&#13;
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)
    });
}
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
&#13;
&#13;
&#13;