背景
WebアプリケーションにGoogle Chartを使ったグラフを表示させるために、chartを表示させるJavaScriptを生成するRubyのWrapperを作った。
コード
- 基本的な構成はChartクラスで行い、個別のチャートについての相違をサブクラスで実装している。
- 現状は、パイチャート、バーチャート、ラインチャートのみ作成。
- ヘッダーに、以下の記載が必要(erbテンプレートを使用した例)
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<%=header%>
</head>
<body>
...
<%=body%>
...
</html>
# 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へのリンクを指定
サンプル
パイチャート
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タグ内に記載
バーチャート
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での埋め込みなどで使用
ラインチャート
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での埋め込みなどで使用