AngularJS选项卡中的Highcharts动态(重新)大小调整
我的应用程序在各种选项卡中显示HighCharts图表(使用AngularJS)。 请注意, 每次选择选项卡时都会动态重新生成图表(意味着每次 Angular“删除或重新创建DOM树的一部分”)。
我的问题是, 只有在我第一次点击选项卡时 ,图表的大小才是正确的 。 当我切换标签时,创建的图表大大超过了其容器的大小。 令人惊讶的是,在调整窗口大小(即调用chart.reflow()
时chart.reflow()
后,图表会正确resize。
所以我尝试了以下,但没有帮助:
$(element).highcharts({ chart: { type: 'scatter', zoomType: 'xy', events: { load: function () { this.reflow(); } } }, ...
最后,以下确实有效,但感觉就像是黑客。
$(element).highcharts({ chart: { type: 'scatter', zoomType: 'xy', events: { load: function () { var chart = this; setTimeout(function () { chart.reflow(); }, 0); } } }, ...
知道问题的来源吗? 我花了好几个小时,这非常令人沮丧……
编辑:我有另一个相关的问题:默认情况下,我的图表有一个给定的大小,但我有一个“放大”按钮,使他们占据整个空间。 该按钮只是切换一个CSS类来做到这一点。 但是,这样做不会触发resize事件,因此不会触发重排。 所以我有同样的问题,图表没有填充他们的容器。
这是一个演示问题的小提琴: http : //jsfiddle.net/swaek268/3/
我再次找到解决问题的方法,但感觉就像是一个更大的黑客。
var width = 0; var planreflow = function(){ setTimeout(function(){ if(width!==$('#container').width()){ $('#container').highcharts().reflow(); console.log('reflow!') } width = $('#container').width(); planreflow(); }, 10); }; planreflow();
我想我找到了解决我的两个问题的方法:
- 图表加载完成后尺寸错误:
问题不是来自Highcharts,而是来自创建图表的时间。 我直接从我的Angular指令的link()
函数调用.highcharts()
。 JS看起来基本上是这样的:
app.directive('dynamicView', function() { return { link: function(scope, element, attrs){ $(element).highcharts({...}); }, }; });
由于我的元素也有一个ng-if
指令取决于是否选中了tab,我想当该条件变为true
,angular会在确定元素的维度之前调用link()
函数(我猜HTML有准备好以确定元素的大小)。 所以我认为问题是我在文档准备好之前调用了.highcharts()
。 由于某种原因,我仍然不明白,元素的大小是正确的,第一次ng-if变为true,但下次不正确。
无论如何,一个解决方案(仍然不是很优雅 – 但比调用reflow()
更好)是延迟调用.highcharts()
本身,以确保在创建图表时HTML已准备就绪:
link: function(scope, element, attrs){ setTimeout(function () { $(element).highcharts({...}); }, 0); }
感谢@Pavel Fus对.highcharts()
和setTimeout()
行为的评论。
- 切换类时图表不会resize
对于这个问题,我利用了Angular的事件系统。
在我的控制器中控制全屏按钮:
$scope.toggleFullScreen = function(e){ $scope.$broadcast('fullscreen'); }
此事件在层次结构中传递,最终到我的包含图表的指令。 在创建图表时,我只需要监听此事件,并相应地触发reflow()
:
scope.$on('fullscreen', function(){ setTimeout(function () { $(element).highcharts().reflow(); }, 0); });
注意–again–这个技巧只有在我用setTimeout()
延迟重排时才有效。 不知道为什么。
我希望这有帮助! 在这上花了不少时间……
所以,实际上你有两个问题:
1)第二次点击时尺寸不正确。 这很可能是由隐藏( display: none
)容器的宽度和高度错误引起的。 在这种情况下,浏览器会报告不正确的宽度/高度(如0px
)。 同样的问题在这里和这里 。
2)设置容器的类不会触发图表的resize
(或更确切地说是reflow
)事件。 这意味着您需要自己调用chart.reflow()
。 我建议你在改变class级时在同一个地方做这件事。