fix(rebar): 확대기초 단면 하단 지시선·격자 치수·우측 주석·상단 여백 정리
- 하단 풍선 B2·B4·B3를 각 철근 바로 아래(가운데 기준 좌·중앙·우)에 두고 수직 지시선으로 연결 - 격자 치수 글자를 우측 중앙으로 옮겨 지시선과 겹치지 않게 함 - 뷰박스를 600 × 430으로 넓히고 전체를 20 px 아래로 이동 (우측 주석과 상단 풍선이 잘리지 않음) - 범례와 캡션을 아래로 이동 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8860fb8231
commit
eb6c7bb4ad
1 file changed
+21
-8
@@ -30,7 +30,7 @@ const Y0 = 230;
|
||||
|
||||
export function footingSectionSvg(model: PierModel): string {
|
||||
const foot = model.footings[0];
|
||||
if (!foot) return '<svg viewBox="0 0 560 360" width="560" height="360" role="img" aria-label="확대기초 없음"><text x="20" y="180" font-size="12">확대기초 없음</text></svg>';
|
||||
if (!foot) return '<svg viewBox="0 0 600 430" width="600" height="430" role="img" aria-label="확대기초 없음"><text x="20" y="180" font-size="12">확대기초 없음</text></svg>';
|
||||
const fs = model.footingRebar ?? DEFAULT_FOOTING_REBAR;
|
||||
const L = foot.length * 1000;
|
||||
const W = foot.width * 1000;
|
||||
@@ -139,7 +139,8 @@ export function footingSectionSvg(model: PierModel): string {
|
||||
parts.push(text(x(W / 2) + 5, yDim + 14, `${fs.cSide}`, 'start', COLOR.dim));
|
||||
parts.push(text(x(-W / 2 + fs.cSide) + 2, yDim + 14, `${g.e.toFixed(1)}`, 'start', COLOR.dim));
|
||||
parts.push(text(x(W / 2 - fs.cSide) - 2, yDim + 14, `${g.e.toFixed(1)}`, 'end', COLOR.dim));
|
||||
parts.push(text(cx, yDim - 6, `${g.n}@${fs.sAxis}=${g.G}`, 'middle', COLOR.dim));
|
||||
// The grid string sits right of centre, so the bottom leaders (at the centre and the two sides) do not cross it.
|
||||
parts.push(text(cx + 150, yDim - 6, `${g.n}@${fs.sAxis}=${g.G}`, 'middle', COLOR.dim));
|
||||
parts.push(text(cx, 20, `교각축 직각 단면 · 폭 ${W.toFixed(0)}`, 'middle', '#1F2937'));
|
||||
const xr = X0 + W_PX + 18;
|
||||
parts.push(`<line x1="${xr}" x2="${xr}" y1="${y(H).toFixed(1)}" y2="${y(0).toFixed(1)}" stroke="${COLOR.dim}" stroke-width="0.8"/>`);
|
||||
@@ -159,18 +160,29 @@ export function footingSectionSvg(model: PierModel): string {
|
||||
return `<g class="bubble" data-bubble="${name}" style="cursor:pointer"><line class="leader" data-bar="${name}" x1="${bx.toFixed(1)}" x2="${tx.toFixed(1)}" y1="${edgeY.toFixed(1)}" y2="${ty.toFixed(1)}" stroke="${COLOR.outline}" stroke-width="0.7"/><circle cx="${bx.toFixed(1)}" cy="${by.toFixed(1)}" r="11" fill="#fff" stroke="${COLOR.outline}"/><text x="${bx.toFixed(1)}" y="${(by + 3).toFixed(1)}" font-size="9" text-anchor="middle" fill="${COLOR.outline}">${name}</text></g>`;
|
||||
};
|
||||
const yTop = 40;
|
||||
const yBot = Y0 + 66;
|
||||
const yBot = Y0 + 100;
|
||||
// Each bottom bubble sits straight below its own bar (B2 left of centre, B4 at centre, B3 right of centre) on a bar of the right parity.
|
||||
const nearest = (target: number, parity: number) => {
|
||||
let best = -1;
|
||||
xs.forEach((mm, i) => {
|
||||
if (i % 2 === parity && (best < 0 || Math.abs(mm - target) < Math.abs(xs[best] - target))) best = i;
|
||||
});
|
||||
return best;
|
||||
};
|
||||
const iB2 = nearest(-1930, 1);
|
||||
const iB4 = nearest(0, 0);
|
||||
const iB3 = nearest(1930, 1);
|
||||
const zB11 = js.length > 0 ? fs.cBottom + js[0] * fs.sV : fs.cBottom;
|
||||
parts.push(bubble('B5', xa + 12, yTop, xa + 12, y(z.B5)));
|
||||
parts.push(bubble('B1', x(xs[1]) + 60, yTop, x(xs[1]), y(z.B1)));
|
||||
parts.push(bubble('B11', xb - 20, yTop, xb, y(zB11)));
|
||||
parts.push(bubble('B10-1', X0 - 18, y(fs.cBottom + (levels - 1) * fs.sV / 2), X0 + 2, y(fs.cBottom + (levels - 1) * fs.sV / 2)));
|
||||
parts.push(bubble('B2', cx - 70, yBot, x(xs[1]), y(z.B24)));
|
||||
parts.push(bubble('B4', cx, yBot, x(xs[2]), y(z.B24)));
|
||||
parts.push(bubble('B3', cx + 70, yBot, x(xs[3]), y(z.B3)));
|
||||
parts.push(bubble('B2', x(xs[iB2]), yBot, x(xs[iB2]), y(z.B24)));
|
||||
parts.push(bubble('B4', x(xs[iB4]), yBot, x(xs[iB4]), y(z.B24)));
|
||||
parts.push(bubble('B3', x(xs[iB3]), yBot, x(xs[iB3]), y(z.B3)));
|
||||
|
||||
// Legend (선 모양별, 삽도 기준) and the units note.
|
||||
const yLeg = 330;
|
||||
const yLeg = 352;
|
||||
parts.push(`<line x1="20" x2="44" y1="${yLeg}" y2="${yLeg}" stroke="${COLOR.b5}" stroke-width="1.6"/>${text(50, yLeg + 3, '주철근 (B5–B8)', 'start', COLOR.outline)}`);
|
||||
parts.push(`<circle cx="180" cy="${yLeg}" r="2.6" fill="${COLOR.b14}"/>${text(188, yLeg + 3, '직각·보조 (B1–B4)', 'start', COLOR.outline)}`);
|
||||
parts.push(`<line x1="330" x2="330" y1="${yLeg - 8}" y2="${yLeg + 8}" stroke="${COLOR.b9}" stroke-width="1"/>${text(338, yLeg + 3, '전단·띠 (B9)', 'start', COLOR.outline)}`);
|
||||
@@ -178,5 +190,6 @@ export function footingSectionSvg(model: PierModel): string {
|
||||
parts.push(`<line x1="250" x2="274" y1="${yLeg + 22}" y2="${yLeg + 22}" stroke="${COLOR.b11}" stroke-width="1.2" stroke-dasharray="6 3"/>${text(280, yLeg + 25, '조립 (B11·B12)', 'start', COLOR.outline)}`);
|
||||
parts.push(text(20, yLeg + 48, '치수 mm · 높이 방향은 실제 비율 · 다리 생략 (B6 다리는 주석) · 기준: 확대기초 하면 0', 'start', COLOR.outline));
|
||||
|
||||
return `<svg viewBox="0 0 560 360" width="560" height="360" role="img" aria-label="확대기초 교각축 직각 단면">${parts.join('')}</svg>`;
|
||||
// The whole drawing shifts down 20 px so the top bubbles are not clipped.
|
||||
return `<svg viewBox="0 0 600 430" width="600" height="430" role="img" aria-label="확대기초 교각축 직각 단면"><g transform="translate(0 20)">${parts.join('')}</g></svg>`;
|
||||
}
|
||||
Reference in new issue
Block a user