javascript - D3 - 将事件添加到酒吧

标签 javascript events d3.js

我正在尝试向图表中的条形图添加一个事件。我尝试了下面这个函数,但是使用这个函数,无论我点击哪个栏,它总是返回数组中的最后一个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);

这将返回 truefalse,正如它应该的那样。我认为这与异步有关的另一个原因。

我的基本问题是; 我怎样才能在这个栏上创建一个点击事件来返回正确的key

最佳答案

首先:这不是在 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>

现在再一个,使用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/

相关文章:

c# - 为什么在我的新类(class)中创建事件时出现错误?

jquery - d3js饼图的响应线标签

javascript - Lodash forEach 关联数组

javascript - Window.Print() 在 FF3 中不起作用

javascript - 如何通过异步函数设置 react 父组件状态,然后将此状态作为 Prop 传递给子组件?

c# - 从封装类传递事件

objective-c - 如何在macOS的非主线程上发生事件循环?

JavaScript 运行时错误 : unable to get property 'replace' of undefined or null reference

javascript 将对象转换为数组

javascript - 用 x,y,x1,y1,x2,y2,z 冲撞 d3js