Files
stock_chart_site/web/components/Sparkline.tsx
claude-owner ae4f07d675 feat(home+search): KOSPI/KOSDAQ 인덱스 카드 + 검색결과 미니 sparkline
- Sparkline 컴포넌트를 PriceHero 내부에서 web/components/Sparkline.tsx 로 분리·재사용
- /api/markets/indices: macro_daily 의 kospi/kosdaq N일 시계열 + 최신값/전일대비
- 홈 IndicesPanel: 두 인덱스 카드(현재값/등락/우측 sparkline)
- /api/symbols/search?with_sparkline=true: 결과 한 번에 최근 30 종가 batch 조회
- SearchBox 결과 행에 mini sparkline + 현재가/등락률 인라인 표시

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 14:46:13 +09:00

50 lines
1.2 KiB
TypeScript

// 가벼운 SVG sparkline. lightweight-charts 인스턴스를 또 만들 필요 없음.
// 종가 시계열을 받아 polyline 으로 그린다. 색상은 호출부에서 결정 (KR 관행: 상승=빨강, 하락=파랑).
type Props = {
values: number[];
stroke: string;
width?: number;
height?: number;
className?: string;
};
export function Sparkline({
values,
stroke,
width = 140,
height = 44,
className,
}: Props) {
if (values.length < 2) return null;
const min = Math.min(...values);
const max = Math.max(...values);
const span = max - min || 1;
const stepX = width / (values.length - 1);
const points = values
.map((v, i) => {
const x = (i * stepX).toFixed(1);
const y = (height - ((v - min) / span) * height).toFixed(1);
return `${x},${y}`;
})
.join(" ");
return (
<svg
width={width}
height={height}
viewBox={`0 0 ${width} ${height}`}
className={`shrink-0 opacity-80 ${className ?? ""}`}
aria-hidden
>
<polyline
points={points}
fill="none"
stroke={stroke}
strokeWidth={1.5}
strokeLinejoin="round"
strokeLinecap="round"
/>
</svg>
);
}