环境
vue: 3.2.13
echarts:5.3.3
实现效果
饼图
圆环显示,圆环中间显示数据总数,能自定义圆环各项颜色,legend实现数据名与值的显示,并且两者颜色不一致。
直方图
取消横纵坐标,悬停显示信息,数据可以有不同的颜色。
实现
圆环
<template>
<BaseTitle :title="props.title" :myClass="props.myClass"></BaseTitle>
<div class="content">
<div ref="main" style="width: 190px; height: 220px;margin-bottom: -50px;">
</div>
</div>
</template>
<script setup>
import * as echarts from "echarts";
import { ref, onMounted, watch, defineProps } from 'vue';
const props = defineProps({
myClass: {
type: String,
default: 'day',
},
title: {
type: String,
default: '',
},
data: {
type: Array,
default: [],
},
color: {
type: Array,
default: [],
},
unit: {
type: String,
default: '',
},
});
onMounted(() => {
init();
});
const main = ref();
let myChart;
const init = () => {
if (myChart && !myChart.isDisposed()) { // 检查是否存在并且未被销毁
myChart.dispose(); // 销毁旧的图表实例
}
myChart = echarts.init(main.value); // 初始化新的图表实例
const totalSum = props.data.reduce((accumulator, current) => accumulator + current.value, 0);
const option = {
grid: {
containLabel: true
},
title: {
text: `${totalSum}`,
subtext: '共计',
textAlign: 'center',
x: '36%',
y: '16%',
textStyle: {
color: '',
fontSize: 24,
},
subtextStyle: {
color: '',
fontSize: 14,
},
},
legend: {
top: '130px',
left: '0px',
itemHeight: 8, // 每个图例的宽度
itemWidth: 8, // 每个图例的高度
formatter: function (name) {
let data = option.series[0].data;
let tarValue = 0;
for (let i = 0, l = data.length; i < l; i++) {
if (data[i].name == name) {
tarValue = data[i].value;
}
}
return '{a|' + name + '} {b|' + tarValue + props.unit + '}';
},
textStyle: {
rich: {
a: {
color: '',
},
b: {
color: '',
}
}
}
},
tooltip: {
trigger: 'item',
confine: true,
},
series: [
{
label: {
show: false
},
radius: ['42%', '55%'],
center: ['38%', '29%'],
type: 'pie', //type为pie,表示图表为饼图
data: [],
color: [],
}
]
};
const pieData = props.data.map(item => ({
name: item.name,
value: item.value
}));
option.series[0].data = pieData;
option.series[0].color = [...props.color];
const labelColor = props.myClass === 'day' ? '#000' : '#fff';
const subColor = props.myClass === 'day' ? '#666' : '#999';
const legendColor = props.myClass === 'day' ? ['rgba(0,0,0,0.7)', '#000'] : ['rgba(255,255,255,0.7)', '#fff'];
option.title.textStyle.color = labelColor;
option.title.subtextStyle.color = subColor;
option.legend.textStyle.rich.a.color = legendColor[0];
option.legend.textStyle.rich.b.color = legendColor[1];
myChart.setOption(option);
};
watch(() => props.myClass, () => {//监听模式是否更改,如更改则重新渲染echarts图表
init();
});
</script>
直方图
<template>
<BaseTitle :title="props.title" :myClass="props.myClass"></BaseTitle>
<div class="content">
<div ref="main" style="width: 410px; height: 480px;" :class="props.myClass">
</div>
</div>
</template>
<script setup>
import * as echarts from "echarts"; //引入echarts
import { ref, onMounted, watch, defineProps } from 'vue';
const props = defineProps({
myClass: {
type: String,
default: 'day',
},
title: {
type: String,
default: '',
},
data: {
type: Array,
default: [],
},
});
onMounted(() => {
init();
});
const main = ref();
let myChart;
const init = () => {
if (myChart && !myChart.isDisposed()) { // 检查是否存在并且未被销毁
myChart.dispose(); // 销毁旧的图表实例
}
myChart = echarts.init(main.value); // 初始化新的图表实例
const option = {
grid: {
top: '3%',
left: '3%',
right: '7%',
bottom: '-5%',
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
xAxis: {
show: false,
},
yAxis: {
type: 'category',
data: [],
axisLabel: {
color: ''
},
axisLine: {
show: false, // 不显示纵坐标轴线
},
axisTick: {
show: false, // 不显示纵坐标刻度线
},
},
series: [
{
type: 'bar',
data: [],
label: {
show: true, // 显示标签
position: 'right', // 标签位置(可根据需要自行调整)
color: '', // 标签字体颜色(可根据需要自行调整)
},
itemStyle: {
color: function (params) {
// 判断当前柱子是否为最后一个柱子
if (params.dataIndex === 0) {
return '#949494'; // 最后一个柱子
} else {
return '#2E89DE'; // 其他柱子
}
}
},
},
]
};
option.yAxis.data = props.data.map(item => item.title).reverse();
option.series[0].data = props.data.map(item => item.counts).reverse();
const labelColor = props.myClass === 'day' ? '#000' : 'rgba(255, 255, 255, 0.8)';
option.series[0].label.color = labelColor;
option.yAxis.axisLabel.color = labelColor;
myChart.setOption(option);
};
watch(() => props.myClass, () => { //此处用于切换白天与夜间模式时使用
init();
});
</script>
使用
myClass是白天模式或者夜间模式,title为图表标题,在封装的echarts组件中传入到自己封装的baseTitle组件中,data为图表的数据,color是图表中的颜色,如果对图表颜色需求较多的话,还可以将颜色细分后来封装。
<pie-info :myClass="props.myClass" :title="'风险级别'" :data="props.data.riskLevel"
:color="['#fd612a', '#1580dc']" :unit="'个'"></pie-info>
<bar-info :myClass="props.myClass" :title="'隐患类型'" :data="props.data.type"></bar-info>