95

( Android WebView HTML5 キャンバス エラー) で、Graph.js ライブラリを使用したグラフのプロットに関する質問を投稿しました。私が今抱えている問題は、関数を呼び出してグラフを複数回プロットすると、キャンバスのサイズが毎回変更されることです。グラフが同じキャンバスに再描画されるたびに、そのサイズも変更されます。キャンバスのサイズも設定しようとしましたが、成功しませんでした。

その理由は何ですか?毎回キャンバスのサイズが変更されるのはなぜですか?

4

16 に答える 16

64

何が起こっているのかというと、Chart.js が呼び出されたときにキャンバスのサイズを増やしてから、CSS を使用して縮小しようとします。その目的は、高 dpi デバイスに高解像度のグラフを提供することです。

問題は、これが既に行われていることに気付いていないため、連続して呼び出されると、物事が壊れ始めるまで、既に (2 倍か何か) サイズが AGAIN に乗算されます。(実際に起こっているのは、幅と高さの DOM 属性を変更してキャンバスにピクセルを追加する必要があるかどうかを確認することです。必要な場合は、何らかの係数 (通常は 2) を掛けてから、それを変更し、css スタイルを変更します。ページ上で同じサイズを維持するための属性)。

たとえば、キャンバスの幅と高さが 300 に設定されている場合、一度実行すると 600 に設定され、次に style 属性が 300 に変更されます... しかし、もう一度実行すると、DOM の幅と高さがは 600 です (理由については、この質問に対する他の回答を確認してください)。次に、それを 1200 に設定し、CSS の幅と高さを 600 に設定します。

最も洗練されたソリューションではありませんが、Chart.js を連続して呼び出す前にキャンバスの幅と高さを手動で設定するだけで、Retina デバイスの拡張解像度を維持しながらこの問題を解決しました。

var ctx = document.getElementById("canvas").getContext("2d");
ctx.canvas.width = 300;
ctx.canvas.height = 300;
var myDoughnut = new Chart(ctx).Doughnut(doughnutData);
于 2014-02-15T13:00:35.587 に答える
21

IOS および Android では、スクロール中にブラウザーがツールバーを非表示にするため、ウィンドウのサイズが変更され、chartjs がグラフのサイズを変更します。解決策は、アスペクト比を維持することです。

var options = { 
    responsive: true,
    maintainAspectRatio: true
}

これで問題が解決するはずです。

于 2015-01-28T06:01:13.313 に答える
3

同様の問題があり、あなたの答えを見つけました..最終的に解決策にたどり着きました。

Chart.jsのソースには次のように見えます(おそらく、同じキャンバスでまったく異なるグラフを再レンダリングすることは想定されていないためです):

    //High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
if (window.devicePixelRatio) {
    context.canvas.style.width = width + "px";
    context.canvas.style.height = height + "px";
    context.canvas.height = height * window.devicePixelRatio;
    context.canvas.width = width * window.devicePixelRatio;
    context.scale(window.devicePixelRatio, window.devicePixelRatio);
}

これは 1 回呼び出された場合は問題ありませんが、複数回再描画すると、canvas DOM 要素のサイズが複数回変更され、サイズ変更が発生します。

それが役立つことを願っています!

于 2014-02-06T19:25:07.667 に答える
0

このスレッドで複数の回答を試しましたが、うまくいったのは(reactjsを使用していることに注意してください)、チャートコンポーネントに渡された以前の小道具をチェックすることでした。DOM のサイズを変更していたときに、グラフが空のデータで再描画されていました。

componentDidUpdate(prevProps: ChartProps) { if(prevProps.data !== props.data) renderChart(); }
于 2021-05-12T14:03:45.273 に答える
-6
 let canvasBox = ReactDOM.findDOMNode(this.refs.canvasBox);
 let width = canvasBox.clientWidth;
 let height = canvasBox.clientHeight;
 let charts = ReactDOM.findDOMNode(this.refs.charts);
 let ctx = charts.getContext('2d');
 ctx.canvas.width = width;
 ctx.canvas.height = height;
 this.myChart = new Chart(ctx);
于 2016-01-31T11:40:28.910 に答える