eharts图优化

This commit is contained in:
chenlin
2026-01-08 17:53:25 +08:00
parent 5066c80e8f
commit fff83a909e

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="center-container"> <div class="center-container" :data-window-width="windowWidth">
<div class="center-content"> <div class="center-content">
<!-- 隐患排查治理 这个标题需要隐藏 2025-10-31 --> <!-- 隐患排查治理 这个标题需要隐藏 2025-10-31 -->
<span class="title"></span> <span class="title"></span>
@@ -72,7 +72,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, watch } from 'vue' import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
import echarts from '@/plugins/echarts'
interface Props { interface Props {
@@ -96,6 +97,116 @@ interface Props {
const props = defineProps<Props>() const props = defineProps<Props>()
// 窗口尺寸响应式变量,用于强制响应式更新
const windowWidth = ref(window.innerWidth)
const windowHeight = ref(window.innerHeight)
// 防抖函数
let resizeTimer: ReturnType<typeof setTimeout> | null = null
// 手动触发 ECharts 图表 resize
const resizeEcharts = () => {
nextTick(() => {
// 查找所有 ECharts 容器并触发 resize
// Echart 组件会在内部创建 divclass 包含 progress-chart
const chartContainers = document.querySelectorAll('.center-container .progress-chart')
chartContainers.forEach((container) => {
try {
const chartInstance = echarts.getInstanceByDom(container as HTMLElement)
if (chartInstance) {
chartInstance.resize()
}
} catch (error) {
console.warn('ECharts resize 失败:', error)
}
})
// 如果上面的选择器找不到,尝试更通用的方式
if (chartContainers.length === 0) {
const allContainers = document.querySelectorAll('.center-container [class*="echart"]')
allContainers.forEach((container) => {
try {
const chartInstance = echarts.getInstanceByDom(container as HTMLElement)
if (chartInstance) {
chartInstance.resize()
}
} catch (error) {
// 忽略错误
}
})
}
})
}
// 监听窗口尺寸变化
const handleResize = () => {
// 立即更新窗口尺寸(用于响应式绑定)
windowWidth.value = window.innerWidth
windowHeight.value = window.innerHeight
// 立即触发一次 ECharts resize快速响应
resizeEcharts()
// 清除之前的定时器
if (resizeTimer) {
clearTimeout(resizeTimer)
}
// 使用防抖,延迟执行样式重新计算(优化性能)
resizeTimer = setTimeout(() => {
// 强制触发样式重新计算 - 通过读取 offsetHeight 触发重排
const container = document.querySelector('.center-container') as HTMLElement
if (container) {
// 触发重排,强制浏览器重新计算样式
void container.offsetHeight
}
// 再次触发 ECharts resize确保完全更新
resizeEcharts()
}, 100) // 100ms 防抖延迟
}
// 全屏切换处理函数(立即执行,不使用防抖)
const handleFullscreenChange = () => {
// 立即更新窗口尺寸
windowWidth.value = window.innerWidth
windowHeight.value = window.innerHeight
// 延迟一点确保 DOM 已更新
setTimeout(() => {
resizeEcharts()
// 强制触发样式重新计算
const container = document.querySelector('.center-container') as HTMLElement
if (container) {
void container.offsetHeight
}
}, 150) // 稍微延迟确保全屏切换完成
}
onMounted(() => {
window.addEventListener('resize', handleResize)
// 监听全屏变化 - 立即执行,不使用防抖
document.addEventListener('fullscreenchange', handleFullscreenChange)
document.addEventListener('webkitfullscreenchange', handleFullscreenChange)
document.addEventListener('mozfullscreenchange', handleFullscreenChange)
document.addEventListener('MSFullscreenChange', handleFullscreenChange)
// 组件挂载时,如果已有数据,立即更新图表
if (props.hiddenDangerData?.progress) {
console.log('onMounted: 初始化图表数据', props.hiddenDangerData.progress)
refreshProcessCharts(props.hiddenDangerData.progress)
}
})
onUnmounted(() => {
if (resizeTimer) {
clearTimeout(resizeTimer)
}
window.removeEventListener('resize', handleResize)
document.removeEventListener('fullscreenchange', handleFullscreenChange)
document.removeEventListener('webkitfullscreenchange', handleFullscreenChange)
document.removeEventListener('mozfullscreenchange', handleFullscreenChange)
document.removeEventListener('MSFullscreenChange', handleFullscreenChange)
})
// 图表引用 // 图表引用
const progressChartOption = ref<any>({ const progressChartOption = ref<any>({
backgroundColor: 'transparent', backgroundColor: 'transparent',
@@ -335,19 +446,11 @@ watch(() => props.hiddenDangerData?.progress, (newVal, oldVal) => {
watch(() => props.hiddenDangerData?.top3Types, (newVal) => { watch(() => props.hiddenDangerData?.top3Types, (newVal) => {
refreshTop3TypesCharts(newVal) refreshTop3TypesCharts(newVal)
}, { deep: true }) }, { deep: true })
onMounted(() => {
// 组件挂载时,如果已有数据,立即更新图表
if (props.hiddenDangerData?.progress) {
console.log('onMounted: 初始化图表数据', props.hiddenDangerData.progress)
refreshProcessCharts(props.hiddenDangerData.progress)
}
})
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
/* 响应式设计 */ /* 响应式设计 */
@media (width <=1200px) { @media (max-width: 1200px) {
.center-container { .center-container {
width: 60vh; width: 60vh;
height: 60vh; height: 60vh;
@@ -376,7 +479,7 @@ onMounted(() => {
} }
} }
@media (width <=1024px) { @media (max-width: 1024px) {
.center-container { .center-container {
width: 55vh; width: 55vh;
height: 55vh; height: 55vh;
@@ -425,7 +528,7 @@ onMounted(() => {
} }
} }
@media (width <=768px) { @media (max-width: 768px) {
.center-container { .center-container {
top: 60%; top: 60%;
width: 50vh; width: 50vh;
@@ -518,7 +621,7 @@ onMounted(() => {
} }
} }
@media (width <=480px) { @media (max-width: 480px) {
.center-container { .center-container {
top: 65%; top: 65%;
width: 45vh; width: 45vh;