amCharts ( Raphaël を舞台裏で使用)を使用してレンダリングしています一部のグラフはSVGです。また、SVGが最初は非表示のdivでレンダリングされた場合、divが表示されてもブラウザーはすぐに画像をレンダリングしないことに注意してください。ただし、表示を変更した場合は、ブラウザのサイズを変更するか、Ctrlキーとマウスホイールでズームすると、ページが再描画されたときにSVG画像が期待どおりにレンダリングされます。
Divの表示切り替えの正確な方法は、 Bootstrapのタブ付きnavbar を使用する方法です。
SVGの経験があまりないことを認めます-これはブラウザーのレンダリング、またはamChartsのSVGマークアップの問題ですか、それともSVGの可視性が変更されたことがわかると、何らかの再描画メソッドを明示的に呼び出す必要がありますか?
これは、問題を説明する jsFiddleです ;セクション2に切り替えると(Chrome、Firefoxの場合)、チャートは最初は表示されません。ディスプレイのサイズを変更すると表示されます。
最初の動作と回避策の両方の理由を見つけました-それはすべてamCharts固有(SVG自体には関係ありません)なので、それに応じてタイトルを言い換えます。
AmChartsがSVGを作成するときに、絶対的な用語で幅と高さを定義する(または少なくとも決定する)必要があるということです。これらは、offsetWidth
およびoffsetHeight
プロパティを介して取得されるターゲットdivのサイズに基づいています。
非アクティブなタブにはdisplay: none
プロパティが設定されており、その結果、DOMのこの部分はレンダリングされないため、両方のサイズプロパティに対してゼロを返します。これにより、最終的にchart.write
が非表示のdivに対して呼び出されたときに、amChartsが0x0 SVGチャートを作成します。
各チャートは、チャートのonresize
メソッドを呼び出すhandleResize
ウィンドウイベントにリスナーを登録するため、サイズを変更すると状況が修正されます。これにより、divの新しい(現在の)寸法に基づいて、幅と高さが再計算されます。
結論として、これを処理するには2つの代替方法があると思います。
chart.write
を呼び出して、タブが表示されるようになったときだけチャートを表示します。handleResize
メソッドを呼び出します。(最初のオプションは、非表示のグラフをレンダリングする最初のヒットを回避しますが、タブが変更されるたびに完全な再描画を行います。後者は、最初にヒットを受け取りますが、その後はより高速です。ボーナスマークの場合、最良の解決策は各チャートを各サイズ変更の間に正確に1回表示するには、最初に表示されますが、特に、デフォルトのイベントリスナーとの干渉が発生するため、はるかに複雑です。
更新:非表示のグラフのレンダリングにはさらに複雑な問題があります。特に、高さの計算でドメイン軸に必要なスペースが考慮されていないため、グラフをdivから引き伸ばす際に問題が見つかりました。これはhandleResize
を呼び出しても修正されませんでした。measureMargins
を呼び出すと、正常に機能するように見えましたが、機能しませんでした。 (おそらく、この後でresetMargins
のように機能させるために呼び出すことができる別のメソッドがあるでしょうが、この時点で非常に不安定に感じ始めました...)
そのため、非表示のdivで初めてチャートをレンダリングすることは現実的ではないと思うので、上記の箇条書きのいくつかの組み合わせを使用しました。チャートのタブが初めて表示されたときにリッスンし、適切なチャートオブジェクトに対してchart.write
を呼び出します-タブが変更されるたびに、all以前にレンダリングされたチャートは、サイズ変更を処理するように指示されます。
*編集済み*
これが更新された 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);
});
それはあなたが探しているものとは正確には違うと思いますが、それが今のところ役に立てば幸いです。
私は同じ問題を抱えていましたが、私の解決策はdisplay:noneの代わりです:CSSでこのクラスを使用できます
.hidden {
position: absolute !important;
top: -9999px !important;
left: -9999px !important;
}
画面が消えるが、アンチャートでは表示されるため、チャートの解像度がサイズを失うことはありません!!!!
<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>
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>
これは、問題の解決に役立つ場合があります。アンチャートを別のタブパンに表示しています。 SVGコンポーネントでは、サイズ変更の問題により、そのdivを表示できません。
$(window).resize(function() {
setTimeout(function() {
chart.write("chartdiv1");
}, 300);
});
チャートを作成しながら、ウィンドウのサイズを再度変更します。
私はアンジェイ・ドイルに完全に同意します。
選択したdiv(タブ)をクリックしたときにチャートでhandleresizeを発行すると、カスタムタブ(jqueryタブではない)を備えたcs-cartで機能します。
以下は、カートがグローバルに定義されているときに機能します。
function refreshchart(){
chart.handleResize();
};
私も問題に遭遇し、初期化子を関数にすることで修正しました。 作業フィドル 。
$("#button").click(function(){
$("#chartdiv").toggle();
makeChart();
});
function makeChart() {
var chart = AmCharts.makeChart("chartdiv", {
//all the stuff
});
}
異なるタブに2つのアンチャートがあります。 #chartdivに配置する株価チャートと#chartdivpieに配置する円グラフ。これは私が私の問題を解決した方法です。
私のカスタムCSS-上書きするbootstrap-
#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');
})
別の回避策は
_drawTransactionTypeChart();
setTimeout(function(){hidePieCharts();},1);
_
最初に_display:inline
_をチャートコンテナーであるdivに設定すると、レンダリングされます。
次に、1ミリ秒後にsetTimeout()
を使用して_display:none
_を設定します。
お役に立てれば...