Files
sgxt_web/src/views/home/echarts/3DbarEcharts.vue
2026-01-29 16:47:04 +08:00

235 lines
4.8 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 { onMounted, ref, reactive, defineProps, onUnmounted, watch, nextTick } from "vue";
const props = defineProps({
echartsId: {
type: String,
default: '3DbarId'
},
data: {
type: Object,
default: () => { }
}
});
// 保存echarts实例
const myChart = ref(null);
// 定义resize处理函数
const handleResize = () => {
if (myChart.value) {
myChart.value.resize();
}
};
// 组织数据
const setData = function (data, constData, showData) {
data.filter(function (item) {
if (item) {
constData.push(1);
showData.push(item);
} else {
constData.push(0);
showData.push({
value: 1,
itemStyle: {
normal: {
borderColor: "rgba(0,0,0,0)",
borderWidth: 2,
color: "rgba(0,0,0,0)",
},
},
});
}
});
}
// 组织颜色
const setColor = function (colorArr) {
let color = {
type: "linear",
x: 0,
x2: 1,
y: 0,
y2: 0,
colorStops: [{
offset: 0,
color: colorArr[0],
},
{
offset: 0.5,
color: colorArr[0],
},
{
offset: 0.5,
color: colorArr[1],
},
{
offset: 1,
color: colorArr[1],
},
],
};
return color
}
function chartFn() {
// 如果已有实例,先销毁
if (myChart.value) {
myChart.value.dispose();
}
// 创建新实例
myChart.value = echarts.init(document.getElementById(props.echartsId));
// 处理数据
const barWidth = 30;
const constData = [];
const showData = [];
const values = props.data.list && Array.isArray(props.data.list) ? props.data.list.map(v => v.val || v.value) : [];
if (Array.isArray(values)) {
setData(values, constData, showData);
}
// 处理颜色
const colorArr = props.data.colors || ["#345A8B", "#387ABD", "#51C0DB"];
const color = setColor(colorArr);
// 安全获取标签数据
const labels = props.data.list && Array.isArray(props.data.list) ? props.data.list.map(v => v.label) : [];
const option = {
grid: {
top: '15%',
left: '2%',
right: '2%',
bottom: '15%',
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
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: labels,
axisLabel: {
color: '#FFFFFF'
},
axisLine: {
show: false,
lineStyle: {
color: '#1B3F66'
}
},
axisTick: {
show: true
}, axisLabel: {
interval: 0 // 控制标签的显示间隔0 表示全部显示,可以根据需要调整为其他值,例如 1 表示每隔一个显示一个标签。
}
},
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.color },
},
series: [
{
z: 1,
type: 'bar',
name: '柱子',
barWidth: barWidth,
itemStyle: {
borderRadius: [0, 0, 0, 0],
color: color
},
label: {
show: true,
position: 'top'
},
data: values
},
{
z: 2,
name: '柱子底部',
type: "pictorialBar",
data: constData,
symbol: "diamond",
symbolOffset: ["0%", "50%"],
symbolSize: [barWidth - 4, 10],
itemStyle: {
normal: {
color: color
},
},
},
{
z: 3,
name: '柱子顶部',
type: "pictorialBar",
symbolPosition: "end",
data: showData,
symbol: "diamond",
symbolOffset: ["0%", "-50%"],
symbolSize: [barWidth - 4, 10],
itemStyle: {
normal: {
color: props.data.topColor || colorArr[2]
},
},
tooltip: {
show: false,
},
}
]
};
option && myChart.value.setOption(option);
}
// 监听数据变化
watch(() => props.data, val => {
nextTick(() => { chartFn() })
}, { immediate: true, deep: true })
// 组件挂载时初始化图表并添加事件监听
onMounted(() => {
chartFn();
window.addEventListener('resize', handleResize);
});
// 组件卸载时清理资源
onUnmounted(() => {
if (myChart.value) {
myChart.value.dispose();
myChart.value = null;
}
window.removeEventListener('resize', handleResize);
});
</script>
<style lang="scss" scoped></style>