Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do I actually "append" a point to Highcharts.series? #51

Closed
ritou11 opened this issue Sep 2, 2018 · 10 comments
Closed

How do I actually "append" a point to Highcharts.series? #51

ritou11 opened this issue Sep 2, 2018 · 10 comments

Comments

@ritou11
Copy link

ritou11 commented Sep 2, 2018

I'm having a problem on the rendering speed of this.

Data comes continuously at a frequency of 100Hz or higher and I need to show them on the chart. Now I'm using a button to trigger the update process of HighchartsReact, but with the growing size of data, the update process gets quite slow and blocks UI.

After reading the code I found the update process here:

componentWillReceiveProps: function () {
this.chart.update(Object.assign({}, this.props.options), true, !(this.props.oneToOne === false))
},

It seems to update all the data every time by giving the entire "options" object to chart. I guess the chart won't diff the options. Apparently, if you draw tons of data every time, the rendering could be really slow.

In the example of Highcharts, series.addPoint is used to append data. So is there any chance I can actually "append" a point to Highcharts.series instead of writing the huge chunk of data every time?

@KacperMadej
Copy link

Hi @ritou11

Currently only chart.update is used, so if you require an advanced solution then you could try using Highcharts without the wrapper and call API functions that will work best for your chart performance.

Internal note:
Possible enhancement - enable series.addPoint function call through the wrapper without triggering chart.update or maybe something more general, like marking the change as handled when a custom code handles it.

@ldelossa
Copy link

@KacperMadej are we able to access the chart directly via reft? Like the example here:
https://github.com/kirjs/react-highcharts

@ppotaczek
Copy link
Contributor

Hi @ldelossa,

Yes, you can access directly the chart by refs, for example in this way:

class Chart extends React.Component {
  constructor(props) {
    super(props);
    this.chartComponent = React.createRef();

    this.state = {
      options: {
        series: [
          {
            data: [1, 2, 3]
          }
        ]
      }
    };
  }

  componentDidMount() {
    const chart = this.chartComponent.current.chart;
    // ...
  }

  render() {
    return (
      <HighchartsReact
        constructorType={"chart"}
        ref={this.chartComponent}
        highcharts={Highcharts}
        options={this.state.options}
      />
    );
  }
}

Best regards!

@ldelossa
Copy link

If I wanted to extend the above concept to live updating data, do you have any recommendation? Currently I’m pulling data from a websocket and I’d like to add a point or multiple points to the existing array in an efficiently manner

@ppotaczek
Copy link
Contributor

@ldelossa,

It depends on the amount of data and the interval. You can test the following solutions and find out which one will be best for you:

We try to keep this repository only for bugs, so in the future please contact Highcharts suport for this type of questions: https://www.highcharts.com/blog/support/

Best regards!

@LucidityDesign
Copy link

LucidityDesign commented Aug 9, 2019

I'm using Highstock and have something like this as dataset:

[
  [timestamp, 1.2],
  [timestamp + 1s, 1.4],
  [timestamp + 2s, 0.9],
...
]

If I use state or setState the limits and range the user has selected gets overridden due to the re-renderings.

If I use addPoint the navigator messes up my data.
I have one series and add data by calling:

shouldComponentUpdate (nextProps) {
  chart.series[0].addPoint(nextProps.values[nextProps.values.length - 1], true, true)`
  return false
}

After that I can see following output:

console.log(chart.series[0].data) // my data
=>
52: C {series: v, x: 1565355010863, y: 0, options: {…}, isNull: false, …}
53: C {series: v, x: 1565355011863, y: 0, options: {…}, isNull: false, …}
54: C {series: v, x: 1565355012863, y: 0, options: {…}, isNull: false, …}
55: C {series: v, x: 1565355013863, y: 46.16563087189379, options: {…}, isNull: false, …}
56: C {series: v, x: 1565355013863, y: 46.16563087189379, options: {…}, isNull: false, …}
57: C {series: v, x: 1565355015907, y: 50.51810410147327, options: {…}, isNull: false, …}
58: C {series: v, x: 1565355017853, y: 45.926992636929334, options: {…}, isNull: false, …}
59: C {series: v, x: 1565355019811, y: 45.545298897828026, options: {…}, isNull: false, …}
60: C {series: v, x: 1565355021846, y: 41.76886760720148, options: {…}, isNull: false, …}
console.log(chart.series[1].data) // data of navigator (?)
=>
52: C {series: v, x: 1565355010863, y: 0, options: {…}, isNull: false, …}
53: C {series: v, x: 1565355011863, y: 0, options: {…}, isNull: false, …}
54: C {series: v, x: 1565355012863, y: 0, options: {…}, isNull: false, …}
55: C {series: v, x: 1565355013863, y: 46.16563087189379, options: {…}, isNull: false, …}
56: C {series: v, x: 1565355013863, y: 46.16563087189379, options: {…}, isNull: false, …}
57: C {series: v, x: 1565355015907, y: 50.51810410147327, options: {…}, isNull: false, …}
58: C {series: v, x: 1565355017853, y: 45.926992636929334, options: {…}, isNull: false, …}
59: C {series: v, x: 1565355019811, y: 45.545298897828026, options: {…}, isNull: false, …}
60: C {series: v, x: 1565355021846, y: 41.76886760720148, options: {…}, isNull: false, …}
61: C {series: v, x: 1565355015907, y: 50.51810410147327, options: {…}, isNull: false, …}
62: C {series: v, x: 1565355017853, y: 45.926992636929334, options: {…}, isNull: false, …}
63: C {series: v, x: 1565355019811, y: 45.545298897828026, options: {…}, isNull: false, …}
64: C {series: v, x: 1565355021846, y: 41.76886760720148, options: ...

As you can see, series[0] is sorted correctly while series[1][60] has a higher timestamp than the following values.

@ppotaczek
Copy link
Contributor

Hi @LucidityDesign,

That issue is probably not related with highcharts-react-official wrapper. Could you reproduce it without the wrapper in some online code editor?

You can start from: http://jsfiddle.net/BlackLabel/z394cktd/

Best regards!

@LucidityDesign
Copy link

Hi,
thanks, I can reproduce it with setData: http://jsfiddle.net/obpuj0wy/

It seems like Highcharts is modifying my data array. If I pass a clone of the array ([...data]) it works as expected

@ppotaczek
Copy link
Contributor

Yes, Highcharts mutate source data array for performance. You can check this thread: highcharts/highcharts#4259 for more information.

@ppotaczek
Copy link
Contributor

The best way to add a new point is to call addPoint method directly on the chart. Our wrapper architecture does not provide for any other possibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants