Andre
Andre

Reputation: 23

HighCharts not updating when the state changes in React

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

Answers (6)

Nikolay Rogchev
Nikolay Rogchev

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

Michael
Michael

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

Brodie
Brodie

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

Swapnil Navalakha
Swapnil Navalakha

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

clint_milner
clint_milner

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

d4vsanchez
d4vsanchez

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

Related Questions