EChartsはデータ可視化において非常に強力なライブラリですが、複数回使用する際に共通するコードが増える傾向があります。このような繰り返し処理を効率化するために、Reactのフックを活用してEChartsの初期化処理をカプセル化します。
カスタムフックの構成要素
このカスタムフックでは、以下の要素を扱う必要があります:
- HTML要素(EChartsを描画するためのDOMノード)
- オプション設定(グラフの構成情報)
- インスタンス管理(初期化と破棄のライフサイクル管理)
基本構造
まず、ReactのuseRefとuseEffectを用いて、DOM要素とEChartsインスタンスを保持します。
import * as echarts from 'echarts';
import { useRef, useEffect } from 'react';
const useECharts = (option) => {
const chartRef = useRef(null);
const instanceRef = useRef(null);
// ...初期化と破棄処理
const getChartInstance = () => instanceRef.current;
return [chartRef, getChartInstance];
};
初期化とクリーンアップ
DOMがマウントされた後にEChartsを初期化し、コンポーネントがアンマウントされた時にインスタンスを破棄する処理を追加します。
useEffect(() => {
if (!chartRef.current) return;
instanceRef.current = echarts.init(chartRef.current);
instanceRef.current.setOption(option);
return () => {
if (instanceRef.current) {
instanceRef.current.dispose();
}
};
}, [option]);
共通オプションの適用
プロジェクト内で共通して使用するスタイルや設定をデフォルトとして定義し、個別のオプションとマージします。
import merge from 'lodash/merge';
const DEFAULT_CONFIG = {
tooltip: {},
xAxis: {
axisLabel: {}
},
yAxis: {},
series: {
itemStyle: {
borderRadius: [5, 5, 0, 0],
color: '#a7d1ff'
},
type: 'bar'
}
};
// setOption時にマージ
instanceRef.current.setOption(merge({}, DEFAULT_CONFIG, option));
使用例
以下はカスタムフックを使用したコンポーネントの例です。
import React, { memo } from 'react';
import { useECharts } from './useECharts';
const BarChart = memo(() => {
const [chartRef, getChart] = useECharts({
xAxis: {
data: ['A', 'B', 'C', 'D', 'E', 'F']
},
series: {
data: [5, 20, 36, 10, 10, 20]
}
});
const handleUpdate = () => {
getChart().setOption({
series: [
{
type: 'bar',
data: [111, 200, 36, 10, 10, 20]
}
]
});
};
return (
<div>
<button onClick={handleUpdate}>更新</button>
<div ref={chartRef} style={{ width: 400, height: 400 }}></div>
</div>
);
});