Explicit support for drill-down Ajax interactive data zooming
I have an extremely large dataset (once-a-second measurements extending over several years) that I'd like to be able to zoom in (and out) interactively with the Highstock navigator as well as direct selection with the mouse.
I think I have finally managed to piece together a somewhat stable solution by using the rather under-documented setExtremes event. However, some slight instabilities remain, mainly due to the fact that the setData method appears to itself trigger the setExtremes event sometimes. In addition, my dataset is discontiguous (has many gaps) and Highchart seems to like to shrink the limits of the selected data range to exclude gaps surrounding the data, which also ends up triggering setExtremes again.
So, since such interactive Ajax behavior seems to still be in the experimental phase, I'd like to cast my vote for it becoming an official feature.
Based on my experience working with the tool over the last couple days, I've arrived at the following approach which could work so much better if Highcharts somehow better supported this, probably through explicit events tailored to dynamically populating data interactively.
- My external server-side script has two distinct modes-
(a) give me all the data, averaged by hour. This gives me on the order of 10,000 points, which is very doable to work with to populate the navigator series and provide interactivity with a good range of zoom levels.
(b) give me a date range of data in full, down to the second. This I use for data ranges less than 24 hours long, This gives me no more than 86,400 points, which is doable especially because the user is expecting a delay (and I show the "loading" display).
My client-side Javascript, which uses Highstock, initially reads in all the data by hour and explicitly populates the navigator with it, as well as the main chart.
I hook into the setExtremes event of the xAxis, and if the selected date range is 24 hours or less, I retrieve just that data and use setData to apply it to the series of the main chart. If the selected date range is greater than 24 hours, I simply setData back to the original full series, which is still in memory and in use by the navigator.
The problems are mainly that the setExtremes event tends to get triggered multiple times per user interaction, particularly when the navigator is manipulated by the user. So, I have to put in an explicit test to make sure that the min and max passed directly in the event object are in fact different than the current min and max, which I obtain from the currentTarget property of the event object. If I don't test for it, an endless loop often occurs because it appears that in some cases the setData method can trigger a setExtremes event itself.
In addition, as I mentioned, the system seems to like to shrink the gaps between the data and the start of the date range, which can be disconcerting because, when zooming in on a particular "island" of data, it is useful to see the gaps so that you know you have all the data from that island in view, and that the edge didn't get chopped off.
So, I think one approach to this could be the creation of a "getData" event, which would be triggered whenever the display range of the chart is changed - after the system has completely settled on exactly what the new range will be, but before it has attempted to update the display. This event would be triggered regardless of the source of the display change, whether it is programmatic, or through user manipulation of the navigator or direct selection of a subrange on the chart by click and drag.
The event would be passed the exact date range (or more generally the xAxis range) that it intends to display. The user handler could choose to do nothing (the default), in which case the existing series data would be displayed. Or, the handler could fetch new data into one or more series' data range(s). The Highchart system would then, upon completion of the getData event, display exactly the xAxis data range it had passed to the getData event, possibly adjusting the yAxis to conform to the new data depending on settings related to yAxis behavior.
This event, in my vision of things, would not have the ability to change the xAxis range that is to be displayed, nor could the system "change its mind" and make adjustments to the range being displayed after the getData event is triggered. This is important because the user will then experience a stable environment in which what they select with the mouse is what they get, no matter what the data looks like, or what gaps are in it.
From my testing, no event exists that satisfies this criteria. The redraw event comes close, but it is not always consistently triggered, particularly when the Highstock navigator is used. The setExtremes event comes closer, but it exhibits the instabilities I have discussed, that I had to work around. setExtremes appears to be triggered too "early" in the process, so to speak.
If there is a way to accomplish exactly what I have proposed using existing features of Highchart/Highstock, please enlighten me. Otherwise, my feature request is respectfully submitted.
Thanks!
[note: I have at least one other request that is related but I will submit separately.]
-
Actually I have spent quite some time trying to accomplished exactly this, because I feel it is a common use case. But so far I haven't been able to prevent the setExtremes event from triggering. The goal is to make this happen with minimal coding.