gchartrb 0.5.4 → 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/Rakefile +1 -1
- data/lib/google_chart/base.rb +436 -436
- data/lib/test.rb +15 -0
- metadata +2 -2
data/History.txt
CHANGED
data/Rakefile
CHANGED
@@ -8,7 +8,7 @@ class Hoe
|
|
8
8
|
def extra_deps; @extra_deps.reject { |x| Array(x).first == "hoe" } end
|
9
9
|
end # copied from the Rakefile of the sup project
|
10
10
|
|
11
|
-
Hoe.new('gchartrb', "0.5.
|
11
|
+
Hoe.new('gchartrb', "0.5.5") do |p|
|
12
12
|
p.rubyforge_name = 'gchartrb'
|
13
13
|
p.author = 'Deepak Jois'
|
14
14
|
p.email = 'deepak.jois@gmail.com'
|
data/lib/google_chart/base.rb
CHANGED
@@ -1,460 +1,460 @@
|
|
1
1
|
require 'uri'
|
2
2
|
|
3
3
|
module GoogleChart
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
4
|
+
class Base
|
5
|
+
BASE_URL = "http://chart.apis.google.com/chart?"
|
6
|
+
|
7
|
+
SIMPLE_ENCODING = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'.split('');
|
8
|
+
COMPLEX_ENCODING_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-.'.split('');
|
9
|
+
@@complex_encoding = []
|
10
|
+
COMPLEX_ENCODING_ALPHABET.each_with_index do |outer,index_outer|
|
11
|
+
COMPLEX_ENCODING_ALPHABET.each_with_index do |inner, index_inner|
|
12
|
+
@@complex_encoding[index_outer * 64 + index_inner] = outer + inner
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
SHAPE_MARKERS = {:arrow => "a",
|
17
|
+
:cross => "c",
|
18
|
+
:diamond => "d",
|
19
|
+
:circle => "o",
|
20
|
+
:square => "s",
|
21
|
+
:vline_segment => "v",
|
22
|
+
:vline_full => "V",
|
23
|
+
:hline_full => "h",
|
24
|
+
:x => "x"
|
25
|
+
}
|
26
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
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
27
|
+
# Size of the chart in WIDTHxHEIGHT format
|
28
|
+
attr_accessor :chart_size
|
29
|
+
|
30
|
+
# Type of the chart. Usually, you do not need to set this yourself
|
31
|
+
attr_accessor :chart_type
|
32
|
+
|
33
|
+
# Chart title
|
34
|
+
attr_accessor :chart_title
|
35
|
+
|
36
|
+
# RRGGBB hex value for the color of the title
|
37
|
+
attr_accessor :title_color
|
38
|
+
|
39
|
+
# Font size of the title
|
40
|
+
attr_accessor :title_font_size
|
41
|
+
|
42
|
+
# Data encoding to use. Can be one of <tt>:simple</tt>, <tt>:text</tt> or <tt>:extended</tt> (see http://code.google.com/apis/chart/#chart_data)
|
43
|
+
attr_accessor :data_encoding
|
44
|
+
|
45
|
+
# A hash of the params used to construct the URL
|
46
|
+
attr_accessor :params
|
47
|
+
|
48
|
+
# Set to <tt>true</tt> or <tt>false</tt> to show or hide the chart legend. Not applicable for Scatter Chart.
|
49
|
+
attr_accessor :show_legend
|
50
|
+
|
51
|
+
def initialize(chart_size, chart_title)
|
52
|
+
self.params = Hash.new
|
53
|
+
@labels = []
|
54
|
+
@data = []
|
55
|
+
@colors = []
|
56
|
+
@axis = []
|
57
|
+
@markers = []
|
58
|
+
self.chart_size = chart_size
|
59
|
+
self.chart_title = chart_title
|
60
|
+
self.data_encoding = :simple
|
61
|
+
self.show_legend = true
|
62
|
+
end
|
63
|
+
|
64
|
+
# Generates the URL string that can be used to retrieve the graph image in PNG format.
|
65
|
+
# Use this after assigning all the properties to the graph
|
66
|
+
# You can pass in additional params as a hash for features that may not have been implemented
|
67
|
+
# For e.g
|
68
|
+
# lc = GoogleChart::LineChart.new('320x200', "Line Chart", false)
|
69
|
+
# lc.data "Trend 1", [5,4,3,1,3,5,6], '0000ff'
|
70
|
+
# lc.data "Trend 2", [1,2,3,4,5,6], '00ff00'
|
71
|
+
# lc.data "Trend 3", [6,5,4,3,2,1], 'ff0000'
|
72
|
+
# puts lc.to_url({:chm => "000000,0,0.1,0.11"}) # Single black line as a horizontal marker
|
73
|
+
def to_url(extras={})
|
74
|
+
params.clear
|
75
|
+
set_size
|
76
|
+
set_type
|
77
|
+
set_colors
|
78
|
+
set_fill_options
|
79
|
+
add_axis unless @axis.empty?
|
80
|
+
add_grid
|
81
|
+
add_data
|
82
|
+
add_markers unless @markers.empty?
|
83
|
+
add_labels(@labels) if [:p, :p3].member?(self.chart_type)
|
84
|
+
add_legend(@labels) if show_legend
|
85
|
+
add_title if chart_title.to_s.length > 0
|
86
|
+
|
87
|
+
params.merge!(extras)
|
88
|
+
query_string = params.map { |k,v| "#{k}=#{URI.escape(v.to_s).gsub(/%20/,'+').gsub(/%7C/,'|')}" }.join('&')
|
89
|
+
BASE_URL + query_string
|
90
|
+
end
|
91
|
+
|
92
|
+
# Adds the data to the chart, according to the type of the graph being generated.
|
93
|
+
#
|
94
|
+
# [+name+] is a string containing a label for the data.
|
95
|
+
# [+value+] is either a number or an array of numbers containing the data. Pie Charts and Venn Diagrams take a single number, but other graphs require an array of numbers
|
96
|
+
# [+color+ (optional)] is a hexadecimal RGB value for the color to represent the data
|
97
|
+
#
|
98
|
+
# ==== Examples
|
99
|
+
#
|
100
|
+
# for GoogleChart::LineChart (normal)
|
101
|
+
# lc.data "Trend 1", [1,2,3,4,5], 'ff00ff'
|
102
|
+
#
|
103
|
+
# for GoogleChart::LineChart (XY chart)
|
104
|
+
# lc.data "Trend 2", [[4,5], [2,2], [1,1], [3,4]], 'ff00ff'
|
105
|
+
#
|
106
|
+
# for GoogleChart::PieChart
|
107
|
+
# lc.data "Apples", 5, 'ff00ff'
|
108
|
+
# lc.data "Oranges", 7, '00ffff'
|
109
|
+
def data(name, value, color=nil)
|
110
|
+
@data << value
|
111
|
+
@labels << name
|
112
|
+
@colors << color if color
|
113
|
+
end
|
114
|
+
|
115
|
+
# Allows (optional) setting of a max value for the chart, which will be used for data encoding and axis plotting.
|
116
|
+
# The value to pass depends on the type of chart
|
117
|
+
# * For Line Chart and Bar Charts it should be a single integer or float value
|
118
|
+
# * For Scatter Charts and Line XY Charts, you MUST pass an array containing the maximum values for X and Y
|
119
|
+
#
|
120
|
+
# ==== Examples
|
121
|
+
# For bar charts
|
122
|
+
# bc.max_value 5 # 5 will be used to calculate the relative encoding values
|
123
|
+
# For scatter chart
|
124
|
+
# sc.max_value [5,6] # 5 is the max x value and 6 is the max y value
|
125
|
+
#
|
126
|
+
# Note : MAKE SURE you are passing the right values otherwise an exception will be raised
|
127
|
+
def max_value(value)
|
128
|
+
if [:lxy, :s].member?(self.chart_type) and value.is_a?(Array)
|
129
|
+
@max_x = value.first
|
130
|
+
@max_y = value.last
|
131
|
+
elsif [:lc,:bhg,:bhs,:bvg,:bvs] and (value.is_a?(Integer) or value.is_a?(Float))
|
132
|
+
@max_data = value
|
133
|
+
else
|
134
|
+
raise "Invalid max value for this chart type"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# Adds a background or chart fill. Call this option twice if you want both a background and a chart fill
|
139
|
+
# [+bg_or_c+] Can be one of <tt>:background</tt> or <tt>:chart</tt> depending on the kind of fill requested
|
140
|
+
# [+type+] Can be one of <tt>:solid</tt>, <tt>:gradient</tt> or <tt>:stripes</tt>
|
141
|
+
# [+options+] : Options depend on the type of fill selected above
|
142
|
+
#
|
143
|
+
# ==== Options
|
144
|
+
# For <tt>:solid</tt> type
|
145
|
+
# * A <tt>:color</tt> option which specifies the RGB hex value of the color to be used as a fill. For e.g <tt>lc.fill(:chart, :solid, {:color => 'ffcccc'})</tt>
|
146
|
+
#
|
147
|
+
# For <tt>:gradient</tt> type
|
148
|
+
# * An <tt>:angle</tt>, which is the angle of the gradient between 0(horizontal) and 90(vertical)
|
149
|
+
# * A <tt>:color</tt> option which is a 2D array containing the colors and an offset each, which specifies at what point the color is pure where: 0 specifies the right-most chart position and 1 the left-most. e,g <tt>lc.fill :background, :gradient, :angle => 0, :color => [['76A4FB',1],['ffffff',0]]</tt>
|
150
|
+
#
|
151
|
+
# For <tt>:stripes</tt> type
|
152
|
+
# * An <tt>:angle</tt>, which is the angle of the stripe between 0(horizontal) and 90(vertical)
|
153
|
+
# * A <tt>:color</tt> option which is a 2D array containing the colors and width value each, which must be between 0 and 1 where 1 is the full width of the chart. for e.g <tt>lc.fill :chart, :stripes, :angle => 90, :color => [ ['76A4FB',0.2], ['ffffff',0.2] ]</tt>
|
154
|
+
def fill(bg_or_c, type, options = {})
|
155
|
+
case bg_or_c
|
156
|
+
when :background
|
157
|
+
@background_fill = "bg," + process_fill_options(type, options)
|
158
|
+
when :chart
|
159
|
+
@chart_fill = "c," + process_fill_options(type, options)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# Adds an axis to the graph. Not applicable for Pie Chart (GoogleChart::PieChart) or Venn Diagram (GoogleChart::VennDiagram)
|
164
|
+
#
|
165
|
+
# [+type+] is a symbol which can be one of <tt>:x</tt>, <tt>:y</tt>, <tt>:right</tt>, <tt>:top</tt>
|
166
|
+
# [+options+] is a hash containing the options (see below)
|
167
|
+
#
|
168
|
+
# ==== Options
|
169
|
+
# Not all the options are mandatory.
|
170
|
+
# [<tt>:labels</tt>] An array containing the labels for the axis
|
171
|
+
# [<tt>:positions</tt>] An Array containing the positions for the labels
|
172
|
+
# [<tt>:range</tt>] An array containing 2 elements, the start value and end value
|
173
|
+
#
|
174
|
+
# axis styling options have to be specified as follows
|
175
|
+
# [<tt>:color</tt>] Hexadecimal RGB value for the color to represent the data for the axis labels
|
176
|
+
# [<tt>:font_size</tt>] Font size of the labels in pixels
|
177
|
+
# [<tt>:alignment</tt>] can be one of <tt>:left</tt>, <tt>:center</tt> or <tt>:right</tt>
|
178
|
+
#
|
179
|
+
# ==== Examples
|
180
|
+
# lc.axis :y, :range => [0,6], :color => 'ff00ff', :font_size => 16, :alignment => :center
|
181
|
+
#
|
182
|
+
def axis(type, options = {})
|
183
|
+
raise "Illegal axis type" unless [:x, :y, :right, :top].member?(type)
|
184
|
+
@axis << [type, options]
|
185
|
+
end
|
186
|
+
|
187
|
+
# Adds a grid to the graph. Applicable only for Line Chart (GoogleChart::LineChart) and Scatter Chart (GoogleChart::ScatterChart)
|
188
|
+
#
|
189
|
+
# [+options+] is a hash containing the options (see below)
|
190
|
+
#
|
191
|
+
# === Options
|
192
|
+
# [<tt>:xstep</tt>] X axis step size
|
193
|
+
# [<tt>:ystep</tt>] Y axis step size
|
194
|
+
# [<tt>:length_segment</tt> (optional)] Length of the line segement. Useful with the :length_blank value to have dashed lines
|
195
|
+
# [<tt>:length_blank</tt> (optional)] Length of the blank segment. use 0 if you want a solid grid
|
196
|
+
#
|
197
|
+
# === Examples
|
198
|
+
# lc.grid :x_step => 5, :y_step => 5, :length_segment => 1, :length_blank => 0
|
199
|
+
#
|
200
|
+
def grid(options={})
|
201
|
+
@grid_str = "#{options[:x_step].to_f},#{options[:y_step].to_f}"
|
202
|
+
if options[:length_segment] or options[:length_blank]
|
203
|
+
@grid_str += ",#{options[:length_segment].to_f},#{options[:length_blank].to_f}"
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
# Defines a horizontal or vertical range marker. Applicable for line charts and vertical charts
|
208
|
+
#
|
209
|
+
# [+alignment+] can be <tt>:horizontal</tt> or <tt>:vertical</tt>
|
210
|
+
# [+options+] specifies the color, start point and end point
|
211
|
+
#
|
212
|
+
# ==== Options
|
213
|
+
# [<tt>:color</tt>] RRGGBB hex value for the color of the range marker
|
214
|
+
# [<tt>:start_point</tt>] position on the x-axis/y-axis at which the range starts where 0.00 is the left/bottom and 1.00 is the right/top
|
215
|
+
# [<tt>:end_point</tt>] position on the x-axis/y-axis at which the range ends where 0.00 is the left/bottom and 1.00 is the right/top
|
216
|
+
#
|
217
|
+
# ==== Examples
|
218
|
+
# lc.range_marker :horizontal, :color => 'E5ECF9', :start_point => 0.1, :end_point => 0.5
|
219
|
+
# lc.range_marker :vertical, :color => 'a0bae9', :start_point => 0.1, :end_point => 0.5
|
220
|
+
def range_marker(alignment, options={})
|
221
|
+
raise "Invalid alignment specified" unless [:horizontal, :vertical].member?(alignment)
|
222
|
+
str = (alignment == :horizontal ) ? "r" : "R"
|
223
|
+
str += ",#{options[:color]},0,#{options[:start_point]},#{options[:end_point]}"
|
224
|
+
@markers << str
|
225
|
+
end
|
226
226
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
227
|
+
# Defines a shape marker. Applicable for line charts and scatter plots
|
228
|
+
#
|
229
|
+
# [+type+] can be <tt>:arrow</tt>, <tt>:cross</tt>, <tt>:diamond</tt>, <tt>:circle</tt>, <tt>:square</tt>, <tt>:vline_segment</tt>, <tt>:vline_full</tt>, <tt>:hline_full</tt>, <tt>:x</tt>
|
230
|
+
# [+options+] specifies the color, data set index, data point index and size in pixels
|
231
|
+
#
|
232
|
+
# ==== Options
|
233
|
+
# [<tt>:color</tt>] RRGGBB hex value for the color of the range marker
|
234
|
+
# [<tt>:data_set_index</tt>] the index of the line on which to draw the marker. This is 0 for the first data set, 1 for the second and so on.
|
235
|
+
# [<tt>:data_point_index</tt>] is a floating point value that specifies on which data point of the data set the marker will be drawn. This is 0 for the first data point, 1 for the second and so on. Specify a fraction to interpolate a marker between two points.
|
236
|
+
# [<tt>:size</tt>] is the size of the marker in pixels.
|
237
|
+
#
|
238
|
+
# ==== Examples
|
239
|
+
# lcxy.shape_marker :circle, :color => "000000", :data_set_index => 1, :data_point_index => 2, :pixel_size => 10
|
240
|
+
# lcxy.shape_marker :cross, :color => "E5ECF9", :data_set_index => 0, :data_point_index => 0.5, :pixel_size => 10
|
241
|
+
def shape_marker(type, options={})
|
242
|
+
raise "Invalid shape marker type specified" unless SHAPE_MARKERS.has_key?(type)
|
243
|
+
shape_marker_str = "#{SHAPE_MARKERS[type]},#{options[:color]},#{options[:data_set_index]},#{options[:data_point_index]},#{options[:pixel_size]}"
|
244
|
+
@markers << shape_marker_str
|
245
|
+
end
|
246
|
+
|
247
|
+
protected
|
248
|
+
|
249
|
+
def process_fill_options(type, options)
|
250
|
+
case type
|
251
|
+
when :solid
|
252
|
+
"s,#{options[:color]}"
|
253
|
+
when :gradient
|
254
|
+
"lg,#{options[:angle]}," + options[:color].collect { |o| "#{o.first},#{o.last}" }.join(",")
|
255
|
+
when :stripes
|
256
|
+
"ls,#{options[:angle]}," + options[:color].collect { |o| "#{o.first},#{o.last}" }.join(",")
|
257
|
+
end
|
258
|
+
|
259
|
+
end
|
260
|
+
|
261
|
+
def set_type
|
262
|
+
params.merge!({:cht => chart_type})
|
263
|
+
end
|
264
|
+
|
265
|
+
def set_size
|
266
|
+
params.merge!({:chs => chart_size})
|
267
|
+
end
|
268
|
+
|
269
|
+
def set_colors
|
270
|
+
params.merge!({:chco => @colors.collect{|c| c.downcase}.join(",") }) if @colors.size > 0
|
271
|
+
end
|
272
|
+
|
273
|
+
def set_fill_options
|
274
|
+
fill_opt = [@background_fill, @chart_fill].compact.join("|")
|
275
|
+
params.merge!({:chf => fill_opt}) if fill_opt.length > 0
|
276
|
+
end
|
277
|
+
|
278
|
+
def add_labels(labels)
|
279
|
+
params.merge!({:chl => labels.collect{|l| l.to_s}.join("|") }) if self.show_labels
|
280
|
+
end
|
281
|
+
|
282
|
+
def add_legend(labels)
|
283
|
+
params.merge!({:chdl => labels.collect{ |l| l.to_s}.join("|")})
|
284
|
+
end
|
285
|
+
|
286
|
+
def add_title
|
287
|
+
params.merge!({:chtt => chart_title})
|
288
|
+
params.merge!({:chts => title_color}) if title_color
|
289
|
+
params.merge!({:chts => "#{title_color},#{title_font_size}"}) if title_color and title_font_size
|
290
|
+
end
|
291
|
+
|
292
|
+
def add_axis
|
293
|
+
chxt = []
|
294
|
+
chxl = []
|
295
|
+
chxp = []
|
296
|
+
chxr = []
|
297
|
+
chxs = []
|
298
|
+
# Process params
|
299
|
+
@axis.each_with_index do |axis, idx|
|
300
|
+
# Find axis type
|
301
|
+
case axis.first
|
302
|
+
when :x
|
303
|
+
chxt << "x"
|
304
|
+
when :y
|
305
|
+
chxt << "y"
|
306
|
+
when :top
|
307
|
+
chxt << "r"
|
308
|
+
when :right
|
309
|
+
chxt << "t"
|
245
310
|
end
|
246
311
|
|
247
|
-
|
248
|
-
|
249
|
-
def process_fill_options(type, options)
|
250
|
-
case type
|
251
|
-
when :solid
|
252
|
-
"s,#{options[:color]}"
|
253
|
-
when :gradient
|
254
|
-
"lg,#{options[:angle]}," + options[:color].collect { |o| "#{o.first},#{o.last}" }.join(",")
|
255
|
-
when :stripes
|
256
|
-
"ls,#{options[:angle]}," + options[:color].collect { |o| "#{o.first},#{o.last}" }.join(",")
|
257
|
-
end
|
258
|
-
|
259
|
-
end
|
312
|
+
# Axis labels
|
313
|
+
axis_opts = axis.last
|
260
314
|
|
261
|
-
|
262
|
-
|
315
|
+
if axis_opts[:labels]
|
316
|
+
chxl[idx] = "#{idx}:|" + axis_opts[:labels].join("|")
|
263
317
|
end
|
264
318
|
|
265
|
-
|
266
|
-
|
319
|
+
# Axis positions
|
320
|
+
if axis_opts[:positions]
|
321
|
+
chxp[idx] = "#{idx}," + axis_opts[:positions].join(",")
|
267
322
|
end
|
268
323
|
|
269
|
-
|
270
|
-
|
324
|
+
# Axis range
|
325
|
+
if axis_opts[:range]
|
326
|
+
chxr[idx] = "#{idx},#{axis_opts[:range].first},#{axis_opts[:range].last}"
|
271
327
|
end
|
272
328
|
|
273
|
-
|
274
|
-
|
275
|
-
|
329
|
+
# Axis Styles
|
330
|
+
if axis_opts[:color] or axis_opts[:font_size] or axis_opts[:alignment]
|
331
|
+
if axis_opts[:alignment]
|
332
|
+
alignment = case axis_opts[:alignment]
|
333
|
+
when :center
|
334
|
+
0
|
335
|
+
when :left
|
336
|
+
-1
|
337
|
+
when :right
|
338
|
+
1
|
339
|
+
else
|
340
|
+
nil
|
341
|
+
end
|
342
|
+
end
|
343
|
+
chxs[idx] = "#{idx}," + [axis_opts[:color], axis_opts[:font_size], alignment].compact.join(",")
|
276
344
|
end
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
345
|
+
end
|
346
|
+
|
347
|
+
# Add to params hash
|
348
|
+
params.merge!({ :chxt => chxt.join(",") }) unless chxt.empty?
|
349
|
+
params.merge!({ :chxl => chxl.compact.join("|") }) unless chxl.compact.empty?
|
350
|
+
params.merge!({ :chxp => chxp.compact.join("|") }) unless chxp.compact.empty?
|
351
|
+
params.merge!({ :chxr => chxr.compact.join("|") }) unless chxr.compact.empty?
|
352
|
+
params.merge!({ :chxs => chxs.compact.join("|") }) unless chxs.compact.empty?
|
353
|
+
end
|
281
354
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
params.merge!({:chts => "#{title_color},#{title_font_size}"}) if title_color and title_font_size
|
290
|
-
end
|
291
|
-
|
292
|
-
def add_axis
|
293
|
-
chxt = []
|
294
|
-
chxl = []
|
295
|
-
chxp = []
|
296
|
-
chxr = []
|
297
|
-
chxs = []
|
298
|
-
# Process params
|
299
|
-
@axis.each_with_index do |axis, idx|
|
300
|
-
# Find axis type
|
301
|
-
case axis.first
|
302
|
-
when :x
|
303
|
-
chxt << "x"
|
304
|
-
when :y
|
305
|
-
chxt << "y"
|
306
|
-
when :top
|
307
|
-
chxt << "r"
|
308
|
-
when :right
|
309
|
-
chxt << "t"
|
310
|
-
end
|
311
|
-
|
312
|
-
# Axis labels
|
313
|
-
axis_opts = axis.last
|
314
|
-
|
315
|
-
if axis_opts[:labels]
|
316
|
-
chxl[idx] = "#{idx}:|" + axis_opts[:labels].join("|")
|
317
|
-
end
|
318
|
-
|
319
|
-
# Axis positions
|
320
|
-
if axis_opts[:positions]
|
321
|
-
chxp[idx] = "#{idx}," + axis_opts[:positions].join(",")
|
322
|
-
end
|
323
|
-
|
324
|
-
# Axis range
|
325
|
-
if axis_opts[:range]
|
326
|
-
chxr[idx] = "#{idx},#{axis_opts[:range].first},#{axis_opts[:range].last}"
|
327
|
-
end
|
328
|
-
|
329
|
-
# Axis Styles
|
330
|
-
if axis_opts[:color] or axis_opts[:font_size] or axis_opts[:alignment]
|
331
|
-
if axis_opts[:alignment]
|
332
|
-
alignment = case axis_opts[:alignment]
|
333
|
-
when :center
|
334
|
-
0
|
335
|
-
when :left
|
336
|
-
-1
|
337
|
-
when :right
|
338
|
-
1
|
339
|
-
else
|
340
|
-
nil
|
341
|
-
end
|
342
|
-
end
|
343
|
-
chxs[idx] = "#{idx}," + [axis_opts[:color], axis_opts[:font_size], alignment].compact.join(",")
|
344
|
-
end
|
345
|
-
end
|
346
|
-
|
347
|
-
# Add to params hash
|
348
|
-
params.merge!({ :chxt => chxt.join(",") }) unless chxt.empty?
|
349
|
-
params.merge!({ :chxl => chxl.compact.join("|") }) unless chxl.compact.empty?
|
350
|
-
params.merge!({ :chxp => chxp.compact.join("|") }) unless chxp.compact.empty?
|
351
|
-
params.merge!({ :chxr => chxr.compact.join("|") }) unless chxr.compact.empty?
|
352
|
-
params.merge!({ :chxs => chxs.compact.join("|") }) unless chxs.compact.empty?
|
353
|
-
end
|
354
|
-
|
355
|
-
def add_grid
|
356
|
-
params.merge!({ :chg => @grid_str }) if @grid_str
|
357
|
-
end
|
358
|
-
|
359
|
-
def add_markers
|
360
|
-
params.merge!({:chm => @markers.join("|")})
|
361
|
-
end
|
355
|
+
def add_grid
|
356
|
+
params.merge!({ :chg => @grid_str }) if @grid_str
|
357
|
+
end
|
358
|
+
|
359
|
+
def add_markers
|
360
|
+
params.merge!({:chm => @markers.join("|")})
|
361
|
+
end
|
362
362
|
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
363
|
+
def add_data
|
364
|
+
converted_data = process_data
|
365
|
+
case data_encoding
|
366
|
+
when :simple
|
367
|
+
converted_data = "s:" + converted_data
|
368
|
+
when :text
|
369
|
+
converted_data = "t:" + converted_data
|
370
|
+
when :extended
|
371
|
+
converted_data = "e:" + converted_data
|
372
|
+
else
|
373
|
+
raise "Illegal Encoding Specified"
|
374
|
+
end
|
375
|
+
params.merge!({:chd => converted_data})
|
376
|
+
end
|
377
|
+
|
378
|
+
def encode_data(values, max_value=nil)
|
379
|
+
case data_encoding
|
380
|
+
when :simple
|
381
|
+
simple_encode(values, max_value)
|
382
|
+
when :text
|
383
|
+
text_encode(values, max_value)
|
384
|
+
when :extended
|
385
|
+
extended_encode(values, max_value)
|
386
|
+
else
|
387
|
+
raise "Illegal Encoding Specified"
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
def simple_encode(values, max_value=nil)
|
392
|
+
alphabet_length = 61
|
393
|
+
max_value = values.max unless max_value
|
394
394
|
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
end
|
405
|
-
end
|
406
|
-
|
407
|
-
return chart_data.join('')
|
408
|
-
end
|
409
|
-
|
410
|
-
def text_encode(values, max_value=nil)
|
411
|
-
max_value = values.max unless max_value
|
412
|
-
values.inject("") { |sum, v|
|
413
|
-
if max_value == 0
|
414
|
-
sum += "0,"
|
415
|
-
else
|
416
|
-
sum += ( "%.1f" % (v*100/max_value) ) + ","
|
417
|
-
end
|
418
|
-
}.chomp(",")
|
419
|
-
end
|
420
|
-
|
421
|
-
def extended_encode(values, max_value)
|
422
|
-
max_value = values.max unless max_value
|
423
|
-
values.collect { |v|
|
424
|
-
if max_value == 0
|
425
|
-
@@complex_encoding[0]
|
426
|
-
else
|
427
|
-
@@complex_encoding[(v * 4095/max_value).to_i]
|
428
|
-
end
|
429
|
-
}.join('')
|
430
|
-
end
|
431
|
-
|
432
|
-
def join_encoded_data(encoded_data)
|
433
|
-
encoded_data.join((self.data_encoding == :simple) ? "," : "|")
|
434
|
-
end
|
435
|
-
|
436
|
-
def max_data_value
|
437
|
-
@max_data or @data.flatten.max
|
395
|
+
chart_data = values.collect do |val|
|
396
|
+
if val.to_i >=0
|
397
|
+
if max_value == 0
|
398
|
+
SIMPLE_ENCODING[0]
|
399
|
+
else
|
400
|
+
SIMPLE_ENCODING[(alphabet_length * val / max_value).to_i]
|
401
|
+
end
|
402
|
+
else
|
403
|
+
"_"
|
438
404
|
end
|
439
|
-
|
440
|
-
|
441
|
-
|
405
|
+
end
|
406
|
+
|
407
|
+
return chart_data.join('')
|
408
|
+
end
|
409
|
+
|
410
|
+
def text_encode(values, max_value=nil)
|
411
|
+
max_value = values.max unless max_value
|
412
|
+
values.inject("") { |sum, v|
|
413
|
+
if max_value == 0
|
414
|
+
sum += "0,"
|
415
|
+
else
|
416
|
+
sum += ( "%.1f" % (v*100/max_value) ) + ","
|
442
417
|
end
|
443
|
-
|
444
|
-
|
445
|
-
|
418
|
+
}.chomp(",")
|
419
|
+
end
|
420
|
+
|
421
|
+
def extended_encode(values, max_value)
|
422
|
+
max_value = values.max unless max_value
|
423
|
+
values.collect { |v|
|
424
|
+
if max_value == 0
|
425
|
+
@@complex_encoding[0]
|
426
|
+
else
|
427
|
+
@@complex_encoding[(v * 4095/max_value).to_i]
|
446
428
|
end
|
429
|
+
}.join('')
|
430
|
+
end
|
431
|
+
|
432
|
+
def join_encoded_data(encoded_data)
|
433
|
+
encoded_data.join((self.data_encoding == :simple or self.data_encoding == :extended) ? "," : "|")
|
434
|
+
end
|
435
|
+
|
436
|
+
def max_data_value
|
437
|
+
@max_data or @data.flatten.max
|
438
|
+
end
|
439
|
+
|
440
|
+
def max_x_value
|
441
|
+
@max_x or x_data.flatten.max
|
442
|
+
end
|
447
443
|
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
end
|
452
|
-
end
|
444
|
+
def max_y_value
|
445
|
+
@max_y or y_data.flatten.max
|
446
|
+
end
|
453
447
|
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
end
|
448
|
+
def x_data
|
449
|
+
@data.collect do |series|
|
450
|
+
series.collect { |val| val.first }
|
451
|
+
end
|
459
452
|
end
|
460
|
-
|
453
|
+
|
454
|
+
def y_data
|
455
|
+
@data.collect do |series|
|
456
|
+
series.collect { |val| val.last }
|
457
|
+
end
|
458
|
+
end
|
459
|
+
end
|
460
|
+
end
|
data/lib/test.rb
CHANGED
@@ -138,5 +138,20 @@ stacked.title_font_size=18
|
|
138
138
|
puts "\nStacked Chart with colored title"
|
139
139
|
puts stacked.to_url
|
140
140
|
|
141
|
+
# Encoding Error (Bar Chart)
|
142
|
+
bc = GoogleChart::BarChart.new('800x350', nil, :vertical, true) do |chart|
|
143
|
+
chart.data_encoding = :extended
|
144
|
+
|
145
|
+
chart.data "2^i", (0..8).to_a.collect{|i| 2**i}, "ff0000"
|
146
|
+
chart.data "2.1^i", (0..8).to_a.collect{|i| 2.1**i}, "00ff00"
|
147
|
+
chart.data "2.2^i", (0..8).to_a.collect{|i| 2.2**i}, "0000ff"
|
148
|
+
max = 2.2**8
|
149
|
+
|
150
|
+
chart.show_legend = true
|
151
|
+
chart.axis :y, :range => [0,max], :font_size => 16, :alignment => :center
|
152
|
+
chart.axis :x, :labels => (0..8).to_a, :font_size => 16, :alignment => :center
|
153
|
+
end
|
141
154
|
|
155
|
+
puts "\nBar chart encoding error test"
|
156
|
+
puts bc.to_url
|
142
157
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gchartrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Deepak Jois
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-01-
|
12
|
+
date: 2008-01-23 00:00:00 +08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|