feat: 자산 차트 단위 경계 세로선 — 일별=주 경계, 월별=연 경계

- 일별 보기: ISO 주차가 바뀌는 첫 점에 세로 점선 (주 단위 구간 인지)
- 월별 보기: 연도가 바뀌는 첫 점에 세로 점선
- per_period 모드는 기존 period-sep과 중복이라 생략, week/year 단위 미표시
- 스타일 .grid-v — 가로 grid와 동일 톤 점선

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
hyowons
2026-06-12 10:03:11 +09:00
parent b5e3fc0f4e
commit ff3652c8b1
@@ -3537,6 +3537,31 @@ def _render_net_worth_chart(series: list[tuple[str, int]], current_net: int | No
label = f'{gv / 1_000_000:,.{dec_m}f}M' if abs(gv) >= 1_000_000 else f'{gv / 1000:,.{dec_k}f}K'
grid_lines.append(f'<text class="axis" x="{L - 6}" y="{gy + 3.5:.2f}" text-anchor="end">{html.escape(label)}</text>')
# 단위 경계 세로선 — 일별=주 경계(ISO 주가 바뀌는 첫 점), 월별=연 경계(연도가 바뀌는 첫 점).
# 그 외 단위는 미표시. per_period 모드는 period-sep(점마다 구분선)이 이미 있어 중복이라 생략.
boundary_lines: list[str] = []
if not per_period and selected_unit in ('day', 'month'):
from datetime import date as _bd_date
def _bkey(ds: str):
if selected_unit == 'day':
try:
iso = _bd_date.fromisoformat(ds).isocalendar()
return (iso[0], iso[1]) # (ISO연, 주차)
except Exception:
return None
return ds[:4] # month → 연도
_prev_bk = _bkey(full[0][0])
for _bi in range(1, n):
_bk = _bkey(full[_bi][0])
if _bk is not None and _prev_bk is not None and _bk != _prev_bk:
_bx = x_at(_bi)
boundary_lines.append(
f'<line class="grid-v" x1="{_bx:.2f}" x2="{_bx:.2f}" y1="{T:.2f}" y2="{T + ih:.2f}" />'
)
if _bk is not None:
_prev_bk = _bk
# 0원 기준선 — 손익 0 높이가 차트 범위 안일 때만 (어디부터 적자/흑자인지 표시). 순자산은 항상 양수라 자동 미표시.
# 기준선(가로선)은 유지하고 '0' 텍스트 라벨만 제거 (관리자님 요청 — M/K 라벨과 겹쳐 보기 번잡).
zero_line = ''
@@ -3704,6 +3729,7 @@ def _render_net_worth_chart(series: list[tuple[str, int]], current_net: int | No
'</linearGradient>'
'</defs>',
''.join(grid_lines),
''.join(boundary_lines),
zero_line,
''.join(period_seps),
]
@@ -4689,6 +4715,7 @@ section.tab-content { min-height: calc(100dvh - 110px); }
}
.net-chart-svg .grid { stroke: #353b4a; stroke-width: 1; stroke-dasharray: 3 3; }
.net-chart-svg .period-sep { stroke: #4a5266; stroke-width: 1; stroke-dasharray: 2 4; opacity: 0.85; }
.net-chart-svg .grid-v { stroke: #353b4a; stroke-width: 1; stroke-dasharray: 3 3; opacity: 0.8; }
.net-chart-svg .zero-line { stroke: #8b93a7; stroke-width: 1.2; stroke-dasharray: 5 3; opacity: 0.9; }
.net-chart-svg .pt-dot { stroke: #0b0d12; stroke-width: 1.2; }
.net-chart-svg .axis { fill: #6b7280; font-size: 14px; font-variant-numeric: tabular-nums; }