From 4a57272e7295bbbfa1f598e2c6e699abba06ec0c Mon Sep 17 00:00:00 2001 From: umsangdon Date: Fri, 4 Sep 2026 23:19:07 +0900 Subject: [PATCH] =?UTF-8?q?fix(B05,B06):=20=EC=A2=85=EB=8B=A8=20=EA=B7=B8?= =?UTF-8?q?=EB=9E=98=ED=94=84=EB=A5=BC=20=EC=99=94=EB=8B=A4=EA=B0=94?= =?UTF-8?q?=EB=8B=A4=ED=95=98=EB=A9=B4=20Y=EC=B6=95=20=EB=88=88=EA=B8=88?= =?UTF-8?q?=EC=9D=B4=20=EB=B9=84=EB=8D=98=20=EA=B2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 사용자 보고(2026-09-04) — 「종단 그래프 왔다갔다하면 Y축 값이 비는 경우가 있음」. 세로창을 변환으로 옮기면서 눈금을 **배율이 크게 바뀔 때만** 다시 만들게 해 뒀는데, 창이 위아래로 **이동만** 하면 배율은 그대로라 눈금이 한쪽으로 쓸려 나가고 그 자리가 빔. - 새 창에 있어야 할 눈금 수와 화면에 남는 수가 다르면 눈금을 다시 만들게 함(요소 20개 안팎이라 값싸다). 배율 문턱 판정은 그대로 둠. 자체검증(공용 브라우저 임시 탭): 확대 4칸 뒤 좌우로 6번(+900·+900·−600·+1400·−1800·+2400px) 오가며 눈금이 플롯을 덮는지 측정 — 눈금 6~11개가 항상 이어지고 **위·아래 빈틈 최대 37px** (플롯 높이 329px, 창 여유 20%에 해당). 고치기 전에는 플롯 절반이 비었음. 전체 시험 381 통과·17 건너뜀. Co-Authored-By: Claude Opus 5 --- common_util/common_util_chart_ywindow.ts | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/common_util/common_util_chart_ywindow.ts b/common_util/common_util_chart_ywindow.ts index 5a631ea8..f0ad8d96 100644 --- a/common_util/common_util_chart_ywindow.ts +++ b/common_util/common_util_chart_ywindow.ts @@ -130,6 +130,16 @@ function rebuildTicks(baked: Baked, root: ParentNode, center: number, span: numb return true; } +/** 지금 그려져 있는 눈금 글자 중 새 창 안에 남는 개수. */ +function countTicksInside(baked: Baked, scale: number, offset: number): number { + let count = 0; + baked.svg.querySelectorAll(`text[${Y_WINDOW_BAKED_ATTR}]`).forEach((label) => { + const moved = scale * Number(label.getAttribute(Y_WINDOW_BAKED_ATTR)) + offset; + if (moved >= baked.top && moved <= baked.top + baked.height) count += 1; + }); + return count; +} + /** * 종단 그래프의 세로 창을 옮긴다. 대상 그래프가 없거나(고정 배율 B06) 창이 없으면 null. * 좌측 고정 축(`b05-profile__yaxis-tick`)도 같은 식으로 따라 옮긴다. @@ -147,14 +157,20 @@ export function applyElevationWindow( const pxPerM = (baked.exaggeration * baked.height) / span; const scale = pxPerM / baked.pxPerM; - // 배율이 크게 벌어지면 눈금 간격이 원래 의도와 어긋난다 — 눈금만 새로 만든다(요소 20개 - // 안팎). 그래프 전체를 다시 만들던 예전 방식이 34ms 끊김의 원인이었다. + const offset = baked.zero * (1 - scale) + (center - baked.center) * pxPerM; + + // 눈금을 새로 만들 때 — 둘 중 하나만 걸려도 만든다(요소 20개 안팎이라 싸다). + // ① 배율이 크게 벌어짐 — 눈금 간격이 원래 의도(1·2·5 계열)와 어긋난다. + // ② **새 창에 있어야 할 눈금 수와 지금 화면에 남은 수가 다름** — 창이 위아래로 이동만 + // 하면 배율은 그대로인데 눈금이 한쪽으로 쓸려 나가 그 자리가 빈다(2026-09-04 사용자 + // 보고: 「종단 그래프 왔다갔다하면 Y축 값이 비는 경우」). + const wanted = yWindowTickValues(center, span / baked.exaggeration, baked.height).length; + const staying = countTicksInside(baked, scale, offset); let rebuiltTicks = false; - if (scale < TICK_KEEP_MIN || scale > TICK_KEEP_MAX) { + if (scale < TICK_KEEP_MIN || scale > TICK_KEEP_MAX || staying !== wanted) { rebuiltTicks = rebuildTicks(baked, root, center, span); } - const offset = baked.zero * (1 - scale) + (center - baked.center) * pxPerM; const transform = `translate(0 ${offset}) scale(1 ${scale})`; baked.svg.querySelectorAll(`.${Y_WINDOW_CLASS}`).forEach((layer) => { layer.setAttribute("transform", transform);