【D3.js - v5.x】(4)繪製餅圖 | 附完整代碼

餅圖

https://www.d3js.org.cn/document/d3-shape/#pies

定義一個佈局:

var pie = d3.pie();

返回值賦給變量 pie,此時 pie 可以當做函數使用。

var piedata = pie(dataset);

將數組 dataset 作爲 pie() 的參數,返回值給 piedata。如此一來,

piedata 就是轉換後的數據。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-wrzSgd1j-1587639740183)(/Users/imaginexie/Library/Application Support/typora-user-images/image-20200423182708947.png)]

如上圖所示,5 個整數被轉換成了 5 個對象(Object) ,每個對象都有變量起始角度(startAngle)終止角度(endAngle),還有原數據(屬性名稱爲 data)。這些都是繪圖需要的數據。

記住:佈局是爲了得到繪圖所需的數據

繪製圖形

爲了根據轉換後的數據 piedata 來作圖,還需要一樣工具:生成器

SVG 有一個元素,叫做路徑 path,是 SVG 中功能最強的元素,它可以表示其它任意的圖形。

顧名思義,路徑元素就是通過定義一個段“路徑”,來繪製出各種圖形。

但是,路徑是很難計算的,通過佈局轉換後的數據 piedata 仍然很難手動計算得到路徑值。爲我們完成這項任務的,就是生成器

這裏要用到的叫做弧生成器,能夠生成弧的路徑,因爲餅圖的每一部分都是一段弧。https://www.d3js.org.cn/document/d3-shape/#arcs

arc 生成器用來在餅圖或圓環圖中生成 circular(圓形)annular(環形) 扇形。

var outerRadius = 150; //外半徑
var innerRadius = 0; //內半徑,爲0則中間沒有空白
var arc_generator = d3.arc()
                .innerRadius(0)
                .outerRadius(100); 

弧生成器返回的結果賦值給 arc。此時,arc 可以當做一個函數使用,把 piedata 作爲參數傳入,即可得到路徑值。

接下來,可以在 SVG 中添加圖形元素了。先在 svg 裏添加足夠數量(5個)個分組元素(g),每一個分組用於存放一段弧的相關元素。

var g = svg.append("g")             .attr("transform","translate("+marge.top+","+marge.left+")");
var gs = g.selectAll(".g")
                .data(pieData)
                .enter()
                .append("g")               	.attr("transform","translate("+width/2+","+height/2+")")//位置信息

接下來對每個 g 元素,添加 path 。

gs.append("path")
  .attr("d",function(d){
  return arc_generator(d);//往弧形生成器中出入數據
})
  .attr("fill",function(d,i){
  return colorScale(i);
});

因爲 arcs 是同時選擇了 5 個 g 元素的選擇集,所以調用 append(“path”) 後,每個 g 中都有 path 。路徑值的屬性名稱是 d,調用弧生成器後返回的值賦值給它。要注意,arc(d) 的參數 d 是被綁定的數據。

另外,color 是一個顏色比例尺,它能根據傳入的索引號獲取相應的顏色值,定義如下。

//設置一個color的顏色比例尺,爲了讓不同的扇形呈現不同的顏色
var colorScale = d3.scaleOrdinal()
                .domain(d3.range(dataset.length))
                .range(d3.schemeCategory10);

然後在每一個弧線中心添加文本:

gs.append("text")
                .attr("transform",function(d){//位置設在中心處
                    return "translate("+arc_generator.centroid(d)+")";
                })
                .attr("text-anchor","middle")
                .text(function(d){
                    return d.data;
                })

arc.centroid(d) 能算出弧線的中心。要注意,text() 裏返回的是 d.data ,而不是 d 。因爲被綁定的數據是對象,裏面有 d.startAngle、d.endAngle、d.data 等,其中 d.data 纔是轉換前的整數的值。

完整代碼:

<body>
        <svg width="500" height="500"></svg>
        <script>
            var marge = {top:60,bottom:60,left:60,right:60}
            var svg = d3.select("svg")
            var width = svg.attr("width")
            var height = svg.attr("height")
            var g = svg.append("g")
                .attr("transform","translate("+marge.top+","+marge.left+")");
                
            var dataset = [ 30 , 10 , 43 , 55 , 13 ];
            
            //設置一個color的顏色比例尺,爲了讓不同的扇形呈現不同的顏色
            var colorScale = d3.scaleOrdinal()
                .domain(d3.range(dataset.length))
                .range(d3.schemeCategory10);
            
            //新建一個餅狀圖
            var pie = d3.pie();
            
            //新建一個弧形生成器
            var innerRadius = 0;//內半徑
            var outerRadius = 100;//外半徑
            var arc_generator = d3.arc()
                .innerRadius(0)
                .outerRadius(100);
                
            //將原始數據變成可以繪製餅狀圖的數據,
            var pieData = pie(dataset);
            
            //在瀏覽器的控制檯打印pieData
            console.log(pieData);
            
            //在有了繪製餅狀圖必須的數據後,我們就可以開始繪製了
            var gs = g.selectAll(".g")
                .data(pieData)
                .enter()
                .append("g")
                .attr("transform","translate("+width/2+","+height/2+")")//位置信息
                
            //繪製餅狀圖的各個扇形
            gs.append("path")
                .attr("d",function(d){
                    return arc_generator(d);//往弧形生成器中出入數據
                })
                .attr("fill",function(d,i){
                    return colorScale(i);
                });
                
            //繪製餅狀圖上面的文字信息
            gs.append("text")
                .attr("transform",function(d){//位置設在中心處
                    return "translate("+arc_generator.centroid(d)+")";
                })
                .attr("text-anchor","middle")
                .text(function(d){
                    return d.data;
                })
            
        </script>
      </body>

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章