gpt4 book ai didi

reactjs - 使用react-grid-layout调整 Highcharts 大小不起作用

转载 作者:行者123 更新时间:2023-12-03 13:44:23 26 4
gpt4 key购买 nike

我正在react中工作,并使用highcharts和react-grid-layout来调整div中元素的大小。不知何故,可调整大小的功能适用于图像,但不适用于 Highcharts 。 Grid.js是一个制作ResponsiveReactGridLayout的文件,它从chart.js文件中获取highchart。请找到下面的代码。

//Grid.js
import React, { Component } from 'react';
import {Responsive, WidthProvider,ReactGridLayout} from 'react-grid-layout';
import Charts from './charts.js';

const ResponsiveReactGridLayout = WidthProvider(Responsive);

class Grid extends Component {

onLayoutChange(layout) {
console.log(layout);
}

render(){
return (<div style={{borderStyle: 'groove'}}>
<h2> Panel Header </h2>
<ResponsiveReactGridLayout className="layout"
breakpoints={{lg: 1200, md: 96, sm: 768}}
cols={{lg: 5, md: 10, sm: 6}}
onLayoutChange={this.onLayoutChange}>

<div key="c" data-grid={{x: 0, y: 0, w: 1, h: 3}} style={{ border:'1px solid green', borderStyle: 'groove'}}>
<img src="https://cdn.geckoandfly.com/wp-content/uploads/2013/03/530-smiley-face.jpg" style={{width:'inherit', height:'inherit'}} />
</div>
<div key="d" className = 'react-grid-item react-resizable'
data-grid={{x: 1, y: 0, w: 1, h: 3}} style={{ border:'1px solid green', borderStyle: 'groove'}}
>
<Charts style={{width:'inherit'}} id={'Chart 1'}/>
</div>
<div key="e" data-grid={{x: 2, y: 0, w: 1, h: 3}} style={{ border:'1px solid green',borderStyle: 'groove'}}>
<Charts style={{width:'inherit'}} id={'Chart 2'}/>
</div>
<div key="f" data-grid={{x: 3, y: 0, w: 1, h: 3}} style={{ border:'1px solid green',borderStyle: 'groove'}}>
<Charts style={{width:'inherit'}} id={'Chart 3'}/>
</div>
</ResponsiveReactGridLayout>
</div>
)
}
}
export default (Grid);


//Charts.js
import React, { Component } from 'react';
const Highcharts = require('highcharts');
class Charts extends Component{
constructor(props){
super(props);
this.state = {
data : {
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 295.6, 454.4]
}]
},
pieData: [{name: "Firefox",y: 6},{name: "MSIE",y: 4},{name: "Safari",y: 4},{name: "Opera",y: 1},{name: "Chrome",y: 7}]
};
}

/**
* Inject highcharts markup into the DOM after the rest of the component has mounted
* @return {None}
*/
componentDidMount() {
// Load in any highcharts modules
if (this.props.modules) {
this.props.module.forEach((module) => {
module(Highcharts);
});
}

// Create the actual chart and assign reference
const props = this.processPropsModel(this.props);
const containerRef = `container${props.id}`;
this.chart = new Highcharts.chart(
containerRef,
props.options
);
}

processPropsModel(props) {
const newProps = {};
newProps.id = this.props.id;
newProps.options = this.generateDefaultOptions();
return newProps;
}

/**
* Generating some default chart options for placeholding purposes
* @return {Object} The options to be passed into the chart
*/
generateDefaultOptions() {
return {

title: {
text: this.props.id,
x: -20 //center
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
yAxis: {
title: {
text: null
}
},
tooltip: {
valueSuffix: '°C'
},
series: [{
name: 'Tokyo',
data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
}]
};
}

render(){
const props = this.processPropsModel(this.props);
return (
<div id={`container${props.id}`}>
</div>
);
}
}
export default Charts;

最佳答案

所以,我在使用 highcharts-react-official 和 react-grid-layout 时遇到了同样的问题。

这就是我最终让它发挥作用的方法。

<小时/>

