Note: Unless otherwise specified, all line and source numbers refer to file highcharts.src.js obtained from http://code.highcharts.com/3/highcharts.src.js on May 13th, 2013.
Summary:
It seems that in this particular case of rendering histograms with IE8, Highcharts 3.0.1 and JQuery 1.7.1, there is a problem if you specify plotOptions.column.dataLabels.rotation to be truthy values ββ(something other than undefined or zero). As far as I can tell, this combination of factors makes someone (Highcharts, jQuery?) Try to animate the "align" property with unpleasant results. I tried to recreate this in Fiddle, but my simple case works. This is because IE9 does not use the problem code path, and jsFiddle does not work in IE8, so I can not check there.
Here's the fiddle anyway: http://jsfiddle.net/Wr9wX/6/
As a side note, these column charts with the same error come out using Highcharts v2.3.3. I originally wrote v2.3.3, I did not let it down, but subsequent testing showed that v2.3.3 also fails. My production page displays correctly if I comment on line 13950 in the highcharts.js file, thereby preventing it from trying to animate the align property.
Since then, I have managed to create a separate test page that reproduces the problem. The key is calling chart.setSize (width, height, wait). A failure is thrown if animate = true. Interestingly, the render is not interrupted if the built-in reflow logic handles resizing. Code follows:
<!DOCTYPE html"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <script type='text/javascript' src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script type='text/javascript' src="http://code.highcharts.com/highcharts.js"></script> </head> <body> <div class="highcharts-container" id="highcharts-2" style='z-index: 0; position: relative; text-align: left; line-height: normal; height: 100%;width: 100%; font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif; height: 100%; font-size: 12px; overflow: hidden;'> </div> <script type="text/javascript"> var chart; var render = function(id) { var foo; var chartSpec = { credits: false, chart: { animation: false, renderTo: id, type: 'column' }, xAxis: { categories: ['Jan'] }, plotOptions: { series: {animation:false}, column: { pointPadding: 0.2, borderWidth: 0, dataLabels: { rotation: -75, align: 'left', enabled: true } } }, series: [{ data: [29.9] }] }; foo = new Highcharts.Chart(chartSpec, function (chart) { chart.setSize(800, 600, true); </script> </body> </html>
Gory Details:
I access highcharts through jQuery v1.7.1, and I updated it from Highcharts v2.3.3 to v3.0.1. Our application worked fine in Highcharts v2.3.3, but not with Highcharts v3.0.1. In versions v3.0.1 and IE8 (browser mode: "IE8", document mode: "IE8 standards"), I get an "invalid argument" from the Highcharts extend () function:
function extend(a, b) { var n; if (!a) { a = {}; } for (n in b) { a[n] = b[n]; <------ fails here } return a; }
I get crashes in two conditions: one where n = one of ("top", "left") and one where n = "textAlign".
In the case of failure, where n is one of ("top", "left"), and then [n] = "<number> of points" (where <number> represents a valid squence of digital characters; for example, "100px") and b [n] = "NaNpx".
When n = "textAlign", then [n] = "and b [n] is the string whose value is the source code for the function with the string" NaN "added to it. The function that provided this source looks like align () starting at line 2720 in highcharts.src.js. The error message also differs in this case: "Failed to get the textAlign property. Invalid Argument "
I spent some time looking for this problem, of course, but all that taught me was that extend () may fail for various reasons, depending on the values ββof a, b, and n; not surprising.
Then I spent several hours paving the call stack up and down. I found that in the animate () function in the Highcharts adapter for jQuery, line 1408 runs as:
$el.animate(params, options);
which disappears in jQuery, appearing back in Highcharts in the init () method (line 1090) of the same adapter. In the code block starting with 1138:
return elem.attr ? // is SVG element wrapper elem.attr(fx.prop, fn === 'cur' ? UNDEFINED : fx.now) : // apply the SVG wrapper method base.apply(this, arguments); // use jQuery built-in method
Interestingly, although I draw four different types of chart (bar, column, pie, and scatter), only the column chart fails. All the column charts that I'm trying to crash, regardless of which of my datasets I draw.
Well, it does not work in animation (); turn off the animation for the chart. Still broken. Look at the call stack again: hmmm; still live through live. What for?
Research shows that rotating data labels is still related to animation (), even if the rendering of the chart is not animated on its own. Comment on the rotation in plotOptions.column.dataLabels and it works now.
Here is the refractory plot Options:
plotOptions: { series: {}, column: { pointPadding: 0.2, borderWidth: 0, dataLabels: { enabled: true, rotation: -75, align: 'left' } } }
It doesn't seem to matter what the value of the rotation is. If it has a "true" value, rendering is interrupted. If it is undefined, no problem.
So create a script. The script is displayed correctly; with or without rotation. Understand that I'm an idiot because I am running a script under IE9; quickly find that jsFiddle is not working in IE8. In any case, write a link to Fiddle (see Summary above).
Look at the stack again. I know that it fails when it goes to the conditional beginning of line 13952. What is the value of dataLabel? Hmmm ... dataLabel.textAlign is a string whose value is the source of the function. Where did it come from?
Unfortunately, I do not know. Everything still looks great when it disappears in jQuery in a call to $ el.animate () on line 1408. When it appears in win.HighchartsAdapeter.init on line 1093, I see that in the case where the requested function is '_default' , which sometimes fx.now (fx is bound to line 1128) is a function string instead of a number. Since fx is being passed from jQuery, I really don't know where it came from.
Since the function representing the string is represented in Highcharts, but fx comes from the jQuery animation logic, it seems likely that some Highcharts component has compressed this function and returned it to jQuery. It also seems reasonable to assume that this will happen in the adapter. I have no evidence of this, but it seems to be a good place to start looking.
I have already looked for definition errors around the 'align' symbol, but have not found anything. There are several business monkeys on line 4024 that look suspicious ... yes, I see that it is called using the key = 'align' and value = <stringified align () source> + 'NaN'.
The calling here is the attr () adapter implementation (line 4539). The hash and val arguments contain our (supposedly) bad string. These values ββwere passed from line 1139 to init (), which again brings us back to jQuery. Deja vu.
So, is this a jQuery bug? If so, why did he work with Highcharts v2.3.3?
I see that the anonymous function in init () implements the _default () method used by the jQuery animation step, but I still don't know why this member "now" has this strange meaning. It is also obvious that turns are treated as a special case when applied to point labels, and that special care is taken to avoid overwriting the SVG "align" property. jQuery 1.7+ also seems to be a separate case, and the _default () adapter is generated only for jQuery 1.7+.
Looking at the jQuery documentation for the animate () function, I suspect that the whole problem is that the system is trying to animate the "align" property in the first place. Animation of a non-numeric value does not make any sense to me, and the element looks incorrect, since the properties "end" and "now" have non-numeric values, and "start" is completely absent.
Apparently, "align" is animated, because it is in the collection "animatedProperties" of some object (not sure what it is), along with "x" and "y". The documentation for animate () seems to make it clear that animated properties should be numeric (seems perfectly reasonable to me). What happens if I leave the "rotation" property in my plotOptions.column.dataLabels setting but delete the "align"?
Still breaking.
I'm going to stop digging here and ask the Highchart people to take a look at this.