第5回Rails勉強会@東京の議事メモ

早いものでいつのまにかもう第5回のRails勉強会に行ってきました。今回は過去最高の参加人数ということで、見慣れた方も初めて見る方もたくさんいらっしゃいました。このイキオイで盛り上がっていきたいものです。
今回はRailsレシピのネタ出しセッションと、Railsから使えるグラフ作成ライブラリのセッションに参加しました。

前半セッション : 『たのしいRailsレシピ』(仮)打ち合わせ

前半は今秋?出版予定の『たのしいRailsレシピ』についてのネタ募集をしました。詳しい話は、今回もyuguiさんが素晴らしい議事録を書いていらっしゃいますのでそちらへのリンクを。

みなさんからのお話を聞いて思ったのはvalidate_*回りへの関心がすごく高いんだなぁ、ということ。バリデーションはどうしても泥臭くなるところなので、具体的な正規表現の書き方とか、現場で使えるレシピを多く盛りこめたらなぁ、と思います。

あとはMacOS Xのインストール関係も、intel Macへの移行とあいまっていろいろと難しいとのこと。私が使っていたころはfink一色のころだったのでお話を聞いて勉強になりました。ちゃんとメモをとれていればいいんですが。ちなみにGentoo for Mac OS Xはあまり普及していないんですかね。いま私がMacを買ったら使いたいなぁ、と思ってるんですが。

時間が全然足りず、このあとの飲み会でも本のアイディアをうかがったんですが、まだまだ言い足りないという方がいればコメントやメールやなんやかやでご提案くださいませ。もちろん高橋さんや井上さん、荻野さんにお伝えしてくださってもけっこうですよ*1

後半セッション : Gruffでグラフ

後半はGruffという、Rubyのグラフ描画ライブラリと、それをRailsから使う方法について話しました。

このライブラリをつかうと、比較的単純なグラフは簡単&キレイに作成することができます。実物のイメージは増井さんのデモアプリを見ていただくのがよいかと思います。keynoteカッコいいです。

インストール

Gruffライブラリは、早い話がRMagick*2のラッパーになります。RMagickもGruffもgemでインストール可能ですので、インストールは簡単ですね。
WindowsでRMagickを使う場合は、こちらのプロジェクトページから-win32を落としてください。

 # gem install rmagick
 # gem install gruff
ActiveRecordプラグインに仕立ててみました

Gruffの使い方は、ARにグラフ作成機能を追加する*3という拙作ライブラリをベースに説明しました。興味がある方はこちらからどうぞ。

Prefectureが都道府県テーブルで、populationという人口カラムがあり、Area(関東とか東北とか)にbelongしてると思ってください。で、以下のように書くと

  Prefecture.draw_graph(:pie,
                       {:font  => "/usr/share/fonts/monafont/mona.ttf",
                        :theme => "keynote"
                        :legend_font_size => 12,
                        :title => "地域ごと人口",
                        :label => :name,
                        :value =>{:calculate => :sum,
                                  :data      => :population} },
                        {:group => :area })

こうなります。


Gruff::Baseを継承した各種グラフのインスタンスを生成する

ということでGruffの使い方です。まずはGruff::Baseを継承した各グラフ(棒グラフだったり円グラフだったり)のインスタンスを生成します。私のプラグインでは以下のように取り出しています。

  graph = eval("Gruff::#{type.to_s.classify}.new")

evalしているtypeには上記例の第一引数、:pieが入ります。ようするにGruff::Pie.newです。

他にも棒グラフや折れ線グラフが使えます。詳細は本家のドキュメントを。

テーマを設定する

次に、そのグラフのテーマを指定します。生成したGruff::Pieオブジェクトに対してtheme_xxxメソッドを呼び出すことで設定します。たとえばkeynoteテーマであれば、こんな感じです。

  graph.theme_keynote()

プラグイン化したものではこれを動的にやろうとして以下みたいな感じにしています。無理矢理。

  graph.__send__("theme_#{opts.delete(:theme)}".to_sym)
