Top View


Author Isse Teruhi

react-chartjs-2の使い方②

2024/08/29

概要

今回は、react-chartjs-2を使用して箱ひげ図を作成しました。react-chartjs-2自体には箱ひげ図を描画する機能が含まれていないため、代わりにchartjs-chart-boxplot という Chart.js のモジュールを利用しています。

注意: まだお読みでない方は、react-chartjs-2の使い方①の記事もご覧ください。

Install

reactの開発プロジェクトで前回の記事のコマンドに加えて次のコマンドを実行してください。

npm install chart.js @sgratzl/chartjs-chart-boxplot

chartjs-chart-boxplotの利用にはchart.jsやreact-chartjs-2の導入が必要ですのでご注意ください。

描画できるグラフ

chartjs-chart-boxplotを使用することでchartjsのみでは描画できなかった次のようなグラフを描画できます。

  • 箱ひげ図
  • バイオリン図

グラフ表示

今回は単純な箱ひげ図を表示してみました。コンポーネントを次のように作成しました。

import { useRef } from 'react'
import {
  Chart as ChartJS,
  CategoryScale,
  Title,
  Tooltip,
  Legend,
  ChartOptions,
  ChartData,
} from 'chart.js'
import { Chart } from 'react-chartjs-2'
import zoomPlugin from 'chartjs-plugin-zoom'
import {
  BoxPlotController,
  BoxAndWiskers,
  BoxPlotDataPoint,
} from '@sgratzl/chartjs-chart-boxplot'
import { ZoomPluginOptions } from 'chartjs-plugin-zoom/types/options'

ChartJS.register(
  CategoryScale,
  BoxPlotController,
  BoxAndWiskers,
  Title,
  Tooltip,
  Legend,
  zoomPlugin
)

interface BoxplotProps {
  graphData: ChartData<'boxplot', BoxPlotDataPoint[], string>
  title: string
  xtext: string
  ytext: string
  className: string
}

export default function Boxplot({
  graphData,
  title,
  xtext,
  ytext,
  className,
}: BoxplotProps) {
  const chartRef = useRef<ChartJS<'boxplot', BoxPlotDataPoint[], string>>(null)
  
  const onResetZoom = () => {
    chartRef?.current?.resetZoom()
  }
  
  const zoomOptions: Partial<ZoomPluginOptions> = {
    zoom: {
      wheel: {
        enabled: true,
      },
      pinch: {
        enabled: true,
      },
      mode: 'y',
    },
    pan: {
      enabled: true,
      mode: 'y',
    },
  }

  const options: ChartOptions<'boxplot'> = {
    responsive: true,
    scales: {
      x: {
        title: {
          display: true,
          text: xtext,
        },
      },
      y: {
        title: {
          display: true,
          text: ytext,
        },
      },
    },
    plugins: {
      legend: {
        position: 'top',
      },
      title: {
        display: true,
        text: title,
      },
      zoom: zoomOptions,
    },
  }
  return (
    <>
      <Chart
        type="boxplot"
        options={options}
        data={graphData}
        ref={chartRef}
        className={className}
      />
      <button onClick={onResetZoom}>zoom reset</button>
    </>
  )
}

コードの説明

import

import { useRef } from 'react'
import {
  Chart as ChartJS,
  CategoryScale,
  Title,
  Tooltip,
  Legend,
  ChartOptions,
  ChartData,
} from 'chart.js'
import { Chart } from 'react-chartjs-2'
import zoomPlugin from 'chartjs-plugin-zoom'
import {
  BoxPlotController,
  BoxAndWiskers,
  BoxPlotDataPoint,
} from '@sgratzl/chartjs-chart-boxplot'
import { ZoomPluginOptions } from 'chartjs-plugin-zoom/types/options'
  • ①の記事で必要だったものに加えて(LineLineElementなどを除く)、react-chartjs-2からChart@sgratzl/chartjs-chart-boxplotから必要なものをインポートしています。
  • BoxPlotControllerは箱ひげ図の描画、BoxAndWiskersは箱ひげ図のビジュアル要素の描画、BoxPlotDataPointは箱ひげ図に必要なデータポイントの型定義に必要となります。

ChartJS.register()

ChartJS.register(
  CategoryScale,
  BoxPlotController,
  BoxAndWiskers,
  Title,
  Tooltip,
  Legend,
  zoomPlugin
)
  • ①の記事で書いたものと同様に必要なものを登録します。今回は箱ひげ図を利用するのに必要な BoxPlotControllerBoxAndWiskers を追加登録します。

BoxplotProps

interface BoxplotProps {
  graphData: ChartData<'boxplot', BoxPlotDataPoint[], string>
  title: string
  xtext: string
  ytext: string
  className: string
}

export default function Boxplot({
  graphData,
  title,
  xtext,
  ytext,
  className,
}: BoxplotProps) {
  const chartRef = useRef<ChartJS<'boxplot', BoxPlotDataPoint[], string>>(null)
  • このインターフェースは、①の記事で定義されているものと同様に、Boxplotコンポーネントに渡されるプロパティを定義しています。

操作関数と各種オプション

  const onResetZoom = () => {
    chartRef?.current?.resetZoom()
  }
  const zoomOptions: Partial<ZoomPluginOptions> = {
    zoom: {
      wheel: {
        enabled: true,
      },
      pinch: {
        enabled: true,
      },
      mode: 'y',
    },
    pan: {
      enabled: true,
      mode: 'y',
    },
  }

  const options: ChartOptions<'boxplot'> = {
    responsive: true,
    scales: {
      x: {
        title: {
          display: true,
          text: xtext,
        },
      },
      y: {
        title: {
          display: true,
          text: ytext,
        },
      },
    },
    plugins: {
      legend: {
        position: 'top',
      },
      title: {
        display: true,
        text: title,
      },
      zoom: zoomOptions,
    },
  }
  • onResetZoom では箱ひげ図のズームをリセットするためのボタンを定義しています。
  • zoomOptions,optionsでは箱ひげ図のズームやパンの動作や制限の設定、箱ひげ図自体の設定を定義しています。設定オプションは①の記事に掲載されているものと同様です。詳しくは①の記事をご確認ください。

コンポーネントのレンダリング

  return (
    <>
      <Chart
        type="boxplot"
        options={options}
        data={graphData}
        ref={chartRef}
        className={className}
      />
      <button onClick={onResetZoom}>zoom reset</button>
    </>
  )
}
  • Chartコンポーネントを使用して、チャートを描画します。
  • 今回はズームやパンをリセットするボタンのみ追加しています。

コンポーネントの使い方

import Boxplot from './components/Boxplot.tsx'
// ...
<Boxplot title="sample graph" xtext="x軸のテキスト" ytext="y軸のテキスト" graphData={sampleBoxplotDatas}/>
  • 使い方は前回の記事と同様です。

このコンポーネントを使うことで具体的に次のような箱ひげ図を表示できます。

boxplot.png

以上になります。今回は参考にできるドキュメントが少なく、実装に苦労しましたが、無事に完成させることができました。

参考にした記事・文献

Isse Teruhi

Isse Teruhi