From 3ba6c6a4c2d893b2094792b9d480440d24dd11d3 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Sat, 25 Jul 2026 13:40:25 +0900 Subject: [PATCH] 260725_3 --- .../B06_wf3_ProfileCross_UI_Section_View.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/B06_wf3_ProfileCross/B06_wf3_ProfileCross_UI_Section_View.ts b/B06_wf3_ProfileCross/B06_wf3_ProfileCross_UI_Section_View.ts index 0a050d95..54cea947 100644 --- a/B06_wf3_ProfileCross/B06_wf3_ProfileCross_UI_Section_View.ts +++ b/B06_wf3_ProfileCross/B06_wf3_ProfileCross_UI_Section_View.ts @@ -72,11 +72,12 @@ export function createSectionView( const cachedRowHeight = new Map(); const contentWidth = (): number => { + // 요소가 DOM 밖(detached)이면 computed padding이 ""라 parseFloat이 NaN을 만든다. + // NaN이 renderWidth로 흘러가면 종단 SVG 전 좌표가 NaN이 되므로 0으로 방어한다. const style = getComputedStyle(root); - return Math.max( - 0, - root.clientWidth - parseFloat(style.paddingLeft) - parseFloat(style.paddingRight), - ); + const pad = (value: string): number => Number.parseFloat(value) || 0; + const width = root.clientWidth - pad(style.paddingLeft) - pad(style.paddingRight); + return Number.isFinite(width) ? Math.max(0, width) : 0; }; const selectStation = (stationId: string, scroll: boolean): void => { @@ -107,7 +108,7 @@ export function createSectionView( ); const draw = (): void => { - if (!currentDetail || renderWidth <= 0) return; + if (!currentDetail || !Number.isFinite(renderWidth) || renderWidth <= 0) return; root.replaceChildren(); const detail = currentDetail; cachedYScale = calculateYScale(detail); @@ -194,7 +195,8 @@ export function createSectionView( const resizeObserver = new ResizeObserver(() => { const nextWidth = contentWidth(); - if (nextWidth <= 0 || Math.abs(nextWidth - renderWidth) < 1) return; + if (!Number.isFinite(nextWidth) || nextWidth <= 0 || Math.abs(nextWidth - renderWidth) < 1) + return; window.clearTimeout(resizeTimer); resizeTimer = window.setTimeout(() => { renderWidth = nextWidth;