Railsアプリにいい感じのグラフを導入する
こんにちは。スバルです。
今回は、Railsアプリにいい感じのグラフを導入する方法を勉強します。
診断系のアプリで、結果画面にグラフが表示されてることって結構ありますよね。
図を表示
あれ、僕もやってみたかったんです。この前作ったアプリに実装してみました。
開発環境
手順
railsにいい感じにグラフを入れるためには、chart.jsというコードを使用する必要があります。
手順に倣って導入していきましょう。
まずは<head>タグの中にCDNを用意します。
# app/views/layout/application.html.erb
<script src="<https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js>"></script>
グラフを表示したいviewにcanvas idを設置します
app/views/optimes/_result.html.erb
<div class ="chart_area">
<canvas id="myChart"></canvas>
</div>
chart.js公式サイトにあるコードをコピーします。
<script>
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["赤", "青", "黄色", "緑", "紫", "橙"],
datasets: [{
label: '得票数',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
</script>
上記のdata:部分を改良させることで、診断結果とグラフを対応させることが出来ます。
表示される診断結果項目にspanタグをつけ、それぞれにclassを設定します。
<ul>
<li><p class="optime subtitle border-bottom" >睡眠時間</p><span class="optime__select"><%= optime.sleepy %></span>時間</li>
<li class="mb-4 comment"><%= good_sleep(optime)%></li>
<li><p class="optime subtitle border-bottom">勤務時間</p><span class="optime__select"><%=optime.work%></span>時間</li>
<li class="mb-4 comment"><%= good_work(optime)%></li>
<li><p class="optime subtitle border-bottom">食事時間</p><span class="optime__select"><%=optime.eat%></span>時間</li>
<li class="mb-4 comment"><%= good_eat(optime)%></li>
<li><p class="optime subtitle border-bottom">通勤時間</p><span class="optime__select"><%=optime.commute%></span>時間</li>
<li class="mb-4 comment"><%= good_commute(optime)%></li>
<li><p class="optime subtitle border-bottom">衛生管理時間</p><span class="optime__select"><%=optime.hygiene%></span>時間</li>
<li class="mb-4 comment"><%= good_hygiene(optime)%></li>
</ul>
そして、pタグに設定したoptimeクラスの配列一つ一つをDOM操作していきます。
<script>
//ページ内の科目を取得
var subject01 = document.querySelectorAll('.optime')[0].innerHTML,
subject02 = document.querySelectorAll('.optime')[1].innerHTML,
subject03 = document.querySelectorAll('.optime')[2].innerHTML,
subject04 = document.querySelectorAll('.optime')[3].innerHTML,
subject05 = document.querySelectorAll('.optime')[4].innerHTML,
//ページ内の数値を取得
subjectnum01 = document.querySelectorAll('.optime__select')[0].innerHTML,
subjectnum02 = document.querySelectorAll('.optime__select')[1].innerHTML,
subjectnum03 = document.querySelectorAll('.optime__select')[2].innerHTML,
subjectnum04 = document.querySelectorAll('.optime__select')[3].innerHTML,
subjectnum05 = document.querySelectorAll('.optime__select')[4].innerHTML;
dataを編集していきます。
//取得した科目と数値をChart.jsに入れる
var data = {
labels: [subject01, subject02, subject03, subject04, subject05],
datasets: [{
label: '可処分時間項目',
data: [subjectnum01, subjectnum02, subjectnum03, subjectnum04, subjectnum05],
backgroundColor: ['rgb(248, 252, 8)','rgb(162, 226, 89)','rgb(253, 237, 15)','rgb(228, 230, 141)','rgb(89, 226, 203)'],
borderColor: 'rgba(255,135,0,1)',
pointBackgroundColor: 'rgba(255,135,0,1)',
pointBorderColor: 'rgba(255,135,0,0)',
pointBorderWidth: 0,
pointRadius: 5,
pointStyle: 'circle',
pointHoverRadius: 5,
pointHitRadius: 5
}]
};
varで設定したdataを、グラフ上のdataに紐づけます。
<script>
//ページ内の科目を取得
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'doughnut',
typetype options: {
title: {
display: true,
text: '固定時間内訳',
padding: 4,
fontSize: 20
},
legend: {
text: '固定時間内訳',
display: false,
labels: {
fontColor: 'rgb(5, 99, 132)',
fontSize: 16
}
},
scale: {
pointLabels: {
fontSize: 15,
fontColor: 'rgb(0, 65, 112)',
padding: 20
},
ticks: {
beginAtZero: true,
}
},
layout: {
padding: {
left: 0,
right: 0,
top: 0,
bottom: 0
}
},
maintainAspectRatio: false,
}
});
</script>
実際に出来上がったview
<div class ="chart_area mp-3">
<canvas id="myChart" ></canvas>
</div>
<div class="text-center wrapper mb-3 mt-4">
<h2 class="text-center title" >固定時間削減方法</h2>
<ul>
<li><p class="optime subtitle border-bottom" >睡眠時間</p><span class="optime__select"><%= optime.sleepy %></span>時間</li>
<li class="mb-4 comment"><%= good_sleep(optime)%></li>
<li><p class="optime subtitle border-bottom ">勤務時間</p><span class="optime__select"><%=optime.work%></span>時間</li>
<li class="mb-4 comment"><%= good_work(optime)%></li>
<li><p class="optime subtitle border-bottom">食事時間</p><span class="optime__select"><%=optime.eat%></span>時間</li>
<li class="mb-4 comment"><%= good_eat(optime)%></li>
<li><p class="optime subtitle border-bottom">通勤時間</p><span class="optime__select"><%=optime.commute%></span>時間</li>
<li class="mb-4 comment"><%= good_commute(optime)%></li>
<li><p class="optime subtitle border-bottom">衛生管理時間</p><span class="optime__select"><%=optime.hygiene%></span>時間</li>
<li class="mb-4 comment"><%= good_hygiene(optime)%></li>
</ul>
</div>
</div>
//ページ内の科目を取得
var subject01 = document.querySelectorAll('.optime')[0].innerHTML,
subject02 = document.querySelectorAll('.optime')[1].innerHTML,
subject03 = document.querySelectorAll('.optime')[2].innerHTML,
subject04 = document.querySelectorAll('.optime')[3].innerHTML,
subject05 = document.querySelectorAll('.optime')[4].innerHTML,
//ページ内の数値を取得
subjectnum01 = document.querySelectorAll('.optime__select')[0].innerHTML,
subjectnum02 = document.querySelectorAll('.optime__select')[1].innerHTML,
subjectnum03 = document.querySelectorAll('.optime__select')[2].innerHTML,
subjectnum04 = document.querySelectorAll('.optime__select')[3].innerHTML,
subjectnum05 = document.querySelectorAll('.optime__select')[4].innerHTML;
//取得した科目と数値をChart.jsに入れる
var data = {
labels: [subject01, subject02, subject03, subject04, subject05],
datasets: [{
label: '可処分時間項目',
data: [subjectnum01, subjectnum02, subjectnum03, subjectnum04, subjectnum05],
backgroundColor: ['rgb(248, 252, 8)','rgb(162, 226, 89)','rgb(253, 237, 15)','rgb(228, 230, 141)','rgb(89, 226, 203)'],
borderColor: 'rgba(255,135,0,1)',
pointBackgroundColor: 'rgba(255,135,0,1)',
pointBorderColor: 'rgba(255,135,0,0)',
pointBorderWidth: 0,
pointRadius: 5,
pointStyle: 'circle',
pointHoverRadius: 5,
pointHitRadius: 5
}]
};
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'doughnut',
data: data,
options: {
title: {
display: true,
text: '固定時間内訳',
padding: 4,
fontSize: 20
},
legend: {
text: '固定時間内訳',
display: false,
labels: {
fontColor: 'rgb(5, 99, 132)',
fontSize: 16
}
},
scale: {
pointLabels: {
fontSize: 15,
fontColor: 'rgb(0, 65, 112)',
padding: 20
},
ticks: {
beginAtZero: true,
}
},
layout: {
padding: {
left: 0,
right: 0,
top: 0,
bottom: 0
}
},
maintainAspectRatio: false,
}
});
それでは、試してみましょう。
グインって感じでグラフが実装できましたね。
ちなみに、 type: 'doughnut',の部分を変えるだけで様々なグラフに変化させることができます。
type: 'radar'
type: 'pie'
type: 'bar'