📊

Next.js+TypeScript+Chart.js(react-chartjs-2)の最小構成

2023/05/06に公開

開発環境

  • Next.js v13.3.4
  • npm v9.5.1
  • node v18.16.0
  • chartjs v4.3.0
  • react-chartjs-2 5.2.0

導入手順

Next.jsをインストール

npx create-next-app@latest --typescript

react-chartjs-2をインストール

https://react-chartjs-2.js.org/

npm install --save chart.js react-chartjs-2

react-chartjs-2自体の導入はこれで完了ですが、今回はダミーデータ生成用にFakerも導入しておきます。
https://fakerjs.dev/

npm install @faker-js/faker --save-dev

サンプルコード

以下は折れ線グラフを描画するための最小限のコードです。

./src/pages/index.tsx
import LineChart from '@/features/chart/components/LineChart'

export default function Home() {
  return (
    <>
      <LineChart></LineChart>
    </>
  )
}
./src/features/components/LineChart.tsx
import { faker } from '@faker-js/faker'

// point 1
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  ChartOptions,
  ChartData,
} from 'chart.js'
import { Line } from 'react-chartjs-2'
ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement)

// point 2
export const options: ChartOptions<'line'> = {}

// point 3
const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']
export const data: ChartData<'line'> = {
  labels,
  datasets: [
    {
      data: labels.map(() => faker.datatype.number({ min: -100, max: 1000 })),
    },
  ],
}

// point 4
export default function LineChart(): JSX.Element {
  return <Line options={options} data={data} />
}

コード解説

point 1

import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  ChartOptions,
  ChartData,
} from 'chart.js'
ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement)

import { Line } from 'react-chartjs-2'

必要なモジュールのimportを行います。

Chart.jsはv3からTree-shakingに対応しています(これに合わせる形でreact-chartjs-2ではv4から対応)。Tree-shakingとはアプリケーションで利用していない不要なコードを除去するための技術であり、これによりバンドルサイズを最小限に抑えることが可能です。

逆に言えば、上記でimportしている

  • LineElement
  • PointElement
  • CategoryScale
  • LinearScale

は、Line Chartを実現する上で最低限必要な要素です(ChartOptionsChartDataは型)。各グラフの描画で最低限必要な要素についてはChart.js公式にまとめられているので、詳しくはそちらをご確認ください。

point 2

export const options: ChartOptions<'line'> = {}

タイトルや凡例、グラフや文字・線の色・サイズといったChartのオプションを登録します。

ただし今回は最小構成ということで、あえて何も設定していません。(ChartOptions型の実装はDeepPartial<T>なので、何も設定しなくても問題ありません)。

内容についてもここでは触れませんが、Tree-shakingを使用している場合optionsだけでなくモジュールのimportも変更する必要があることにはご注意ください。

import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  ChartOptions,
  ChartData,
  Title, // add
} from 'chart.js'
ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Title) // add Title

export const options: ChartOptions<'line'> = {
  plugins: {
    title: {
      display: true,
      text: 'Chart Title',
    },
  }
}

point 3

const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']
export const data: ChartData<'line'> = {
  labels,
  datasets: [
    {
      data: labels.map(() => faker.datatype.number({ min: -100, max: 1000 })),
    },
  ],
}

Chartで表示するデータの実体です。labelsの内容は公式Exampleに倣う形で定義しています。

データの書き方には、いくつかの方法があります。

Primitive[]

今回使用している書き方です。Primitive[]型のdataプロパティと、optionalなプロパティであるlabelsを用いて記述します。この際、labelsの配列長はdataの中で最も長い配列の配列長以上である必要があります。

Object[]

dataプロパティをPoint[]型で記述する方法です。

export const options: ChartOptions<'line'> = {
  scales: {
    x: {
      type: 'linear', // スケールの種類を明示しないとグラフがぺちゃんこになる
      min: 0,
      max: 10,
    },
  },
}

export const data: ChartData<'line'> = {
  datasets: [
    {
      data: [...Array(7)].map((el, index: number) => ({
        x: index,
        y: faker.datatype.number({ min: -100, max: 100 }),
      })),
    },
  ],
}

その他、Objectのkeyとしてxやy以外を用いる方法等もあります。詳しくは公式documentをご参考ください。

point 4

export default function LineChart(): JSX.Element {
  return <Line options={options} data={data} />
}

設定したoptionsとdataをpropsとして渡してあげます。

おわりに

Chart.jsを使用する度に毎回似たようなことを調べたり雰囲気でコードを書いているような気がしたので、今後楽できるように最小構成についてまとめてみました。

Discussion