以前、リンゴ全体の食べた割合をグラフ化してみました。
Ruby + Heroku + Highchartsで食べたリンゴの割合をグラフ化してみた - メモ的な思考的な
ただ、これではどの時期に何のリンゴを食べたのか、つまり旬のリンゴは何なのかが分かりづらい状態でした。
そのため、今回は月別のグラフを追加してみることにしました*1。
■デモ
■2013/3/31時点
シナノゴールドばかり食べていたせいで、旬のリンゴがよく分かりません...
8月あたりからツガルが始まり、9月と10月頃はトキや秋映を食べていたような気がします。
Twitter始めたのが遅かったので、トキ・秋映が反映されていないのが悲しいなぁ。一ヶ月間くらい、それらを食べていた記憶がある。
■悩んだことと対応
HighChartsのうち、どのグラフを使うか
HighChartsにはデモサイトがあり、使えるグラフの一覧があります。今回は「Stacked area」を選びました。
Highcharts - Basic line
HighChartsにおいて、前回利用した「pie」との作り方の違いとしては、以下のようなものでした。
- pie: 一つのseriesを使い、addPointsで割合を加える
- area: 複数のseriesを使い、addSeriesで割合を加える
参考:HighCharts load data via ajax - Stack Overflow
メニューなどの表現
TwitterBootstrapのCDNがあれば使ってみるかと調べてみたところ、以下のものがありました。
Bootstrap CDN
「...Don't believe us? Ask these guys: 」と書いてありましたのでたぶん大丈夫だろうと思い、今回は試してみることにしました。
haml中の日本語表記について
何もせずに日本語を記載したところ、エラーで動作しなくなりました。
以下のサイトを参考に、config/boot.rbのPadrino.before_loadに処理を追加しました。
参考:http://blog.cabbagekobe.info/blog/2012/11/06/padorino-haml-japanese/
config/boot.rb
Padrino.before_load do Encoding.default_internal = nil Encoding.default_external = 'UTF-8' end
hamlに値を渡すには
haml側からはコントローラーのインスタンス変数が参照できたので、それを利用しました。
ただ、使うjavascriptを切り替えるために、インスタンス変数へパスを設定したのは良かったのかどうか...
controllers/apples.rb
get :index, map: "/" do @highchart_path = "/javascripts/total.js" @home_active = "active" render "apples/index" end
application.haml
%script{ src: @highchart_path, type: "text/javascript"}
ページ共通のテンプレート使用
今回はページが2つに増えたことから、ページ共通のテンプレートを app/views/layouts/application.haml として作成しました。
一方個別のページは、 app/views/apples/ 配下に作りましたが、実際のところは両方とも同じです。
食べたリンゴの個数を月別に集約するには
前回ローカルのDBをPostgreSQLにしたおかげで、ローカルでもPostgreSQLの独自関数が使えるようになりました。
そのため、Modelのscopeで以下の集計を行いました。
scope :count_apple_monthly, select("name, to_char(tweeted_at, 'MM') as month, count(name) as amount") .group('name, month') .order('name, month')
参考:http://www.postgresql.jp/document/9.1/html/functions-formatting.html
戻り値だけで使うクラスを用意するには
RubyのStructクラスを使いました。
参考:class Struct
そもそも必要になった経緯はというと、上記のSQLで
name | month | amount |
---|---|---|
シナノゴールド | 01 | 20 |
シナノゴールド | 02 | 5 |
フジ | 01 | 10 |
のように取得できるのですが、HighChartsのSeriesで扱うには、amountを[20,5,..]のような配列で持たせる必要がありました。
このように縦持ちを横持ちに変換するのを、SQL・Ruby・JavaScriptのどこでやろうかと考えましたが、せっかくだからRubyを使うことにしました。
そこでPadrinoのhelperの中でやることにしたところ、メソッドの戻り値で使えるクラスを定義する必要が出てきました。
その戻り値用のクラスをどこかで定義しようと考えたのですが、Padrinoでは定義したものをどこに置けばよいか分かりませんでした。
そこでいろいろと調べてみたところ、Structクラスを知ったため、使うようにしました。
参考:
■負債の返済
前回の「良くない設計」であげていた、
- モデルへ入れる際のSELECTで、ダミーの列を取得
- JSONで渡す際に、app/helpers/apples_helper.rb のadd_colorメソッドで、モデルのダミー項目を上書き
について、Structクラスを使えばダミー列とかを使わなくて済むことが分かりました。
そのため、今回のタイミングで、そちらの部分もStructを使うように修正しました。
*1:最初は年別月別の集計も考えましたが、そもそも旬のリンゴを知りたかったため、年はあまり関係ないだろうと考えました。よって、年は考慮せずに月別に集計することにしています。