本章制作一個餅狀圖。在布局的應用中,最簡單的就是餅狀圖,通過本文你將對布局有一個初步了解。
http://wiki.jikexueyuan.com/project/d3wiki/images/pie-1.png" alt="餅狀圖" />
有如下數(shù)據(jù),需要可視化:
var dataset = [ 30 , 10 , 43 , 55 , 13 ];
這樣的值是不能直接繪圖的。例如繪制餅狀圖的一個部分,需要知道一段弧的起始角度和終止角度,這些值都不存在于數(shù)組 dataset 中。因此,需要用到布局,布局的作用就是:
計算出適合于作圖的數(shù)據(jù)。
這一個過程,在本教程中為了方便理解,筆者稱之為“數(shù)據(jù)轉(zhuǎn)換”。
定義一個布局,
var pie = d3.layout.pie();
返回值賦給變量 pie,此時 pie 可以當做函數(shù)使用。
var piedata = pie(dataset);
將數(shù)組 dataset 作為 pie() 的參數(shù),返回值給 piedata。如此一來,
piedata 就是轉(zhuǎn)換后的數(shù)據(jù)。
簡單吧,非常輕松就得到了。在控制臺輸出 piedata ,讓我們來看看數(shù)據(jù)轉(zhuǎn)換成什么了。
http://wiki.jikexueyuan.com/project/d3wiki/images/pie-2.png" alt="轉(zhuǎn)換后的數(shù)據(jù)" />
如上圖所示,5 個整數(shù)被轉(zhuǎn)換成了 5 個對象(Object) ,每個對象都有變量起始角度(startAngle)和終止角度(endAngle),還有原數(shù)據(jù)(屬性名稱為 data)。這些都是繪圖需要的數(shù)據(jù)。
千萬記?。?strong>布局要直接繪圖,而是為了得到繪圖所需的數(shù)據(jù)。
為了根據(jù)轉(zhuǎn)換后的數(shù)據(jù) piedata 來作圖,還需要一樣工具:生成器。
SVG 有一個元素,叫做路徑 path,是 SVG 中功能最強的元素,它可以表示其它任意的圖形。顧名思義,路徑元素就是通過定義一個段“路徑”,來繪制出各種圖形。但是,路徑是很難計算的,通過布局轉(zhuǎn)換后的數(shù)據(jù) piedata 仍然很難手動計算得到路徑值。為我們完成這項任務的,就是生成器。
這里要用到的叫做弧生成器,能夠生成弧的路徑,因為餅圖的每一部分都是一段弧。
var outerRadius = 150; //外半徑
var innerRadius = 0; //內(nèi)半徑,為0則中間沒有空白
var arc = d3.svg.arc() //弧生成器
.innerRadius(innerRadius) //設置內(nèi)半徑
.outerRadius(outerRadius); //設置外半徑
弧生成器返回的結果賦值給 arc。此時,arc 可以當做一個函數(shù)使用,把 piedata 作為參數(shù)傳入,即可得到路徑值。
接下來,可以在 SVG 中添加圖形元素了。先在 svg 里添加足夠數(shù)量(5個)個分組元素(g),每一個分組用于存放一段弧的相關元素。
var arcs = svg.selectAll("g")
.data(piedata)
.enter()
.append("g")
.attr("transform","translate("+ (width/2) +","+ (width/2) +")");
接下來對每個 g 元素,添加 path 。
arcs.append("path")
.attr("fill",function(d,i){
return color(i);
})
.attr("d",function(d){
return arc(d); //調(diào)用弧生成器,得到路徑值
});
因為 arcs 是同時選擇了 5 個 g 元素的選擇集,所以調(diào)用 append(“path”) 后,每個 g 中都有 path 。路徑值的屬性名稱是 d,調(diào)用弧生成器后返回的值賦值給它。要注意,arc(d) 的參數(shù) d 是被綁定的數(shù)據(jù)。
另外,color 是一個顏色比例尺,它能根據(jù)傳入的索引號獲取相應的顏色值,定義如下。
var color = d3.scale.category10(); //有十種顏色的顏色比例尺
然后在每一個弧線中心添加文本。
arcs.append("text")
.attr("transform",function(d){
return "translate(" + arc.centroid(d) + ")";
})
.attr("text-anchor","middle")
.text(function(d){
return d.data;
});
arc.centroid(d) 能算出弧線的中心。要注意,text() 里返回的是 d.data ,而不是 d 。因為被綁定的數(shù)據(jù)是對象,里面有 d.startAngle、d.endAngle、d.data 等,其中 d.data 才是轉(zhuǎn)換前的整數(shù)的值。
下載地址:rm80.zip