vue3中封装echarts组件并实现夜间模式

环境

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>

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leviash

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值