Html 使用 highcharts 时,为什么 Bootstrap 选项卡会显示宽度不正确的选项卡窗格 div?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17206631/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why are Bootstrap tabs displaying tab-pane divs with incorrect widths when using highcharts?
提问by VirtualValentin
So I'm creating a page with tabbed content using Twitter's Bootstrap, yet the content of my starting active div is always different than that of my other tabs. For example, I am putting in charts using highcharts.js in my different tabs, yet the active one always shows correctly while the others have an incorrect width.
所以我正在使用 Twitter 的 Bootstrap 创建一个带有标签内容的页面,但我的起始活动 div 的内容总是与其他标签的内容不同。例如,我在不同的选项卡中使用 highcharts.js 放入图表,但活动的总是显示正确,而其他的宽度不正确。
Check out the example below:
看看下面的例子:
<div class = "row-fluid">
<div class = "span9">
<div class = "row-fluid">
<h3>Test</h3>
<ul class="nav nav-tabs">
<li class = "active">
<a data-toggle = "tab" href = "#one">One</a>
</li>
<li><a data-toggle = "tab" href = "#two">Two</a></li>
<li><a data-toggle = "tab" href = "#three">Three</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="one" >
<h4>One</h4>
<div id = "container1"></div>
<script type = "text/javascript">
$(function () {
$('#container1').highcharts({
chart: {
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
});
</script>
</div>
<div class="tab-pane" id="two" >
<h4>Two</h4>
<div id = "container2"></div>
<script type = "text/javascript">
$(function () {
$('#container2').highcharts({
chart: {
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
});
</script>
</div>
<div class="tab-pane" id="three" >
<h4>Three</h4>
<div id = "container3"></div>
<script type = "text/javascript">
$(function () {
$('#container3').highcharts({
chart: {
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
});
</script>
</div>
</div>
</div>
</div>
<div class = "span3">
<p>Here is the content on my sidebar</p>
</div>
</div>
In this case, switching the active tab on page load makes that chart look correct for me, but the rest always extend all the way to the edge (In the case of my data, which I want to only fill up the space of the span9 div. I just used dummy charts in this case, but it's the same idea.
在这种情况下,在页面加载时切换活动选项卡使该图表看起来对我来说是正确的,但其余的总是一直延伸到边缘(在我的数据的情况下,我只想填充 span9 的空间div. 在这种情况下我只是使用了虚拟图表,但它的想法是一样的。
Here's a JSFiddle: http://jsfiddle.net/dw9tn/
这是一个 JSFiddle:http: //jsfiddle.net/dw9tn/
My questions for you all are:
我想问大家的问题是:
1.) Is this just me?
1.) 这只是我吗?
2.) What exactly is going on when tabs are made active? Looking at the bootstrap css, this seems to deal with display: none and display: block, but I don't have a good understanding of how that works in this case.
2.) 当标签被激活时到底发生了什么?查看引导 css,这似乎处理 display: none 和 display: block,但我不太了解在这种情况下它是如何工作的。
3.) Is this a highcharts issue or a bootstrap issue? I noticed this happened to me with non-highchart elements (like showing tweets in the sidebar), so I'm leaning toward bootstrap.
3.) 这是 highcharts 问题还是 bootstrap 问题?我注意到这发生在我身上的非高图元素(比如在侧边栏中显示推文),所以我倾向于引导程序。
4.) Is there any solution you can find to make everything consistent?
4.) 有没有什么解决方案可以让一切都保持一致?
Thanks guys!
谢谢你们!
回答by ryenus
The Cause
原因
This is not a Highcharts issue, at least not by itself, the problem is caused by the fact that Bootstrap uses display: none
to hide inactive tabs:
这不是 Highcharts 问题,至少不是其本身,问题是由 Bootstrapdisplay: none
用来隐藏非活动选项卡的事实引起的:
.tab-content > .tab-pane, .pill-content > .pill-pane {
display: none; /* this is the problem */
}
This causes Highcharts not able to get the expected width to initialize the chart, thus defaults to 600px
. This would happen to other tools using the same approach to hide content.
这会导致 Highcharts 无法获得预期的宽度来初始化图表,因此默认为600px
。使用相同方法隐藏内容的其他工具也会发生这种情况。
A Pure CSS Solution
纯 CSS 解决方案
Instead of working around the issue with an extra redraw or delayed initialization, we can achieve the hidden effect using height: 0; overflow-y: hidden
, this way the hidden tab panes are still in place and having valid width
:
我们可以使用 来实现隐藏效果height: 0; overflow-y: hidden
,而不是通过额外的重绘或延迟初始化来解决问题,这样隐藏的选项卡窗格仍然存在并且具有有效的width
:
/* bootstrap hack: fix content width inside hidden tabs */
.tab-content > .tab-pane:not(.active),
.pill-content > .pill-pane:not(.active) {
display: block;
height: 0;
overflow-y: hidden;
}
/* bootstrap hack end */
Update: We now target inactive tabs directly, via :not(.active)
, to avoid possible side effect if any.
更新:我们现在通过 直接定位非活动选项卡:not(.active)
,以避免可能的副作用(如果有的话)。
This solution is seamless, so you no longer have to worry whether the chart is inside a tab-pane or not. And it's efficient as it fixes the width issue in the first place, thus there's no need to workaround the width issue afterward via resize/redraw/reflow using javascript.
此解决方案是无缝的,因此您不再需要担心图表是否在选项卡窗格内。它是高效的,因为它首先解决了宽度问题,因此之后无需通过使用 javascript 调整大小/重绘/回流来解决宽度问题。
Note about cascading order
关于级联顺序的注意事项
This patch needs to be loaded after bootstrapcss, because of CSS cascading order rules, in short, the latter rule wins.
这个补丁需要在bootstrapcss之后加载,因为CSS级联顺序规则,总之,后一条规则胜出。
Demo
演示
Tip: switch to the Profiletab to see the difference.
提示:切换到配置文件选项卡以查看差异。
回答by Pawe? Fus
The problem is that Highcharts can not calculate width of the container which has CSS: display:none
, so applied is default width (600px). In fact, browser is not able to calculate width for such elements.
问题是 Highcharts 无法计算具有 CSS: 的容器的宽度display:none
,因此应用的是默认宽度(600px)。事实上,浏览器无法计算此类元素的宽度。
For example when you will use separator to resize Result window, chart will resize and will work. So you have three options:
例如,当您使用分隔符调整结果窗口的大小时,图表将调整大小并起作用。所以你有三个选择:
- render chart after first click on that tab
- render chart at the beginning, but after each click and window resize use
chart.setSize(w,h)
with new width and height - render chart at the beginning, but after tab click call
chart.reflow()
- 第一次单击该选项卡后呈现图表
- 在开始时渲染图表,但在每次单击和窗口调整大小后使用
chart.setSize(w,h)
新的宽度和高度 - 在开始时渲染图表,但在选项卡单击调用后
chart.reflow()
回答by oaamados
Based on the Pawel's answer I render the chart at beginning and then resize the chart.
根据 Pawel 的回答,我在开始时渲染图表,然后调整图表大小。
The code used (with bootstrap 3.0.3 and HighCharts 3.0.7)
使用的代码(使用 bootstrap 3.0.3 和 HighCharts 3.0.7)
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
$('#container').highcharts().setSize($('#container').width(),$('#container').height());
})
回答by metaColin
Based on Pawe?'s answer I've made a working example:
基于 Pawe? 的回答,我做了一个工作示例:
http://codepen.io/colinsteinmann/pen/BlGfE
http://codepen.io/colinsteinmann/pen/BlGfE
Basically the .reflow() function is called on each chart when a tab is clicked. That way the chart gets redrawn based on the new dimensions which are applied to the container when it becomes visible.
单击选项卡时,基本上会在每个图表上调用 .reflow() 函数。这样,图表会根据在容器可见时应用于容器的新维度重新绘制。
This is the most important snippet of code:
这是最重要的代码片段:
// fix dimensions of chart that was in a hidden element
jQuery(document).on( 'shown.bs.tab', 'a[data-toggle="tab"]', function (e) { // on tab selection event
jQuery( ".contains-chart" ).each(function() { // target each element with the .contains-chart class
var chart = jQuery(this).highcharts(); // target the chart itself
chart.reflow() // reflow that chart
});
})
回答by Joel Luevano
I found an easier solution in another post. Basically, the problem comes because Highcharts cannot render on a div with 'display: none' set. The solution is just write a fix in your CSS stylesheet.
我在另一篇文章中找到了一个更简单的解决方案。基本上,问题出现是因为 Highcharts 无法在设置了 'display: none' 的 div 上呈现。解决方案只是在您的 CSS 样式表中编写一个修复程序。
.tab-content > .tab-pane,
.pill-content > .pill-pane {
display: inline;
visibility: hidden;
position: absolute;
width: 930px;
}
.tab-content > .active,
.pill-content > .active {
display: inline;
visibility: visible;
position: absolute;
width: 930px;
}
This is going to make the tabs to work with visibility
attribute instead of display
. Charts will render well.
这将使选项卡使用visibility
属性而不是display
. 图表将呈现良好。
回答by Balint Bako
The in-line style "width" is different for the charts. I'm not sure when and how are those calculated, but you can override those in css for example.
图表的内嵌样式“宽度”是不同的。我不确定这些是何时以及如何计算的,但是您可以例如在 css 中覆盖它们。