"use client"; import { useState } from "react"; import { LineChart, Line, BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, ComposedChart, Area, } from "recharts"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import type { PriceData, PriceStats } from "@/lib/types"; interface PriceChartProps { priceData: PriceData[]; priceStats: PriceStats; ticker: string; } export function PriceChart({ priceData, priceStats, ticker }: PriceChartProps) { const [chartType, setChartType] = useState<"line" | "candlestick">("line"); // 格式化數字 const formatNumber = (num: number) => { return num.toLocaleString('zh-TW', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); }; // 格式化日期(只顯示月-日) const formatDate = (dateStr: string) => { const date = new Date(dateStr); return `${date.getMonth() + 1}/${date.getDate()}`; }; return (
{ticker} 價格走勢 setChartType(v as "line" | "candlestick")}> 折線圖 K線圖
{/* 統計資訊 */}

增長率

= 0 ? 'text-green-600' : 'text-red-600'}`}> {priceStats.growth_rate >= 0 ? '+' : ''}{priceStats.growth_rate}%

時長

{priceStats.duration_days} 天

起始價格

${formatNumber(priceStats.start_price)}

{priceStats.start_date}

結束價格

${formatNumber(priceStats.end_price)}

{priceStats.end_date}

{/* 價格圖表 */}

價格走勢

{chartType === "line" ? ( `$${value.toFixed(0)}`} /> [`$${formatNumber(value)}`, '收盤價']} labelFormatter={(label) => `日期: ${label}`} /> ) : ( // 真正的K線圖(蠟燭圖) `$${value.toFixed(0)}`} /> { if (active && payload && payload.length) { const data = payload[0].payload; return (

日期: {data.Date}

開: ${formatNumber(data.Open)}

收: ${formatNumber(data.Close)}

高: ${formatNumber(data.High)}

低: ${formatNumber(data.Low)}

); } return null; }} /> { const { x, y, width, payload } = props; const { Open, Close, High, Low } = payload; // 計算Y軸的比例尺 const yAxis = props.yAxis; const yScale = (value: number) => { const { domain, height } = yAxis; const [min, max] = domain; return height - ((value - min) / (max - min)) * height; }; const openY = yScale(Open); const closeY = yScale(Close); const highY = yScale(High); const lowY = yScale(Low); // 判斷漲跌 const isUp = Close >= Open; const color = isUp ? '#22c55e' : '#ef4444'; // 綠色上漲,紅色下跌 const fillColor = isUp ? '#22c55e' : '#ef4444'; // K線寬度 const candleWidth = Math.min(width * 0.6, 8); const centerX = x + width / 2; // 實體高度 const bodyHeight = Math.abs(closeY - openY); const bodyY = Math.min(openY, closeY); return ( {/* 上影線 */} {/* 下影線 */} {/* K線實體 */} ); }} />
)}
{/* 交易量圖表 */}

交易量

{ if (value >= 1000000) return `${(value / 1000000).toFixed(1)}M`; if (value >= 1000) return `${(value / 1000).toFixed(1)}K`; return value.toString(); }} /> [value.toLocaleString(), '交易量']} labelFormatter={(label) => `日期: ${label}`} />
); }