From 49c40b20b7ee1cb01c84b6829927f1f3ca9cb829 Mon Sep 17 00:00:00 2001 From: ryan Date: Thu, 18 Jun 2026 19:12:08 +0800 Subject: [PATCH] =?UTF-8?q?fix(wavelet):=20=E4=BF=AE=E5=A4=8D=E5=85=A8?= =?UTF-8?q?=E7=90=83=E6=80=81=E5=8A=BF=E6=9D=BF=E5=9C=B0=E5=9B=BE=E5=AE=B9?= =?UTF-8?q?=E5=99=A8=E5=B0=BA=E5=AF=B8=E4=B8=BA=200?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 地图注册完成后再挂载 ResizeObserver,并在获得有效宽高后才初始化 ECharts。 --- .../components/dashboard/world-stage-map.tsx | 69 +++++++++++++------ .../components/dashboard/world-stage.tsx | 26 ++++--- docs/changelog/index.md | 1 + 3 files changed, 60 insertions(+), 36 deletions(-) diff --git a/Wavelet/frontend/app/(main)/components/dashboard/world-stage-map.tsx b/Wavelet/frontend/app/(main)/components/dashboard/world-stage-map.tsx index f4d83936..792d1722 100644 --- a/Wavelet/frontend/app/(main)/components/dashboard/world-stage-map.tsx +++ b/Wavelet/frontend/app/(main)/components/dashboard/world-stage-map.tsx @@ -214,6 +214,10 @@ export function WorldStageMap({ }, []); useEffect(() => { + if (!mapReady) { + return; + } + const container = chartContainerRef.current; if (!container) { return; @@ -222,18 +226,23 @@ export function WorldStageMap({ const updateSize = () => { const nextWidth = container.clientWidth; const nextHeight = container.clientHeight; + if (nextWidth <= 0 || nextHeight <= 0) { + return; + } setContainerSize((previous) => previous.width === nextWidth && previous.height === nextHeight ? previous - : { width: nextWidth, height: nextHeight }, + : {width: nextWidth, height: nextHeight}, ); }; updateSize(); + const frameId = window.requestAnimationFrame(updateSize); if (typeof ResizeObserver === 'undefined') { window.addEventListener('resize', updateSize); return () => { + window.cancelAnimationFrame(frameId); window.removeEventListener('resize', updateSize); }; } @@ -244,16 +253,17 @@ export function WorldStageMap({ observer.observe(container); return () => { + window.cancelAnimationFrame(frameId); observer.disconnect(); }; - }, []); + }, [mapReady]); const mapPalette = useMemo( () => isDark ? { - areaColor: '#1c1f26', - borderColor: 'rgba(148,163,184,0.16)', + areaColor: '#1e293b', + borderColor: 'rgba(148,163,184,0.32)', labelColor: '#e2e8f0', healthyColor: '#34d399', warningColor: '#fbbf24', @@ -263,8 +273,8 @@ export function WorldStageMap({ dangerBorder: '#fca5a5', } : { - areaColor: '#f4f4f5', - borderColor: 'rgba(148,163,184,0.28)', + areaColor: '#e2e8f0', + borderColor: 'rgba(100,116,139,0.45)', labelColor: '#18181b', healthyColor: '#10b981', warningColor: '#f59e0b', @@ -544,23 +554,38 @@ export function WorldStageMap({ ); } + const chartReady = containerSize.width > 0 && containerSize.height > 0; + return ( -
- { - if (params.data?.route) { - router.push(params.data.route); - } - }, - }} - style={{ height: '100%', width: '100%' }} - /> +
+ {chartReady ? ( + { + if (params.data?.route) { + router.push(params.data.route); + } + }, + }} + style={{ + height: containerSize.height, + width: containerSize.width, + }} + /> + ) : ( +
+ +
+ )}
); } diff --git a/Wavelet/frontend/app/(main)/components/dashboard/world-stage.tsx b/Wavelet/frontend/app/(main)/components/dashboard/world-stage.tsx index 1cd8023f..5b632469 100644 --- a/Wavelet/frontend/app/(main)/components/dashboard/world-stage.tsx +++ b/Wavelet/frontend/app/(main)/components/dashboard/world-stage.tsx @@ -229,21 +229,19 @@ export function WorldStage({
-
- {shouldRenderMap ? ( - - ) : ( -
- -
- )} -
+ {shouldRenderMap ? ( + + ) : ( +
+ +
+ )} {shouldRenderMap && nodes.length === 0 ? (
diff --git a/docs/changelog/index.md b/docs/changelog/index.md index 148faa88..f3382395 100644 --- a/docs/changelog/index.md +++ b/docs/changelog/index.md @@ -22,6 +22,7 @@ sidebar: false - Wavelet 总览仪表盘迁移旧前端「全球态势板」:世界地图展示节点健康与来源国家热度,并保留在线覆盖、流量与容量摘要指标。 - Wavelet 全球态势板视觉对齐系统风格:改用 `Card` / `Badge` / `Progress` 与虚线边框指标卡,地图配色与 tooltip 跟随主题 token。 - Wavelet 全球态势板布局紧凑化:地图高度降至约 260px,指标改为侧栏密集单元格,图例改为行内色点标注。 +- 修复 Wavelet 全球态势板 ECharts 地图在紧凑布局下容器尺寸为 0 导致无法渲染的问题。 - 将 `openflare-server` 后端业务域迁移至 `Wavelet/internal/apps/openflare/`,通过 `/api/*` legacy 兼容层保持旧前端 API 路径不变。 - 新增 OpenFlare 业务表 goose 迁移(`of_options`、`of_origins`、`of_proxy_routes`、`of_nodes`、`of_waf_*`、`of_tls_*`、`of_config_versions`、`of_pages_*`、`of_apply_logs` 等)。