21

一部のチャートを SVG としてレンダリングするために、 amCharts (舞台裏でRaphaëlを使用) を使用しています。また、SVG が最初は非表示の div でレンダリングされる場合、ブラウザーは div が表示されたときにすぐに画像をレンダリングしないことに気付きました。ただし、ブラウザーのサイズを変更したり、Ctrl キーを押しながらマウスホイールでズームしたりして表示を変更すると、ページが再描画されたときに SVG 画像が期待どおりにレンダリングされます。

div 表示切り替えの正確な方法は、Bootstrap のタブ付き navbarを使用することです。

私は SVG の経験があまりないことを認めます - これはブラウザのレンダリングの問題ですか、それとも amCharts の SVG マークアップの問題ですか、それとも SVG の可視性が変更されたことがわかったときに何らかの再描画メソッドを明示的に呼び出す必要があるのでしょうか?

問題を説明するjsFiddle を次に示します。セクション 2 (Chrome、Firefox) に切り替えると、グラフは最初は表示されません。ディスプレイのサイズを変更すると、表示されます。

4

10 に答える 10

26

私は初期の動作と回避策の両方の理由を見つけました-そしてそれはすべてamCharts固有です(SVG自体とは関係ありません)ので、それに応じてタイトルを言い換えています。

何が起こるかというと、amChartsがSVGを作成するとき、絶対的な用語で幅と高さを定義する必要があります(または少なくとも決定する必要があります)。offsetWidthこれらは、およびoffsetHeightプロパティを介して取得されたターゲットdivのサイズに基づいています。

非アクティブなタブにはdisplay: noneプロパティが設定されており、その結果、DOMのこの部分もレンダリングされないため、両方のサイズのプロパティに対してゼロが返されます。chart.writeこれにより、非表示のdivに対してが呼び出されたときに、amChartsが0x0SVGチャートを作成することになります。

onresize各チャートは、チャートのhandleResizeメソッドを呼び出すウィンドウイベントにリスナーを登録するため、サイズ変更により問題が修正されます。これにより、divの新しい(現在の)寸法に基づいて幅と高さが再計算されます。


したがって、結論として、これを処理するための2つの代替方法があると思います。

  • chart.writeタブが表示されたときにのみチャートを呼び出します。
  • handleResizeタブが変更されたら、各チャートのメソッドを呼び出します。

(最初のオプションは、非表示のグラフをレンダリングする最初のヒットを回避しますが、タブが変更されるたびに完全に再描画します。後者は前もってヒットしますが、その後は速くなる可能性があります。ボーナスマークの場合、最善の解決策は次のとおりです。各チャートを各サイズ変更の間に1回だけレンダリングし、最初に表示されるようにしますが、デフォルトのイベントリスナーなどに干渉するため、これははるかに複雑です。)

更新:非表示のグラフのレンダリングにはさらに複雑な問題があります。特に、ドメイン軸に必要なスペースが考慮されていないため、チャートをそのdivから引き伸ばす高さの計算に問題があることがわかりました。これは電話で修正されませんでしたhandleResize-measureMargins事前に電話をかけるとうまくいくように見えましたが、うまくいきませんでした。(この後、それを機能させるために呼び出すことができる別のメソッドがおそらくありますresetMarginsが、この時点でそれは非常に不安定に感じ始めました...)

そのため、非表示のdivで初めてグラフをレンダリングするのは実用的ではないと思うので、上記の箇条書きをいくつか組み合わせて使用​​しました。グラフのタブが初めて表示されるのを聞いてからchart.write、適切なグラフオブジェクトを呼び出します。タブが変更されるたびに、以前にレンダリングされたすべてのグラフがサイズ変更を処理するように指示されます。

于 2012-04-04T16:07:32.503 に答える
4

* 編集済み *

ここに更新されたfiddleがあります。キャンバスは、タブが表示された後にのみレンダリングされます。chartdiv id を配列に格納し、そこにあるかどうかを確認します。

* 編集済み *

私が見つけた唯一の解決策は、特定のタブが表示された後にグラフを表示することでした。

このjsFiddleでわかるように。

var tabs = $('.tabbable').tab()

tabs.on('shown', function(e){
   id = $(e.target).attr('href');        
   chartdiv_id = $(id).find('.chartdiv').attr('id');                        
   doChart(chartdiv_id, true);
});

探しているものとは違うと思いますが、とりあえず参考になれば幸いです。

于 2012-04-04T15:36:38.110 に答える
4

私は同じ問題を抱えていましたが、私の解決策はdisplay:noneの代わりです.cssでこのクラスを使用できます

.hidden {
   position: absolute !important;
   top: -9999px !important;
   left: -9999px !important;
}

この画面は消えますが、amchart では表示されるため、チャートの解像度がサイズを失うことはありません!!!!

于 2013-06-06T01:43:19.390 に答える
2

私もこの問題に遭遇し、初期化子を関数にすることで修正しました。ワーキングフィドル

$("#button").click(function(){
    $("#chartdiv").toggle();
    makeChart();
});

function makeChart() {
     var chart = AmCharts.makeChart("chartdiv", {
         //all the stuff
     });
}
于 2014-06-19T14:24:32.253 に答える
2

これは、問題の解決に役立つ場合があります。amchart を別の tab pan に表示しています。SVG コンポーネントでは、サイズ変更の問題により、その div を表示できません。

$(window).resize(function() {
    setTimeout(function() {
        chart.write("chartdiv1");
    }, 300);
});

グラフの作成中にウィンドウのサイズを再度変更します..

于 2014-05-30T11:59:14.707 に答える
2
<a href="#" class="show_charts">Show me charts</a>
<div class="charts_div" style="display:hidden;">
some charts here
</div>
<script>
    $(document).on('click', '.show_charts', function(){
        $('.charts_div').toggle();
        //just redraw all charts available on the page
        for(var i = 0; i < AmCharts.charts.length; i++) {
            AmCharts.charts[i].validateData();
        }
    });
</script>
于 2015-10-05T19:33:42.330 に答える
1
var chart = null;
AmCharts.ready(function () {
    chart = AmCharts.makeChart('chart', .....);
});
$(document).ready(function(){
    $("#view_chart").click(function(){
        chart.validateSize();
    });
});


<button type="button" id="view_chart">View Chart</button>
<div style="display:none;" id="chart"></div>
于 2015-09-17T17:31:34.583 に答える
0

別の回避策は

drawTransactionTypeChart();
setTimeout(function(){hidePieCharts();},1);

最初display:inlineはチャート コンテナである div に設定され、レンダリングされます。

その後、1ms 後にdisplay:none使用して設定します。setTimeout()

お役に立てれば...

于 2013-12-19T11:21:27.267 に答える
0

異なるタブに2つの amchartがあります。#chartdiv に配置する株価チャートと #chartdivpie に配置する円グラフ。これが私の問題を解決した方法です。

私のカスタムCSS - ブートストラップを上書きする -

#chartdivpie { width: 1138px; height: 500px; }
.tab-content .tab-pane {
   position: absolute;
   top: -9999px;
   left: -9999px;
   display: inline;
}
.tab-content .tab-pane.active {
    position: inherit !important;
}

JQuery 呼び出し

$('#myTab a').click(function (e) {
      e.preventDefault()
        $(this).tab('show');
        chart.invalidateSize();
        chart.write('chartdiv');
    })
于 2014-03-09T22:40:18.053 に答える