diff --git a/A00_Common/design/design_profile.ts b/A00_Common/design/design_profile.ts index ac9480145..4937ff064 100644 --- a/A00_Common/design/design_profile.ts +++ b/A00_Common/design/design_profile.ts @@ -14,7 +14,6 @@ import { routeSpansFromStructures } from "../../B05_Profile/B05_Profile_UI_Drainage_Spans"; import { readState, writeState } from "../b_page_state"; import type { SectionDetailResponse } from "../../B06_Section/B06_Section_Api_Fetch"; -import { createWorkflowPanelHandle } from "@ui/ui_template_overlay"; import type { StructureInstance, StructureType, @@ -24,7 +23,6 @@ import { readAlignment, toDesignProfile, } from "../../B05_Profile/logic/B05_Profile_UI_Profile_Data"; -import { createProgressCircle } from "@ui/ui_template_progress"; import { showToast } from "@ui/ui_template_elements"; import { saveProfileAlignment } from "../../B05_Profile/B05_Profile_Api_Fetch"; import { hasStaleDesigns } from "../../B06_Section/B06_Section_UI_Section_Common"; @@ -86,11 +84,7 @@ import { createProfileOverlays } from "./design_profile_overlays"; import { bindProfileViewport, createSelectionReveal } from "./design_profile_viewport"; import { CROSS_PREVIEW_DEBOUNCE_MS, type DesignProfileContext } from "./design_profile_context"; import { pageRouteId } from "./design_page_route"; -import "../../B06_Section/B06_Section_UI_Style.css"; -// SVG 차트 색상(.b06-chart__*)의 정의처는 _Style_Cross.css다. 이걸 빼면 B05로 바로 진입했을 때 -// 배경 rect가 브라우저 기본 fill(검정)로 그려진다 — B06을 먼저 방문해야 정상으로 보이던 원인. -import "../../B06_Section/B06_Section_UI_Style_Cross.css"; -import "../../B06_Section/B06_Section_UI_Style_Cross_Areas.css"; +import { createProfileFrame } from "./design_profile_frame"; // 판 뼈대 · 종단 CSS(700줄 한계) export type { DesignOverlayBoard, @@ -104,30 +98,8 @@ export type { DesignProfileContext } from "./design_profile_context"; export function createDesignProfile(ctx: DesignProfileContext) { const { projectId, onSelectStation, onResetAll, callbacks } = ctx; adoptLegacyProfileKeys(); - const root = document.createElement("section"); - root.className = "b05-route-profile"; - root.dataset.view = ctx.view; - // 이름표 "종단" — 무엇의 손잡이인지 화살표 옆에 밝힌다(2026-08-04 사용자 지시). - const panelHandle = createWorkflowPanelHandle("bottom", "down", "종단"); - const balanceBar = document.createElement("div"); - balanceBar.className = "b05-route-profile__balance"; - const body = document.createElement("div"); - body.className = "b05-route-profile__body"; - const empty = document.createElement("p"); - empty.className = "b05-route-profile__empty"; - empty.textContent = "최적 경로를 계산하면 종단면도가 표시됩니다."; - body.append(empty); - // 종단면 본문 + 우측 판(배수유역도)을 나란히 놓는 2단 구성. - // 우측 판이 이 안에 있으므로 하단 패널을 접으면 함께 사라진다(사용자 지시). - // 그래프 영역 정중앙 로딩 서클 — 종단면 자료가 도착할 때까지 빈 안내만 보인다. - // body는 그릴 때마다 자식이 통째로 교체되므로 서클은 감싸는 칸에 둔다. - const progress = createProgressCircle({ overlay: true }); - progress.root.hidden = true; - const bodyWrap = document.createElement("div"); - bodyWrap.className = "b05-route-profile__body-wrap"; - // 절토·성토 요약 줄은 **종단 쪽 열 안**에 둔다 — 패널 전체 폭에 걸치면 우측 배수유역도 - // 구분선이 그 높이만큼 끊겨 보인다(2026-08-04 사용자 보고). - bodyWrap.append(balanceBar, body, progress.root); + const { root, panelHandle, balanceBar, body, empty, progress, bodyWrap, content, trailing } = + createProfileFrame(ctx.view); // 유토곡선 · 테이블 — 종단 칸 바닥 겹침 판(2026-08-04 · 392-2) · 위 경계 리사이저로 높이 조절. // 서브패널 리사이저를 끄는 동안엔 메인 드래그와 같은 **경량 동기화**만 프레임마다 돌리고 // (차트 SVG·테이블 재생성은 무거워 덜컹였다 — 2026-08-06 분석 원인 3), 전체 재구성은 @@ -144,8 +116,6 @@ export function createDesignProfile(ctx: DesignProfileContext) { body, onChange: subPanelChanged, }); - const content = document.createElement("div"); - content.className = "b05-route-profile__content"; /** 횡단배수 최소 계획고 대상(배수관·BOX암거) — 관 목록이 바뀔 때 갱신한다. */ let minCoverTargets: MinCoverPoint[] = []; /** 최소고를 편집에서 강제할지 — 종단 보기 「페이지 설정」 체크박스를 따라온다(기본 해제). @@ -270,8 +240,6 @@ export function createDesignProfile(ctx: DesignProfileContext) { let updateElevationWindow: (() => ElevationWindowResult | null) | null = null; /** 계획고 편집 버튼(▲▼)을 누르고 있는 동안 Y 축을 고정한다(`_Profile_Drag` 몫). */ const elevationHold = createElevationHold(body, () => draw()); - const trailing = document.createElement("div"); - trailing.className = "b05-route-profile__trailing"; trailing.append(profileZoom.bar); /** 도구 묶음은 그릴 때마다 새로 만든다 — 맨 앞([초기화] 왼쪽)에 `toolLead` 를 다시 옮겨 붙인다. */ const withToolLead = (wrap: HTMLElement): HTMLElement => { diff --git a/A00_Common/design/design_profile_frame.ts b/A00_Common/design/design_profile_frame.ts new file mode 100644 index 000000000..f014d74a0 --- /dev/null +++ b/A00_Common/design/design_profile_frame.ts @@ -0,0 +1,45 @@ +/* ============================================================================= + * A00_Common/design/design_profile_frame.ts + * 종단도 한 벌의 **판 뼈대**(DOM 틀) — `design_profile.ts` 에서 갈라냄(700줄 한계 · 472-5). + * 그리기 · 편집 · 상태는 저쪽 몫 · 여기는 칸만 만들어 돌려줌. + * ========================================================================== */ + +import { createWorkflowPanelHandle } from "@ui/ui_template_overlay"; +import { createProgressCircle } from "@ui/ui_template_progress"; +import "../../B06_Section/B06_Section_UI_Style.css"; +// SVG 차트 색상(.b06-chart__*)의 정의처는 _Style_Cross.css다. 이걸 빼면 B05로 바로 진입했을 때 +// 배경 rect가 브라우저 기본 fill(검정)로 그려진다 — B06을 먼저 방문해야 정상으로 보이던 원인. +import "../../B06_Section/B06_Section_UI_Style_Cross.css"; +import "../../B06_Section/B06_Section_UI_Style_Cross_Areas.css"; + +export function createProfileFrame(view: string) { + const root = document.createElement("section"); + root.className = "b05-route-profile"; + root.dataset.view = view; + // 이름표 "종단" — 무엇의 손잡이인지 화살표 옆에 밝힌다(2026-08-04 사용자 지시). + const panelHandle = createWorkflowPanelHandle("bottom", "down", "종단"); + const balanceBar = document.createElement("div"); + balanceBar.className = "b05-route-profile__balance"; + const body = document.createElement("div"); + body.className = "b05-route-profile__body"; + const empty = document.createElement("p"); + empty.className = "b05-route-profile__empty"; + empty.textContent = "최적 경로를 계산하면 종단면도가 표시됩니다."; + body.append(empty); + // 종단면 본문 + 우측 판(배수유역도)을 나란히 놓는 2단 구성. + // 우측 판이 이 안에 있으므로 하단 패널을 접으면 함께 사라진다(사용자 지시). + // 그래프 영역 정중앙 로딩 서클 — 종단면 자료가 도착할 때까지 빈 안내만 보인다. + // body는 그릴 때마다 자식이 통째로 교체되므로 서클은 감싸는 칸에 둔다. + const progress = createProgressCircle({ overlay: true }); + progress.root.hidden = true; + const bodyWrap = document.createElement("div"); + bodyWrap.className = "b05-route-profile__body-wrap"; + // 절토·성토 요약 줄은 **종단 쪽 열 안**에 둔다 — 패널 전체 폭에 걸치면 우측 배수유역도 + // 구분선이 그 높이만큼 끊겨 보인다(2026-08-04 사용자 보고). + bodyWrap.append(balanceBar, body, progress.root); + const content = document.createElement("div"); + content.className = "b05-route-profile__content"; + const trailing = document.createElement("div"); + trailing.className = "b05-route-profile__trailing"; + return { root, panelHandle, balanceBar, body, empty, progress, bodyWrap, content, trailing }; +}