LoginSignup
5
5

More than 3 years have passed since last update.

【Ruby on Rails】Chartkickでカラム別集計の円グラフを作成

Posted at

はじめに

railsでグラフを挿入したかったのでchartkickを使用しました。
導入自体も容易なので、集計結果の円グラフ化の方法を記載します。

参考にしたページ
-chartkick公式ドキュメント
-Railsでシンプルなグラフを扱うならchart-js-rails よりchartkickを使うべし
-爆速で円グラフを実装する[5分]

環境

ruby 2.5.1
Rails 5.2.4.3

前提と目標

ユーザの意見をまとめたvotesテーブルopinionカラム(integer)から円グラフを作成する。
opinionカラムの値が1の場合は賛成、0の場合は反対で集計しますが、他の値やNULL値が混ざっている状態で作成します。

votesテーブル

id opinion
1 1
2 1
3 0
4 1
5 0
6 2
7 NULL
8 3
9 NULL
10 0

完成図

pie_A.png
※実機では円グラフの各要素にマウスカーソルを当てると要素数が表示されます。

Chartkickの導入

参考ページに記載されていますが改めて記載します。

Gemfile
gem "chartkick"   #追記する
Gemfile
$ bundle install
app/javascript/packs/application.js
//= require chartkick
//= require Chart.bundle  #2行追記する

viewページへの反映

表示させるページはどこでもいいですが今回はpostsコントローラーのindex.html.erbにグラフを表示させたいと思います。

app/views/posts/index.html.erb
<%= pie_chart Vote.group(:opinion).count%>

chart (1).png

これだけでは何を表しているのかよくわからないグラフになっています。。

そこでコントローラーファイルに変数とグラフ用のメソッドを定義します。

app/controllers/posts_controller.rb
  def index
    @opinion = Vote.pluck(:opinion)
    @aggregate = aggregateOpinion(@opinion)
    @sum = sumOpinion(@opinion)
  end

  def aggregateOpinion(array)
    result = [["賛成",0],["反対",0],["どちらでもない",0],["無回答",0]]
    array.each do |i|
      if i == 1
        result[0][1] += 1
      elsif i == 0
        result[1][1] += 1
      elsif i == nil
        result[3][1] += 1
      else 
        result[2][1] += 1
      end
    end
    return result
  end

  def sumOpinion(array)
    result = [["総投票数",0],["有効投票数",0],["無効投票数",0]]
    array.each do |i|
      if i == nil
        result[2][1] += 1
      else 
        result[1][1] += 1
      end
    end
    result[0][1] = array.length 
    return result
  end

解説

pluckメソッドで対象のカラムだけを配列で取得しています。
その後、aggregateOpinionメソッドで円グラフ用のデータに整形しています。

result配列のインデックスがそのまま円グラフの表示順になるのでパラメータが
NULL値のものを最後にしてその次に所謂"その他"(今回の場合は[どちらでもない]という名前)が来るようにしています。

sumOpinionメソッドは直接グラフには関係ありませんが総投票数の情報をグラフに載せることが難しいので別途作成しています。

以上の内容を踏まえ、改めてビューページに反映させたいと思います。

app/views/posts/index.html.erb
<%= pie_chart @aggregate, width: "500px"%>

chart (2).png

これでも問題ないですが最後にレイアウトとsumOpinionメソッドで取得した内容をtable要素で表示させて完成です。

app/views/posts/index.html.erb
<%= pie_chart @aggregate,colors: ["#3333cc","#cc3333","#339966","333"], donut: true , width: "500px"%>
<table border="1" width="500">
  <tr>
    <th>総投票数</th>
    <th>有効投票数</th>
    <th>無効投票数</th>
  </tr>
    <tr>
    <th><%=@sum[0][1]%></th>
    <th><%=@sum[1][1]%></th>
    <th><%=@sum[2][1]%></th>
  </tr>
</table> 

pie_A.png

終わりに

いかがでしたでしょうか。もう少しメソッドの部分に応用を効かせられたなぁと自分でも思いますね。。
もちろんchartkickが対応しているのは円グラフだけではないので是非調べてみてください。
見て頂いてありがとうございました!

5
5
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
5
5