We are working on new components <3
HextaUIHextaUI
DataChart

Chart

A responsive and customizable chart component using Recharts.

Preview

Installation

npm install recharts

Code

Chart.tsx
"use client";
 
import {
  Bar,
  BarChart,
  CartesianGrid,
  XAxis,
  Tooltip,
  Legend,
  ResponsiveContainer,
} from "recharts";
import { cn } from "@/lib/utils";
 
export interface ChartConfig {
  [key: string]: {
    label: string;
    color: string;
    icon?: React.ComponentType;
  };
}
 
export interface ChartProps {
  data: any[];
  config: ChartConfig;
  className?: string;
  dataKeys?: string[];
  xAxisKey?: string;
  showGrid?: boolean;
  showTooltip?: boolean;
  showLegend?: boolean;
}
 
export function Chart({
  data,
  config,
  className,
  dataKeys,
  xAxisKey = "name",
  showGrid = true,
  showTooltip = true,
  showLegend = true,
}: ChartProps) {
  const keys = dataKeys || Object.keys(config);
 
  return (
    <div className={cn("w-full h-[500px]", className)}>
      <ResponsiveContainer width="100%" height="100%">
        <BarChart data={data}>
          {showGrid && (
            <CartesianGrid className="opacity-10" vertical={false} />
          )}
 
          <XAxis
            dataKey={xAxisKey}
            tickLine={false}
            axisLine={false}
            padding={{ left: 20, right: 20 }}
          />
 
          {showTooltip && (
            <Tooltip
              content={({ active, payload, label }) => {
                if (!active || !payload) return null;
 
                return (
                  <div className="rounded-lg border bg-background p-2 shadow-sm">
                    <div className="font-medium">{label}</div>
                    {payload.map((item: any, index: number) => (
                      <div
                        key={index}
                        className="flex items-center gap-2 text-sm text-muted-foreground"
                      >
                        <div
                          className="h-2 w-2 rounded-full"
                          style={{ backgroundColor: item.fill }}
                        />
                        <span>{config[item.dataKey].label}:</span>
                        <span className="font-medium text-foreground">
                          {item.value}
                        </span>
                      </div>
                    ))}
                  </div>
                );
              }}
            />
          )}
 
          {showLegend && (
            <Legend
              content={({ payload }) => {
                if (!payload) return null;
 
                return (
                  <div className="flex gap-4 text-sm text-muted-foreground">
                    {payload.map((item: any, index: number) => (
                      <div key={index} className="flex items-center gap-2">
                        <div
                          className="h-2 w-2 rounded-full"
                          style={{ backgroundColor: item.color }}
                        />
                        <span>{item.value}</span>
                      </div>
                    ))}
                  </div>
                );
              }}
            />
          )}
 
          {keys.map((key) => (
            <Bar
              key={key}
              dataKey={key}
              fill={config[key].color}
              radius={[4, 4, 0, 0]}
            />
          ))}
        </BarChart>
      </ResponsiveContainer>
    </div>
  );
}

Usage

Chart.tsx
import { Chart } from "@/components/library/data/Chart";
 
// Define your data
const data = [
  { name: "Jan", users: 100, revenue: 400 },
  { name: "Feb", users: 150, revenue: 600 },
  { name: "Mar", users: 200, revenue: 800 },
];
 
// Define your configuration
const config = {
  users: {
    label: "Active Users",
    color: "hsl(var(--blue))",
  },
  revenue: {
    label: "Revenue",
    color: "hsl(var(--secondary))",
  },
};
 
export function ChartExample() {
  return <Chart data={data} config={config} className="h-[400px]" />;
}

Props

Chart

PropTypeDefault
data
any[]
-
config
ChartConfig
-
className
string
-
dataKeys
string[]
-
xAxisKey
string
-
showGrid
boolean
-
showTooltip
boolean
-
showLegend
boolean
-

Configuration

The ChartConfig type allows you to specify how each data series should be displayed:

interface ChartConfig {
  [key: string]: {
    label: string; // Display label for the series
    color: string; // Color for the bars/lines
    icon?: React.ComponentType; // Optional icon component
  };
}

Examples

Basic Chart

Multiple Series

Custom Height

Without Grid or Legend

Edit on GitHub

Last updated on

On this page