gchart 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,71 @@
1
+ module GChart
2
+ class Map < GChart::Base
3
+ AREAS = %w[africa asia europe middle_east south_america usa world]
4
+ attr_accessor :area
5
+ attr_accessor :area_codes
6
+ attr_accessor :background
7
+
8
+ def initialize(*args, &block)
9
+ super(*args, &block)
10
+ # Set some sane defaults so that the only requirement is data
11
+ @area = 'world' #default
12
+ @background = 'dfdfff' #make it look like water
13
+ @colors = ['ffffff','f8fcf8','006c00']
14
+ #Set the maximum size for maps (this is a better default because
15
+ # it is also the proper aspect ratio)
16
+ @width = '440'
17
+ @height = '220'
18
+ end
19
+
20
+ # Map data can be in the form {"VA'=>5,'NY'=>1} or [['VA',5],['NY',1]]
21
+ # Raises +ArgumentError+ if data does not fit these forms.
22
+ def data=(data)
23
+ if data.is_a?(Array) && data.any?{ |pair| pair.size != 2 }
24
+ raise ArgumentError, "Data array must contain [area],[value] pairs"
25
+ end
26
+ # 'unzip' the data into separate arrays
27
+ area_data, values = data.to_a.transpose
28
+
29
+ # Reject malformed area codes
30
+ if area_data.any?{ |code| code !~ /^\w\w$/}
31
+ raise ArgumentError, "Area data must have exactly two characters"
32
+ end
33
+ @area_codes = area_data.join.upcase
34
+ super(values)
35
+ end
36
+
37
+ def render_chart_type #:nodoc:
38
+ "t"
39
+ end
40
+
41
+ def area=(area)
42
+ raise ArgumentError unless AREAS.include? area
43
+ @area = area
44
+ end
45
+
46
+ # overrides GChart::Base#query_params
47
+ def query_params(params={}) #:nodoc:
48
+ params["chtm"] = area unless area.empty?
49
+ params["chld"] = area_codes if area_codes
50
+ params["chf"] = "bg,s,#{@background}" if @background
51
+ super(params)
52
+ end
53
+
54
+ # overrides GChart::Base#render_data
55
+ def render_data(params)
56
+ super(params)
57
+ # Maps require at least one data point. Add a "missing value".
58
+ # It may be better to refactor the base class.
59
+ params["chd"] << '__' if params["chd"] =~ /e:$/
60
+ end
61
+
62
+ def render_title(params) #:nodoc:
63
+ nil #N/A for map
64
+ end
65
+
66
+ def render_legend(params) #:nodoc:
67
+ nil #N/A for map
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,29 @@
1
+ module GChart
2
+ class Meter < GChart::Base
3
+ attr_accessor :label
4
+
5
+ def render_chart_type #:nodoc:
6
+ "gom"
7
+ end
8
+
9
+ # The data for a meter is a single data point expressed as a percent
10
+ def render_data(params)
11
+ value = data.is_a?(Array) ? data.flatten.first : data
12
+ params["chd"] = "t:#{value.to_f}"
13
+ end
14
+
15
+ def label=(string)
16
+ return if string.nil?
17
+ if (string.is_a?(Array) && string.size > 1) or string.include?("|")
18
+ raise ArgumentError, "Meter can only have one label"
19
+ end
20
+ @label = string.to_s
21
+ end
22
+
23
+ # Commandeer render_legend to render the label
24
+ def render_legend(params)
25
+ self.label = legend if self.label.nil? # Can use legend instead of label
26
+ params["chl"] = label if label
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ module GChart
2
+ class Sparkline < GChart::Base
3
+ # Sparklines are essentially the same as line charts, but without
4
+ # axis lines. Because they are often placed within text, the default
5
+ # size should be smaller.
6
+ def initialize(*args, &block)
7
+ super(*args, &block)
8
+ @width = "60"
9
+ @height = "20"
10
+ end
11
+ def render_chart_type #:nodoc:
12
+ "ls"
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,3 @@
1
1
  module GChart
