Highcharts在AngularJS选项卡中的动态(重新)大小 [英] Highcharts dynamic (re-)sizing in AngularJS tabs

查看:260
本文介绍了Highcharts在AngularJS选项卡中的动态(重新)大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序在各种选项卡中显示HighCharts图表(使用AngularJS)。请注意,每次选择标签页时都会重新生成图表(这意味着Angular每次都会移除或重新创建一部分DOM树)。

My application displays HighCharts charts in various tabs (using AngularJS). Note that the charts are re-generated on the fly every time a tab is selected (Meaning that Angular "removes or recreates a portion of the DOM tree" every time).

我的问题是图表的大小是正确的只有第一次我点击选项卡。当我切换选项卡时,创建的图表大大超过了其容器的大小。令人惊讶的是,在调整窗口大小后(即调用 chart.reflow()时),图表正确调整大小。

My problem is that the size of the chart is correct only the first time I click on a tab. When I switch tabs, the charts that are created largely exceed the size of their container. Surprisingly, the charts are correctly resized after a window resize (i.e. when chart.reflow() is called).

所以我试过下面这个没有帮助:

So I tried the following, which did not help:

$(element).highcharts({
    chart: {
      type: 'scatter',
      zoomType: 'xy',
      events: {
        load: function () {
          this.reflow();
        }
      }
    },
    ...

最后,下面的工作,但感觉像一个黑客。

Finally, the following did work, but it feels like a hack.

$(element).highcharts({
    chart: {
      type: 'scatter',
      zoomType: 'xy',
      events: {
        load: function () {
          var chart = this;
          setTimeout(function () { chart.reflow(); }, 0);
        }
      }
    },
    ...

任何想法问题来自哪里?我花了几个小时在这,这是非常令人沮丧...

Any idea where the problem comes from? I am spending hours on this, and this is pretty frustrating...

编辑:我有另一个相关问题:默认情况下,我的图表有一个给定的大小,但我有一个放大按钮,使他们占用整个空间。该按钮只是切换一个CSS类来做到这一点。但是,这样做会触发调整大小事件,因此不会触发回流。

I have another related question: By default my charts have a given size, but I have an "enlarge" button to make them take the full space. The button simply toggles a CSS class to do that. However, doing this does not trigger a resize event, and so does not trigger a reflow. So I have the same problem of charts not filling their container.

这里是一个小提示来演示这个问题:
http://jsfiddle.net/swaek268/3/

Here is a fiddle to demonstrate the issue: http://jsfiddle.net/swaek268/3/

同样,我找到了一种方法问题,但感觉更像一个更大的黑客。

Again, I have found a way around the problem, but it feels like an even bigger hack.

var width = 0;
var planreflow = function(){
  setTimeout(function(){
      if(width!==$('#container').width()){
          $('#container').highcharts().reflow(); 
          console.log('reflow!')
      }
      width = $('#container').width();
      planreflow();
  }, 10);
};
planreflow();


推荐答案

我认为我找到了两个问题的解决方案:

I think I found solutions to both of my problems:


  1. 图表加载完成时大小不正确

  1. Wrong size when chart finishes loading:

问题不是来自Highcharts,而是从图表创建的时间。我直接从$ Angular指令的 link()函数中调用 .highcharts() JS看起来基本上是这样的:

The problem does not come from Highcharts, but from the timing when the chart is created. I directly called .highcharts() from the link() function of my Angular directive. The JS looking essentially like this:

app.directive('dynamicView', function() {
  return {
    link: function(scope, element, attrs){
      $(element).highcharts({...});
    },    
  };
});

由于我的元素还有一个 ng-if 指令取决于选项卡是否被选中我想象,当该条件变为 true 时,角度调用 link()函数前的元素的维度确定(我猜,HTML已经准备好,以确定元素的大小)。所以我认为问题是,我在文档准备好之前调用 .highcharts()。由于某些原因,我仍然不明白,元素的大小是正确的第一次ng-如果变为真,但不正确的下一次。

As my element also has a ng-if directive depending on whether the tab is selected or not, I imagine that when that condition turns true, angular calls the link() function before the dimension of the element is determined (I guess the HTML has to be ready in order to determine the size of the elements). So I think the problem was that I was calling .highcharts() before the document was ready. For some reason that I still don't understand, the size of the element is correct the first time ng-if turns true, but incorrect the next times.

一个解决方案(仍然不是很优雅 - 但优于调用 reflow())是延迟调用 .highcharts()本身,以确保在创建图表时HTML已准备就绪:

Anyway, a solution (still not very elegant - but better than calling reflow()) is to delay the call to .highcharts() itself, to make sure that the HTML is ready when creating the charts:

link: function(scope, element, attrs){
  setTimeout(function () {
    $(element).highcharts({...});
  }, 0);
}

感谢您@pavel Fus < .highcharts() setTimeout()的行为。

Thank you @Pavel Fus for your comments on the behaviour of .highcharts() and setTimeout().


  1. 切换类别时图表不会调整大小

  1. Chart not resizing when toggling a class



<对于这个问题,我利用了Angular的事件系统。

For this problem I took advantage of Angular's eventing system.

在我的控制器控制全屏按钮:

In my controller controlling the full-screen button:

$scope.toggleFullScreen = function(e){
  $scope.$broadcast('fullscreen');
}

此事件沿层次结构向下传递,图表。所有我要做的,创建我的图表是听这个事件,并触发 reflow()相应地:

This event is passed down the hierarchy, ending-up to my directives containing the charts. All I have to do, when creating my charts is to listen to this event, and trigger a reflow() accordingly:

scope.$on('fullscreen', function(){
  setTimeout(function () { 
    $(element).highcharts().reflow(); 
  }, 0);
});

注意--again--只有当我用 setTimeout()。不确定为什么。

Note that --again-- the trick only works if I delay the reflow with setTimeout(). Not sure why.

我希望这有助于!花了相当多的时间在这... ...

I hope this helps! Spent quite a bit of time on this...

这篇关于Highcharts在AngularJS选项卡中的动态(重新)大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