Reputation: 23
Im working on a quick program that takes data from an enzyme reaction and plots it to a graph. Im running into this issue where my highcharts component will not update if i pass data to it in props. I can see that the data in state is changing in the console but i dont see anything on the chart.
The Graph component:
class HighGraph extends Component {
state = {
title: {
text: "My chart"
},
series: [
{
data: [1, 2, 3]
}
]
};
componentDidMount() {
let _this = this;
_this.interval = setInterval(function() {
console.log(_this.state.series[0].data);
_this.state.series[0].data = _this.props.list;
}, 2000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return (
<div>
<HighchartsReact highcharts={Highcharts} options={this.state} />
</div>
);
}
}
export default HighGraph;
the way im passing in the props:
<div>
<HighGraph list={this.state.graphdata} />
</div>
The array being passed:
[0.003, 0.006, 0, 0, 0.003, 0.006, 0.006, 0, 0.003, 0.006, 0.003, 0.003, 0.006, 0.006, 0.006, 0.006, 0.006, 0.006, 0.003, 0, 0.003, 0.003, 0.006, 0.003, 0.003, 0.003, 0.006, 0.003, 0.01, 0.006, 0, 0.003, 0.003, 0.003, 0.003, 0.003, 0.006, 0.003, 0, 0.006, 0.006]
Any Ideas? I still see 1,2,3 in the chart regardless even though the console tells me the state has changed
Upvotes: 2
Views: 10010
Reputation: 119
I know it's been some time, but I lost a day debugging this, finally the only thing that worked for me was passing immutable = { true }
to the chart component. This basically tells the chart to re-initialize every time the config changes and ignores the optimizations
Upvotes: 1
Reputation: 5038
I'll just throw in my own experience, hopefully this helps someone. for some inexplicable reason the only way I got this working was by using the index of a the series.
This code works and the chart updates without need for any of the above props:
currentSeries.forEach((s, i) => {
if (s.name === e?.target?.name || forceReset) {
if (forceReset) {
setIsFilterMode(false);
}
currentSeries[i].visible = true;
return;
}
currentSeries[i].visible = !currentSeries[i].visible;
The point is accessing the visible
property on each series by the index.
This code does not work and none of the above helped:
currentSeries.forEach((s, i) => {
if (s.name === e?.target?.name || forceReset) {
if (forceReset) {
setIsFilterMode(false);
}
s.visible = true;
return;
}
s.visible = !s.visible;
Upvotes: 0
Reputation: 11
I've been dealing with some similar issues in which I tried a lot of the same suggestions of adding the oneToOne={true}
and updateArgs={[true, true, true]}
.
In my application I am using React Context api and useReducer to store chart options. I had success in getting the chart to re-render by changing the series section from an array of series to just a singular series object.
Example from your state
state = {
title: {
text: "My chart"
},
series: [
{
data: [1, 2, 3]
}
]
};
You could try changing to
state = {
title: {
text: "My chart"
},
series:
{
data: [1, 2, 3]
}
};
For some reason, it would not trigger a re-render when attempting to change the state accessing the series array. Might also work to change the whole series state as well instead of accessing state.series[0]
to update. Hope that makes sense.
Upvotes: 1
Reputation: 319
setting updateArgs worked for me which is documented on https://github.com/highcharts/highcharts-react#readme
<HighchartsReact
highcharts={Highcharts}
options={ALARM_COUNT_CHART}
updateArgs={[true]}
/>
Upvotes: 7
Reputation: 365
In your HighchartsReact component, you need to supply a prop called oneToOne
and set it to true
.
<HighchartsReact highcharts={Highcharts} options={this.state} oneToOne={true} />
This tells the component to re-render when new data is present by way of State or Prop data.
ref: https://api.highcharts.com/class-reference/Highcharts.Chart#update
Upvotes: 0
Reputation: 1994
If you don't call the this.setState()
method, React will not trigger a re-render with the new data.
Try changing the line in your componentDidMount
.
It'll look something like this:
componentDidMount() {
let _this = this;
_this.interval = setInterval(function() {
console.log(_this.state.series[0].data);
_this.setState({ series: [{ data: _this.props.list }] });
}, 2000);
}
Upvotes: 2