效果展示
组件代码
<template>
<div class="donut-chart">
<div ref="chart" class="chart"></div>
</div>
</template>
<script>
const OVERVIEW_COLOR_LIST = [
'#6F9CF9',
'#65DCAC',
'#A486D5',
'#F7C739',
'#EB7F65',
'#5DD4F7',
'#43AFE8',
'#FFAC68',
'#4CBEBE',
'#F697C1',
];
export default {
name: 'DonutChart',
props: {
chartInfo: {
type: Object,
default: () => ({})
},
},
data() {
return {
OVERVIEW_COLOR_LIST,
chartColorList: [],
chartVariable: {}, //不同标签个数对应变量
};
},
watch: {
chartInfo() {
this.init();
},
},
methods: {
// 初始化数据
init() {
if (this.chartInfo.chartData) {
const chartLen = this.chartInfo.chartData.length;
if (!this.chartInfo.isChartData) {
this.chartColorList = ['#ccc'];
} else {
if (this.chartInfo.colorList) {
this.chartColorList = this.chartInfo.colorList;
} else {
this.chartColorList = OVERVIEW_COLOR_LIST;
}
}
// 是否截断
if (chartLen > 8) {
this.chartVariable = {
width: '350px',
itemGap: 15,
isLegendTooltip: true,
formatter: (name) => {
if (name.length > 5) {
name = name.slice(0, 4) + '...';
}
const arr = ['{item|' + name + '}'];
return arr.join('\n');
},
};
} else {
this.chartVariable = {
width: '300px',
itemGap: 20,
isLegendTooltip: false,
formatter: (name) => {
const arr = ['{item|' + name + '}'];
return arr.join('\n');
},
};
}
// 图形大小
if (this.chartInfo.size === 'large') {
this.chartVariable.center = ['20%', '45%'];
this.chartVariable.radius = ['60%', '75%'];
this.chartVariable.titleTop = '30%';
this.chartVariable.titleFontSize = {
val: 24,
name: 16,
};
this.chartVariable.legendTop = chartLen > 18 ? '10%' : '25%';
} else {
this.chartVariable.center = ['20%', '35%'];
this.chartVariable.radius = ['50%', '65%'];
this.chartVariable.titleTop = '20%';
this.chartVariable.titleFontSize = {
val: 20,
name: 12,
};
this.chartVariable.legendTop = '15%';
}
this.paintChart();
}
},
// 绘制图表
paintChart() {
const chartDom = this.$echarts.init(this.$refs.chart);
if (chartDom) {
const option = {
color: this.chartColorList,
tooltip: {
show: true,
},
title: [
{
text:
'{val|' +
this.chartInfo.chartCount.toLocaleString() +
'}\n{name|' +
this.chartInfo.chartName +
'}',
top: this.chartVariable.titleTop,
left: '19.5%',
textAlign: 'center',
textStyle: {
rich: {
name: {
fontSize: this.chartVariable.titleFontSize.name,
color: '#6E7784',
align: 'center',
padding: [10, 0],
},
val: {
fontSize: this.chartVariable.titleFontSize.val,
fontWeight: 'bold',
color: '#151631',
align: 'center',
padding: [10, 0],
},
},
},
},
],
legend: {
icon: 'circle',
y: 'center',
x: 'right',
width: this.chartVariable.width,
left: '43%',
top: this.chartVariable.legendTop,
itemWidth: 8,
itemHeight: 8,
itemGap: this.chartVariable.itemGap,
formatter: this.chartVariable.formatter,
tooltip: {
show: this.chartVariable.isLegendTooltip,
},
textStyle: {
color: '#6E7784',
rich: {
item: {
backgroundColor: '#fff',
width: 80,
},
},
},
},
series: [
{
name: this.chartInfo.chartName,
type: 'pie',
radius: this.chartVariable.radius,
center: this.chartVariable.center,
tooltip: {
trigger: 'item',
borderWidth: 2,
borderColor: '#ECECEE',
backgroundColor: '#fff',
textStyle: {
color: '#666666',
},
position: 'right',
padding: 20,
formatter: (params) => {
const res = `${params.data.name}<br />占比:${this.chartInfo.chartCount
? Number(
(params.data.value / this.chartInfo.chartCount) * 100
).toFixed(2)
: 100}%`;
return res;
},
},
emphasis: {
focus: 'self',
},
itemStyle: {
borderWidth: 1,
borderColor: '#fff',
},
avoidLabelOverlap: false,
label: {
show: false,
},
data: this.chartInfo.chartData,
},
],
};
chartDom && chartDom.setOption(option);
chartDom.on('click', (param) => {
this.chartInfo.chartClickFunc(param);
});
const sizeFun = () => {
chartDom.resize();
};
window.addEventListener('resize', sizeFun);
this.$once('hook:beforeDestroy', function () {
this.$echarts.dispose(chartDom);
});
}
},
},
};
</script>
<style lang="less">
.donut-chart {
height: 320px;
width: 100%;
& .chart {
height: 320px;
width: 100%;
min-width: 600px;
}
}
</style>
使用方式
<template>
<div>
<donut-chart :chartInfo="normalInfo"/>
</div>
</template>
<script>
export default {
data(){
return{
normalInfo:{},
}
},
mounted(){
let chartData = [];
let eventCount = 11288;
let isChartData = true;
let dataList=[
{
"name": "互联网",
"count": 11078,
},
{
"name": "境外互联网",
"count": 5604,
},
{
"name": "境内互联网",
"count": 1049,
},
{
"name": "互联网-境内",
"count": 523,
},
{
"name": "局域网-生产网",
"count": 1049,
},
{
"name": "局域网-测试网",
"count": 523,
}
];
dataList.forEach(item=>{
chartData.push({
value: item.count,
name: item.name,
});
})
this.normalInfo = {
chartName: "API个数",
chartData: chartData,
chartCount: eventCount,
isChartData: isChartData,
size: "large",
chartClickFunc: (params) => {},
};
},
}
</script>