Next.js Bar Chart
A Next.js bar chart for the App Router: a Chart.js client component rendered from a server component page, in theme colors for light and dark mode.
Use a bar chart to compare values side by side, such as this year's sales against last year's, month by month. In the free and PRO versions of AdminKit for Next.js, the ChartJs component draws it with Chart.js. AdminKit PRO also has ApexChart for ApexCharts.
Chart.js draws on a canvas in the browser, so ChartJs is a client component, marked "use client". That decides where the chart goes. The chart's configuration is a function of the theme colors, and pages in the App Router are server components, which cannot pass a function to a client component. So write the chart in its own client component and render that from your page. The page stays a server component with its metadata export. Chart setup explains the components.
Example
Each month has two bars, last year and this year. The rounded top corners (borderRadius: 10) come from AdminKit's Chart.js defaults.
"use client";
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>
);
}The page imports it like any other component. pageMetadata() reads the title and description from src/data/pages.json, so a new page needs an entry there (see Add a page).
import { SalesBarChart } from "@/components/sales-bar-chart";
import { pageMetadata } from "@/lib/site";
export const metadata = pageMetadata("/reports");
export default function ReportsPage() {
return (
<>
<h1 className="h3 mb-3">Reports</h1>
<div className="card">
<div className="card-header">
<h2 className="card-title">Sales</h2>
</div>
<div className="card-body">
<SalesBarChart />
</div>
</div>
</>
);
}The theme colors are only known in the browser. So the exported HTML has an empty <canvas> and a skeleton in the .chart box, and the chart draws once the page has hydrated. The server and browser output match, and the layout does not move.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
config | (theme: Theme) => ChartConfiguration | The 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>. The container heights and AdminKit's Chart.js defaults are on Chart setup.
Colors in dark mode
To make a color follow the mode, read it from theme. "This year" keeps the fixed #dee2e6 of the HTML example, so it stays light gray in dark mode. theme["gray-300"] gives the same gray in light mode and follows the gray scale of dark mode:
backgroundColor: theme["gray-300"],Horizontal and stacked bars
Horizontal and stacked bars are a matter of Chart.js options. indexAxis: "y" turns the bars sideways, and stacked: true on both scales stacks the series:
options: {
indexAxis: "y",
scales: {
x: { stacked: true },
y: { stacked: true },
},
},ApexCharts example
This example is only available in AdminKit PRO. Learn more.
This example draws a horizontal stacked bar chart with ApexChart. plotOptions.bar.horizontal lays the bars on their side, and chart.stacked stacks the series. ApexChart is a client component too, so this file also starts with "use client". It loads ApexCharts in the browser only, so you don't need next/dynamic.
"use client";
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>
);
}Without colors in the options, 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. theme.white, the surface color, follows the mode.
Accessibility
- The
<canvas>thatChartJsrenders hasrole="img". Screen readers do not read the bars, so give it anaria-labelthat says what it shows, and the figures that matter in text. - The legend is hidden in the Chart.js example, so the two series differ only by color. Name them in the card text or turn the legend on.
- Under
prefers-reduced-motion, both components draw the chart without the entrance animation.
Related
- React bar chart: the same chart in AdminKit for React (Vite)
- Bootstrap 5 bar chart: the bar chart of the HTML version
- Chart setup: the
ChartJs,ApexChartandVectorMapcomponents - Line chart: values over time
- Chart.js demo and ApexCharts demo
Last updated on
Chart setup
Next.js charts in client components: the ChartJs, ApexChart (PRO) and VectorMap components of AdminKit, with colors that follow light and dark mode.
Line chart
Draw a Next.js line chart with Chart.js in a client component: monthly sales and orders that redraw in the new colors when the color mode changes.