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


86

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

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


現在、彼らはChart.jsの公式ウェブサイトにある専用のページです。chartjs.org/ docs / latest / general / response.htmlソリューションをテストしましたが、問題なく動作します。
Amine27

回答:


175

私はそれに関して多くの問題を抱えていました。なぜなら、マウスをホバリングしたときに私の線のグラフィックがひどく見え、それを行うためのより簡単な方法を見つけたので、それが役立つことを願っています:)

次の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,

答えてくれてありがとう@NoFlag。私の場合、高さと幅の属性がキャンバスに適用されていませんでした。誰かがここでキャンバスのサイズを変更しようとする解決策を探している場合は、trueに応答して設定してみてください。* Chart.defaults.global.responsive = false *
sghosh968 2016

13
この方法が正しく機能するためには、キャンバスをに配置し、キャンバスの代わりに<div>高さや幅を上記<div>に設定する必要があることを忘れないでください。
totymedli 2017

2
これらのフラグはデフォルトでに設定されているためtrue、タッチする必要はありません。chartjs.org
Ferreira

これに伴い、キャンバスの幅と高さも設定します。その後、正常に動作します。ありがとう
MazharMIK19年

63

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

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

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

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

var ctx = document.getElementById("canvas").getContext("2d");
ctx.canvas.width = 300;
ctx.canvas.height = 300;
var myDoughnut = new Chart(ctx).Doughnut(doughnutData);

私はこのエラーに遭遇しました:Uncaught ReferenceError:doughnutData is not defined
Dulith De Costa 2016

11
エラー。はい、グラフ化しようとしたデータがわからないため、これは単なるプレースホルダー変数です。
jcmiller11 2016

26

これは私のために働きます:

<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タグでキャンバスのサイズを設定する必要があるということです。


同意する!キャンバスをdiv内に配置し、「レスポンシブ」のオプションがfalseでないことを確認します(デフォルトではtrueです)。次に、サイズ設定ルールをdivに適用します。
noelB 2017年

20

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

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

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


6

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); 
}

申し訳ありませんが、これがどのように機能するか説明できますか?たとえば、ページを開いたときにキャンバスのサイズは1つですが、ウィンドウのサイズを変更すると、キャンバスのサイズが異なります(以前のウィンドウのサイズであったため、元のサイズは必要ないでしょう)。
kiradotee 2016

6

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

まず、canvas要素をブロックレベルのコンテナ内にラップする必要があります。私はあなたに言います、canvas要素に兄弟を持たせないでください。それは頑固甘やかされているので、それを孤独な子供にしましょう。(ラッパーにサイズ制限を設定する必要がない場合もありますが、安全のために最大高さを適用するとよい場合があります。)

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

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

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

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

他の方法で子供に対処しようとしないでください。これにより、満足のいく適切にレイアウトされたチャートが作成され、ベビーベッドに静かにとどまります。


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

お役に立てば幸いです。


1

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

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

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

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

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

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

    #canvasContainer { 
      width: 300px;
    }
    
    canvas {
      width: 300px;
    }


0

AngularCLIを使用した場合と同じ種類のスケーリングの問題がありました。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


-3

追加するdivと問題が解決します

<div style="position:absolute; top:50px; left:10px; width:500px; height:500px;"></div>

-5
 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);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.