D3.js系列——動態效果和Update、Enter、Exit的理解


一、動態效果

  D3 支持制作動態的圖表。有時候,圖表的變化需要緩慢的發生,以便於讓用戶看清楚變化的過程,也能給用戶不小的友好感。

1、什么是動態效果

  前面制作的圖表是一蹴而就地出現,然后繪制完成后不再發生變化的,這是靜態的圖表。

  動態的圖表,是指圖表在某一時間段會發生某種變化,可能是形狀、顏色、位置等,而且用戶是可以看到變化的過程的。例如,有一個圓,圓心為 (100, 100)。現在我們希望圓的 x 坐標從 100 移到 300,並且移動過程在 2 秒的時間內發生。這種時候就需要用到動態效果,在 D3 里我們稱之為過渡(transition)

2、實現動態的方法

  D3 提供了 4 個方法用於實現圖形的過渡:從狀態 A 變為狀態 B。

transition()

  啟動過渡效果。其前后是圖形變化前后的狀態(形狀、位置、顏色等等),例如:

.attr("fill","red")         //初始顏色為紅色
.transition()               //啟動過渡
.attr("fill","steelblue")   //終止顏色為鐵藍色

  D3 會自動對兩種顏色(紅色和鐵藍色)之間的顏色值(RGB值)進行插值計算,得到過渡用的顏色值。我們無需知道中間是怎么計算的,只需要享受結果即可。

duration()

  指定過渡的持續時間,單位為毫秒。如 duration(2000) ,指持續 2000 毫秒,即 2 秒。

ease()

  指定過渡的方式,常用的有:

    linear:普通的線性變化

    circle:慢慢地到達變換的最終狀態

    elastic:帶有彈跳的到達最終狀態

    bounce:在最終狀態處彈跳幾次

  調用時,格式形如: ease(“bounce”)。

delay()

  指定延遲的時間,表示一定時間后才開始轉變,單位同樣為毫秒。此函數可以對整體指定延遲,也可以對個別指定延遲。

  例如,對整體指定時:

.transition() .duration(1000) .delay(500)

  如此,圖形整體在延遲 500 毫秒后發生變化,變化的時長為 1000 毫秒。因此,過渡的總時長為1500毫秒。

  又如,對一個一個的圖形(圖形上綁定了數據)進行指定時:

.transition() .duration(1000) .delay(funtion(d,i){ return 200*i; })

  如此,假設有 10 個元素,那么第 1 個元素延遲 0 毫秒(因為 i = 0),第 2 個元素延遲 200 毫秒,第 3 個延遲 400 毫秒,依次類推….整個過渡的長度為 200 * 9 + 1000 = 2800 毫秒。

3、實現簡單的動態效果

    var width=400,height=400; var svg = d3.select("body").append("svg").attr("width",width).attr("height",height); var circle=svg.append("circle").attr("cx",100).attr("cy",100).attr("r",50).style("fill","green"); circle.transition() .ease("bounce") // 終點彈跳
        .duration(2000) //過渡時長2s
        .attr("cx",300) //圓心坐標從100變為300
        .attr("r",25)   //半徑變為25
        .style("fill","red") //顏色變紅色
        .delay(1000);   //延時1s執行

二、理解 Update、Enter、Exit

  Update、Enter、Exit 是 D3 中三個非常重要的概念,它處理的是當選擇集和數據的數量關系不確定的情況。

1、什么是 Update、Enter、Exit

  前幾章里,反復出現了形如以下的代碼。

svg.selectAll("rect")   //選擇svg內所有的矩形
    .data(dataset)      //綁定數組
    .enter()            //指定選擇集的enter部分
    .append("rect")     //添加足夠數量的矩形元素

  前面提到,這段代碼使用的情況是當以下情況出現的時候:有數據,而沒有足夠圖形元素的時候,使用此方法可以添加足夠的元素。當時並沒有深究這段代碼是什么意思,本章將對此進行講解。但是,由於此問題相對復雜,本章只進行最初步的介紹。

  假設,在 body 中有三個 p 元素,有一數組 [3, 6, 9],則可以將數組中的每一項分別與一個 p 元素綁定在一起。但是,有一個問題:當數組的長度與元素數量不一致(數組長度 > 元素數量 or 數組長度 < 元素數量)時呢?這時候就需要理解 Update、Enter、Exit 的概念。如果數組為 [3, 6, 9, 12, 15],將此數組綁定到三個 p 元素的選擇集上。可以想象,會有兩個數據沒有元素與之對應,這時候 D3 會建立兩個空的元素與數據對應,這一部分就稱為 Enter。而有元素與數據對應的部分稱為 Update。如果數組為 [3],則會有兩個元素沒有數據綁定,那么沒有數據綁定的部分被稱為 Exit。示意圖如下所示。

  看到這,我想大家能體會到為什么本節最開始處的代碼能夠給 SVG 內添加足夠數量的元素了吧。它的意思其實是:

  此時 SVG 里沒有 rect 元素,即元素數量為 0。有一數組 dataset,將數組元素數量為 0 的選擇集綁定后,選擇其 Enter 部分(請仔細看上圖),然后添加(append)元素,也就是添加足夠的元素,使得每一個數據都有元素與之對應。

2、Update 和 Enter 的使用

  當對應的元素不足時 ( 綁定數據數量 > 對應元素 ),需要添加元素(append)。

  現在 body 中有三個 p 元素,要綁定一個長度大於 3 的數組到 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 部分的處理辦法一般是:先添加元素后,再賦予屬性值

3、Update 和 Exit 的使用

  當對應的元素過多時 ( 綁定數據數量 < 對應元素 ),需要刪掉多余的元素。

  現在 body 中有三個 p 元素,要綁定一個長度小於 3 的數組到 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();

  請大家記住:

  exit 部分的處理辦法一般是:刪除元素(remove)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM