LoginSignup
15
13

More than 3 years have passed since last update.

Chart.jsに背景を入れる方法

Last updated at Posted at 2019-04-29

はじめに

棒グラフ・折れ線グラフをはじめ、様々なグラフを簡単に描画できるChart.js。
設定をすればカスタマイズも可能です。しかしこのモジュールには重大な欠点が...

ずばり、グラフに背景を入れることができない!!!
プラグインを使わないとすれば、自分でcanvasに描画するしかないんです。

プラグインを増やしたくないという方に向けに、canvas情報の取得・操作の方法を書き残します。

動作環境

  • HTML 5
  • CSS 3
  • jQuery 3.3.1
  • Chart.js 2.8.0

準備

ここはできること前提なので簡単な説明のみとします。

まずはグラフを描画するための場所作り。bodyタグにcanvasタグ作ります。

bodyタグ
<body>
    <canvas id="temperatureChart"></canvas>
</body>

今回は折れ線グラフを描画。jQueryとchart.jsの読み込みをして、最低限の設定をします。

scriptタグ
<script src="https://ajax.googleapis.com/ajax/libs/jquery/x.x.x/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script type="text/javascript">
$(function() {

    var config = {
        type: "line",
        data: {
            labels: ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],
            datasets: [{
                label: "最高気温",
                lineTension: 0,
                borderColor: "#000000",
                fill: false,
                data: [9.6, 10.4, 13.6, 19.0, 22.9, 25.5, 29.2, 30.8, 26.9, 21.5, 16.3, 11.9]
            }]
        },
        options: {
            scales: {
                yAxes: [{
                    ticks: {
                        min: -5,
                        max: 35
                    }
                }]
            }
        }
    };
    var ctx = $("#temperatureChart").get(0).getContext("2d");
    var lineChart = new Chart(ctx, config);    
});
</script>

これで準備はOKですね。
年間の気温を表すグラフが出来上がり。

graph1.png

背景の描画

ここからが本題になります。
やっていることは、canvas情報を取得してcanvas操作をしています。

まず、背景描画のための関数を用意します。引数targetにはcanvasの情報(変数ctx)が入ります。target.scalesの中にはキャンバスに描画されるものの情報が入っています。例えば、target.scales["x-axis-0"].getPixelForValue("3月")で3月のx座標を取得できます。
情報が取れたらfillStylefillRect()を使って四角形を描画します。

以下のdrawBackground()は必要な座標情報を取得し、canvasの操作をしている関数です。

drawBackground()
function drawBackground(target) {
    var xscale = target.scales["x-axis-0"];
    var yscale = target.scales["y-axis-0"];
    var left = xscale.left;
    var high_top = yscale.getPixelForValue(35);
    var high_height = yscale.getPixelForValue(25) - high_top; // 夏日
    var low_top = yscale.getPixelForValue(0);
    var low_height = yscale.getPixelForValue(-5) - low_top;   // 真冬日

    // 赤い範囲
    ctx.fillStyle = "rgba(255, 0, 100, 0.2)";
    ctx.fillRect(left, high_top, xscale.width, high_height);

    // 青い範囲
    ctx.fillStyle = "rgba(0, 100, 255, 0.2)";
    ctx.fillRect(left, low_top, xscale.width, low_height);
}

ここまで出来たら完成も同然です。
先ほど定義したconfigpluginsを追加し、beforeDrawで呼び出します。

var config = {
    plugins: [{
        beforeDraw: drawBackground
    }],
    // 以下省略
}

はい、完成!!!

graph2.png

背景はcanvasに四角形を描画しているだけなので、画像を入れることも可能ですね。

補足

options.animation.onCompleteで先ほど作った関数を呼び出してしまうと、グラフの上に背景を描画してしまうので注意が必要です。
逆に言えば、背景ではなくグラフの上に何かを描画したい場合はonCompleteの方が良いですね。

15
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
13