gchart 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,15 @@
1
+ == 0.5.0 (2008-05-11)
2
+
3
+ * Support for Map charts [Mark Thomas]
4
+ * Support for Sparkline charts [Mark Thomas]
5
+ * Initial support for Google-o-meter [Mark Thomas]
6
+ * Implemented both background solid fill and chart area solid fill.
7
+ * Added color aliasing: 3-character colors and a COLORS table.
8
+ * Full support for axis labels.
9
+ * Implemented horizontal/vertical range markers.
10
+ * New committer, Jim Ludwig.
11
+ * Freeze GChart::VERSION.
12
+
1
13
  == 0.4.2 (2008-01-09)
2
14
 
3
15
  * Encoding a flatlined chart doesn't asplode [Jack Danger Canty]
@@ -3,21 +3,41 @@ Manifest.txt
3
3
  README.txt
4
4
  Rakefile
5
5
  lib/gchart.rb
6
+ lib/gchart/axis.rb
7
+ lib/gchart/axis/bottom_axis.rb
8
+ lib/gchart/axis/horizontal_axis.rb
9
+ lib/gchart/axis/left_axis.rb
10
+ lib/gchart/axis/right_axis.rb
11
+ lib/gchart/axis/top_axis.rb
12
+ lib/gchart/axis/vertical_axis.rb
6
13
  lib/gchart/bar.rb
7
14
  lib/gchart/base.rb
15
+ lib/gchart/colors.rb
8
16
  lib/gchart/line.rb
17
+ lib/gchart/map.rb
18
+ lib/gchart/meter.rb
9
19
  lib/gchart/pie.rb
10
20
  lib/gchart/pie_3d.rb
11
21
  lib/gchart/scatter.rb
22
+ lib/gchart/sparkline.rb
12
23
  lib/gchart/venn.rb
13
24
  lib/gchart/xy_line.rb
14
25
  lib/version.rb
26
+ spec/gchart/axis/bottom_axis_spec.rb
27
+ spec/gchart/axis/left_axis_spec.rb
28
+ spec/gchart/axis/right_axis_spec.rb
29
+ spec/gchart/axis/top_axis_spec.rb
30
+ spec/gchart/axis_spec.rb
15
31
  spec/gchart/bar_spec.rb
16
32
  spec/gchart/base_spec.rb
33
+ spec/gchart/colors_spec.rb
17
34
  spec/gchart/line_spec.rb
35
+ spec/gchart/map_spec.rb
36
+ spec/gchart/meter_spec.rb
18
37
  spec/gchart/pie_3d_spec.rb
19
38
  spec/gchart/pie_spec.rb
20
39
  spec/gchart/scatter_spec.rb
40
+ spec/gchart/sparkline_spec.rb
21
41
  spec/gchart/venn_spec.rb
22
42
  spec/gchart/xy_line_spec.rb
23
43
  spec/gchart_spec.rb
data/README.txt CHANGED
@@ -8,9 +8,9 @@ a friendly Ruby interface. It can generate the URL for a given chart
8
8
 
9
9
  == PROBLEMS/TODO
10
10
 
11
- * Add support fills (area or background), grid lines, shape markers, range markers
12
- * Support shorthand colors and color names
11
+ * Add grid lines, linear stripes, shape markers, gradient fills
13
12
  * Make venn data specification friendlier
13
+ * Make documentation more digestible
14
14
 
15
15
  There are lots of missing features. Until they're implemented, you can directly specify
16
16
  query parameters using the :extras key, e.g.,
@@ -34,6 +34,12 @@ query parameters using the :extras key, e.g.,
34
34
 
35
35
  # scatter plot (x coords, y coords [, sizes])
36
36
  g = GChart.scatter(:data => [[1, 2, 3, 4, 5], [5, 4, 3, 2, 1], [1, 2, 3, 4, 5]])
37
+
38
+ # map chart
39
+ g = GChart.map(:area => 'usa', :data => {'NY'=>1,'VA'=>3,'CA'=>2})
40
+
41
+ # meter
42
+ g = GChart.meter(:data => 70, :label => "70%")
37
43
 
38
44
  # chart title
39
45
  g = GChart.line(:title => "Awesomeness over Time", :data => [0, 10, 100])
@@ -49,11 +55,98 @@ query parameters using the :extras key, e.g.,
49
55
  g.write("foo.png") # write to a file (defaults to "chart.png")
50
56
  g.write(stream) # write to anything that quacks like IO
51
57
 
58
+ == AXIS LABELING
59
+
60
+ Charts which support an axis concept can be labeled. Supported types
61
+ are line charts, bar charts, radar charts and scatter plots. See
62
+ +GChart::Axis+ for more information.
63
+
64
+ == EXAMPLES
65
+
66
+ === Simple Line Chart with 2 data sets
67
+
68
+ require 'gchart'
69
+ chart = GChart.line do |g|
70
+ g.data = [[0, 1, 2, 3, 4, 5, 6], [3, 2, 4, 1, 5, 0, 6]]
71
+ g.colors = [:red, :yellow]
72
+ g.legend = ["Line", "Wonkiness"]
73
+
74
+ g.width = 600
75
+ g.height = 150
76
+
77
+ g.entire_background = "f4f4f4"
78
+
79
+ g.axis(:left) { |a| a.range = 0..6 }
80
+
81
+ g.axis(:bottom) do |a|
82
+ a.labels = ["Mon", "Tue", "Thu", "Sun"]
83
+ a.label_positions = [0, 16.67, 50, 100]
84
+ a.text_color = :black
85
+ end
86
+
87
+ g.axis(:bottom) do |a|
88
+ a.labels = ["Week 42"]
89
+ a.label_positions = [50]
90
+ end
91
+ end
92
+
93
+ === Complex Line Chart with multiple axes
94
+
95
+ require 'gchart'
96
+ chart = GChart.line do |g|
97
+ g.data = [data_array1, data_array2, data_array3]
98
+ g.colors = [:red, :green, :blue]
99
+ g.legend = ["Set 1", "Set 2", "Set 3"]
100
+
101
+ g.width = 950
102
+ g.height = 315
103
+
104
+ g.entire_background = "434"
105
+ g.chart_background = "aba"
106
+
107
+ g.axis(:left) do |a|
108
+ a.range = 0..100
109
+ a.text_color = :red
110
+ a.font_size = 9
111
+ end
112
+
113
+ g.axis(:right) do |a|
114
+ a.range = 0..1000
115
+ a.labels = %w(250 500 750)
116
+ a.label_positions = [250, 500, 750]
117
+
118
+ a.text_color = :green
119
+ a.font_size = 8
120
+ a.text_alignment = :right
121
+ end
122
+
123
+ g.axis(:top) do |a|
124
+ a.labels = %w(2008)
125
+ a.positions = [50]
126
+ end
127
+
128
+ bottom1 = g.axis(:bottom)
129
+ bottom1.labels = dates_array
130
+ bottom1.range_markers = [
131
+ [0..33.33, 'ff000044'], [33.33..66.67, '00ff0044'], [66.67..100, '0000ff44']
132
+ ]
133
+
134
+ # We "manually" create our 2nd bottom axis...
135
+ bottom2 = GChart::Axis.create(:bottom)
136
+ bottom2.labels = %w(Dates)
137
+ bottom2.label_positions = [50]
138
+
139
+ # ...and therefore need to also add it to our axes "manually".
140
+ g.axes << bottom2
141
+ end
142
+
143
+ url = chart.to_url
144
+
52
145
  == LICENSE
53
146
 
54
147
  (The MIT License)
55
148
 
56
- Copyright 2007-2008 John Barnette (jbarnette@rubyforge.org)
149
+ Copyright 2007-2008 John Barnette (jbarnette@rubyforge.org), Jim Ludwig (supplanter@rubyforge.org)
57
150
 
58
151
  Permission is hereby granted, free of charge, to any person obtaining
59
152
  a copy of this software and associated documentation files (the
@@ -1,9 +1,15 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + "/version")
2
+ require File.expand_path(File.dirname(__FILE__) + "/gchart/colors")
3
+ require File.expand_path(File.dirname(__FILE__) + "/gchart/axis")
2
4
 
3
- %w(base bar line pie pie_3d scatter venn xy_line).each do |type|
5
+ %w(base bar line map meter pie pie_3d scatter sparkline venn xy_line).each do |type|
4
6
  require File.expand_path(File.dirname(__FILE__) + "/gchart/#{type}")
5
7
  end
6
8
 
9
+ %w(horizontal vertical top right bottom left).each do |type|
10
+ require File.expand_path(File.dirname(__FILE__) + "/gchart/axis/#{type}_axis")
11
+ end
12
+
7
13
  module GChart
