2018/10/26
Django フロントエンド手軽に綺麗なデザイン!グラフを簡単に実装できるChart.js の使い方
今日は、とっても手軽にグラフを実装できてしまうChart.jsを紹介します。
使い方が簡単で、しかもいろんな種類のチャートがサクッと表示できるので、覚えておくととても便利です。
後半では、Djangoのモデルから情報を取得して、複数のデータを比較する例もご紹介します。
どんな種類のチャートがある?
Chart.jsの公式ページにあるサンプル一覧ページから、どんなチャートがあるかを確認できます。綺麗なデザインで動きもあるので、視覚的にもインパクトがありますね。
Chart.jsの導入方法
では、実際にChart.jsを導入して、表示してみましょう。導入手順はとてもシンプルです。
<head>
タグでchart.jsを読み込む- チャートを表示させたいところに
<canvas>
タグを記述する <script>
タグ内で表示するチャートに必要な情報を定義する
1. タグでchart.jsを読み込む
index.html
<!DOCTYPE html>
<html>
<head>
<title>Chart.jsを使うページ</title>
<!-- Chart.jsを読み込む -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
</head>
<body>
</body>
</html>
これでChart.jsの機能が使えるようになりました。今回はCDNで読み込みましたが、npmやBowerからインストールして使用することもできます。詳しくはこちらのページで。
2. チャートを表示させたいところに<canvas>
タグを記述する
次にbodyの中にcanvasタグを追加しましょう。ここにチャートが表示されることになります。タグには、idを追加しておきます。
index.html
<!DOCTYPE html>
<html>
<head>
<title>Chart.jsを使うページ</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js">
</script>
</head>
<body>
<!-- 追加 -->
<canvas id="radar-chart" height="70px"></canvas>
</body>
</html>
<script>
タグ内で表示するチャートに必要な情報を定義する
最後に、<script>
タグ内でチャートに必要な情報を定義します。まずはシンプルに、必要最低限の情報だけを与えましょう。
index.html
<!DOCTYPE html>
<html>
<head>
<title>Chart.jsを使うページ</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
</head>
<body>
<canvas id="radar-chart" height="70px"></canvas>
<script type="text/javascript">
/* idが"radar-chart"の要素を取得 */
var ctx = document.getElementById("radar-chart");
/* 上記要素にチャートを描画 */
var myRadarChart = new Chart(ctx, {
type: 'radar',
data: {
labels: ['国語', '算数', '理科', '社会', '英語'],
datasets: [{
label: "Aさん",
data: [65, 76, 87, 75, 90]
}]},
});
</script>
</body>
</html>
type='radar'
とすることで、レーダーチャートが作られます。そして、dataプロパティの中で、各種設定をしていきます。labelsの個数は自由に変更できますが、dataはそれに対応した個数を指定する必要があります。
dataプロパティ内の設定方法は、チャートの種類によって微妙に違いますので、詳しい設定方法はこちらのページから自分の使用するチャートのページを確認してください。
ここまでの設定で、こんなレーダーチャートを表示することができます。とても便利ですね。
デフォルトのままだとちょっと地味なので、以下のように色などを加工してみましょう。色はCSSと同じ感じでカラーコードなどで指定します。また、以下の例ではdatasetsを2つにすることで、双方を比較しています。
index.html
<script type="text/javascript">
var ctx = document.getElementById("radar-chart");
var myRadarChart = new Chart(ctx, {
type: 'radar',
data: {
labels: ['国語', '算数', '理科', '社会', '英語'],
datasets: [
{ label: "Aさん",
data: [65, 76, 87, 75, 90],
backgroundColor: 'rgba(255, 99, 132, 0.6)',
borderColor: 'rgba(255, 99, 132, 0.9)',
pointBackgroundColor: 'rgba(255, 99, 132, 0.9)',
pointBorderColor: 'rgba(255, 99, 132, 1)',
borderWidth: 3,
pointRadius: 3,
},{
label: "全国平均",
data: [75, 86, 84, 65, 89],
backgroundColor: 'rgba(0, 0, 255, 0.6)',
borderColor: 'rgba(0, 0, 255, 0.9)',
pointBackgroundColor: 'rgba(0, 0, 255, 0.9)',
pointBorderColor: 'rgba(0, 0, 255, 1)',
borderWidth: 3,
pointRadius: 3,
}]}
});
</script>
ここまでで、だいぶ見栄えがよくなりましたがより詳細な設定をしたい時はoptionsプロパティを使います。以下は optionsプロパティを使った一例です。
index.html
<script type="text/javascript">
var ctx = document.getElementById("radar-chart");
var myRadarChart = new Chart(ctx, {
type: 'radar',
data: {
labels: ['国語', '算数', '理科', '社会', '英語'],
datasets: [
{ label: "Aさん",
data: [65, 76, 87, 75, 90],
backgroundColor: 'rgba(255, 99, 132, 0.6)',
borderColor: 'rgba(255, 99, 132, 0.9)',
pointBackgroundColor: 'rgba(255, 99, 132, 0.9)',
pointBorderColor: 'rgba(255, 99, 132, 1)',
borderWidth: 3,
pointRadius: 3,
},{
label: "全国平均",
data: [75, 86, 84, 65, 89],
backgroundColor: 'rgba(0, 0, 255, 0.6)',
borderColor: 'rgba(0, 0, 255, 0.9)',
pointBackgroundColor: 'rgba(0, 0, 255, 0.9)',
pointBorderColor: 'rgba(0, 0, 255, 1)',
borderWidth: 3,
pointRadius: 3,
}]},
options : {
animation: { duration: 2000 },
legend: { display: false },
scale: {
ticks: {
min: 50,
max: 100,
stepSize: 10,
backdropColor: 'rgba(255, 255, 255, 0)',
}}}
});
</script>
今回の例では、optionsでアニメーションの速度を変えたり、凡例を非表示にしています。ticksプロパティでは、メモリについての設定をしています。最低値50、最高値100、メモリ幅10という設定をした上で、メモリの背景色は透明にしています。
この他にも細かい設定は可能ですので、公式リファレンスを見てみてくださいね。
Djangoでの使用例
最後におまけとして、Djangoで使う場合のサンプルコードを紹介します。やっていることは上とほとんど同じで、Viewから渡ってきた数値をdataプロパティに渡してあげるだけです。
2人の生徒の成績を比較するという前提でつくります。
models.py
from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator
class Person(models.Model):
name = models.CharField(max_length=100)
japanese = models.IntegerField('国語', validators=[MinValueValidator(0), MaxValueValidator(100)])
math = models.IntegerField('算数', validators=[MinValueValidator(0), MaxValueValidator(100)])
science = models.IntegerField('理科', validators=[MinValueValidator(0), MaxValueValidator(100)])
social = models.IntegerField('社会', validators=[MinValueValidator(0), MaxValueValidator(100)])
english = models.IntegerField('英語', validators=[MinValueValidator(0), MaxValueValidator(100)])
DBはこんなイメージになります。
views.py
from django.shortcuts import render
from .models import Person
def index(request):
person1 = Person.objects.get(id=1)
person2 = Person.objects.get(id=2)
return render(request, 'app/index.html', {'person1':person1, 'person2':person2})
viewsから渡ってきたperson1、person2の情報を渡す。
index.html
<!DOCTYPE html>
<html>
<head>
<title>Chart.jsを使うページ</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
</head>
<body>
<canvas id="radar-chart" height="70px"></canvas>
<script type="text/javascript">
var ctx = document.getElementById("radar-chart");
var myRadarChart = new Chart(ctx, {
type: 'radar',
data: {
labels: ['国語', '算数', '理科', '社会', '英語'],
datasets: [
{ label: "{{ person1.name }}",
data: ['{{ person1.japanese }}', '{{ person1.math }}', '{{ person1.science }}', '{{ person1.social }}', '{{ person1.english }}'],
backgroundColor: 'rgba(255, 99, 132, 0.6)',
borderColor: 'rgba(255, 99, 132, 0.9)',
pointBackgroundColor: 'rgba(255, 99, 132, 0.9)',
pointBorderColor: 'rgba(255, 99, 132, 1)',
borderWidth: 3,
pointRadius: 3,
},{
label: "{{ person2.name }}",
data: ['{{ person2.japanese }}', '{{ person2.math }}', '{{ person2.science }}', '{{ person2.social }}', '{{ person2.english }}'],
backgroundColor: 'rgba(0, 0, 255, 0.6)',
borderColor: 'rgba(0, 0, 255, 0.9)',
pointBackgroundColor: 'rgba(0, 0, 255, 0.9)',
pointBorderColor: 'rgba(0, 0, 255, 1)',
borderWidth: 3,
pointRadius: 3,
}]},
options : {
scale: {
ticks: {
min: 50,
max: 100,
stepSize: 5,
backdropColor: 'rgba(255, 255, 255, 0)',
}}}
});
</script>
</body>
</html>
表示されるグラフはこんな感じです。