Webサイトのデータ量が多いときは、データを見やすくするための方法を見つけなければなりません。なんだかんだと、人間は数値データの長いリストを理解するのが得意ではありません。
そこで、チャートやグラフが役に立ちます。チャートやグラフを使えば、 複雑な統計関連のデータが分かりやすく直観的に理解できるようになるのはもちろんのこと、英語を話さない人でも利用可能になります。基本的なチャートであればみな同じスピードで理解できますが、専門用語が散りばめられた文章ではそうはいきません。 必要に応じてチャートを使えば、Webサイトは理解しやすくなり、見た目ももっと魅力的になります。
本記事ではChart.jsと呼ばれるJavaScriptのチャートライブラリーを紹介します。6つのスタイリッシュな事例を挙げ、Chart.jsを使ってWebサイト上でのデータビジュアライゼーションの方法やニーズを満たすための設定について説明します。
Chart.jsを使う理由
Chart.jsを選択した理由は、簡単に習得して利用できるからです。Chart.jsは容易さを念頭に置いて設計されていますが、カスタマイズ性にも優れています。経験上、チャートライブラリーは複雑な領域にあり、ライブラリーが複雑であればカスタマイズ範囲がより広がりますが、習得するのは容易です。Chart.jsはもっともすばやく簡単に習得できるライブラリーの1つであり、選択肢をあまり制限しません。8つの異なるタイプのチャートが用意されており、データで必要なことの大部分をカバーします。
Chart.jsは積極的なオープンソースコミュニティによって高水準で維持されています。先日バージョン2.0が公開されたましたが、いくつかの基本構文が変更されました。コードの一貫性が高まり、モバイルのサポートが提供されています。この記事では、Chart.js 2.0とその新しい構文を使用します。Chart.js 2.0の使い方の説明のあとに、1.0から2.0への移行や、オンラインにおけるChart.jsの古い事例を見てなにが起こるかを説明するセクションを記事の最後に設けています。
Chart.jsのインストール
繰り返しになりますが、Chart.jsは簡単に使えることを目的としています。習得しやすく、利用しやすく、さらにインストールが容易です。実際のコードを試したい場合は、GitHub projectをチェックしてください。
Chart.jsを使うのに必要なものは2つだけです。
- ライブラリー:立ち上げが容易で速く動作するため、CDNの使用を推奨
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js"></script>
- <canvas>要素:Chart.jsがHTML5のキャンバスを使用するため
<canvas id="myChart"></canvas>
また、ライブラリーをダウンロードするのにパッケージマネージャーを使用できます。詳細については、Getting Startedガイドを参照してください。
シンプルだと思いませんか? さあ前置きはこれくらいにして、Chart.jsの実際について説明します。
折れ線グラフ
最小限の折れ線グラフをChart.jsで作るのに必要なものはこれだけです。HTML5 Canvasを宣言したあとに、<body>の中のどこかで、次のコードを<script></script>内に記述するだけです。
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['M', 'T', 'W', 'T', 'F', 'S', 'S'],
datasets: [{
label: 'apples',
data: [12, 19, 3, 17, 6, 3, 7],
backgroundColor: "rgba(153,255,51,0.4)"
}, {
label: 'oranges',
data: [2, 29, 5, 5, 2, 3, 10],
backgroundColor: "rgba(255,153,0,0.4)"
}]
}
});
このコードが難しく見えたとしても大丈夫です! Chart.jsのコードは、ほとんどの部分が、上のフォーマットに従っています。では、1行ごとになにが起こっているのか説明していきます。
var ctx = document.getElementById("myChart").getContext('2d');
この行では事前に生成した<canvas>要素への参照を取得し、getContextメソッドを呼び出します。getContextメソッドはキャンバス上に描画するためのメソッドとプロパティを提供するオブジェクトを返します。これをctxという名前の変数に格納します。
var myChart = new Chart(ctx, {
type: 'line',
data: // array of line data goes here
});
これが作成したチャートオブジェクトです。typeプロパティに集中するためdataを省略しました。typeプロパティは必要なチャートのタイプを決定します。Chart.jsのnew Chart()コンストラクターは以下の2つのパラメーターを取得します。
- チャートがレンダリングされる<canvas>要素への参照または2次元描画コンテキストへの参照(ここでは2d contextを使用)。どちらを使っても、Chart.jsの規則によってctxが呼び出される
- Chart.jsがチャートをビルドするために使用する、データや構成オプションを含むオブジェクトリテラル。要求されるプロパティはtypeおよびdata。例では折れ線グラフを作成したいので、typeに「line」を指定している。dataはチャートを追加するのに使われるデータ
Chart.jsはグラフの位置を決めるのに配列の位置を使用します。 「apples」の最初の点では値「12」を保持し、2番目の点では「19」を保持し、そのあとも同様になります。新しい行を追加するのは、labelやdataに新しいオブジェクトを追加するのと同じくらい簡単です。
最後にrgbaの背景色を各データに設定して、もっと視覚に訴えるようにします。
Chart.jsの折れ線グラフの詳細については、 このドキュメントを参照してください。
コツ:チャートの任意の凡例(ここでは「Apples」や「Oranges」)をクリックすると、特定のデータセットが切り替わります。これはすべてのタイプのチャートで動作します。
棒グラフ
棒グラフは見た目が少し違う折れ線グラフのようなものです。前に挙げた例から1行変更すれば、棒グラフを生成できます。
type: 'line'
を以下に変更してください。
type: 'bar'
とても簡単です。
棒グラフに関するドキュメント全体はここにあります。
例の棒グラフのコードは以下のようになります。
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["M", "T", "W", "R", "F", "S", "S"],
datasets: [{
label: 'apples',
data: [12, 19, 3, 17, 28, 24, 7]
}, {
label: 'oranges',
data: [30, 29, 5, 5, 20, 3, 10]
}]
}
});
レーダーチャート
レーダーチャートは私のお気に入りのタイプで、これも折れ線グラフや棒グラフの仲間です。レーダーチャートは、直線ではなく放射状のX軸に対する折れ線グラフのようなものです。簡単にレーダーチャートを作るには、以下のように変更します。
type: 'bar'
を以下に変更してください。
type: 'radar'
なぜこのようにするかと言われても、これがChart.jsの流儀だからです。
あいにく、結果は少し不格好で読み取りにくいです。棒グラフは重なり合わないので、一色で塗りつぶすのが有効です。しかし、レーダーチャートは重なり合うので、これには当てはまりません。backgroundColorの透明度の値を調整したり、borderColorを追加したりすることで対応できます。
{
label: 'apples',
backgroundColor: "rgba(179,11,198,.2)",
borderColor: "rgba(179,11,198,1)",
data: [12, 19, 3, 17, 6, 3, 7]
}
上のように記述すると背景が透過し、重なった箇所が見やすくなります。
レーダーチャートの詳細については、このドキュメントを参照してください。
例のレーダーチャートのコードは以下のようになります。
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'radar',
data: {
labels: ["M", "T", "W", "T", "F", "S", "S"],
datasets: [{
label: 'apples',
backgroundColor: "rgba(153,255,51,0.4)",
borderColor: "rgba(153,255,51,1)",
data: [12, 19, 3, 17, 28, 24, 7]
}, {
label: 'oranges',
backgroundColor: "rgba(255,153,0,0.4)",
borderColor: "rgba(255,153,0,1)",
data: [30, 29, 5, 5, 20, 3, 10]
}]
}
});
ポーラーチャート
ポーラーチャートでは、各データポイントで等量の放射状の空間が得られます。より大きな値を持つセグメントはグラフの中心から離れた場所に広がっていきます。この項ではapplesデータセットのポーラーチャートについて説明します。
これまでと同様に、ポーラーチャートはたった1行で指定できます。変更箇所は以下のとおりです。
type: 'radar'
を以下に変更してください。
type: 'polarArea'
しかしポーラーチャートは、これまで説明してきたグラフとは異なり、2つのデータセットの比較に使用できないグラフです。前述の折れ線グラフと棒グラフの例は2つの同じ長さの配列を対比する異なる手法でしたが、ポーラーチャート(および次に説明する円グラフ)は1つの数値グループを視覚化するのみです。
例のポーラーチャートのコードは以下のようになります。
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'polarArea',
data: {
labels: ["M", "T", "W", "T", "F", "S", "S"],
datasets: [{
backgroundColor: [
"#2ecc71",
"#3498db",
"#95a5a6",
"#9b59b6",
"#f1c40f",
"#e74c3c",
"#34495e"
],
data: [12, 19, 3, 17, 28, 24, 7]
}]
}
});
新しいコードはbackgroundColor配列のみです。 各色は同じインデックスのdata要素に適合します。
ポーラーチャートの詳細については、このドキュメントを参照してください。
円グラフとドーナツグラフ
おそらくこのパートについてもすぐに推測できると思いますが、変更箇所は以下のとおりです。
type: 'polarArea'
を以下に変更してください。
type: 'pie'
typeプロパティはChart.jsの鍵となります。折れ線グラフを棒グラフやレーダーチャートに変更するのがとても簡単だったのを覚えていますか? ポーラーチャート、円グラフ、ドーナツグラフも同様に互いに変更可能です。たった1つの変更で、ポーラーチャートを円グラフに変更できます。
また、ドーナツグラフの場合は以下のとおりです。:
type: 'pie'
を以下に変更してください。
type: 'doughnut'
円グラフとドーナツグラフの詳細については、このドキュメントを参照してください。
円グラフのコードは以下のようになります。
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ["M", "T", "W", "T", "F", "S", "S"],
datasets: [{
backgroundColor: [
"#2ecc71",
"#3498db",
"#95a5a6",
"#9b59b6",
"#f1c40f",
"#e74c3c",
"#34495e"
],
data: [12, 19, 3, 17, 28, 24, 7]
}]
}
});
ドーナツグラフには中心の穴の大きさを指示する、cutoutPercentageと呼ばれるおもしろいプロパティが存在します。cutoutPercentageを掘り下げる前に、基本的なチャートのタイプを早く理解するために、これまでスキップしてきたChart.jsに関する事項について説明する必要があります。
Chart.jsの設定
これまでの各例では、以下のフォーマットを使用してきました。
var myChart = new Chart(ctx, {
type: //chart type,
data: // chart data
});
しかし、optionsと呼ばれる3つ目のプロパティが存在し、dataのすぐ下にあります。
var myChart = new Chart(ctx, {
type: //chart type,
data: // chart data,
options: // chart options
});
すでにChart.jsの基礎について理解しているはずなので、ここからはoptionsで利用可能ないくつかの方法について説明していきます。
タイトル
このoptionsのセットを追加すれば、簡単に任意のChart.jsチャートにタイトルが追加できます。ネイティブのタイトルもすばらしいのですが、たいていは固定で変更不可であり意味がありません。すぐにカスタムイベントを追加したい場合、これは問題となります。
options: {
title: {
display: true,
text: 'Custom Chart Title'
}
}
ドーナツの穴
cutoutPercentageプロパティは0から50までの値を取ります。円グラフはcutoutPercentageが0のドーナツグラフだということになります。
options: {
cutoutPercentage: 10,
}
積み上げ棒グラフ
積み上げの棒グラフを使用したければ、以下のoptionsのセットを棒グラフのコードに追加するだけです。
options: {
scales: {
yAxes: [{
stacked: true
}]
}
}
チャートのタイプごとに、より機能を使いこなすためのオプションが豊富に用意されています。ぜひそれらを活用してください。
イベントのハンドリング
前述のとおり、凡例の上でクリックすると特定の凡例に関連付けられたデータセットが切り替わります。これに関して、独自の機能を実装しながら議論していきましょう。
var original = Chart.defaults.global.legend.onClick;
Chart.defaults.global.legend.onClick = function(e, legendItem) {
// Insert your custom functionality here
original.call(this, e, legendItem);
};
このコードによって凡例項目のonClick関数への参照をoriginalと呼ばれる変数に保存します。そのあと、独自にカスタマイズされたバージョンでonClick関数を上書きします。それに渡されるeパラメーターは、その関数を動作させるきっかけとなるクリックイベントへの参照であり、legendItemパラメーターはクリックされた凡例への参照です。独自のコードの追加が終わったら、thisの値を指定するオリジナルの関数を呼び出して、期待されるパラメーターを通じて引き渡します。この結果、凡例をクリックするとデフォルトの動作(データセットが切り替わる)が実行されます。
要するに、original.call()の前に設置しさえすれば、好きな機能をなんでもonClick()呼び出しの上に追加できるということです。
具体例
ユーザーが凡例をクリックしたときにチャートの下部のキャプションを自動で更新できるように、前述のコードに付け加えます。
キャプションを変更するだけですが、好きな機能の追加もできます。たとえば、ダッシュボードで毎日のapples、orangesの値を保持できます。また、そのダッシュボードで、カスタムコールバックを利用した、チャートの状態に基づく動的更新も可能です。Chart.jsでインタラクティブなデータを生成するのは容易です。
これがそのコードです。
var labels = {
"apples": true,
"oranges": true
};
var caption = document.getElementById("caption");
var update_caption = function(legend) {
labels[legend.text] = legend.hidden;
var selected = Object.keys(labels).filter(function(key) {
return labels[key];
});
var text = selected.length ? selected.join(" & ") : "nothing";
caption.innerHTML = "The above chart displays " + text;
};
見てのとおり、オブジェクトリテラルを使用して凡例の状態を記録します。また、legend.text、legend.hiddenプロパティを利用してその状態を更新します。filter関数はキャプションのビルドに用いるtrueの値を持つすべてのオブジェクトキーを返します。
Chart.js 2.0 vs 1.0
この記事ではChart.js 2.0の構文を使用しました。Chart.js 2.0は2016年にリリースされた比較的新しいバージョンです。2.0と1.0のもっとも大きく異なる点はチャートの宣言の仕方です。
1.0
var LineChartDemo = new Chart(ctx).Line(
//data here,
//options here
);
2.0
var myChart = new Chart(ctx, {
type: 'line',
data: //data here,
options: //options here
}
バージョン1.0では特定のタイプのチャートを生成するのに関数チェーンを使用して、それからデータやオプションを渡すようにしています。これに対してバージョン2.0では、ユーザーが一般的なチャートオブジェクトを生成し、そのあとタイプやデータ、オプションを渡せるようになっています。2.0でのアプローチは極力モジュール式の個別の構成になっており、よりChart.jsの理念に合致していると言えます。Chart.js 2.0は1.0との互換性を保っているので、1.0の構文を受け取れることは知っておくとよいでしょう。
Chart.js 2.0の主要な特徴はモバイルのサポートです。いまではChartsはモバイル画面に対応し、モバイルブラウザー上のタッチイベントを扱います。現在のモバイル端末の流行を見ると、これは2016年のWebサイトでは必須の機能だと言えます。
2.0のもう1つの新しい機能は、本ガイドでも使用したtitleです。Chartsは現在、添付されたチャートと連携する統合されたタイトルを備えています。
更新箇所全体のリストは2.0.0リリースノートで確認できます。
最後に
Chart.jsは単純なチャートをすばやく試作するのに最適です。8つの主要なチャートタイプが存在し、その中のline、bar、radar、polarArea、pie、doughnutについて説明しました。これらの多様なチャートによって、データビジュアライゼーションのもっとも一般的な方法がカバーされます。つまり、Chart.jsはおそらく次のプロジェクトで必要とする唯一のグラフィックスライブラリーとなります。
Chart.jsに関してもっと知りたければ、Chart.jsサイトにあるドキュメントがとてもおすすめです。
※本記事はTim Severien、Simon Codringtonが査読を担当しています。最高のコンテンツに仕上げるために尽力してくれたSitePointの査読担当者のみなさんに感謝します。
(原文:An Introduction to Chart.js 2.0 — Six Simple Examples)
[翻訳:市川千枝/編集:Livit]