您现在的位置是:网站首页 > 饼图(Pie Chart)实现文章详情
饼图(Pie Chart)实现
陈川
【
ECharts
】
64724人已围观
7991字
饼图(Pie Chart)实现
饼图是一种常见的数据可视化形式,通过扇形区域的大小直观展示各部分在整体中的占比关系。ECharts提供了丰富的配置项来实现各种风格的饼图,从基础展示到复杂的交互效果都能轻松应对。
基础饼图实现
最简单的饼图只需要指定系列类型为'pie'并提供相应的数据即可:
option = {
title: {
text: '某站点用户访问来源',
subtext: '纯属虚构',
left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: 'left',
data: ['直接访问','邮件营销','联盟广告','视频广告','搜索引擎']
},
series: [
{
name: '访问来源',
type: 'pie',
radius: '50%',
data: [
{value: 335, name: '直接访问'},
{value: 310, name: '邮件营销'},
{value: 234, name: '联盟广告'},
{value: 135, name: '视频广告'},
{value: 1548, name: '搜索引擎'}
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
这段代码创建了一个标准的饼图,包含标题、图例和提示框。radius
属性控制饼图的大小,设置为'50%'表示占据容器宽度的一半。
环形饼图
通过设置radius
为数组可以实现环形饼图效果:
series: [{
type: 'pie',
radius: ['40%', '70%'],
data: [
{value: 1048, name: '搜索引擎'},
{value: 735, name: '直接访问'},
{value: 580, name: '邮件营销'},
{value: 484, name: '联盟广告'},
{value: 300, name: '视频广告'}
]
}]
这里radius
的第一个值表示内半径,第二个值表示外半径。通过调整这两个值可以控制环形的宽度。
南丁格尔玫瑰图
将roseType
设置为'area'可以创建南丁格尔玫瑰图:
series: [{
type: 'pie',
radius: [30, 120],
roseType: 'area',
data: [
{value: 10, name: 'rose1'},
{value: 5, name: 'rose2'},
{value: 15, name: 'rose3'},
{value: 25, name: 'rose4'},
{value: 20, name: 'rose5'},
{value: 35, name: 'rose6'},
{value: 30, name: 'rose7'},
{value: 40, name: 'rose8'}
]
}]
玫瑰图通过扇区的半径长度来展示数值大小,适合展示大量分类数据的对比。
多级饼图
通过嵌套多个饼图系列可以实现多级饼图效果:
series: [
{
type: 'pie',
radius: ['0%', '30%'],
label: {show: false},
data: [
{value: 335, name: 'A类'},
{value: 310, name: 'B类'},
{value: 234, name: 'C类'}
]
},
{
type: 'pie',
radius: ['40%', '70%'],
data: [
{value: 135, name: 'A1'},
{value: 148, name: 'A2'},
{value: 52, name: 'A3'},
{value: 210, name: 'B1'},
{value: 100, name: 'B2'},
{value: 134, name: 'C1'},
{value: 100, name: 'C2'}
]
}
]
内层饼图展示大类数据,外层展示详细分类,形成层次关系。
自定义标签样式
饼图的标签可以通过label
属性进行高度自定义:
series: [{
type: 'pie',
radius: '55%',
center: ['50%', '60%'],
data: [
{value: 335, name: '直接访问'},
{value: 310, name: '邮件营销'},
{value: 234, name: '联盟广告'},
{value: 135, name: '视频广告'},
{value: 1548, name: '搜索引擎'}
],
label: {
color: '#333',
formatter: '{b}: {c} ({d}%)',
fontSize: 14,
fontWeight: 'bold',
lineHeight: 22,
rich: {
a: {
color: '#999',
lineHeight: 22
},
hr: {
borderColor: '#aaa',
width: '100%',
borderWidth: 0.5,
height: 0
}
}
},
labelLine: {
lineStyle: {
color: 'rgba(0, 0, 0, 0.3)'
},
smooth: 0.2,
length: 10,
length2: 20
}
}]
label.formatter
支持字符串模板和回调函数两种形式,rich
属性可以定义富文本样式。
交互效果增强
ECharts饼图支持丰富的交互效果:
series: [{
type: 'pie',
selectedMode: 'single',
selectedOffset: 30,
avoidLabelOverlap: false,
emphasis: {
scale: true,
scaleSize: 10,
label: {
show: true,
fontSize: '20',
fontWeight: 'bold'
}
},
data: [
{value: 335, name: '直接访问'},
{value: 310, name: '邮件营销', selected: true},
{value: 234, name: '联盟广告'},
{value: 135, name: '视频广告'},
{value: 1548, name: '搜索引擎'}
]
}]
selectedMode
控制选中模式,emphasis
定义高亮样式,selected
可以预设选中状态。
动态数据更新
饼图支持动态数据更新,实现动画效果:
let data = [
{value: 335, name: '直接访问'},
{value: 310, name: '邮件营销'},
{value: 234, name: '联盟广告'},
{value: 135, name: '视频广告'},
{value: 1548, name: '搜索引擎'}
];
let option = {
series: [{
type: 'pie',
data: data
}]
};
// 定时更新数据
setInterval(function() {
data = data.map(item => {
return {
name: item.name,
value: item.value * (0.9 + Math.random() * 0.2)
};
});
myChart.setOption({
series: [{
data: data
}]
});
}, 2000);
自定义图形样式
通过itemStyle
可以完全自定义饼图的图形样式:
series: [{
type: 'pie',
radius: '55%',
itemStyle: {
color: function(params) {
const colorList = ['#c23531','#2f4554','#61a0a8','#d48265','#91c7ae'];
return colorList[params.dataIndex];
},
borderColor: '#fff',
borderWidth: 2,
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.3)',
borderRadius: 5
},
data: [
{value: 335, name: '直接访问'},
{value: 310, name: '邮件营销'},
{value: 234, name: '联盟广告'},
{value: 135, name: '视频广告'},
{value: 1548, name: '搜索引擎'}
]
}]
颜色可以使用回调函数根据数据索引动态分配,borderRadius
可以创建圆角效果。
大数据量优化
当数据量较大时,可以通过以下方式优化性能:
series: [{
type: 'pie',
radius: '55%',
data: largeData,
large: true,
largeThreshold: 1000,
progressive: 400,
animation: false,
label: {
show: false
}
}]
large
和largeThreshold
启用大数据模式,progressive
控制渐进渲染的块大小,关闭动画和标签可以进一步提升性能。
与其他图表组合
饼图可以与其他图表类型组合使用:
option = {
tooltip: {
trigger: 'axis',
axisPointer: {type: 'shadow'}
},
legend: {
data: ['利润', '支出', '收入']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'value'
},
yAxis: {
type: 'category',
data: ['周一','周二','周三','周四','周五','周六','周日']
},
series: [
{
name: '利润',
type: 'bar',
data: [200, 170, 240, 244, 200, 220, 210]
},
{
name: '收入',
type: 'pie',
radius: [0, '30%'],
center: ['75%', '25%'],
data: [
{value: 335, name: '直接访问'},
{value: 310, name: '邮件营销'},
{value: 234, name: '联盟广告'},
{value: 135, name: '视频广告'},
{value: 1548, name: '搜索引擎'}
]
}
]
};
这个例子将柱状图和饼图组合在一起,通过center
和radius
控制饼图的位置和大小。
事件处理
ECharts饼图支持丰富的事件交互:
myChart.on('click', function(params) {
console.log(params);
});
myChart.on('mouseover', function(params) {
console.log('鼠标悬停在'+params.name);
});
myChart.on('globalout', function() {
console.log('鼠标移出图表区域');
});
可以通过事件回调实现点击扇形跳转、显示详细信息等交互功能。
主题定制
ECharts内置了多种主题,也可以自定义主题:
// 使用内置dark主题
echarts.init(dom, 'dark');
// 自定义主题
let myTheme = {
color: ['#dd6b66','#759aa0','#e69d87','#8dc1a9','#ea7e53'],
backgroundColor: '#f5f5f5',
textStyle: {},
title: {
textStyle: {color: '#333'},
subtextStyle: {color: '#aaa'}
}
};
echarts.registerTheme('myTheme', myTheme);
echarts.init(dom, 'myTheme');
主题可以统一控制图表的颜色、背景、文字等样式属性。
服务端渲染
对于Node.js环境,可以使用node-echarts
实现服务端渲染:
const echarts = require('echarts');
const { createCanvas } = require('canvas');
// 创建canvas实例
const canvas = createCanvas(800, 600);
const chart = echarts.init(canvas);
// 设置选项
chart.setOption({
series: [{
type: 'pie',
data: [
{value: 335, name: 'A'},
{value: 310, name: 'B'},
{value: 234, name: 'C'}
]
}]
});
// 输出图片
const buffer = canvas.toBuffer('image/png');
require('fs').writeFileSync('pie.png', buffer);
这种方式适合生成静态图表图片用于邮件、报告等场景。
移动端适配
针对移动设备需要进行特殊适配:
option = {
series: [{
type: 'pie',
radius: ['30%', '70%'],
label: {
fontSize: (window.innerWidth / 20) + 'px'
},
labelLine: {
length: window.innerWidth > 500 ? 15 : 5,
length2: window.innerWidth > 500 ? 30 : 10
},
data: pieData
}]
};
通过检测屏幕宽度动态调整字体大小和标签线长度,确保在小屏幕上也能清晰显示。
无障碍访问
为提升可访问性,可以添加ARIA属性:
series: [{
type: 'pie',
data: [
{
value: 335,
name: '直接访问',
itemStyle: {color: '#c23531'},
aria: {
label: '直接访问占比26.7%'
}
}
// 其他数据...
],
aria: {
enabled: true,
label: {
description: '这是一个饼图,展示了不同访问来源的占比情况'
}
}
}]
这些属性可以帮助屏幕阅读器用户理解图表内容。
上一篇: 柱状图(Bar Chart)实现
下一篇: 散点图(Scatter Chart)实现