使用d3提示关闭问题

时间:2017-01-01 12:25:50

标签: javascript d3.js

另一个带有闭包问题的javascript初学者......但是,我一直在阅读有关闭包绑定的各种来源(most helpful),但我仍然无法完全将其转移到我的具体问题。< / p>

为方便起见,我准备了minimal jsfiddle。我的问题是使用d3-tip多个不同的渲染逻辑。在jsfiddle中,您可以看到顶部和下面的情节。将鼠标悬停在框上时,每个绘图都应生成自己的工具提示。但是,正如您所看到的,第一个绘图也使用第二个绘图的工具提示回调。或者更一般:最后一个工具提示回调会覆盖以前的回调。

该实现遵循一些标准的d3 / d3-tip模式。基本上我有多个这样的绘图功能:

function somePlottingFunction(data, locator) {
   var svg = ... // append svg

   // define plot-specific tooltip logic
   function tipRenderer(d) {
     return "Renderer of plot 1: " + d;
   } 
   tip = d3.tip()
           .attr("class", "d3-tip")
           .html(tipRenderer);
   svg.call(tip);

   // and a .enter()
   svg.selectAll("rect")
      .data(data)
      .enter()
      .append("rect")
      // ... attr ...
      .on("mouseover", (d) => tip.show(d)) // <= issue here
      .on("mouseout", (d) => tip.hide(d));
}

仅使用.on("mouseover", tip.show)时,代码就可以工作。但是在我的实际代码中,我需要mouseover中的其他逻辑,这就是我需要一个包装闭包的原因。我的问题是:

  • 为什么闭包关闭了错误的tip变量?或者更确切地说:第二个绘图函数如何修改第一个函数的闭包绑定?
  • 体验javascript程序员如何解决这个问题?

注意:在jsfiddle中,两个绘图函数(和工具提示逻辑)几乎完全相同,以保持示例小,这表示无论如何都只使用相同的tipRenderer。我的实际用例是一个具有完全不同的图的页面,因此,工具提示呈现不能(或不应该)统一。

1 个答案:

答案 0 :(得分:3)

如果您不使用var声明变量,它就会变成全局变量。

所以,这是两个函数中的简单修复:

var tip = d3.tip()
    .attr("class", "d3-tip")
    .direction("s")
    .html(tipRenderer);

这是您更新的小提琴:https://jsfiddle.net/wd08acg1/