アプリケーションは多くの場合、レポート作成によってデータベース内でデータを分析します。グラフはレポートを視覚的に表現するもので、傾向の理解に役立ち、一般的にデータ統合をさらに簡素化します。Ruby On Railsは、レポートやグラフを用いてこれらのWebアプリケーションを作成するのに使用可能な技術の1つです。この記事では、Ruby on Rails上でグラフを作成する方法について説明します。
データベース内でレポートやデータからグラフを作成するには、優れたグラフ化製品が必要です。Ruby on Rails向けに利用可能な製品例として、Gruff、JFreeChart、XML/SWF Charts、FusionChartsなどが挙げられます。以下の表は、これらのグラフ化製品を大まかに比較したものです。すべての製品を試したり、テストを行ったりしたわけではないことに注意してください。以下の分析のほとんどは、製品のマニュアルから集めた情報に基づいています。
Gruff | JFreeChart | XML/SWF | FusionCharts(無料) | FusionCharts v3 (有料) | |
種類 | Rubyクラス | Javaクラスファイル | Flashチャーティングコンポーネント | Flashチャーティングコンポーネント | Flashチャーティングコンポーネント |
オペレーティングシステム | O/S依存なし | O/S依存なし | O/S依存なし | O/S依存なし | O/S依存なし |
Adobe Flashプラグインの必要性 | 必要なし | 必要なし | 必要 | 必要 | 必要 |
高度なデータ分析に適するか | 適さない | 適する | 適する | 適さない | 適する |
インストールすべきプラグインまたはソフトウェアの有無 | あり(RMagick, ImageMagick and Gruff) | あり(JDK バージョン1.3以降) | なし | なし | なし |
グラフのアニメーション可 | 不可 | 可 | 可 | 可 | 可 |
グラフのイメージ保存 | 可 | 可 | 可 | 不可 | 可 |
UTF8対応状況 | 記載なし | 対応 | 対応 | 対応 | 対応 |
RoRでの使いやすさ | 使いやすいが、多くのコーディングを伴う | あまり使いやすいとは言えず、エンドユーザには不向き | 複雑で、グラフの構成にあまりにも多くのXMLタグが必要 | 非常に使いやすく、開発者やエンドユーザ向き | 非常に使いやすく、開発者やエンドユーザ向き |
2D、3D横棒グラフ | 可 | 可 | 可 | 可 | 可 |
折れ線グラフ | 可 | 可 | 可 | 可 | 可 |
散布図 | 可 | 可 | 可 | 可 | 可 |
面グラフ | 可 | 可 | 可 | 可 | 可 |
2D、3D円グラフ | 可 | 可 | 可 | 可 | 可 |
2D、3Dドーナツグラフ | 不可 | 可(円環グラフ) | 可 | 可 | 可 |
ガントチャート | 不可 | 可 | 不可 | 可 | 可(FusionWidgets v3の一部として) |
組み合わせグラフ | 不可 | 可 | 可 | 可 | 可 |
ゲージグラフ | 不可 | 可(XML/SWF Gaugeの一部として) | 可 | 不可 | 可(FusionWidgets v3の一部として) |
リアルタイムグラフ | 不可 | 不可 | 不可 | 不可 | 可(FusionWidgets v3の一部として) |
データ駆動型マップ | 不可 | 不可 | 不可 | 不可 | 可(FusionWidgets v3の一部として) |
この記事では、Rails上でFusionChartsおよびMySQLデータベースを使用してグラフを作成する方法について考察します。FusionChartsはFlashベースのチャーティングコンポーネントで、アニメーション化されたインタラクティブなグラフの作成が可能です。FusionChartsはあらゆるWebスクリプト言語で使用でき、ごく最小限のコードで強力なグラフを提供します。FusionChartsにはRoRで使用するためのラッパーモジュールが備わっています。この記事でFusionChartsを使用したのは、使いやすいさまざまなグラフタイプ、分かりやすいマニュアル、および質の高いサポートが用意されているためです。
この記事では、サンプルアプリケーションを用いて、Ruby on Rails上でFusionChartsを使用してグラフを作成するメカニズムについて説明します。この記事に記載するサンプルアプリケーションを実行するには、以下が必要です。
• FusionCharts Free/ v3
FusionCharts Freeは www.fusioncharts.com/free から、またオプションが追加されたコマーシャルバージョンはwww.fusioncharts.com からダウンロード可能です。この記事では、フリーバージョンを使用してグラフ作成を行います。
FusionChartsのインストールに必要なことは、swfおよび.rbファイルをダウンロードパッケージから適切なアプリケーションフォルダにコピー&ペーストすることだけです。なお、.rbファイルはDownload Package > Code > RoR > Librariesフォルダにあります。
• Ruby 1.8.6 以上
http://www.rubyonrails.org/downで入手可能です。
• Rails gem 2.0.2 以上
RubyGemsをロードすると、以下のコマンドラインを使用してすべてのRailsとそのdependency(従属性)をインストールできるようになります。
gem install rails
また、Railsはスタンドアロンパッケージとしてここから (リンク)ダウンロードも可能です。
• MySQL 4.0 以上
ここから(リンク)ダウンロード可能です。
この記事向けに開発したサンプルアプリケーションは、基本的なタイムトラッカーアプリケーションです。これは、従業員が1週間分の時間を記入し、入力した時間に基づいたグラフを閲覧する単純なアプリケーションです。この記事では、サンプルアプリケーションを2つのパートに分けて説明します。最初のパートでは、従業員およびタイムシートの一覧表示、編集、閲覧、破棄を含む基本的なアプリケーションの開発について取り扱います。すでにアプリケーション内でグラフを統合する必要がある場合は、このパートをとばして直接次のパートにお進みください。次のパートではグラフとアプリケーションの統合について説明します。この記事では、読者がRuby on Railsの基本知識を持っていることを前提としています。
基本的なタイムトラッカーアプリケーションの作成方法
scaffoldを使用して、従業員およびタイムシートの一覧表示、閲覧、編集、削除という基本機能が実現可能です。基本的な従業員およびタイムシートコントローラを作成するコマンドは以下のとおりです(1行目のコマンドで作成したTimeTrackerApplicationフォルダ内から、残り2行のコマンドを実行します)。
rails –d mysql TimeTrackerApplication ruby script/generate scaffold Employee name:text ruby script/generate scaffold Timesheet log_date:datetime hours_spent:integer employee_id:integer
次に、configフォルダにあるdatabase.ymlを変更して「timetrackerdb」を示すようにし、また自身のデータベースに一致するユーザー名およびパスワードエントリに変更します。この後、以下のrakeコマンドを実行してデータベースを作成します。
rake db:create rake db:migrate
従業員とタイムシートテーブルの間の外部キー関係を確立するため、以下のクエリーをmysqlインスタンス内で実行します。
alter table timesheets add constraint fk_employee_id foreign key fk_employee_id(employee_id) references employees(id) on delete cascade
当然、外部キーを作成する方法は他にもありますが、この記事においてその説明は不要でしょう。Ruby on Railsにて上述の外部キー関係を表すには、モデル間で関連付けを作成する必要があります。
従業員モデルでは、クラス宣言文の後、以下の文を記述します。
has_many :timesheets
タイムシートモデルでは、以下のように記述します。
belongs_to :employee
サンプル値をデータベースに挿入するには、sqlスクリプトdb/sampledata.sqlを実行する必要があります。これで基本アプリケーションの準備が整いました。ここから、従業員の追加、閲覧、または削除が可能となります。
アプリケーション内でのグラフ統合方法
基本的なタイムトラッカーアプリケーションの環境が整うと、以下の方法で従業員のタイムトラッカーグラフを作成します。
• FusionCharts Free/Proのダウンロードパッケージで入手可能なFusionChartsフォルダ(Download Package > Code > FusionCharts)をTimeTrackerApplicationのpublicフォルダにコピーする。
• Download Package > Code > FusionChartsフォルダにあるファイルFusionCharts.jsをpublic/javascriptsフォルダにコピーする。
• ダウンロードのDownload Package > Code > RoR > Librariesフォルダからfusioncharts_helper.rbをTimeTrackerApplicationのlibフォルダにコピーする。
これで、FusionChartsの設定は完了です。
従業員ページのリストから、タイムトラッカーグラフへのリンクを作成します。こうして、すべての従業員を対象として、彼らの時間をグラフとして表示するリンクが用意されます。タイムトラッカーグラフへのリンクは、app/views/employees/index.html.erbファイルに作成されます。リスト1は、追加したリンクの詳細を示しています。このリンクをページ内の他のリンクの後に追加します。
リスト 1
<td><%= link_to 'Time Chart', {:action=>'view_timesheet_chart',:id=>employee.id} %></td>
図1は、アプリケーションからの従業員ページのリストを示しています。図1に見られる機能は、データベース設定および前項で説明したruby scaffoldを用いて簡単に実現されています。このページはアドレス「http://yourserver:port/employees」にアクセスして閲覧可能です。この画面の関連部分が図1に示した内容です。
図 1
この「Time Chart」リンクをクリックして起動するアクションは、従業員コントローラのview_timesheet_chartアクションです。リスト2はこのアクション用のコードを示しています。このアクションは、選択した従業員用のグラフをレンダリングします。このアクションは、従業員モデルに作用して、「2008年12月1日」から「2008年12月7日」までの日付範囲でこの従業員向けのタイムシートを見つけ、それから「view_timelog_chart.html.erb」をレンダリングします。単純化するため、日付範囲はコントローラ内で固定されています。実際のアプリケーションでは、レポート/グラフを作成するための日付範囲はユーザーが選択します。
リスト 2
EmployeesController
def view_timesheet_chart start_date= "2008-12-01" end_date="2008-12-07" @employee_id = params[:id] employee_details_with_timesheets = Employee.find_with_timesheets_in_date_range(@employee_id,start_date,end_date) if(!employee_details_with_timesheets.nil?) @employee_details_with_timesheets =employee_details_with_timesheets[0] else @employee_details_with_timesheets =nil; end headers["content-type"]="text/html" end
従業員IDをパラメータとして使用して、このアクションは従業員モデルに作用して指定の期間内のこの従業員用のタイムシートを見つけます。従業員モデル内で追加される機能を、リスト3に示します。
リスト 3
Employee.rb
def self.find_with_timesheets_in_date_range(id, start_date, end_date) conditions="employees.id =? and log_date between ? and ?" employee_details_with_timesheets=self.find(:all, :include=>'timesheets', :conditions=> [conditions,id,start_date,end_date], :order=>'log_date asc') return employee_details_with_timesheets end
このアクションは、最終的に「view_time_chart.html.erb」をレンダリングします。テンプレート「view_timelog_chart.html.erb」は、従業員コントローラのすべてのビューに共通なレイアウト「employees.html.erb」を使用します。したがって、リスト4に見られるとおり、ビュー内のコードは短くて簡単です。
リスト 4
view_timesheet_chart.html.erb (in app/views/employees folder)
<%= javascript_include_tag "FusionCharts"%> <% # The xml is obtained as a string from builder template. str_xml = render "employees/timesheet_data" #Create the chart - Column 3D Chart with data from strXML render_chart '/FusionCharts/Column3D.swf' , '' , str_xml , 'TimeChart' , 650 , 400 , false , false do -%> <% end -%>
上記のコードから、ビューページ内でグラフをレンダリングするのに以下のステップが必要なことが分かります。
- FusionCharts.jsファイルをインクルードする。
- ビルダーからXMLデータを入手する(ビルダーはコントローラアクションからのデータを使用してXMLを構築)。
- 適切なパラメータを使用してrender_chart機能を呼び出すことでグラフをレンダリングする。
通常、時間はガントチャートで表され、このグラフはFusionChartsでも利用可能です。ここでは簡素化のため、縦棒グラフを使用しました。
2つ目のステップはxmlの作成に関連します。FusionChartsはXML(eXtensible Markup Language)を使用してグラフを作成、操作します。FusionChartsグラフ全体はXMLパラメータに制御されます。つまり、XMLを使用して見栄えとともにグラフ用の機能プロパティを定義します。各グラフタイプに応じて多くのプロパティが定義可能です。FusionChartsは各グラフ特有のXML構造を持ちます。当該グラフは単独系グラフ(1セットのデータのみを持つ)で、曜日と従業員がその日に費やした時間数を表示します。このグラフのサンプルXMLをリスト5に示します。
リスト5
単独系グラフのサンプルXML
<graph xAxisName="Day" showValues="1" caption="Time Tracker Chart" numberSuffix=" hrs." subcaption="For Employee John Wilson" yAxisName="Hours Spent"> <set name="Monday" value="8" color="AFD8F8"/> <set name="Tuesday" value="6" color="F6BD0F"/> <set name="Wednesday" value="5" color="8BBA00"/> <set name="Thursday" value="9" color="A66EDD"/> <set name="Friday" value="9" color="F984A1"/> <set name="Saturday" value="8" color="CCCC00"/> </graph>
データベース内にあるデータでリスト5のようなXMLを生成するには、ビルダーファイルを使用します。
ビルダーはどのようにグラフ用XMLを構築するのでしょうか。答えは、アクション内に保存された@employee_details_with_timesheets変数を使用するのです。リスト6はビルダーファイルの内容を示しています。
リスト 6
timesheet_data.builder (in app/views/employees folder)
xml = Builder::XmlMarkup.new(:indent=>0) options = { :caption=>'Time Tracker Chart', :subcaption=>'For Employee '+ @employee_details_with_timesheets.name , :yAxisName=>'Hours Spent', :xAxisName=>'Day', :showValues=>'1', :formatNumberScale=>'0', :numberSuffix=>' hrs.' } xml.graph(options) do for timesheet in @employee_details_with_timesheets.timesheets do log_day = timesheet.log_date.strftime('%a') xml.set(:name=>log_day,:value=>timesheet.hours_spent,:color=>''+get_FC_color) end end
ビルダー内にて、まず0に等しい「indent」値で新しいXMLMarkupオブジェクトを作成し、このオブジェクトをXMLの構築に使用します。
グラフの構成に必要なすべてのオプションは、optionsという名のハッシュ内にあり、これは、最上位(グラフ)タグに渡されます。グラフに提供可能なオプションの詳細については、FusionChartsマニュアル一式を参照してください。XMLルートエレメントは「graph」です。この中に、選択した従業員の各タイムシートに一致する「set」エレメントがあります。各「set」エレメントは属性として名前と値を持ちます。名前には曜日が、値にはその従業員がその日に費やした時間が含まれます。ビルダーはコントローラアクション内にある@employee_details_with_timesheets変数を使用して、これらの値を入手します。
最後に、ビューページにおいて、パラメータとしてswfグラフファイル名、URL、XML、幅、高さ、debugMode、registerWithJSを利用とする機能render_chartを使用して、グラフがレンダリングされます。この機能は、libフォルダにあるfusioncharts_helperモジュール内で入手可能です。これは、リスト7に示すとおり、application_helper.rb内にインクルードすることによって、すべてのビューにアクセス可能となります。
リスト 7
application_helper.rb
require 'fusioncharts_helper' include FusionChartsHelper
グラフ表示に必要なswfファイルは、public/FusionChartsフォルダ内にあります。ここではColumn3D.swfが使用されていますが、他の種類の単独系グラフも、swfファイル名を変更するだけで作成可能です。データはdataXMLメソッドを使用して提供されていますが、dataURLでも提供可能です。この例はFusionChartsマニュアルに記載されています。
ここで、従業員ページのリストで従業員用の「Time Chart」リンクをクリックしてみると、2008年12月1日から2008年12月7日までの週に相当するタイムログエントリがグラフの形で表示されます。タイムシートグラフは、以下の図2と同様になります。
図 2
グラフ作成ステップのまとめ
アプリケーション内でFusionChartsを設定し、application_helper.rb内にFusionChartsHelperをインクルードした後、以下のステップを行います。
- コントローラアクション内で、データベースからグラフに必要なデータを見つける。
- ビルダーを記述してこのデータからグラフ用XMLを構築する。
- ステップ1におけるコントローラアクション用のビューで、データを渡すか、ビルダーにコントローラアクションからのデータを使用させるかして、ビルダーからXMLを入手する。
- 次に、適切なパラメータ(ステップ3で入手したXMLも含む)で機能render_chartを呼び出す。
この記事では、タイムトラッカーアプリケーションによって、Ruby on Rails上でFusionChartsを使用して単純なグラフを作成する方法を説明しました。サンプルアプリケーションにいくつか変更を加えると、すべての従業員向けのタイムログ概要でグラフを作成できます。このグラフから、特定の従業員について掘り下げ、その従業員用の時間の詳細を得ることができるでしょう。グラフの検索にはAjaxが使用可能です。可能性は無限に広がります。FusionChartsダウンロードパッケージ自体には、検索可能ないくつかの例が含まれています。この記事で説明したサンプルアプリケーションの完全版はここ(リンク)でダウンロード可能です。
著者について
著者は、IT業界で6年以上の経験を持つコンサルタントで、J2EEスタック、Ruby On Rails、およびPHPに関連する幅広いWeb技術に関心を持っています。
原文はこちらです:http://www.infoq.com/articles/sharma-charts-in-rails
(このArticleは2009年1月29日に原文が掲載されました)