LoginSignup
1
0

More than 1 year has passed since last update.

chartckickで円グラフを実装(2つのモデルにまたがるデータ)

Last updated at Posted at 2021-10-03

概要

家計簿WEBアプリで、月毎やカテゴリ毎に支出を可視化したい!
→グラフを簡単に導入したい!
→chart.jsってのがあるらしい!
→でも、基本的な使い方以外の記事が少ないな…。

ということで、自分なりに試行錯誤した内容を記事にしてみました。

なお、導入や基本機能については以下記事を参照してください。
公式のgithub
導入方法と基本機能

開発環境

Ruby 2.7.4 / Ruby on Rails 6.1.4 / RSpec

Docker / Docker-compode / CircleCI(CI/CD) / Heroku / SendGrid(mailer)

完成のイメージ

以下のモデルのアソシエーションから、
ER2.png

以下のようなグラフを作りたい。
Post(支出)モデル元にカテゴリと月毎にまとめたデータを可視化する。
グラフをタップすると、カテゴリ名と支出の小計が表示される

スクリーンショット (55).png

つまり必要なのは、 Category.name, Post.priceの合計, Category.color あたり。
CategoryとPostの2モデルにまたがっているので、面倒そう…。

作りたいデータの形

いくつかの記事を見ていると、
以下のような1つのモデル内で2カラムを取り出すような形の取り扱いが多い。

<%= pie_chart RugbyWorldCupHostCountry.pluck(:held_at, :total_attendance) %>

2モデルにまたがっているの場合はどうすれば…?
調べてみると、でーたの形式は以下のように
index(今回で言う"category.name")とvalue(今回で言うところの"post.price")配列になっているのだそう。

[[data1_index, data1_value], [data2_index, data2_value], … ]

ここまでわかれば後は簡単なはず!

実装

こうすれば、適宜@monthの値を変えて、前月のグラフなども出せます。

controller/hoge.rb
  def month
    family_category_ids = @relationship.category_ids
    # 今月の1日を取得
    @month = Time.zone.now.beginning_of_month

    # 空の配列を用意
    @pie_chart = []

    # カテゴリ毎にループを回す
    family_category_ids.each do |c_id|
      @pie_chart.push(
        [Category.find_by(id: c_id).name, 
          Post.where(category_id: c_id, payment_at: @month.all_month).sum(:price)]
      )
    end

    # @pie_chartとは別にcolorsの配列も用意
    @pie_chart_colors = Category.where(id: family_category_ids).map(&:color)
  end



以下では少しスタイルをいじっています。

  • legend: {display: false}で、凡例を消す
  • donut: trueで真ん中に穴
views/hoge.html.erb
  <%= pie_chart @pie_chart,legend: {display: false}, donut: true, width: "200px", height: "200px", colors: @pie_chart_colors %>

さいごに

以上です。
質問や、「ほかにもこんな実装方法があるよ!」などコメントいただけると幸いです。
どなたかのためになればうれしいです。

1
0
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
1
0