2
- VERSION = "0.4.2"
2
+ VERSION = "0.5.0".freeze
3
3
  end
@@ -0,0 +1,13 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../helper")
2
+
3
+ describe GChart::BottomAxis do
4
+ before(:each) { @axis = GChart::Axis.create(:bottom) }
5
+
6
+ it "describes its axis_type_label as 'x'" do
7
+ @axis.axis_type_label.should == 'x'
8
+ end
9
+
10
+ it "describes its range_marker_type_label as being vertical ('R')" do
11
+ @axis.range_marker_type_label.should == 'R'
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../helper")
2
+
3
+ describe GChart::LeftAxis do
4
+ before(:each) { @axis = GChart::Axis.create(:left) }
5
+
6
+ it "describes its axis_type_label as 'y'" do
7
+ @axis.axis_type_label.should == 'y'
8
+ end
9
+
10
+ it "describes its range_marker_type_label as being horizontal ('r')" do
11
+ @axis.range_marker_type_label.should == 'r'
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../helper")
2
+
3
+ describe GChart::RightAxis do
4
+ before(:each) { @axis = GChart::Axis.create(:right) }
5
+
6
+ it "describes its axis_type_label as 'r'" do
7
+ @axis.axis_type_label.should == 'r'
8
+ end
9
+
10
+ it "describes its range_marker_type_label as being horizontal ('r')" do
11
+ @axis.range_marker_type_label.should == 'r'
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../helper")
2
+
3
+ describe GChart::TopAxis do
4
+ before(:each) { @axis = GChart::Axis.create(:top) }
5
+
6
+ it "describes its axis_type_label as 't'" do
7
+ @axis.axis_type_label.should == 't'
8
+ end
9
+
10
+ it "describes its range_marker_type_label as being vertical ('R')" do
11
+ @axis.range_marker_type_label.should == 'R'
12
+ end
13
+ end
@@ -0,0 +1,216 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../helper")
2
+
3
+ describe GChart::Axis do
4
+ before(:each) { @axis = GChart::Axis.create(:bottom) }
5
+
6
+ it "blows up when you try to create it with new" do
7
+ lambda { GChart::Axis.new }.should raise_error(NoMethodError)
8
+ end
9
+
10
+ describe ".create" do
11
+ {
12
+ :top => GChart::TopAxis, :right => GChart::RightAxis,
13
+ :bottom => GChart::BottomAxis, :left => GChart::LeftAxis
14
+ }.each do |axis_type, axis_class|
15
+ it "can create a #{axis_class}" do
16
+ axis = GChart::Axis.create(axis_type)
17
+ axis.should be_instance_of(axis_class)
18
+ end
19
+ end
20
+
21
+ it "explodes with an invalid axis_type" do
22
+ lambda { GChart::Axis.create(:middle) }.should raise_error(ArgumentError)
23
+ end
24
+ end
25
+
26
+ describe ".validate!" do
27
+ it "will validate all axis attributes as working with each other by not blowing up" do
28
+ @axis.validate!
29
+ end
30
+ end
31
+
32
+ describe ".labels" do
33
+ it "will contain an array of labels" do
34
+ @axis.labels = %w(Mon Tue Wed Thu Fri)
35
+ end
36
+ end
37
+
38
+ describe ".label_positions" do
39
+ it "will contain an array of label_positions" do
40
+ @axis.label_positions = [0, 25, 50, 75, 100]
41
+ end
42
+ end
43
+
44
+ describe ".validate!" do
45
+ it "will blow up if there are labels and label_positions, but their sizes don't match" do
46
+ @axis.labels = %w(Mon Tue Wed Thu Fri)
47
+ @axis.label_positions = [0, 25, 50]
48
+ lambda { @axis.validate! }.should raise_error(ArgumentError)
49
+ end
50
+
51
+ it "will be happy when there is 1 label_position for every label" do
52
+ @axis.labels = %w(Mon Tue Wed Thu Fri)
53
+ @axis.label_positions = [0, 25, 50, 75, 100]
54
+ @axis.validate!
55
+ end
56
+
57
+ it "will be happy if there are labels but no label_positions" do
58
+ @axis.labels = %w(Mon Tue Wed Thu Fri)
59
+ @axis.validate!
60
+ end
61
+
62
+ it "will be happy if there are label_positions but no labels" do
63
+ @axis.label_positions = [0, 25, 50, 75, 100]
64
+ @axis.validate!
65
+ end
66
+
67
+ it "will blow up if label_positions contains non-numeric values" do
68
+ @axis.label_positions = %w(a e h l)
69
+ lambda { @axis.validate! }.should raise_error(ArgumentError)
70
+ end
71
+ end
72
+
73
+ describe ".range" do
74
+ it "will contain a range from which to derive labels" do
75
+ @axis.range = 0..1300
76
+ end
77
+ end
78
+
79
+ describe ".validate!" do
80
+ it "will blow up if range() does not contain a range" do
81
+ @axis.range = [0, 50, 100]
82
+ lambda { @axis.validate! }.should raise_error(ArgumentError)
83
+ end
84
+
85
+ it "will blow up if range() contains a range of non-numeric values" do
86
+ @axis.range = 'a'..'z'
87
+ lambda { @axis.validate! }.should raise_error(ArgumentError)
88
+ end
89
+
90
+ it "will be content if a range is used in combination with labels" do
91
+ @axis.range = 0..100
92
+ @axis.labels = [25, 50, 75]
93
+ @axis.validate!
94
+ end
95
+
96
+ it "will be content if a range is used in combination with labels and label_positions both" do
97
+ @axis.range = 0..100
98
+ @axis.labels = %w(25 50 75)
99
+ @axis.label_positions = [25, 50, 75]
100
+ @axis.validate!
101
+ end
102
+ end
103
+
104
+ describe ".text_color" do
105
+ it "will contain the color in which to draw axis labelings" do
106
+ @axis.text_color = :green
107
+ end
108
+ end
109
+
110
+ describe ".font_size" do
111
+ it "will contain the font_size for the labels on the axis" do
112
+ @axis.font_size = 12
113
+ end
114
+ end
115
+
116
+ describe ".text_alignment" do
117
+ it "will contain the information on how to align labels on the axis" do
118
+ @axis.text_alignment = :right
119
+ end
120
+ end
121
+
122
+ describe ".validate!" do
123
+ it "will be happy if the text_color is a valid color" do
124
+ @axis.text_color = 'ff0199aa'
125
+ @axis.validate!
126
+ end
127
+
128
+ it "will blow up if the text_color is not a valid color" do
129
+ @axis.text_color = :rgb_freakout
130
+ lambda { @axis.validate! }.should raise_error(ArgumentError)
131
+ end
132
+
133
+ it "will be happy if font_size is specified along with text_color" do
134
+ @axis.text_color = 'bbb'
135
+ @axis.font_size = 12
136
+ @axis.validate!
137
+ end
138
+
139
+ it "will blow up if font_size is given without a corresponding text_color" do
140
+ @axis.font_size = 12
141
+ lambda { @axis.validate! }.should raise_error(ArgumentError)
142
+ end
143
+
144
+ it "will blow up if the text_color is valid but the font_size is not numeric" do
145
+ @axis.text_color = :black
146
+ @axis.font_size = "13.5"
147
+ lambda { @axis.validate! }.should raise_error(ArgumentError)
148
+ end
149
+
150
+ it "will be happy if text_alignment is specified with both font_size and text_color" do
151
+ @axis.text_alignment = :center
152
+ @axis.font_size = 11.5
153
+ @axis.text_color = :cyan
154
+ @axis.validate!
155
+ end
156
+
157
+ it "will blow up if text_alignment is given without both font_size and text_color" do
158
+ @axis.text_alignment = :left
159
+ lambda { @axis.validate! }.should raise_error(ArgumentError)
160
+ end
161
+
162
+ it "will blow up if text_alignment is given with a valid font_size but no text_color" do
163
+ @axis.text_alignment = :left
164
+ @axis.font_size = 10
165
+ lambda { @axis.validate! }.should raise_error(ArgumentError)
166
+ end
167
+
168
+ it "will blow up if text_alignment is given with a valid text_color but no font_size" do
169
+ @axis.text_alignment = :left
170
+ @axis.text_color = :magenta
171
+ lambda { @axis.validate! }.should raise_error(ArgumentError)
172
+ end
173
+
174
+ it "will blow up if font_size and text_color are valid, but text_alignment isn't in TEXT_ALIGNMENT table" do
175
+ @axis.text_color = :magenta
176
+ @axis.font_size = 12
177
+ @axis.text_alignment = :upper
178
+ lambda { @axis.validate! }.should raise_error(ArgumentError)
179
+ end
180
+ end
181
+
182
+ describe ".range_markers" do
183
+ it "will contain an array of ranges of markers and their colors" do
184
+ @axis.range_markers = [[45..70, :magenta], [75..90, :pink]]
185
+ end
186
+ end
187
+
188
+ describe ".validate!" do
189
+ it "be happy when range_markers contains an array of 2-element subarrays of ranges and colors" do
190
+ @axis.range_markers = [[45..70, :magenta], [75..90, :pink]]
191
+ @axis.validate!
192
+ end
193
+
194
+ it "will bomb if any element in range_markers is not an array of 2 elements" do
195
+ @axis.range_markers = ["string", :thistle]
196
+ lambda { @axis.validate! }.should raise_error(ArgumentError)
197
+
198
+ @axis.range_markers = [[:one, :two, :three], [:un, :deux, :trois]]
199
+ lambda { @axis.validate! }.should raise_error(ArgumentError)
200
+ end
201
+
202
+ it "will bomb if the 1st element in any of the 2-element arrays in range_markers is not a numeric range" do
203
+ @axis.range_markers = [[75, :blue], [75..100, :green]]
204
+ lambda { @axis.validate! }.should raise_error(ArgumentError)
205
+
206
+ @axis.range_markers = [['a'..'z', :blue], [75..10, :green]]
207
+ lambda { @axis.validate! }.should raise_error(ArgumentError)
208
+ end
209
+
210
+ it "will bomb if the 2nd element in any of the 2-element arrays in range_markers is not a valid color" do
211
+ @axis.range_markers = [[75..90, :blue], [75..100, :cyantiago]]
212
+ lambda { @axis.validate! }.should raise_error(ArgumentError)
213
+ end
214
+ end
215
+
216
+ end
@@ -98,6 +98,27 @@ describe GChart::Base, "#query_params" do
98
98
  @chart.query_params["chtt"].should == "foo|bar"
