在AngularJS选项卡中动态(重新)调整大小
Highcharts dynamic (re-)sizing in AngularJS tabs
我的应用程序在不同的选项卡中显示HighCharts图表(使用AngularJS)。请注意,每次选择选项卡时,图表都会在动态中重新生成(这意味着Angular每次都会"删除或重新创建DOM树的一部分")。
我的问题是,图表的大小是正确的只有第一次我点击一个标签。当我切换选项卡时,创建的图表很大程度上超过了其容器的大小。令人惊讶的是,图表在窗口大小调整后正确地调整了大小(即当chart.reflow()
被调用时)。
所以我尝试了以下方法,但没有帮助:
$(element).highcharts({
chart: {
type: 'scatter',
zoomType: 'xy',
events: {
load: function () {
this.reflow();
}
}
},
...
最后,下面的代码可以工作了,但是感觉像是一个hack。
$(element).highcharts({
chart: {
type: 'scatter',
zoomType: 'xy',
events: {
load: function () {
var chart = this;
setTimeout(function () { chart.reflow(); }, 0);
}
}
},
...
你知道问题出在哪里吗?我花了几个小时在这上面,这真是令人沮丧……
编辑:我有另一个相关的问题:默认情况下,我的图表有一个给定的大小,但我有一个"放大"按钮,使他们占据整个空间。按钮只是切换一个CSS类来实现这一点。然而,这样做不会触发调整大小事件,因此不会触发流。所以我也有同样的问题,图表没有填满它们的容器。
下面是一个小提琴来演示这个问题:http://jsfiddle.net/swaek268/3/
我又找到了一个解决问题的方法,但感觉像是一个更大的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();
我想我找到了两个问题的解决方案:
- 图表加载完成时尺寸错误:
问题不是来自Highcharts,而是来自图表创建的时间。我直接从Angular指令的link()
函数中调用了.highcharts()
。JS看起来像这样:
app.directive('dynamicView', function() {
return {
link: function(scope, element, attrs){
$(element).highcharts({...});
},
};
});
由于我的元素也有一个ng-if
指令取决于选项卡是否被选中,我想当该条件变为true
时,angular在确定元素的尺寸之前调用link()
函数(我猜HTML必须准备好以确定元素的大小)。所以我认为问题是我在文件准备好之前调用了.highcharts()
。由于某些我仍然不明白的原因,元素的大小在ng-if第一次变为true时是正确的,但在下一次变为true时就不正确了。
无论如何,一个解决方案(仍然不是很优雅-但比调用reflow()
更好)是延迟调用.highcharts()
本身,以确保HTML在创建图表时准备好:
link: function(scope, element, attrs){
setTimeout(function () {
$(element).highcharts({...});
}, 0);
}
谢谢你@Pavel Fus对.highcharts()
和setTimeout()
行为的评论。
- 切换类时图表不调整大小
对于这个问题,我利用了Angular的事件处理系统。
在我的控制器中控制全屏按钮:
$scope.toggleFullScreen = function(e){
$scope.$broadcast('fullscreen');
}
该事件向下传递到包含图表的指令。在创建图表时,我所要做的就是听这个事件,并相应地触发reflow()
:
scope.$on('fullscreen', function(){
setTimeout(function () {
$(element).highcharts().reflow();
}, 0);
});
注意——再次——这个技巧只有在我用setTimeout()
延迟回流时才有效。不知道为什么。
我希望这对你有帮助!
实际上你有两个问题:
1)第二次点击时尺寸不正确。这很可能是由于隐藏(display: none
)容器的宽度和高度错误造成的。在这种情况下,浏览器报告不正确的宽度/高度(如0px
)。这里和这里都是同样的问题。
2)为容器设置类不会为图表触发resize
(或者更确切地说是reflow
)事件。这意味着您需要自己调用chart.reflow()
。
- 合并两个数组,重新调整循环js
- 可以在调整窗口大小时重新调整stellar.js的元素偏移量
- 销毁窗口.重新调整事件订阅服务器的大小
- 如何在方向更改时重新调整/排列布局(Apache Cordova)
- 当行增加时自动递增序列号,并在 jQuery 中删除行时自动重新调整编号顺序
- 将 jsViews/jsRender 与重新调整为字典条目的属性一起使用
- 重新调整网页内容的大小
- 如何防止iframe在缩放时重新调整大小
- CSS Flex-当重新调整包装器Flex项的大小时,更改其宽度尺寸
- 预加载图像,使其不会't在加载过程中重新调整大小
- 由于图像大小不同,带有rslide的滑块会重新调整自身大小
- 如何防止导航栏中的元素在重新调整大小时被切断
- 拖放后,如果不重新调整大小并在可放置区域中拖动图像
- 如果我在循环中运行 Gulp,我应该重新调整什么
- 设置 style.display= none 后优雅的 javascript 重新调整
- 在 PHP 中重新调整字符串
- 动态重新调整n个图像的行大小,使所有5行的高度一致
- 固定Div内的Fluid Image未重新调整大小
- 在GET之前重新调整发送OPTIONS方法的角度
- javascript窗口.页面加载时重新调整大小