Next.js 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.
Line charts are for trends: how sales, visits or orders move from one month to the next. AdminKit for Next.js draws them with the ChartJs component, in the free and PRO versions. AdminKit PRO adds ApexChart for ApexCharts.
Chart.js needs the browser's canvas, so ChartJs is a client component, marked "use client". Its config is a function of the theme colors. Your page is a server component, and functions cannot cross from a server component to a client component. So the chart goes in a small client component of its own, which your page renders. Chart setup covers both chart components.
Example
Sales and orders over twelve months. The lines are curved because AdminKit sets tension: 0.4 as a Chart.js default.
"use client";
import { ChartJs } from "@/components/plugins/chartjs";
export function SalesLineChart() {
return (
<div className="chart">
<ChartJs
aria-label="Sales and orders per month"
config={(theme) => ({
type: "line",
data: {
labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
datasets: [
{
label: "Sales ($)",
fill: true,
backgroundColor: "transparent",
borderColor: theme.primary,
data: [2115, 1562, 1584, 1892, 1487, 2223, 2966, 2448, 2905, 3838, 2917, 3327],
},
{
label: "Orders",
fill: true,
backgroundColor: "transparent",
borderColor: "#adb5bd",
borderDash: [4, 4],
data: [958, 724, 629, 883, 915, 1214, 1476, 1212, 1554, 2128, 1466, 1827],
},
],
},
options: {
maintainAspectRatio: false,
plugins: {
legend: { display: false },
tooltip: { intersect: false },
filler: { propagate: false },
},
scales: {
x: {
grid: { color: "rgba(0,0,0,0.05)" },
border: { color: "rgba(0,0,0,0.05)" },
},
y: {
ticks: { stepSize: 500 },
grid: { color: "transparent" },
},
},
},
})}
/>
</div>
);
}Render it from the page, which stays a server component:
import { SalesLineChart } from "@/components/sales-line-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 and orders</h2>
</div>
<div className="card-body">
<SalesLineChart />
</div>
</div>
</>
);
}The static HTML holds a skeleton in the .chart box, and the chart draws in the browser after hydration.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
config | (theme: Theme) => ChartConfiguration | The Chart.js configuration. 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 needs a height, and .chart gives it 300px. The other heights are on Chart setup.
Straight lines and filled areas
Two dataset options change the shape. tension: 0 gives straight segments. A backgroundColor other than "transparent", with fill: true, turns the line into an area chart. Chart.js' color helper, which AdminKit's wrapper also uses, makes a theme color transparent:
import { color } from "chart.js/helpers";
// in the datasets of config(theme)
{
label: "Sales ($)",
fill: true,
tension: 0,
backgroundColor: color(theme.primary).alpha(0.2).rgbString(),
borderColor: theme.primary,
data: [2115, 1562, 1584, 1892, 1487, 2223],
}Colors in dark mode
The "Orders" line (#adb5bd) and the x grid (rgba(0,0,0,0.05)) keep the fixed colors of the HTML example, in both modes. Read theme["gray-500"] instead: it is #adb5bd in light mode and follows the gray scale of dark mode. Leave grid.color out and the grid takes the border color that AdminKit sets for the current mode.
ApexCharts example
This example is only available in AdminKit PRO. Learn more.
In this version, ApexChart draws three series, each with its own line width (stroke.width) and dash (stroke.dashArray). Like ChartJs, it goes in a "use client" file, and it loads ApexCharts only in the browser.
"use client";
import { ApexChart } from "@/components/plugins/apexcharts";
export function VisitsLineChart() {
return (
<div className="position-relative" style={{ minHeight: 365 }}>
<ApexChart
options={() => ({
chart: { height: 350, type: "line", zoom: { enabled: false } },
dataLabels: { enabled: false },
stroke: { width: [5, 7, 5], curve: "straight", dashArray: [0, 8, 5] },
series: [
{ name: "Session Duration", data: [45, 52, 38, 24, 33, 26, 21, 20, 6, 8, 15, 10] },
{ name: "Page Views", data: [35, 41, 62, 42, 13, 18, 29, 37, 36, 51, 32, 35] },
{ name: "Total Visits", data: [87, 57, 74, 99, 75, 38, 62, 47, 82, 56, 45, 47] },
],
markers: { size: 0 },
xaxis: {
categories: ["01 Jan", "02 Jan", "03 Jan", "04 Jan", "05 Jan", "06 Jan", "07 Jan", "08 Jan", "09 Jan", "10 Jan", "11 Jan", "12 Jan"],
},
tooltip: {
y: [
{ title: { formatter: (val: string) => val + " (mins)" } },
{ title: { formatter: (val: string) => val + " per session" } },
{ title: { formatter: (val: string) => val } },
],
},
grid: { borderColor: "#f1f1f1" },
})}
/>
</div>
);
}Accessibility
ChartJsgives its<canvas>role="img". Screen readers cannot read the lines, so add anaria-labeland state the key figures in text.- "Orders" is dashed, so it differs from "Sales ($)" by more than color. The legend is hidden, so name both series near the chart.
- Under
prefers-reduced-motion, the charts draw without the entrance animation.
Related
- React line chart: the same chart in AdminKit for React (Vite)
- Bootstrap 5 line chart: the line chart of the HTML version
- Chart setup: the
ChartJs,ApexChartandVectorMapcomponents - Bar chart: compare values between categories
- Chart.js demo and ApexCharts demo
Last updated on
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.
Pie chart
A Next.js pie chart in a "use client" component: Chart.js slices for traffic sources, rendered from an App Router page and colored by the theme.