Update、Enter、Exit 是 D3 中三個非常重要的概念,它處理的是當選擇集和數(shù)據(jù)的數(shù)量關系不確定的情況。
http://wiki.jikexueyuan.com/project/d3wiki/images/enterexit-1.png" alt="選擇集與數(shù)據(jù)" />
前幾章里,反復出現(xiàn)了形如以下的代碼。
svg.selectAll("rect") //選擇svg內(nèi)所有的矩形
.data(dataset) //綁定數(shù)組
.enter() //指定選擇集的enter部分
.append("rect") //添加足夠數(shù)量的矩形元素
前面提到,這段代碼使用的情況是當以下情況出現(xiàn)的時候:
有數(shù)據(jù),而沒有足夠圖形元素的時候,使用此方法可以添加足夠的元素。
當時并沒有深究這段代碼是什么意思,本章將對此進行講解。但是,由于此問題相對復雜,本章只進行最初步的介紹。
假設,在 body 中有三個 p 元素,有一數(shù)組 [3, 6, 9],則可以將數(shù)組中的每一項分別與一個 p 元素綁定在一起。但是,有一個問題:當數(shù)組的長度與元素數(shù)量不一致(數(shù)組長度 > 元素數(shù)量 or 數(shù)組長度 < 元素數(shù)量)時呢?這時候就需要理解 Update、Enter、Exit 的概念。
如果數(shù)組為 [3, 6, 9, 12, 15],將此數(shù)組綁定到三個 p 元素的選擇集上。可以想象,會有兩個數(shù)據(jù)沒有元素與之對應,這時候 D3 會建立兩個空的元素與數(shù)據(jù)對應,這一部分就稱為 Enter。而有元素與數(shù)據(jù)對應的部分稱為 Update。如果數(shù)組為 [3],則會有兩個元素沒有數(shù)據(jù)綁定,那么沒有數(shù)據(jù)綁定的部分被稱為 Exit。示意圖如下所示。
http://wiki.jikexueyuan.com/project/d3wiki/images/enterexit-2.png" alt="update,enter,exit" />
看到這,我想大家能體會到為什么本節(jié)最開始處的代碼能夠給 SVG 內(nèi)添加足夠數(shù)量的元素了吧。它的意思其實是:
此時 SVG 里沒有 rect 元素,即元素數(shù)量為 0。有一數(shù)組 dataset,將數(shù)組與元素數(shù)量為 0 的選擇集綁定后,選擇其 Enter 部分(請仔細看上圖),然后添加(append)元素,也就是添加足夠的元素,使得每一個數(shù)據(jù)都有元素與之對應。
當對應的元素不足時 ( 綁定數(shù)據(jù)數(shù)量 > 對應元素 ),需要添加元素(append)。
現(xiàn)在 body 中有三個 p 元素,要綁定一個長度大于 3 的數(shù)組到 p 的選擇集上,然后分別處理 update 和 enter 兩部分。
var dataset = [ 3 , 6 , 9 , 12 , 15 ];
//選擇body中的p元素
var p = d3.select("body").selectAll("p");
//獲取update部分
var update = p.data(dataset);
//獲取enter部分
var enter = update.enter();
//update部分的處理:更新屬性值
update.text(function(d){
return "update " + d;
});
//enter部分的處理:添加元素后賦予屬性值
enter.append("p")
.text(function(d){
return "enter " + d;
});
結果如下圖,update 部分和 enter 部分被綁定的數(shù)據(jù)很清晰地表示了出來。
http://wiki.jikexueyuan.com/project/d3wiki/images/enterexit-3.png" alt="update和enter" />
請大家記住:
當對應的元素過多時 ( 綁定數(shù)據(jù)數(shù)量 < 對應元素 ),需要刪掉多余的元素。
現(xiàn)在 body 中有三個 p 元素,要綁定一個長度小于 3 的數(shù)組到 p 的選擇集上,然后分別處理 update 和 exit 兩部分。
var dataset = [ 3 ];
//選擇body中的p元素
var p = d3.select("body").selectAll("p");
//獲取update部分
var update = p.data(dataset);
//獲取exit部分
var exit = update.exit();
//update部分的處理:更新屬性值
update.text(function(d){
return "update " + d;
});
//exit部分的處理:修改p元素的屬性
exit.text(function(d){
return "exit";
});
//exit部分的處理通常是刪除元素
// exit.remove();
結果如下,請大家區(qū)分好 update 部分和 exit 部分。這里為了表明哪一部分是 exit,并沒有刪除掉多余的元素,但實際上 exit 部分的絕大部分操作是刪除。
http://wiki.jikexueyuan.com/project/d3wiki/images/enterexit-4.png" alt="update和exit" />
請大家記住:
下載地址:rm70.zip