eharts图优化
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="center-container">
|
||||
<div class="center-container" :data-window-width="windowWidth">
|
||||
<div class="center-content">
|
||||
<!-- 隐患排查治理 这个标题需要隐藏 2025-10-31 -->
|
||||
<span class="title"></span>
|
||||
@@ -72,7 +72,8 @@
|
||||
</template>
|
||||
|
||||
<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 {
|
||||
@@ -96,6 +97,116 @@ interface 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 组件会在内部创建 div,class 包含 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>({
|
||||
backgroundColor: 'transparent',
|
||||
@@ -335,19 +446,11 @@ watch(() => props.hiddenDangerData?.progress, (newVal, oldVal) => {
|
||||
watch(() => props.hiddenDangerData?.top3Types, (newVal) => {
|
||||
refreshTop3TypesCharts(newVal)
|
||||
}, { deep: true })
|
||||
|
||||
onMounted(() => {
|
||||
// 组件挂载时,如果已有数据,立即更新图表
|
||||
if (props.hiddenDangerData?.progress) {
|
||||
console.log('onMounted: 初始化图表数据', props.hiddenDangerData.progress)
|
||||
refreshProcessCharts(props.hiddenDangerData.progress)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
/* 响应式设计 */
|
||||
@media (width <=1200px) {
|
||||
@media (max-width: 1200px) {
|
||||
.center-container {
|
||||
width: 60vh;
|
||||
height: 60vh;
|
||||
@@ -376,7 +479,7 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
@media (width <=1024px) {
|
||||
@media (max-width: 1024px) {
|
||||
.center-container {
|
||||
width: 55vh;
|
||||
height: 55vh;
|
||||
@@ -425,7 +528,7 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
@media (width <=768px) {
|
||||
@media (max-width: 768px) {
|
||||
.center-container {
|
||||
top: 60%;
|
||||
width: 50vh;
|
||||
@@ -518,7 +621,7 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
@media (width <=480px) {
|
||||
@media (max-width: 480px) {
|
||||
.center-container {
|
||||
top: 65%;
|
||||
width: 45vh;
|
||||
|
||||
Reference in New Issue
Block a user