From 62edc8fceb830c85f2a81a525fb9dbbefaac7153 Mon Sep 17 00:00:00 2001
From: yaowanxin <3588231647@qq.com>
Date: 星期五, 30 一月 2026 17:10:55 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_New' into dev_New
---
src/components/Echarts/echarts.vue | 135 ++++++++++++++++++++++++++++++++++----------
1 files changed, 104 insertions(+), 31 deletions(-)
diff --git a/src/components/Echarts/echarts.vue b/src/components/Echarts/echarts.vue
index 15e74d8..0e07163 100644
--- a/src/components/Echarts/echarts.vue
+++ b/src/components/Echarts/echarts.vue
@@ -1,12 +1,15 @@
<template>
- <div>
+ <div style="position: relative;">
<div ref="chartRef" :style="chartStyle"></div>
+ <slot></slot>
</div>
</template>
<script setup>
-import { ref, onMounted, onBeforeUnmount, watchEffect } from 'vue'
+import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
import * as echarts from 'echarts'
+
+const emit = defineEmits(['finished'])
// Props
const props = defineProps({
@@ -51,15 +54,15 @@
},
lineColors: {
type: Array,
- default: () => ['#A4EEDA', '#86C1F4', '#91A0FC', '#F6C18B', '#F09595']
+ default: () => []
},
barColors: {
type: Array,
- default: () => ['#A4EEDA', '#86C1F4', '#91A0FC', '#F6C18B', '#F09595']
+ default: () => []
},
pieColors: {
type: Array,
- default: () => ['#A4EEDA', '#86C1F4', '#91A0FC', '#F6C18B', '#F09595']
+ default: () => []
},
loadingOption: {
type: Object,
@@ -70,45 +73,102 @@
maskColor: 'rgba(255, 255, 255, 0.8)',
zlevel: 0
})
- }
+ },
+ color: {
+ type: Array,
+ default: () => []
+ },
+ visualMap: {
+ type: Object,
+ default: () => ({})
+ },
+ option: {
+ type: Object,
+ default: () => ({})
+ },
})
+
+import { watch } from 'vue'
// Refs
const chartRef = ref(null)
let chartInstance = null
+let finishedHandler = null
+let initTimer = null
+let initAttempts = 0
+
+function clearInitTimer() {
+ if (initTimer) {
+ clearTimeout(initTimer)
+ initTimer = null
+ }
+}
+
+function isContainerReady() {
+ const el = chartRef.value
+ if (!el) return false
+ // offsetWidth/offsetHeight 鏇磋创杩戠湡瀹炲竷灞�锛堜负 0 寰�寰�浠h〃杩樻病甯冨眬/涓嶅彲瑙侊級
+ return el.offsetWidth > 0 && el.offsetHeight > 0
+}
+
+function initChartWhenReady() {
+ clearInitTimer()
+ initAttempts += 1
+
+ if (!isContainerReady()) {
+ // 绛夊鍣ㄧ湡姝f湁灏哄锛堥伩鍏嶉灞忓垵濮嬪寲鍋忕Щ/绌虹櫧锛岀儹鏇存柊鍚庢墠姝e父鐨勬儏鍐碉級
+ // 鏈�澶氶噸璇曠害 3 绉掞紝閬垮厤鏃犻檺寰幆
+ if (initAttempts < 60) {
+ initTimer = setTimeout(initChartWhenReady, 50)
+ }
+ return
+ }
+
+ if (chartInstance) return
+ chartInstance = echarts.init(chartRef.value)
+ finishedHandler = () => emit('finished')
+ chartInstance.on('finished', finishedHandler)
+ renderChart()
+ // setOption 鍚庤ˉ涓�娆� resize锛岀‘淇濋灞忓昂瀵告纭�
+ nextTick(() => {
+ if (chartInstance) chartInstance.resize()
+ })
+}
// Methods
function generateChart(option) {
- if (option.series && option.series.length > 0) {
- option.series.forEach((s, index) => {
- if (s.type === 'line') {
- s.itemStyle = {
- color: props.lineColors[index] || props.lineColors[0]
- }
- s.lineStyle = {
- color: props.lineColors[index] || props.lineColors[0]
- }
- } else if (s.type === 'bar') {
- s.itemStyle = {
- color: props.barColors[index] || props.barColors[0]
- }
+ const copiedOption = option
+
+ if (copiedOption.series && copiedOption.series.length > 0) {
+ copiedOption.series.forEach((s, index) => {
+ if (s.type === 'line' && props.lineColors.length) {
+ s.itemStyle = s.itemStyle || {}
+ s.lineStyle = s.lineStyle || {}
+ s.itemStyle.color = props.lineColors[index] || props.lineColors[0]
+ s.lineStyle.color = props.lineColors[index] || props.lineColors[0]
+ } else if (s.type === 'bar' && props.barColors.length) {
+ s.itemStyle = s.itemStyle || {}
+ s.itemStyle.color = props.barColors[index] || props.barColors[0]
}
})
}
- chartInstance.setOption(option)
+ chartInstance.setOption(copiedOption)
}
function renderChart() {
const option = {
+ color: props.color.length ? props.color : undefined,
backgroundColor: props.options.backgroundColor || '#fff',
+ textStyle: props.options.textStyle || { color: '#333' },
xAxis: props.xAxis,
yAxis: props.yAxis,
dataset: props.dataset,
series: props.series,
grid: props.grid,
legend: props.legend,
- tooltip: props.tooltip
+ tooltip: props.tooltip,
+ visualMap: Object.keys(props.visualMap).length ? props.visualMap : undefined,
}
chartInstance.clear()
@@ -122,26 +182,39 @@
// Lifecycle hooks
onMounted(() => {
- chartInstance = echarts.init(chartRef.value)
- renderChart()
+ initAttempts = 0
+ initChartWhenReady()
window.addEventListener('resize', windowResizeListener)
})
onBeforeUnmount(() => {
if (chartInstance) {
window.removeEventListener('resize', windowResizeListener)
+ if (finishedHandler) {
+ chartInstance.off('finished', finishedHandler)
+ finishedHandler = null
+ }
chartInstance.dispose()
chartInstance = null
}
+ clearInitTimer()
})
// Watch all reactive props that affect the chart
-watchEffect(() => {
- // 閬垮厤鍦� mounted 鍓嶈Е鍙�
- if (chartInstance) {
- renderChart()
- }
-}, {
- flush: 'post'
-})
+watch(
+ () => [props.xAxis, props.yAxis, props.series, props.legend, props.tooltip, props.visualMap],
+ () => {
+ // 濡傛灉棣栧睆杩樻病鍒濆鍖栨垚鍔燂紝绛夊緟瀹瑰櫒 ready 鍚庡啀娓叉煋
+ if (!chartInstance) {
+ initChartWhenReady()
+ return
+ }
+ renderChart()
+ // 鏁版嵁鍙樺寲鍚庤ˉ涓�娆� resize锛岄伩鍏嶅竷灞�鍙樺寲瀵艰嚧鐨勫亸绉�
+ nextTick(() => {
+ if (chartInstance) chartInstance.resize()
+ })
+ },
+ { deep: true, immediate: true }
+)
</script>
\ No newline at end of file
--
Gitblit v1.9.3