【Rails】chart.jsを使った投稿数のグラフ化
本の投稿サイトに、chart.jsを使って、投稿数をグラフ化させます!
前回の続きです。
実装要件
- 過去7日間分、それぞれの投稿数を一覧表示させる
- chart.jsを使って、過去7日分の投稿数のグラフ化
完成イメージ
1. 投稿数の一覧表示
2. chart.jsを使ったグラフ化
1. 投稿数の一覧表示
では投稿数の一覧表示からやっていきます。
モデル記述
bookモデルにメソッドを記載する。
scope :created_today, -> { where(created_at: Time.zone.now.all_day) } # 今日
scope :created_yesterday, -> { where(created_at: 1.day.ago.all_day) } # 前日
scope :created_2day_ago, -> { where(created_at: 2.day.ago.all_day) } # 2日前
scope :created_3day_ago, -> { where(created_at: 3.day.ago.all_day) } # 3日前
scope :created_4day_ago, -> { where(created_at: 4.day.ago.all_day) } # 4日前
scope :created_5day_ago, -> { where(created_at: 5.day.ago.all_day) } # 5日前
scope :created_6day_ago, -> { where(created_at: 6.day.ago.all_day) } # 6日前
コントローラ記述
今回はユーザー詳細ページに表示させるため、ユーザーコントローラから呼び出してあげます。
def show
@user = User.find(params[:id])
@books = @user.books
@book = Book.new
@today_book = @books.created_today
@yesterday_book = @books.created_yesterday
@this_week_book = @books.created_this_week
@last_week_book = @books.created_last_week
end
ビュー記述
分かりやすい書き方だと以下の通り書くことができます。
<h4>7日間分の投稿数</h4>
<table class='table table-bordered'>
<thead>
<tr>
<th>6日前</th>
<th>5日前</th>
<th>4日前</th>
<th>3日前</th>
<th>2日前</th>
<th>1日前</th>
<th>今日</th>
</tr>
</thead>
<tbody>
<tr>
<td><%= @books.created_6day_ago.count %></td>
<td><%= @books.created_5day_ago.count %></td>
<td><%= @books.created_4day_ago.count %></td>
<td><%= @books.created_3day_ago.count %></td>
<td><%= @books.created_2day_ago.count %></td>
<td><%= @books.created_yesterday.count %></td>
<td><%= @books.created_today.count %></td>
</tr>
</tbody>
</table>
よりシンプルな書き方をすると以下のようにもできますので参考までに。
<h4>7日間分の投稿数</h4>
<table class="table table-bordered">
<tbody>
<tr>
<% (6.downto(0)).each do |n| %>
<td><%= n == 0 ? '今日' : "#{n}日前" %></td>
<% end %>
</tr>
<tr>
<% (6.downto(0)).each do |n| %>
<td><%= @books.where(created_at: n.day.ago.all_day).count %></td>
<% end %>
</tr>
</tbody>
</table>
<% (6.downto(0)).each do |n| %>
: 数字を6から0までカウントダウンし、n変数に順番に代入させています。
<%= n == 0 ? '今日' : "#{n}日前" %>
: n == 0は変数nが0かどうかをチェックしています。もしnが0であれば条件はtrueになり、「今日」というテキストを表示させます。それ以外の場合は、条件がfalseにあり、「n日前」というテキストを表示させます。
2. chart.jsを使って、過去7日分の投稿数のグラフ化
chart.jsを使い、グラフを表示させます!
導入
今回はCDN(Content Delivery Network)を使って使用します。
<!DOCTYPE html>
<html>
<head>
<!-- その他のヘッダーコード -->
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<!-- ここにコンテンツを配置 -->
</body>
</html>
ビュー作成
<canvas id="postCountChart"></canvas>
<script>
// ページが読み込まれたときの処理
$(document).on('turbolinks:load', function() {
// グラフを描画するためのCanvas要素を取得
var ctx = document.getElementById("postCountChart");
// Chart.jsを使ってグラフを作成
var postCountChart = new Chart(ctx, {
type: 'line', // ラインチャートを使用
data: {
// グラフのラベル(x軸の値)
labels: ['6日前', '5日前', '4日前', '3日前', '2日前', '1日前', '今日'],
datasets: [
{
// データセットのラベル
label: '投稿した本の数',
// データセットの値
data: [
<%= @books.created_6day_ago.count %>, // 6日前の投稿数
<%= @books.created_5day_ago.count %>, // 5日前の投稿数
<%= @books.created_4day_ago.count %>, // 4日前の投稿数
<%= @books.created_3day_ago.count %>, // 3日前の投稿数
<%= @books.created_2day_ago.count %>, // 2日前の投稿数
<%= @books.created_yesterday.count %>, // 昨日の投稿数
<%= @books.created_today.count %> // 今日の投稿数
],
// グラフの線の色(緑)
borderColor: "rgba(0, 255, 0, 1)",
// グラフの背景色(透明)
backgroundColor: "rgba(0, 0, 0, 0)",
// グラフの曲線の滑らかさ(0から1の範囲で設定。数値が大きくなるほど曲線が滑らかになる)
tension: 0.3
}
],
},
options: {
title: {
// グラフのタイトル表示
display: true,
text: '7日間の投稿数の比較'
},
responsive: true, // グラフのレスポンシブデザインを有効化
scales: {
y: {
// y軸(縦軸)の設定。設定しないと自動になるので書かなくても良い。
suggestedMin: 0, // 最小値を0に設定
suggestedMax: 10 // 最大値を10に設定
},
},
}
});
});
</script>
解説:
基本的な解説はコメントアウトにいれました!
色や曲線は自由にアレンジしてくださいね!
Canvas要素の作成
<canvas id="postCountChart"></canvas>
グラフを表示するために、HTMLに<canvas>
要素を作成します。id属性の名前は何でもよいですが、後でJavaScriptからこの要素を参照するために使います。
Turbolinksの無効化
Turbolinksは、Railsでデフォルトで有効になっています。通常のページ遷移では、ページ全体が再読み込みされますが、Turbolinksを使用すると、ページの一部、主に <body> タグ内のコンテンツのみが更新されます。これにより、ページ遷移が高速化されます。
Turbolinksが使われると、ページ遷移したときに、JavaScriptが読み込まれずコードが正しく動作しないことがあります。この問題を回避するために無効化してあげます。
サンプルデータの挿入
グラフがちゃんと表示されるかどうか、毎日投稿し7日間待つのも大変なので、グラフが適切に表示されるかどうかサンプルデータを入れてあげます。
この課題やっているときってまだ勉強しないのですが、チーム開発やポートフォリオ製作でSeedは使っていくので、なんとく触れておくと良いかもです。
以下記事も参考にしてくださいね。
Seedsファイル記述
db内のseeds.rbに以下を記述します。
# 5人のユーザーを作成
5.times do |n|
user = User.create(
name: "user#{n+1}", # ユーザー名を設定 ("user1" から "user5")
email: "test#{n+1}@test.com", # ユーザーのメールアドレスを設定
password: "123456", # パスワードを一律で設定
)
if user.valid?
puts "User #{n+1} created" # ユーザーの作成をコンソールに出力
else
puts "Error creating user #{n+1}: #{user.errors.full_messages.join(', ')}" # エラー表示
end
end
# それぞれのユーザーに対して、5つの本を作成
User.all.each do |user|
5.times do |n|
book = Book.create(
title: "本#{n+1}", # 本のタイトルを設定
body: "サンプル投稿です#{n+1}", # 本の本文を設定
user_id: user.id, # 本をユーザーに関連付け
created_at: Time.current - rand(10).day # 本の作成日時を設定(過去10日間からランダムに選択)
)
if book.valid?
puts "Book for User #{user.id} created" # 本の作成をコンソールに出力
else
puts "Error creating book for User #{user.id}: #{book.errors.full_messages.join(', ')}" # エラー表示
end
end
end
ターミナル実行
rails db:seed
実行画面
コンソールに出さなくてもいいのですが、出した方が分かりやすくて好き。
エラー表示もいれるとポートフォリオで複雑なseedをつくるときに便利です!
データベースのリセット
データベースをリセットしたいときは以下コマンドを実行します。
リセット後、シードデータが再挿入されます。
rails db:reset
完成!
記事100本目~!成果として嬉しい♪
最近はDWC生からフィードバックをいっぱいもらえるの嬉しいです!
続きはこちら↓↓
Discussion
100!記念すべきですね!!!お疲れ様です♡
なんだか私も嬉しいというか感動です...!
いつも周りを巻き込みながら学びのみではなくて、いい刺激も与えていて、本当にすごいです。
いつも一緒に喜んでくれてとても嬉しいです♪
ありがとうございます😊
その言葉そのままそっくりあいりさんにお返ししたいです😌笑
あいりさんをきっかけにしていること、見習っていることがたくさんあります
これからもよろしくお願いします🥰