Chart.js のグラフを画像化し、透過する背景に色を指定する

更新:

Chart.js で作成したグラフを画像に変換し、透過する背景に色を指定するサンプルを記す。

アニメーションを禁止して画像に変換

Chart.js はデフォルトではグラフの表示時にアニメーションする。 そのため普通に画像化すると何も描画されていない。 そこでまず、アニメーションを停止して画像にするサンプルを記す。 コードは以下の通り。

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>

<style>
#ex_chart {max-width:640px;max-height:480px;}
</style>

<canvas id="ex_chart"></canvas>

<img id="ex_img" src="" />
<br />
<a id="ex_imglink" href="">画像</a>

<script>
var ctx = document.getElementById('ex_chart');

var data = {
    labels: ["1月", "2月", "3月", "4月", "5月"],
    datasets: [{
        label: '客数',
        data: [1200, 1350, 1220, 1220, 1420],
        borderColor: 'rgba(255, 100, 100, 1)',
        lineTension: 0,
        fill: false,
        borderWidth: 3
    }]
};

var options = {
    animation: {
        duration: 0
    }
};

var ex_chart = new Chart(ctx, {
    type: 'line',
    data: data,
    options: options
});

var image = ex_chart.toBase64Image();
//var image = document.getElementById('ex_chart').toDataURL();
document.getElementById('ex_img').setAttribute('src', image);
document.getElementById('ex_imglink').setAttribute('href', image);
</script>

HTML 部分は、canvas 要素にグラフ、img 要素に変換した画像、a 要素に画像へのリンクが表示される。

options にある animation の duration を 0(ゼロ)にしてアニメーションを禁止している。

画像化するには Chart.js にある toBase64Image() か、canvas 要素に適用できる toDataURL() を使う。 どちらを使っても良く、ここでは片方をコメントアウトしている。

Chart.js のグラフの画像化

アニメーション後に画像に変換

せっかくグラフがアニメーションするのに無効にするのはもったいないという場合は、アニメーション後に描画することもできる。 変更箇所だけ以下に記す。

var options = {
    animation: {
        onComplete: function(animation){
            var image = ex_chart.toBase64Image();
            //var image = document.getElementById('ex_chart').toDataURL();
            document.getElementById('ex_img').setAttribute('src', image);
            document.getElementById('ex_imglink').setAttribute('href', image);
        }
    }
};

最初のサンプルの画像化の部分を options の中に入れた。 グラフのアニメーション終了後に画像が表示される。

背景色を指定して透過させないようにする

上記2つのサンプルを動かすと分かるが、グラフの画像の背景色が透過してしまう。 その方が都合が良い場合もあるが、Twitter などに投稿すると透けてしまうので困る場合もある。 また、CSS で背景色を指定しても反映されない。 そこで Chart.js の Plugin で描画前に背景を塗る処理を入れる。

var ctx = document.getElementById('ex_chart');

Chart.plugins.register({
    beforeDraw: function(ch){
        var ctx = ch.chart.ctx;
        ctx.fillStyle = 'rgba(255, 255, 255, 1)';
        ctx.fillRect(0, 0, ch.chart.width, ch.chart.height);
    }
});

var data = {
    labels: ["1月", "2月", "3月", "4月", "5月"],
    datasets: [{
        label: '客数',
        data: [1200, 1350, 1220, 1220, 1420],
        borderColor: 'rgba(255, 100, 100, 1)',
        lineTension: 0,
        fill: false,
        borderWidth: 3
    }]
};

var options = {
    animation: {
        onComplete: function(animation){
            var image = ex_chart.toBase64Image();
            document.getElementById('ex_img').setAttribute('src', image);
            document.getElementById('ex_imglink').setAttribute('href', image);
        }
    }
};

var ex_chart = new Chart(ctx, {
    type: 'line',
    data: data,
    options: options
});

ここではグラフ全体の背景色に白を指定している。

このエントリーをはてなブックマークに追加