Fork me on GitHub

用d3画环形图

目录

前言:环形图很好实现,百度的echart图标库就可以实现各种形式的环形,但是还是会有个别环形图的特殊样式,echart实现不了的那就用d3实现吧。

定义数据格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
var dataSet = [{
id: 0,
name: '国土局',
value: 30
}, {
id: 1,
name: '教育局',
value: 50
}, {
id: 2,
name: '民宗局',
value: 39
}, {
id: 3,
name: '文体局',
value: 70
}, {
id: 4,
name: '编办',
value: 78
}, {
id: 5,
name: '商务局',
value: 33
}, {
id: 6,
name: '财政局',
value: 19
}, {
id: 7,
name: '科技局',
value: 36
}, {
id: 8,
name: '环保局',
value: 60
}, {
id: 9,
name: '其他局',
value: 84
}];

创建虚拟数组,绘制外部弧线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var updateData = function(arr) {
var _updateArr = [];
var _len = arr.length;
for(var i = 0; i < _len; i++) {
if(i === _len - 1) {
_updateArr.push({
value: ((arr[i].value) / 2 + (arr[0].value) / 2),
name: arr[i].name
});
} else {
_updateArr.push({
value: ((arr[i].value) / 2 + (arr[i + 1].value) / 2),
name: arr[i].name
});
}
};
return _updateArr;
};
var outerCircleData = updateData(dataSet);
//定义颜色数组
var colors = ['#21b6fc', '#7cfdfb', '#32fffe', '#59fee8', '#02d38b', '#d9fd8c', '#ffd553', '#ff396a', '#b860ef', '#015fc8'];

创建svg

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//定义svg宽高
var width = 460,
height = 238;
var svg = d3.select('.comBox')
.append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', 'translate(150,120)');
//求value总和
var grossData = 0;
dataSet.map(function(item) {
grossData += item.value;
});

创建弧生成器

1
2
3
4
var arc = d3.arc()
.innerRadius(56)
.outerRadius(70)
.padAngle(0.01);

创建饼布局

1
2
3
4
5
var pie = d3.pie()
.value(function(d) {
return d.value;
})
.sort(null)

转换数据格式

1
var pieData = pie(dataSet);

开始绘制

1
2
3
4
5
6
7
8
9
10
11
//添加与data数量相等的g节点
var arc_g = svg.selectAll('g')
.data(pieData)
.enter()
.append('g');
//添加path节点
var arcPath = arc_g
.append('path')
.attr('d', function(d) {
return arc(d)
})

添加line节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
arc_g.append('line')
.transition()
.duration(600)
.attr('stroke', '#3e8eff')
.attr('stroke-dasharray', ' 1 , 1.5 ')
.attr('stroke-width', 2)
.attr('x1', function(d) {
return arc.centroid(d)[0] * 1.1
})
.attr('y1', function(d) {
return arc.centroid(d)[1] * 1.1
})
.attr('x2', function(d) {
return arc.centroid(d)[0] * 1.3
})
.attr('y2', function(d) {
return arc.centroid(d)[1] * 1.3
});

添加文字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
arc_g.append('text')
.transition()
.duration(600)
.attr('transform', function(d) {
var x = arc.centroid(d)[0] * 1.5;
var y = arc.centroid(d)[1] * 1.48;
return "translate(" + (x + 3) + "," + (y + 5) + ")";
})
.attr("font-size", "14px")
.attr("font-family", "微软雅黑")
.style("text-anchor", "middle")
.attr("fill", '#02f4ff')
.text(function(d) {
return Math.ceil(d.value / grossData * 100) + '%';

绘制外圆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var arc = d3.arc()
.innerRadius(76)
.outerRadius(77)
.padAngle(0.08);
var arcLineData = pie(outerCircleData);
var arcLine_g = svg.append('g')
.attr('transform', 'rotate(12)');
arcLine_g.selectAll('path')
.data(arcLineData)
.enter()
.append('path')
.attr('d', function(d) {
console.log(d)
return arc(d)
})
.attr('fill', '#3e8eff');

添加图例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
var rects = svg.append('g')
.attr('transform', 'translate(170,-80)');
var rect_g = rects.selectAll('g')
.data(dataSet)
.enter()
.append('g');
rect_g.append('rect')
.transition()
.duration(600)
.delay(function(d,i){
console.log(d,i)
return i*50
})
.attr('width', 20)
.attr('height', 8)
.attr('y', function(d, i) {
return 18 * i;
})
.attr('fill', function(d, i) {
return colors[i]
});
rect_g.append('text')
.attr("font-size", "14px")
.attr("font-family", "微软雅黑")
.style("text-anchor", "middle")
.attr("fill", '#30b4ff')
.attr('dy', 10)
.attr('y', function(d, i) {
return 18 * i;
})
.attr('x', 60)
.text(function(d) {
return d.name
})

添加动画

1
2
3
4
5
6
7
8
9
arcPath
.transition()
.duration(1500)
.delay(function(d, i) {
return i * 50;
})
.attr('fill', function(d) {
return colors[d.data.id]
});

最终效果图:

本文d3相关属性和方法讲解:
d3.arc() - 创建一个新弧生成器
arc.innerRadius() - 设置内半径
arc.outerRadius() - 设置外半径
arc.padAngle() - 设置相邻弧之间的夹角(取值范围0~0.1)
arc.centroid() - 弧中心
arc.centroid(d)[0] - x轴坐标
arc.centroid(d)[1 ] - y轴坐标
d3.transition() - 添加动画
transition.duration - 指定每个元素的持续时间(以毫米为单位)。
transition.delay - 指定每个元素的延迟时间(以毫米为单位)。

-------------本文结束感谢您的阅读-------------

发布时间:2018年04月02日 - 14:04

最后更新:2018年04月02日 - 18:04

原始链接:https://xn--v4q63d8za.xn--6qq986b3xl/用d3画环形图/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

谢谢您给我买糖吃~