Google ChartのRuby Wrapper

## 背景
WebアプリケーションにGoogle Chartを使ったグラフを表示させるために、chartを表示させるJavaScriptを生成するRubyのWrapperを作った。

## コード
- 基本的な構成はChartクラスで行い、個別のチャートについての相違をサブクラスで実装している。
- 現状は、パイチャート、バーチャート、ラインチャートのみ作成。
- ヘッダーに、以下の記載が必要（erbテンプレートを使用した例）

```html
<html>
<head>
  <script type="text/javascript" src="https://www.google.com/jsapi"></script>
  <%=header%>  
</head>
<body>
...
<%=body%>
...
</html>
```

```rb
# encoding: utf-8
require 'erb'
require 'date'

class Chart
  attr_accessor :column,:data,:options,:name

  def self.to_js_date(d)
    a = Date.parse(d)
    "#{a.year},#{a.mon - 1},#{a.mday}"
  end

  def initialize(column,data,options,name)
    @column = column
    @data = data
    @options = options
    @name = name
    @chart_type = ''
  end

  # body部分に表示するスクリプト
  def body_script
    erb = ERB.new(<<-EOS,nil,'-')
<div id="<%=@name%>"></div>
EOS
    erb.result(binding)
  end

  def header_script
    erb = ERB.new(<<-EOS,nil,'-')
<script type="text/javascript">
google.load('visualization', '1.0', {'packages':['corechart']});
google.setOnLoadCallback(drawChart);

function drawChart() {
  var data = new google.visualization.DataTable();
  <%- @column.each do |c| -%>
  data.addColumn('<%=c.keys[0]%>','<%=c.values[0]%>');
  <%- end -%>
  data.addRows([
  <%- @data.each_with_index do |d,index| -%>
  [<%=data_format(d)%>]<%="," if index < @data.length - 1%>
  <%- end -%>
  ]);

  var options ={
	  <%- @options.each_with_index do |o,index| -%>
    '<%=o.keys[0]%>':<%=o.values[0]%><%="," if index < @options.length - 1%>
    <%- end -%>
  };

  var chart = new google.visualization.<%=@chart_type%>(document.getElementById('<%=@name%>'));
  chart.draw(data, options);
}
</script>
EOS
    erb.result(binding)
  end

  def data_format(d)
    d.inspect
  end

end

# PieChart
class PieChart < Chart
  def initialize(column,data,options,name)
    super
    @chart_type = 'PieChart'
  end

  def data_format(d)
    "'#{d.keys[0]}',#{d.values[0]}"
  end
end

# LineChart
class LineChart < Chart
  def initialize(column,data,options,name)
    super
    @chart_type = 'LineChart'
  end

  def data_format(d)
    d.each_with_index.inject("") do |r,(v,index)|
      r += "new Date(#{Chart.to_js_date(v)})" if index == 0
      r += "#{v}" if index > 0
      r += "," if index < d.length - 1
      r
    end
  end
end

# BarChart
class BarChart < Chart
  def initialize(column,data,options,name)
    super
    @chart_type = 'BarChart'
  end

  def data_format(d)
    "'#{d.keys[0]}',#{d.values[0]}"
  end
end

```

## 使い方
- column,data,options,nameを指定
- header_script及びbody_scriptでJavaScriptを生成
- 対象ページには、Google Chartへのリンクを指定

## サンプル
### パイチャート

```rb
column = [{'string' => '会社名'},{'number' => '金額'}]
data = [
  {'A社' => '10000'},
  {'B社' => '20000'},
  {'C社' => '30000'},
  {'D社' => '40000'}
]
options = [{'width' => 400},{'height' => 300}]  # 400px x 300px とする場合
name = 'pie_chart'                              # 識別できればOK

pc = PieChart.new(column,data,options,name)
header = pc.header_script   # HTMLのheaderタグ内に記載
body = pc.body_script       # HTMLのbodyタグ内に記載
```

### バーチャート

```rb
column = [{'string' => '会社名'},{'number' => '金額'}]
data = [
  {'A社' => '10000'},
  {'B社' => '20000'},
  {'C社' => '30000'},
  {'D社' => '40000'}
]
options = [{'width' => 400},{'height' => 300}]  # 400px x 300px とする場合
name = 'bar_chart'                              # 識別できればOK

bc = BarChart.new(column,data,options,name)
header = bc.header_script   # HTMLのheaderタグ内に記載/ERBでの埋め込みなどで使用
body = bc.body_script       # HTMLのbodyタグ内に記載/ERBでの埋め込みなどで使用
```

### ラインチャート

```rb
column = [{'string' => '決算期'},{'number' => 'A社'},{'number' => 'B社'}]
fy = ['2012年度','2013年度','2014年度']
a = [10000,9000,12000]
b = [20000,21000,19000]
data = fy.zip(a,b)
options = [{'width' => 400},{'height' => 300}]  # 400px x 300px とする場合
name = 'line_chart'                              # 識別できればOK

lc = LineChart(column,data,options,name)
header = lc.header_script   # HTMLのheaderタグ内に記載/ERBでの埋め込みなどで使用
body = lc.body_script       # HTMLのbodyタグ内に記載/ERBでの埋め込みなどで使用
```