feat: 순자산 차트에 고/저점 마커 추가
차트보기 구간의 최고점(고·노란 점)·최저점(저·파란 점)에 마커+라벨. 극값이 마지막(현재) 점이면 기존 끝점 마커가 커버하므로 생략(중복 방지). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -3729,6 +3729,19 @@ def _render_net_worth_chart(series: list[tuple[str, int]], current_net: int | No
|
|||||||
svg_parts.append(
|
svg_parts.append(
|
||||||
f'<circle class="peak-dot" cx="{peak_x:.2f}" cy="{peak_y:.2f}" r="3.6" fill="#fbbf24"/>'
|
f'<circle class="peak-dot" cx="{peak_x:.2f}" cy="{peak_y:.2f}" r="3.6" fill="#fbbf24"/>'
|
||||||
)
|
)
|
||||||
|
svg_parts.append(
|
||||||
|
f'<text class="hl-label" x="{peak_x:.2f}" y="{max(peak_y - 10, T + 12):.2f}" text-anchor="middle" fill="#fbbf24" font-size="20" font-weight="700">고</text>'
|
||||||
|
)
|
||||||
|
# 저점 dot — min 시점에 파란 마커 + '저' 라벨. 마지막/고점과 겹치면 생략.
|
||||||
|
low_i = min(range(len(plot_values)), key=lambda i: plot_values[i])
|
||||||
|
if low_i != n - 1 and low_i != peak_i:
|
||||||
|
low_x, low_y = pts[low_i]
|
||||||
|
svg_parts.append(
|
||||||
|
f'<circle class="low-dot" cx="{low_x:.2f}" cy="{low_y:.2f}" r="3.6" fill="#4a8cf0"/>'
|
||||||
|
)
|
||||||
|
svg_parts.append(
|
||||||
|
f'<text class="hl-label" x="{low_x:.2f}" y="{min(low_y + 22, T + ih - 4):.2f}" text-anchor="middle" fill="#4a8cf0" font-size="20" font-weight="700">저</text>'
|
||||||
|
)
|
||||||
# 신고가 마커 — 오늘(마지막) 그려진 값이 이전 모든 포인트를 strict 하게 초과하면 last dot 위에 금색 ring + 라벨.
|
# 신고가 마커 — 오늘(마지막) 그려진 값이 이전 모든 포인트를 strict 하게 초과하면 last dot 위에 금색 ring + 라벨.
|
||||||
# per_period면 '역대 최고 기간 손익', 아니면 누적/순자산 신고가.
|
# per_period면 '역대 최고 기간 손익', 아니면 누적/순자산 신고가.
|
||||||
if n >= 2 and plot_values[-1] > max(plot_values[:-1]):
|
if n >= 2 and plot_values[-1] > max(plot_values[:-1]):
|
||||||
@@ -4667,6 +4680,8 @@ section.tab-content { min-height: calc(100dvh - 110px); }
|
|||||||
.net-chart-svg .line.dashed { stroke-dasharray: 5 4; stroke-opacity: 0.85; }
|
.net-chart-svg .line.dashed { stroke-dasharray: 5 4; stroke-opacity: 0.85; }
|
||||||
.net-chart-svg .last-dot { stroke: #0b0d12; stroke-width: 1.5; }
|
.net-chart-svg .last-dot { stroke: #0b0d12; stroke-width: 1.5; }
|
||||||
.net-chart-svg .peak-dot { stroke: #0b0d12; stroke-width: 1.5; }
|
.net-chart-svg .peak-dot { stroke: #0b0d12; stroke-width: 1.5; }
|
||||||
|
.net-chart-svg .low-dot { stroke: #0b0d12; stroke-width: 1.5; }
|
||||||
|
.net-chart-svg .hl-label { paint-order: stroke; stroke: #0b0d12; stroke-width: 3; }
|
||||||
.net-chart-svg .last-dot.live { stroke: #0b0d12; stroke-width: 2; animation: live-pulse 1.6s ease-in-out infinite; }
|
.net-chart-svg .last-dot.live { stroke: #0b0d12; stroke-width: 2; animation: live-pulse 1.6s ease-in-out infinite; }
|
||||||
.net-chart-svg .live-halo { animation: live-halo 1.6s ease-in-out infinite; }
|
.net-chart-svg .live-halo { animation: live-halo 1.6s ease-in-out infinite; }
|
||||||
.net-chart-svg .ath-ring { animation: ath-pulse 1.8s ease-in-out infinite; }
|
.net-chart-svg .ath-ring { animation: ath-pulse 1.8s ease-in-out infinite; }
|
||||||
|
|||||||
Reference in New Issue
Block a user