AdminKitDocs
Charts

Next.js Timeline Chart

A Next.js timeline chart for the App Router: tasks from start to end date as an ApexCharts rangeBar in a client component of AdminKit PRO.

Pro

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

Project plans and release schedules read well as a timeline chart. Each task is a bar that runs from its start date to its end date, so overlaps and gaps are easy to see. AdminKit for Next.js draws it with the ApexChart client component (Chart setup). For ApexCharts, it is a rangeBar chart with plotOptions.bar.horizontal: true.

ApexCharts draws in the browser, and its options are a function that a server component cannot pass on. So the chart file starts with "use client", and a server component page renders it. The tasks can stay in the client file, as here, or come from the page as props.

Example

src/components/release-timeline.tsx
"use client";

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

const day = (date: string) => new Date(date).getTime();

const tasks = [
  { x: "Code", y: [day("2026-03-02"), day("2026-03-04")] },
  { x: "Test", y: [day("2026-03-04"), day("2026-03-08")] },
  { x: "Validation", y: [day("2026-03-08"), day("2026-03-12")] },
  { x: "Deployment", y: [day("2026-03-12"), day("2026-03-18")] },
];

export function ReleaseTimeline() {
  return (
    <div className="position-relative" style={{ minHeight: 365 }}>
      <ApexChart
        options={() => ({
          series: [{ data: tasks }],
          chart: { height: 350, type: "rangeBar" },
          plotOptions: { bar: { horizontal: true } },
          xaxis: { type: "datetime" },
        })}
      />
    </div>
  );
}
src/app/(dashboard)/releases/page.tsx
import { ReleaseTimeline } from "@/components/release-timeline";
import { pageMetadata } from "@/lib/site";

export const metadata = pageMetadata("/releases");

export default function ReleasesPage() {
  return (
    <div className="card">
      <div className="card-header">
        <h2 className="card-title mb-0">Release 2.4</h2>
      </div>
      <div className="card-body">
        <ReleaseTimeline />
      </div>
    </div>
  );
}

pageMetadata() looks up /releases in src/data/pages.json, so add the route there.

Props

PropTypeDefaultDescription
options(theme: Theme) => ApexOptionsThe ApexCharts options, with series and chart.type. Called again with the new colors when the color mode changes

Data

FieldValue
xThe task, shown as the label on the y-axis
y[start, end], as timestamps
fillColorOptional: the color of this bar only

Timestamps are plain numbers, so a server component page can pass the tasks as props. Date-only strings such as "2026-03-02" are read as midnight UTC, and ApexCharts shows datetime labels in UTC, so each bar starts on a day boundary.

To make one task stand out, such as the one in progress, give it a fillColor with a theme color:

options={(theme) => ({
  series: [
    {
      data: tasks.map((task) =>
        task.x === "Test" ? { ...task, fillColor: theme.warning } : task
      ),
    },
  ],
  chart: { height: 350, type: "rangeBar" },
  plotOptions: { bar: { horizontal: true } },
  xaxis: { type: "datetime" },
})}

Accessibility

  • Start and end dates show in the tooltip on hover only. Keep them in text too, for example in the task list of the page.
  • When a color marks a state, also write the state in text.
  • Other props of ApexChart go to its <div>: role="figure" and aria-label name the chart.

Last updated on

On this page