import { ResponsiveContainer, ComposedChart, Line, XAxis, YAxis, Tooltip, ReferenceLine, CartesianGrid, } from 'recharts' function CustomTooltip({ active, payload, label }) { if (!active || !payload?.length) return null const price = payload.find(p => p.dataKey === 'price') return (
{label}
{price && (
${Number(price.value).toFixed(2)}
)}
) } export default function PriceChart({ data }) { const { price_series, ma20, ma50, bb_upper, bb_lower, current_price } = data if (!price_series || Object.keys(price_series).length === 0) return null const chartData = Object.entries(price_series).map(([date, price]) => ({ date: date.slice(5), price: Number(price), ma20: ma20 ? Number(ma20) : undefined, ma50: ma50 ? Number(ma50) : undefined, bbUpper: bb_upper ? Number(bb_upper) : undefined, bbLower: bb_lower ? Number(bb_lower) : undefined, })) const prices = chartData.map(d => d.price) const lastPrice = prices[prices.length - 1] const isUp = lastPrice >= prices[0] const lineColor = isUp ? 'var(--buy)' : 'var(--sell)' const allValues = [ ...prices, bb_upper ? Number(bb_upper) : null, bb_lower ? Number(bb_lower) : null, ].filter(Boolean) const minY = Math.min(...allValues) * 0.995 const maxY = Math.max(...allValues) * 1.005 const change = lastPrice - prices[0] const changePct = ((change / prices[0]) * 100).toFixed(2) return (

30-Day Price

{change >= 0 ? '+' : ''}{changePct}%
`$${v.toFixed(0)}`} width={50} /> } /> {/* Bollinger band lines */} {chartData[0]?.bbUpper && ( )} {chartData[0]?.bbLower && ( )} {/* MA50 */} {ma50 && ( )} {/* MA20 */} {ma20 && ( )} {/* Price */} {/* Current price dashed line */}
— Price {ma20 && -- MA20} {ma50 && -- MA50} {bb_upper && -- Bollinger}
) }