feat(rebar): 확대기초 다리 배치 상세 탭과 B10 모서리 탭 추가

- core/rebar/footing-legs.ts: 번호별 다리 형태·길이·끝 높이·이음 여부 (계산 함수 결과 사용)
- view/footing-corner-svg.ts: B10-2 → B10-1 모서리 갈고리, 깊이 122.25 / 123.85, l_h 296, 최하단 제외 표시
- 패널 탭 4개 모두 작동 (B10 모서리는 개략도, 단면 비율 아님)
- 테스트: 12개 철근, B2 다리 1723, B6 이음 필요, 모서리 값

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-10-27 14:09:13 +09:00
1 parent df96991c9b
commit ab04c19afb
4 files changed
+152 -5

No files matched your search

+21 -5
View File
@@ -34,6 +34,8 @@ import { DEFAULT_FOOTING_REBAR, FOOTING_REBAR_RANGES, type FootingRebarSettings,
import { footingRuleValues } from './core/rebar/footing';
import { footingSectionSvg } from './view/footing-section-svg';
import { footingSectionLSvg } from './view/footing-section-l-svg';
import { footingCornerSvg } from './view/footing-corner-svg';
import { footingLegRows } from './core/rebar/footing-legs';
import { columnElevationSvg } from './view/column-elevation-svg';
import { type ColumnSection, columnSectionSvg } from './view/column-section-svg';
import { groundSectionSvg } from './view/ground-svg';
@@ -1376,7 +1378,7 @@ function renderFootingSettings(box: HTMLDivElement, pier: Pier): void {
wrap.append(msg, apply);
// 확대기초 단면 탭 (승인 2026-10-26): 교각축 직각 단면 (폭 W) and 교각축 단면 (길이 L) work; the other tabs are next steps.
const footingModel = pier.model;
let footingView: 'W' | 'L' = 'W';
let footingView: 'W' | 'L' | 'D' | 'B10' = 'W';
const tabs = el('div');
tabs.style.display = 'flex';
tabs.style.flexWrap = 'wrap';
@@ -1384,22 +1386,36 @@ function renderFootingSettings(box: HTMLDivElement, pier: Pier): void {
const figBox = el('div');
const drawFootingFigure = (): void => {
tabs.replaceChildren();
for (const [view, label, enabled] of [['W', '교각축 직각 단면 (폭 W)', true], ['L', '교각축 단면 (길이 L)', true], ['D', '다리 배치 상세', false], ['B10', 'B10 모서리', false]] as const) {
for (const [view, label, enabled] of [['W', '교각축 직각 단면 (폭 W)', true], ['L', '교각축 단면 (길이 L)', true], ['D', '다리 배치 상세', true], ['B10', 'B10 모서리', true]] as const) {
const b = el('button', label, 'btn small');
b.type = 'button';
b.setAttribute('aria-pressed', String(view === footingView));
b.disabled = !enabled;
if (!enabled) b.title = '다음 단계에서 추가';
if (enabled) b.addEventListener('click', () => {
footingView = view as 'W' | 'L';
footingView = view as 'W' | 'L' | 'D' | 'B10';
drawFootingFigure();
});
tabs.appendChild(b);
}
figBox.replaceChildren();
if (footingView === 'D') {
// 다리 배치 상세 (승인 2026-10-27): leg shape, leg length and leg top per bar; splices where the bar exceeds the 12000 standard.
const table = el('table', undefined, 'grid-table');
for (const h of ['번호', '규격', '다리 형태', '다리 길이 (mm)', '다리 끝 높이 (하면 기준, mm)', '전체 길이 (mm)', '이음']) table.appendChild(el('th', h));
for (const r of footingLegRows(footingModel)) {
const tr = el('tr');
tr.append(el('td', r.bar), el('td', r.size), el('td', r.shape), el('td', r.legLength === null ? '—' : r.legLength.toFixed(0)), el('td', r.legTop === null ? '—' : r.legTop.toFixed(0)), el('td', r.total.toFixed(0)), el('td', r.splice ? '겹침 필요 (12000 초과)' : '—'));
table.appendChild(tr);
}
figBox.appendChild(table);
figBox.appendChild(el('p', '다리 길이는 12d 기준 (Q-B5 확인 필요). B11·B12 갈고리는 l_h 246.', 'muted small'));
return;
}
const sectionFig = el('figure', undefined, 'ground-fig');
sectionFig.innerHTML = footingView === 'W' ? footingSectionSvg(footingModel) : footingSectionLSvg(footingModel);
sectionFig.appendChild(el('figcaption', footingView === 'W' ? '교각축 직각 단면 (폭 W) · 실제 비율 · 다리 생략' : '교각축 단면 (길이 L) · 실제 비율 · 다리 생략', 'muted small'));
const captions = { W: '교각축 직각 단면 (폭 W) · 실제 비율 · 다리 생략', L: '교각축 단면 (길이 L) · 실제 비율 · 다리 생략', B10: 'B10 모서리 · 개략도 (단면 비율 아님)' } as const;
sectionFig.innerHTML = footingView === 'W' ? footingSectionSvg(footingModel) : footingView === 'L' ? footingSectionLSvg(footingModel) : footingCornerSvg(footingModel);
sectionFig.appendChild(el('figcaption', captions[footingView], 'muted small'));
figBox.appendChild(sectionFig);
};
drawFootingFigure();