D3的基本設計思路

學習一項新技術,首先要搞清楚它的基本設計思路,有了這個宏觀的技術架構,使用該技術起來,就會駕輕就熟了。不然,就會不知道如何下手,即便看到人家的例子程序,可能也不知其因此然。html

 

下面,就簡單的結合本身研究的官方文檔,對D3的使用,給其基本設計思路,作一個簡單的描述:node

 

在html文件中加載完官方的js插件d3.v3.min.js後:算法

1.  設計畫布(這裏主要基於SVG介紹,固然,畫布其實還有Canvas)。數組

     a. 主要包括SVG的大小,含有width,以及height。數據結構

     b. 經過d3全局對象,構建svg對象。架構

 

2. 建立視圖(D3支持的視圖不少)app

 1 [[bundle|捆綁佈局]] - 對邊使用Holten 層次捆綁算法。
 2 [[chord|弦佈局]] - 從關係矩陣生成一個弦圖。
 3 [[cluster|簇佈局]] - 將實體彙集成樹狀圖。
 4 [[force|力佈局]] - 模擬物理力排放相連節點的位置。
 5 [[hierarchy|層次佈局]] - 這是個抽象佈局,可派生一個定製的層次佈局。
 6 [[histogram|直方圖佈局]] - 使用量化的箱計算數據的分佈。
 7 [[pack|包佈局]] - 用遞歸的圓形包裝生成一個層次佈局。
 8 [[partition|分區佈局]] - 遞歸地將節點樹分割爲旭日狀或者冰柱狀。
 9 [[pie|餅佈局]] - 計算餅圖或圓環圖中弧的開始和結束角度。
10 [[stack|堆疊佈局]] - 計算堆疊圖或者面積圖的基線。
11 [[tree|樹佈局]] - 整齊地排列樹節點。注意簇佈局不是整齊的。
12 [[treemap|矩形樹佈局]] - 使用空間遞歸分區算法展現樹的節點。

   例如:框架

          var tree = d3.layout.tree();異步

 

3. 數據綁定svg

    其實,這一步作的事情,就是一個視圖與數據的結合,視圖將數據轉化爲該視圖內定的數據結構,重點是添加了一些D3功能相關的輔助參數或者變量。 例如上例中的樹視圖,數據綁定後過程以下:

1 var nodes = tree.nodes(root).reverse(),
2 var links = tree.links(nodes);

這個綁定,也能夠說是數據轉化,以後,nodes對象中不只含有root這個原始數據(用戶提供的輸入數據),還含有D3系統須要的輔助參數,好比parent,depth等。

 

4.  視圖數據結合

     這一步,其實最能體現D3的設計思想,這一步涵蓋的內容最爲豐富,可是很少講,重點介紹D3的特點操做enter,update,exit。

     a. 獲取新的選擇器(SVG灌入綁定數據後的新對象)

         例如: 

               var node = svg.selectAll("g.node").data(nodes, function(d) { return d.id || (d.id = ++i); });

     b. enter/update/exit

        這三個概念是什麼含義呢?

        若是數組爲 [3, 6, 9, 12, 15],將此數組綁定到三個 p 元素的選擇集上。能夠想象,會有兩個數據沒有元素與之對應,這時候 D3 會創建兩個空的元素與數據對應,這一部分就稱爲 Enter。而有元素與數據對應的部分稱爲 Update。若是數組爲 [3],則會有兩個元素沒有數據綁定,那麼沒有數據綁定的部分被稱爲 Exit。

        例以下圖:

        

        對於圖形存在交互操做的情景,enter,update,以及exit都會用獲得,例如我上一篇博客D3樹狀圖異步按需加載數據裏面的樹狀圖,點擊節點會有展開和收縮的效果,這個時候三者都會參與實際的邏輯處理。

        

     Update 和 Enter 的使用

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

        如今 body 中有三個 p 元素,要綁定一個長度大於 3 的數組到 p 的選擇集上,而後分別處理 update 和 enter 兩部分。

 1 var dataset = [ 3 , 6 , 9 , 12 , 15 ];
 2 
 3 //選擇body中的p元素
 4 var p = d3.select("body").selectAll("p");
 5 
 6 //獲取update部分
 7 var update = p.data(dataset);
 8 
 9 //獲取enter部分
10 var enter = update.enter();
11 
12 //update部分的處理:更新屬性值
13 update.text(function(d){
14     return "update " + d;
15 });
16 
17 //enter部分的處理:添加元素後賦予屬性值
18 enter.append("p")
19     .text(function(d){
20         return "enter " + d;
21     });
  • update 部分的處理辦法通常是:更新屬性值
  • enter 部分的處理辦法通常是:添加元素後,賦予屬性值

     

    Update 和 Exit 的使用

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

      如今 body 中有三個 p 元素,要綁定一個長度小於 3 的數組到 p 的選擇集上,而後分別處理 update 和 exit 兩部分。

      

 1 var dataset = [ 3 ];
 2 
 3 //選擇body中的p元素
 4 var p = d3.select("body").selectAll("p");
 5 
 6 //獲取update部分
 7 var update = p.data(dataset);
 8 
 9 //獲取exit部分
10 var exit = update.exit();
11 
12 //update部分的處理:更新屬性值
13 update.text(function(d){
14     return "update " + d;
15 });
16 
17 //exit部分的處理:修改p元素的屬性
18 exit.text(function(d){
19         return "exit";
20     });
21 
22 //exit部分的處理一般是刪除元素
23 // exit.remove();
  • exit 部分的處理辦法通常是:刪除元素(remove)

 

     到此, 入門D3,瞭解這個基本的框架,再去細讀API文檔或者教程,相對會容易些!

 

     最後,附帶一個簡單的例子,繪製環狀圖(顯示資源佔用比例的場景,仍是頗有使用價值的):

     

 1 <html>  
 2   <head>  
 3         <meta charset="utf-8">  
 4         <title>環裝圖</title>  
 5   </head> 
 6 
 7 <style>
 8 
 9 
10 </style>
11     <body>  
12         <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>  
13         <script>
14         
15         var width = 400;
16         var height = 400;
17         var dataset = [ 30 , 10 , 43 , 55 , 13 , 11, 100, 99];
18         
19         var svg = d3.select("body")
20                     .append("svg")
21                     .attr("width", width)
22                     .attr("height", height);
23         
24         var pie = d3.layout.pie();
25 
26         var piedata = pie(dataset);
27         
28         var outerRadius = 150;    //外半徑
29         var innerRadius = 100;    //內半徑,爲100則中間沒有空白
30 
31         var arc = d3.svg.arc()    //弧生成器
32                     .innerRadius(innerRadius)    //設置內半徑
33                     .outerRadius(outerRadius);    //設置外半徑
34         
35         var color = d3.scale.category20c();
36         
37         var arcs = svg.selectAll("g")
38                       .data(piedata)
39                       .enter()
40                       .append("g")
41                       .attr("transform","translate("+ (width/2) +","+ (width/2) +")");
42                       
43         arcs.append("path")
44             .attr("fill",function(d,i){
45                 return color(i);
46             })
47             .attr("d",function(d){
48                 return arc(d);
49             });
50         
51         arcs.append("text")
52             .attr("transform",function(d){
53                 return "translate(" + arc.centroid(d) + ")";
54             })
55             .attr("text-anchor","middle")
56             .text(function(d){
57                 return d.data;
58             });          
59         </script>  
60         
61     </body>  
62 </html>  

相關文章
相關標籤/搜索