8
14
  URL = "http://chart.apis.google.com/chart"
9
15
  SIMPLE_CHARS = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a
@@ -20,18 +26,27 @@ module GChart
20
26
  # Convenience constructor for GChart::Bar.
21
27
  def bar(*args, &block); Bar.new(*args, &block) end
22
28
 
29
+ # Convenience constructor for GChart::Map.
30
+ def map(*args, &block); Map.new(*args, &block) end
31
+
32
+ # Convenience constructor for GChart::Meter.
33
+ def meter(*args, &block); Meter.new(*args, &block) end
34
+
23
35
  # Convenience constructor for GChart::Pie.
24
36
  def pie(*args, &block); Pie.new(*args, &block) end
25
37
 
26
38
  # Convenience constructor for GChart::Pie3D.
27
39
  def pie3d(*args, &block); Pie3D.new(*args, &block) end
28
40
 
29
- # Convenience constructor for GChart::Venn.
30
- def venn(*args, &block); Venn.new(*args, &block) end
31
-
32
41
  # Convenience constructor for GChart::Scatter.
33
42
  def scatter(*args, &block); Scatter.new(*args, &block) end
34
43
 
44
+ # Convenience constructor for GChart::Sparkline.
45
+ def sparkline(*args, &block); Sparkline.new(*args, &block) end
46
+
47
+ # Convenience constructor for GChart::Venn.
48
+ def venn(*args, &block); Venn.new(*args, &block) end
49
+
35
50
  # Encode +n+ as a string. +n+ is normalized based on +max+.
36
51
  # +encoding+ can currently only be :extended.
37
52
  def encode(encoding, n, max)
@@ -0,0 +1,139 @@
1
+ module GChart
2
+ class Axis
3
+
4
+ # Array of axis labels. Can be exactly placed along the axis with
5
+ # +label_positions+, otherwise are evenly spaced.
6
+ attr_accessor :labels
7
+
8
+ # Array of float positions for +labels+. Without +labels+, the
9
+ # +label_positions+ are self-labeling.
10
+ attr_accessor :label_positions
11
+
12
+ # Takes a +Range+ of float values. With +labels+, defines +labels+
13
+ # context, meaning the +labels+ will be spaced at their proper
14
+ # location within the +range+. Without +labels+, smart-labeling
15
+ # occurs for +range+.
16
+ attr_accessor :range
17
+
18
+ # An rrggbb color for axis text.
19
+ attr_accessor :text_color
20
+
21
+ # Size of font in pixels. To set +font_size+, +text_color+ is also
22
+ # required.
23
+ attr_accessor :font_size
24
+
25
+ # +TEXT_ALIGNMENT+ property for axis labeling. To set
26
+ # +text_alignment+, both +text_color+ and +font_size+ must also be
27
+ # set.
28
+ attr_accessor :text_alignment
29
+
30
+ # Array of 2-element sub-arrays such that the 1st element in each
31
+ # sub-array is a +Range+ of float values which describe the start
32
+ # and end points of the range marker, and the 2nd element in each
33
+ # sub-array is an rrggbb color for the range marker. For +:top+
34
+ # and +:bottom+ +AXIS_TYPES+, markers are vertical. For +:right+
35
+ # and +:left+ +AXIS_TYPES+, markers are horizontal.
36
+ attr_accessor :range_markers
37
+
38
+ AXIS_TYPES = [ :top, :right, :bottom, :left ]
39
+
40
+ # Defaults: +:left+ for +RightAxis+, +:center+ for +TopAxis+ and
41
+ # for +BottomAxis+, and +:right+ for +LeftAxis+.
42
+ TEXT_ALIGNMENT = { :left => -1, :center => 0, :right => 1 }
43
+
44
+ class << self
45
+ # Instantiates the proper +GChart::Axis+ subclass based on the
46
+ # +axis_type+.
47
+ def create(axis_type, &block)
48
+ raise ArgumentError.new("Invalid axis type '#{axis_type}'") unless AXIS_TYPES.include?(axis_type)
49
+
50
+ axis = Object.module_eval("GChart::#{axis_type.to_s.capitalize}Axis").new
51
+
52
+ yield(axis) if block_given?
53
+ axis
54
+ end
55
+
56
+ private :new
57
+ end
58
+
59
+ def initialize
60
+ @labels = []
61
+ @label_positions = []
62
+ @range_markers = {}
63
+ end
64
+
65
+ # Returns a one-character label of the axis according to its type.
66
+ def axis_type_label
67
+ raise NotImplementedError.new("Method must be overridden in a subclass of this abstract base class.")
68
+ end
69
+
70
+ # Returns a one-character label to indicate whether
71
+ # +ranger_markers+ are vertical or horizontal.
72
+ def range_marker_type_label
73
+ raise NotImplementedError.new("Method must be overridden in a subclass of this abstract base class.")
74
+ end
75
+
76
+ # Ensures that all combinations of attributes which have been set
77
+ # will work with each other. Raises +ArgumentError+ otherwise.
78
+ def validate!
79
+ if labels.size > 0 and label_positions.size > 0 and labels.size != label_positions.size
80
+ raise ArgumentError.new(
81
+ "Both labels and label_positions have been specified, but their " +
82
+ "respective counts do not match (labels.size = '#{labels.size}' " +
83
+ "and label_positions.size = '#{label_positions.size}')"
84
+ )
85
+ end
86
+
87
+ unless label_positions.all? { |pos| pos.is_a?(Numeric) }
88
+ raise ArgumentError.new(
89
+ "The label_positions attribute requires numeric values for each position specified"
90
+ )
91
+ end
92
+
93
+ if range
94
+ unless range.is_a?(Range)
95
+ raise ArgumentError.new("The range attribute has been specified with a non-Range class")
96
+ end
97
+
98
+ unless range.first.is_a?(Numeric)
99
+ raise ArgumentError.new("The range attribute has been specified with non-numeric range values")
100
+ end
101
+ end
102
+
103
+ if font_size and not text_color
104
+ raise ArgumentError.new("To specify a font_size, a text_color must also be specified")
105
+ end
106
+
107
+ if text_alignment and not (text_color and font_size)
108
+ raise ArgumentError.new(
109
+ "To specify a text_alignment, both text_color and font_size must also be specified"
110
+ )
111
+ end
112
+
113
+ if text_color and not GChart.valid_color?(text_color)
114
+ raise ArgumentError.new("The text_color attribute has been specified with an invalid color")
115
+ end
116
+
117
+ if font_size and not font_size.is_a?(Numeric)
118
+ raise ArgumentError.new("The font_size must have a numeric value")
119
+ end
120
+
121
+ if text_alignment and not TEXT_ALIGNMENT[text_alignment]
122
+ raise ArgumentError.new(
123
+ "The text_alignment attribute has been specified with a non-TEXT_ALIGNMENT"
124
+ )
125
+ end
126
+
127
+ if not range_markers.all? { |array| array.is_a?(Array) and array.size == 2 and
128
+ array[0].is_a?(Range) and array[0].first.is_a?(Numeric) and
129
+ GChart.valid_color?(array[1]) }
130
+ raise ArgumentError.new(
131
+ "The range_markers attribute must be an array of 2-element sub-arrays such that " +
132
+ "the first element in each sub-array is a Range of numeric values and the second " +
133
+ "element in each sub-array is a valid color"
134
+ )
135
+ end
136
+ end
137
+
138
+ end
139
+ end
@@ -0,0 +1,10 @@
1
+ module GChart
2
+ class BottomAxis < HorizontalAxis
3
+ # Returns 'x'.
4
+ def axis_type_label
5
+ 'x'
6
+ end
7
+
8
+ class << self ; public :new ; end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ module GChart
2
+ class HorizontalAxis < Axis
3
+ # Returns 'R' to indicate a vertical +range_marker+ (stemming
4
+ # from a horizontal axis).
5
+ def range_marker_type_label
6
+ 'R'
7
+ end
8
+
9
+ class << self ; private :new ; end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module GChart
2
+ class LeftAxis < VerticalAxis
3
+ # Returns 'y'.
4
+ def axis_type_label
5
+ 'y'
6
+ end
7
+
8
+ class << self ; public :new ; end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module GChart
2
+ class RightAxis < VerticalAxis
3
+ # Returns 'r'.
4
+ def axis_type_label
5
+ 'r'
6
+ end
7
+
8
+ class << self ; public :new ; end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module GChart
2
+ class TopAxis < HorizontalAxis
3
+ # Returns 't'.
4
+ def axis_type_label
5
+ 't'
6
+ end
7
+
8
+ class << self ; public :new ; end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ module GChart
2
+ class VerticalAxis < Axis
3
+ # Returns 'r' to indicate a horizontal +range_marker+ (stemming
4
+ # from a vertical axis).
5
+ def range_marker_type_label
6
+ 'r'
7
+ end
8
+
9
+ class << self ; private :new ; end
10
+ end
11
+ end
@@ -5,31 +5,44 @@ module GChart
5
5
  class Base
6
6
  # Array of chart data. See subclasses for specific usage.
7
7
  attr_accessor :data
8
-
8
+
9
9
  # Hash of additional HTTP query params.
10
10
  attr_accessor :extras
11
-
11
+
12
12
  # Chart title.
13
13
  attr_accessor :title
14
-
14
+
15
15
  # Array of rrggbb colors, one per data set.
16
16
  attr_accessor :colors
17
-
17
+
18
18
  # Array of legend text, one per data set.
19
19
  attr_accessor :legend
20
-
20
+
21
21
  # Max data value for quantization.
22
22
  attr_accessor :max
23
23
 
24
24
  # Chart width, in pixels.
25
- attr_reader :width
26
-
25
+ attr_reader :width
26
+
27
27
  # Chart height, in pixels.
28
28
  attr_reader :height
29
29
 
30
+ # Background rrggbb color of entire chart image.
31
+ attr_accessor :entire_background
32
+
33
+ # Background rrggbb color of just chart area of chart image.
34
+ attr_accessor :chart_background
35
+
36
+ # Array of +GChart::Axis+ objects.
37
+ attr_accessor :axes
38
+
30
39
  def initialize(options={}, &block)
31
- @data = []
40
+ @data = []
41
+ @colors = []
42
+ @legend = []
43
+ @axes = []
32
44
  @extras = {}
45
+
33
46
  @width = 300
34
47
  @height = 200
35
48
 
@@ -51,9 +64,9 @@ module GChart
51
64
  # if +height+ is less than 1 or greater than 1,000.
52
65
  def height=(height)
53
66
  if height.nil? || height < 1 || height > 1_000
54
- raise ArgumentError, "Invalid height: #{height.inspect}"
67
+ raise ArgumentError, "Invalid height: #{height.inspect}"
55
68
  end
56
-
69
+
57
70
  @height = height
58
71
  end
59
72
 
@@ -66,7 +79,7 @@ module GChart
66
79
  # if +width+ * +height+ is greater than 300,000 pixels.
67
80
  def size=(size)
68
81
  self.width, self.height = size.split("x").collect { |n| Integer(n) }
69
-
82
+
70
83
  if (width * height) > 300_000
71
84
  raise ArgumentError, "Invalid size: #{size.inspect} yields a graph with more than 300,000 pixels"
72
85
  end
@@ -90,6 +103,14 @@ module GChart
90
103
  open(io_or_file, "w+") { |io| io.write(fetch) }
91
104
  end
92
105
 
106
+ # Adds an +axis_type+ +GChart::Axis+ to the chart's set of
107
+ # +axes+. See +GChart::Axis::AXIS_TYPES+.
108
+ def axis(axis_type, &block)
109
+ axis = GChart::Axis.create(axis_type, &block)
110
+ @axes.push(axis)
111
+ axis
112
+ end
113
+
93
114
  protected
94
115
 
95
116
  def query_params(raw_params={}) #:nodoc:
@@ -99,6 +120,13 @@ module GChart
99
120
  render_title(params)
100
121
  render_colors(params)
101
122
  render_legend(params)
123
+ render_backgrounds(params)
124
+
125
+ unless @axes.empty?
126
+ if is_a?(GChart::Line) or is_a?(GChart::Bar) or is_a?(GChart::Scatter) # or is_a?(GChart::Radar)
127
+ render_axes(params)
128
+ end
129
+ end
102
130
 
103
131
  params.merge(extras)
104
132
  end
@@ -110,24 +138,127 @@ module GChart
110
138
  def render_data(params) #:nodoc:
111
139
  raw = data && data.first.is_a?(Array) ? data : [data]
112
140
  max = self.max || raw.collect { |s| s.max }.max
113
-
141
+
114
142
  sets = raw.collect do |set|
115
143
  set.collect { |n| GChart.encode(:extended, n, max) }.join
116
144
  end
117
-
118
145
  params["chd"] = "e:#{sets.join(",")}"
119
146
  end
120
147
 
121
148
  def render_title(params) #:nodoc:
