//index.tsx
import React, { useEffect, useRef, useState } from "react";
import * as echarts from "echarts";
import useEchartResizer from "./useEchartResizer";
export interface BaseChartProps {
options: echarts.EChartsOption;
}
const Echart: React.FC<BaseChartProps> = ({ options }) => {
const chartRef = useRef<HTMLDivElement>(null);
useEchartResizer(chartRef);
let myChart: any = null;
/**
* @description: resize
* @return {*}
*/
const handleResize = () => {
myChart?.resize();
};
/**
* @description: 初始化
* @return {*}
*/
const initChart = () => {
window.removeEventListener("resize", handleResize);
myChart?.dispose();
const renderedInstance = echarts.getInstanceByDom(chartRef?.current);
if (renderedInstance) {
myChart = renderedInstance;
} else {
myChart = echarts?.init(chartRef?.current as HTMLElement);
}
myChart?.setOption(options, true);
window.addEventListener("resize", handleResize);
};
useEffect(() => {
initChart();
return () => {};
}, [options]);
return <div ref={chartRef} style={{ height: "100%", width: "100%" }} />;
};
export default Echart;
//useEchartResizer.ts
import useComponentSize from "./useComponentSize";
import * as echarts from "echarts";
import React, { useEffect } from "react";
const useEchartResizer = (chartRef: React.MutableRefObject<HTMLDivElement>) => {
const size = useComponentSize(chartRef);
useEffect(() => {
const chart =
chartRef.current && echarts.getInstanceByDom(chartRef.current);
if (chart) {
chart.resize();
}
}, [chartRef, size]);
};
export default useEchartResizer;
// useComponentSize.ts
import React, { useState, useLayoutEffect } from "react";
function getSize(el) {
if (!el) {
return {};
}
return {
width: el.offsetWidth,
height: el.offsetHeight,
};
// 之前求高度都是用的getComputedClientRect()這個方法
}
export default function useComponentSize(ref) {
let [size, setSize] = useState(getSize(ref.current));
function handleResize() {
if (ref && ref.current) {
setSize(getSize(ref.current));
}
}
useLayoutEffect(() => {
handleResize();
// 第一次初始化就執行一遍
let resizeObserver = new ResizeObserver(() => handleResize());
// 定義一個檢測變動的狀態機
resizeObserver.observe(ref.current);
// 把這個檢測機制綁定到當前元素
return () => {
resizeObserver.disconnect(ref.current);
resizeObserver = null;
};
}, []);
return size;
}