使用React根据网格布局的宽度和高度调整HighCharts的大小

3
我在React中编写了一个网格布局组件,里面加载了High Chart,效果很好。但是,在调整网格的宽度和高度时,High Chart不会自动调整大小,并且调整大小后可能会出现问题。我在Stack Overflow上搜索到了同样的问题,链接为:Resize highcharts using react-grid-layout not working。然后我知道需要调用chart reflow方法来使High Chart在网格布局发生变化时适应网格布局。由于我是React的新手,不知道如何实现此功能。请提供一些解决方案。以下是我尝试的代码:
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,这是Highcharts中的一个错误,已在此处报告:https://github.com/highcharts/highcharts/issues/9491。我在在线代码编辑器中复制了您的代码,似乎调用`chart.reflow()`方法不够。请检查此示例:https://codesandbox.io/s/highcharts-react-demo-fnj1i(禁用`reflow`),并告诉我是否符合您的要求。 - ppotaczek
谢谢您的回复。我尝试了您的示例,并将“chat overflow”更改为“true”,以检查当网格布局更改时聊天是否会重新流动。但是它失败了。图表被打破了。我希望图表能够根据网格布局大小进行调整大小。 - smackbeta
@ppotaczek,有没有其他的方法可以实现这个呢? - smackbeta
嗨@smackbeta,请查看此类似的帖子,其中包含antd:https://github.com/highcharts/highcharts-react/issues/121。解决方案是设置`hasSider`属性,在`react-grid-layout`中是否有类似的东西? - ppotaczek
2个回答

2
我认为高级图表缩放功能无法正常工作的原因可以从Highcharts中'reflow'的文档中找到。

默认情况下,图表会在窗口调整大小事件(即window.resize)发生时自动重新布局以适应其容器,根据chart.reflow选项。然而,对于div调整大小没有可靠的事件,所以如果容器在没有窗口调整大小事件的情况下被调整大小,则必须显式调用该事件。

这种情况与您现在所做的相匹配:您尝试调整div本身的大小,而不是窗口大小,因此它不能按照您的期望工作。

我所做的使我的图表在网格中可调整大小的方法如下:

  1. 创建一个函数来执行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
      }
    }
  };

使用由react-grid-layout提供的onLayoutChange
<GridLayout
    cols={12}
    layout={layout}
    rowHeight={30}
    width={1200}
    onLayoutChange={() => onLayoutChange()}
>
...
</GridLayout>

然后...砰!你得到了可以通过react-grid-layout中的调整大小按钮控制的可调整大小图表。

为了更容易理解,您可以在此处查看实时工作示例: https://codesandbox.io/s/resize-highcharts-in-grid-9e625?file=/src/App.js

你的代码在宽度方面运行良好,但高度不具有响应性。 - Rana Faraz

0

这是使其适合于网格布局的解决方案:

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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接