D3.js上手——餅狀圖

餅狀圖是數據統計中常常用到的另外一類圖表,餅圖能夠直觀地顯示一個數據系列中各項的大小與各項總和的比例,本文將使用D3上手製做一個簡單的餅狀圖數組

什麼是佈局

佈局是D3中很是重要的內容,有了佈局D3才能畫出複雜的矢量圖。但佈局並非直接繪製圖形,只是將初始數據轉換成容易畫圖的圖形語言,畫圖工具能讀懂圖形語言來進行繪製。瀏覽器

在繪製餅狀圖中,例若有一組數據[1, 2, 3],只依靠這些數據是畫不出的,須要將這些數據轉化爲圓形的起始角度和終止角度,第一塊的角度區域爲[0, π/3],第二塊的角度區域爲[π/3, π]……繪製工具能根據這些角度值進行繪製。佈局只進行數據轉換app

D3還提供其餘經常使用圖表的佈局函數,好比力導向圖(Force)、弦圖(Chord)、樹狀圖(Tree)、直方圖(Histogram)、分區圖(Partition)等,每種佈局有對應的APIsvg

肯定數據

表格數據是來自w3schools的2016年9月的瀏覽器使用率函數

瀏覽器 佔比
Chrome 72.5%
IE 5.3%
Firefox 16.3%
Safari 3.5%
Opera 1.0%
Others 1.4%

對此設定如下二維數組裝載這些數據工具

var dataset = [['Chrome', 72.5], ['IE', 5.3], ['Firefox', 16.3], ['Safari', 3.5], ['Opera', 1.0], ['Others', 1.4]];
複製代碼

創建佈局

  • d3.pie() 構造一個新的餅佈局

構建一個餅佈局並接收數據佈局

var pie = d3.pie()
            .sort(null) // 在建立佈局的時候,默認排序數據從大到小,設爲null能夠按照數組默認順序排序
            .value(function(d){
              return d[1]
            });
複製代碼

把數據轉換爲餅圖繪製所須要的數據ui

var piedata = pie(dataset);
console.log(piedata);
複製代碼

在控制檯輸出piedata,看看轉換後的數據spa

能夠看到,原來的數據已經被轉換成6組適合畫圖的數據code

  • data —— 保留原有數據
  • index —— 序號
  • startAngle —— 一段弧的起始角度
  • endAngle —— 一段弧的終止角度

生成弧生成器

雖然有了角度,但目前仍是很難畫出咱們想要的餅圖,還要用到D3中的路徑生成器。在svg中,path標籤的路徑數值每每十分複雜,手動去生成是不現實的,尤爲是要生成各類複雜曲線的時候,好在D3提供了基本的路徑生成器,有線段、區域、弧生成器等。畫餅圖的時候須要用到弧生成器,幫助咱們把轉換後的數據真正繪製出來

  • d3.arc() 建立一個新的弧生成器
  • arc.innerRadius([radius]) 設置內部半徑
  • arc.outerRadius([radius]) 設置外部半徑

這裏把畫布的四分之一做爲外部半徑,內部半徑設爲0就是餅圖,沒錯,設置大於0就是圓環圖

var outerRadius = width / 4;
var innerRadius = 0;
var arc = d3.arc()
            .outerRadius(outerRadius)
            .innerRadius(innerRadius);
複製代碼

繪製餅圖

跟以前同樣,建立g組合標籤後,把piedata數據綁定至g標籤,這裏要用到D3的內置顏色,d3.schemeCategory10選了10種顏色,方便咱們隨時使用,爲餅圖的不一樣區域填色,沒必要爲想不出好的顏色搭配而煩惱,固然也能夠自定義顏色

var arcs = svg.selectAll('g')
              .data(piedata)
              .enter()
              .append('g')
              .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');
// 調用內置顏色序列
var colors = d3.schemeCategory10;
arcs.append('path')
    .attr('fill', function(d, i){
      return colors[i];
    })
    .attr('d', function(d){
      return arc(d);
    });
複製代碼

在path標籤中,給d屬性賦予數據通過弧生成器處理的值,這樣一個沒有標註的餅圖就完成了

添加標註

  • arc.centroid(arguments…) 獲取弧中心座標

接下來給餅圖加一些標註,以便更好地閱讀圖形,主要用到弧中心的概念,以下圖,黑點就是每一個弧的中心,利用**arc.centroid()**能夠獲取弧中心的座標,而且這個座標是相對圓形的相對座標。有了這個座標,能夠很方便地在每一個弧上添加文字標註

arc.centroid(d)是一個包含橫座標和縱座標的數組[x, y],給座標乘以2倍以上的數值就把文字移到圓形外邊

arcs.append('text')
    .attr('transform', function(d, i){
      var x = arc.centroid(d)[0] * 2.8;
      var y = arc.centroid(d)[1] * 2.8;
      return 'translate(' + x + ', ' + y + ')';
    })
    .attr('text-anchor', 'middle')
    .text(function(d){
      var percent = Number(d.value) / d3.sum(dataset, function(d){
        return d[1];
      }) * 100;
      return d.data[0] + ' ' + percent.toFixed(1) + '%';
    })
複製代碼

最後再加一些連線

arcs.append('line')
    .attr('stroke', 'black')
    .attr('x1', function(d){ return arc.centroid(d)[0] * 2; })
    .attr('y1', function(d){ return arc.centroid(d)[1] * 2; })
    .attr('x2', function(d, i){
      return arc.centroid(d)[0] * 2.5;
    })
    .attr('y2', function(d, i){
      return arc.centroid(d)[1] * 2.5;
    });
複製代碼

因爲最後幾個數據過小,標註文字會重疊到一塊兒,這裏作了一個判斷處理來錯開數據值較小的文字,最後的效果圖以下所示

查看完整示例代碼

相關文章
相關標籤/搜索