Rechartsの棒グラフにnullが含まれるデータを渡すと表示がおかしくなる場合の対処法
概要
- Rechartsで棒グラフ作成時、値がnullであるデータがエリア外に描画される場合がある
- nullが入りうるような場合は、YAxisのdomainを0が範囲内に入るように設定すると良さそう
参考にしたページ、引用元など
下記に記載しているコードは公式ドキュメントの棒グラフのサンプルをちょっとだけ変更したものです。
また、グラフ画像は同じく公式ドキュメントのcodesandboxのリンク先でコードを実行した結果のスクショです。
経緯
お仕事でRechartsを使ったグラフ描画機能を触っています。
RechartsはReactで使えるグラフ描画のためのライブラリです。
ぱっと綺麗なグラフが描けて、アニメーションもついてるのでいいなぁと思ってるのですが、今回ちょっとした不都合に行き当たりました。
公式ドキュメントにそのような場合についての記述が見つけられず、ちょっと戸惑ったので、解決策を書き留めておきます。
正常に表示できる場合
RechartsではデータをObjectのArrayとして渡します。
例えば下記のようなコードを実行した時、
import "./styles.css"; import React from "react"; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend } from "recharts"; // これがグラフに表示されるデータ const data = [ { name: "Data A", value_1: 1000, value_2: 1500 }, { name: "Data B", value_1: 2000, value_2: 2300 }, { name: "Data C", value_1: 3000, value_2: 2800 } ]; export default function App() { return ( <BarChart width={500} height={300} data={data} margin={{ top: 5, right: 30, left: 20, bottom: 5 }} > <CartesianGrid strokeDasharray="3 3" /> <XAxis dataKey="name" /> <YAxis /> <Tooltip /> <Legend /> <Bar dataKey="value_1" fill="#82ca9d" /> <Bar dataKey="value_2" fill="#8884d8" /> </BarChart> ); }
下図のようなグラフが表示されます。
わかりやすくていいですよね。
値がnullのデータがあると表示がおかしくなる
ところが、ある状況下で表示がおかしくなる場合があります。
その状況というのは、
- 渡されたデータの中に値がnullであるものがある
- 他の値が全て負の値である
という場合です。
コード内の変数dataをこの状態に書き換えてみます。
まず、全て負の数にしてみます。
const data = [ { name: "Data A", value_1: -1000, value_2: -1500 }, { name: "Data B", value_1: -2000, value_2: -2300 }, { name: "Data C", value_1: -3000, value_2: -2800 } ];
するとグラフはこうなります。
この時点でもちょっと嫌ですが、さらに一部の値をnullにしてみると、
const data = [ { name: "Data A", value_1: null, value_2: -1500 }, { name: "Data B", value_1: -2000, value_2: -2300 }, { name: "Data C", value_1: -3000, value_2: -2800 } ];
グラフはこうなります。
軸の外側になんか生えてしまいました。
なぜこうなるのか?
この現象自体への言及は見つけられなかったですが、公式ドキュメントのYAxisの説明によると、Y軸の最小最大をdomainという属性で指定できるようで、これを指定しない場合、デフォルトでは 0 ~ auto の範囲が設定されるようです。
察するに、
- デフォルトでY軸の範囲は0始まりで正方向に自動で伸びる
- この範囲外のデータが入ってきた場合、軸の範囲が auto ~ auto に切り替わる(範囲外の値も非表示とはならない)
- データの中に値がnullであるものが含まれる場合、それは0として読み替えられる。ただし軸の範囲調整が正常に行われず、棒グラフがエリア外に飛び出す(エリア外の0に向かってグラフが伸びる)
という感じになっていると思われます。
どうすればいいか?
Y軸の範囲調整がうまくいっていないようなので、こちらで明示的に指定すれば良さそうです。
その際、0がエリア内に収まるように調整してやります。
例えば上のデータを表示したい場合は、
<YAxis domain={['auto', 0]}/>
のように、YAxisのdomain属性を設定します。
すると、グラフは下図のようになります。
軸の外側に飛び出していたものが消えてくれました。
まとめ
というわけで、Rechartsを使用する場合、nullが含まれるデータを渡す場合は軸の範囲設定をしないといけない場合がある、というお話でした。
Recharts、今後も使い倒していきたいなーと思います。