99
99
  end
100
100
 
101
+ it "contains the chart's data colors" do
102
+ @chart.colors = ["cccccc", "eeeeee", :salmon3, "49d", :red]
103
+ @chart.query_params["chco"].should == "cccccc,eeeeee,cd7054,4499dd,ff0000"
104
+
105
+ @chart.colors = []
106
+ @chart.query_params["chco"].should be_nil
107
+ end
108
+
109
+ it "contains the chart's background colors" do
110
+ @chart.query_params["chf"].should be_nil
111
+
112
+ @chart.entire_background = :red
113
+ @chart.query_params["chf"].should == "bg,s,ff0000"
114
+
115
+ @chart.chart_background = "704"
116
+ @chart.query_params["chf"].should == "bg,s,ff0000|c,s,770044"
117
+
118
+ @chart.entire_background = nil
119
+ @chart.query_params["chf"].should == "c,s,770044"
120
+ end
121
+
101
122
  it "contains the chart's colors" do
102
123
  @chart.colors = ["cccccc", "eeeeee"]
103
124
  @chart.query_params["chco"].should == "cccccc,eeeeee"
@@ -154,3 +175,89 @@ describe GChart::Base, "#write" do
154
175
  result.should == "PAYLOAD"
155
176
  end
156
177
  end
