はじめに
お仕事でグラフを表示するページを作ることがあったので、まぁSVGとかで頑張って描画してもよかったのですが、いくつか要求仕様があったので、せっかくなら便利でオシャレなグラフツールでもないかな~と思って探したところに出てきたのがChart.js。
これを使ってみたところ、見た目もアニメーションもなんだかかわいくてとてもよい!
ところが、グラフの背景に色をつけたいな~と思って背景色設定のプロパティを探したところ、どうやらbackground-color: 'white';
みたいに1行で背景色が設定できる便利機能はないことが分かりました。
グラフの領域を目立たせたりデザインをよくしたり、背景色を変えるモチベーションは多いと思ったのでデフォルトで設定機能がないのは意外だったのですが、実装にちょっと苦労したので共有。
Chart.jsについて
私が使用したChart.jsのバージョンは、3.7.0 です。
今回はChart.jsの基本的なグラフ作成方法の説明は省略します。
(※ Chart.jsは2系と3系で書き方が異なる部分もありますので、お使いのバージョンにご注意ください!)
Chart.js公式ドキュメントはこちら(Chart.js 3.7.0)。
特に、この記事を書いている途中でやっと発見したのですが、こちら(Canvas background)に背景の描画方法がちゃんと載っていました。
ドキュメント検索能力もまだまだ未熟です笑
グラフ作成
まずは事前準備として簡単なグラフを作成します。
例として折れ線グラフを作ります。
とりあえずHTMLにはcanvasを用意。
<canvas id="my_graph" ></canvas>
次にjavascriptでチャートを作成していきます。
// ラベルとデータ
let label_list = ['09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00']
let data_list = [100, 120, 130, 100, 98, 124, 80, 85, 113, 97]
// データのプロパティ
let set = [{
data: data_list, // プロットするデータ
lineTension: 0, // 線のベジェ曲線の張力(直線は0を設定)
borderWidth: 2, // 折れ線の太さ
borderColor: "skyblue", // 折れ線の色
backgroundColor: "blue", // プロットの塗りつぶし色
}];
let ctx = document.getElementById('graph').getContext('2d');
let myChart = new Chart(ctx, {
plugins: [{
// のちほどここに背景色を描画するプラグインが入ります。
}],
type: 'line',
data: {
labels: label_list,
datasets: set,
},
options: {
scales: {
y: {
min: 0,
max: 200,
},
},
plugins: {
legend: {
display: false, // 凡例は非表示
},
},
},
});
(※new Chart()
は変数に格納する必要はないのですが、説明の便宜上変数を用意しています。)
これで以下のような折れ線グラフが描画できました。
かわいい!
背景色の描画方法
先に結論を書きます。
上で示したmyChart
のpluginsについて、以下のように「beforeDraw」に背景色を描画するための関数(適当にdrawBackground
とする)を設定します。
plugins: [{
beforeDraw: drawBackground
}],
drawBackgroundは以下のように定義します。
function drawBackground(target) { // 引数はmyChart自身とされる。
let x_scale = target.scales.x; // x軸プロパティ取得
let y_scale = target.scales.y; // y軸プロパティ取得
let left = x_scale.left; // x軸の左端座標取得
let top = y_scale.top; // y軸の上端座標取得
let width = x_scale.width; // x軸の幅取得
let heigh = y_scale.height; // y軸の高さ取得
var cvs = document.getElementById(target.canvas.id); // もちろん'my_graph'で直接指定してもOK
var ctx = cvs.getContext('2d');
// プロット領域に重なるように、背景色の四角形を描画
ctx.fillStyle = "dimgray"; // 背景色(今回は濃いグレー)
ctx.fillRect(left, top, width, height); // 四角形描画
}
これで、以下のようにプロット領域に背景色をつけることができました!
(色合いのセンスが抜群に悪いのは不問としてください)
解説
今回の概要を説明すると、Chart.jsで描画するグラフはデフォルトだと背景透過のため、プラグインでプロット領域にちょうど重なるように色の付いた四角形を先に描画した、ということです。
drawBackground
の定義でいきなりtarget
とかいう引数が急に登場しますが(もちろん引数名はtargetでなくても何でもよい)、このようにプラグインのbeforeDrawで引数を設定すると、myChart自身が入る仕様になっています。
実際にmyChart
とtarget
をそれぞれコンソールに出力してみると同じものだということが分かります。
その中身をちょいと覗いてみると、
といった感じで自分の作ったチャートのプロパティが入っており、赤枠で囲ったようにx軸・y軸のプロパティも格納されています。
そこで更にこのmyChart.scales.x
を開いてみると、x軸左端の座標left
、幅width
が入っています。
同様にmyChart.scales.y
には、y軸上端の座標top
や高さheight
が入っています。
これらによって、背景色を塗りたいプロット領域の左上の座標、および幅・高さが以下の図のようなイメージで取得できるので、あとはその通りに四角形を描画してあげれば背景色として見えるわけです。
ここまでわかれば、プロット領域に限らず、特定の領域だけ背景色を置いたり、軸上にまで背景色を拡大させることもできるなーとわかります。
適当にdrawBackground
の四角形描画を変更するとこんな感じ。
context.fillRect(left-50, top-10, width+10, height+30);
これで背景色描画の自由度があがりましたね!
おまけ
実はこちら(Canvas background)にも書いてあるように、CSSで背景色を付けるのが最も簡単な方法のようなのですが、どうやら画像保存などをするときにその背景色が反映されない問題があるようです。
今回の方法であればその問題はクリアするため、まぁ程度問題ではありますが今回の内容の方が汎用性のある推奨方法なのだと思います。
まとめ
今回はタイトルこそChart.jsで「グラフの背景色を設定する方法」でしたが(検索するならこういうキーワードになると思ったため)、実際には「グラフの背景にうまく四角形を書いて背景色っぽく見せる方法」を紹介しました。
そしてこれが現時点で公式の方法のようですが、もしかしたらそのうち1行で簡単に設定できるようになるのかも知れませんね。
Chart.js、かわいいので皆さんもぜひお試しください!