[メモ] amCharts を使用するフック
amCharts を React で使用するフックです。
Using React - amCharts 4 Documentation
useAmChart
import { SerialChart } from '@amcharts/amcharts4/.internal/charts/types/SerialChart';
import * as am4core from '@amcharts/amcharts4/core';
import am4themes_animated from '@amcharts/amcharts4/themes/animated';
import { RefObject, useEffect, useState } from 'react';
am4core.useTheme(am4themes_animated);
/**
* amCharts を指定した `elementRef` に適用するフック
* @param elementRef チャートを紐づける要素の `ref` (とりあえず `div`)
* @param classType `@amcharts/amcharts4/charts` に定義されているチャートのタイプ
*/
const useAmChart = <T extends SerialChart>(
elementRef: RefObject<HTMLDivElement> | null,
classType: new () => T
): T | null => {
// am4core.create の戻り値を格納する変数
const [chart, setChart] = useState<T | null>(null);
useEffect(() => {
// componentWillUnmount と同様に実行させる dispose
return () => {
chart && chart.dispose();
};
}, []);
// elementRef の値に基づいて am4core.create の実行と chart への格納
useEffect(() => {
const element = elementRef?.current;
if (element) {
setChart(am4core.create(element, classType));
}
}, [elementRef]);
return chart;
};
export default useAmChart;
import React, { useRef, useEffect } from "react";
import useAmChart from "./hooks/useAmChart";
export default function App() {
// 表示対象向けの ref
const chartRef = useRef<HTMLDivElement>(null);
// useAmChart を適用
const chart = useAmChart(chartRef, am4charts.XYChart);
// チャートへのデータ反映など
useEffect(() => {
if (chart) {
chart.paddingRight = 20;
const data = [];
・・・
})
return (
・・・
// 表示対象の要素の ref に chartRef を指定
<div ref={chartRef} style={{ width: "100%", height: "500px" }}></div>
・・・
);
}