The goal of this question
To understand why I have to wrap a highcharts load event handler call with a $timeout, before I can have full access to all the data the highcharts object embedded in the event is meant to provide. As stated in the topic I am using angularjs and highcharts-ng.
I find it really weird that the load event manages to fire before all of the data that is supposed to be present in the object is present. Especially since I am not using addSeries
to populate the chart with data. I am manually constructing the entire config object. This approach is also what highcharts-ng prescribes.
I also find it hard to accept that I need to use a '$timeout' to deal with what seems to be a race condition. This is because I am from a C++ background, it might not be a race condition, but just one of the natural quirks of the nature of what is modern web development, javascript and Jquery. Of which I know very little.
If I can understand what is going on, I can move on with some confidence. If this issue is to do with our use of highcharts-ng
I could ditch that and wrap highcharts
myself. If there is a better way of solving my use-case (see below) that would be ok as well.
The behaviour I am seeing
I started working on solving my problem by printing out the highcharts object to the console, it showed all the fields when I expanded it. However, when I tried to begin working on my problem I started to see that some of the fields are actually undefined when I try to access them.
Ok so I discovered that this is because by the time I click expand in the console all values have been populated. But when I try to access them in my load handler they are undefined.
When I wrap my callback in angular's $timeout
the problem goes away. But why ? highcharts should not have triggered the load callback till it has done all it's calculations, in fact it cannot render the chart without calculating some of the undefined fields. So what gives ? Is some html5 web worker multithreading going on ? :D
Highcharts Animation... Is an animation causing the race like behaviour ?
I found some references on this issues where the prescribed solution was to hook in to animation complete method. The chart has animation disabled. But I suppose some jquery
animation could still be in use by highcharts
? I could try hooking into this handler if it would solve my problem and means I don't have to use a $timeout
.
The problem I am trying to solve.
I am working on a complex visualisation app and I need to dynamically rescale the Y-Axis so that 2 key plotlines on the Y axis are always present. Hard coding the extremes is not an option as it prevents the charts from scaling out based on the range of the data.
Highcharts
calculates various max and min values, I want to examine these, and if my plot lines do not fall within these max and min values I want to set new extremes and redraw the graph.
This question has some potential solutions to the problem. Sadly, the hacky answer seems the most robust and simplest --i.e., add a point on the plot line and hide it. I might go down this route to save time. Though I don't want to.
I'm the author of highcharts-ng.
I think the issue is that in highcharts-ng, it initializes the chart and then adds the series.
This could be fixed fairly easily. It would require a change to getMergedOptions: https://github.com/pablojim/highcharts-ng/blob/master/src/highcharts-ng.js#L245
At the moment getMergedOptions does not include the series objects and therefore when the chart is initialized it has no series. This behavior could be changed. There are some complications like ensuring that the series have ids. But it would be quite doable. I will get to doing it at some point, but pull requests gladly accepted in the meantime.
Another approach would be to dynamically set the x and y axis values on the highcharts-ng config object based on your data.