"use client"; import { useEffect, useRef } from "react"; import * as echarts from "echarts"; import type { BarChartDataItem, PieChartDataItem } from "./types"; export interface BarChartProps { data: BarChartDataItem[]; title?: string; dark?: boolean; color?: string; className?: string; } export function BarChart({ data, title, dark = false, color = "#ff4d4f", className = "", }: BarChartProps) { const ref = useRef(null); useEffect(() => { if (!ref.current || data.length === 0) return; const chart = echarts.init(ref.current); const textColor = dark ? "#e2e8f0" : "#334155"; chart.setOption({ title: title ? { text: title, left: "center", textStyle: { color: textColor } } : undefined, tooltip: { trigger: "axis" }, grid: { left: "3%", right: "4%", bottom: "3%", top: title ? 40 : 20, containLabel: true }, xAxis: { type: "category", data: data.map((d) => d.name), axisLabel: { color: textColor }, }, yAxis: { type: "value", axisLabel: { color: textColor }, splitLine: { lineStyle: { color: dark ? "#334155" : "#e2e8f0" } }, }, series: [ { type: "bar", data: data.map((d) => d.value), itemStyle: { color }, barMaxWidth: 36, }, ], }); return () => chart.dispose(); }, [data, title, dark, color]); return
; } export interface PieChartProps { data: PieChartDataItem[]; title?: string; dark?: boolean; className?: string; } const PIE_COLORS = ["#ff4d4f", "#f97316", "#eab308", "#22c55e", "#0ea5e9", "#8b5cf6"]; export function PieChart({ data, title, dark = false, className = "", }: PieChartProps) { const ref = useRef(null); useEffect(() => { if (!ref.current || data.length === 0) return; const chart = echarts.init(ref.current); const textColor = dark ? "#e2e8f0" : "#334155"; chart.setOption({ title: title ? { text: title, left: "center", textStyle: { color: textColor } } : undefined, tooltip: { trigger: "item", formatter: "{b}: {c} ({d}%)" }, legend: { bottom: 0, textStyle: { color: textColor } }, series: [ { type: "pie", radius: ["40%", "70%"], center: ["50%", title ? "45%" : "50%"], data: data.map((d, i) => ({ name: d.name, value: d.value, itemStyle: { color: PIE_COLORS[i % PIE_COLORS.length] }, })), }, ], }); return () => chart.dispose(); }, [data, title, dark]); return
; } export interface LineChartProps { data: { xAxis: string[]; series: { name: string; data: number[] }[] }; title?: string; dark?: boolean; className?: string; } export function LineChart({ data, title, dark = false, className = "", }: LineChartProps) { const ref = useRef(null); useEffect(() => { if (!ref.current || !data.xAxis?.length) return; const chart = echarts.init(ref.current); const textColor = dark ? "#e2e8f0" : "#334155"; chart.setOption({ title: title ? { text: title, left: "center", textStyle: { color: textColor } } : undefined, tooltip: { trigger: "axis" }, legend: { bottom: 0, textStyle: { color: textColor } }, grid: { left: "3%", right: "4%", bottom: 60, top: title ? 40 : 20, containLabel: true }, xAxis: { type: "category", data: data.xAxis, axisLabel: { color: textColor }, }, yAxis: { type: "value", axisLabel: { color: textColor }, splitLine: { lineStyle: { color: dark ? "#334155" : "#e2e8f0" } }, }, series: data.series.map((s, i) => ({ type: "line", name: s.name, data: s.data, smooth: true, itemStyle: { color: PIE_COLORS[i % PIE_COLORS.length] }, })), }); return () => chart.dispose(); }, [data, title, dark]); return
; }