在数据可视化领域,环形图是一种非常有效的图表类型,它能够清晰地展示各部分与整体的关系。今天,我们将通过ECharts来创建一个带百分比标注的环形图,并详细解释如何实现这一效果。
1. 数据准备
首先,我们定义了一些基础数据:
dashedPic
:一个base64编码的图片,用作Y轴标签的背景。color
:一个颜色数组,用于环形图各部分的填充颜色。chartData
:包含活动名称、价值和单位的对象数组。
2. 数据处理
接下来,我们对chartData
进行处理,提取名称和值,并计算总和价值:
chartData.forEach((v, i) => {
arrName.push(v.name);
arrValue.push(v.value);
sum = sum + v.value;
})
3. 构建环形图系列
我们使用双重循环来构建环形图的系列,每个活动对应两个环形图系列,一个用于显示实际数据,另一个用于创建间隔效果:
chartData.forEach((v, i) => {
pieSeries.push({
name: '课外活动',
type: 'pie',
clockWise: false,
hoverAnimation: false,
radius: [65 - i * 15 + '%', 57 - i * 15 + '%'],
center: ["30%", "50%"],
label: {
show: false
},
data: [{
value: v.value,
name: v.name
}, {
value: sum - v.value,
name: '',
itemStyle: {
color: "rgba(0,0,0,0)"
}
}]
});
pieSeries.push({
name: '',
type: 'pie',
silent: true,
z: 1,
clockWise: false, //顺时加载
hoverAnimation: false, //鼠标移入变大
radius: [65 - i * 15 + '%',57 - i * 15 + '%'],
center: ["30%", "50%"],
label: {
show: false
},
data: [{
value: 7.5,
itemStyle: {
color: "#E3F0FF"
}
}, {
value: 2.5,
name: '',
itemStyle: {
color: "rgba(0,0,0,0)"
}
}]
});
})
每个系列都设置了radius
和center
属性来定义环形的大小和位置,并且通过data
属性来绑定具体的数据。
4. 百分比和Y轴标签
我们为每个活动计算百分比,并创建Y轴标签:
v.percent = (v.value / sum * 100).toFixed(1) + "%";
lineYAxis.push({
value: i,
textStyle: {
rich: {
circle: {
color: color[i],
padding: [0, 5]
}
}
}
});
5. 完整的ECharts配置
最后,我们将所有配置整合到ECharts的option
对象中:
let dashedPic = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAM8AAAAOBAMAAAB6G1V9AAAAD1BMVEXKysrk5OTj4+TJycoJ0iFPAAAAG0lEQVQ4y2MYBaNgGAMTQQVFOiABhlEwCugOAMqzCykGOeENAAAAAElFTkSuQmCC';
let color = ['#FCC667', '#8693F3', '#89C3F8', '#F2A695'];
let chartData = [{
name: "剪纸",
value: 132,
unit: '间'
},
{
name: "篮球",
value: 421,
unit: '人'
},
{
name: "声乐",
value: 817,
unit: '人'
},
{
name: "舞蹈",
value: 121,
unit: '人'
}
];
let arrName = [];
let arrValue = [];
let sum = 0;
let pieSeries = [],
lineYAxis = [];
// 数据处理
chartData.forEach((v, i) => {
arrName.push(v.name);
arrValue.push(v.value);
sum = sum + v.value;
})
// 图表option整理
chartData.forEach((v, i) => {
pieSeries.push({
name: '课外活动',
type: 'pie',
clockWise: false,
hoverAnimation: false,
radius: [65 - i * 15 + '%', 57 - i * 15 + '%'],
center: ["30%", "50%"],
label: {
show: false
},
data: [{
value: v.value,
name: v.name
}, {
value: sum - v.value,
name: '',
itemStyle: {
color: "rgba(0,0,0,0)"
}
}]
});
pieSeries.push({
name: '',
type: 'pie',
silent: true,
z: 1,
clockWise: false, //顺时加载
hoverAnimation: false, //鼠标移入变大
radius: [65 - i * 15 + '%',57 - i * 15 + '%'],
center: ["30%", "50%"],
label: {
show: false
},
data: [{
value: 7.5,
itemStyle: {
color: "#E3F0FF"
}
}, {
value: 2.5,
name: '',
itemStyle: {
color: "rgba(0,0,0,0)"
}
}]
});
v.percent = (v.value / sum * 100).toFixed(1) + "%";
lineYAxis.push({
value: i,
textStyle: {
rich: {
circle: {
color: color[i],
padding: [0, 5]
}
}
}
});
})
option = {
backgroundColor: '#0A2E5D',
title: {
text: '学生课外选修情况',
textAlign: "center",
left: "49%",
textStyle: {
color: '#fff',
fontSize: 22,
fontWeight: '400'
}
},
color: color,
grid: {
top: '15%',
bottom: '54%',
left: "30%",
containLabel: false
},
yAxis: [{
type: 'category',
inverse: true,
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
formatter: function(params) {
let item = chartData[params];
console.log(item)
return '{line|}{circle|●}{name|'+ item.name +'}{bd||}{percent|'+item.percent+'}{value|'+ item.value+'}{unit|人}'
},
interval: 0,
inside: true,
textStyle: {
color: "#333",
fontSize: 14,
rich: {
line: {
width: 170,
height: 10,
backgroundColor: {image: dashedPic}
},
name: {
color: 'white',
fontSize: 14,
},
bd: {
color: 'white',
padding: [0, 5],
fontSize: 14,
},
percent:{
color: 'white',
fontSize: 14,
},
value: {
color: 'white',
fontSize: 16,
fontWeight: 500,
padding: [0, 0, 0, 20]
},
unit: {
fontSize: 14
}
}
},
show: true
},
data: lineYAxis
}],
xAxis: [{
show: false
}],
series: pieSeries
};
6. 应用配置
将配置应用到ECharts实例上,就可以看到最终的环形图效果:
myChart.setOption(option);
7. 总结
通过以上步骤,我们创建了一个带百分比标注的环形图,它不仅展示了各部分的比例关系,还通过Y轴标签提供了更详细的信息。这种图表非常适合展示分类数据的比例和分布情况。你可以根据自己的需求调整颜色、大小和样式,以达到最佳的展示效果。希望这篇文章能够帮助你掌握ECharts环形图的创建技巧,为你的数据可视化项目增添亮点。如果有任何问题,欢迎在评论区交流。