mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-29 14:06:36 +08:00
fix(wavelet): 修复全球态势板地图容器尺寸为 0
地图注册完成后再挂载 ResizeObserver,并在获得有效宽高后才初始化 ECharts。
This commit is contained in:
@@ -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 (
|
||||
<div ref={chartContainerRef} className="h-full w-full">
|
||||
<ReactEChartsCore
|
||||
echarts={echarts}
|
||||
option={mapOption}
|
||||
notMerge
|
||||
lazyUpdate
|
||||
opts={{ renderer: 'canvas' }}
|
||||
onEvents={{
|
||||
click: (params: { data?: MapNodeDatum }) => {
|
||||
if (params.data?.route) {
|
||||
router.push(params.data.route);
|
||||
}
|
||||
},
|
||||
}}
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
/>
|
||||
<div ref={chartContainerRef} className="h-full min-h-0 w-full">
|
||||
{chartReady ? (
|
||||
<ReactEChartsCore
|
||||
echarts={echarts}
|
||||
option={mapOption}
|
||||
notMerge
|
||||
lazyUpdate
|
||||
opts={{renderer: 'canvas'}}
|
||||
onEvents={{
|
||||
click: (params: {data?: MapNodeDatum}) => {
|
||||
if (params.data?.route) {
|
||||
router.push(params.data.route);
|
||||
}
|
||||
},
|
||||
}}
|
||||
style={{
|
||||
height: containerSize.height,
|
||||
width: containerSize.width,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<EmptyState
|
||||
title="全球地图加载中"
|
||||
description="正在测量地图容器尺寸..."
|
||||
iconSize="sm"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -229,21 +229,19 @@ export function WorldStage({
|
||||
<div className="grid gap-3 lg:grid-cols-[minmax(0,1fr)_12.5rem] lg:gap-4">
|
||||
<div
|
||||
ref={mapViewportRef}
|
||||
className="relative h-[200px] overflow-hidden rounded-lg border border-dashed bg-muted/20 sm:h-[240px] lg:h-[260px]"
|
||||
className="relative h-[200px] min-h-[200px] min-w-0 overflow-hidden rounded-lg border border-dashed bg-muted/20 sm:h-[240px] sm:min-h-[240px] lg:h-[260px] lg:min-h-[260px]"
|
||||
>
|
||||
<div className="absolute inset-0">
|
||||
{shouldRenderMap ? (
|
||||
<WorldStageMap nodes={nodes} sourceCountries={sourceCountries} />
|
||||
) : (
|
||||
<div className="flex h-full items-center justify-center px-4">
|
||||
<EmptyState
|
||||
title="地图准备中"
|
||||
description="进入可视区域后加载"
|
||||
iconSize="sm"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{shouldRenderMap ? (
|
||||
<WorldStageMap nodes={nodes} sourceCountries={sourceCountries} />
|
||||
) : (
|
||||
<div className="flex h-full items-center justify-center px-4">
|
||||
<EmptyState
|
||||
title="地图准备中"
|
||||
description="进入可视区域后加载"
|
||||
iconSize="sm"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{shouldRenderMap && nodes.length === 0 ? (
|
||||
<div className="pointer-events-none absolute inset-x-3 bottom-2 z-10">
|
||||
|
||||
@@ -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` 等)。
|
||||
|
||||
Reference in New Issue
Block a user