フォント他の体裁をを指定する

あとはGruff::Baseを継承したオブジェクトのインスタンス変数に対して、いろいろなオプションを指定してグラフの体裁を整えていきます。

指定できるオプションは

  • font
  • legend_font_size
  • title
  • title_font_size

なんかがあります。これもAPIドキュメントをご覧いただくのが早いかと。

fontにTrueTypeフォントのフルパス(/usr/share/fonts/monafont/monafont.ttfとか)を指定し、出力文字列をUTF-8にすることで、タイトルやラベルに日本語を使うこともできます。

グラフのデータをセットする

ここまでで体裁が整ったら、

  graph.data(legend_name, [value0, value1.. ])

とすることでグラフの値を入れていきます。第二引数は数値の配列となります。さらに、ここで二要素以上の配列を指定することで、増井さんのデモで見ることができるような複数の線があるグラフを描画可能です。

また、標準で色が用意されている7つ以上の値を設定すると例外が発生しますが、ここでもっとたくさんの要素をいれたい、という場合はGruff::Base#add_color(rgb_string)で色を追加することができます。

私のプラグインのほうでは、例外を補足して新しい色を適当にいれる、という対策をしています。

  begin
    graph.data( label.to_proc.call(key).toutf8,
               [value_markup.to_proc.call(value).to_f] )
  rescue Gruff::ColorlistExhaustedException
    graph.add_color(new_color)
    retry
  end

上記からも、Gruff::Base#dataの引数として結局のところ第一引数にtoutf8をした文字列、第二引数にto_fした結果の1要素配列を指定しているのがわかると思います。

グラフを出力する

グラフの出力はすごく簡単で、上記までの過程を経てデータを入力したGruff::Baseオブジェクトに対して、to_blobないしはwrite(image_file)メソッドを呼び出します。

前者は作成したグラフのイメージをバイナリストリームとして取り出すメソッド、後者はファイルに書き出すメソッドです。
Railsから使う場合は、to_blobしてそれをsend_dataでブラウザに返すとグラフが表示されます。

  # Prefecture.draw_graph() の戻り値が Gruff::Base#to_blob('png')したもの
  send_data(Prefecture.draw_graph(:pie, ...いろいろ... ),
            :type => "image/png")

こんな感じでRailsから使うことができます。書いてみると長いですが、ほんとに簡単に使えるんですってば。
質問・ツッコミ、プラグインへの批評などは、いつものようにコメントやTBでお願いします。

その他のグラフライブラリ

Gruff以外の手段でグラフを作る場合には以下のようなものがあります。

このうち、sparklinesについては生成されるグラフがシンプル過ぎ、イマイチ使いづらかった記憶があります。で、RMagickで書いたんですが、こちらは面倒ではあるんですが決して難しくはありません。RMagickの場合、基本は始点と終点の座標を指定して線をひたすら書いていく感じになります。

CSSグラフはdiv要素の色とwidthを指定してグラフを書いていく感じです。サーバ側の負荷という面では最も有利でしょうから、シンプルな棒グラフが欲しい場合は試してみるのもよいと思います。また、CSSでグラフを書くというアイディア自体はWeb方面の方には常識なのか、かなり美しいグラフの書き方も検索するとすぐ出てきますね。

あとは井上さんにOpen LaszloのRubyバインディングも教えていただきました。Laszlo自体、まだあんまり触れてないんですがどんな感じなんでしょ。

さらにその他
  • RailsってViewが弱くね? テンプレート欲しくなんないのかなぁ、と笹田さんのお言葉。たしかに。
  • SVGはみんな使わないの? => 結局あまり軽くない、IEで表示できないのがなんとも。

などなど。

*1:というか私がいちばん当てにならないような(汗

*2:ImageMagickRubyバインディング

*3:「グラフ作成」ってモデルがやる仕事じゃない気がしますが、まぁあまり気にせずに。。。