122
149
  params["chtt"] = title.tr("\n ", "|+") if title
123
150
  end
124
-
151
+
125
152
  def render_colors(params) #:nodoc:
126
- params["chco"] = colors.join(",") if colors
153
+ unless colors.empty?
154
+ params["chco"] = colors.collect{ |color| GChart.expand_color(color) }.join(",")
155
+ end
127
156
  end
128
-
157
+
129
158
  def render_legend(params) #:nodoc:
130
- params["chdl"] = legend.join("|") if legend
131
- end
159
+ params["chdl"] = legend.join("|") unless legend.empty?
160
+ end
161
+
162
+ def render_backgrounds(params) #:nodoc:
163
+ if entire_background || chart_background
164
+ if entire_background and not GChart.valid_color?(entire_background)
165
+ raise ArgumentError.new("The entire_background attribute has an invalid color")
166
+ end
167
+ if chart_background and not GChart.valid_color?(chart_background)
168
+ raise ArgumentError.new("The chart_background attribute has an invalid color")
169
+ end
170
+
171
+ separator = entire_background && chart_background ? "|" : ""
172
+ params["chf"] = entire_background ? "bg,s,#{GChart.expand_color(entire_background)}" : ""
173
+ params["chf"] += "#{separator}c,s,#{GChart.expand_color(chart_background)}" if chart_background
174
+ end
175
+ end
176
+
177
+ def render_axes(params) #:nodoc:
178
+ @axes.each do |axis|
179
+ axis.validate!
180
+ end
181
+
182
+ render_axis_type_labels(params)
183
+ render_axis_labels(params)
184
+ render_axis_label_positions(params)
185
+ render_axis_ranges(params)
186
+ render_axis_styles(params)
187
+ render_axis_range_markers(params)
188
+ end
189
+
190
+ def render_axis_type_labels(params) #:nodoc:
191
+ params["chxt"] = @axes.collect{ |axis| axis.axis_type_label }.join(',')
192
+ end
193
+
194
+ def render_axis_labels(params) #:nodoc:
195
+ if @axes.any?{ |axis| axis.labels.size > 0 }
196
+ chxl = []
197
+
198
+ @axes.each_with_index do |axis, index|
199
+ if axis.labels.size > 0
200
+ chxl.push("#{index}:")
201
+ chxl += axis.labels
202
+ end
203
+ end
204
+
205
+ params["chxl"] = chxl.join('|')
206
+ end
207
+ end
208
+
209
+ def render_axis_label_positions(params) #:nodoc:
210
+ if @axes.any?{ |axis| axis.label_positions.size > 0 }
211
+ chxp = []
212
+
213
+ @axes.each_with_index do |axis, index|
214
+ chxp.push("#{index}," + axis.label_positions.join(',')) if axis.label_positions.size > 0
215
+ end
216
+
217
+ params["chxp"] = chxp.join('|')
218
+ end
219
+ end
220
+
221
+ def render_axis_ranges(params) #:nodoc:
222
+ if @axes.any?{ |axis| axis.range }
223
+ chxr = []
224
+
225
+ @axes.each_with_index do |axis, index|
226
+ chxr.push("#{index},#{axis.range.first},#{axis.range.last}") if axis.range
227
+ end
228
+
229
+ params["chxr"] = chxr.join('|')
230
+ end
231
+ end
232
+
233
+ def render_axis_styles(params) #:nodoc:
234
+ if @axes.any?{ |axis| axis.text_color }
235
+ chxs = []
236
+
237
+ @axes.each_with_index do |axis, index|
238
+ if axis.text_color
239
+ chxs.push(
240
+ "#{index}," +
241
+ [GChart.expand_color(axis.text_color), axis.font_size, axis.text_alignment].compact.join(',')
242
+ )
243
+ end
244
+ end
245
+
246
+ params["chxs"] = chxs.join('|')
247
+ end
248
+ end
249
+
250
+ def render_axis_range_markers(params) #:nodoc:
251
+ if @axes.any?{ |axis| axis.range_markers.size > 0 }
252
+ chmr = []
253
+
254
+ @axes.each do |axis|
255
+ axis.range_markers.each do |range, color|
256
+ chmr.push("#{axis.range_marker_type_label},#{color},0,#{range.first},#{range.last}")
257
+ end
258
+ end
259
+
260
+ params["chm"] = chmr.join('|')
261
+ end
262
+ end
132
263
  end
133
264
  end