82 lines
2.6 KiB
TypeScript
82 lines
2.6 KiB
TypeScript
import type {
|
|
LongitudinalSection,
|
|
SectionDetailResponse,
|
|
} from "../B06_wf3_ProfileCross/B06_wf3_ProfileCross_Api_Fetch";
|
|
import { createLongitudinalProfile } from "../B06_wf3_ProfileCross/B06_wf3_ProfileCross_UI_Section_View";
|
|
import "../B06_wf3_ProfileCross/B06_wf3_ProfileCross_UI_Style.css";
|
|
|
|
const COLLAPSED_KEY = "b05-route-profile-collapsed";
|
|
|
|
function normalizedLongitudinal(data: LongitudinalSection): LongitudinalSection {
|
|
return {
|
|
...data,
|
|
samples: data.samples.map((sample) => ({
|
|
...sample,
|
|
elevation_m: sample.elevation_m ?? sample.z ?? null,
|
|
})),
|
|
};
|
|
}
|
|
|
|
export function createRouteProfilePanel(onSelectStation: (stationId: string) => void) {
|
|
const root = document.createElement("section");
|
|
root.className = "b05-route-profile";
|
|
const header = document.createElement("header");
|
|
const toggle = document.createElement("button");
|
|
toggle.type = "button";
|
|
toggle.className = "b05-route-profile__toggle";
|
|
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);
|
|
header.append(toggle);
|
|
root.append(header, body);
|
|
let detail: SectionDetailResponse | null = null;
|
|
let selectedStationId: string | null = null;
|
|
let stationInterval: number | undefined;
|
|
|
|
function draw(): void {
|
|
if (!detail) return;
|
|
body.replaceChildren(
|
|
createLongitudinalProfile(
|
|
normalizedLongitudinal(detail.longitudinal),
|
|
selectedStationId,
|
|
1,
|
|
undefined,
|
|
onSelectStation,
|
|
stationInterval,
|
|
),
|
|
);
|
|
}
|
|
|
|
function setCollapsed(collapsed: boolean): void {
|
|
root.classList.toggle("is-collapsed", collapsed);
|
|
toggle.textContent = collapsed ? "⌃" : "⌄";
|
|
toggle.setAttribute("aria-label", collapsed ? "종단면도 펼치기" : "종단면도 접기");
|
|
toggle.setAttribute("aria-expanded", String(!collapsed));
|
|
sessionStorage.setItem(COLLAPSED_KEY, String(collapsed));
|
|
}
|
|
|
|
toggle.addEventListener("click", () => setCollapsed(!root.classList.contains("is-collapsed")));
|
|
setCollapsed(sessionStorage.getItem(COLLAPSED_KEY) === "true");
|
|
|
|
return {
|
|
root,
|
|
render(nextDetail: SectionDetailResponse, nextStationInterval?: number) {
|
|
detail = nextDetail;
|
|
stationInterval = nextStationInterval;
|
|
draw();
|
|
},
|
|
setSelectedStation(stationId: string | null) {
|
|
selectedStationId = stationId;
|
|
draw();
|
|
},
|
|
clear() {
|
|
detail = null;
|
|
selectedStationId = null;
|
|
body.replaceChildren(empty);
|
|
},
|
|
};
|
|
}
|