【Rails】chartkickとgroupdateを使って投稿に紐づくデータでグラフを作る

題名通りchartkickとgroupdateを使って投稿に紐づいたデータでグラフを作っていきたいと思います。
groupdateでかなり泥沼にハマったのでそれも合わせて書いていこうと思います。

##  完成形
[![Image from Gyazo](https://i.gyazo.com/4bc8f5fa6e2b5f6a74fbe8a10c4c63a5.png)](https://gyazo.com/4bc8f5fa6e2b5f6a74fbe8a10c4c63a5)

はこんな感じです。投稿日に紐付けて棒グラフを作っていきます。

## 前提
Rails 6.0.3.5
金額や体重などなんらかのデータを入力している投稿機能を実装ずみ
##Chartkickとgroupdateの導入
Chartkickだけでもグラフは作れるのですが、日時も表示したいのでgroupdateも導入します。

```ruby:Gemfile

gem 'chartkick' # 追記
gem 'groupdate' # 追記

```
***
```
bundle install
```
***


さらにgroupdateの公式にMysqlのタイムゾーンを設定しろと書いてあるので設定します。
[![Image from Gyazo](https://i.gyazo.com/e1c91f43daba553cd7a158aaba79ecf5.png)](https://gyazo.com/e1c91f43daba553cd7a158aaba79ecf5)

```
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
```
***

続いてchart.jsの導入

```
$ yarn add chartkick chart.js
```

読み込めるように記述します

```js:avascript/packs/application.js
require("chartkick") // 追記
require("chart.js") // 追記
```

これで導入は終了です。

## 投稿に紐づいたデータを用意しよう
今回は投稿時に金額が入力できて、その金額を棒グラフに出力します。
コントローラーに表示用の変数を定義します。

```ruby:users.controller.rb
def show
  @user = User.find(params[:id])
  @data = @user.posts
end
```

変数`@date`にユーザーに紐づいた投稿を取得させています。

## ビューで表示しよう
groupdateを導入したことで使えるようになったgroup_by_weekを使ってチャートを表示してみましょう。

```erb:show.html.erb
<%= column_chart @data.group_by_week(:created_at).sum(:price)%>
```

`＠data`で取得した日付と日時に対して1週間ごとの合計金額sum(:price)を表示しています。

[![Image from Gyazo](https://i.gyazo.com/2f8109f55a4d67bdc1fc1208c69fe1f4.png)](https://gyazo.com/2f8109f55a4d67bdc1fc1208c69fe1f4)

いい感じにできましたね。

***
今度は1週間ごとではなく一日ごとになるようにしましょう。groupdateで使えるgroup_by_dayを使います。

```erb:show.html.erb
<%= column_chart @data.group_by_day(:created_at, last: 7).sum(:price)%>
```
group_by_dayで日付毎に`last: 7`で7日分を表示させています。
[![Image from Gyazo](https://i.gyazo.com/8e9216c5bdce99a74ce6917b248412d1.png)](https://gyazo.com/8e9216c5bdce99a74ce6917b248412d1)

いい感じになりましたね！！！

##　その他のオプションを使ってみましょう

[chartkick公式](https://chartkick.com/)
[groudate公式](https://github.com/ankane/groupdate)

にも書かれているように色々な使い方ができるので試してみましょう！！！！
私は英語は読めませんが、日本語翻訳といろいろ試してなんとかなります。

***

```
<%= column_chart @data.group_by_day(:created_at, last: 7).sum(:price), xtitle: "日付", ytitle: "円"%>
```

[![Image from Gyazo](https://i.gyazo.com/27c96158fd042fa84cdea3cbc2af2b4b.png)](https://gyazo.com/27c96158fd042fa84cdea3cbc2af2b4b)

xtitleで横軸のタイトルがytitleで縦軸のタイトルが指定できます。
***
```erb:show.html.erb
<%= column_chart @data.group_by_day(:created_at, last: 7).sum(:price), xtitle: "日付", ytitle: "円",  min: 0, max: 1000%>
```
[![Image from Gyazo](https://i.gyazo.com/eecb7fe24e2042b4865329519472cd7e.png)](https://gyazo.com/eecb7fe24e2042b4865329519472cd7e)

minで最低値が、maxで最高値が指定できます。
***

```erb:show.html.erb
<%= line_chart @data.group_by_day(:created_at, last: 7).sum(:price), xtitle: "日付", ytitle: "円",  min: 0, max: 1000%>
```

[![Image from Gyazo](https://i.gyazo.com/255a2caa09953181000821fc9237b85b.png)](https://gyazo.com/255a2caa09953181000821fc9237b85b)

line_chartで折れ線グラフになります。
***

他にもさまざまな使い方があるので気になった方はぜひチェック!!!

## 苦労した点、工夫した点
groupdateについての日本語の文献がなく英語の公式のオプションをみていろいろ試して実装しました。
特に1週間分だけのデータをグラフに表示させる方法がわからずorz
公式見ていろいろ試して、group_by_day(:created_at, last:7)という形に落ち着きました。
いい感じに1週間分のデータを表示できてると思います。
ちなみに一ヶ月分の表示させるのは同じ考えで、
group_by_day(:created_at, last: 30)
でいけます。厳密には一ヶ月ではなく30日分ですが。
英語アレルギーダメゼッタイ！！！
***
config.active_record.default_timezone = :localでDBの時間を日本時間にしたら

```
ActiveRecord::Base.default_timezone must be :utc to use Groupdate
```

というエラーにハマるorz
結局公式のGitHubのissueで製作者が[![Image from Gyazo](https://i.gyazo.com/ab5e84edf31042abf74bf1fc1aab752e.png)](https://gyazo.com/ab5e84edf31042abf74bf1fc1aab752e)

と言ってるのを見つけるorz(遅い)
まずは公式をみよう・・・（遅い）

でも開発環境であって本番環境はまた別に設定すればいいのでは？と気づき沼から抜ける。

## 最後に

やはりエラーやわからないことがあったらまず公式を見ることが大切だと改めて思いました（遅い）
日本語翻訳でもなんとかなります。オプションも試してみれば大体どういうのかわかります。

今後はまず英語の公式見る癖をつけたいと思います(遅い）



以上です。拙い文章にお付き合いいただきありがとうございました。