# 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](/nextjs/) 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](/nextjs/docs/charts/overview/) 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.

```html
<div class="chart">
  <canvas id="chartjs-line"></canvas>
</div>

<script>
adminkit.chartjs("#chartjs-line", function (theme) {
  return {
    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"
          }
        }
      }
    }
  };
});
</script>
```
```tsx code title="src/components/sales-line-chart.tsx"
"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:

```tsx title="src/app/(dashboard)/reports/page.tsx"
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](/nextjs/docs/charts/overview/#chartjs).

## 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:

```tsx
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](/pricing/#nextjs).

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.

```html
<div id="apexcharts-line"></div>

<script>
var 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: function(val) {
          return val + " (mins)"
        }
      }
    }, {
      title: {
        formatter: function(val) {
          return val + " per session"
        }
      }
    }, {
      title: {
        formatter: function(val) {
          return val;
        }
      }
    }]
  },
  grid: {
    borderColor: "#f1f1f1",
  }
}
adminkit.apexcharts("#apexcharts-line", function () {
  return options;
});
</script>
```
```tsx code title="src/components/visits-line-chart.tsx"
"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

- `ChartJs` gives its `<canvas>` `role="img"`. Screen readers cannot read the lines, so add an `aria-label` and 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](/react/docs/charts/line-chart/): the same chart in AdminKit for React (Vite)
- [Bootstrap 5 line chart](/bootstrap/docs/charts/line-chart/): the line chart of the HTML version
- [Chart setup](/nextjs/docs/charts/overview/): the `ChartJs`, `ApexChart` and `VectorMap` components
- [Bar chart](/nextjs/docs/charts/bar-chart/): compare values between categories
- [Chart.js demo](https://nextjs-demo.adminkit.io/charts-chartjs) and [ApexCharts demo](https://nextjs-demo.adminkit.io/charts-apexcharts)

---

Canonical HTML page: https://adminkit.io/nextjs/docs/charts/line-chart/

Site overview for agents: https://adminkit.io/llms.txt (expanded: https://adminkit.io/llms-full.txt) · Documentation: https://adminkit.io/bootstrap/docs/ · Questions: support@adminkit.io
