2017-01-01 43 views
1

另一個JavaScript初學者有一個關閉問題......但是,我一直在讀封閉綁定(most helpful)上的各種來源,但我仍然無法完全轉移到我的具體問題。關閉問題使用d3提示

爲了方便,我準備了minimal jsfiddle。我的問題是使用d3-tip與多個不同的渲染邏輯。在jsfiddle中,您可以在頂部和底部看到一個情節。當您將鼠標懸停在框上時,每個圖都應該生成自己的工具提示。但是,如您所見,第一個繪圖也使用第二個繪圖的工具提示回調。或者更一般:最後一個工具提示回調會覆蓋以前的回調。

該實現遵循一些標準的d3/d3-tip模式。 Basiscally我有多個繪圖功能是這樣的:

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反正。我的實際使用案例是具有完全不同的圖的頁面,因此,工具提示渲染不能(或不應該)統一。

回答

3

如果您不使用var聲明變量,它將變成全局變量。

所以,這是一個簡單的修復,這兩個函數裏面:

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

這裏是你的更新提琴:https://jsfiddle.net/wd08acg1/

+0

外賣:學習基礎知識_before_高級主題。添加一個問題,以避免我的評論再次被刪除:爲什麼它與普通的'tip.show'雖然工作?我猜是因爲在這種情況下'show'函數的'this'綁定了實際的'tip'對象,而在閉包的情況下,由於看到一個全局的JavaScript,javascript不會關閉任何東西。 – bluenote10

+0

我不是在追隨你的最後一個問題(「爲什麼它能夠和普通的tip.show一起工作?」),如果你澄清它,我會很感激。但是,請記住,您沒有將'this'傳遞給'tip.show()'(它不適用於箭頭函數),而是* datum *。 –

+0

我的意思是用'tip.show'本身替換箭頭函數([更新的小提琴](https://jsfiddle.net/vb3xfe5k/6/))。這就是爲什麼我首先感到困惑。 – bluenote10