|
|
"use client"; |
|
|
|
|
|
import { |
|
|
BarChart as RechartsBarChart, |
|
|
Bar, |
|
|
XAxis, |
|
|
YAxis, |
|
|
CartesianGrid, |
|
|
Tooltip, |
|
|
Legend, |
|
|
ResponsiveContainer, |
|
|
Cell, |
|
|
Label |
|
|
} from 'recharts'; |
|
|
|
|
|
interface BarChartProps { |
|
|
data: Array<{ [key: string]: any }>; |
|
|
title?: string; |
|
|
xKey?: string; |
|
|
yKey?: string; |
|
|
color?: string; |
|
|
height?: number; |
|
|
horizontal?: boolean; |
|
|
xAxisLabel?: string; |
|
|
yAxisLabel?: string; |
|
|
} |
|
|
|
|
|
|
|
|
const COLORS = ['#6366f1', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#06b6d4', '#ec4899']; |
|
|
|
|
|
export default function BarChart({ |
|
|
data, |
|
|
title, |
|
|
xKey = 'name', |
|
|
yKey = 'value', |
|
|
color = '#6366f1', |
|
|
height = 300, |
|
|
horizontal = false, |
|
|
xAxisLabel, |
|
|
yAxisLabel |
|
|
}: BarChartProps) { |
|
|
return ( |
|
|
<div className="w-full bg-white rounded-xl border border-slate-100 p-4 shadow-sm"> |
|
|
{title && ( |
|
|
<h3 className="text-sm font-semibold text-slate-700 mb-4">{title}</h3> |
|
|
)} |
|
|
<ResponsiveContainer width="100%" height={height}> |
|
|
<RechartsBarChart |
|
|
data={data} |
|
|
layout={horizontal ? 'vertical' : 'horizontal'} |
|
|
margin={{ top: 5, right: 30, left: 20, bottom: 20 }} // Increased bottom margin for label |
|
|
> |
|
|
<CartesianGrid strokeDasharray="3 3" stroke="#e2e8f0" /> |
|
|
{horizontal ? ( |
|
|
<> |
|
|
<XAxis type="number" tick={{ fill: '#64748b', fontSize: 12 }}> |
|
|
{xAxisLabel && <Label value={xAxisLabel} offset={-10} position="insideBottom" style={{ fill: '#64748b', fontSize: 12 }} />} |
|
|
</XAxis> |
|
|
<YAxis |
|
|
dataKey={xKey} |
|
|
type="category" |
|
|
tick={{ fill: '#64748b', fontSize: 12 }} |
|
|
width={100} |
|
|
> |
|
|
{yAxisLabel && <Label value={yAxisLabel} angle={-90} position="insideLeft" style={{ fill: '#64748b', fontSize: 12 }} />} |
|
|
</YAxis> |
|
|
</> |
|
|
) : ( |
|
|
<> |
|
|
<XAxis |
|
|
dataKey={xKey} |
|
|
tick={{ fill: '#64748b', fontSize: 12 }} |
|
|
angle={-45} |
|
|
textAnchor="end" |
|
|
height={80} |
|
|
> |
|
|
{xAxisLabel && <Label value={xAxisLabel} offset={0} position="insideBottom" dy={10} style={{ fill: '#64748b', fontSize: 12 }} />} |
|
|
</XAxis> |
|
|
<YAxis tick={{ fill: '#64748b', fontSize: 12 }}> |
|
|
{yAxisLabel && <Label value={yAxisLabel} angle={-90} position="insideLeft" style={{ fill: '#64748b', fontSize: 12 }} />} |
|
|
</YAxis> |
|
|
</> |
|
|
)} |
|
|
<Tooltip |
|
|
contentStyle={{ |
|
|
background: 'white', |
|
|
border: '1px solid #e2e8f0', |
|
|
borderRadius: '8px', |
|
|
boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1)' |
|
|
}} |
|
|
labelStyle={{ color: '#334155', fontWeight: 600 }} |
|
|
/> |
|
|
<Legend wrapperStyle={{ fontSize: '12px', paddingTop: '10px' }} /> |
|
|
<Bar |
|
|
dataKey={yKey} |
|
|
radius={[4, 4, 0, 0]} |
|
|
name={yAxisLabel || yKey.charAt(0).toUpperCase() + yKey.slice(1)} // Use label as legend name if available |
|
|
> |
|
|
{data.map((entry, index) => ( |
|
|
<Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} /> |
|
|
))} |
|
|
</Bar> |
|
|
</RechartsBarChart> |
|
|
</ResponsiveContainer> |
|
|
</div> |
|
|
); |
|
|
} |
|
|
|