はじめに
プログラミングスクールでのポートフォリオ制作で得た学びをアウトプットします。
Rails初学者のため、誤りやアドバイスがありましたらご指摘いただけると嬉しいです!
今回は、Railsで以下のような「ドーナツグラフ」を簡単に作る方法についてまとめます。
使用するのはGemの「Chartkick」とJavaScriptのライブラリ 「Highcharts」です。
記載したコードは、わかりやすいよう一部省略している場合があります。不明点はGitHubでご確認いただくか、お問い合わせいただければ幸いです。
Highchartsは、「商用利用では有料」です。
開発環境
- Ruby(2.6.5)
- Ruby on Rails(6.0.0)
ポートフォリオ
URL: https://good-yen.onrender.com
GitHub: https://github.com/Asami119/good_yen
前提となる情報
- Chartkick(Gem)を利用することで、Highcharts(JavaScriptのグラフ描画ライブラリ)を「Rubyの記述だけ」で利用し、グラフを簡単に実装することができる!
- ポイントは、データを以下のようなハッシュ形式でセットし、ビューへ渡すこと
@data = { '項目名1': sample1, '項目名2': sample2, '項目名3': sample3 }
# keyに項目名、valueに対応する数値(または数値を代入した変数)を指定
# 「pie_chart(=円グラフ)」はグラフの種類を指定する記述
# 続けて、データを代入したインスタンス変数を記述
<%= pie_chart @data %>
手順
大まかな流れ
・環境設定(①〜③)
・ビュー(④)・コントローラー(⑤)・モデル(⑥)への記述
*④〜⑥の作業は、順番通りでなくて大丈夫です。
① Chartkickをインストール
以下を記述して、ターミナルで bundle install します。
gem 'chartkick'
② Highchartsを追加
ターミナルで以下を実行します。
yarn add chartkick highcharts
この部分(作業②)はうろ覚えで正確性に自信がない箇所です。他の情報元(以下)を参照したためおそらく合っているとは思うのですが、念のためその旨を記載させていただきます。
- chartkick × Highchartsでドーナツグラフを作る
-
Chartkick公式サイト
* 公式では「Highcharts」ではなく、別のJavaScriptのグラフ描画ライブラリ「Chart.js」を利用するための記述が記載されています。
③ application.jsファイルに以下の記述を追加
import 'chartkick/highcharts'
④ ビューに以下のような任意の記述を追加
公式の記述例と、実際の記述の両方を記載します。
#公式の例
<%= pie_chart Yogurt.group(:flavor).count %>
「Yogurt.group(:flavor).count」で、ヨーグルトの「フレーバーごとのレコード数」を算出しています。
Yogurt.group(:flavor).count
=> {"Blueberry"=>10, "Strawberry"=>5, "Banana"=>5, "Apple"=>5, "Grape"=>2}
戻り値はハッシュ形式で返されるため、上記のようなビューファイルの記述1行で、以下のような円グラフの反映が可能となります。
*上記画像はChartkick公式サイトより引用
* groupメソッドとcountメソッドについては、以下のサイトを参考にしました。
【Rails】 groupメソッドの使い方とは?仕組みを図解で丁寧に解説!
そして、以下が実際の記述です。公式よりも記述が複雑なのは、データをユーザーで絞り込んだり、表示形式を変更したりする必要があったためです。
ポイントは以下の3つです。
・1行目の「pie_chart」の記述でグラフの種類を指定
・続くインスタンス変数「@price_sums」には、反映したいデータが代入されている
・続く「options」以下の記述で、グラフの「色」や「位置」などの表示形式を指定
# 実際の記述
<%= pie_chart @price_sums, options = {
donut: true, # ドーナツグラフにするための記述
colors: ["#ACFF40", "#FFF33F"], # 色を指定
thousands: ",", # 金額表示にする(カンマを入れる)
suffix: "円", # 単位を指定
label: "金額", # ホバーした時に表示される詳細の項目名を指定
library: {
title: {
text: "Good yen!<br>#{@price_true_percent}%", # 中央(ドーナツの穴)部分の記述を指定
align: 'center', # 位置を指定(水平方向)
verticalAlign: 'middle' # 位置を指定(垂直方向)
},
plotOptions: {
pie: {
dataLabels: {
enabled: false #データラベルを表示するか否か
},
innerSize: '50%', # 中央(ドーナツの穴)部分のサイズを指定
}
}
}
} %>
反映イメージは以下です。
グラフの右上部分に重なっている金額の詳細は、グラフをホバーすると表示されます。
他に、グラフやフォントのサイズ指定など、様々な設定が可能なようです。
以下のサイト(再掲)がとても参考になります!
chartkick × Highchartsでドーナツグラフを作る
⑤ コントローラーに以下のような任意の記述を追加
以下の記述では、Postモデルに自作したcalc_donutメソッドを呼び出し、引数postsを用いた計算結果を2つのインスタンス変数に代入しています。
これによりビューファイル「search.html.erb」にて、インスタンス変数の記述でデータをグラフ化できるようにしています。
def search
posts = @q.result.order(date_of_post: :DESC, created_at: :DESC)
@price_sums, @price_true_percent = Post.calc_donut(posts) if posts.present?
# 引数postsには、反映したいデータ(検索で絞り込んだデータ)を代入
# 引数postsが空だった場合、上記は実行しない(ifで条件分岐)
end
⑥ モデルに以下のような任意の記述を追加
def self.calc_donut(posts)
price_true = posts.where(select_yen: true).sum(:price) # true(Good yen!)の値を合計
price_false = posts.where(select_yen: false).sum(:price) # false(あと一歩)の値を合計
price_total = (price_true + price_false).to_f
price_true_percent = (price_true / price_total * 100).floor(1) # trueの割合を計算
[{ 'Good yen!': price_true, 'あと一歩': price_false }, price_true_percent] # 戻り値2つをセット
end
最後に記述した角カッコ内の値が、「@price_sums」「@price_true_percent」にそれぞれ代入されます。
上記では項目が「Good yen!」と「あと一歩」の2つですが、同じ形式で続けて記述することで、必要な項目をさらに増やすことも可能です。
今回は以上です。
読んでくださってありがとうございました!