下载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); // }) }
复制