81 lines
3.5 KiB
TypeScript
81 lines
3.5 KiB
TypeScript
/* =============================================================================
|
|
* common_util_mass_haul_legend.ts
|
|
* 유토곡선 곡선 이름 · 범례 줄(`common_util_mass_haul_view` 에서 나눔).
|
|
* ========================================================================== */
|
|
|
|
import type { MassHaulBasis, MassHaulSeries } from "./common_util_mass_haul";
|
|
import type { LocaleKey } from "@ui/ui_template_locale";
|
|
import { MASS_HAUL_BALANCE_KEY } from "./common_util_mass_haul";
|
|
import { L } from "./common_util_svg";
|
|
|
|
const BASIS_LABEL: Record<MassHaulBasis, LocaleKey> = {
|
|
cross: "B06_MassHaul_Basis_Cross",
|
|
longitudinal: "B06_MassHaul_Basis_Long",
|
|
};
|
|
|
|
/** 범례·곡선에 함께 쓰는 이름. 색이 곧 산출 기준이다. */
|
|
export function massHaulSeriesLabel(series: MassHaulSeries): string {
|
|
return L(BASIS_LABEL[series.basis]);
|
|
}
|
|
|
|
export function seriesClass(series: MassHaulSeries, base: string): string {
|
|
return `${base} ${base}--${series.basis}`;
|
|
}
|
|
|
|
/**
|
|
* 곡선 표시/숨김 버튼 줄.
|
|
*
|
|
* 그래프 **아래**에 둔다(2026-08-02 사용자 지시). 예전에는 그래프 위에 겹치는 오버레이였는데,
|
|
* 가로 스크롤 컨테이너 안에 있으면 컨테이너 폭 계산에 끼어들어 종단면도와 X축이 어긋난다.
|
|
* 지금은 스크롤 컨테이너 **밖** 패널 본문에 붙어 곡선 폭에 전혀 관여하지 않는다.
|
|
*/
|
|
export function createMassHaulLegend(
|
|
series: MassHaulSeries[],
|
|
visibleKeys: ReadonlySet<string>,
|
|
onToggle: (key: string) => void,
|
|
onResetBalloons?: () => void,
|
|
): HTMLElement {
|
|
const legend = document.createElement("div");
|
|
legend.className = "b06-masshaul__legend";
|
|
legend.setAttribute("role", "group");
|
|
legend.setAttribute("aria-label", L("B06_MassHaul_Legend_Title"));
|
|
const addItem = (key: string, label: string, variantClass: string): void => {
|
|
const shown = visibleKeys.has(key);
|
|
const button = document.createElement("button");
|
|
button.type = "button";
|
|
button.className = variantClass;
|
|
button.classList.toggle("is-off", !shown);
|
|
button.setAttribute("aria-pressed", String(shown));
|
|
button.title = `${label} — ${L(shown ? "B06_MassHaul_Legend_Hide" : "B06_MassHaul_Legend_Show")}`;
|
|
const swatch = document.createElement("span");
|
|
swatch.className = "b06-masshaul__legend-swatch";
|
|
swatch.setAttribute("aria-hidden", "true");
|
|
const text = document.createElement("span");
|
|
text.textContent = label;
|
|
button.append(swatch, text);
|
|
button.addEventListener("click", () => onToggle(key));
|
|
legend.append(button);
|
|
};
|
|
for (const entry of series) {
|
|
addItem(entry.key, massHaulSeriesLabel(entry), seriesClass(entry, "b06-masshaul__legend-item"));
|
|
}
|
|
// 토량 분배는 곡선이 아니라 곡선 위에 얹는 레이어라 스와치 모양을 따로 준다.
|
|
addItem(
|
|
MASS_HAUL_BALANCE_KEY,
|
|
L("B06_MassHaul_Balance_Layer"),
|
|
"b06-masshaul__legend-item b06-masshaul__legend-item--balance",
|
|
);
|
|
// 끌어 옮긴 balloon을 한 번에 자동 배치로 되돌린다(프론트 캐시 + 다음 확정 시 영구저장소).
|
|
if (onResetBalloons && visibleKeys.has(MASS_HAUL_BALANCE_KEY)) {
|
|
const reset = document.createElement("button");
|
|
reset.type = "button";
|
|
reset.className = "b06-masshaul__legend-item b06-masshaul__legend-item--reset";
|
|
reset.textContent = L("B06_MassHaul_Balloon_Reset");
|
|
reset.title = L("B06_MassHaul_Balloon_Reset_Tip");
|
|
reset.addEventListener("click", onResetBalloons);
|
|
// [횡단 기준] 왼쪽(367-1)
|
|
legend.prepend(reset);
|
|
}
|
|
return legend;
|
|
}
|