使用 lazy_high_chart 画图,同时把图表放在 bootstrap 的 nav-tab 下面。
情况一:打开页面是默认 active 的那个 tab-content,显示的 chart 是正常 100% 宽度。

情况二:点击 tab,切换到相应的 tab-content,因为之前这个区域是 display:none 的,所以它得不到正常宽度,所以会显示默认宽度 600px。但我需要它显示的是 100% 宽度。

怎样才能以最简洁的方式让它显示 100% 宽度呢?
注:
scss
svg rect{
  width: 100%;
}
无效。
它自动生成的 html 为
erb
<rect x="0" y="0" width="600" height="400" strokeWidth="0" fill="#FFFFFF" class=" highcharts-background"></rect>
其它:正在研究这个官方例子 和另一个例子:我觉得它能解决这个问题,但好像代码太复杂了……我用不着这么多……
回帖有几个解决方案,但我自己还没有用对。 目前比较简洁的是一个 css hack 方法
.tab-content > .tab-pane{
        display: block;
        height: 0;
        overflow-y: hidden;
        &.active{
          height: auto;
        }
      }
lazy_high_chart 或者其他 chart 组件,通常为了方便应用,一般都是通过初始化参数指定,或者直接从上层容器获取宽度,高度信息,所以请检查一下改变一下放置 chart 容器的宽度是不是正确。
#3 楼 @lgn21st 可是为了简洁一点,我现在是只在 controller 里面设置所有参数,在 view 中显示,就没有再在 js 文件中写什么了…… 如果要计算什么的,我想想,是不是应该在 view 中去改些什么东东……
现在我的写法是 view 中:
<div role="tabpanel" class="text-center">
  <ul class="nav nav-tabs text-center" role="tablist">
    <li role="presentation" class="active">
      <a href="#per_week"  class="btn btn-default" aria-controls="per_week" role="tab" data-toggle="tab">一周</a>
    </li>
    <li role="presentation">
      <a href="#per_month"  class="btn btn-default" aria-controls="per_month" role="tab" data-toggle="tab">一月</a>
    </li>
    <li role="presentation">
      <a href="#per_year"  class="btn btn-default" aria-controls="per_year" role="tab" data-toggle="tab">一年</a>
    </li>
  </ul>
  <!-- Tab panes -->
  <div class="tab-content">
    <article role="tabpanel" class="tab-pane active" id="per_week">
      <%= high_chart("asset_growth_per_week_chart", @asset_growth_per_week_chart)  %>
    </article>
    <article role="tabpanel" class="tab-pane" id="per_month">
      <%= high_chart("asset_growth_per_month_chart", @asset_growth_per_month_chart)  %>
    </article>
    <article role="tabpanel" class="tab-pane" id="per_year">
      <%= high_chart("asset_growth_per_year_chart", @asset_growth_per_year_chart)  %>
    </article>
  </div>
</div>
controller 中
# 资产增长 - 每周
   @asset_growth_per_week_chart = LazyHighCharts::HighChart.new('graph') do |f|
     f.chart({ type: 'line'} )
     series = {
         name: '资金数量',
         data: [7.0, 6.9, 9.5, 14.5, 18.4, 21.5, 25.2]
     }
     f.series(series)
     f.xAxis({categories: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']})
     f.yAxis({title: {text: '资产数量 (万)'}})
     f.plot_options(line:{
                        allowPointSelect: true,
                        cursor: "pointer" ,
                        color: 'rgb(122, 201, 237)',
                        dataLabels:{enabled: true},
                        enableMouseTracking: false
                    })
   end
楼主这个问题我也碰到过类似的,使用 lazy 在多个 tab pane 生成图,第一个是 100% 宽度,后面几个切换就是 pane 的宽度,很窄,然后浏览器缩小下,然后放大,就变成 100% 宽度了。
就像 @lgn21st 提及的那样,首先看这个选项支不支持类似于 label formatter 那样传入函数:
labels: {
  formatter: %|function(){ return this.value + '#{x_suffix}' }|.js_code
}
但是,非常遗憾,我查了一下 API,好像不支持,那么就只能使用纯 JS 的方式解决问题了。先获取 tab 宽度,然后使用 setSize 这个函数设置宽度就可以了,详情请仔细阅读 API,哈哈!
chart.setSize(chartWidth);
在处理响应式页面的时候我用的是:
$(this).highcharts().reflow() 
$(this)是 highchart 的 DOM obj
bs nav-tab 不是有事件调用吗?绑定 tab 的 click/shown 然后调用 reflow() 有没有试过?
#8 楼 @xhj6 有啊,在 view 中使用,就是丑陋了点。比如我上一个饼图,在 view 中是这么写的
<%= high_chart("asset_allocation_chart", @asset_allocation_chart) do |c| %>
        <%= raw "options.tooltip.formatter = function() {return '<b>'+ this.point.name +'</b>: '+ this.y +' %';}"  %>
        <%= raw "options.plotOptions.pie.dataLabels.formatter = function() {
        if (this.y > 5) return this.point.name + ': ' + Math.round(this.percentage*100)/100 + ' %';; }"  %>
    <% end %>
感觉像是把 js 代码写到 html 里,挺别扭的其实……
对于本问题,@gihnius 的答案是最优解(我提的 reSize 也行,只不过要指定一下宽度,稍显麻烦了一些),具体实现可参考如下代码:
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
  $('.chart', e.relatedTarget).highcharts().reflow();
})
注意以上代码未经测试,不一定可用,但思路应该是这样的,你后面改 CSS 就越走越远了。
另外,你把 js 写入 HTML 中,当然就很丑了啊,js 就应该在 js 文件中,而向传递 formatter 的函数,lazyhighcharts 给出的正确做法是写入 Controller 中(或 Model 中),具体写法见我在 8 楼给出的代码示例。
#21 楼 @jasontang168 我现在报废一台用了不到一年的苹果电脑,心情不好,不要找我。你就直接用上面那个 scss 的去覆盖对应的元素就行了!
