kouの技術的メモ

学習した内容の定着やアウトプット用に開設しました

成果物の作成2作品目⑤ 予定管理サービス スケジュールのグラフ表示

グラフ表示部分の導入です。 ライブラリはchartkickを使おうと思います。

公式サイトを見ながら勧めていきます。 https://chartkick.com/

表示するグラフのタイプは選べるのですが、何がいいかは試行錯誤しながら決めていきます。

おそらくtimelineかpie chartがいいかな。

設定

まずこのgemをインストール

gem "chartkick"

bundle install

application.jsに以下の項目を加えます

//= require Chart.bundle
//= require chartkick

timelineを使うためにはgooglechartsの機能も使わないといけないので、

headタグ内に

<%= javascript_include_tag "https://www.gstatic.com/charts/loader.js" %>

を埋め込みます。

<!DOCTYPE html>
<html lang="ja">
<html>
  <head>
    <%= javascript_include_tag "https://www.gstatic.com/charts/loader.js" %>
    <title>full_title(schedule)</title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag    'application', media: 'all',
                               'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application',
                               'data-turbolinks-track': 'reload' %>
  </head>
実装

さて、時間グラフ描画用のtimelineの書式は

こういう[[名前][始まる時間][終わる時間].

     [名前2][始まる時間][終わる時間] ..]という2次元配列の形式になっています。

 <%= timeline [["Monday", "0000-00-00 15:00:00", "0000-00-00 15:15:00"], 
                      ["Tuesday", "0000-00-00 16:05:00", "0000-00-00 16:07:00"]] %>

時刻と日付データが以上の形式なので、この形式でそれぞれDB内に、time_scheduleカラム、start_timeカラム、end_timeカラムとしてデータを入れます。

そして、そのDBからデータを取り出し、chartkickの形式に沿った2次元配列をコントローラで作り、

viewでグラフ描画すれば完成!

と思いきや、グラフに渡す時刻データと実際に描画される描画の時刻が9時間分ずれるという謎の現象が発生。

いろいろ調べましたが、世界標準時UTC日本標準時JSTの時差も9時間なので、おそらく時刻の設定の関係と思われます。

いろいろ試行錯誤しましたが、全然うまく描画されません。

グラフの表示機能はオミットしようかと思いましたが、せっかくだし、面白そうなので自作のメソッドを組んで対応してみることにしました。

時刻データと、描画されるデータに9時間分のズレがありますので、DBからデータを引っ張って来てあげて、

9時間ずらしたデータをchartkickに渡してあげれば、正常なグラフが描画されるはずです。

グラフ描画用にモデルの普通のデータから、2次元配列の生成をする

app/controllers/schedule_controller.rb

 def show
     @day_schedule = DaySchedule.find(params[:id])
     @time_shcedule =  @day_schedule.time_schedule

    #グラフ描画用多次元配列の作成
      @chart = []                                                               #グラフ用の配列の宣言
      
      @time_shcedule.each do |num|
        val1  =  num.time_schedule
        val2  =  num.start_time
        val2  =  conversion(val2)                                               #timechartのグラフの時刻表示が9時間ほどずれてしまうので、ずれを無くすために
        val3  =  num.end_time                                                   #applicationhelperのconversionメソッドを自作し、文字列を操作、
        val3  =  conversion(val3)                                               #多次元配列を作り、chartkickでグラフ描画。
        @chart << [val1, val2, val3]                                            
      end

変換メソッド

app/helpers/application_helper.rb

  def conversion(string)                                                        #グラフの表示が9時間分ずれているので、変換メソッドを作成。
   
    a = string[11..12]                                                          #変数[11..12]で、変数内の前から12~13番目の文字情報を取り出す
    
    return "1900-00-00 15:00:00"  if a == "00"                                  #文字12~13番目の文字がどれかなら、対応する文字列を返す
    return "1900-00-00 16:00:00"  if a == "01"
    return "1900-00-00 17:00:00"  if a == "02"
    return "1900-00-00 18:00:00"  if a == "03"
    return "1900-00-00 19:00:00"  if a == "04"
    return "1900-00-00 20:00:00"  if a == "05"
    return "1900-00-00 21:00:00"  if a == "06"
    return "1900-00-00 22:00:00"  if a == "07"
    return "1900-00-00 23:00:00"  if a == "08"
    return "1900-00-00 00:00:00"  if a == "09"
    return "1900-00-00 01:00:00"  if a == "10"
    return "1900-00-00 02:00:00"  if a == "11"
    return "1900-00-00 03:00:00"  if a == "12"
    return "1900-00-00 03:00:00"  if a == "13"
    return "1900-00-00 05:00:00"  if a == "14"
    return "1900-00-00 06:00:00"  if a == "15"
    return "1900-00-00 07:00:00"  if a == "16"
    return "1900-00-00 08:00:00"  if a == "17"
    return "1900-00-00 09:00:00"  if a == "18"
    return "1900-00-00 10:00:00"  if a == "19"
    return "1900-00-00 11:00:00"  if a == "20"
    return "1900-00-00 12:00:00"  if a == "21"
    return "1900-00-00 13:00:00"  if a == "22"
    return "1900-00-00 14:00:00"  if a == "23"
  end

コントローラ

/schedule/app/views/schedule/show.html.erb

 <%= timeline @chart %>

これで無事にきちんと描画されました!

嬉しいですね!