import * as React from "react";
import { formatNumber } from "~/lib/utils";
export interface BarChartData {
label: string;
value: number;
maxValue?: number;
color?: string;
labelColor?: string;
valuePrefix?: string;
valueSuffix?: string;
}
interface CustomBarChartProps {
data: BarChartData[];
title?: string;
height?: string;
barHeight?: string;
showAxisLabels?: boolean;
className?: string;
loading?: boolean;
}
export function CustomBarChart({
data,
title,
height = "auto",
barHeight = "h-6",
showAxisLabels = true,
className = "",
loading = false,
}: CustomBarChartProps) {
// Calculate the maximum value across all data points for consistent scaling
const globalMaxValue = Math.max(
...data.map((item) => item.maxValue || item.value),
);
// Loading skeleton
if (loading) {
return (
{title && (
)}
{Array.from({ length: 4 }).map((_, index) => (
{/* Label skeleton */}
{/* Bar skeleton */}
{/* Value skeleton */}
))}
);
}
return (
{title && (
{title}
)}
{data.map((item, index) => {
const percentage =
globalMaxValue > 0 ? (item.value / globalMaxValue) * 100 : 0;
const displayValue = item.value.toFixed(1);
return (
{/* Label */}
{item.label}
{/* Bar Container */}
{/* Add a subtle gradient effect for better visual appeal */}
{/* Value Label */}
{item.valuePrefix || ""}
{formatNumber(parseFloat(displayValue))}
{item.valueSuffix || ""}
);
})}
{/* Axis Labels */}
{showAxisLabels && globalMaxValue > 0 && (
{formatNumber(0)}
{formatNumber(Math.round(globalMaxValue / 4))}
{formatNumber(Math.round(globalMaxValue / 2))}
{formatNumber(Math.round((globalMaxValue * 3) / 4))}
{formatNumber(Math.round(globalMaxValue))}
)}
);
}