reactjsechartsreact-grid-layoutapache-echarts

how do i make echarts resize together with the react-grid-layout?


I am using ResponsiveGridLayout, React-Grid-Layout in my application, and I am using echarts as grid items.

The drag and drop works fine, but when i resize the grid item, the chart did not resize together with it. I have tried implementing the onLayoutchange properties, but it is not working.

can someone can help me out here

this is my codesandbox that reproduce the issue


Solution

  • I was able to achieve this, at least when modifying grid items width (not height yet...), by using this hook, then in your chart component :

    [...]
    
    const chartRef = useRef<HTMLDivElement>();
    const size = useComponentSize(chartRef);
    
    useEffect(() => {
      const chart = chartRef.current && echarts.getInstanceByDom(chartRef.current);
      if (chart) {
        chart.resize();
      }
    }, [size]);
    
    [...]
    
    return <div ref={chartRef}></div>;
    

    ...so your chart will resize when the grid item is resized. I'm not sure about that, still a WIP for me but it works.

    Extract this as a custom hook

    You can create useEchartResizer.ts, based on @rehooks/component-size :

    import useComponentSize from '@rehooks/component-size';
    import * as echarts from 'echarts';
    import React, { useEffect } from 'react';
        
    export 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]);
    };
    

    Then use it in the component which holds the chart :

    export const ComponentWithChart = (props): React.ReactElement => {
      const chartRef = useRef<HTMLDivElement>();
      useEchartResizer(chartRef);
    
      useEffect(() => {
        const chart = echarts.init(chartRef.current, null);
        // do not set chart height in options
        // but you need to ensure that the containing div is not "flat" (height = 0)
        chart.setOption({...} as EChartsOption); 
      });
    
      return (<div ref={chartRef}></div>);
    });
    

    So each time the div is resized, useEchartResizer will trigger a chart.resize(). Works well with react-grid-layout.