Next.js Doughnut Chart
Build a Next.js doughnut chart with Chart.js: a client component with a 65% cutout, rendered from a server component page in the App Router.
A doughnut chart shows a total split into a few parts as a ring: a pie chart with an empty center. In the free and PRO versions of AdminKit for Next.js, the ChartJs component draws it with Chart.js. In AdminKit PRO, ApexChart draws the ApexCharts version.
ChartJs is a client component, since Chart.js draws in the browser. You describe the chart with a function of the theme colors. Pages in the App Router are server components, and server components cannot pass functions to client components. So the chart lives in its own "use client" file that your page renders. More in Chart setup.
Example
Traffic sources with a cutout of 65% of the radius.
"use client";
import { ChartJs } from "@/components/plugins/chartjs";
export function TrafficDoughnutChart() {
return (
<div className="chart">
<ChartJs
aria-label="Visits per traffic source"
config={(theme) => ({
type: "doughnut",
data: {
labels: ["Social", "Search Engines", "Direct", "Other"],
datasets: [
{
data: [260, 125, 54, 146],
backgroundColor: [theme.primary, theme.success, theme.warning, "#dee2e6"],
borderColor: "transparent",
},
],
},
options: {
maintainAspectRatio: false,
cutout: "65%",
plugins: { legend: { display: false } },
},
})}
/>
</div>
);
}The server component page renders it:
import { TrafficDoughnutChart } from "@/components/traffic-doughnut-chart";
import { pageMetadata } from "@/lib/site";
export const metadata = pageMetadata("/traffic");
export default function TrafficPage() {
return (
<>
<h1 className="h3 mb-3">Traffic</h1>
<div className="card">
<div className="card-header">
<h2 className="card-title">Traffic sources</h2>
</div>
<div className="card-body">
<TrafficDoughnutChart />
</div>
</div>
</>
);
}The exported HTML shows a skeleton where the chart goes. The ring draws once the browser has taken over that HTML (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 demo's doughnut chart sits in .chart.chart-sm, 250px high. Chart setup has the other heights.
Cutout and colors
cutout is the size of the hole, as a percentage of the radius or in pixels. Raise it for a thinner ring:
options: {
maintainAspectRatio: false,
cutout: "80%",
},The "Other" slice uses the fixed #dee2e6 from the HTML example. theme["gray-300"] is that gray in light mode and follows the gray scale of dark mode.
ApexCharts example
This example is only available in AdminKit PRO. Learn more.
ApexCharts calls this chart type "donut". Its series is a plain array of numbers, one per slice. The file starts with "use client", like the Chart.js one.
"use client";
import { ApexChart } from "@/components/plugins/apexcharts";
export function SourcesDonutChart() {
return (
<div className="position-relative" style={{ minHeight: 365 }}>
<ApexChart
options={() => ({
chart: { height: 350, type: "donut" },
dataLabels: { enabled: false },
series: [44, 55, 13, 33],
})}
/>
</div>
);
}The slices take the primary, success, warning and danger colors and the borders the surface color (theme.white). On a color mode change, ApexChart draws the donut again without animation, with the new colors.
Accessibility
- The
<canvas>ofChartJshasrole="img". Screen readers do not read the slices, so add anaria-labeland write the shares in text. - The Chart.js example hides the legend, so only color tells the sources apart. Show the legend or name them next to the chart.
- Under
prefers-reduced-motion, the charts draw without the entrance animation.
Related
- React doughnut chart: the same chart in AdminKit for React (Vite)
- Bootstrap 5 doughnut chart: the doughnut chart of the HTML version
- Chart setup: the
ChartJs,ApexChartandVectorMapcomponents - Pie chart: the same data without the hole
- Chart.js demo
Last updated on
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.
Polar area chart
A Next.js polar area chart as a Chart.js client component: equal-angle segments sized by value, colored by the theme and drawn after hydration.