"use client"
import { cn } from "@/lib/utils"
import React from "react"
import {
CartesianGrid,
Line,
LineChart as RechartsLineChart,
ResponsiveContainer,
Tooltip,
XAxis,
YAxis,
} from "recharts"
interface LineChartProps extends React.HTMLAttributes<HTMLDivElement> {
data: Record<string, any>[]
index: string
categories: string[]
strokeColors?: string[]
tooltipBgColor?: string
tooltipBorderColor?: string
gridColor?: string
valueFormatter?: (value: number) => string
showGrid?: boolean
showTooltip?: boolean
strokeWidth?: number
dotSize?: number
className?: string
}
const LineChart = React.forwardRef<HTMLDivElement, LineChartProps>(
(
{
data = [],
index,
categories = [],
strokeColors = ["var(--foreground)"],
tooltipBgColor = "var(--background)",
tooltipBorderColor = "var(--border)",
gridColor = "var(--muted)",
valueFormatter = (value: number) => value.toString(),
showGrid = true,
showTooltip = true,
strokeWidth = 2,
dotSize = 4,
className,
...props
},
ref
) => {
return (
<div ref={ref} className={cn("h-80 w-full", className)} {...props}>
<ResponsiveContainer width="100%" height="100%">
<RechartsLineChart data={data} margin={{ top: 0, right: 30, left: 0, bottom: 0 }}>
{showGrid && (
<CartesianGrid strokeDasharray="3 3" stroke={gridColor} />
)}
<XAxis
dataKey={index}
axisLine={false}
tickLine={false}
className="text-xs fill-muted-foreground"
/>
<YAxis
axisLine={false}
tickLine={false}
className="text-xs fill-muted-foreground"
tickFormatter={valueFormatter}
/>
{showTooltip && (
<Tooltip
content={({ active, payload, label }) => {
if (!active || !payload?.length) return null
return (
<div
className="border p-2 shadow"
style={{
backgroundColor: tooltipBgColor,
borderColor: tooltipBorderColor
}}
>
<div className="grid grid-cols-2 gap-2">
<div className="flex flex-col">
<span className="text-[0.70rem] uppercase text-muted-foreground">
{index}
</span>
<span className="font-bold text-muted-foreground">
{label}
</span>
</div>
{payload.map((entry, index) => (
<div key={index} className="flex flex-col">
<span className="text-[0.70rem] uppercase text-muted-foreground">
{entry.dataKey}
</span>
<span className="font-bold" style={{ color: entry.color }}>
{valueFormatter(entry.value as number)}
</span>
</div>
))}
</div>
</div>
)
}}
/>
)}
{categories.map((category, index) => {
const strokeColor = strokeColors[index] || strokeColors[0]
return (
<Line
key={category}
dataKey={category}
stroke={strokeColor}
strokeWidth={strokeWidth}
dot={{ r: dotSize, fill: strokeColor }}
activeDot={{ r: dotSize + 2, fill: strokeColor }}
/>
)
})}
</RechartsLineChart>
</ResponsiveContainer>
</div>
)
}
)
LineChart.displayName = "LineChart"
export { LineChart, type LineChartProps }