tl;博士

  1. 将图表的所有父项(直到网格项)的高度设置为 100%。
  2. highcharts 自己创建了一个烦人的 div。找到一种方法来识别它并赋予它 100% 的高度。
  3. 将图表本身的高度设置为 100%。
  4. 使用 React highcharts 回调来获取图表对象。
  5. 当您的组件更新时,会重排您的图表。
<小时/>

下面是我的响应式网格布局,只是为了提供一些上下文。

// Component/Grid/Grid.js
<ResponsiveGridLayout
...
>
{this.state.widgets.map((widget) =>
<Card key={widget.DWG_ID}>
<Widget
widget={widget}
/>
</Card>
)}
</ResponsiveGridLayout>

现在,在 Widget 组件内,将作为 highchart 父级的任何 div 的高度设置为 100%。

// Component/Widget/Widget.js
<CardBody className="widgetContent">
<CardTitle className="widget-title">{this.props.widget.DWG_LABEL}</CardTitle>
<Chart
widget={this.props.widget}
/>}
</CardBody>

对于上面的 jsx,我只需要对具有类 widgetContent 的元素 CardBody 执行此操作,所以

// Component/Widget/Widget.css
.widgetContent { height: 100%; }

现在,在图表组件(最有趣的地方)中,我必须创建一个非常丑陋的 div,以便能够识别 highcharts 创建的最外层 div。

elements created by highcharts

上图中可以看到有问题的臭名昭著的 div,位于类 highchartsWrapper 的 div 的正下方,其属性为 data-highcharts-chart 。这个 div 是我的图表中唯一一个我无法直接识别以给出 100% 高度的父级。所以我创建了包装器以便能够明确地识别它。请注意,在图表选项中,我们还传递了一个类名,以便能够为图表本身提供 CSS 高度属性。

如果有人对如何识别这个有问题的 div 有更好的想法,请告诉我。

// Component/Chart/Chart.js
options = {
...
chart: { className: 'chart' }
}
<div className="highchartsWrapper">
<HighchartsReact
highcharts={Highcharts}
options={options}
callback={(chart) => this.setChart(chart)}
/>
</div>

所以我可以给它 css

// Component/Chart/Chart.css
.highchartsWrapper > div {
height: 100%;
}
.chart {
height: 100%;
}

现在,您的 Highcharts 理想情况下会采用正确的宽度和高度。但还有另一个复杂之处:当 highchart 第一次渲染并检查其 parent 的高度时,react-grid-layout 尚未完成其调整大小的魔力。这意味着您的图表将非常小。此外,当您调整网格项目的大小时,您希望将 Highcharts 调整为新的父级大小。但是等等,我以前使用过 highcharts,我知道该怎么做!好旧的 Chart.reflow() !不幸的是,这最终并不那么容易。

首先,获取可以调用回流的图表对象并不是很简单。如果您注意到,我给了我的 HighchartsReact 回调

(chart) => this.setChart(chart)

这只是将图表对象存储为我的类组件的属性。我的 setChart 函数仅执行以下操作:

setChart(chart) {
this.chart = chart;
}

这样做可能看起来很愚蠢。为什么不直接将 setChart 赋予 HighchartsReact 的回调属性呢?好吧,因为如果你这样做,根据 highcharts-react-official 文档,你在 setChart 函数中的 this 将是你的图表对象......一切都非常困惑,但它似乎是这样工作的。

再次强调,如果有人有更简洁的解决方案,请告诉我

最后,当我们的图表组件更新时,我们可以调用 this.chart.reflow() 。我所做的就是这样的

constructor() {
super(props)

this.firstResize = true;
}

componentDidUpdate(prevProps) {

if (this.didWidgetSizeChange(prevProps) || this.isFirstResize) {
this.chart.reflow();
this.isFirstResize = false;
}
}

当组件更新时,我们称为图表重排。在 componentDidMount 上,网格项还没有最终大小,因此我使用一个标志来确定第一次更新(这正是:网格项已完成第一次调整大小)。然后,对于任何其他更新,我编写了一个函数,该函数基本上将该网格项的先前布局与新布局进行比较,以确定大小或宽度是否已更改。如果是这样,我们再次回流以将 highcharts 的大小调整为新的网格项大小。

希望这有帮助!

和平!

关于reactjs - 使用react-grid-layout调整 Highcharts 大小不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40430415/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com