Docs
Bar Chart
A sample bar chart for widgets/presentation
Installation
Run the following command
It will create a new file called bar-chart.tsx
inside the components/animata/graphs
directory.
mkdir -p components/animata/graphs && touch components/animata/graphs/bar-chart.tsx
Paste the code
Open the newly created file and paste the following code:
import { useEffect, useRef, useState } from "react";
import { cn } from "@/lib/utils";
interface BarChartProps {
/**
* The items to display in the BarChart.
*/
items: {
progress: number;
label: string;
className?: string;
containerClassName?: string;
}[];
/**
* The height of the BarChart.
*/
height?: number;
className?: string;
}
export default function BarChart({ items, className, height: providedHeight }: BarChartProps) {
const [{ height }, setSize] = useState({
height: providedHeight ?? 12,
});
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
setSize({
height: providedHeight ?? containerRef.current?.offsetHeight ?? 12,
});
}, [providedHeight]);
const [shouldUseValue, setShouldUseValue] = useState(false);
useEffect(() => {
const timeout = setTimeout(() => {
// This is a hack to force the animation to run for the first time.
// We can use framer-motion to achieve this but just keeping it simple for now.
setShouldUseValue(true);
}, 250);
return () => clearTimeout(timeout);
}, []);
return (
<div
ref={containerRef}
className={cn(
"relative box-border flex min-h-4 w-full flex-wrap items-end gap-[2px] overflow-hidden",
className,
)}
style={{ height }}
>
{items.map((item, index) => {
const clampedProgress = Math.min(100, Math.max(0, item.progress));
const barHeight = shouldUseValue ? (clampedProgress / 100) * height : 0;
return (
<div
className={cn("flex h-full flex-1 flex-col-reverse", item.containerClassName)}
key={`bar_${index}`}
title={item.label}
>
<div
style={{ height: barHeight }}
className={cn("transition-all duration-200", item.className)}
/>
</div>
);
})}
</div>
);
}
Credits
Built by hari