8
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Rails] chart.jsでRailsアプリに投稿数推移グラフを描画する [chart.js]

Last updated at Posted at 2021-05-10

はじめに

 このたび、Ruby on Railsの学習を始めました。まだまだ初学者ですが、日々の学びや気づき、エラーとの闘いをここに記録していきたいと思います。ご要望、ご指摘もお待ちしております!

記事の概要

 アプリで取り扱われるデータを可視化できればと思い、chart.jsを使ってRailsアプリにグラフを描いてみます。
 1. chart.jsの導入手順
 2. 記事投稿数の推移グラフを描いてみる

chart.jsとは?

 JavaScriptで実装されたグラフをRailsアプリに組込むことができるライブラリです。
 公式
 https://www.chartjs.org/docs/latest/

1. chart.jsの導入手順

 Gemfileに記述する。

Gemfile
gem 'chart-js-rails', '~> 0.1.4'

 そしてターミナルでbundle installを実行する。

% bundle install

 package.jsonに以下の通り追記。

package.json
{
  # 省略
  "dependencies": {
    #省略
    "chart.js": "^2.7.1" # ←ここに追記
  }
}

 そしてターミナルでyarn installを実行。

% yarn install

2. 記事投稿数推移グラフを描いてみる

 ここでは、とあるArticleモデルの投稿数推移について、Articlesコントローラーでデータを加工してarticles#indexにグラフ描画することをゴールとします。
 横軸が日付、縦軸が投稿数です。なお、日時データを扱う"groupdate" gemは導入済みとして進めます。

 まず、グラフ描画の基本構成は下記のようになります。公式ページのサンプル参照。

app/views/articles/index.html.erb
<canvas id="myChart" width="200" height="100"> </canvas>

<script> 
    var ctx = document.getElementById("myChart").getContext('2d');
    var myChart = new Chart(ctx, {
        type: 'bar',                      # 'bar'でグラフタイプを縦棒グラフに指定 
        data: {
            labels: <%= @chartlabels %>,  # 横軸にとるデータ(今回は投稿日付)を埋め込む
            datasets: [{
                label: "投稿数",
                data: <%= @chartdatas %>, # 縦軸にとるデータ(今回は投稿数)を埋め込む
                backgroundColor: 'rgba(255, 80, 120, 1.0)',
                borderColor: 'rgba(255, 80, 120, 1.0)',
                fill: false
            }]
        },
    });
</script>

 グラフに渡すデータをarticles_controllerで用意しましょう。インスタンス変数を定義します。

app/controllers/articles_controller
class ArticlesController < ApplicationController
  def index
    @articles = Article.all
     
    @article_by_day = @articles.group_by_day(:created_at).size
    # groupdateのgroup_by_dayメソッドで投稿日(created_at)に基づくグルーピングして個数計上。 
    # => {Wed, 05 May 2021=>23, Thu, 06 May 2021=>20, Fri, 07 May 2021=>3, Sat, 08 May 2021=>0, Sun, 09 May 2021=>12, Mon, 10 May 2021=>2}
    
    @chartlabels = @article_by_day.map(&:first).to_json.html_safe
    # 投稿日付の配列を格納。文字列を含んでいると正しく表示されないので.to_json.html_safeでjsonに変換。
    # => "[\"2021-05-05\",\"2021-05-06\",\"2021-05-07\",\"2021-05-08\",\"2021-05-09\",\"2021-05-10\"]"
    
    @chartdatas = @article_by_day.map(&:second)
    # 日別投稿数の配列を格納。
    # => [23, 20, 3, 0, 12, 2]
  end
end

 Railsアプリを起動し/indexへアクセスすると縦棒グラフが描画されている。
9b48f26e7b6e328f9f4e7909036baf80.png

 次に、累計投稿数を折れ線グラフにして、先ほどのグラフに重ねてみます。

app/views/articles/index.html.erb
<canvas id="myChart" width="200" height="100"> </canvas>

<script> 
    var ctx = document.getElementById("myChart").getContext('2d');
    var myChart = new Chart(ctx, {
        type: 'bar',                      
        data: {
            labels: <%= @chartlabels %>,  
            datasets: [{
                label: "日別投稿数",
                data: <%= @chartdatas %>, 
                backgroundColor: 'rgba(255, 80, 120, 1.0)',
                borderColor: 'rgba(255, 80, 120, 1.0)',
                fill: false
            },{ //ここから追記
                label: "累積投稿数",
                data: <%= @cumulative %>, // 縦軸にとる累積投稿数データを埋め込む
                backgroundColor: 'rgba(255, 80, 120, 0.2)',
                borderColor: 'rgba(255, 80, 120, 1.0)',
                type: 'line', // 'line'でグラフタイプを折線グラフに指定
            }]
        },
    });
</script>

 累積投稿数データを配列にして、インスタンス変数として用意します。

app/controllers/articles_controller
class ArticlesController < ApplicationController
  def index
    @articles = Article.all
     
    @article_by_day = @articles.group_by_day(:created_at).size
    
    @chartlabels = @article_by_day.map(&:first).to_json.html_safe
      
    @chartdatas = @article_by_day.map(&:second)

    # ここから追記
    @cumulative = []
    sum=0
    @chartdatas.each do |a|
      sum = sum + a
      @cumulative<<sum
    end
  end
end

 アプリを起動し/indexへアクセスすると、線グラフも表示されました。

e3ab7a129fe8fecaf3509774075090a5.png

まとめ

 chart.jsを活用し、記事投稿数推移グラフを縦棒+折れ線グラフで表現できました。データベースから加工したデータをグラフで表現することができるので、アプリの管理者機能、可視化など幅広く活用できそうです。カスタマイズも柔軟にできそうなので、今後も記事で取扱いたいと思います。
 Rubyでのデータ加工(もっと簡潔にできそう)とJavaScript記述の良いトレーニングにもなりました。

8
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?