- 토적표 칸 = 사용자 견본 32칸 · 보정량계 = 절토 보정량만 · 면 계열(면고르기 · 지장목제거 · 제근 · 노면정리) 거리 = B07 횡단 수량 함수 · 면적 = 앞뒤 평균 × 측점 거리 - 토공집계표 · 운반 시트 = 거창 실무 워크북 같은 이름 시트 칸 · 식 · Q · L = 저장된 유토곡선 배분(서버 · 읽기만) - 시험 test_69_b08_earthwork_tabs.py · 보정량계 시험 정함대로 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UoSr2sqvYtBf1dtQdus88s
134 lines
4.9 KiB
TypeScript
134 lines
4.9 KiB
TypeScript
/* =============================================================================
|
||
* B08_Quantity_UI_Earthwork_Sheets.ts
|
||
* 토공 보조 탭 셋(PLAN 69-2) — 토공집계표 · 평균운반거리 · 종방향 무대운반거리.
|
||
*
|
||
* 칸 · 식 = 거창 실무 워크북 같은 이름 시트 그대로 · 값은 서버가 셈(`…_Engine_Earthwork_Summary`).
|
||
* 운반 Q · L = 저장된 유토곡선 배분(B07 토적도와 같은 정본) — 없으면 그 사유만 보임.
|
||
* ========================================================================== */
|
||
|
||
import {
|
||
cell,
|
||
note,
|
||
tableCard,
|
||
type EarthworkTable,
|
||
type HaulList,
|
||
} from "./B08_Quantity_UI_Earthwork";
|
||
|
||
const fmt = (value: number | null | undefined): string =>
|
||
value == null || !Number.isFinite(value)
|
||
? "—"
|
||
: value.toLocaleString("ko-KR", { maximumFractionDigits: 2 });
|
||
|
||
function row(cells: HTMLElement[], className = ""): HTMLTableRowElement {
|
||
const tr = document.createElement("tr");
|
||
if (className) tr.className = className;
|
||
tr.append(...cells);
|
||
return tr;
|
||
}
|
||
|
||
function station(text: string, span?: { row?: number; col?: number }): HTMLElement {
|
||
const th = cell("th", text, span);
|
||
th.className = "b08-summary__station";
|
||
return th;
|
||
}
|
||
|
||
/** 토공집계표 — 구분 · 공종 · 규격 · 단위 · 계 · 비고 · 같은 구분은 한 칸으로 묶음 */
|
||
export function renderEarthworkSummary(host: HTMLElement, table: EarthworkTable): void {
|
||
const thead = document.createElement("thead");
|
||
thead.append(
|
||
row([station("구분"), ...["공종", "규격", "단위", "계", "비고"].map((t) => cell("th", t))]),
|
||
);
|
||
const tbody = document.createElement("tbody");
|
||
const rows = table.summary;
|
||
rows.forEach((item, i) => {
|
||
const cells: HTMLElement[] = [];
|
||
if (rows[i - 1]?.group !== item.group) {
|
||
let span = 1;
|
||
while (rows[i + span]?.group === item.group) span += 1;
|
||
cells.push(station(item.group, { row: span }));
|
||
}
|
||
const value = cell("td", fmt(item.value));
|
||
value.className = "b08-earthwork__num";
|
||
cells.push(cell("td", item.kind), cell("td", item.spec), cell("td", item.unit), value);
|
||
cells.push(cell("td", item.note));
|
||
tbody.append(row(cells));
|
||
});
|
||
const info = note(
|
||
"토적표 합계 · 평균운반거리 · 종방향 무대운반거리를 실무 토공집계표 식대로 묶음 · " +
|
||
"리핑암 = 연암 · 발파암 = 경암 · 구조물 쪽 줄은 구조물 수량에서(— = 아직 값 없음)",
|
||
);
|
||
host.replaceChildren(tableCard([info], "b08-earthwork__sheet", [thead, tbody]));
|
||
}
|
||
|
||
function haulNote(table: EarthworkTable): HTMLElement[] {
|
||
return table.haul_saved
|
||
? []
|
||
: [note("유토곡선 배분이 저장되지 않았습니다 — 횡단 설계 [확정] 뒤에 채워집니다.")];
|
||
}
|
||
|
||
/** 운반 시트 한 장 — 묶음마다 토량(Q) · 거리(L) · Q×L · 맨 아래 합계 · 아래 평균운반거리 줄 */
|
||
function haulSheet(
|
||
host: HTMLElement,
|
||
table: EarthworkTable,
|
||
groups: Array<[string, HaulList]>,
|
||
info: string,
|
||
): void {
|
||
const thead = document.createElement("thead");
|
||
thead.append(
|
||
row([station("번호", { row: 2 }), ...groups.map(([label]) => cell("th", label, { col: 3 }))]),
|
||
row(groups.flatMap(() => ["토량(Q)", "거리(L)", "Q×L"].map((t) => cell("th", t)))),
|
||
);
|
||
const count = Math.max(0, ...groups.map(([, list]) => list.rows.length));
|
||
const tbody = document.createElement("tbody");
|
||
for (let i = 0; i < count; i += 1) {
|
||
const cells = groups.flatMap(([, list]) => {
|
||
const item = list.rows[i];
|
||
return item ? [fmt(item.q), fmt(item.l), fmt(item.ql)] : ["", "", ""];
|
||
});
|
||
tbody.append(row([station(String(i + 1)), ...cells.map((t) => cell("td", t))]));
|
||
}
|
||
const tfoot = document.createElement("tfoot");
|
||
tfoot.append(
|
||
row(
|
||
[
|
||
station("합계"),
|
||
...groups.flatMap(([, list]) => [fmt(list.q), "", fmt(list.ql)].map((t) => cell("td", t))),
|
||
],
|
||
"b08-earthwork__total",
|
||
),
|
||
);
|
||
const averages = groups.map(([label, list], i) =>
|
||
note(
|
||
`${i + 1}) ${label} 평균운반거리: ${fmt(list.ql)} ÷ ${fmt(list.q)} = ${fmt(list.average_m)} M`,
|
||
),
|
||
);
|
||
const card = tableCard([note(info), ...haulNote(table)], "b08-earthwork__haul", [
|
||
thead,
|
||
tbody,
|
||
tfoot,
|
||
]);
|
||
card.append(...averages);
|
||
host.replaceChildren(card);
|
||
}
|
||
|
||
export function renderHaulDistance(host: HTMLElement, table: EarthworkTable): void {
|
||
haulSheet(
|
||
host,
|
||
table,
|
||
[
|
||
["덤프트럭", table.haul.dump_truck],
|
||
["불도우저", table.haul.dozer],
|
||
],
|
||
"유토곡선 배분의 덤프 · 도저 띠와 떨어진 구간 운반 · 평균 = ΣQ×L ÷ ΣQ (소수 둘째 자리) · 단위 ㎥ · m",
|
||
);
|
||
}
|
||
|
||
export function renderFreeHaul(host: HTMLElement, table: EarthworkTable): void {
|
||
haulSheet(
|
||
host,
|
||
table,
|
||
[["종방향무대", table.haul.free_haul]],
|
||
"유토곡선 배분의 무대(20 m 안) 띠 · 평균 = ΣQ×L ÷ ΣQ (소수 둘째 자리) · 단위 ㎥ · m",
|
||
);
|
||
}
|