fix(regime): 情绪周期时间轴冷加载空白 — useEChart 惰性 init

useEChart 的 init effect 依赖为 [] 仅组件挂载时执行一次, 而情绪周期图的
容器 div 是条件渲染 (hasPhaseData && rows.length > 0)。冷加载/硬刷新时
history 查询异步未返回 → 首帧 rows 为空 → div 不在 DOM → init 扑空且
永不再执行; 数据到达后卡片出现但 ECharts 实例从未创建, 280px 画布永久
空白 (趋势图/分布图容器为无条件渲染故不受影响)。5 分钟缓存内的二次
导航首帧即有数据, 所以表现为"时好时坏"。

修复: init 从挂载 effect 挪入 setOption effect 做惰性创建 — option 变化
时若 div 已挂载且实例不存在则补建, 再 setOption。无条件容器行为不变。

验证: tsc 通过; 新标签页冷加载 /regime 实测 — canvas 数 3 (修复前冷加载
该图为 0), 情绪周期画布 1254x280, 截图确认红线/琥珀柱/蓝虚线/图例/
双轴刻度/缩放滑块/阶段色带全部渲染 (gui-test-screenshots/regime-phase-
chart-after-fix.png)。
This commit is contained in:
shy3130
2026-08-17 12:43:33 +08:00
parent 8929cb310e
commit 5d6669d4f3
2 changed files with 8 additions and 3 deletions
+8 -3
View File
@@ -79,8 +79,6 @@ function useEChart(option: echarts.EChartsOption | null, deps: unknown[]) {
const ref = useRef<HTMLDivElement>(null)
const instRef = useRef<echarts.ECharts | null>(null)
useEffect(() => {
if (!ref.current) return
instRef.current = echarts.init(ref.current, undefined, { renderer: 'canvas' })
const onResize = () => instRef.current?.resize()
window.addEventListener('resize', onResize)
return () => {
@@ -90,7 +88,14 @@ function useEChart(option: echarts.EChartsOption | null, deps: unknown[]) {
}
}, [])
useEffect(() => {
if (instRef.current && option) instRef.current.setOption(option, { notMerge: true })
if (!ref.current) return
// 惰性 init: 图表容器可能条件渲染晚于组件挂载 (如情绪周期图依赖异步查询结果,
// 冷加载时首帧 rows 为空 → div 不在 DOM, 仅挂载时跑一次的 init 会扑空)。
// 数据到达后 option 变化触发本 effect, 此时 div 已挂载 — 补建实例再 setOption。
if (!instRef.current) {
instRef.current = echarts.init(ref.current, undefined, { renderer: 'canvas' })
}
if (option) instRef.current.setOption(option, { notMerge: true })
}, [option, ...deps])
return ref
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB