web-dev-qa-db-ja.com

Chart.jsキャンバスのサイズ変更

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

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

77
Jaka

マウスのホバリング時に線のグラフィックがひどく見えたので、それを行うためのより簡単な方法を見つけたので、私はそれで多くの問題を抱えていました:

これらのChart.jsオプションを使用します。

// Boolean - whether or not the chart should be responsive and resize when the browser does.

responsive: true,

// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container

maintainAspectRatio: false,
159
NoFlag

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

問題は、すでにこれを実行していることに気付かないため、連続して呼び出されたときに、既に(2倍またはなんらかの)サイズが再び増加するまで、問題が始まるまで繰り返します。 (実際に起こっているのは、幅と高さのDOM属性を変更してキャンバスにピクセルを追加する必要があるかどうかをチェックし、必要であれば、それを何らかの係数で乗算し、通常2、それを変更してからCSSスタイルを変更することですページで同じサイズを維持するための属性。)

たとえば、一度実行すると、キャンバスの幅と高さが300に設定され、600に設定され、スタイル属性が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);
61
jcmiller11

これは私のために働く:

<body>
    <form>
        [...]
        <div style="position:absolute; top:60px; left:10px; width:500px; height:500px;">
            <canvas id="cv_values"></canvas>

            <script type="text/javascript">
                var indicatedValueData = {
                    labels: ["1", "2", "3"],
                    datasets: [
                        {
                            [...]
                        };

                var cv_values = document.getElementById("cv_values").getContext("2d");
                var myChart = new Chart(cv_values, { type: "line", data: indicatedValueData });
            </script>
        </div>
    </form>
</body>

本質的な事実は、divタグでキャンバスのサイズを設定する必要があることです。

23
Patrick Pirzer

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

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

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

18

Jcmiller11が示唆したように、幅と高さを設定すると役立ちます。少し良い解決策は、チャートを描画する前にキャンバスの幅と高さを取得することです。次に、それらの数値を使用して、チャートを再描画するたびにチャートを設定します。これにより、javascriptコードに定数が含まれないことが保証されます。

ctx.canvas.originalwidth = ctx.canvas.width;
ctx.canvas.originalheight = ctx.canvas.height;

function drawchart() {
    ctx.canvas.width = ctx.canvas.originalwidth;
    ctx.canvas.height = ctx.canvas.originalheight;

    var chartctx = new Chart(ctx);
    myNewBarChart = chartctx.Bar(data, chartSettings); 
}
6
Anon

ここでは、いくつかの微調整を加えた複数の回答の組み合わせを使用する必要がありました。

最初に、必要ですブロックレベルのコンテナ内にキャンバス要素をラップします。 notを実行すると、canvas要素に兄弟ができます。 stubbornおよびspoiledであるため、孤独な子供にしましょう。 (ラッパーにはサイズ変更の制限は必要ありませんが、安全のために、max-heightを適用するとよい場合があります。)

前の条件が満たされていることを確認した後、チャートを開始するときに、次のオプションが使用されていることを確認します。

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

チャートの高さを調整する場合は、キャンバス要素レベルで調整します。

<canvas height="500"></canvas>

他の方法で子供に対処しようとしないでください。これにより、満足のいく適切にレイアウトされたチャートが作成されるはずです。

4
truefusion

同様の問題があり、あなたの答えが見つかりました。

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回呼び出されれば問題ありませんが、複数回再描画すると、キャンバスDOM要素のサイズが複数回変更され、サイズ変更が発生します。

お役に立てば幸いです!

3
yahfree

JQueryを使用してCanvasのサイズを変更しようとしましたが、うまくいきませんでした。 CSS3は、特定の場所でホバーズームしたい場合に試してみることができる最良のオプションだと思いますレベル。

他のコードパンリンクからのホバーオプションに従う:

.style_prevu_kit:hover{
    z-index: 2;
    -webkit-transition: all 200ms ease-in;
    -webkit-transform: scale(1.5);
    -ms-transition: all 200ms ease-in;
    -ms-transform: scale(1.5);   
    -moz-transition: all 200ms ease-in;
    -moz-transform: scale(1.5);
    transition: all 200ms ease-in;
    transform: scale(1.5);
}

私のコードパンリンクに従ってください:

https://codepen.io/hitman0775/pen/XZZzqN

1
Hiten Patel

誰かが問題を抱えている場合、応答性などを犠牲にすることのない解決策を見つけました。

Chartコンストラクターを呼び出す前に、キャンバスをdivコンテナー(スタイルなし)でラップし、divのコンテンツをIDを持つ空のキャンバスにリセットするだけです。

例:

HTML:

<div id="chartContainer">
    <canvas id="myChart"></canvas>
</div>

JS:

$("#chartContainer").html('<canvas id="myChart"></canvas>');
//call new Chart() as usual
1
fpscolin

私は同じ問題を抱えていました。オプションを設定することで解決できました:

responsive: false,
maintainAspectRatio: true,
showScale: false,

CSSで、コンテナdivの幅をキャンバスと同じに設定します。

    #canvasContainer { 
      width: 300px;
    }
    
    canvas {
      width: 300px;
    }
0
Nova Qiu

Angular CLIを使用して、同じ種類のスケーリングの問題が発生しました。 index.htmlから次の行を削除することで機能するようになりました。

<script src="node_modules/chart.js/dist/Chart.bundle.min.js"></script>

次に、これを使用して、angular-cli.jsonファイルのスクリプトセクションで:

"scripts": ["../node_modules/chart.js/dist/Chart.bundle.min.js"]

ソース :mikebarr58

0
Wouter Vanherck