将当前参数传递给循环功能

时间:2019-03-20 07:32:40

标签: javascript d3.js

我正在使用D3打印多个矩形。现在,我希望rect可以允许用户单击它并激活某些功能。

例如,有3个矩形,"Tom""Mary""Ben"。当用户单击不同的矩形时,它将传递当前值。就像当我单击"Tom"时,它将通过"Tom"来调用该函数。

但是,我发现打印完矩形后,无论我单击哪个矩形,它们都将返回数据集的最小值。

在我的示例中,即使我单击"Tom""Mary",都返回"Ben"

for (var i = 0; i < ward_set.length; i++) {
  var ward_id = ward_set[i];
  legend.append("rect")
    .attr("x", legend_x + 180 + 100 * n)
    .attr("y", legend_y)
    .attr("width", 18)
    .attr("height", 18)
    .attr("fill", colors[count])
    .attr("class", "legend" + ward_set[i])
    .on("click", function() {
      console.log(ward_id);
    });
}

1 个答案:

答案 0 :(得分:1)

您的问题完美地说明了一个非常重要的原则,如果您愿意,在编写D3代码时应遵循以下经验法则:请勿使用循环来添加元素。请使用输入/更新/退出模式。

使用循环(public void function(List<Activities> listOfActivities) { for (int i = 0; i < listOfActivities.size(); i++) { Activities activities = listOfActivities.get(i); if (activities instanceOf IndoorGames) { Outdoorgames games = new OutdoorGames(); games.setName(activities.getName()); listOfActivities.set(i,games); // this will replace the // IndoorGames instance with // the new Outdoorgames // instance break; } } } forwhile等)时,不仅会发生数据绑定,而且还会遇到这种情况您描述的奇怪结果(总是获取最后一个值),在这里进行了解释:JavaScript closure inside loops – simple practical example

因此,使用D3惯用回车选择的解决方案将是:

forEach

然后,在const data = ["Tom", "Mary", "Ben"]; const svg = d3.select("svg"); const rects = svg.selectAll(null) .data(data) .enter() .append("rect") //etc... 侦听器中,您将得到第一个参数,即数据:

click

这是一个演示:

.on("click", function(d) {
    console.log(d)
})
const data = ["Tom", "Mary", "Ben"];

const svg = d3.select("svg");

const rects = svg.selectAll(null)
  .data(data)
  .enter()
  .append("rect")
  .attr("width", 50)
  .attr("height", 150)
  .attr("x", (_, i) => i * 60)
  .on("click", function(d) {
    console.log(d)
  })