All files / src/components bar-chart.tsx

66.66% Statements 4/6
100% Branches 14/14
50% Functions 2/4
66.66% Lines 4/6

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123                                                            4x                                     15x                                                                                                                         59x                 4x      
import { forwardRef } from 'react';
import {
  BarChart as RechartsBarChart,
  Bar,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  ResponsiveContainer,
  Cell,
} from 'recharts';
 
import { cn } from '@/lib/utils';
import { ChartTooltip, type TooltipData } from './chart-tooltip';
 
export interface BarChartProps {
  data: Array<Record<string, any>>;
  dataKey: string;
  xAxisKey: string;
  className?: string;
  height?: number;
  color?: string;
  showGrid?: boolean;
  showTooltip?: boolean;
  showXAxis?: boolean;
  showYAxis?: boolean;
  tooltipTitle?: string;
  tooltipFormatter?: (data: TooltipData) => string;
}
 
const BarChart = forwardRef<HTMLDivElement, BarChartProps>(
  (
    {
      className,
      data,
      dataKey,
      xAxisKey,
      height = 300,
      color = 'hsl(var(--primary))',
      showGrid = true,
      showTooltip = true,
      showXAxis = true,
      showYAxis = true,
      tooltipTitle,
      tooltipFormatter,
      ...props
    },
    ref
  ) => {
    return (
      <div ref={ref} className={cn('w-full', className)} {...props}>
        <ResponsiveContainer width="100%" height={height}>
          <RechartsBarChart
            data={data}
            margin={{ top: 60, right: 30, left: 20, bottom: 5 }}
          >
            <defs>
              <linearGradient id="barGradient" x1="0" y1="0" x2="0" y2="1">
                <stop offset="0%" stopColor="var(--gradient-start)" />
                <stop offset="100%" stopColor="var(--gradient-end)" />
              </linearGradient>
            </defs>
            {showGrid && (
              <CartesianGrid
                strokeDasharray="3 3"
                stroke="hsl(var(--border))"
                vertical={false}
                horizontal={true}
              />
            )}
            {showXAxis && (
              <XAxis
                dataKey={xAxisKey}
                stroke="hsl(var(--muted-foreground))"
                fontSize={12}
                tickLine={false}
                axisLine={false}
                textAnchor="middle"
                height={60} // FIXME: Adjust height based on response data
              />
            )}
            {showYAxis && (
              <YAxis
                stroke="hsl(var(--muted-foreground))"
                fontSize={12}
                tickLine={false}
                axisLine={{
                  stroke: 'hsl(var(--border))',
                  strokeWidth: 2,
                }}
                tickFormatter={(value: number | string) => `${value}`}
              />
            )}
            {showTooltip && (
              <Tooltip
                cursor={{ fill: 'rgba(0, 0, 0, 0.1)' }}
                wrapperStyle={{ outline: 'none' }}
                content={({ active, payload, label, coordinate }) => (
                  <ChartTooltip
                    active={active}
                    payload={payload}
                    coordinate={coordinate}
                    title={tooltipTitle}
                    formatValue={tooltipFormatter}
                  />
                )}
              />
            )}
            <Bar dataKey={dataKey} radius={[100, 100, 0, 0]} barSize={16}>
              {data.map((entry, index) => (
                <Cell key={`cell-${index}`} fill="url(#barGradient)" />
              ))}
            </Bar>
          </RechartsBarChart>
        </ResponsiveContainer>
      </div>
    );
  }
);
BarChart.displayName = 'BarChart';
 
export { BarChart };