Files
sgxt_web/src/views/home/echarts/moreBarEcharts.vue
2026-04-15 16:04:50 +08:00

144 lines
3.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div style="height:100%;width:100%" :id="echartsId"></div>
</template>
<script setup>
import * as echarts from "echarts";
import { el } from "element-plus/es/locale.mjs";
import { on } from "element-plus/lib/utils";
import { onMounted, ref, reactive, defineProps, onUnmounted, watch, nextTick, onBeforeUnmount } from "vue";
const props = defineProps({
echartsId:{
type:String,
default:'moreBarId'
},
data:{
type:Object,
default:{
xData:[],
color:[],
stack:false, //fasle 并排展示 true 堆叠展示
barWidth:'12px',
labelColor:'#fff', //横坐标颜色 - 纵坐标颜色 - 标题颜色
list:[]
}
}
});
// 保存图表实例和 resize 处理函数
let myChart = null;
const handleResize = () => {
myChart && myChart.resize();
};
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,
barWidth: val.barWidth ? val.barWidth: "12px",
}
// 是否渐变
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'} }
}
// 是否堆叠
if(val.stack) obj.stack = 'total';
return obj;
})
chartFn(series)
}
function chartFn(series) {
// 复用已有的图表实例,避免重复创建
if (!myChart) {
myChart = echarts.init(document.getElementById(props.echartsId));
}
var option = {
grid: {
top: "12%",
right: "2%",
left: "2%",
bottom: "5%",
containLabel:true
},
legend:{
data:props.data.list.map(v=>{return v.label}),
textStyle: { color: props.data.labelColor || "#fff" },
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 },
axisLabel: { color: props.data.labelColor || "#fff",magin:20 },
},
yAxis: {
type: "value",
splitLine: {
show:true ,
lineStyle: {
type:'dashed',
color: "rgba(14,95,255,0.5)"
}
},
axisTick: { show: false },
axisLine: { show: false },
axisLabel: { color: props.data.labelColor || "#fff"},
},
series:series
};
option && myChart.setOption(option);
}
// 组件挂载时添加 resize 监听
onMounted(() => {
window.addEventListener('resize', handleResize);
});
// 组件卸载时清理资源
onBeforeUnmount(() => {
window.removeEventListener('resize', handleResize);
if (myChart) {
myChart.dispose();
myChart = null;
}
});
</script>
<style lang="scss" scoped>
</style>