這是鍵功能,第二個參數selection.data的目的:它可以讓你通過控制數據被綁定到哪個元素保持object constancy。例如,假設你有對象的數組代表水果:
var fruits = [
{name: "orange", value: 200},
{name: "apple", value: 124},
{name: "banana", value: 32}
];
當你第一次創建的元素,你並不需要的關鍵功能,因爲沒有任何現有的元素,所以你可以使用標準的全選,數據輸入,追加模式:
var div = d3.select("body").selectAll(".fruit")
.data(fruits)
.enter().append("div")
.attr("class", "fruit")
.text(function(d) { return d.name + ": " + d.value; });
這種操作的結果是:
<body>
<div class="fruit">orange: 200</div>
<div class="fruit">apple: 124</div>
<div class="fruit">banana: 32</div>
</body>
但是,現在讓我們假設你的數據的變化,並且要更新到refle新數據。這一新數據可能會以不同的順序,並且一些元素可以添加或刪除:
var fruits2 = [
{name: "apple", value: 124},
{name: "lemon", value: 17},
{name: "banana", value: 32},
{name: "strawberry", value: 1465}
];
蘋果和香蕉分別在原始數據,所以我們想留住他們。這被稱爲更新選擇。草莓和檸檬是新的;這是輸入的選擇。最後橘子走開了,形成了退出的選擇。
使用引用數據的name
屬性的鍵函數,我們可以按照預期將新數據分配給舊元素。然後,我們可以創建進入水果和刪除退出的水果:
var div = d3.select("body").selectAll(".fruit")
.data(fruits2, function(d) { return d.name; });
div.enter().append("div")
.attr("class", "fruit")
.text(function(d) { return d.name + ": " + d.value; });
div.exit().remove();
這就是所謂的general update pattern。 (你可有周圍做這個的第一次;它的全選,數據輸入,追加模式的更一般的形式)的結果是:
<body>
<div class="fruit">apple: 124</div>
<div class="fruit">banana: 32</div>
<div class="fruit">lemon: 17</div>
<div class="fruit">strawberry: 1465</div>
</body>
雖然選擇div
順序的數據相匹配fruit2
,DOM中的順序不是而是,因爲輸入元素被添加到主體的末尾。 (選擇。追加沒有任何花哨的邏輯來保證排序;它只是將新元素添加到父項的最後)。使用SVG時,我們通常不關心DOM元素的順序,因爲所有元素都是絕對定位的。如果您做一下順序護理,你可以使用selection.order進入後修復:
div.order(); // make the DOM element order match the selection
而且,在這個例子中,我們不需要做出更新選擇的任何變化,因爲這些值對於蘋果和香蕉沒有改變。如果更新數據也發生變化,您可以直接調用selection.attr和selection.text來調用上面的selection.data調用。
謝謝邁克!!!! – ehsan
THx的答案。我在兩個準相同的情況下使用selection.order(),一次它工作,一次它不。選擇的順序究竟是什麼?它取決於給數據功能的關鍵嗎? – JulienFr
我想答案是基於「[enter.append有一個方便的副作用:它用更新選擇中的新元素替換了輸入選擇中新創建的元素。因此,在enter.append之後,更新選擇是修改爲包含輸入和更新元素。](https://bost.ocks.org/mike/selection/#enter-update)「。但是,我的[測試](https://gist.github.com/an0/a924bf0d25e43d71584402dff6e28344)似乎並非如此。更新選擇仍然只包含enter.append後的更新。必須在'update'和'enter'的'merge'上調用'order'使其工作。爲什麼? – an0