(Android WebView HTML5キャンバスエラー)で、Graph.jsライブラリを使用したグラフのプロットに関する質問を投稿しました。私が今抱えている問題は、グラフを複数回プロットする関数を呼び出すと、キャンバスが毎回サイズ変更されることです。グラフが同じキャンバスに再描画されるたびに、そのサイズも変更されます。キャンバスのサイズも設定してみましたが、うまくいきませんでした。
理由は何でしょうか?なぜキャンバスは毎回サイズ変更されるのですか?
(Android WebView HTML5キャンバスエラー)で、Graph.jsライブラリを使用したグラフのプロットに関する質問を投稿しました。私が今抱えている問題は、グラフを複数回プロットする関数を呼び出すと、キャンバスが毎回サイズ変更されることです。グラフが同じキャンバスに再描画されるたびに、そのサイズも変更されます。キャンバスのサイズも設定してみましたが、うまくいきませんでした。
理由は何でしょうか?なぜキャンバスは毎回サイズ変更されるのですか?
回答:
私はそれに関して多くの問題を抱えていました。なぜなら、マウスをホバリングしたときに私の線のグラフィックがひどく見え、それを行うためのより簡単な方法を見つけたので、それが役立つことを願っています:)
次の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,
<div>
高さや幅を上記<div>
に設定する必要があることを忘れないでください。
true
、タッチする必要はありません。chartjs.org
何が起こっているのかというと、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);
これは私のために働きます:
<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タグでキャンバスのサイズを設定する必要があるということです。
IOSおよびAndroidでは、スクロール時にブラウザがツールバーを非表示にするため、ウィンドウのサイズが変更され、chartjsがグラフのサイズを変更します。解決策は、アスペクト比を維持することです。
var options = {
responsive: true,
maintainAspectRatio: true
}
これで問題が解決するはずです。
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);
}
ここでは、いくつかの小さな調整を加えて、複数の回答を組み合わせて使用する必要がありました。
まず、canvas要素をブロックレベルのコンテナ内にラップする必要があります。私はあなたに言います、canvas要素に兄弟を持たせないでください。それは頑固で甘やかされているので、それを孤独な子供にしましょう。(ラッパーにサイズ制限を設定する必要がない場合もありますが、安全のために最大高さを適用するとよい場合があります。)
前の条件が満たされていることを確認した後、チャートを開始するときに、次のオプションが使用されていることを確認してください。
var options = {
"responsive": true,
"maintainAspectRatio": false
}
グラフの高さを調整する場合は、キャンバス要素レベルで調整します。
<canvas height="500"></canvas>
他の方法で子供に対処しようとしないでください。これにより、満足のいく適切にレイアウトされたチャートが作成され、ベビーベッドに静かにとどまります。
私も同様の問題を抱えていて、あなたの答えを見つけました。私は最終的に解決策にたどり着きました。
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要素のサイズが複数回変更されてサイズが変更されます。
お役に立てば幸いです。
誰かが問題を抱えているなら、私は応答性などを犠牲にすることを伴わない解決策を見つけました。
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
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);
}
私のコードパンのリンクをたどってください:
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
追加するdiv
と問題が解決します
<div style="position:absolute; top:50px; left:10px; width:500px; height:500px;"></div>
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);