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 +6 -1
- data/VERSION +1 -1
- data/lib/gchart.rb +55 -55
- data/lib/gchart/aliases.rb +2 -1
- data/spec/gchart_spec.rb +35 -10
- metadata +2 -2
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.
|
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 "
|
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] ||=
|
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
|
-
|
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
|
-
|
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
|
-
|
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 ||
|
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=\"#{
|
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
|
-
|
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
|
-
|
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
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
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
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
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
|
-
|
484
|
-
when '
|
485
|
-
|
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
|
-
"
|
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
|
-
|
509
|
-
when '
|
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 =
|
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 =
|
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(
|
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(
|
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 = '&'
|
684
684
|
end
|
685
685
|
|
686
|
-
jstize(
|
686
|
+
jstize(query_params.join(delimiter))
|
687
687
|
end
|
688
688
|
|
689
689
|
end
|
data/lib/gchart/aliases.rb
CHANGED
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
|
-
|
118
|
-
|
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
|
-
|
122
|
-
|
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
|
-
|
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.
|
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-
|
12
|
+
date: 2010-05-06 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|