首页 文章

使用highcharts时,为什么Bootstrap选项卡显示宽度不正确的tab-pane div?

提问于
浏览
49

所以我正在使用Twitter的Bootstrap创建一个带有标签内容的页面,但我的开始活动div的内容总是与我的其他标签的内容不同 . 例如,我在不同的选项卡中使用highcharts.js放入图表,但活动的一个总是正确显示而其他的宽度不正确 .

看看下面的例子:

<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>

在这种情况下,在页面加载时切换活动选项卡使得该图表看起来对我来说是正确的,但其余的总是一直延伸到边缘(在我的数据的情况下,我想只填充span9的空间div . 在这种情况下我只是使用虚拟图表,但这是相同的想法 .

这是一个JSFiddle:http://jsfiddle.net/dw9tn/

我对你们的问题是:

1.)这只是我吗?

2.)当标签处于活动状态时到底发生了什么?看一下bootstrap css,这似乎处理display:none和display:block,但我对这种情况下的工作原理并不了解 .

3.)这是一个高级问题还是一个引导问题?我注意到这发生在我身上的非高图元素(比如在侧边栏中显示推文),所以我倾向于引导 .

4.)是否有任何解决方案可以使一切都保持一致?

多谢你们!

6 回答

  • 27

    问题是Highcharts无法计算具有CSS的容器的宽度: display:none ,因此应用的是默认宽度(600px) . 实际上,浏览器无法计算这些元素的宽度 .

    例如,当您使用分隔符调整“结果”窗口的大小时,图表将调整大小并且将起作用 . 所以你有三个选择:

    首次单击该选项卡后

    • 渲染图表

    • 在开始时渲染图表,但在每次单击和窗口调整大小后使用 chart.setSize(w,h) 具有新的宽度和高度

    • 在开头渲染图表,但在标签点击后调用 chart.reflow()

  • -1

    原因

    这不是Highcharts问题,至少本身不是问题,问题是由Bootstrap使用 display: none 来隐藏非活动标签引起的:

    .tab-content > .tab-pane, .pill-content > .pill-pane {
        display: none;      /* this is the problem */
    }
    

    这会导致Highcharts无法获得预期的宽度来初始化图表,因此默认为 600px . 使用相同方法隐藏内容的其他工具会发生这种情况 .

    纯CSS解决方案

    我们可以使用 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 :之前的两步解决方案首先隐藏所有选项卡,然后再次显示活动选项卡 . 相比之下,现在我们有一个单步解决方案,它直接针对非活动选项卡 .

    此解决方案是无缝的,因此您不必再担心图表是否位于选项卡窗格内 . 并且它是有效的,因为它首先修复了宽度问题,因此之后无需通过使用javascript调整大小/重绘/重排来解决宽度问题 .

    关于级联顺序的注意事项

    这个补丁需要在bootstrap css之后加载,因为CSS cascading order rules,简而言之, the latter rule wins .

    演示

    Before vs After

    提示:切换到“配置文件”选项卡以查看差异 .

  • 5

    根据Paweł的回答,我做了一个有效的例子:

    http://codepen.io/colinsteinmann/pen/BlGfE

    基本上,单击选项卡时,会在每个图表上调用.reflow()函数 . 这样,图表会根据容器变为可见时应用的新尺寸重新绘制 .

    这是最重要的代码片段:

    // 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
        });
    })
    
  • 1

    基于Pawel的答案,我在开始时渲染图表,然后调整图表的大小 .

    使用的代码(使用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());
    })
    

    资料来源:http://getbootstrap.com/javascript/#tabs-usage

  • 5

    我在另一篇文章中找到了一个更容易的解基本上,问题出现是因为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;
    }
    

    这将使选项卡与 visibility 属性而不是 display 一起使用 . 图表将很好地呈现 .

  • 144

    图表的内嵌式“宽度”不同 . 我不确定这些计算的时间和方式,但你可以在css中覆盖那些例如 .

相关问题