學習一項新技術,首先要搞清楚它的基本設計思路,有了這個宏觀的技術架構,使用該技術起來,就會駕輕就熟了。不然,就會不知道如何下手,即便看到人家的例子程序,可能也不知其因此然。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樹狀圖異步按需加載數據,裏面的樹狀圖,點擊節點會有展開和收縮的效果,這個時候三者都會參與實際的邏輯處理。
當對應的元素不足時 ( 綁定數據數量 > 對應元素 ),須要添加元素(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 });
當對應的元素過多時 ( 綁定數據數量 < 對應元素 ),須要刪掉多餘的元素。
如今 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();
到此, 入門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>