forked from CoralineAda/seer
/
line_chart.rb
141 lines (120 loc) · 4.87 KB
/
line_chart.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
module Seer
# =USAGE
#
# In your controller:
#
# @data = Widgets.all # Must be an array of objects that respond to the specidied data method
# # (In this example, 'quantity'
#
# @series = @data.map{|w| w.widget_stats} # An array of arrays
#
# In your view:
#
# <div id="chart"></div>
#
# <%= Seer::visualize(
# @data,
# :as => :line_chart,
# :in_element => 'chart',
# :series => {
# :series_label => 'name',
# :data_label => 'date',
# :data_method => 'quantity',
# :data_series => @series
# },
# :chart_options => {
# :height => 300,
# :width => 300,
# :axis_font_size => 11,
# :colors => ['#7e7587','#990000','#009900'],
# :title => "Widget Quantities",
# :point_size => 5
# }
# )
# -%>
#
# For details on the chart options, see the Google API docs at
# http://code.google.com/apis/visualization/documentation/gallery/linechart.html
#
class LineChart
include Seer::Chart
# Graph options
attr_accessor :axis_color, :axis_background_color, :axis_font_size, :background_color, :border_color, :enable_tooltip, :focus_border_color, :height, :legend, :legend_background_color, :legend_font_size, :legend_text_color, :line_size, :log_scale, :max, :min, :point_size, :reverse_axis, :show_categories, :smooth_line, :title, :title_x, :title_y, :title_color, :title_font_size, :tooltip_font_size, :tooltip_height, :number, :tooltip_width, :width
# Graph data
attr_accessor :data, :data_label, :data_method, :data_series, :data_table, :series_label
def initialize(args={}) #:nodoc:
# Standard options
args.each{ |method,arg| self.send("#{method}=",arg) if self.respond_to?(method) }
# Chart options
args[:chart_options].each{ |method, arg| self.send("#{method}=",arg) if self.respond_to?(method) }
# Handle defaults
@colors ||= args[:chart_options][:colors] || DEFAULT_COLORS
@legend ||= args[:chart_options][:legend] || DEFAULT_LEGEND_LOCATION
@height ||= args[:chart_options][:height] || DEFAULT_HEIGHT
@width ||= args[:chart_options][:width] || DEFAULT_WIDTH
@data_table = []
end
def data_columns #:nodoc:
_data_columns = " data.addRows(#{data_rows.size});\r"
_data_columns << " data.addColumn('string', 'Date');\r"
data.each do |datum|
_data_columns << " data.addColumn('number', '#{datum.send(series_label)}');\r"
end
_data_columns
end
def data_table #:nodoc:
_rows = data_rows
_rows.each_with_index do |r,i|
@data_table << " data.setCell(#{i}, 0,'#{r}');\r"
end
data_series.each_with_index do |column,i|
column.each_with_index do |c,j|
@data_table << "data.setCell(#{j},#{i+1},#{c.send(data_method)});\r"
end
end
@data_table
end
def data_rows
data_series.inject([]) do |rows, element|
rows |= element.map { |e| e.send(data_label) }
end
end
def nonstring_options #:nodoc:
[ :axis_font_size, :colors, :enable_tooltip, :height, :legend_font_size, :line_size, :log_scale, :max, :min, :point_size, :reverse_axis, :show_categories, :smooth_line, :title_font_size, :tooltip_font_size, :tooltip_height, :tooltip_width, :width]
end
def string_options #:nodoc:
[ :axis_color, :axis_background_color, :background_color, :border_color, :focus_border_color, :legend, :legend_background_color, :legend_text_color, :title, :title_x, :title_y, :title_color ]
end
def to_js #:nodoc:
%{
<script type="text/javascript">
google.load('visualization', '1', {'packages':['linechart']});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
#{data_columns}
#{data_table.to_s}
var options = {};
#{options}
var container = document.getElementById('#{self.chart_element}');
var chart = new google.visualization.LineChart(container);
chart.draw(data, options);
}
</script>
}
end
# ====================================== Class Methods =========================================
def self.render(data, args) #:nodoc:
graph = Seer::LineChart.new(
:data => data,
:series_label => args[:series][:series_label],
:data_series => args[:series][:data_series],
:data_label => args[:series][:data_label],
:data_method => args[:series][:data_method],
:chart_options => args[:chart_options],
:chart_element => args[:in_element] || 'chart'
)
graph.to_js
end
end
end