web-dev-qa-db-ja.com

jQueryUIタブとハイチャートの表示/レンダリングの問題

jquery-ui-1.8.9のタブ(Highcharts 2.1.4)と円グラフを一緒に使用したことはありますか?簡単に言うと、複数のタブがあり、各タブには異なるデータの円グラフが表示されます。チャートはdivにレンダリングされますが、2番目のタブをクリックすると、チャートは本来あるべき場所の右側に300pxと表示されます。ブラウザウィンドウをズームインまたはズームアウトすると、チャートは修正位置に戻ります。

私のコード:

//変数$ countに基づいてタブの数が生成され、2つのタブがあるとします。

<script type="text/javascript">

var chart_tab_<?=count?>;

$(document).ready(function() {
    chart_tab_<?=count?> = new Highcharts.Chart({
      chart: {
         renderTo: 'chart_tab_<?=count?>',
         // blah blah
      }

<body>
    <div id="chart_tab_<?=count?>"></div>
</body>

繰り返しますが、グラフはレンダリングされますが、2番目のタブの表示にバグがあります。

更新:この種類の問題が修正されることを私は知っています:

<script type="text/javascript"> 
   $(document).ready(function() {
      $( "#tabs" ).tabs({
          cookie: { expires: 1 }
      });
      $( "#tabs" ).tabs({
          select: function(event, ui) { window.location.reload(); }
      });
   });

しかし、ユーザーがタブをクリックするたびにページをリロードする必要があるため、これは本当に厄介です。どんなアイデアでも素晴らしいでしょう。

17
Brian

これが私の解決策です(SafariとFirefoxでのみテストされています)。柔軟な幅のページの非表示のタブにグラフをロードする場合に最適です。ブラウザウィンドウのサイズが変更されると、グラフのサイズが変更されます。

グラフの設定で、ページの読み込み時に開くタブからグラフの幅を設定します(jQueryを使用して幅を取得します)。

   var chart = new Highcharts.Chart({
     chart: {
       renderTo: 'container',
       type: 'column',
       width: $('#tab-1').width()
     },
     ....

次の関数は、ブラウザウィンドウのサイズが変更された場合に幅を調整します。 500は高さです。チャートオプションで幅が指定されていない場合、これは自動的に行われます。

$(window).resize(function() {
   chart.setSize($('#chart_tab').width(),500);       
});
12
LordNelson

ハイチャートを非表示のjQueryタブで機能させるために必要な変更。デフォルトでは、jQueryはdisplay:noneを非表示のタブに設定しますが、このアプローチでは、Highchartsは要素の実際の幅と高さを取得できません。したがって、代わりに、絶対に配置し、ビューポートから離します。

 <style type="text/css">
.ui-tabs .ui-tabs-hide {
     position: absolute;
     top: -10000px;
     display: block !important;
}           
 </style>

例を追加: http://www.highcharts.com/studies/jquery-ui-tabs.htm

6
Haim

2番目のグラフは、描画すると非表示になっているように聞こえるため、オフになっている可能性があります。選択時にチャートを描いてみてください。

これが私が想像するもののアイデアをあなたに与えるためのいくつかの擬似コードです。これはテストされていません。

$("#tabs").tabs({
  select: function(event, ui) {
     var chart = new Highcharts.Chart({
      chart: {
       renderTo: ui.panel.id,
       // blah blah
      }
     });

  }
});
4
ojreadmore

サイズ変更イベントを手動でトリガーする必要があります

$(window).trigger('resize');
3
Ramin Mousavi

最善の解決策は、タブのコールバック関数を使用するか、各タブをクリックしたときにハイチャートをリフローすることです。それを見てください:

Chart.reflow およびこのリンク jsfiddle およびタブコールバックに追加したこのコード:

$('#chart-1').highcharts().reflow();
2
Parhum

より小さな回避策は、CSSでチャートに静的な幅を使用することです(それがどうあるべきかを知っている場合)-

.tab-pane { width: 1200px; }
1
ToddN

追加 class="chart"タブ内のすべてのハイチャートコンテナに。

このjQueryコードを追加します。

jQuery(document).on( 'shown.bs.tab', 'a[data-toggle="tab"]', function () { 
    $( '.chart' ).each(function() { 
        $(this).highcharts().reflow();
    });
})
0
user2511140

jQuery UI 1.9以降では、タブの非表示方法が変更されました。この方法でタブをアクティブ化する場合は、独自のクラスを設定する必要があります。

$('#tabs').tabs({
  beforeActivate: function (event, ui) {
    $(ui.oldPanel).addClass('ui-tabs-hide');
    $(ui.newPanel).removeClass('ui-tabs-hide');
  }
});

次のCSSと組み合わせる:

.ui-tabs-hide { 
  display: block !important; 
  height: 0!important; 
  width: 0!important; 
  border:none!important; 
}

これにより、Flash埋め込みオブジェクトが非表示のタブに正しく読み込まれないことも修正されます。

0
Loris Guignard

これは、タブにクラス名(contains-chart)を追加した後、私にとってはうまくいきました

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
            }
0
John Sarties

私は同じ問題に遭遇しました、reflow()メソッドは私のために働きます。グローバルHighcharts変数にアクセスして、対応するチャートを把握します。ここで、チャートの順序はタブの順序です。

<script type="text/javascript">
    $(function () {
        $("#tabs").tabs({
            show: function (event, ui) {
                var chart = Highcharts.charts[ui.index];
                if (chart != null) {
                    chart.reflow();
                }
            }
        });
    });
</script>
0
Huy Do

チャートが文字化けして開いていたjQueryアコーディオンがありました...これが私の解決策でした:

最初にチャートをグローバルに詰め込みます:window.myNamespace.charts。#{container_id}、次に私のアコーディオンでこれを行います:

$('#my-accordion').accordion
  ...,
  change: () ->
    chartId = ui.newContent.find('.highcharts-container').parent().attr('id')
    window.myNamespace.charts[chartId].setSize(248,220) if chartId?

上記はコーヒースクリプトですが、翻訳するのは簡単なはずです...

基本的に、チャートでsetSizeを呼び出して、チャートを既にあるサイズに設定します...これは、チャートが開いた後にクリーンアップする効果があります...これは単なる回避策です...理想的にはハイチャートバグを修正し、非表示の要素からサイズを計算する代わりに、指定したサイズを使用します

0
fringd

こんにちは私のフィドルを参照してください jsfiddle

...
$("#tabs").tabs();
var ids = ['chart-1', 'chart-2', 'chart-3'];
for (var i = 0, j = ids.length; i < j; i++) {
    if ((container = $('#'+ids[i])).size()) {
        if (container.width()==0) {
            container.width(container.actual('width'));   
        }

        oclone = $.extend({}, options);
        oclone.chart.renderTo = ids[i];
        new Highcharts.Chart(oclone);
    }

}
...
0
Lgrusev

チャートがデフォルトでアクティブ化されていないタブにあるときはいつでも、チャートがゼロ幅でクライアントにレンダリングされるという同様の問題がありました。この答えは、ojreadmoreの答えに触発されました。 jQueryのドキュメント準備完了イベントを使用してハイチャートを初期化する代わりに、チャートが表示されているタブのアクティブ化イベントを使用する必要があります。これには、ユーザーがタブをクリックするたびに洗練されたグラフアニメーションを実行するという追加の利点があります。

の代わりに:

$(document).ready(function() { 
    var chart1 = new Highcharts.Chart({
        chart: {
            renderTo: 'container',
            type: 'bar'
        },
        title: {
            text: 'Fruit Consumption'
        },
        xAxis: {
            categories: ['Apples', 'Bananas', 'Oranges']
        },
        yAxis: {
            title: {
                text: 'Fruit eaten'
            }
        },
        series: [{
            name: 'Jane',
            data: [1, 0, 4]
        }, {
            name: 'John',
            data: [5, 7, 3]
        }]
    });
});​

使用する:

$('#tabcontainer').on('tabsactivate', function (event, ui) { 
    var chart1 = new Highcharts.Chart({
        chart: {
            renderTo: 'container',
            type: 'bar'
        },
        title: {
            text: 'Fruit Consumption'
        },
        xAxis: {
            categories: ['Apples', 'Bananas', 'Oranges']
        },
        yAxis: {
            title: {
                text: 'Fruit eaten'
            }
        },
        series: [{
            name: 'Jane',
            data: [1, 0, 4]
        }, {
            name: 'John',
            data: [5, 7, 3]
        }]
    });
});​
0
Robb Vandaveer