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

Updating Live Data on LineChart #52

Closed
mattspeller opened this issue Dec 11, 2017 · 10 comments
Closed

Updating Live Data on LineChart #52

mattspeller opened this issue Dec 11, 2017 · 10 comments

Comments

@mattspeller
Copy link

Hey buddy, thanks for all the awesome work with this project.

Please see the sandbox linked here - CodeSandbox.io

I am trying to update data to show a series of updated points on a chart. The similar code works on a pure HighChart js control, however I think something funky is happening under the covers when setting the state,

Basically setting new state for the line chart does not update the line chart drawn.

this.setState({ data: this.state.data });

I have also had to initialise the array to have n empty array points at the beginning of the control to correctly show the correct range on the chart before the points start ticking in.

    while (idx < buffersize) {
      data.push([]);
      idx++;
    }

Also can you shed some light on how best to get the Series instance from the controls rendered? Surely there is a better way than traversing a reference like I have shown below:

<HighchartsChart ref={ref => this.chart = ref}>

    if (this.chart) {
      let chart = this.chart.context.Highcharts.charts[0];
      if (chart) {
        chart.series[0].addPoint(this.state.data[this.state.data.length - 1], true, true);
      }
    }

I would like to see the similar output to available on the Live Data demo on the Highcharts website - Dynamic Updates

thanks in advance - I am pretty sure I must be over thinking the solution here.

M@

@whawker
Copy link
Owner

whawker commented Dec 11, 2017

Hi @mattspeller, the problem here is how array props should be updated when using React.

React performs a comparison of the props when deciding whether to re-render. if you push to an array, without cloning it, React considers them equal as they have the same memory reference. Therefore you must clone the array and then push changes to the clone, then you'll see the changes you expect (FYI this is also the reason Immutable.js exists).

So my advice would be to clone the data array, as I demonstrate here, or use Immutable.js List structures for you data prop instead

@mattspeller
Copy link
Author

makes perfect sense - thanks for finding time to respond.

@timogasda
Copy link

Sorry to comment on a closed issue, but I have a follow-up question for this.

To me it looks like because we need to clone the data array each time we add a new data point, the graph is completely redrawn and rerendered every time. Is that correct? That seems terribly inefficient and also appears to be the reason why I cannot get the animation to work like in the previously mentioned example here. (although, that might just be an error on my part)

@whawker
Copy link
Owner

whawker commented Jan 4, 2018

Hi @TwoLaid, the entire graph shouldn't be redrawn but the single series (related to the data array) will be re-plotted.

I did investigate comparing the nextProp data length, if it is one greater than the prevProp length, we could use the addDataPoint Highcharts method, which would be slightly more efficient than setData. But I figure that might be too naïve for more complex use cases.

@sorenhoyer
Copy link

Why was this issue closed? This seems to be a real problem.

@whawker
Copy link
Owner

whawker commented Feb 15, 2018

Are you referring to the original issue, or the question @TwoLaid raised afterwards?

@sorenhoyer
Copy link

I just find it very inefficient having to .slice() the array we send setData. Imagine it had 10000+ objects in it, which would update every 1 second or so. An application with multiple live data charts needs every single drop of cpu optimization possible, and at least for us MobX users it would be quite a performance improvement if we could stay mutable - without being forced to give that up, by having to copy the array for react to pickup the changes. I'd much rather if we could just call addPoint on the chart directly and pass just the newly added point. :)

@JPNZ4
Copy link

JPNZ4 commented Oct 10, 2018

Hey @whawker, I've been having some performance issues with my charts and have just read through this thread. I'm getting data really quickly (Up to 50hz) and would like to plot it in some charts. Currently I'm wanting to display it at 10hz but the scripting takes too long and the chart freezes.

With one series plotted I can run 10hz for a few minutes before it freezes and with 5 series it only takes seconds before freezing. In chrome debugger I can see the time for setData() increases the longer the incoming data has been running and I believe this is where the bottleneck is.

I have tried changing setData to use addPoint() and shifting older data out, but this has had little effect.

Do you have any recommendations for displaying data at 10hz or quicker?

@whawker
Copy link
Owner

whawker commented Oct 10, 2018

Hi @JPNZ4, how many data points are displayed at once? Have you considered using the Highcharts boost module?

@JPNZ4
Copy link

JPNZ4 commented Oct 10, 2018

I'm using boost module and displaying around 1500 data points at once. The rendering is pretty quick with the boost module and taking up minimal time in chrome debugger.

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

No branches or pull requests

5 participants