1. 程式人生 > >D3.js之餅圖

D3.js之餅圖

一.繪製餅圖的步驟:

  1. 新增svg並新增svg屬性(width, height);
      <script type="text/javascript">
        var width = 400;      //設定svg區域的寬度
        var height = 400;     //設定svg區域的高度
    
        var svg = d3.select('body')               //選擇body區
                	.append('svg')                //在body中新增svg
                	.attr('width', width)					//將寬度賦給width屬性
                	.attr('height', height);      //將高度賦給height屬性
    
      </script>

     

  2. 確定初始資料;
    //確定初始資料
        var dataset = [['小米', 22.5], ['華為', 32.7], ['中興', 14.2], ['努比亞', 22.1], ['聯想', 14.2], ['其他', 10.3]];

     

  3. 轉換資料;
        //轉換資料
        var pie = d3.layout.pie()
        			 .value(function (d) { return d[1]; });
        var piedata = pie(dataset);
        console.log(piedata);

     

  4. 繪製;
  • 外半徑和內半徑
        //外半徑和內半徑
        var outerRadius = width / 3;
        var innerRadius = 0;

     

  • 建立弧生成器
    //建立弧生成器
    var arc = d3.svg.arc()
    								.innerRadius(innerRadius)
    								.outerRadius(outerRadius);
    var color = d3.scale.category20();
  • 新增對應數目的弧組,即<g>元素
    var arcs = svg.selectAll('g')
    			.data(piedata)        //繫結轉換後的資料,即piedata
    			.enter()
    			.append('g')
    			.attr('transform', 'translate(' + (width / 2) + ',' + (height / 2) + ')');
  • 新增弧的路徑元素
    //新增弧的路徑元素
    arcs.append('path')
    		.attr('fill', function(d,i) {
    		  return color(i);         //設定弧的顏色
    		})
    		.attr('d', function(d) {
    		  return arc(d);           //使用弧生成器
    		});

效果圖:

 

  • 新增弧內的文字元素
        //新增弧內的文字元素
        arcs.append('text')
        		.attr('transform', function(d) {
        		  var x = arc.centroid(d)[0] * 1.4;      //文字的x座標
        		  var y = arc.centroid(d)[1] * 1.4;      //文字的y座標
        		  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 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) { return arc.centroid(d)[0] * 2.2; })
        		.attr('y2', function(d) { return arc.centroid(d)[1] * 2.2; });

    效果圖:

 

  • 新增弧外的文字元素
        arcs.append('text')
        		.attr('transform', function(d) {
        		  var x = arc.centroid(d)[0] * 2.5;
        		  var y = arc.centroid(d)[1] * 2.5;
        		  return 'translate(' + x + ',' + y + ')';
        		})
        		.attr('text-anchor', 'middle')
        		.text(function(d) {
        		  return d.data[0];
        		});

    效果圖:

 

全部程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<script src="https://cdn.bootcss.com/d3/3.2.1/d3.js"></script>
</head>
<body>
  <script type="text/javascript">
    var width = 400;      //設定svg區域的寬度
    var height = 400;     //設定svg區域的高度

    var svg = d3.select('body')               //選擇body區
            		.append('svg')                //在body中新增svg
            		.attr('width', width)					//將寬度賦給width屬性
            		.attr('height', height);      //將高度賦給height屬性

    //確定初始資料
    var dataset = [['小米', 22.5], ['華為', 32.7], ['中興', 14.2], ['努比亞', 22.1], ['聯想', 14.2], ['其他', 10.3]];

    //轉換資料
    var pie = d3.layout.pie()
    									 .value(function (d) { return d[1]; });
    var piedata = pie(dataset);
    console.log(piedata);

    //外半徑和內半徑
    var outerRadius = width / 3;
    var innerRadius = 0;

    //建立弧生成器
    var arc = d3.svg.arc()
    								.innerRadius(innerRadius)
    								.outerRadius(outerRadius);
    var color = d3.scale.category20();

    //新增對應數目的弧組,即<g>元素
    var arcs = svg.selectAll('g')
    							.data(piedata)
    							.enter()
    							.append('g')
    							.attr('transform', 'translate(' + (width / 2) + ',' + (height / 2) + ')');

    //新增弧的路徑元素
    arcs.append('path')
    		.attr('fill', function(d,i) {
    		  return color(i);         //設定弧的顏色
    		})
    		.attr('d', function(d) {
    		  return arc(d);           //使用弧生成器
    		});


    //新增弧內的文字元素
    arcs.append('text')
    		.attr('transform', function(d) {
    		  var x = arc.centroid(d)[0] * 1.4;      //文字的x座標
    		  var y = arc.centroid(d)[1] * 1.4;      //文字的y座標
    		  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 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) { return arc.centroid(d)[0] * 2.2; })
    		.attr('y2', function(d) { return arc.centroid(d)[1] * 2.2; });

    //新增弧外的文字元素
    arcs.append('text')
    		.attr('transform', function(d) {
    		  var x = arc.centroid(d)[0] * 2.5;
    		  var y = arc.centroid(d)[1] * 2.5;
    		  return 'translate(' + x + ',' + y + ')';
    		})
    		.attr('text-anchor', 'middle')
    		.text(function(d) {
    		  return d.data[0];
    		});
  </script>
</body>
</html>