注意:除非另有说明,否则所有行号和来源均指2013年5月13日从http://code.highcharts.com/3/highcharts.src.js获得的文件highcharts.src.js。
要点:
似乎在使用IE8,Highcharts 3.0.1和jQuery 1.7.1呈现柱形图的特定情况下,如果指定plotOptions.column.dataLabels.rotation为truthy值,则会出现问题除了未定义或零)。我能说的最好,这些因素的组合会导致某人(Highcharts,jQuery?)尝试动画"对齐"财产,带来不愉快的结果。我试图在小提琴中重新创建它,但我的简单案例有效。这似乎是因为IE9没有运行问题代码路径,并且jsFiddle不能在IE8下工作,所以我无法在那里进行测试。
无论如何,这里是小提琴:http://jsfiddle.net/Wr9wX/6/
作为旁注,这些柱形图与Highcharts v2.3.3失败并出现相同的错误。我最初编写的v2.3.3没有失败,但随后的测试显示v2.3.3也失败了。如果我在highcharts.js中注释掉第13950行,我的生产页面会正确呈现,从而阻止它尝试动画“对齐”#39;属性。
我已经能够创建一个可以重现问题的独立测试页面。关键是调用chart.setSize(width,height,animate)。如果animate = true,渲染将失败。有趣的是,如果内置的reflow逻辑正在处理resize,渲染不会失败。代码如下:
<!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); // <====== fails here
});
};
$(function () {
render('highcharts-2');
});
</script>
</body>
</html>
血腥细节:
我通过jQuery v1.7.1访问highcharts,我已经从Highcharts v2.3.3升级到v3.0.1。我们的应用程序在Highcharts v2.3.3下工作正常,但在Highcharts v3.0.1中失败了。在v3.0.1和IE8(浏览器模式:&#34; IE8&#34 ;;文档模式:&#34; IE8标准&#34;)下,我得到一个&#34;无效的参数&#34;来自Highcharts extend()函数:
/**
* Extend an object with the members of another
* @param {Object} a The object to be extended
* @param {Object} b The object to add to the first one
*/
function extend(a, b) {
var n;
if (!a) {
a = {};
}
for (n in b) {
a[n] = b[n]; <------ fails here
}
return a;
}
我在两种情况下失败:其中n =(&#39; top&#39;,&#39; left&#39;)之一,n =&#39; textAlign&#39;。
在n是(&#39; top&#39;,&#39; left&#39;)之一的失败情况下,则a [n] =&#34;&lt; number&gt; px&#34; (其中&lt; number&gt;表示数字字符的有效序列;例如,&#34; 100px&#34;),b [n] =&#34; NaNpx&#34;。
当n =&#34; textAlign&#34;时,则[n] =&#34;&#34;和b [n]是一个字符串,其值是具有字符串&#34; NaN&#34;的函数的源代码。附加到它。提供此源的函数似乎是从highcharts.src.js中第2720行开始的align()函数。在这种情况下,错误消息也不同:&#34;无法获取textAlign属性。参数无效&#34;
当然,我花了一些时间在这个问题上进行搜索,但所有教会我的是,extend()可能由于各种原因而失败,具体取决于a,b和n的值;这并不奇怪。
然后我花了几个小时在调用堆栈中上下调查。我发现,在用于jQuery的Highcharts适配器的animate()函数中,第1408行执行为:
$el.animate(params, options);
消失在jQuery中,在同一个适配器的init()方法(第1090行)中重新出现在Highcharts中。在从1138开始的代码块中:
return elem.attr ? // is SVG element wrapper
elem.attr(fx.prop, fn === 'cur' ? UNDEFINED : fx.now) : // apply the SVG wrapper's method
base.apply(this, arguments); // use jQuery's built-in method
有趣的是,虽然我渲染了四种不同类型的图表(条形图,柱形图,饼图和散点图),但只有柱形图失败。无论我正在绘制哪些数据集,我尝试渲染的所有柱形图都会失败。
好吧,它在animate()中失败了;为图表关闭动画。仍然破碎。再看一下调用栈:嗯;仍然通过动画进入。为什么?
调查表明,旋转数据标签仍然涉及animate(),即使图表渲染本身没有动画。在plotOptions.column.dataLabels中注释掉旋转属性,现在它可以工作。
以下是打破plotOptions:
plotOptions: {
series: {},
column: {
pointPadding: 0.2,
borderWidth: 0,
dataLabels: {
enabled: true,
rotation: -75,
align: 'left'
}
}
}
旋转的价值似乎并不重要。如果它有一个&#34; truthy&#34;值,渲染中断。如果未定义,则没有问题。
所以,创造一个小提琴。小提琴渲染正确;有或没有旋转。意识到我是一个白痴,因为我在IE9下运行小提琴;很快发现jsFiddle在IE8下无法运行。无论如何发布到Fiddle的链接(参见上面的摘要)。
再看一下堆栈。我知道当它从第13952行开始进入条件时它会失败.DataLabel的值是多少?嗯...... dataLabel.textAlign是一个字符串,其值是函数的来源。来自哪里?
不幸的是,我不知道。当它在第1408行的$ el.animate()调用中消失到jQuery时,一切看起来仍然很好。当它在第1093行的win.HighchartsAdapeter.init中弹出时,我可以看到,在所请求的函数是&#39; _default&#39;有时fx.now(fx在第1128行绑定)是这个函数字符串而不是数字。由于fx是从jQuery传入的,所以我真的不知道它来自哪里。
由于字符串表示的函数似乎在Highcharts中,但fx来自jQuery动画逻辑,因此Highcharts的某些组件似乎可以将该函数字符串化并将其返回给jQuery。假设在适配器中发生这种情况似乎也是合理的。我没有这方面的证据,但它似乎是一个开始寻找的好地方。
我已经考虑过使用&#39;对齐&#39;符号,但没有找到任何东西。在第4024行有一些看起来很可疑的猴子商业......是的,我可以看到它被调用了密钥=&#39; align&#39;和value =&lt; stringified align()source&gt; +&#39; NaN&#39;。
这里的调用者是适配器的attr()实现(第4539行)。 hash和val参数都包含我们的(可能是)坏字符串。这些值是从init()中的第1139行传入的,这导致我们再次回到jQuery。似曾相识。
那么,它是一个jQuery错误?如果是这样,为什么它与Highcharts v2.3.3一起使用?
我可以看到init()中的匿名函数实现了jQuery动画步骤所采用的_default()方法,但我仍然不知道为什么步骤现在&#39; ;会员有这个奇怪的价值。同样明显的是,当应用于点标签时,旋转作为特殊情况处理,并且特别注意避免覆盖SVG&#39;对齐&#39;属性。 jQuery 1.7+似乎也是一个独特的案例,_default()适配器仅为jQuery 1.7+生成。
在查看animate()函数的jQuery文档之后,我怀疑整个问题是系统正在尝试动画&#34;对齐&#34;物业在第一位。动画非数字值对我来说没有任何意义,并且该元素似乎是格式错误的,因为“结束”这个元素的结果是错误的。和&#39;现在&#39;属性具有非数字值,并且&#39; start&#39;完全没有了。
显然,&#39;对齐&#39;正在动画,因为它是在动画属性&#39;收集一些物品(不确定它是什么),以及&#39; x&#39;和&#39;。 animate()的文档似乎清楚地表明动画属性必须是数字(对我来说似乎完全合理)。如果我离开&#39;旋转&#39;我的plotOptions.column.dataLabels设置中的属性,但删除&#39;对齐&#39;?
仍然休息。
我要停止在这里挖掘并要求Highchart人员看看这个。
答案 0 :(得分:0)
到目前为止,我发现将无效参数传递给VMLRenderer.attr方法。将此日志添加到函数定义的顶部以查看:
attr:function(hash,val){if(hash =='align'){console.log('@ attr'+ val); }
这个方法可能是从动画逻辑调用的。
解决方案是:
// Don't run animations on textual properties like align (#1821)
if (fx.prop === 'align') {
return;
}
<强>参考强>