feat(B05/B06): 종단 그래프 줌 버튼 단순화 + 세로 자동 맞춤
- 줌 버튼을 셋(줌인·줌아웃·초기화)으로 줄임. 세로 배율·창 이동 버튼 제거 - 배율 1 = 기본값이자 축소 한계 — 한계에 닿은 버튼은 흐리게 죽임 - 세로는 보이는 누가거리 구간의 지반·계획선 범위로 자동(공통 함수 windowElevationRange, B05·B06 종단이 함께 씀). 스크롤이 멈춘 뒤 0.16초에 갱신 - 계획고 편집 버튼을 누르고 있는 동안 Y 축 고정, 손을 떼면 다시 맞춤 - 유토곡선 Y 도 같은 창 기준(전 구간 ±200㎥ 고정 해제) - B06 종단이 쓰던 공통 Y 스케일(calculateYScale) 제거 — 횡단 카드는 원래 안 쓰던 값 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -59,7 +59,6 @@ import {
|
||||
unwrapChart,
|
||||
} from "./B06_Section_UI_Section_View_Panel";
|
||||
import {
|
||||
calculateYScale,
|
||||
CROSS_GRID_GAP,
|
||||
CROSS_GRID_MIN_WIDTH,
|
||||
CROSS_WIDTH,
|
||||
@@ -69,7 +68,9 @@ import {
|
||||
emptyView,
|
||||
inferStationInterval,
|
||||
L,
|
||||
type YScaleOptions,
|
||||
LONG_PAD,
|
||||
longitudinalMaxChainage,
|
||||
windowElevationRange,
|
||||
} from "./B06_Section_UI_Section_Common";
|
||||
|
||||
export type { CrossDesignChange, DesignChangeHandler, RockBoundaryControl };
|
||||
@@ -142,7 +143,6 @@ export function createSectionView(
|
||||
let lastChartAvailable = 0;
|
||||
let chartFitScheduled = false;
|
||||
// 카드 단위 재빌드에 재사용하는 렌더 컨텍스트 (draw에서 갱신)
|
||||
let cachedYScale: YScaleOptions | undefined;
|
||||
let cachedStationInterval = 1;
|
||||
let cachedCardWidth = CROSS_WIDTH;
|
||||
// 같은 행 카드는 같은 높이가 되도록 draw에서 측점별 행 높이를 계산해 둔다(단건 갱신도 이 값 재사용).
|
||||
@@ -473,8 +473,24 @@ export function createSectionView(
|
||||
const heights = chartHeights(lastChartAvailable);
|
||||
const minWidth = longitudinalMinimumWidth(detail.longitudinal, cachedStationInterval);
|
||||
const chartWidth = Math.max(renderWidth, minWidth);
|
||||
// 종단도 높이가 줄면 Y스케일도 그 높이로 다시 잡아야 표고가 잘리지 않는다.
|
||||
cachedYScale = calculateYScale(detail, heights.long);
|
||||
// 종단 그래프의 세로는 **보이는 구간에 자동으로 맞춘다**(2026-09-04 사용자 확정,
|
||||
// B05 와 같은 규칙·같은 함수). 가로 스크롤 위치와 컨테이너 폭이 곧 보이는 구간이다.
|
||||
const maxChainageM = longitudinalMaxChainage(detail.longitudinal);
|
||||
const plotWidth = Math.max(1, chartWidth - LONG_PAD.left - LONG_PAD.right);
|
||||
const toChainage = (px: number): number => ((px - LONG_PAD.left) / plotWidth) * maxChainageM;
|
||||
const viewFromM = Math.max(0, toChainage(keepScrollLeft));
|
||||
const viewToM = Math.min(
|
||||
maxChainageM,
|
||||
toChainage(keepScrollLeft + (chartWrap.clientWidth || chartWidth)),
|
||||
);
|
||||
const longElevationRange = windowElevationRange(
|
||||
[
|
||||
detail.longitudinal.samples,
|
||||
...(detail.longitudinal.design_profiles ?? []).map((profile) => profile.samples),
|
||||
],
|
||||
viewFromM,
|
||||
viewToM,
|
||||
);
|
||||
|
||||
// Y축 눈금을 렌더러에서 받아 가로 스크롤 고정 오버레이로 얹는다(2026-08-04 사용자
|
||||
// 지시 — 테이블 행 이름표처럼 스크롤해도 계속 보이게, B05와 같은 방식).
|
||||
@@ -485,7 +501,8 @@ export function createSectionView(
|
||||
detail.longitudinal,
|
||||
selectedStationId,
|
||||
currentExaggeration,
|
||||
cachedYScale,
|
||||
// 공통 Y 스케일(횡단 카드 몫)을 여기 넘기면 종단이 전 구간 축에 묶여 눌린다.
|
||||
undefined,
|
||||
(stationId) => selectStation(stationId, true),
|
||||
cachedStationInterval,
|
||||
chartWidth,
|
||||
@@ -496,6 +513,11 @@ export function createSectionView(
|
||||
(axis) => {
|
||||
longAxis = axis;
|
||||
},
|
||||
undefined,
|
||||
undefined,
|
||||
0,
|
||||
0,
|
||||
longElevationRange,
|
||||
),
|
||||
),
|
||||
];
|
||||
@@ -517,6 +539,8 @@ export function createSectionView(
|
||||
selectStation: (stationId) => selectStation(stationId, true),
|
||||
toggleSeries,
|
||||
redraw: drawPanel,
|
||||
// 유토곡선도 종단과 같은 창을 본다(2026-09-04).
|
||||
viewRange: { fromM: viewFromM, toM: viewToM },
|
||||
});
|
||||
if (massHaul.chart) nodes.push(massHaul.chart);
|
||||
chartWrap.replaceChildren(...nodes);
|
||||
@@ -553,6 +577,20 @@ export function createSectionView(
|
||||
}
|
||||
}
|
||||
|
||||
/** 가로 스크롤이 이만큼 멈춰 있으면 보이는 구간이 정해진 것으로 보고 세로를 다시 맞춘다. */
|
||||
const SCROLL_SETTLE_MS = 160;
|
||||
let settledScrollLeft = 0;
|
||||
let scrollSettleTimer = 0;
|
||||
// 스크롤·팬 하는 내내 축이 출렁이면 어지럽다 — 멈춘 뒤 한 번만 다시 그린다(2026-09-04).
|
||||
chartWrap.addEventListener("scroll", () => {
|
||||
window.clearTimeout(scrollSettleTimer);
|
||||
scrollSettleTimer = window.setTimeout(() => {
|
||||
if (Math.abs(chartWrap.scrollLeft - settledScrollLeft) < 1) return;
|
||||
settledScrollLeft = chartWrap.scrollLeft;
|
||||
drawPanel();
|
||||
}, SCROLL_SETTLE_MS);
|
||||
});
|
||||
|
||||
const draw = (): void => {
|
||||
if (!currentDetail || !Number.isFinite(renderWidth) || renderWidth <= 0) return;
|
||||
const detail = currentDetail;
|
||||
|
||||
Reference in New Issue
Block a user