Files
livedash-node/components/charts/bar-chart.tsx

106 lines
2.7 KiB
TypeScript

"use client";
import {
BarChart,
Bar,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
ResponsiveContainer,
Cell,
} from "recharts";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
interface BarChartProps {
data: Array<{ name: string; value: number; [key: string]: any }>;
title?: string;
dataKey?: string;
colors?: string[];
height?: number;
className?: string;
}
const CustomTooltip = ({ active, payload, label }: any) => {
if (active && payload && payload.length) {
return (
<div className="rounded-lg border bg-background p-3 shadow-md">
<p className="text-sm font-medium">{label}</p>
<p className="text-sm text-muted-foreground">
<span className="font-medium text-foreground">
{payload[0].value}
</span>{" "}
sessions
</p>
</div>
);
}
return null;
};
export default function ModernBarChart({
data,
title,
dataKey = "value",
colors = [
"rgb(37, 99, 235)", // Blue (primary)
"rgb(107, 114, 128)", // Gray
"rgb(236, 72, 153)", // Pink
"rgb(34, 197, 94)", // Lime green
"rgb(168, 85, 247)", // Purple
],
height = 300,
className,
}: BarChartProps) {
return (
<Card className={className}>
{title && (
<CardHeader>
<CardTitle className="text-lg font-semibold">{title}</CardTitle>
</CardHeader>
)}
<CardContent>
<ResponsiveContainer width="100%" height={height}>
<BarChart data={data} margin={{ top: 5, right: 30, left: 20, bottom: 5 }}>
<CartesianGrid
strokeDasharray="3 3"
stroke="rgb(229, 231, 235)"
strokeOpacity={0.5}
/>
<XAxis
dataKey="name"
stroke="rgb(100, 116, 139)"
fontSize={12}
tickLine={false}
axisLine={false}
angle={-45}
textAnchor="end"
height={80}
/>
<YAxis
stroke="rgb(100, 116, 139)"
fontSize={12}
tickLine={false}
axisLine={false}
/>
<Tooltip content={<CustomTooltip />} />
<Bar
dataKey={dataKey}
radius={[4, 4, 0, 0]}
className="transition-all duration-200"
>
{data.map((entry, index) => (
<Cell
key={`cell-${index}`}
fill={colors[index % colors.length]}
className="hover:opacity-80"
/>
))}
</Bar>
</BarChart>
</ResponsiveContainer>
</CardContent>
</Card>
);
}