Files
sgxt_web/src/views/home/echarts/3DbarEcharts.vue

235 lines
4.8 KiB
Vue
Raw Normal View History

2025-04-16 23:06:01 +08:00
<template>
<div style="height:100%;width:100%" :id="echartsId"></div>
</template>
<script setup>
import * as echarts from "echarts";
2025-12-27 11:10:31 +08:00
import { onMounted, ref, reactive, defineProps, onUnmounted, watch, nextTick } from "vue";
2025-04-16 23:06:01 +08:00
const props = defineProps({
2026-01-16 12:40:42 +08:00
echartsId: {
type: String,
default: '3DbarId'
2025-04-16 23:06:01 +08:00
},
2026-01-16 12:40:42 +08:00
data: {
type: Object,
default: () => { }
2025-04-16 23:06:01 +08:00
}
});
2025-12-27 11:10:31 +08:00
// 保存echarts实例
const myChart = ref(null);
2025-04-16 23:06:01 +08:00
2025-12-27 11:10:31 +08:00
// 定义resize处理函数
const handleResize = () => {
if (myChart.value) {
myChart.value.resize();
}
};
2026-01-16 12:40:42 +08:00
// 组织数据
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
}
2025-12-27 11:10:31 +08:00
function chartFn() {
// 如果已有实例,先销毁
if (myChart.value) {
myChart.value.dispose();
}
2026-01-16 12:40:42 +08:00
2025-12-27 11:10:31 +08:00
// 创建新实例
myChart.value = echarts.init(document.getElementById(props.echartsId));
2026-01-16 12:40:42 +08:00
2025-12-27 11:10:31 +08:00
// 处理数据
2026-01-16 12:40:42 +08:00
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);
}
2025-12-27 11:10:31 +08:00
2026-01-16 12:40:42 +08:00
// 处理颜色
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) : [];
2025-12-27 11:10:31 +08:00
const option = {
2025-04-16 23:06:01 +08:00
grid: {
2026-01-16 12:40:42 +08:00
top: '15%',
2025-12-27 11:10:31 +08:00
left: '2%',
right: '2%',
2026-01-16 12:40:42 +08:00
bottom: '15%',
2025-04-16 23:06:01 +08:00
containLabel: true
},
2025-12-27 11:10:31 +08:00
tooltip: {
trigger: 'axis',
axisPointer: {
2026-01-16 12:40:42 +08:00
type: 'shadow'
2025-12-27 11:10:31 +08:00
},
backgroundColor: 'rgba(255,255,255,1)',
padding: [5, 10],
textStyle: {
color: '#7588E4'
},
extraCssText: 'box-shadow: 0 0 5px rgba(0,0,0,0.3)'
2025-04-16 23:06:01 +08:00
},
2025-12-27 11:10:31 +08:00
xAxis: {
type: 'category',
2026-01-16 12:40:42 +08:00
data: labels,
axisLabel: {
color: '#FFFFFF'
2025-12-27 11:10:31 +08:00
},
axisLine: {
2026-01-16 12:40:42 +08:00
show: false,
lineStyle: {
color: '#1B3F66'
}
2025-12-27 11:10:31 +08:00
},
2026-01-16 12:40:42 +08:00
axisTick: {
show: true
}, axisLabel: {
interval: 0 // 控制标签的显示间隔0 表示全部显示,可以根据需要调整为其他值,例如 1 表示每隔一个显示一个标签。
}
2025-12-27 11:10:31 +08:00
},
yAxis: {
2026-01-16 12:40:42 +08:00
type: "value",
2025-12-27 11:10:31 +08:00
splitLine: {
2026-01-16 12:40:42 +08:00
show:true ,
2025-12-27 11:10:31 +08:00
lineStyle: {
2026-01-16 12:40:42 +08:00
type:'dashed',
color: "rgba(14,95,255,0.5)"
2025-12-27 11:10:31 +08:00
}
},
2026-01-16 12:40:42 +08:00
axisTick: { show: false },
axisLine: { show: false },
axisLabel: { color: props.color },
2025-12-27 11:10:31 +08:00
},
2025-04-16 23:06:01 +08:00
series: [
{
2025-12-27 11:10:31 +08:00
z: 1,
2026-01-16 12:40:42 +08:00
type: 'bar',
name: '柱子',
barWidth: barWidth,
2025-04-16 23:06:01 +08:00
itemStyle: {
2026-01-16 12:40:42 +08:00
borderRadius: [0, 0, 0, 0],
color: color
},
label: {
show: true,
position: 'top'
},
data: values
2025-04-16 23:06:01 +08:00
},
{
2025-12-27 11:10:31 +08:00
z: 2,
2026-01-16 12:40:42 +08:00
name: '柱子底部',
type: "pictorialBar",
data: constData,
symbol: "diamond",
symbolOffset: ["0%", "50%"],
symbolSize: [barWidth - 4, 10],
2025-12-27 11:10:31 +08:00
itemStyle: {
2026-01-16 12:40:42 +08:00
normal: {
color: color
},
},
2025-12-27 11:10:31 +08:00
},
2025-04-16 23:06:01 +08:00
{
2026-01-16 12:40:42 +08:00
z: 3,
name: '柱子顶部',
type: "pictorialBar",
symbolPosition: "end",
data: showData,
symbol: "diamond",
symbolOffset: ["0%", "-50%"],
symbolSize: [barWidth - 4, 10],
2025-04-16 23:06:01 +08:00
itemStyle: {
2026-01-16 12:40:42 +08:00
normal: {
2026-01-29 16:47:04 +08:00
color: props.data.topColor || colorArr[2]
2026-01-16 12:40:42 +08:00
},
},
tooltip: {
show: false,
2025-04-16 23:06:01 +08:00
},
}
]
};
2026-01-16 12:40:42 +08:00
2025-12-27 11:10:31 +08:00
option && myChart.value.setOption(option);
2025-04-16 23:06:01 +08:00
}
2025-12-27 11:10:31 +08:00
// 监听数据变化
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);
});
2025-04-16 23:06:01 +08:00
</script>
2026-01-16 12:40:42 +08:00
<style lang="scss" scoped></style>