2016-08-11 78 views
1

我很困惑爲什麼下面的簡單更新模式不起作用。據我所知,這遵循建議的General Update Pattern一般更新模式不能按預期與d3.selection一起工作

<script src="https://d3js.org/d3-selection.v1.min.js"></script> 
... 
    var dat = ["One","Two","Buckle my shoe"]; 
    var sel = d3.selectAll("p.test").data(dat); 
    sel.enter().append("p").classed("test", true); 
    sel.exit().remove(); 

    //update 1 ... doesn't work 
    sel.text(function(d) { return d;}) 

段落創建正常,但文本未設置。但是,如果我這樣做:

 //update 2 ... this works as expected 
    d3.selectAll("p.test").text(function(d) { return d;}); 

...一切工作正常。第一個版本一直在過去。

更新:我嘗試使用全D3庫...

<script src="https://d3js.org/d3.v4.min.js"></script> 

...和第一個版本再次工作。我需要比d3.selection更多嗎?爲了澄清,我過去的做法是定義一個單獨的更新函數,將選擇作爲參數。例如,function doUpdate(sel) { sel.text(...);}這適用於我期望數據元素在大小中幾乎沒有變化的情況,但內容中的許多變化。將選擇存儲爲變量並反覆運行更新之前運行良好。

+0

在d3.js版本4。進入(),並卸下襬臂這個工作好()是不夠的,你必須使用.merge()https://github.com/d3/d3-transition/blob/master/README.md#transition_merge這可能與你的update1不起作用有關。 ..如果你看看你提供的例子,它使用merge()。嘗試粘貼'.merge(text) .text(function(d){return d;});'在您的'.classed(「test」,true)之後'' – Tekill

+0

雖然這可能需要使用d3轉換使用.enter(),.exit(),.remove()和.merge()...所以你可能想嘗試包括。 – Tekill

+0

@Yourinium感謝您的意見。儘管我沒有使用轉換,並且我已經有了一個不需要添加額外腳本的解決方法。我查看了你發佈的鏈接,可以確認添加轉換,顏色,調度,簡化,內插和計時器腳本對問題沒有影響 - 這是值得的。 –

回答

3

因此,在研究發行說明之後,似乎這不會向後兼容,原因很多。首先,簡單的答案:

替換此:

sel.enter().append("p").classed("test", true); 
... 
sel.text(function(d) { return d;})  //update block 

與此:

var update = sel.enter().append("p").classed("test", true).merge(sel); 
... 
update.text(function(d) { return d;}) //update block 

其原因被描述in this article(感謝@mbostock),是空的選擇問題修復與v3。我最初錯過的一點是,輸入()塊需要先運行,以便合併()塊有填充選項可供使用。這意味着merge()調用必須在enter()塊鏈的末尾結束。

更改文件的格式有點隱藏,因爲很多示例都使用函數調用鏈。我習慣於將輸入/更新塊分割成單獨的變量。這有助於可讀性(通常),並且意味着我可以將輸入/更新操作排除在外以分離函數 - 這種方式具有更多可重用的代碼。

考慮到這一點

所以,這工作:

var enter = sel.enter(); 
var update = enter.merge(sel); //Nope! Not populated at this point. 
enter.append(...);    //too late! Update block uses an empty selection. 

var enter = sel.enter(); 
enter.append(...); 
var update = enter.merge(sel); //defined after block is populated 
+0

謝謝你的解釋。我浪費了大量的時間搜索「無法讀取未定義的屬性'setProperty'」和「無法讀取未定義的屬性'getPropertyValue'」。 – SubOne

相關問題