1

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

yongchang
  • 503
  • 6
  • 18

1 Answers1

2

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.

Florian Motteau
  • 3,467
  • 1
  • 22
  • 42
  • Sorry I won't have the time to setup a codesandbox for this, just throwing the main ideas of my WIP... – Florian Motteau Sep 02 '21 at 14:59
  • for this part `const chartRef = useRef();` so i will be passing from my index.js to my chart component? – yongchang Sep 02 '21 at 15:01
  • This part allows you to get the chart instance through a React Ref (https://reactjs.org/docs/hooks-reference.html#useref), so you can trigger a resize on the chart when the component is resized (using react-grid-layout). This is done with a useEffect, triggered when "size" (which is the actual dimensions of the component) changes. – Florian Motteau Sep 02 '21 at 15:05
  • as in how do i get HTMLDivElement? since my chart component is functional component, the only way i see how its going to get a HTMLDivElement, is index.js pass it as props – yongchang Sep 02 '21 at 15:11
  • This is the type of the element which will be targeted by the ref, so here : https://developer.mozilla.org/fr/docs/Web/API/HTMLDivElement. You can forget about this if you prefer : const chartRef = useRef();. See https://linguinecode.com/post/how-to-use-react-useref-with-typescript for example. – Florian Motteau Sep 02 '21 at 15:13
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/236716/discussion-between-user14857732-and-florian-motteau). – yongchang Sep 03 '21 at 01:54