Files
sgxt_web/src/views/home/echarts/moreBarEcharts.vue

144 lines
3.5 KiB
Vue
Raw Normal View History

2025-04-15 14:38:12 +08:00
<template>
<div style="height:100%;width:100%" :id="echartsId"></div>
</template>
<script setup>
import * as echarts from "echarts";
2025-05-19 15:50:38 +08:00
import { el } from "element-plus/es/locale.mjs";
2025-04-15 14:38:12 +08:00
import { on } from "element-plus/lib/utils";
2026-04-15 16:04:50 +08:00
import { onMounted, ref, reactive, defineProps, onUnmounted, watch, nextTick, onBeforeUnmount } from "vue";
2025-04-15 14:38:12 +08:00
const props = defineProps({
echartsId:{
type:String,
default:'moreBarId'
},
data:{
type:Object,
default:{
xData:[],
color:[],
2025-05-19 15:50:38 +08:00
stack:false, //fasle 并排展示 true 堆叠展示
barWidth:'12px',
labelColor:'#fff', //横坐标颜色 - 纵坐标颜色 - 标题颜色
2025-04-15 14:38:12 +08:00
list:[]
}
}
});
2026-04-15 16:04:50 +08:00
// 保存图表实例和 resize 处理函数
let myChart = null;
const handleResize = () => {
myChart && myChart.resize();
};
2025-04-15 14:38:12 +08:00
watch(()=>props.data,val=>{
nextTick(()=>{ init(val) })
},{immediate:true,deep:true})
// 初始化
function init (val) {
let color = val.color;
let list = val.list
let series = list.map((item ,idx)=>{
let obj = {
type: "bar",
name:item.label,
data:item.val,
2025-05-19 15:50:38 +08:00
barWidth: val.barWidth ? val.barWidth: "12px",
2025-04-15 14:38:12 +08:00
}
2025-05-19 15:50:38 +08:00
// 是否渐变
if( Array.isArray(color[idx]) && color[idx].length > 0){
obj.label = { normal:{show:true,position:'top',color:color[idx][0] ? color[idx][0] : '#EB00FF'} }
obj.itemStyle = {
normal: {
color: new echarts.graphic.LinearGradient(0,0,0,1,[{ offset: 0, color: color[idx][0] },{ offset: 1, color: color[idx][1] }],false)
}
}
}else{
obj.itemStyle = {normal: {color: color[idx] ? color[idx] : '#EB00FF'}}
obj.label = { normal:{show:true,position:'top',color:color[idx] ? color[idx] : '#EB00FF'} }
2025-04-15 14:38:12 +08:00
}
2025-05-19 15:50:38 +08:00
// 是否堆叠
if(val.stack) obj.stack = 'total';
2025-04-15 14:38:12 +08:00
return obj;
})
chartFn(series)
}
function chartFn(series) {
2026-04-15 16:04:50 +08:00
// 复用已有的图表实例,避免重复创建
if (!myChart) {
myChart = echarts.init(document.getElementById(props.echartsId));
}
2025-04-15 14:38:12 +08:00
var option = {
grid: {
2025-05-19 15:50:38 +08:00
top: "12%",
2025-04-15 14:38:12 +08:00
right: "2%",
left: "2%",
2025-05-19 15:50:38 +08:00
bottom: "5%",
2025-04-15 14:38:12 +08:00
containLabel:true
},
legend:{
data:props.data.list.map(v=>{return v.label}),
2025-05-19 15:50:38 +08:00
textStyle: { color: props.data.labelColor || "#fff" },
2025-04-15 14:38:12 +08:00
icon:'diamond', //arrow,diamond,roundRect,rect,none,circle
itemWidth:16,
itemHeight:8,
itemGap:10
},
tooltip: {
trigger: "axis",
axisPointer: {
lineStyle: { color: "#ddd" }
},
backgroundColor: "rgba(255,255,255,1)",
padding: [5, 10],
textStyle: { color: "#7588E4" },
extraCssText: "box-shadow: 0 0 5px rgba(0,0,0,0.3)"
},
xAxis: {
type: "category",
data:props.data.xData,
axisTick: { show: false },
axisLine: { show: false },
2025-05-19 15:50:38 +08:00
axisLabel: { color: props.data.labelColor || "#fff",magin:20 },
2025-04-15 14:38:12 +08:00
},
yAxis: {
type: "value",
splitLine: {
show:true ,
lineStyle: {
type:'dashed',
color: "rgba(14,95,255,0.5)"
}
},
axisTick: { show: false },
axisLine: { show: false },
2025-05-19 15:50:38 +08:00
axisLabel: { color: props.data.labelColor || "#fff"},
2025-04-15 14:38:12 +08:00
},
series:series
};
option && myChart.setOption(option);
}
2026-04-15 16:04:50 +08:00
// 组件挂载时添加 resize 监听
onMounted(() => {
window.addEventListener('resize', handleResize);
});
// 组件卸载时清理资源
onBeforeUnmount(() => {
window.removeEventListener('resize', handleResize);
if (myChart) {
myChart.dispose();
myChart = null;
}
});
2025-04-15 14:38:12 +08:00
</script>
<style lang="scss" scoped>
</style>