Accepted answer

I had spent a few weeks solving this problem, and it is tricky. It is a very simple matter to have lazy loading (see the "1.7 million points with async loading" demo at ) OR have new data points added, but both requires a bit of a hack.

First I'll detail the solution I ended up with. Do not set adaptToUpdatedData to false, simply leave it out. All the work you will do will require changes on the backend code that produces the data. Essentially, the data that is returned to Highstock will always be the full range of data that you have, however you will have a high resolution of data points for the window that is currently being viewed, but low resolution of data points for the range before and after this window. New data points are added to the end of the data as you would normally do (see the "dynamically updated data" demo at )

This ensures that when new data points are added, the navigator will also be updated. However, it also prevents you from having to load the full number of data points (since the before and after ranges only contain a low resolution of data points). You will need to write code that correctly averages your data into fewer data points before returning it to the highstocks chart.

In the setExtremes handler function (which gets called when the user scrolls the navigator), I have code that makes an AJAX request for new data to add to the Highstocks chart. I also have code that uses setInterval() to fetch new data points every 10 seconds. You need a variable that tracks when the setInterval() update is happening, because if it adds new data points to the chart, this will also end up calling the setExtremes handler function, which will then make yet another AJAX request. The AJAX request in your setExtremes handler should only run if a setInterval() update isn't happening. (It is easy to have some bug that causes an infinite loop of AJAX requests for data.)

You will also need a variable in the AJAX request for data so that the back end code knows if the request is from setInterval() or from your setExtremes handler (when the user scrolled the navigator), so that it knows if it should just return the data for the requested time range as is (for setInterval() request) or do the low/high resolution averaging for the full range of data (for setExtremes handler requests).

I don't think these variables completely erase the potential for race conditions.

The problems you described are correct: You can't set adaptToUpdatedData to false and add new data points because the navigator will not update. This prevents you from scrolling the navigator to the new points. But if you don't set it, when you request the new (and smaller) range of data, the navigator will update to fit this range. The navigator and the main chart will show the same range of data, making the navigator useless.

Sebastian's answer doesn't work, unfortunately. Updating series[0] won't affect the navigator because setting adaptToUpdatedData to false disables the navigator from redrawing itself.

This low/high resolution approach is a hack, but it is the only way I found that works (after going through a half-dozen or so other ways that didn't work.) It would be great if the Highstocks team could add this feature to their library.


I had this problem too, and after trying many solutions, I got one that really worked for me.

I used a global variable that contains the max value of xAxis and when I update the chart I verify if the new xAxis value is bigger then the maxX variable.

If it's true then I update the maxX with the new point and then I use the chart.xAxis.setExtremes (chart.xAxis.min, maxX); and after this I redraw the chart.

With these two things the chart will simulate the lazy loading with dynamic data, but another problem came through: the range selector and the navigator weren't updating. The solution was:


These two lines enable the range selector again and everything became ok.

Related Query

More Query from same tag