highcharts - Highcharts v3.0.1在IE8和jQuery v1.7.1中旋转数据标签的问题

标签 highcharts

注意:除非另有说明,否则所有行号和源均引用文件highcharts.src.js,该文件是从2013年5月13日从http://code.highcharts.com/3/highcharts.src.js获得的。



摘要:

似乎在使用IE8,Highcharts 3.0.1和jQuery 1.7.1绘制柱形图的特定情况下,如果将plotOptions.column.dataLabels.rotation指定为真实值(不是未定义的值),就会出现问题。或零)。尽我所知,这种因素的组合使某人(Highcharts,jQuery?)无意对“ align”属性进行动画处理,结果令人不快。我试图在小提琴中重新创建它,但是我的简单案例仍然有效。这似乎是因为IE9不会执行问题代码路径,并且jsFiddle在IE8下无法正常工作,所以我无法在那里进行测试。

无论如何,这是小提琴:http://jsfiddle.net/Wr9wX/6/

附带说明一下,这些柱形图在Highcharts v2.3.3中失败,并出现相同的错误。我最初编写的v2.3.3并没有失败,但是随后的测试表明v2.3.3也失败了。如果我在highcharts.js中注释掉第13950行,则我的生产页面可以正确呈现,从而防止它尝试为'align'属性设置动画。

从那以后,我就能够创建一个独立的测试页面来重现该问题。关键是对chart.setSize(width,height,animate)的调用。如果animate = true,则渲染将失败。有趣的是,如果内置的重排逻辑正在处理调整大小,则渲染不会失败。代码如下:

<!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(浏览器模式:“ IE8”;文档模式:“ IE8标准”)下,我从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 =('top','left')之一,另一种情况是n ='textAlign'。

在n为('top','left')之一的失败情况下,则a [n] =“ px”(其中代表数字字符的有效序列;例如,“ 100px”) ,并且b [n] =“ NaNpx”。

当n =“ textAlign”时,则a [n] =“”,b [n]是一个字符串,其值是函数的源代码,并附加了字符串“ NaN”。提供此源代码的函数似乎是align()函数,从highcharts.src.js中的第2720行开始。在这种情况下,错误消息也将有所不同:“无法获取textAlign属性。无效的参数”

当然,我花了一些时间在这个问题上进行搜索,但是教会我的是,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()中失败;为图表关闭动画。还是坏了。再看一下调用堆栈:hmmm;仍然通过动画进入。为什么?

调查表明,旋转数据标签本身仍然涉及animate(),即使图表渲染本身没有动画。注释掉plotOptions.column.dataLabels中的旋转属性,现在可以使用了。

这是令人震惊的plotOptions:

    plotOptions: {
      series: {},
      column: {
        pointPadding: 0.2,
        borderWidth: 0,
        dataLabels: {
          enabled: true,
          rotation: -75,
          align: 'left'            
        }
      }
    }


轮换的值似乎无关紧要。如果它具有“真实”值,则渲染会中断。如果未定义,则没有问题。

因此,创建一个小提琴。小提琴正确渲染;旋转或不旋转。意识到我是个白痴,因为我正在IE9下运行小提琴;很快发现jsFiddle在IE8下不起作用。无论如何都将链接发布到Fiddle(请参见上面的摘要)。

再次查看堆栈。我知道它在从13952行开始进入条件时会失败。dataLabel的值是什么?嗯... dataLabel.textAlign是一个字符串,其值是函数的来源。那是哪里来的

不幸的是,我不知道。当它在第1408行的$ el.animate()调用中消失到jQuery中时,一切仍然看起来很好。当在第1093行的win.HighchartsAdapeter.init中弹出它时,在请求的函数为“ _default”有时是fx.now(fx绑定在第1128行)是此函数字符串而不是数字。由于fx是从jQuery传递过来的,所以我真的不知道它来自哪里。

由于字符串表示的函数似乎在Highcharts中,但是fx来自jQuery动画逻辑,因此Highcharts的某些组件似乎将函数字符串化并返回给jQuery。假设这会在适配器中发生似乎也是合理的。我没有任何证据,但这似乎是一个开始寻找的好地方。

我已经在寻找有关使用“ align”符号的范围界定错误,但还没有发现任何东西。在第4024行上发生了一些猴子事务,看起来很可疑...是的,我可以看到它被用key ='align'和value = +'NaN'调用。

这里的调用者是适配器的attr()实现(第4539行)。 hash和val参数都包含我们的(大概是)错误的字符串。这些值是从init()的1139行传入的,这又使我们回到了jQuery。似曾相识

因此,这是一个jQuery错误?如果是这样,为什么它可以与Highcharts v2.3.3一起使用?

我可以看到init()中的匿名函数实现了jQuery动画步骤所使用的_default()方法,但是我仍然不知道为什么该步骤的“现在”成员具有这个奇怪的值。同样很明显,将旋转应用于点标签时,将旋转作为特殊情况处理,并且要格外小心,以免覆盖SVG的“ align”属性。 jQuery 1.7+似乎也是一种特殊情况,并且_default()适配器仅针对jQuery 1.7+生成。

在查看animate()函数的jQuery文档之后,我怀疑整个问题是系统首先尝试对“ align”属性进行动画处理。对非数字值进行动画处理对我来说是没有意义的,并且该元素似乎格式错误,因为'end'和'now'属性具有非数字值,并且'start'完全缺失。

显然,“ align”是动画的,因为它与某个对象(“ x”和“ y”)一起存在于某个对象的“ animatedProperties”集合中(不确定它是什么)。 animate()的文档似乎清楚地表明,动画属性必须是数字的(对我来说似乎完全合理)。如果在我的plotOptions.column.dataLabels设置中保留“ rotation”属性,但删除“ align”会怎样?

仍然休息。

我将在这里停止挖掘,并请Highchart的人员对此进行研究。

最佳答案

到目前为止,我发现无效的参数已传递给VMLRenderer.attr方法。将此日志添加到函数定义的顶部以查看:
attr:函数(hash,val){if(hash =='align'){console.log('@ attr'+ val); }
此方法可能是从动画逻辑调用的。

解决方案是:

// Don't run animations on textual properties like align (#1821)
if (fx.prop === 'align') {
  return;
}

参考资料

Fixed issue with JS errors in IE8 when trying to animate a rotated data label

关于highcharts - Highcharts v3.0.1在IE8和jQuery v1.7.1中旋转数据标签的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16370879/

相关文章:

css - 无法将 Highcharts 发送到页面背面(z-index)

javascript - 如何将模板变量传递给javascript

jquery - Highcharts 不工作

javascript - Highstock highcharts 不规则数据在 x 尺度上出错

javascript - 删除下钻标签的下划线

javascript - Highcharts 中两条线交叉时绘制垂直线

javascript - 如何为数组的数组制作 Javascript 输出括号。 (对于 Highcharts)

highcharts - 向 Highcharts 图表添加日期范围过滤器

javascript - Highcharts:在工具提示中格式化系列名称

colors - Highcharts 面积图,在 X 轴上方/下方使用 2 种填充颜色