googlecharts 1.5.4 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -238,6 +238,11 @@ The hash lets you set these values directly, with the Google default values set
238
238
  Gchart.bar(:data => @data, :bar_width_and_spacing => {:width => 19})
239
239
  Gchart.bar(:data => @data, :bar_width_and_spacing => {:spacing => 10, :group_spacing => 12})
240
240
 
241
+ Radar:
242
+ -------------
243
+ In a Radar graph, the x-axis is circular. The points can be connected by straight lines or curved lines.
244
+ Gchart.radar(:data => @data, :curved => true)
245
+
241
246
  Sparklines:
242
247
  -------------
243
248
 
@@ -287,4 +292,4 @@ People reported using this gem:
287
292
 
288
293
  * [http://feedflix.com/](http://feedflix.com/) [lifehacker article](http://lifehacker.com/395610/feedflix-creates-detailed-charts-from-your-netflix-use)
289
294
 
290
- * [California State University, Chico](http://www.csuchico.edu/)
295
+ * [California State University, Chico](http://www.csuchico.edu/)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.5.4
1
+ 1.6.0
data/lib/gchart.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  $:.unshift File.dirname(__FILE__)
2
2
  require 'gchart/version'
3
3
  require 'gchart/theme'
4
- require "open-uri"
4
+ require "net/http"
5
5
  require "uri"
6
6
  require "cgi"
7
7
  require 'enumerator'
@@ -14,7 +14,7 @@ class Gchart
14
14
  end
15
15
 
16
16
  def self.types
17
- @types ||= ['line', 'line_xy', 'scatter', 'bar', 'venn', 'pie', 'pie_3d', 'jstize', 'sparkline', 'meter', 'map']
17
+ @types ||= ['line', 'line_xy', 'scatter', 'bar', 'venn', 'pie', 'pie_3d', 'jstize', 'sparkline', 'meter', 'map', 'radar']
18
18
  end
19
19
 
20
20
  def self.simple_chars
@@ -33,7 +33,7 @@ class Gchart
33
33
  'chart.png'
34
34
  end
35
35
 
36
- attr_accessor :title, :type, :width, :height, :horizontal, :grouped, :legend, :data, :encoding, :bar_colors,
36
+ attr_accessor :title, :type, :width, :height, :curved, :horizontal, :grouped, :legend, :data, :encoding, :bar_colors,
37
37
  :title_color, :title_size, :custom, :axis_with_labels, :axis_labels, :bar_width_and_spacing, :id, :alt, :klass,
38
38
  :range_markers, :geographical_area, :map_colors, :country_codes, :axis_range, :filename, :min, :max, :colors
39
39
 
@@ -49,7 +49,7 @@ class Gchart
49
49
  options = theme ? Chart::Theme.load(theme).to_options.merge(options) : options
50
50
  # # Extract the format and optional filename, then clean the hash
51
51
  format = options[:format] || 'url'
52
- options[:filename] ||= Gchart.default_filename
52
+ options[:filename] ||= default_filename
53
53
  options.delete(:format)
54
54
  #update map_colors to become bar_colors
55
55
  options.update(:bar_colors => options[:map_colors]) if options.has_key?(:map_colors)
@@ -60,7 +60,7 @@ class Gchart
60
60
  end
61
61
 
62
62
  def self.version
63
- Gchart::VERSION::STRING
63
+ VERSION::STRING
64
64
  end
65
65
 
66
66
  def self.method_missing(m, options={})
@@ -72,6 +72,7 @@ class Gchart
72
72
  @data = []
73
73
  @width = 300
74
74
  @height = 200
75
+ @curved = false
75
76
  @horizontal = false
76
77
  @grouped = false
77
78
  @encoding = 'simple'
@@ -92,7 +93,7 @@ class Gchart
92
93
 
93
94
 
94
95
  def self.supported_types
95
- Gchart.types.join(' ')
96
+ self.class.types.join(' ')
96
97
  end
97
98
 
98
99
  # Defines the Graph size using the following format:
@@ -257,12 +258,16 @@ class Gchart
257
258
 
258
259
  # Returns the chart's generated PNG as a blob. (borrowed from John's gchart.rubyforge.org)
259
260
  def fetch
260
- open(query_builder) { |io| io.read }
261
+ url = URI.parse(self.class.url)
262
+ req = Net::HTTP::Post.new(url.path)
263
+ req.body = query_builder
264
+ req.content_type = 'application/x-www-form-urlencoded'
265
+ Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }.body
261
266
  end
262
267
 
263
268
  # Writes the chart's generated PNG to a file. (borrowed from John's gchart.rubyforge.org)
264
269
  def write
265
- io_or_file = filename || Gchart.default_filename
270
+ io_or_file = filename || self.class.default_filename
266
271
  return io_or_file.write(fetch) if io_or_file.respond_to?(:write)
267
272
  open(io_or_file, "wb+") { |io| io.write(fetch) }
268
273
  end
@@ -273,7 +278,7 @@ class Gchart
273
278
  image = "<img"
274
279
  image += " id=\"#{id}\"" if id
275
280
  image += " class=\"#{klass}\"" if klass
276
- image += " src=\"#{query_builder(:html)}\""
281
+ image += " src=\"#{url_builder(:html)}\""
277
282
  image += " width=\"#{width}\""
278
283
  image += " height=\"#{height}\""
279
284
  image += " alt=\"#{alt}\""
@@ -284,7 +289,7 @@ class Gchart
284
289
  alias_method :img_tag, :image_tag
285
290
 
286
291
  def url
287
- query_builder
292
+ url_builder
288
293
  end
289
294
 
290
295
  def file
@@ -293,8 +298,8 @@ class Gchart
293
298
 
294
299
  #
295
300
  def jstize(string)
296
- Gchart.jstize(string)
297
- end
301
+ self.class.jstize(string)
302
+ end
298
303
 
299
304
  private
300
305
 
@@ -457,20 +462,21 @@ class Gchart
457
462
  # a passed axis_range should look like:
458
463
  # [[10,100]] or [[10,100,4]] or [[10,100], [20,300]]
459
464
  # in the second example, 4 is the interval
460
- if @calculated_axis_range
461
- set = datasets
462
- else
463
- set = axis_range || datasets
464
- end
465
+ set = @calculated_axis_range ? datasets : axis_range || datasets
466
+
467
+ return unless set && set.respond_to?(:each) && set.find {|o| o}.respond_to?(:each)
468
+
465
469
  # in the case of a line graph, the first axis range should 1
466
470
  index_increase = type.to_s == 'line' ? 1 : 0
467
- if set && set.respond_to?(:each) && set.first.respond_to?(:each)
468
- 'chxr=' + set.enum_for(:each_with_index).map do |range, index|
469
- [(index + index_increase), (min_value || range.first), (max_value || range.last)].compact.join(',')
470
- end.join("|")
471
- else
472
- nil
473
- end
471
+ 'chxr=' + set.enum_for(:each_with_index).map do |axis_range, index|
472
+ next nil if axis_range.nil? # ignore this axis
473
+ min, max, step = axis_range
474
+ if axis_range.size > 3 or step && max && step > max # this is a full series
475
+ max = axis_range.last
476
+ step = nil
477
+ end
478
+ [(index + index_increase), (min_value || min || 0), (max_value || max), step].compact.join(',')
479
+ end.compact.join("|")
474
480
  end
475
481
 
476
482
  def set_geographical_area
@@ -478,38 +484,28 @@ class Gchart
478
484
  end
479
485
 
480
486
  def set_type
481
- case type.to_s
482
- when 'line'
483
- "cht=lc"
484
- when 'line_xy'
485
- "cht=lxy"
487
+ 'cht=' + case type.to_s
488
+ when 'line' then "lc"
489
+ when 'line_xy' then "lxy"
490
+ when 'pie_3d' then "p3"
491
+ when 'pie' then "p"
492
+ when 'venn' then "v"
493
+ when 'scatter' then "s"
494
+ when 'sparkline' then "ls"
495
+ when 'meter' then "gom"
496
+ when 'map' then "t"
497
+ when 'radar'
498
+ "r" + (curved? ? 's' : '')
486
499
  when 'bar'
487
- "cht=b" + (horizontal? ? "h" : "v") + (grouped? ? "g" : "s")
488
- when 'pie_3d'
489
- "cht=p3"
490
- when 'pie'
491
- "cht=p"
492
- when 'venn'
493
- "cht=v"
494
- when 'scatter'
495
- "cht=s"
496
- when 'sparkline'
497
- "cht=ls"
498
- when 'meter'
499
- "cht=gom"
500
- when 'map'
501
- "cht=t"
500
+ "b" + (horizontal? ? "h" : "v") + (grouped? ? "g" : "s")
502
501
  end
503
502
  end
504
503
 
505
504
  def fill_type(type)
506
505
  case type
507
- when 'solid'
508
- 's'
509
- when 'gradient'
510
- 'lg'
511
- when 'stripes'
512
- 'ls'
506
+ when 'solid' then 's'
507
+ when 'gradient' then 'lg'
508
+ when 'stripes' then 'ls'
513
509
  end
514
510
  end
515
511
 
@@ -555,7 +551,7 @@ class Gchart
555
551
  if number.nil?
556
552
  "_"
557
553
  else
558
- value = Gchart.simple_chars[number.to_i]
554
+ value = self.class.simple_chars[number.to_i]
559
555
  value.nil? ? "_" : value
560
556
  end
561
557
  end
@@ -564,7 +560,7 @@ class Gchart
564
560
  if number.nil?
565
561
  '__'
566
562
  else
567
- value = Gchart.ext_pairs[number.to_i]
563
+ value = self.class.ext_pairs[number.to_i]
568
564
  value.nil? ? "__" : value
569
565
  end
570
566
  end
@@ -603,7 +599,7 @@ class Gchart
603
599
  # Allowing five pixels per data point, this is sufficient for line and bar charts up
604
600
  # to about 300 pixels. Simple encoding is suitable for all other types of chart regardless of size.
605
601
  def simple_encoding
606
- "s" + number_visible + ":" + encode_scaled_dataset(Gchart.simple_chars, '_')
602
+ "s" + number_visible + ":" + encode_scaled_dataset(self.class.simple_chars, '_')
607
603
  end
608
604
 
609
605
  # http://code.google.com/apis/chart/#text
@@ -627,7 +623,11 @@ class Gchart
627
623
  # Extended encoding has a resolution of 4,096 different values
628
624
  # and is best used for large charts where a large data range is required.
629
625
  def extended_encoding
630
- "e" + number_visible + ":" + encode_scaled_dataset(Gchart.ext_pairs, '__')
626
+ "e" + number_visible + ":" + encode_scaled_dataset(self.class.ext_pairs, '__')
627
+ end
628
+
629
+ def url_builder(options="")
630
+ self.class.url + query_builder(options)
631
631
  end
632
632
 
633
633
  def query_builder(options="")
@@ -683,7 +683,7 @@ class Gchart
683
683
  delimiter = '&amp;'
684
684
  end
685
685
 
686
- jstize(Gchart.url + query_params.join(delimiter))
686
+ jstize(query_params.join(delimiter))
687
687
  end
688
688
 
689
689
  end
@@ -10,5 +10,6 @@ class Gchart
10
10
  alias_method :labels=, :legend=
11
11
  alias_method :horizontal?, :horizontal
12
12
  alias_method :grouped?, :grouped
13
+ alias_method :curved?, :curved
13
14
 
14
- end
15
+ end
data/spec/gchart_spec.rb CHANGED
@@ -112,22 +112,47 @@ describe "generating a default Gchart" do
112
112
  Gchart.line(:axis_labels => [['Jan','July','Jan','July','Jan'], ['0','100'], ['A','B','C'], ['2005','2006','2007']]).include?(Gchart.jstize('chxl=0:|Jan|July|Jan|July|Jan|1:|0|100|2:|A|B|C|3:|2005|2006|2007')).should be_true
113
113
  end
114
114
 
115
+ def labeled_line(options = {})
116
+ Gchart.line({:data => @data, :axis_with_labels => 'x,y'}.merge options)
117
+ end
118
+
115
119
  it "should display ranges properly" do
116
- data = [85,107,123,131,155,172,173,189,203,222,217,233,250,239,256,267,247,261,275,295,288,305,322,307,325,347,331,346,363,382,343,359,383,352,374,393,358,379,396,416,377,398,419,380,409,426,453,432,452,465,436,460,480,440,457,474,501,457,489,507,347,373,413,402,424,448,475,488,513,475,507,530,440,476,500,518,481,512,531,367,396,423,387,415,446,478,442,469,492,463,489,508,463,491,518,549,503,526,547,493,530,549,493,520,541,564,510,535,564,492,512,537,502,530,548,491,514,538,568,524,548,568,512,533,552,577,520,545,570,516,536,555,514,536,566,521,553,579,604,541,569,595,551,581,602,549,576,606,631,589,615,650,597,624,646,672,605,626,654,584,608,631,574,597,622,559,591,614,644,580,603,629,584,615,631,558,591,618,641,314,356,395,397,429,450,421,454,477,507,458,490,560,593]
117
- url = Gchart.line(:data => data, :axis_with_labels => 'x,y', :axis_labels => [(1.upto(24).to_a << 1)])
118
- url.should include('chxr=1,85,593')
120
+ @data = [85,107,123,131,155,172,173,189,203,222,217,233,250,239,256,267,247,261,275,295,288,305,322,307,325,347,331,346,363,382,343,359,383,352,374,393,358,379,396,416,377,398,419,380,409,426,453,432,452,465,436,460,480,440,457,474,501,457,489,507,347,373,413,402,424,448,475,488,513,475,507,530,440,476,500,518,481,512,531,367,396,423,387,415,446,478,442,469,492,463,489,508,463,491,518,549,503,526,547,493,530,549,493,520,541,564,510,535,564,492,512,537,502,530,548,491,514,538,568,524,548,568,512,533,552,577,520,545,570,516,536,555,514,536,566,521,553,579,604,541,569,595,551,581,602,549,576,606,631,589,615,650,597,624,646,672,605,626,654,584,608,631,574,597,622,559,591,614,644,580,603,629,584,615,631,558,591,618,641,314,356,395,397,429,450,421,454,477,507,458,490,560,593]
121
+ labeled_line(:axis_labels => [(1.upto(24).to_a << 1)]).
122
+ should include('chxr=1,85,593')
119
123
  end
120
124
 
121
- it "should force the y range properly" do
122
- url = Gchart.bar(:data => [1,1,1,1,1,1,1,1,6,2,1,1],
125
+ def labeled_bar(options = {})
126
+ Gchart.bar({:data => @data,
123
127
  :axis_with_labels => 'x,y',
124
- :min_value => 0,
125
- :max_value => 16,
126
128
  :axis_labels => [1.upto(12).to_a],
127
- :axis_range => [[0,0],[0,16]],
128
129
  :encoding => "text"
129
- )
130
- url.should include('chxr=0,0,16|1,0,16')
130
+ }.merge(options))
131
+ end
132
+
133
+ it "should force the y range properly" do
134
+ @data = [1,1,1,1,1,1,1,1,6,2,1,1]
135
+ labeled_bar(
136
+ :axis_range => [[0,0],[0,16]]
137
+ ).should include('chxr=0,0,0|1,0,16')
138
+ labeled_bar(
139
+ :max_value => 16,
140
+ :axis_range => [[0,0],[0,16]]
141
+ ).should include('chxr=0,0,16|1,0,16')
142
+
143
+ # nil means ignore axis
144
+ labeled_bar(
145
+ :axis_range => [nil,[0,16]]
146
+ ).should include('chxr=1,0,16')
147
+
148
+ # empty array means take defaults
149
+ labeled_bar(
150
+ :max_value => 16,
151
+ :axis_range => [[],[0,16]]
152
+ ).should include('chxr=0,0,16|1,0,16')
153
+ labeled_bar(
154
+ :axis_range => [[],[0,16]]
155
+ ).should include('chxr=0,0|1,0,16')
131
156
  end
132
157
 
133
158
  it "should take in consideration the max value when creating a range" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: googlecharts
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.4
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Aimonetti
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-03-17 00:00:00 -07:00
12
+ date: 2010-05-06 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15