下载echarts
npm i echarts
饼图对应type为pie
成果图: (数据为动态展示所以要封装组件)
封装组件 为 EPIPieChart.vue
封装组件 通用代码
<template>
</template>
<script setup lang="ts">
import echarts from '@/assets/ts/echarts';
import { nextTick, reactive, watch } from 'vue';
const props = defineProps({
pid: {
type: String,
required: true
},
online: {
type: Number,
required: true
},
offline: {
type: Number,
required: true
}
})
watch([() => props.online, () => props.offline], (newVal) => {
option.series[0].data[0].value = props.online;
option.series[0].data[1].value = props.offline;
initChart();
})
let dataList: { name: string }[] = reactive([]);
nextTick(() => {
const container = document.querySelector('#' + props.pid) as HTMLElement;
initChart(container);
/*
if (container) {
initChart(container);
}
*/
});
const option = {
//echarts配置项
}
let myChart: echarts.ECharts | null = null;
const initChart = (container?: HTMLElement) => {
if (!myChart) myChart = echarts.init(container as HTMLElement);
myChart.setOption(option)
}
}
</script>
<style lang="scss" scoped>
</style>
详细代码如下
<template></template>
<script setup lang="ts">
import { nextTick } from 'vue';
import echarts from '@/assets/ts/echarts';
import { ZRColor } from 'echarts/types/dist/shared';
import useResizeChart from '@/components/CommonChart/hooks/useResizeChart';
const props = defineProps({
// 父容器ID 此处为声明所需要的变量
pid: {
type: String,
required: true,
},
title: {
type: String,
required: true,
},
curData: {
type: Object,
required: true,
},
preData: {
type: Object,
required: true,
},
sequential: {
type: Number,
required: true,
},
// 饼图 颜色
color: {
type: Array as () => ZRColor[],
default: [],
},
});
// 环比 此处需要两组数据,所以添加两个对象
const data = [
{
value: props.curData.value,
label: props.curData.value + ' kW·h',
name: props.curData.title,
},
{
value: props.preData.value,
label: props.preData.value + ' kW·h',
name: props.preData.title,
},
];
nextTick(() => {
const container = document.querySelector('#' + props.pid) as HTMLElement;
if (container) {
const myChart = echarts.init(container);
const upIcon = new URL('../../assets/img/Profile/Charts/up.svg', import.meta.url).href;
const downIcon = new URL('../../assets/img/Profile/Charts/down.svg', import.meta.url).href;
//此处可以根据需要自定义echarts的option类型
const option = {
color: props.color,
title: [
{
text: ` 环比 {${props.sequential > 0 ? 'upIcon' : 'downIcon'}|}`,
subtext: props.sequential + '%',
top: '40%',
left: 'center',
textStyle: {
fontSize: 12,
color: '#fff',
fontWeight: 500,
rich: {
upIcon: {
height: 10,
backgroundColor: {
image: upIcon,
},
},
downIcon: {
height: 10,
backgroundColor: {
image: downIcon,
},
},
},
},
subtextStyle: {
fontSize: 14,
color: '#fff',
},
},
],
// tooltip: {
// trigger: 'item',
// formatter: function (parms: any) {
// const str = parms.marker + '' + parms.name + '</br>' + '用电量:'
+ parms.data.value + ' kW·h' + '</br>' + '占比:' + parms.percent + '%';
// return str;
// },
// },
legend: {
// type: 'scroll',
icon: 'circle',
orient: 'horizontal',
formatter: '{name}用电量',
textStyle: {
color: '#fff',
},
bottom: 0,
height: 250,
},
series: [
{
// 新增: 外环
name: '',
type: 'pie',
radius: ['58%'],
itemStyle: {
color: 'transparent',
borderWidth: 1,
borderColor: '#0fc7c0',
},
data: [100],
animation: false,
// showBackground: true,
// backgroundStyle: {
// color: 'rgba(66, 66, 66, .3)',
// },
},
{
// 新增: 内环
name: '',
type: 'pie',
radius: ['32%'],
avoidLabelOverlap: false,
itemStyle: {
color: 'transparent',
borderWidth: 1,
borderColor: '#0fc7c0',
},
data: [100],
animation: false,
},
{
// 数据环
name: props.title,
type: 'pie',
radius: ['35%', '55%'],
clockwise: false,
// 指示线
label: {
show: true,
position: 'outside',
fontSize: 12,
lineHeight: 16,
color: '#fff',
formatter: '{name|{b}}\n{c}\n',
rich: {
name: {
color: 'inherit', //此时inherit表示文字颜色使用父级对应的值
},
},
},
// 新增: 指示线的样式
labelLine: {
show: true,
lineStyle: {
type: 'dashed', //指示线为虚线
},
},
// 新增: 饼图的样式
itemStyle: {
borderRadius: 10,
borderColor: '#071629',
borderWidth: 4,
},
emphasis: {
scale: false,
},
data: data,
},
],
};
// 是否显示 饼图外环
// if (props.showRing) {
// ringData.forEach(item => {
// option.series.unshift(item);
// });
// }
myChart.setOption(option);
// 自适应 chart
useResizeChart(container, myChart as echarts.ECharts);
}
});
</script>
<style lang="scss" scoped></style>
使用组件
<div id="day-total-electricity">
<EPIPieChart pid="day-total-electricity" title="当日用电量"
:curData="dayElectricity.cur" :preData="dayElectricity.pre" :sequential="siteData.dayCompare" :color="dayColor"></EPIPieChart>
</div>
<div id="month-total-electricity">
<EPIPieChart pid="month-total-electricity" title="当月用电量" :curData="monthElectricity.cur" :preData="monthElectricity.pre" :sequential="siteData.monthCompare" :color="monthColor"></EPIPieChart>
</div>
<script lang="ts" setup>
// 用电概况
//声明日用电量所用的两种颜色
const dayColor = ['#ea713d', '#07ffd5'];
const dayElectricity = computed(() => ({
cur: {
title: '当日',
value: siteData.value.EPITodaySum,
},
pre: {
title: '昨日',
value: siteData.value.EPIYesterdaySum,
},
}));
const monthColor = ['#ff6f92', '#42d3f0'];
const monthElectricity = computed(() => ({
cur: {
title: '当月',
value: siteData.value.EPIThisMonthSum,
},
pre: {
title: '上月',
value: siteData.value.EPILastMonthSum,
},
}));
</script>
useResizeChart.ts文件
用于自适应 echarts 图表大小
import echarts from "@/assets/ts/echarts";
export default function useResizeChart(container: HTMLElement, chart: echarts.ECharts) {
// 监听容器大小变化
const resizeObserver = new ResizeObserver(entries => {
// 重新设置大小
chart.resize({
animation: {
duration: 500
}
});
});
resizeObserver.observe(container);
// onBeforeUnmount(() => {
// // 销毁前解除监听
// resizeObserver.unobserve(container);
// })
}