pmtool / src /components /dashboard /chart-card.tsx
devarshia5's picture
Upload 487 files
d97b8f9 verified
Raw
History Blame Contribute Delete
5.5 kB
import React from "react";
import { cn } from "@/lib/utils";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
Area,
AreaChart,
Bar,
BarChart,
CartesianGrid,
Line,
LineChart,
ResponsiveContainer,
Tooltip,
XAxis,
YAxis,
} from "recharts";
type ChartType = "bar" | "line" | "area";
interface ChartCardProps {
title: string;
data: Array<{
name: string;
value: number;
color?: string;
}>[];
colors?: string[];
type?: ChartType;
className?: string;
showGrid?: boolean;
}
const ChartCard = ({
title,
data,
colors = ["#F97316", "#E53E3E"],
type = "bar",
className,
showGrid = false,
}: ChartCardProps) => {
const renderChart = () => {
switch (type) {
case "bar":
return (
<ResponsiveContainer width="100%" height={250}>
<BarChart data={data[0]}>
{showGrid && <CartesianGrid strokeDasharray="3 3" vertical={false} />}
<XAxis
dataKey="name"
axisLine={false}
tickLine={false}
tick={{ fontSize: 12 }}
dy={10}
/>
<YAxis
axisLine={false}
tickLine={false}
tick={{ fontSize: 12 }}
dx={-10}
/>
<Tooltip
contentStyle={{
backgroundColor: "rgba(255, 255, 255, 0.8)",
borderRadius: "8px",
border: "none",
boxShadow: "0 2px 10px rgba(0, 0, 0, 0.1)",
}}
/>
<Bar dataKey="value" fill={colors[0]} radius={[4, 4, 0, 0]} />
</BarChart>
</ResponsiveContainer>
);
case "line":
return (
<ResponsiveContainer width="100%" height={250}>
<LineChart data={data.length > 1 ? undefined : data[0]}>
{showGrid && <CartesianGrid strokeDasharray="3 3" vertical={false} />}
<XAxis
dataKey="name"
axisLine={false}
tickLine={false}
tick={{ fontSize: 12 }}
dy={10}
/>
<YAxis
axisLine={false}
tickLine={false}
tick={{ fontSize: 12 }}
dx={-10}
/>
<Tooltip
contentStyle={{
backgroundColor: "rgba(255, 255, 255, 0.8)",
borderRadius: "8px",
border: "none",
boxShadow: "0 2px 10px rgba(0, 0, 0, 0.1)",
}}
/>
{data.map((dataset, index) => (
<Line
key={index}
type="monotone"
data={dataset}
dataKey="value"
stroke={colors[index % colors.length]}
strokeWidth={2}
dot={{ r: 3, strokeWidth: 2 }}
activeDot={{ r: 5 }}
/>
))}
</LineChart>
</ResponsiveContainer>
);
case "area":
return (
<ResponsiveContainer width="100%" height={250}>
<AreaChart data={data.length > 1 ? undefined : data[0]}>
{showGrid && <CartesianGrid strokeDasharray="3 3" vertical={false} />}
<XAxis
dataKey="name"
axisLine={false}
tickLine={false}
tick={{ fontSize: 12 }}
dy={10}
/>
<YAxis
axisLine={false}
tickLine={false}
tick={{ fontSize: 12 }}
dx={-10}
/>
<Tooltip
contentStyle={{
backgroundColor: "rgba(255, 255, 255, 0.8)",
borderRadius: "8px",
border: "none",
boxShadow: "0 2px 10px rgba(0, 0, 0, 0.1)",
}}
/>
{data.map((dataset, index) => (
<Area
key={index}
type="monotone"
data={dataset}
dataKey="value"
stroke={colors[index % colors.length]}
fill={`url(#color${index})`}
fillOpacity={0.3}
/>
))}
{data.map((_, index) => (
<defs key={index}>
<linearGradient id={`color${index}`} x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor={colors[index % colors.length]} stopOpacity={0.3} />
<stop offset="95%" stopColor={colors[index % colors.length]} stopOpacity={0} />
</linearGradient>
</defs>
))}
</AreaChart>
</ResponsiveContainer>
);
default:
return null;
}
};
return (
<Card className={cn("overflow-hidden hover-scale", className)}>
<CardHeader className="pb-0">
<CardTitle className="text-lg font-semibold">{title}</CardTitle>
</CardHeader>
<CardContent className="pt-4">{renderChart()}</CardContent>
</Card>
);
};
export default ChartCard;