🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Chart.js

Chart.jsは、多様なグラフを組み込めるJavaScriptのライブラリ。折れ線グラフや棒グラフ、円グラフ、レーダーチャートなどのグラフの種類が用意されています。HTML5のCanvasを用いて描画され、マークアップも分かりやすく、簡単に編集することが可能です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

1958閲覧

[Rails]chart.jsを使用したグラフ(横軸年月/縦軸レコード数)で、レコード数が0の月を「0」として取得したい

mball

総合スコア7

Chart.js

Chart.jsは、多様なグラフを組み込めるJavaScriptのライブラリ。折れ線グラフや棒グラフ、円グラフ、レーダーチャートなどのグラフの種類が用意されています。HTML5のCanvasを用いて描画され、マークアップも分かりやすく、簡単に編集することが可能です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2019/11/05 11:50

編集2019/11/16 08:33

前提・実現したいこと

レコード数が0の月を「0」として取得したいです。

Railsでイベント閲覧アプリを作成していて、chart.jsを使用してグラフを表示しようとしています。
横軸を年月、縦軸をレコード数としていますが、レコード数が「0」の月はグラフで表示できません。詰めてグラフが生成されます。

発生している問題・エラーメッセージ

dayカラムに7月のデータがある状態では正常にグラフが生成されます。
テーブルの画像↓
イメージ説明

グラフの画像↓
イメージ説明

しかし、7月にデータがない状態(レコードへ登録がない月がある状態)ではグラフの生成がうまくいきません。
テーブルの画像↓
イメージ説明
グラフの画像↓
イメージ説明

該当のソースコード

グラフへデータへ渡すためのcontroller.rbの記述↓

Ruby

1start_day = Date.today-183 2end_day = Date.today 3gon.monthly = (start_day..end_day).select {|day| day.day == 1} 4gon.monthly.each_with_index do |month, i| 5 newmonth = month.strftime("%Y年%m月") 6 gon.monthly[i] = newmonth 7end 8sum = 0 9array = Like.where(user_id: current_user.id).where(day: start_day..end_day).group('MONTH(day)').count 10gon.data = array.values # この段階でイベントへ行っていない月は0で配列に加えておきたい 11binding.pry 12gon.linedata = [] 13gon.data.each do |data| 14 sum += data 15 gon.linedata << sum 16end

グラフを表示するためのcoffeeへの記述↓

coffee

1window.draw_graph = -> 2 ctx = document.getElementById("myChart").getContext('2d') 3 barNum = 6 4 labels = new Array(barNum) 5 bgColors = new Array(barNum) 6 bdColors = new Array(barNum) 7 for i in [0...barNum] 8 bgColors[i] = 'rgba(75, 192, 192, 0.2)' 9 bdColors[i] = 'rgba(75, 192, 192, 1)' 10 myChart = new Chart(ctx, { 11 type: 'bar', 12 data: { 13 labels: gon.monthly 14 datasets: [{ 15 label: 'イベントの数', 16 data: gon.data, 17 backgroundColor: bgColors, 18 borderColor: bdColors, 19 borderWidth: 1 20 }, { 21 label: '行ったイベントの総数', 22 data: gon.linedata, 23 type: 'line' 24 }] 25 }, 26 options: { 27 scales: { 28 yAxes: [{ 29 ticks: { 30 beginAtZero:true 31 } 32 }] 33 } 34 } 35 })

テーブルへデータが保存されるフォームは以下の通りです。

ruby

1<%= button_to '行った', "", class: "went-btn js-modal-open" %> 2 <div class="modal js-modal"> 3 <div class="modal__bg js-modal-close"></div> 4 <div class="modal__content"> 5 <%= form_for @like, url: event_likes_path(@event) do |f| %> 6 <%= f.date_field :day, min: @event.start_on, max: @event.end_on, value: @event.start_on.strftime("%Y-%m-%d") %>に 7 <%= f.submit "行った"%> 8 <% end %> 9 </div> 10 </div>

試したこと

Ruby へのコメントアウトへ記載しているように、イベントへ行ったことがない月に対して配列に「0」を加えたい。
しかし、方法がどうしても見つけられないのでご教授いただければと思います。

違う方法が良ければそちらをご紹介していただきたいです。

補足情報(FW/ツールのバージョンなど)

Rails 5.2.3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんばんは。
group byしたときに存在しない月はとれませんので array.values は本来の月数よりも少なくなりますね。
解決策はいくつかあると思います。

  1. SQL側でがんばる

https://www.wakuwakubank.com/posts/409-mysql-virtual-table-of-dates/
のように連続した月をもつ仮想表を作って外部結合してあげる。
2. SQL側でがんばる(その2)
上記を仮想表ではなく、実在する表として予め作っておいて外部結合する。
3. アプリケーション側でがんばる
gon.monthly[i]をeachで回してarrayのキーにある月と一致したらそのカウントを入れる、なければ0を入れる新しい配列を作る
月数はたかがしれているのでこっちが簡単かと思います。

ちなみにですが、group('MONTH(day)')は年まで見てくれないので2019/11や2020/11を一緒にカウントしてしまいます。
3の案とうまく組み合わせるなら group("DATE_FORMAT(date, '%Y年%m月')") でとってあげればよいんじゃないでしょうか。

投稿2019/11/16 14:53

編集2019/11/16 14:54
8zca

総合スコア559

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mball

2019/11/17 03:29

ご回答ありがとうございます!has_key?メソッドの存在を知らなかったので、大変勉強になりました!おかげさまで綺麗なグラフがかけました^^
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問