📊

Reactでチャート作成 Recharts

2020/09/24に公開

前提

Reactでチャートグラフを作成します。
利用するライブラリは Recharts です。

今回は円グラフを作っていきます。

ライブラリの導入

rechartsをインストールします。

$ npm install recharts

インストールしたら、円グラフの作成に必要なメソッドをインポートしましょう。

import { PieChart, Pie, Text } from 'recharts'

円グラフ作成

グラフの作成にはデータがあれば最低限作成可能です。
データは構造配列で用意します。ここではindexも持たせておきます。

const data = [
      {
        index: 0,
        name: 'データ1',
        value: 300,
      },
      {
        index: 1,
        name: 'データ2',
        value: 200,
      },
      {
        index: 2,
        name: 'データ3',
        value: 380,
      },
      {
        index: 3,
        name: 'データ3',
        value: 80,
      },
      {
        index: 4,
        name: 'データ4',
        value: 40,
      }
    ]

あとはデータを円グラフ用のメソッドに渡すだけです。

<PieChart width={730} height={250}>
  <Pie data={data} dataKey="value" cx="50%" cy="50%" outerRadius={100} fill="#82ca9d" label/>
</PieChart>

最低限グラフの作成は完了しました。
これではなかなか実際の運用では不向きなのでラベル表示などアップデートしていきます。

<Pie>パラメータについて

data

グラフのデータ

cx、cy

<PieChart>で確保したグラフ表示領域に対する位置を指します。

cx="100"の場合は、表示領域の右端を円グラフの中央にしてグラフが生成されます。

outerRadius

セレクタの外半径

innerRadius と合わせて設定すると、ドーナツ型の円グラフも作れます。

fill

カラーコードを指定して、グラフのカラーを指定します。

ラベル表示をカスタマイズ

<PieChart>で、グラフの表示サイズを確保します。

ラベルに情報を追加

せっかくdatanameを含めているので、ラベルにnameを表示させます。
labelプロパティはエレメント要素も渡すことができるので、namevalueを表示するラベル要素を作成します。

const label = ({ name, value, cx, x, y }) => {
      return (
        <>
	  {/* 引数で付属情報を受け取れます */}
          <Text x={x} y={y} fill="#82ca9d">{name}</Text>
          <Text x={x} y={y} dominantBaseline="hanging" fill="#82ca9d">{value}</Text>
        </>
      )
    }
...
<PieChart width={730} height={250}>
  <Pie data={data} dataKey="value" cx="50%" cy="50%" outerRadius={100} fill="#82ca9d" label={label}/>
</PieChart>

ラベルの<Text>を並べるだけでは文字が重なってしまうので、片方の情報をdominantBaseline="hanging"プロパティで垂直方向下部に配置させます。

これだけではラベル表示が常に左から右に配置されてしまうので、座標よって、右から左に文字を表示させる必要がありそうです。

位置情報で表示を変更

label関数が受け取っているcxグラフの中央x座標になります。
つまり、ラベルのx座標がグラフの中心のx座標より大きくなる(x > cx)場合はラベルがグラフの右に位置することになります。

textAnchor変数を用意してレンダリング位置を指定します。

const textAnchor = x > cx ? "start" : "end";

そのまま、<Text>textAnchroプロパティに値を渡してあげます。

return (
      <>
        <Text x={x} y={y} textAnchor={textAnchor} fill="#82ca9d">
          {name}
        </Text>
        <Text
          x={x}
          y={y}
          dominantBaseline="hanging"
          textAnchor={textAnchor}
          fill="#82ca9d"
        >
          {value}
        </Text>
      </>
    );
  };

まとめ

以下のようなグラフができましたでしょうか。
Image from Gyazo

実は、隣接するデータが小さいデータ同士の場合、ラベルがかぶってしまう場合があります。
この場合はかなり数学的な解決方法になりますが、需要があれば次回紹介したいと思います。
(サイン、コサイン、タンジェントとか使って、良い感じに配置させることができます。)

RechartsはReactに対応しており、かなり使いやすいチャートライブラリです。
もちろん他の棒グラフや折れ線グラフにも対応しているので、様々な用途で活用できそうです。

しかし、なかなかNoカスタマイズで利用できるケースは少ないのではないかなと感じます。
なんとかアイディア出して、楽な解決策があれば良いですが、かなり緻密な計算を重ねて問題を回避しないといけないといけない場面も出てきそうです。(力の見せ所です)

この辺りのカスタマイズ性も含めて利用しやすいチャートライブラリがあれば、改めて紹介したいと思います。

こんなのあるよ!なんて声お待ちしております。

Discussion