feat(B05): 구간형 구조물이 놓인 자리를 종단에 늘 띠로 표시

B군(측구·맹암거 등)을 넣어도 **어디에 놓였는지 안 보였음**. 알약은 기준점 한 곳에만 찍히고,
시~종점 띠는 **고른 동안만** 폈기 때문. 측구처럼 길게 이어지는 시설은 「어디부터 어디까지」가
곧 그 시설의 내용이라 늘 보여야 함(2026-09-07 사용자 지시).

- 구간형이면 **늘** 띠를 그림. 고른 것은 두껍고 진하게(4px·0.55), 나머지는 얇고 옅게(3px·0.45).
- **레인 높이는 42px 그대로** — 2-5b 에서 줄여 둔 것을 안 부풀림.
- B05 가 레지스트리를 **한 번만 받아 쓰는 자리에 따라 나눔** — 추가 메뉴는 켜진 종류만
  (종전대로 여섯 군), **알약 레인·군 판정은 전부**. B06 에서 넣은 B군은 레지스트리에서
  꺼져 있어, 켜진 것만 주면 종단에 이름·색 없이 「?」 회색 알약으로 떴을 자리였음.

실측(용화, 구간형 7건) — 띠 **0 → 7개**, 높이 3px, 레인 42px 그대로, 알약 18개 그대로.
B군 6종은 전부 `interval` 이라 확인한 C군과 같은 경로를 탐. 타입 응답 36종에 B군 6종 포함 확인.

평면(지도)은 손대지 않음 — 노선 위에 구간을 얹는 방법이 지금 없어 **별건**으로 둠.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-07 15:06:53 +09:00
co-authored by Claude Opus 5
parent 8a0a8f18e3
commit 76fa78c528
3 changed files with 28 additions and 10 deletions
+10 -5
View File
@@ -301,15 +301,20 @@ export function createStructuresBridge(deps: StructuresBridgeDeps) {
/** 진입·새로고침 때 타입 레지스트리와 구조물 정본을 받아 화면에 채운다. */
async function loadStructures(): Promise<void> {
try {
const [types, stored] = await Promise.all([
fetchStructureTypes(),
// 레지스트리는 **한 번만** 받고 쓰는 자리에 따라 나눈다(2026-09-07).
// · 추가 메뉴 — 켜진 종류만(B05 는 종전대로 여섯 군).
// · 알약 레인·군 판정 — **전부**. B06 에서 넣은 B군(측구·맹암거 등)은 레지스트리에서
// 꺼져 있는데, 켜진 것만 주면 이름·색·군을 못 찾아 종단에 「?」 회색 알약으로 뜬다.
const [allTypes, stored] = await Promise.all([
fetchStructureTypes(true),
fetchStructures(deps.projectId),
]);
deps.panel().structures.setTypes(types);
deps.profilePanel().setStructureTypes(types);
const menuTypes = allTypes.filter((type) => type.enabled);
deps.panel().structures.setTypes(menuTypes);
deps.profilePanel().setStructureTypes(allTypes);
// A군 판정에 쓸 타입 정보 — 횡단배수만 그래프 세로선·틸팅 대상이다.
structureTypeMap = new Map(
types.map((type) => [type.type_id, { group: type.group, name: type.name }]),
allTypes.map((type) => [type.type_id, { group: type.group, name: type.name }]),
);
structureRevision = stored.revision;
// 저장하지 않고 나갔던 조작분이 있으면 그것으로 화면을 세운다(2026-08-29).
@@ -157,15 +157,19 @@ export function buildStructureLane(options: StructureMarksOptions): HTMLElement
? (STRUCTURE_LANE_HEIGHT_PX - SOLO_PILL_HEIGHT_PX) / 2
: LANE_PADDING_PX + row * (PILL_HEIGHT_PX + ROW_GAP_PX);
// 구간형은 고른 동안만 시~종점을 띠로 펼친다.
if (selected && structure.placement === "interval") {
// 구간형은 시~종점을 **늘 띠로** 펼친다(2026-09-07 사용자 지시 — B군을 넣어도 어디에
// 놓였는지 안 보였다). 예전에는 고른 동안만 폈는데, 측구·맹암거처럼 길게 이어지는
// 시설은 「어디부터 어디까지인가」가 곧 그 시설의 내용이라 늘 보여야 한다.
// 고른 것은 진하게, 나머지는 옅게 — 레인 높이(42px)는 그대로다.
if (structure.placement === "interval") {
const band = document.createElement("div");
band.className = "b05-structure__band";
band.className = `b05-structure__band${selected ? " is-selected" : ""}`;
const startPx = options.x(structure.start_m ?? 0);
const endPx = options.x(structure.end_m ?? 0);
band.style.left = `${Math.min(startPx, endPx)}px`;
band.style.width = `${Math.max(Math.abs(endPx - startPx), 2)}px`;
band.style.top = `${top + height / 2 - 1}px`;
// 알약 세로 가운데에 맞춘다 — 띠 두께가 골랐을 때만 4px 라 반값이 다르다.
band.style.top = `${top + height / 2 - (selected ? 2 : 1.5)}px`;
band.style.background = type?.style?.color ?? "#888";
lane.append(band);
}
@@ -86,12 +86,21 @@
}
/* 구간 띠 — 고른 동안에만 시~종점을 펼쳐 보여 준다. */
/* 구간형 시설이 놓인 자리 — 늘 보인다(2026-09-07). 고르지 않은 것은 옅은 실선으로 깔려
있고, 고른 것만 두껍고 진해진다. 길게 이어지는 시설(측구·맹암거)이 많아도 알약을 가리지
않도록 얇게 둔다. */
.b05-structure__band {
position: absolute;
height: 3px;
border-radius: 1.5px;
opacity: 0.45;
pointer-events: none;
}
.b05-structure__band.is-selected {
height: 4px;
border-radius: 2px;
opacity: 0.55;
pointer-events: none;
}
/* 값 벌룬 — 유토곡선 벌룬과 같은 결(테두리 도형 + 여러 줄 텍스트). */