3

I have a wrote a grid layout component in react. Inside the grid, I have loaded the high chart and it works great. On resizing the width and height of the grid, the high chart doesn't resize and it breaks when resizing. I have searched for stack overflow and found the same question in here "Resize highcharts using react-grid-layout not working". Then i came to know that chart reflow method is to be called to make the high chart fit with in the grid when the grid layout changes. Since i am new to react, I don't know how to make it possible. Help me with some solutions.

Here's the code i tried:

import React from 'react';
import logo from './logo.svg';
import './App.css';
import '/home/paulsteven/Documents/resize-ui/resize_ui/node_modules/react-grid-layout/css/styles.css';
import '/home/paulsteven/Documents/resize-ui/resize_ui/node_modules/react-resizable/css/styles.css';
import GridLayout from 'react-grid-layout';
import BarChart from "highcharts-react-official";


class MyFirstGrid extends React.Component {
  state ={
    options :{reflow:true,
        title: {
            text: 'Fruit Consumption'
        },
        subtitle: {
            text: 'Steven Chart'
            },
        chart: {
            type: 'bar'
        },
        xAxis: {
            categories: ['Apples', 'Bananas', 'Oranges']
        },
        yAxis: {
            title: {
                text: 'Fruit eaten'
            }
        },
        series: [{
            name: 'Prince',
            data: [4, 4, 2]
        }, {
            name: 'Syed',
            data: [5, 3, 5]
        },
        {
            name: 'Sam',
            data: [1, 3, 3]
        }]
      }
    }

  render() {
    // layout is an array of objects, see the demo for more complete usage
    var layout = [
      {i: 'a', x: 0, y: 0, w: 5, h: 2},
      {i: 'b', x: 1, y: 0, w: 3, h: 2},
      {i: 'c', x: 4, y: 0, w: 1, h: 2}
    ];
    return (
      <GridLayout className="layout" layout={layout} cols={12} rowHeight={30} width={1200}>
        <div style={{backgroundColor: 'grey'}}  key="a">

                  {/* <div id="container" style={{width:'100%',height:'400px'}}></div> */}

                  <BarChart options ={this.state.options} />
        </div>
        <div  style={{backgroundColor: 'red'}}key="b">b</div>
        <div style={{backgroundColor: 'blue'}} key="c">c</div>
      </GridLayout>
    )
  }
}

export default MyFirstGrid;
smackbeta
  • 91
  • 2
  • 5
  • Hi @smackbeta, That is a bug in Highcharts, which is reported here: https://github.com/highcharts/highcharts/issues/9491. I reproduced your code in online code editor and it seems that calling `chart.reflow()` method is not enough. Please check this example: https://codesandbox.io/s/highcharts-react-demo-fnj1i with disabled `reflow` and please let me know if this meets your requirements. – ppotaczek Jul 30 '19 at 11:13
  • Thanks for the response.. I tried your example and changed the `chat overflow` to `true` to check whether the chat gets reflow when the grid layout changed. But it fails. The chart gets breaked. I want the chart to be resized as per the grid layout size. – smackbeta Aug 02 '19 at 06:59
  • @ppotaczek, is there any other way to make it possible.... – smackbeta Aug 02 '19 at 08:55
  • Hi @smackbeta, Please check this similar thread with `antd`: https://github.com/highcharts/highcharts-react/issues/121. The solution was to set `hasSider` property, is there something similar in `react-grid-layout`? – ppotaczek Aug 02 '19 at 10:54

2 Answers2

2

I think the reason why the functionality of resizing highchrts is not working you can find it from the documentation of 'reflow' from hightcharts

By default, the chart reflows automatically to its container following a window.resize event, as per the chart.reflow option. However, there are no reliable events for div resize, so if the container is resized without a window resize event, this must be called explicitly.

The situation matches what you did now: you tried to resize the div itself but not the window size, so it doesn't work as you expected.

What I did to make my charts resizable in grid as following:

  1. Create a function to do reflow
const onLayoutChange = () => {
    for (let i = 0; i < Highcharts.charts.length; i += 1) {
      if (Highcharts.charts[i] !== undefined) {
        Highcharts.charts[i].reflow(); // here is the magic to update charts' looking
      }
    }
  };
  1. Use onLayoutChange provided by react-grid-layout
<GridLayout
    cols={12}
    layout={layout}
    rowHeight={30}
    width={1200}
    onLayoutChange={() => onLayoutChange()}
>
...
</GridLayout>

And then...BANG! you got resizable charts controlled by the resize button in react-grid-layout.

Make it easy to understand, you can view live working here: https://codesandbox.io/s/resize-highcharts-in-grid-9e625?file=/src/App.js

Yi-Pei Huang
  • 131
  • 1
  • 7
0

Here's the Solution to make it fit in the grid layout:

import React from 'react';
import './App.css';
import '/node_modules/react-grid-layout/css/styles.css';
import '/node_modules/react-resizable/css/styles.css';
import GridLayout from 'react-grid-layout';
import Highcharts from "highcharts/highstock";
import HighchartsReact from "highcharts-react-official";

const options = {
  series: [
    {
      data: [1, 2, 3]
    }
  ]
};

class MyFirstGrid extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
    this.conRef = React.createRef();
  }

  render() {
    // layout is an array of objects, see the demo for more complete usage
    var layout = [
      { i: "a", x: 0, y: 0, w: 5, h: 5 },
      { i: "b", x: 1, y: 0, w: 3, h: 2 },
      { i: "c", x: 4, y: 0, w: 1, h: 2 }
    ];
    return (
      <GridLayout
        className="layout"
        layout={layout}
        cols={12}
        rowHeight={30}
        width={1200}
        onResizeStop={function(event) {

         this.myRef.current.chart.setSize(this.conRef.current.clientWidth,this.conRef.current.clientHeight)
          console.log('hello', event);
        }.bind(this)}
      >
        <div ref={this.conRef}  style={{ backgroundColor: "#00000000" }} key="a">
          <HighchartsReact
            ref= {this.myRef}
            containerProps={{ style: { width: '100%', height: '100%' } }}
            options={options}
            highcharts={Highcharts}
          />
        </div>

        <div style={{ backgroundColor: "red" }} key="b">
          b
        </div>
        <div style={{ backgroundColor: "blue" }} key="c">
          c
        </div>
      </GridLayout>
    );
  }
}


export default MyFirstGrid;
Smack Alpha
  • 1,828
  • 1
  • 17
  • 37