AdminKitDocs
Charts

React Bar Chart

A React bar chart with Chart.js: compare monthly values in rounded bars that take their colors from the theme and follow light and dark mode.

A bar chart compares values between categories, such as sales per month. The length of each bar shows at a glance which category is ahead. In AdminKit for React you draw it with the ChartJs component, a wrapper around Chart.js. It is in the free and PRO versions. AdminKit PRO also has ApexChart, which draws the chart with ApexCharts.

Both components take a function of the theme colors instead of a fixed configuration, so the chart follows light and dark mode. Chart setup explains how that works.

Example

This example sets last year against this year, month by month. You don't round the bars yourself: AdminKit's Chart.js defaults give them rounded top corners (borderRadius: 10).

import { ChartJs } from "@/components/plugins/chartjs";

export function SalesBarChart() {
  return (
    <div className="chart">
      <ChartJs
        aria-label="Sales per month, last year and this year"
        config={(theme) => ({
          type: "bar",
          data: {
            labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
            datasets: [
              {
                label: "Last year",
                backgroundColor: theme.primary,
                borderColor: theme.primary,
                hoverBackgroundColor: theme.primary,
                hoverBorderColor: theme.primary,
                data: [54, 67, 41, 55, 62, 45, 55, 73, 60, 76, 48, 79],
                barPercentage: 0.75,
                categoryPercentage: 0.5,
              },
              {
                label: "This year",
                backgroundColor: "#dee2e6",
                borderColor: "#dee2e6",
                hoverBackgroundColor: "#dee2e6",
                hoverBorderColor: "#dee2e6",
                data: [69, 66, 24, 48, 52, 51, 44, 53, 62, 79, 51, 68],
                barPercentage: 0.75,
                categoryPercentage: 0.5,
              },
            ],
          },
          options: {
            maintainAspectRatio: false,
            plugins: { legend: { display: false } },
            scales: {
              y: {
                grid: { display: false },
                border: { display: false },
                stacked: false,
                ticks: { stepSize: 20 },
              },
              x: {
                stacked: false,
                grid: { color: "transparent" },
                border: { display: false },
              },
            },
          },
        })}
      />
    </div>
  );
}

Render the component from a page in src/routes/. Each page loads when it is opened (React.lazy in src/app.tsx), so Chart.js is only downloaded with the first page that draws a chart. A new page also needs an entry in src/data/pages.json (see Add a page).

src/routes/reports.tsx
import { SalesBarChart } from "@/components/sales-bar-chart";

export default function Page() {
  return (
    <div className="card">
      <div className="card-header">
        <h2 className="card-title">Sales</h2>
      </div>
      <div className="card-body">
        <SalesBarChart />
      </div>
    </div>
  );
}

Props

PropTypeDefaultDescription
config(theme: Theme) => ChartConfigurationThe Chart.js configuration: type, data and options. Called again with the new colors when the color mode changes

Other props, such as id and aria-label, go to the <canvas>. Chart setup lists the container heights and the defaults AdminKit sets.

Colors in dark mode

A fixed color does not follow the mode. The "This year" bars keep the #dee2e6 of the HTML example, so they stay light gray in dark mode too. theme["gray-300"] is the same gray in light mode and follows the gray scale of dark mode:

backgroundColor: theme["gray-300"],

Horizontal and stacked bars

For bars that run sideways or add up, set two Chart.js options. indexAxis: "y" draws the bars horizontally, and stacked: true on both scales stacks the series:

options: {
  indexAxis: "y",
  scales: {
    x: { stacked: true },
    y: { stacked: true },
  },
},

ApexCharts example

Pro

This example is only available in AdminKit PRO. Learn more.

With ApexChart, this example draws a horizontal stacked bar chart. plotOptions.bar.horizontal turns the bars sideways, and chart.stacked adds up the series. The container has the chart's height, so the skeleton fills the same space while ApexCharts loads.

import { ApexChart } from "@/components/plugins/apexcharts";

export function ProductsBarChart() {
  return (
    <div className="position-relative" style={{ minHeight: 365 }}>
      <ApexChart
        options={() => ({
          chart: { height: 350, type: "bar", stacked: true },
          plotOptions: { bar: { horizontal: true } },
          stroke: { width: 1, colors: ["#fff"] },
          series: [
            { name: "Marine Sprite", data: [44, 55, 41, 37, 22, 43, 21] },
            { name: "Striking Calf", data: [53, 32, 33, 52, 13, 43, 32] },
            { name: "Tank Picture", data: [12, 17, 11, 9, 15, 11, 20] },
            { name: "Bucket Slope", data: [9, 7, 5, 8, 6, 9, 4] },
            { name: "Reborn Kid", data: [25, 12, 19, 32, 25, 24, 10] },
          ],
          xaxis: {
            categories: [2020, 2021, 2022, 2023, 2024, 2025, 2026],
            labels: { formatter: (val: string) => val + "K" },
          },
          yaxis: { title: { text: undefined } },
          tooltip: { y: { formatter: (val: number) => val + "K" } },
          fill: { opacity: 1 },
          legend: { position: "top", horizontalAlign: "left", offsetX: 40 },
        })}
      />
    </div>
  );
}

The options set no colors, so the series take the primary, success, warning, danger and info colors of the current mode. The 1px #fff stroke between the stacked parts stays white in dark mode. Use theme.white, the surface color, for a stroke that follows the mode.

Accessibility

  • ChartJs renders the <canvas> with role="img". Screen readers do not read what is drawn on it. Give it an aria-label that says what the chart shows, and put the figures that matter in text too.
  • The Chart.js example hides the legend, so the two series differ only by color. Name them in the card title or text, or turn the legend on.
  • Under prefers-reduced-motion, both components draw the chart without the entrance animation.

Last updated on

On this page