feat(B05): 종단도 줌·Y 표시 표고창 조작구
- B05_Profile_UI_Profile_Zoom.ts 신규 — 배율 상태(가로 폭 배수·세로 배율·창 중심)와 버튼 7개(+ − ⇕+ ⇕− ▲ ▼ ⤢). 자리는 요약줄 오른쪽 끝(그래프 우측 상단), 설명은 툴팁, 클릭은 stopPropagation 으로 측점 선택에 번지지 않게 함 - X 줌은 폭 배수 — computeProfileLayout 에 zoomX 를 넘겨 측점 간격·폭맞춤 폭에 함께 곱함. 그래프·테이블·편집 버튼층·구조물 레인이 같은 매핑을 쓰므로 넷의 x 정렬이 유지됨 - Y 는 표시 표고창(제안 A) — createLongitudinalProfile 에 elevationOffsetRatio 인자 추가, 창 높이 = 전범위 ÷ 배율, ▲▼ 가 창 높이의 10%씩 중심 이동. 세로 스크롤 없음 - 지반선·계획선·절성토 음영을 플롯 사각형 clipPath 안으로 옮김 — 배율을 올려도 선이 축·측점 라벨 위로 흘러나오지 않음 (B06 은 배율 1·오프셋 0 이라 표시 불변) - 요약줄 렌더러에 trailing 자리 추가, .b05-profile__zoom* CSS 추가 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,7 @@ import { createRunHighlight } from "./B05_Profile_UI_Profile_RunHighlight";
|
||||
import type { StraightRun } from "./B05_Profile_UI_Profile_Straighten";
|
||||
import type { MinCoverPoint } from "./B05_Profile_UI_Profile_MinCover";
|
||||
import { buildStickyYAxis, type RouteMassHaulDrawParams } from "./B05_Profile_UI_Profile_MassHaul";
|
||||
import type { ProfileZoomState } from "./B05_Profile_UI_Profile_Zoom";
|
||||
import { createProfileTable } from "./B05_Profile_UI_Profile_Table";
|
||||
import {
|
||||
CELL_GAP_PX,
|
||||
@@ -83,6 +84,8 @@ export interface ProfileRenderContext {
|
||||
applyEdits: (next: AlignmentEdits) => void;
|
||||
/** [직선화]·[쉬프트] 도구가 그래프 클릭을 먼저 먹는지(먹었으면 기본 선택을 건너뛴다). */
|
||||
handleToolPick: (chainageM: number | null) => boolean;
|
||||
/** 가로 폭 배수·세로 표시 표고창(줌 조작구 상태) — 2026-09-04. */
|
||||
zoom: () => ProfileZoomState;
|
||||
/** 그래프 x → chainage 역변환이 필요한 도구 판정용 — 클릭 지점의 누가거리. */
|
||||
toolActive: () => boolean;
|
||||
/** [쉬프트]로 고른 직선 구간 — 그래프에 빨갛게 강조한다(2026-09-03). */
|
||||
@@ -114,15 +117,20 @@ export function renderProfile(ctx: ProfileRenderContext): void {
|
||||
ctx.renderBalance();
|
||||
|
||||
const longitudinal = detail.longitudinal;
|
||||
const zoom = ctx.zoom();
|
||||
// 가로 줌은 **폭 배수**다 — 캔버스가 넓어지고 가로 스크롤로 훑는다. 그래프·테이블·
|
||||
// 편집 버튼층·구조물 레인이 같은 매핑을 쓰므로 폭 하나만 키우면 넷이 함께 늘어난다.
|
||||
const availableWidth = Math.max(1, body.clientWidth - 15);
|
||||
// 계획선(편집 가능) 상태에서는 측점 간격 기본값(기준×1.5)으로 펼치되 화면이 넓으면
|
||||
// 폭맞춤으로 늘린다. 그 외(구버전·플레인 뷰)는 예전처럼 화면 폭에 맞춰 펼친다.
|
||||
const stationIntervalM = stationInterval ?? alignment?.policy.station_interval_m;
|
||||
const layout =
|
||||
alignment && stationIntervalM
|
||||
? computeProfileLayout(longitudinal, stationIntervalM, availableWidth)
|
||||
? computeProfileLayout(longitudinal, stationIntervalM, availableWidth, zoom.x)
|
||||
: {
|
||||
width: Math.max(availableWidth, longitudinalMinimumWidth(longitudinal, stationInterval)),
|
||||
width:
|
||||
Math.max(availableWidth, longitudinalMinimumWidth(longitudinal, stationInterval)) *
|
||||
zoom.x,
|
||||
originOffset: 0,
|
||||
cellWidth: STATION_SPACING_PX - CELL_GAP_PX,
|
||||
};
|
||||
@@ -219,7 +227,8 @@ export function renderProfile(ctx: ProfileRenderContext): void {
|
||||
createLongitudinalProfile(
|
||||
graphLongitudinal,
|
||||
selectedStationId,
|
||||
1,
|
||||
// 세로 배율 = 표시 표고창 높이의 역수(1 = 표고 전범위).
|
||||
zoom.y,
|
||||
undefined,
|
||||
ctx.selectStation,
|
||||
stationInterval,
|
||||
@@ -243,6 +252,8 @@ export function renderProfile(ctx: ProfileRenderContext): void {
|
||||
// 올린다. 19px는 라벨-버튼 사이가 너무 벌어져 70% 수준(15px)으로 줄였다
|
||||
// (2026-08-04 사용자 지시). B06은 편집 버튼이 없어 0 유지.
|
||||
15,
|
||||
// 표시 표고창의 중심 이동(창 높이 대비 비율) — ▲▼ 버튼이 옮긴다.
|
||||
zoom.offsetRatio,
|
||||
),
|
||||
);
|
||||
// 구조물 우클릭 메뉴 — 측점선 위면 삭제, 빈 자리면 배관 추가. 이동도 여기(측점선 끌기)서 한다.
|
||||
|
||||
Reference in New Issue
Block a user