refactor(b06): 횡단 카드 렌더러 기능별 나눔 — 조정창 두 벌 · 지반선 · 팬 범위 분리(137-1)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018jonfdxn1Xit9bdkNJpE4G
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
|
||||
import type { CrossSection } from "./B06_Section_Api_Fetch";
|
||||
import { computeStructureAreas, type DesignTrim } from "@util/common_util_cross_structure_areas";
|
||||
import { CROSS_PAD, L, svgElement, svgText } from "./B06_Section_UI_Section_Common";
|
||||
import { CROSS_PAD, L, svgElement, svgText, validElevation } from "./B06_Section_UI_Section_Common";
|
||||
|
||||
type Sample = CrossSection["samples"][number];
|
||||
|
||||
@@ -124,3 +124,43 @@ export function applyStructureAreas(
|
||||
design.cut_soil_area_m2 = Number(areas.cutSoilAreaM2.toFixed(4));
|
||||
}
|
||||
}
|
||||
|
||||
/** 원지반선 — 끊긴 샘플(무효 표고)마다 폴리선을 나눠 그린다. `toY` = 표고 → 화면 y(배율 반영). */
|
||||
export function appendGroundProfile(
|
||||
plotLayer: SVGElement,
|
||||
samples: Sample[],
|
||||
x: (offset: number) => number,
|
||||
toY: (elevation: number) => number,
|
||||
): void {
|
||||
const segments: string[] = [];
|
||||
let current: string[] = [];
|
||||
for (const sample of samples) {
|
||||
if (!validElevation(sample)) {
|
||||
if (current.length > 1) segments.push(current.join(" "));
|
||||
current = [];
|
||||
continue;
|
||||
}
|
||||
current.push(`${x(sample.offset_m ?? 0)},${toY(sample.elevation_m)}`);
|
||||
}
|
||||
if (current.length > 1) segments.push(current.join(" "));
|
||||
segments.forEach((points) =>
|
||||
plotLayer.append(svgElement("polyline", { points, class: "b06-chart__cross-profile" })),
|
||||
);
|
||||
}
|
||||
|
||||
/** 팬 한계로 쓸 **그려진 범위** — 캐시 전 구간의 좌우 끝과 표고 상 · 하단(없으면 undefined). */
|
||||
export function drawnContentBounds(
|
||||
samples: Sample[],
|
||||
x: (offset: number) => number,
|
||||
toY: (elevation: number) => number,
|
||||
): { x: number; width: number; y: number; height: number } | undefined {
|
||||
const offsets = samples.map((sample) => sample.offset_m ?? 0);
|
||||
const displayY = samples.filter(validElevation).map((sample) => toY(sample.elevation_m));
|
||||
if (!offsets.length || !displayY.length) return undefined;
|
||||
return {
|
||||
x: x(Math.max(...offsets)),
|
||||
width: x(Math.min(...offsets)) - x(Math.max(...offsets)),
|
||||
y: Math.min(...displayY),
|
||||
height: Math.max(...displayY) - Math.min(...displayY),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user