gchart 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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