2017-08-03 30 views
1

根據示例here,我在d3 v3中創建了一個sunburst。我無法理解爲什麼在以下情況下attrTween()不起作用。D3:attrTween無法正常工作

path.transition() 
    .duration(750) 
    .attrTween("d", function(d) { 
    var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]), 
     yd = d3.interpolate(y.domain(), [d.y, 1]), 
     yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]); 
    return function(d, i) { 
     var p = i 
      ? function(t) { return arc(d); } 
      : function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); }; 
     return p 
    }; 
    }) 

單擊任何弧線時出現以下錯誤。

Error: attribute d: Expected moveto path command ('M' or 'm'), "function (t) { x…".

然而,定義如下,並呼籲像這樣.attrTween("d", arcTween(d))工作正常功能arcTween()

function arcTween(d) { 
    var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]), 
     yd = d3.interpolate(y.domain(), [d.y, 1]), 
     yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]); 
    return function(d, i) { 
    return i 
     ? function(t) { return arc(d); } 
     : function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t));return arc(d); }; 
}; 
} 

回答

2

工作代碼使用函數聲明來定義function arcTween(d) { }。在.attrTween("d", arcTween(d))中使用此函數將實際執行該函數從封閉函數click(d)傳遞參數d,該函數是綁定到用戶單擊的元素的數據。此調用用於捕獲/關閉內插器xdydyr中的值d,該值隨後用於返回的內部函數。返回的函數是由.attrTween()執行的函數,用於返回用於轉換的插補器。

在你的代碼中,當試圖內聯函數聲明時,你錯過了上面提到的對外函數的調用。因此,由於函數的嵌套太深,最終導致無效的返回值。

但是,有一個簡單的補救措施可以使代碼正常工作:只需在內聯函數後添加一個(d)即可像前代碼那樣執行代碼。

function click(d) {    // This d is what needs to be captured 

    path.transition() 
    .duration(750) 
    .attrTween("d", function(d) { 
     // var...    // This is where the outer d is closed over/captured 
     return function(d, i) { // This is another d not to be confused with the outer one 
     // ... 
     }; 
    }(d))      // This will execute the function passing in click's d 

} 

看看更新的Plunk的工作演示。