betelgeuse-googlecharts 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,48 @@
1
+ == 1.3.6
2
+ * support nil values. The Google Charts API specifies that a single underscore (_) can be used to omit a value from a line chart with 'simple' data encoding, and a double underscore (__) can do the same for a chart with 'extended' data encoding. (Matt Moyer)
3
+ * allow a label to appear on a google-o-meter via the :legend option. (hallettj)
4
+
5
+ == 1.3.5
6
+ * added code to properly escape image tag URLs (mokolabs)
7
+ * added themes support + 4 default themes (keynote, thirty7signals, pastel, greyscale) chart.line(:theme=>:keynote) (jakehow)
8
+
9
+ == 1.3.4
10
+ * updated documentation and cleaned it up (mokolabs)
11
+ * added support for custom class, id and alt tags when using the image_tag format (i.e Gchart.line(:data => [0, 26], :format => 'image_tag')) (mokolabs)
12
+
13
+ == 1.3.2 - 1.3.3
14
+ * changes required by github
15
+
16
+ == 1.3.1
17
+ * added width and spacing options
18
+
19
+ == 1.3.0
20
+ * added support for google-o-meter
21
+ * fixed a bug when the max value of a data set was 0
22
+
23
+ == 1.2.0
24
+ * added support for sparklines
25
+
26
+ == 1.1.0
27
+ * fixed another bug fix related to the uri escaping required to download the file properly.
28
+
29
+ == 1.0.0
30
+ * fixed the (URI::InvalidURIError) issue
31
+
32
+ == 0.2.0
33
+ * added export options (file and image tag)
34
+ * added support for all arguments to be passed as a string or an array
35
+
36
+ == 0.1.0 2007-12-11
37
+ * fixed the axis labels
38
+
39
+ == 0.0.3 2007-12-11
40
+ * added :chart_background alias and fixed a bug related to the background colors.
41
+
42
+ == 0.0.2 2007-12-11
43
+ * added support for more features and aliases
44
+
45
+ == 0.0.1 2007-12-08
46
+
47
+ * 1 major enhancement:
48
+ * Initial release
data/License.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007 Matt Aimonetti
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,18 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ config/hoe.rb
7
+ config/requirements.rb
8
+ lib/gchart.rb
9
+ lib/gchart/aliases.rb
10
+ lib/gchart/theme.rb
11
+ lib/gchart/version.rb
12
+ setup.rb
13
+ spec/gchart_spec.rb
14
+ spec/theme_spec.rb
15
+ spec/spec.opts
16
+ spec/spec_helper.rb
17
+ tasks/environment.rake
18
+ tasks/rspec.rake
data/README.txt ADDED
@@ -0,0 +1,9 @@
1
+ CHECK README.markdown (open as a text file)
2
+
3
+ Or check:
4
+
5
+ http://googlecharts.rubyforge.org
6
+
7
+ and/or
8
+
9
+ http://github.com/mattetti/googlecharts
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ require 'config/requirements'
2
+ require 'config/hoe' # setup Hoe + all gem configuration
3
+
4
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
5
+
6
+ desc %{Update ".manifest" with the latest list of project filenames. Respect\
7
+ .gitignore by excluding everything that git ignores. Update `files` and\
8
+ `test_files` arrays in "*.gemspec" file if it's present.}
9
+ task :manifest do
10
+ list = Dir['**/*'].sort
11
+ spec_file = Dir['*.gemspec'].first
12
+ list -= [spec_file] if spec_file
13
+
14
+ File.read('.gitignore').each_line do |glob|
15
+ glob = glob.chomp.sub(/^\//, '')
16
+ list -= Dir[glob]
17
+ list -= Dir["#{glob}/**/*"] if File.directory?(glob) and !File.symlink?(glob)
18
+ puts "excluding #{glob}"
19
+ end
20
+
21
+ if spec_file
22
+ spec = File.read spec_file
23
+ spec.gsub! /^(\s* s.(test_)?files \s* = \s* )( \[ [^\]]* \] | %w\( [^)]* \) )/mx do
24
+ assignment = $1
25
+ bunch = $2 ? list.grep(/^test\//) : list
26
+ '%s%%w(%s)' % [assignment, bunch.join(' ')]
27
+ end
28
+
29
+ File.open(spec_file, 'w') {|f| f << spec }
30
+ end
31
+ File.open('.manifest', 'w') {|f| f << list.join("\n") }
32
+ end
data/config/hoe.rb ADDED
@@ -0,0 +1,71 @@
1
+ require 'gchart/version'
2
+
3
+ AUTHOR = 'Matt Aimonetti' # can also be an array of Authors
4
+ EMAIL = "mattaimonetti@gmail.com"
5
+ DESCRIPTION = "description of gem"
6
+ GEM_NAME = 'googlecharts' # what ppl will type to install your gem
7
+ RUBYFORGE_PROJECT = 'googlecharts' # The unix name for your project
8
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
9
+ DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
10
+
11
+ @config_file = "~/.rubyforge/user-config.yml"
12
+ @config = nil
13
+ RUBYFORGE_USERNAME = "matt_a"
14
+ def rubyforge_username
15
+ unless @config
16
+ begin
17
+ @config = YAML.load(File.read(File.expand_path(@config_file)))
18
+ rescue
19
+ puts <<-EOS
20
+ ERROR: No rubyforge config file found: #{@config_file}
21
+ Run 'rubyforge setup' to prepare your env for access to Rubyforge
22
+ - See http://newgem.rubyforge.org/rubyforge.html for more details
23
+ EOS
24
+ exit
25
+ end
26
+ end
27
+ RUBYFORGE_USERNAME.replace @config["username"]
28
+ end
29
+
30
+
31
+ REV = nil
32
+ # UNCOMMENT IF REQUIRED:
33
+ # REV = `svn info`.each {|line| if line =~ /^Revision:/ then k,v = line.split(': '); break v.chomp; else next; end} rescue nil
34
+ VERS = GchartInfo::VERSION::STRING + (REV ? ".#{REV}" : "")
35
+ RDOC_OPTS = ['--quiet', '--title', 'gchart documentation',
36
+ "--opname", "index.html",
37
+ "--line-numbers",
38
+ "--main", "README",
39
+ "--inline-source"]
40
+
41
+ class Hoe
42
+ def extra_deps
43
+ @extra_deps.reject! { |x| Array(x).first == 'hoe' }
44
+ @extra_deps
45
+ end
46
+ end
47
+
48
+ # Generate all the Rake tasks
49
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
50
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
51
+ p.author = AUTHOR
52
+ p.description = DESCRIPTION
53
+ p.email = EMAIL
54
+ p.summary = DESCRIPTION
55
+ p.url = HOMEPATH
56
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
57
+ p.test_globs = ["test/**/test_*.rb"]
58
+ p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
59
+
60
+ # == Optional
61
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
62
+ #p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
63
+
64
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
65
+
66
+ end
67
+
68
+ CHANGES = hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
69
+ PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
70
+ hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
71
+ hoe.rsync_args = '-av --delete --ignore-errors'
@@ -0,0 +1,16 @@
1
+ require 'fileutils'
2
+ include FileUtils
3
+
4
+ require 'rubygems'
5
+ %w[rake hoe newgem rubigen].each do |req_gem|
6
+ begin
7
+ require req_gem
8
+ rescue LoadError
9
+ puts "This Rakefile could use '#{req_gem}' RubyGem."
10
+ puts "Installation: gem install #{req_gem} -y"
11
+ end
12
+ end
13
+
14
+ $:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
15
+
16
+ require 'gchart'
data/lib/gchart.rb ADDED
@@ -0,0 +1,494 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+ require 'gchart/version'
3
+ require 'gchart/theme'
4
+ require "open-uri"
5
+ require "uri"
6
+ require "cgi"
7
+ require 'enumerator'
8
+
9
+ class Gchart
10
+
11
+ include GchartInfo
12
+
13
+ @@url = "http://chart.apis.google.com/chart?"
14
+ @@types = ['line', 'line_xy', 'scatter', 'bar', 'venn', 'pie', 'pie_3d', 'jstize', 'sparkline', 'meter', 'map']
15
+ @@simple_chars = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a
16
+ @@chars = @@simple_chars + ['-', '.']
17
+ @@ext_pairs = @@chars.map { |char_1| @@chars.map { |char_2| char_1 + char_2 } }.flatten
18
+ @@file_name = 'chart.png'
19
+
20
+ attr_accessor :title, :type, :width, :height, :horizontal, :grouped, :legend, :data, :encoding, :min_value, :max_value, :bar_colors,
21
+ :title_color, :title_size, :custom, :axis_with_labels, :axis_labels, :bar_width_and_spacing, :id, :alt, :class,
22
+ :range_markers, :geographical_area, :map_colors, :country_codes, :axis_range
23
+
24
+ # Support for Gchart.line(:title => 'my title', :size => '400x600')
25
+ def self.method_missing(m, options={})
26
+ # Start with theme defaults if a theme is set
27
+ theme = options[:theme]
28
+ options = theme ? Chart::Theme.load(theme).to_options.merge(options) : options
29
+ # Extract the format and optional filename, then clean the hash
30
+ format = options[:format] || 'url'
31
+ @@file_name = options[:filename] unless options[:filename].nil?
32
+ options.delete(:format)
33
+ options.delete(:filename)
34
+ #update map_colors to be bar_colors
35
+ options.update(:bar_colors => options[:map_colors]) if options.has_key?(:map_colors)
36
+ # create the chart and return it in the format asked for
37
+ if @@types.include?(m.to_s)
38
+ chart = new(options.merge!({:type => m}))
39
+ chart.send(format)
40
+ elsif m.to_s == 'version'
41
+ Gchart::VERSION::STRING
42
+ else
43
+ "#{m} is not a supported chart format, please use one of the following: #{supported_types}."
44
+ end
45
+ end
46
+
47
+ def initialize(options={})
48
+ @type = :line
49
+ @data = []
50
+ @width = 300
51
+ @height = 200
52
+ @horizontal = false
53
+ @grouped = false
54
+ @encoding = 'simple'
55
+ @max_value = 'auto'
56
+ # Sets the alt tag when chart is exported as image tag
57
+ @alt = 'Google Chart'
58
+ # Sets the CSS id selector when chart is exported as image tag
59
+ @id = false
60
+ # Sets the CSS class selector when chart is exported as image tag
61
+ @class = false
62
+
63
+ # set the options value if definable
64
+ options.each do |attribute, value|
65
+ send("#{attribute.to_s}=", value) if self.respond_to?("#{attribute}=")
66
+ end
67
+ end
68
+
69
+ def self.supported_types
70
+ @@types.join(' ')
71
+ end
72
+
73
+ # Defines the Graph size using the following format:
74
+ # width X height
75
+ def size=(size='300x200')
76
+ @width, @height = size.split("x").map { |dimension| dimension.to_i }
77
+ end
78
+
79
+ def size
80
+ "#{@width}x#{@height}"
81
+ end
82
+
83
+ # Sets the orientation of a bar graph
84
+ def orientation=(orientation='h')
85
+ if orientation == 'h' || orientation == 'horizontal'
86
+ self.horizontal = true
87
+ elsif orientation == 'v' || orientation == 'vertical'
88
+ self.horizontal = false
89
+ end
90
+ end
91
+
92
+ # Sets the bar graph presentation (stacked or grouped)
93
+ def stacked=(option=true)
94
+ @grouped = option ? false : true
95
+ end
96
+
97
+ def bg=(options)
98
+ if options.is_a?(String)
99
+ @bg_color = options
100
+ elsif options.is_a?(Hash)
101
+ @bg_color = options[:color]
102
+ @bg_type = options[:type]
103
+ @bg_angle = options[:angle]
104
+ end
105
+ end
106
+
107
+ def graph_bg=(options)
108
+ if options.is_a?(String)
109
+ @chart_color = options
110
+ elsif options.is_a?(Hash)
111
+ @chart_color = options[:color]
112
+ @chart_type = options[:type]
113
+ @chart_angle = options[:angle]
114
+ end
115
+ end
116
+
117
+ # returns the full data range as an array
118
+ # it also sets the data range if not defined
119
+ def full_data_range(ds)
120
+ return [@min, @max] unless (@min.nil? || @max.nil?)
121
+ @max = (max_value.nil? || max_value == 'auto') ? ds.compact.map{|mds| mds.compact.max}.max : max_value
122
+ if (min_value.nil? || min_value == 'auto')
123
+ min_ds_value = ds.compact.map{|mds| mds.compact.min}.min || 0
124
+ @min = (min_ds_value < 0) ? min_ds_value : 0
125
+ else
126
+ @min = min_value
127
+ end
128
+ @axis_range = [[@min,@max]]
129
+ end
130
+
131
+ def dataset
132
+ @dataset ||= prepare_dataset(data)
133
+ full_data_range(@dataset) unless @axis_range
134
+ @dataset
135
+ end
136
+
137
+ def self.jstize(string)
138
+ string.gsub(' ', '+').gsub(/\[|\{|\}|\||\\|\^|\[|\]|\`|\]/) {|c| "%#{c[0].to_s(16).upcase}"}
139
+ end
140
+ # load all the custom aliases
141
+ require 'gchart/aliases'
142
+
143
+ protected
144
+
145
+ # Returns the chart's generated PNG as a blob. (borrowed from John's gchart.rubyforge.org)
146
+ def fetch
147
+ open(query_builder) { |io| io.read }
148
+ end
149
+
150
+ # Writes the chart's generated PNG to a file. (borrowed from John's gchart.rubyforge.org)
151
+ def write(io_or_file=@@file_name)
152
+ return io_or_file.write(fetch) if io_or_file.respond_to?(:write)
153
+ open(io_or_file, "w+") { |io| io.write(fetch) }
154
+ end
155
+
156
+ # Format
157
+
158
+ def image_tag
159
+ image = "<img"
160
+ image += " id=\"#{@id}\"" if @id
161
+ image += " class=\"#{@class}\"" if @class
162
+ image += " src=\"#{query_builder(:html)}\""
163
+ image += " width=\"#{@width}\""
164
+ image += " height=\"#{@height}\""
165
+ image += " alt=\"#{@alt}\""
166
+ image += " title=\"#{@title}\"" if @title
167
+ image += " />"
168
+ end
169
+
170
+ alias_method :img_tag, :image_tag
171
+
172
+ def url
173
+ query_builder
174
+ end
175
+
176
+ def file
177
+ write
178
+ end
179
+
180
+ #
181
+ def jstize(string)
182
+ Gchart.jstize(string)
183
+ end
184
+
185
+ private
186
+
187
+ # The title size cannot be set without specifying a color.
188
+ # A dark key will be used for the title color if no color is specified
189
+ def set_title
190
+ title_params = "chtt=#{title}"
191
+ unless (title_color.nil? && title_size.nil? )
192
+ title_params << "&chts=" + (color, size = (@title_color || '454545'), @title_size).compact.join(',')
193
+ end
194
+ title_params
195
+ end
196
+
197
+ def set_size
198
+ "chs=#{size}"
199
+ end
200
+
201
+ def set_data
202
+ data = send("#{@encoding}_encoding")
203
+ "chd=#{data}"
204
+ end
205
+
206
+ def set_colors
207
+ bg_type = fill_type(@bg_type) || 's' if @bg_color
208
+ chart_type = fill_type(@chart_type) || 's' if @chart_color
209
+
210
+ "chf=" + {'bg' => fill_for(bg_type, @bg_color, @bg_angle), 'c' => fill_for(chart_type, @chart_color, @chart_angle)}.map{|k,v| "#{k},#{v}" unless v.nil?}.compact.join('|')
211
+ end
212
+
213
+ # set bar, line colors
214
+ def set_bar_colors
215
+ @bar_colors = @bar_colors.join(',') if @bar_colors.is_a?(Array)
216
+ "chco=#{@bar_colors}"
217
+ end
218
+
219
+ def set_country_codes
220
+ @country_codes = @country_codes.join() if @country_codes.is_a?(Array)
221
+ "chld=#{@country_codes}"
222
+ end
223
+
224
+ # set bar spacing
225
+ # chbh=
226
+ # <bar width in pixels>,
227
+ # <optional space between bars in a group>,
228
+ # <optional space between groups>
229
+ def set_bar_width_and_spacing
230
+ width_and_spacing_values = case @bar_width_and_spacing
231
+ when String
232
+ @bar_width_and_spacing
233
+ when Array
234
+ @bar_width_and_spacing.join(',')
235
+ when Hash
236
+ width = @bar_width_and_spacing[:width] || 23
237
+ spacing = @bar_width_and_spacing[:spacing] || 4
238
+ group_spacing = @bar_width_and_spacing[:group_spacing] || 8
239
+ [width,spacing,group_spacing].join(',')
240
+ else
241
+ @bar_width_and_spacing.to_s
242
+ end
243
+ "chbh=#{width_and_spacing_values}"
244
+ end
245
+
246
+ def set_range_markers
247
+ markers = case @range_markers
248
+ when Hash
249
+ set_range_marker(@range_markers)
250
+ when Array
251
+ range_markers.collect{|marker| set_range_marker(marker)}.join('|')
252
+ end
253
+ "chm=#{markers}"
254
+ end
255
+
256
+ def set_range_marker(options)
257
+ orientation = ['vertical', 'Vertical', 'V', 'v', 'R'].include?(options[:orientation]) ? 'R' : 'r'
258
+ "#{orientation},#{options[:color]},0,#{options[:start_position]},#{options[:stop_position]}#{',1' if options[:overlaid?]}"
259
+ end
260
+
261
+ def fill_for(type=nil, color='', angle=nil)
262
+ unless type.nil?
263
+ case type
264
+ when 'lg'
265
+ angle ||= 0
266
+ color = "#{color},0,ffffff,1" if color.split(',').size == 1
267
+ "#{type},#{angle},#{color}"
268
+ when 'ls'
269
+ angle ||= 90
270
+ color = "#{color},0.2,ffffff,0.2" if color.split(',').size == 1
271
+ "#{type},#{angle},#{color}"
272
+ else
273
+ "#{type},#{color}"
274
+ end
275
+ end
276
+ end
277
+
278
+ # A chart can have one or many legends.
279
+ # Gchart.line(:legend => 'label')
280
+ # or
281
+ # Gchart.line(:legend => ['first label', 'last label'])
282
+ def set_legend
283
+ return set_labels if @type == :pie || @type == :pie_3d || @type == :meter
284
+
285
+ if @legend.is_a?(Array)
286
+ "chdl=#{@legend.map{|label| "#{CGI::escape(label)}"}.join('|')}"
287
+ else
288
+ "chdl=#{@legend}"
289
+ end
290
+
291
+ end
292
+
293
+ def set_labels
294
+ if @legend.is_a?(Array)
295
+ "chl=#{@legend.map{|label| "#{label}"}.join('|')}"
296
+ else
297
+ "chl=#{@legend}"
298
+ end
299
+ end
300
+
301
+ def set_axis_with_labels
302
+ @axis_with_labels = @axis_with_labels.join(',') if @axis_with_labels.is_a?(Array)
303
+ "chxt=#{@axis_with_labels}"
304
+ end
305
+
306
+ def set_axis_labels
307
+ labels_arr = []
308
+ axis_labels.each_with_index do |labels,index|
309
+ if labels.is_a?(Array)
310
+ labels_arr << "#{index}:|#{labels.join('|')}"
311
+ else
312
+ labels_arr << "#{index}:|#{labels}"
313
+ end
314
+ end
315
+ "chxl=#{labels_arr.join('|')}"
316
+ end
317
+
318
+ # http://code.google.com/apis/chart/labels.html#axis_range
319
+ # Specify a range for axis labels
320
+ def set_axis_range
321
+ # a passed axis_range should look like:
322
+ # [[10,100]] or [[10,100,4]] or [[10,100], [20,300]]
323
+ # in the second example, 4 is the interval
324
+ dataset # just making sure we processed the data before
325
+ if axis_range && axis_range.respond_to?(:each) && axis_range.first.respond_to?(:each)
326
+ 'chxr=' + axis_range.enum_for(:each_with_index).map{|range, index| [index, range[0], range[1], range[2]].compact.join(',')}.join("|")
327
+ else
328
+ nil
329
+ end
330
+ end
331
+
332
+ def set_geographical_area
333
+ "chtm=#{@geographical_area}"
334
+ end
335
+
336
+ def set_type
337
+ case @type
338
+ when :line
339
+ "cht=lc"
340
+ when :line_xy
341
+ "cht=lxy"
342
+ when :bar
343
+ "cht=b" + (horizontal? ? "h" : "v") + (grouped? ? "g" : "s")
344
+ when :pie_3d
345
+ "cht=p3"
346
+ when :pie
347
+ "cht=p"
348
+ when :venn
349
+ "cht=v"
350
+ when :scatter
351
+ "cht=s"
352
+ when :sparkline
353
+ "cht=ls"
354
+ when :meter
355
+ "cht=gom"
356
+ when :map
357
+ "cht=t"
358
+ end
359
+ end
360
+
361
+ def fill_type(type)
362
+ case type
363
+ when 'solid'
364
+ 's'
365
+ when 'gradient'
366
+ 'lg'
367
+ when 'stripes'
368
+ 'ls'
369
+ end
370
+ end
371
+
372
+ # Wraps a single dataset inside another array to support more datasets
373
+ def prepare_dataset(ds)
374
+ ds = [ds] unless ds.first.is_a?(Array)
375
+ ds
376
+ end
377
+
378
+ def convert_to_simple_value(number)
379
+ if number.nil?
380
+ "_"
381
+ else
382
+ value = @@simple_chars[number.to_i]
383
+ value.nil? ? "_" : value
384
+ end
385
+ end
386
+
387
+ # http://code.google.com/apis/chart/#simple
388
+ # Simple encoding has a resolution of 62 different values.
389
+ # Allowing five pixels per data point, this is sufficient for line and bar charts up
390
+ # to about 300 pixels. Simple encoding is suitable for all other types of chart regardless of size.
391
+ def simple_encoding
392
+ @max_value = dataset.compact.map{|ds| ds.compact.max}.max if @max_value == 'auto'
393
+
394
+ if @max_value == false || @max_value == 'false' || @max_value == :false || @max_value == 0
395
+ "s:" + dataset.map { |ds| ds.map { |number| number.nil? ? '_' : convert_to_simple_value(number) }.join }.join(',')
396
+ else
397
+ "s:" + dataset.map { |ds| ds.map { |number| number.nil? ? '_' : convert_to_simple_value( (@@simple_chars.size - 1) * number / @max_value) }.join }.join(',')
398
+ end
399
+
400
+ end
401
+
402
+ # http://code.google.com/apis/chart/#text
403
+ # Text encoding with data scaling lets you specify arbitrary positive or
404
+ # negative floating point numbers, in combination with a scaling parameter
405
+ # that lets you specify a custom range for your chart. This chart is useful
406
+ # when you don't want to worry about limiting your data to a specific range,
407
+ # or do the calculations to scale your data down or up to fit nicely inside
408
+ # a chart.
409
+ #
410
+ # Valid values range from (+/-)9.999e(+/-)100, and only four non-zero digits are supported (that is, 123400, 1234, 12.34, and 0.1234 are valid, but 12345, 123.45 and 123400.5 are not).
411
+ #
412
+ # This encoding is not available for maps.
413
+ #
414
+ def text_encoding
415
+ "t:" + dataset.map{ |ds| ds.join(',') }.join('|') + "&chds=#{@min},#{@max}"
416
+ end
417
+
418
+ def convert_to_extended_value(number)
419
+ if number.nil?
420
+ '__'
421
+ else
422
+ value = @@ext_pairs[number.to_i]
423
+ value.nil? ? "__" : value
424
+ end
425
+ end
426
+
427
+
428
+ # http://code.google.com/apis/chart/#extended
429
+ # Extended encoding has a resolution of 4,096 different values
430
+ # and is best used for large charts where a large data range is required.
431
+ def extended_encoding
432
+ @max_value = dataset.compact.map{|ds| ds.compact.max}.max if @max_value == 'auto'
433
+
434
+ if @max_value == false || @max_value == 'false' || @max_value == :false || @max_value == 0
435
+ "e:" + dataset.map { |ds| ds.map { |number| number.nil? ? '__' : convert_to_extended_value(number)}.join }.join(',')
436
+ else
437
+ "e:" + dataset.map { |ds| ds.map { |number| number.nil? ? '__' : convert_to_extended_value( (@@ext_pairs.size - 1) * number / @max_value) }.join }.join(',')
438
+ end
439
+
440
+ end
441
+
442
+
443
+ def query_builder(options="")
444
+ dataset
445
+ query_params = instance_variables.sort.map do |var|
446
+ case var
447
+ when '@data'
448
+ set_data unless @data == []
449
+ # Set the graph size
450
+ when '@width'
451
+ set_size unless @width.nil? || @height.nil?
452
+ when '@type'
453
+ set_type
454
+ when '@title'
455
+ set_title unless @title.nil?
456
+ when '@legend'
457
+ set_legend unless @legend.nil?
458
+ when '@bg_color'
459
+ set_colors
460
+ when '@chart_color'
461
+ set_colors if @bg_color.nil?
462
+ when '@bar_colors'
463
+ set_bar_colors
464
+ when '@bar_width_and_spacing'
465
+ set_bar_width_and_spacing
466
+ when '@axis_with_labels'
467
+ set_axis_with_labels
468
+ when '@axis_range'
469
+ set_axis_range if dataset
470
+ when '@axis_labels'
471
+ set_axis_labels
472
+ when '@range_markers'
473
+ set_range_markers
474
+ when '@geographical_area'
475
+ set_geographical_area
476
+ when '@country_codes'
477
+ set_country_codes
478
+ when '@custom'
479
+ @custom
480
+ end
481
+ end.compact
482
+
483
+ # Use ampersand as default delimiter
484
+ unless options == :html
485
+ delimiter = '&'
486
+ # Escape ampersand for html image tags
487
+ else
488
+ delimiter = '&amp;'
489
+ end
490
+
491
+ jstize(@@url + query_params.join(delimiter))
492
+ end
493
+
494
+ end