178
+
179
+ describe GChart::Base, "#axis" do
180
+ before(:each) do
181
+ @chart = GChart::Line.new
182
+ @axis = @chart.axis(:bottom)
183
+ end
184
+
185
+ it "instantiates a new GChart::Axis of the proper axis_type" do
186
+ chart = GChart::Line.new
187
+ axis = chart.axis(:bottom)
188
+ axis.is_a?(GChart::BottomAxis).should == true
189
+ end
190
+
191
+ it "pushes the new axis to the chart's set of axes" do
192
+ chart = GChart::Line.new
193
+ axis = chart.axis(:bottom)
194
+ chart.axes.first.should == axis
195
+ end
196
+
197
+ [GChart::Line, GChart::Bar, GChart::Scatter].each do |chart_type|
198
+ it "renders axis information when chart axes are present and chart is of proper type" do
199
+ chart = chart_type.new
200
+ axis = chart.axis(:left)
201
+ chart.to_url.should =~ /chxt/
202
+ end
203
+ end
204
+
205
+ [GChart::Pie3D, GChart::Pie, GChart::Venn, GChart::XYLine].each do |chart_type|
206
+ it "should not render axis information when chart axes are present but chart is not of proper type" do
207
+ chart = chart_type.new
208
+ axis = chart.axis(:left)
209
+ chart.to_url.should_not =~ /chxt/
210
+ end
211
+ end
212
+ end
213
+
214
+ describe GChart::Base, "#entire_background" do
215
+ it "sets the background color for the entire chart" do
216
+ chart = GChart.line
217
+ chart.entire_background = :blue
218
+ end
219
+ end
220
+
221
+ describe GChart::Base, "#chart_background" do
222
+ it "sets the background color for just the chart area of the chart image" do
223
+ chart = GChart.bar
224
+ chart.chart_background = "876"
225
+ end
226
+ end
227
+
228
+ describe GChart::Base, "#render_backgrounds" do
229
+ before(:each) do
230
+ @chart = GChart::Line.new
231
+ end
232
+
233
+ it "verifies that background colors are valid colors" do
234
+ @chart.chart_background = :cyan
235
+ @chart.to_url
236
+
237
+ @chart.entire_background = 'f37'
238
+ @chart.to_url
239
+ end
240
+
241
+ it "blows up if either of the background colors are invalid" do
242
+ @chart.chart_background = :redneck_skin
243
+ lambda { @chart.to_url }.should raise_error(ArgumentError)
244
+
245
+ @chart.chart_background = nil
246
+ @chart.entire_background = 'f375'
247
+ lambda { @chart.to_url }.should raise_error(ArgumentError)
248
+ end
249
+
250
+ it "renders chart background information correctly" do
251
+ @chart.to_url.should_not =~ /chf=/
252
+
253
+ @chart.chart_background = 'f3A'
254
+ @chart.to_url.should =~ /chf=c,s,ff33AA/
255
+
256
+ @chart.entire_background = :yellow
257
+ @chart.to_url.should =~ /chf=bg,s,ffff00%7Cc,s,ff33AA/
258
+
259
+ @chart.chart_background = nil
260
+ @chart.to_url.should_not =~ /chf=bg,s,ffff00%7Cc,s,ff33AA/
261
+ @chart.to_url.should =~ /chf=bg,s,ffff00/
262
+ end
263
+ end