PSI Labs RSS feed

Chart.js の toBase64Image メソッドは画像が生成されない場合がある

こんにちは、tomita です。最近 Chart.js を触っています。

Chart.js は たったの数行で綺麗なグラフが作成できる、端的にいって素晴らしいプロダクトです。

さて、Chart.js で作成したグラフを base64 で出力し png 表示させるのは自然な流れ(?)ですのでさっそくやってみたのですが、うまくいきませんでした。コードは以下になります。(jQuery-3.0.0, Chart.js-2.1.6 使用)

<canvas id="id_mychart" height="200" width="300"></canvas>
<div id="id_copy_img"></div>
<script>
;$(function(){
	// chart出力
	var $ctx = $("#id_mychart");
	var data = {
		labels: ["a","b","c","d"],
		datasets:[{
			label:"sample",
			data:[4,3,0,5]
		}]
	};
	var myChart = new Chart($ctx, {
		type : "line",
		data : data
	});

	// base64 を取得して img タグに流し込み…したつもりが何も表示されず…
	$("#id_copy_img").append($("<img />").attr({
		src : myChart.toBase64Image()
	}));
});
</script>

原因は chart.js のアニメーションによるグラフレンダリングが終わっていないためです(ディフォルトではレンダリングが終わるまで1秒かかります)。

ということで対処法はふたつ。

ひとつめは以下コードのように duration:0 を指定してアニメーションを止め即時レンダリングされるようにします。

var myChart = new Chart($ctx, {
	type : "line",
	data : data,
	options:{
		animation:{
			// アニメーションストップ
			duration:0
		}
	}
});

// base64 を取得して img タグに流し込み
$("#id_copy_img").append($("<img />").attr({
	src : myChart.toBase64Image()
}));

もうひとつは onComplete:function(){....} を使って、アニメーション完了後にbase64を取得する方法です。

var myChart = new Chart($ctx, {
	type : "line",
	data : data,
	options:{
		animation:{
			onComplete:function(animation){
				// base64 を取得して img タグに流し込み
				$("#id_copy_img").append($("<img />").attr({
					src : animation.chartInstance.toBase64Image()
				}));
			}
		}
	}
});

base64 が取得できれば、サーバに送信して画像として保存することもできるので便利ですね。

それではまた~