# Next.js Scatter Chart

A Next.js scatter chart for the App Router: x/y points of three samples in an ApexCharts client component of AdminKit PRO, with zoom on both axes.

> This component is only available in **AdminKit PRO**. [Learn more](/pricing/#nextjs).

A scatter chart answers one question: do these two values move together? It places each data point by two numeric values, so correlations and clusters stand out. In [AdminKit for Next.js](/nextjs/) you draw it with `ApexChart`, a client component around [ApexCharts](https://apexcharts.com/). [Chart setup](/nextjs/docs/charts/overview/#apexcharts) covers the component.

A server component page cannot pass functions to a client component. The x-axis label `formatter` is a function, like `options` itself, so the chart lives in a client component file. The data can live there too. It can also come from the page as props, since arrays of `[x, y]` numbers are serializable.

## Example

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

<script>
var options = {
  series: [{
    name: "SAMPLE A",
    data: [
      [16.4, 5.4], [21.7, 2], [25.4, 3], [19, 2], [10.9, 1], [13.6, 3.2], [10.9, 7.4], [10.9, 0], [10.9, 8.2], [16.4, 0], [16.4, 1.8], [13.6, 0.3], [13.6, 0], [29.9, 0], [27.1, 2.3], [16.4, 0], [13.6, 3.7], [10.9, 5.2], [16.4, 6.5], [10.9, 0], [24.5, 7.1], [10.9, 0], [8.1, 4.7], [19, 0], [21.7, 1.8], [27.1, 0], [24.5, 0], [27.1, 0], [29.9, 1.5], [27.1, 0.8], [22.1, 2]
    ]
  }, {
    name: "SAMPLE B",
    data: [
      [36.4, 13.4], [1.7, 11], [5.4, 8], [9, 17], [1.9, 4], [3.6, 12.2], [1.9, 14.4], [1.9, 9], [1.9, 13.2], [1.4, 7], [6.4, 8.8], [3.6, 4.3], [1.6, 10], [9.9, 2], [7.1, 15], [1.4, 0], [3.6, 13.7], [1.9, 15.2], [6.4, 16.5], [0.9, 10], [4.5, 17.1], [10.9, 10], [0.1, 14.7], [9, 10], [12.7, 11.8], [2.1, 10], [2.5, 10], [27.1, 10], [2.9, 11.5], [7.1, 10.8], [2.1, 12]
    ]
  }, {
    name: "SAMPLE C",
    data: [
      [21.7, 3], [23.6, 3.5], [24.6, 3], [29.9, 3], [21.7, 20], [23, 2], [10.9, 3], [28, 4], [27.1, 0.3], [16.4, 4], [13.6, 0], [19, 5], [22.4, 3], [24.5, 3], [32.6, 3], [27.1, 4], [29.6, 6], [31.6, 8], [21.6, 5], [20.9, 4], [22.4, 0], [32.6, 10.3], [29.7, 20.8], [24.5, 0.8], [21.4, 0], [21.7, 6.9], [28.6, 7.7], [15.4, 0], [18.1, 0], [33.4, 0], [16.4, 0]
    ]
  }],
  chart: {
    height: 350,
    type: "scatter",
    zoom: {
      enabled: true,
      type: "xy"
    }
  },
  xaxis: {
    tickAmount: 10,
    labels: {
      formatter: function (val) {
        return parseFloat(val).toFixed(1);
      }
    }
  },
  yaxis: {
    tickAmount: 7
  }
};

adminkit.apexcharts("#apexcharts-scatter", function () {
  return options;
});
</script>
```
```tsx code title="src/components/samples-scatter-chart.tsx"
"use client";

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

// [x, y] per point
const samples = [
  {
    name: "SAMPLE A",
    data: [
      [16.4, 5.4], [21.7, 2], [25.4, 3], [19, 2], [10.9, 1], [13.6, 3.2],
      [10.9, 7.4], [10.9, 0], [10.9, 8.2], [16.4, 0], [16.4, 1.8], [13.6, 0.3],
      [13.6, 0], [29.9, 0], [27.1, 2.3], [16.4, 0], [13.6, 3.7], [10.9, 5.2],
      [16.4, 6.5], [10.9, 0], [24.5, 7.1], [10.9, 0], [8.1, 4.7], [19, 0],
      [21.7, 1.8], [27.1, 0], [24.5, 0], [27.1, 0], [29.9, 1.5], [27.1, 0.8],
      [22.1, 2],
    ],
  },
  {
    name: "SAMPLE B",
    data: [
      [36.4, 13.4], [1.7, 11], [5.4, 8], [9, 17], [1.9, 4], [3.6, 12.2],
      [1.9, 14.4], [1.9, 9], [1.9, 13.2], [1.4, 7], [6.4, 8.8], [3.6, 4.3],
      [1.6, 10], [9.9, 2], [7.1, 15], [1.4, 0], [3.6, 13.7], [1.9, 15.2],
      [6.4, 16.5], [0.9, 10], [4.5, 17.1], [10.9, 10], [0.1, 14.7], [9, 10],
      [12.7, 11.8], [2.1, 10], [2.5, 10], [27.1, 10], [2.9, 11.5], [7.1, 10.8],
      [2.1, 12],
    ],
  },
  {
    name: "SAMPLE C",
    data: [
      [21.7, 3], [23.6, 3.5], [24.6, 3], [29.9, 3], [21.7, 20], [23, 2],
      [10.9, 3], [28, 4], [27.1, 0.3], [16.4, 4], [13.6, 0], [19, 5],
      [22.4, 3], [24.5, 3], [32.6, 3], [27.1, 4], [29.6, 6], [31.6, 8],
      [21.6, 5], [20.9, 4], [22.4, 0], [32.6, 10.3], [29.7, 20.8], [24.5, 0.8],
      [21.4, 0], [21.7, 6.9], [28.6, 7.7], [15.4, 0], [18.1, 0], [33.4, 0],
      [16.4, 0],
    ],
  },
];

export function SamplesScatterChart() {
  return (
    <div className="position-relative" style={{ minHeight: 365 }}>
      <ApexChart
        options={() => ({
          series: samples,
          chart: {
            height: 350,
            type: "scatter",
            zoom: { enabled: true, type: "xy" },
          },
          xaxis: {
            tickAmount: 10,
            labels: { formatter: (val: string) => parseFloat(val).toFixed(1) },
          },
          yaxis: { tickAmount: 7 },
        })}
      />
    </div>
  );
}
```

```tsx title="src/app/(dashboard)/samples/page.tsx"
import { SamplesScatterChart } from "@/components/samples-scatter-chart";
import { pageMetadata } from "@/lib/site";

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

export default function SamplesPage() {
  return (
    <div className="card">
      <div className="card-body">
        <SamplesScatterChart />
      </div>
    </div>
  );
}
```

`pageMetadata("/samples")` needs a `/samples` entry in `src/data/pages.json` for the page's title and description.

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `options` | `(theme: Theme) => ApexOptions` | | The ApexCharts options, with `series` and `chart.type`. Called again with the new colors when the color mode changes |

## Options

| Option | Effect |
| --- | --- |
| `series[].data` | `[x, y]` pairs. Both axes are numeric |
| `xaxis.labels.formatter` | Gets each x tick as a string. Here it rounds to one decimal |
| `xaxis.tickAmount`, `yaxis.tickAmount` | Number of ticks: 10 and 7 |
| `chart.zoom` | `type: "xy"`: drag a rectangle to zoom in on both axes. The toolbar zooms out and resets |

The samples take the primary, success and warning colors of the wrapper unless you set `colors`, for example `(theme) => ({ colors: [theme.info, theme.danger, theme.success], ... })`.

## Accessibility

- The legend names the samples. `markers.shape` takes one shape per series (`"circle"`, `"square"`), so the samples can differ by more than color.
- Point coordinates show in the tooltip on hover only. State the trend or cluster that matters in text.
- Zooming needs a pointer drag. The chart at its default zoom should carry the message.
- Other props of `ApexChart` go to its `<div>`: name the chart with `role="figure"` and `aria-label`.

## Related

- [React scatter chart](/react/docs/charts/scatter-chart/): the same chart in AdminKit for React (Vite)
- [Bootstrap 5 scatter chart](/bootstrap/docs/charts/scatter-chart/): the ApexCharts example of the HTML version
- [Chart setup](/nextjs/docs/charts/overview/): the `ApexChart`, `ChartJs` and `VectorMap` client components
- [Next.js bubble chart](/nextjs/docs/charts/bubble-chart/): points with a third value as the size
- [ApexCharts demo](https://nextjs-demo.adminkit.io/charts-apexcharts): the line, area, bar, column, pie, heatmap, mixed and candlestick charts of the demo

---

Canonical HTML page: https://adminkit.io/nextjs/docs/charts/scatter-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
