D3.js之餅圖
阿新 • • 發佈:2019-01-02
一.繪製餅圖的步驟:
- 新增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>
- 確定初始資料;
//確定初始資料 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) //繫結轉換後的資料,即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>