gruff 0.9.0 → 0.12.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +21 -4
  3. data/.rubocop_todo.yml +103 -49
  4. data/.travis.yml +3 -6
  5. data/CHANGELOG.md +30 -0
  6. data/README.md +4 -0
  7. data/gruff.gemspec +8 -3
  8. data/lib/gruff.rb +9 -3
  9. data/lib/gruff/accumulator_bar.rb +13 -5
  10. data/lib/gruff/area.rb +22 -5
  11. data/lib/gruff/bar.rb +38 -10
  12. data/lib/gruff/base.rb +325 -236
  13. data/lib/gruff/bezier.rb +18 -4
  14. data/lib/gruff/bullet.rb +22 -14
  15. data/lib/gruff/dot.rb +20 -33
  16. data/lib/gruff/helper/bar_conversion.rb +7 -7
  17. data/lib/gruff/helper/bar_value_label_mixin.rb +3 -0
  18. data/lib/gruff/helper/stacked_mixin.rb +1 -1
  19. data/lib/gruff/histogram.rb +59 -0
  20. data/lib/gruff/line.rb +33 -28
  21. data/lib/gruff/mini/bar.rb +10 -2
  22. data/lib/gruff/mini/legend.rb +9 -4
  23. data/lib/gruff/mini/pie.rb +9 -3
  24. data/lib/gruff/mini/side_bar.rb +18 -4
  25. data/lib/gruff/net.rb +41 -21
  26. data/lib/gruff/patch/rmagick.rb +22 -24
  27. data/lib/gruff/patch/string.rb +9 -4
  28. data/lib/gruff/photo_bar.rb +12 -16
  29. data/lib/gruff/pie.rb +24 -34
  30. data/lib/gruff/renderer/bezier.rb +4 -3
  31. data/lib/gruff/renderer/circle.rb +4 -3
  32. data/lib/gruff/renderer/dash_line.rb +4 -3
  33. data/lib/gruff/renderer/dot.rb +4 -3
  34. data/lib/gruff/renderer/ellipse.rb +4 -3
  35. data/lib/gruff/renderer/line.rb +14 -5
  36. data/lib/gruff/renderer/polygon.rb +5 -4
  37. data/lib/gruff/renderer/polyline.rb +4 -3
  38. data/lib/gruff/renderer/rectangle.rb +3 -2
  39. data/lib/gruff/renderer/renderer.rb +31 -38
  40. data/lib/gruff/renderer/text.rb +29 -7
  41. data/lib/gruff/scatter.rb +26 -24
  42. data/lib/gruff/scene.rb +0 -1
  43. data/lib/gruff/side_bar.rb +51 -20
  44. data/lib/gruff/side_stacked_bar.rb +42 -15
  45. data/lib/gruff/spider.rb +29 -17
  46. data/lib/gruff/stacked_area.rb +19 -8
  47. data/lib/gruff/stacked_bar.rb +34 -13
  48. data/lib/gruff/store/{base_data.rb → basic_data.rb} +9 -7
  49. data/lib/gruff/store/custom_data.rb +8 -6
  50. data/lib/gruff/store/store.rb +7 -6
  51. data/lib/gruff/store/xy_data.rb +10 -7
  52. data/lib/gruff/version.rb +1 -1
  53. metadata +50 -11
  54. data/Rakefile +0 -23
  55. data/docker/Dockerfile +0 -14
  56. data/docker/build.sh +0 -4
  57. data/docker/launch.sh +0 -4
@@ -1,10 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'gruff/base'
4
-
5
- # A special bar graph that shows a single dataset as a set of
6
- # stacked bars. The bottom bar shows the running total and
7
- # the top bar shows the new value being added to the array.
3
+ #
4
+ # Gruff::AccumulatorBar is a special bar graph that shows a
5
+ # single dataset as a set of stacked bars.
6
+ # The bottom bar shows the running total and the top bar shows
7
+ # the new value being added to the array.
8
+ #
9
+ # Here's how to set up a Gruff::AccumulatorBar.
10
+ #
11
+ # g = Gruff::AccumulatorBar.new
12
+ # g.title = 'Your Savings'
13
+ # g.data 'First', [1, 1, 1]
14
+ # g.write('accumulator_bar.png')
15
+ #
8
16
  class Gruff::AccumulatorBar < Gruff::StackedBar
9
17
  def draw
10
18
  raise(Gruff::IncorrectNumberOfDatasetsException) unless store.length == 1
data/lib/gruff/area.rb CHANGED
@@ -1,11 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'gruff/base'
4
-
3
+ #
4
+ # Gruff::Area provides an area graph which displays graphically
5
+ # quantitative data.
6
+ #
7
+ # Here's how to set up a Gruff::Area.
8
+ #
9
+ # g = Gruff::Area.new
10
+ # g.title = 'Area Graph'
11
+ # g.data :Jimmy, [25, 36, 86, 39, 25, 31, 79, 88]
12
+ # g.data :Charles, [80, 54, 67, 54, 68, 70, 90, 95]
13
+ # g.data :Julie, [22, 29, 35, 38, 36, 40, 46, 57]
14
+ # g.write('area.png')
15
+ #
5
16
  class Gruff::Area < Gruff::Base
17
+ # Specifies the filling opacity in area graph. Default is +0.85+.
18
+ attr_writer :fill_opacity
19
+
20
+ # Specifies the stroke width in line around area graph. Default is +2.0+.
21
+ attr_writer :stroke_width
22
+
6
23
  def initialize_ivars
7
24
  super
8
25
  @sorted_drawing = true
26
+ @fill_opacity = 0.85
27
+ @stroke_width = 2.0
9
28
  end
10
29
  private :initialize_ivars
11
30
 
@@ -36,9 +55,7 @@ class Gruff::Area < Gruff::Base
36
55
  poly_points << @graph_left
37
56
  poly_points << @graph_bottom - 1
38
57
 
39
- Gruff::Renderer::Polygon.new(color: data_row.color).render(poly_points)
58
+ Gruff::Renderer::Polygon.new(color: data_row.color, width: @stroke_width, opacity: @fill_opacity).render(poly_points)
40
59
  end
41
-
42
- Gruff::Renderer.finish
43
60
  end
44
61
  end
data/lib/gruff/bar.rb CHANGED
@@ -1,28 +1,47 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'gruff/base'
4
- require 'gruff/helper/bar_conversion'
5
-
3
+ #
4
+ # Gruff::Bar provide a bar graph that presents categorical data
5
+ # with rectangular bars.
6
+ #
7
+ # Here's how to set up a Gruff::Bar.
8
+ #
9
+ # g = Gruff::Bar.new
10
+ # g.title = 'Bar Graph With Manual Colors'
11
+ # g.spacing_factor = 0.1
12
+ # g.group_spacing = 20
13
+ # g.data :Art, [0, 5, 8, 15], '#990000'
14
+ # g.data :Philosophy, [10, 3, 2, 8], '#009900'
15
+ # g.data :Science, [2, 15, 8, 11], '#990099'
16
+ # g.write('bar.png')
17
+ #
6
18
  class Gruff::Bar < Gruff::Base
19
+ using String::GruffCommify
20
+
7
21
  # Spacing factor applied between bars.
8
- attr_accessor :bar_spacing
22
+ attr_writer :bar_spacing
9
23
 
10
24
  # Spacing factor applied between a group of bars belonging to the same label.
11
- attr_accessor :group_spacing
25
+ attr_writer :group_spacing
12
26
 
13
27
  # Set the number output format for labels using sprintf.
14
28
  # Default is +"%.2f"+.
15
- attr_accessor :label_formatting
29
+ attr_writer :label_formatting
16
30
 
17
31
  # Output the values for the bars on a bar graph.
18
32
  # Default is +false+.
19
- attr_accessor :show_labels_for_bar_values
33
+ attr_writer :show_labels_for_bar_values
34
+
35
+ # Prevent drawing of column labels below a bar graph. Default is +false+.
36
+ attr_writer :hide_labels
20
37
 
21
38
  def initialize_ivars
22
39
  super
23
40
  @spacing_factor = 0.9
41
+ @group_spacing = 10
24
42
  @label_formatting = nil
25
43
  @show_labels_for_bar_values = false
44
+ @hide_labels = false
26
45
  end
27
46
  private :initialize_ivars
28
47
 
@@ -52,12 +71,23 @@ class Gruff::Bar < Gruff::Base
52
71
 
53
72
  protected
54
73
 
74
+ def hide_labels?
75
+ @hide_labels
76
+ end
77
+
78
+ def hide_left_label_area?
79
+ @hide_line_markers
80
+ end
81
+
82
+ def hide_bottom_label_area?
83
+ hide_labels?
84
+ end
85
+
55
86
  def draw_bars
56
87
  # Setup spacing.
57
88
  #
58
89
  # Columns sit side-by-side.
59
90
  @bar_spacing ||= @spacing_factor # space between the bars
60
- @group_spacing ||= 10
61
91
 
62
92
  bar_width = (@graph_width - calculate_spacing) / (column_count * store.length).to_f
63
93
  padding = (bar_width * (1 - @bar_spacing)) / 2
@@ -114,8 +144,6 @@ protected
114
144
 
115
145
  # Draw the last label if requested
116
146
  draw_label(@graph_right, column_count, Magick::NorthWestGravity) if @center_labels_over_point
117
-
118
- Gruff::Renderer.finish
119
147
  end
120
148
 
121
149
  def calculate_spacing
data/lib/gruff/base.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rmagick'
4
3
  require 'bigdecimal'
5
4
 
6
5
  ##
@@ -17,33 +16,34 @@ require 'bigdecimal'
17
16
  #
18
17
  # See {Gruff::Base#theme=} for setting themes.
19
18
  module Gruff
19
+ using String::GruffCommify
20
+
21
+ # A common base class inherited from class of drawing a graph.
20
22
  class Base
21
23
  # Space around text elements. Mostly used for vertical spacing.
22
24
  LEGEND_MARGIN = TITLE_MARGIN = 20.0
23
- LABEL_MARGIN = 10.0
25
+ LABEL_MARGIN = 15.0
24
26
  DEFAULT_MARGIN = 20.0
25
27
 
26
28
  DEFAULT_TARGET_WIDTH = 800.0
27
29
 
28
- THOUSAND_SEPARATOR = ','
29
-
30
- # Blank space above the graph.
31
- attr_accessor :top_margin
30
+ # Blank space above the graph. Default is +20+.
31
+ attr_writer :top_margin
32
32
 
33
- # Blank space below the graph.
34
- attr_accessor :bottom_margin
33
+ # Blank space below the graph. Default is +20+.
34
+ attr_writer :bottom_margin
35
35
 
36
- # Blank space to the right of the graph.
37
- attr_accessor :right_margin
36
+ # Blank space to the right of the graph. Default is +20+.
37
+ attr_writer :right_margin
38
38
 
39
- # Blank space to the left of the graph.
40
- attr_accessor :left_margin
39
+ # Blank space to the left of the graph. Default is +20+.
40
+ attr_writer :left_margin
41
41
 
42
- # Blank space below the title.
43
- attr_accessor :title_margin
42
+ # Blank space below the title. Default is +20+.
43
+ attr_writer :title_margin
44
44
 
45
- # Blank space below the legend.
46
- attr_accessor :legend_margin
45
+ # Blank space below the legend. Default is +20+.
46
+ attr_writer :legend_margin
47
47
 
48
48
  # A hash of names for the individual columns, where the key is the array
49
49
  # index for the column this label represents.
@@ -52,129 +52,125 @@ module Gruff
52
52
  #
53
53
  # @example
54
54
  # { 0 => 2005, 3 => 2006, 5 => 2007, 7 => 2008 }
55
- attr_accessor :labels
55
+ attr_writer :labels
56
56
 
57
57
  # Used internally for spacing.
58
58
  #
59
59
  # By default, labels are centered over the point they represent.
60
- attr_accessor :center_labels_over_point
60
+ attr_writer :center_labels_over_point
61
61
 
62
- # Used internally for horizontal graph types.
63
- attr_accessor :has_left_labels
62
+ # Used internally for horizontal graph types. Default is +false+.
63
+ attr_writer :has_left_labels
64
64
 
65
- # A label for the bottom of the graph.
66
- attr_accessor :x_axis_label
65
+ # Set a label for the bottom of the graph.
66
+ attr_writer :x_axis_label
67
67
 
68
- # A label for the left side of the graph.
69
- attr_accessor :y_axis_label
68
+ # Set a label for the left side of the graph.
69
+ attr_writer :y_axis_label
70
70
 
71
- # Manually set increment of the vertical marking lines.
72
- attr_accessor :x_axis_increment
71
+ # Set increment of the vertical marking lines.
72
+ attr_writer :x_axis_increment
73
73
 
74
- # Manually set increment of the horizontal marking lines.
75
- attr_accessor :y_axis_increment
74
+ # Set increment of the horizontal marking lines.
75
+ attr_writer :y_axis_increment
76
76
 
77
77
  # Height of staggering between labels (Bar graph only).
78
- attr_accessor :label_stagger_height
78
+ attr_writer :label_stagger_height
79
79
 
80
80
  # Truncates labels if longer than max specified.
81
- attr_accessor :label_max_size
81
+ attr_writer :label_max_size
82
82
 
83
- # How truncated labels visually appear if they exceed {#label_max_size}.
83
+ # How truncated labels visually appear if they exceed {#label_max_size=}.
84
84
  #
85
85
  # - +:absolute+ - does not show trailing dots to indicate truncation. This is the default.
86
- # - +:trailing_dots+ - shows trailing dots to indicate truncation (note that {#label_max_size}
86
+ # - +:trailing_dots+ - shows trailing dots to indicate truncation (note that {#label_max_size=}
87
87
  # must be greater than 3).
88
- attr_accessor :label_truncation_style
88
+ attr_writer :label_truncation_style
89
89
 
90
90
  # Get or set the list of colors that will be used to draw the bars or lines.
91
91
  attr_accessor :colors
92
92
 
93
- # The large title of the graph displayed at the top.
94
- attr_accessor :title
95
-
96
- # Font used for titles, labels, etc. Works best if you provide the full
97
- # path to the TTF font file. RMagick must be built with the Freetype
98
- # libraries for this to work properly.
99
- attr_reader :font
93
+ # Set the large title of the graph displayed at the top.
94
+ attr_writer :title
100
95
 
101
- # Same as font but for the title.
102
- attr_accessor :title_font
96
+ # Same as {#font=} but for the title.
97
+ attr_writer :title_font
103
98
 
104
- # Specifies whether to draw the title bolded or not.
105
- attr_accessor :bold_title
99
+ # Specifies whether to draw the title bolded or not. Default is +true+.
100
+ attr_writer :bold_title
106
101
 
107
- attr_accessor :font_color
102
+ # Specifies the text color.
103
+ attr_writer :font_color
108
104
 
109
- # Prevent drawing of line markers.
110
- attr_accessor :hide_line_markers
105
+ # Prevent drawing of line markers. Default is +false+.
106
+ attr_writer :hide_line_markers
111
107
 
112
- # Prevent drawing of the legend.
113
- attr_accessor :hide_legend
108
+ # Prevent drawing of the legend. Default is +false+.
109
+ attr_writer :hide_legend
114
110
 
115
- # Prevent drawing of the title.
116
- attr_accessor :hide_title
111
+ # Prevent drawing of the title. Default is +false+.
112
+ attr_writer :hide_title
117
113
 
118
- # Prevent drawing of line numbers.
119
- attr_accessor :hide_line_numbers
114
+ # Prevent drawing of line numbers. Default is +false+.
115
+ attr_writer :hide_line_numbers
120
116
 
121
- # Message shown when there is no data. Fits up to 20 characters. Defaults
117
+ # Set a message shown when there is no data. Fits up to 20 characters. Defaults
122
118
  # to +"No Data."+.
123
- attr_accessor :no_data_message
119
+ attr_writer :no_data_message
124
120
 
125
- # The font size of the large title at the top of the graph.
126
- attr_accessor :title_font_size
121
+ # Set the font size of the large title at the top of the graph. Default is +36+.
122
+ attr_writer :title_font_size
127
123
 
128
124
  # Optionally set the size of the font. Based on an 800x600px graph.
129
125
  # Default is +20+.
130
126
  #
131
127
  # Will be scaled down if the graph is smaller than 800px wide.
132
- attr_accessor :legend_font_size
128
+ attr_writer :legend_font_size
133
129
 
134
- # Display the legend under the graph.
135
- attr_accessor :legend_at_bottom
130
+ # Display the legend under the graph. Default is +false+.
131
+ attr_writer :legend_at_bottom
136
132
 
137
- # The font size of the labels around the graph.
138
- attr_accessor :marker_font_size
133
+ # The font size of the labels around the graph. Default is +21+.
134
+ attr_writer :marker_font_size
139
135
 
140
- # The color of the auxiliary lines.
141
- attr_accessor :marker_color
142
- attr_accessor :marker_shadow_color
136
+ # Set the color of the auxiliary lines.
137
+ attr_writer :marker_color
143
138
 
144
- # The number of horizontal lines shown for reference.
145
- attr_accessor :marker_count
139
+ # Set the shadow color of the auxiliary lines.
140
+ attr_writer :marker_shadow_color
146
141
 
147
- # Set to true if you want the data sets sorted with largest avg values drawn
148
- # first.
149
- attr_accessor :sort
142
+ # Set the number of horizontal lines shown for reference.
143
+ attr_writer :marker_count
150
144
 
151
- # Set to true if you want the data sets drawn with largest avg values drawn
152
- # first. This does not affect the legend.
153
- attr_accessor :sorted_drawing
145
+ # Set to +true+ if you want the data sets sorted with largest avg values drawn
146
+ # first. Default is +false+.
147
+ attr_writer :sort
154
148
 
155
- # Experimental
156
- attr_accessor :additional_line_values
149
+ # Set to +true+ if you want the data sets drawn with largest avg values drawn
150
+ # first. This does not affect the legend. Default is +false+.
151
+ attr_writer :sorted_drawing
157
152
 
158
153
  # Optionally set the size of the colored box by each item in the legend.
159
154
  # Default is +20.0+.
160
155
  #
161
156
  # Will be scaled down if graph is smaller than 800px wide.
162
- attr_accessor :legend_box_size
157
+ attr_writer :legend_box_size
163
158
 
164
159
  # With Side Bars use the data label for the marker value to the left of the bar.
165
160
  # Default is +false+.
166
- attr_accessor :use_data_label
161
+ attr_writer :use_data_label
167
162
 
168
163
  # If one numerical argument is given, the graph is drawn at 4/3 ratio
169
- # according to the given width (800 results in 800x600, 400 gives 400x300,
164
+ # according to the given width (+800+ results in 800x600, +400+ gives 400x300,
170
165
  # etc.).
171
166
  #
172
- # Or, send a geometry string for other ratios ('800x400', '400x225').
167
+ # Or, send a geometry string for other ratios ( +'800x400'+, +'400x225'+).
168
+ #
169
+ # @param target_width [Numeric, String] The graph image width.
170
+ #
173
171
  def initialize(target_width = DEFAULT_TARGET_WIDTH)
174
172
  if target_width.is_a?(String)
175
- geometric_width, geometric_height = target_width.split('x')
176
- @columns = geometric_width.to_f
177
- @rows = geometric_height.to_f
173
+ @columns, @rows = target_width.split('x').map(&:to_f)
178
174
  else
179
175
  @columns = target_width.to_f
180
176
  @rows = target_width.to_f * 0.75
@@ -182,36 +178,44 @@ module Gruff
182
178
  @columns.freeze
183
179
  @rows.freeze
184
180
 
181
+ initialize_graph_scale
185
182
  initialize_ivars
183
+ initialize_store
186
184
 
187
185
  self.theme = Themes::KEYNOTE
188
186
  end
189
187
 
190
- # Set instance variables for this object.
188
+ def initialize_graph_scale
189
+ @raw_columns = DEFAULT_TARGET_WIDTH
190
+ @raw_rows = DEFAULT_TARGET_WIDTH * (@rows / @columns)
191
+ @raw_columns.freeze
192
+ @raw_rows.freeze
193
+
194
+ @scale = @columns / @raw_columns
195
+ @scale.freeze
196
+ end
197
+ protected :initialize_graph_scale
198
+
199
+ def initialize_store
200
+ @store = Gruff::Store.new(Gruff::Store::BasicData)
201
+ end
202
+ protected :initialize_store
203
+
204
+ # Initialize instance variable of attributes
191
205
  #
192
206
  # Subclasses can override this, call super, then set values separately.
193
207
  #
194
208
  # This makes it possible to set defaults in a subclass but still allow
195
209
  # developers to change this values in their program.
196
210
  def initialize_ivars
197
- # Internal for calculations
198
- @raw_columns = DEFAULT_TARGET_WIDTH
199
- @raw_rows = DEFAULT_TARGET_WIDTH * (@rows / @columns)
200
- @raw_columns.freeze
201
- @raw_rows.freeze
202
-
203
211
  @marker_count = nil
204
212
  @maximum_value = @minimum_value = nil
205
- @increment = nil
206
213
  @labels = {}
207
- @labels_seen = {}
208
214
  @sort = false
209
215
  @sorted_drawing = false
210
216
  @title = nil
211
217
  @title_font = nil
212
218
 
213
- @scale = @columns / @raw_columns
214
-
215
219
  @font = nil
216
220
  @bold_title = true
217
221
 
@@ -234,25 +238,25 @@ module Gruff
234
238
  @label_max_size = 0
235
239
  @label_truncation_style = :absolute
236
240
 
237
- @additional_line_values = []
238
- @additional_line_colors = []
239
- @theme_options = {}
240
-
241
241
  @use_data_label = false
242
242
  @x_axis_increment = nil
243
243
  @x_axis_label = @y_axis_label = nil
244
244
  @y_axis_increment = nil
245
-
246
- @store = Gruff::Store.new(Gruff::Store::BaseData)
247
245
  end
248
246
  protected :initialize_ivars
249
247
 
250
248
  # Sets the top, bottom, left and right margins to +margin+.
249
+ #
250
+ # @param margin [Numeric] The margin size.
251
+ #
251
252
  def margins=(margin)
252
253
  @top_margin = @left_margin = @right_margin = @bottom_margin = margin
253
254
  end
254
255
 
255
256
  # Sets the font for graph text to the font at +font_path+.
257
+ #
258
+ # @param font_path [String] The path to font.
259
+ #
256
260
  def font=(font_path)
257
261
  @font = font_path
258
262
  Gruff::Renderer.font = @font
@@ -260,6 +264,8 @@ module Gruff
260
264
 
261
265
  # Add a color to the list of available colors for lines.
262
266
  #
267
+ # @param colorname [String] The color.
268
+ #
263
269
  # @example
264
270
  # add_color('#c0e9d3')
265
271
  def add_color(colorname)
@@ -277,6 +283,8 @@ module Gruff
277
283
  # {#data} method made prior to this call will use whatever color scheme
278
284
  # was in place at the time data was called.
279
285
  #
286
+ # @param color_list [Array] The array of colors.
287
+ #
280
288
  # @example
281
289
  # replace_colors ['#cc99cc', '#d9e043', '#34d8a2']
282
290
  def replace_colors(color_list = [])
@@ -289,19 +297,29 @@ module Gruff
289
297
  # graph.theme = {
290
298
  # colors: %w(orange purple green white red),
291
299
  # marker_color: 'blue',
292
- # background_colors: ['black', 'grey', :top_bottom]
300
+ # background_colors: ['black', 'grey'],
301
+ # background_direction: :top_bottom
293
302
  # }
294
303
  #
295
304
  # +background_image: 'squirrel.png'+ is also possible.
296
305
  #
306
+ # +background_direction+ accepts one of following parameters.
307
+ # - +:top_bottom+
308
+ # - +:bottom_top+
309
+ # - +:left_right+
310
+ # - +:right_left+
311
+ # - +:topleft_bottomright+
312
+ # - +:topright_bottomleft+
313
+ #
297
314
  # (Or hopefully something better looking than that.)
298
315
  #
316
+ # @param options [Hash] The optional setting for theme
317
+ #
299
318
  def theme=(options)
300
319
  reset_themes
301
320
 
302
321
  defaults = {
303
322
  colors: %w[black white],
304
- additional_line_colors: [],
305
323
  marker_color: 'white',
306
324
  marker_shadow_color: nil,
307
325
  font_color: 'black',
@@ -314,35 +332,42 @@ module Gruff
314
332
  @marker_color = @theme_options[:marker_color]
315
333
  @marker_shadow_color = @theme_options[:marker_shadow_color]
316
334
  @font_color = @theme_options[:font_color] || @marker_color
317
- @additional_line_colors = @theme_options[:additional_line_colors]
318
335
 
319
336
  Gruff::Renderer.setup(@columns, @rows, @font, @scale, @theme_options)
320
337
  end
321
338
 
339
+ # Apply Apple's keynote theme.
322
340
  def theme_keynote
323
341
  self.theme = Themes::KEYNOTE
324
342
  end
325
343
 
344
+ # Apply 37signals theme.
326
345
  def theme_37signals
327
346
  self.theme = Themes::THIRTYSEVEN_SIGNALS
328
347
  end
329
348
 
349
+ # Apply Rails theme.
330
350
  def theme_rails_keynote
331
351
  self.theme = Themes::RAILS_KEYNOTE
332
352
  end
333
353
 
354
+ # Apply Odeo theme.
334
355
  def theme_odeo
335
356
  self.theme = Themes::ODEO
336
357
  end
337
358
 
359
+ # Apply pastel theme.
338
360
  def theme_pastel
339
361
  self.theme = Themes::PASTEL
340
362
  end
341
363
 
364
+ # Apply greyscale theme.
342
365
  def theme_greyscale
343
366
  self.theme = Themes::GREYSCALE
344
367
  end
345
368
 
369
+ # Input the data in the graph.
370
+ #
346
371
  # Parameters are an array where the first element is the name of the dataset
347
372
  # and the value is an array of values to plot.
348
373
  #
@@ -352,6 +377,10 @@ module Gruff
352
377
  # If the color argument is nil, the next color from the default theme will
353
378
  # be used.
354
379
  #
380
+ # @param name [String, Symbol] The name of the dataset.
381
+ # @param data_points [Array] The array of dataset.
382
+ # @param color [String] The color for drawing graph of dataset.
383
+ #
355
384
  # @note
356
385
  # If you want to use a preset theme, you must set it before calling {#data}.
357
386
  #
@@ -382,17 +411,45 @@ module Gruff
382
411
 
383
412
  # Writes the graph to a file. Defaults to +'graph.png'+
384
413
  #
414
+ # @param file_name [String] The file name of output image.
415
+ #
385
416
  # @example
386
417
  # write('graphs/my_pretty_graph.png')
387
418
  def write(file_name = 'graph.png')
388
- draw
389
- Gruff::Renderer.write(file_name)
419
+ to_image.write(file_name)
420
+ end
421
+
422
+ # Return a rendered graph image.
423
+ # This can use RMagick's methods to adjust the image before saving.
424
+ #
425
+ # @return [Magick::Image] The rendered image.
426
+ #
427
+ # @example
428
+ # g = Gruff::Line.new
429
+ # g.data :Jimmy, [25, 36, 86, 39, 25, 31, 79, 88]
430
+ # g.data :Charles, [80, 54, 67, 54, 68, 70, 90, 95]
431
+ # image = g.to_image
432
+ # image = image.resize(400, 300).quantize(128, Magick::RGBColorspace)
433
+ # image.write('test.png')
434
+ #
435
+ def to_image
436
+ @to_image ||= begin
437
+ draw
438
+ Gruff::Renderer.finish
439
+ Gruff::Renderer.instance.image
440
+ end
390
441
  end
391
442
 
392
443
  # Return the graph as a rendered binary blob.
393
- def to_blob(file_format = 'PNG')
394
- draw
395
- Gruff::Renderer.to_blob(file_format)
444
+ #
445
+ # @param image_format [String] The image format of binary blob.
446
+ #
447
+ # @deprecated Please use +to_image.to_blob+ instead.
448
+ def to_blob(image_format = 'PNG')
449
+ warn '#to_blob is deprecated. Please use `to_image.to_blob` instead'
450
+ to_image.to_blob do
451
+ self.format = image_format
452
+ end
396
453
  end
397
454
 
398
455
  protected
@@ -455,6 +512,18 @@ module Gruff
455
512
  store.columns
456
513
  end
457
514
 
515
+ def marker_count
516
+ @marker_count ||= begin
517
+ count = nil
518
+ (3..7).each do |lines|
519
+ if @spread.to_f % lines == 0.0
520
+ count = lines and break
521
+ end
522
+ end
523
+ count || 4
524
+ end
525
+ end
526
+
458
527
  # Make copy of data with values scaled between 0-100
459
528
  def normalize
460
529
  store.normalize(minimum: minimum_value, spread: @spread)
@@ -465,61 +534,37 @@ module Gruff
465
534
  @spread = @spread > 0 ? @spread : 1
466
535
  end
467
536
 
468
- ##
469
- # Calculates size of drawable area, general font dimensions, etc.
470
-
471
- def setup_graph_measurements
472
- @marker_caps_height = @hide_line_markers ? 0 : calculate_caps_height(@marker_font_size)
473
- @title_caps_height = (@hide_title || @title.nil?) ? 0 : calculate_caps_height(@title_font_size) * @title.lines.to_a.size
474
- @legend_caps_height = @hide_legend ? 0 : calculate_caps_height(@legend_font_size)
475
-
476
- if @hide_line_markers
477
- @graph_left = @left_margin
478
- @graph_right_margin = @right_margin
479
- @graph_bottom_margin = @bottom_margin
480
- else
481
- if @has_left_labels
482
- longest_left_label_width = calculate_width(@marker_font_size,
483
- labels.values.reduce('') { |value, memo| (value.to_s.length > memo.to_s.length) ? value : memo }) * 1.25
484
- else
485
- longest_left_label_width = calculate_width(@marker_font_size,
486
- label(maximum_value.to_f, @increment))
487
- end
537
+ def hide_title?
538
+ @hide_title || @title.nil? || @title.empty?
539
+ end
488
540
 
489
- # Shift graph if left line numbers are hidden
490
- line_number_width = @hide_line_numbers && !@has_left_labels ? 0.0 : (longest_left_label_width + LABEL_MARGIN * 2)
541
+ def hide_labels?
542
+ @hide_line_markers
543
+ end
491
544
 
492
- @graph_left = @left_margin + line_number_width + (@y_axis_label.nil? ? 0.0 : @marker_caps_height + LABEL_MARGIN * 2)
545
+ def hide_left_label_area?
546
+ @hide_line_markers
547
+ end
493
548
 
494
- # Make space for half the width of the rightmost column label.
495
- # Might be greater than the number of columns if between-style bar markers are used.
496
- last_label = @labels.keys.max.to_i
497
- extra_room_for_long_label = begin
498
- (last_label >= (column_count - 1) && @center_labels_over_point) ? calculate_width(@marker_font_size, @labels[last_label]) / 2.0 : 0
499
- end
500
- @graph_right_margin = @right_margin + extra_room_for_long_label
549
+ def hide_bottom_label_area?
550
+ @hide_line_markers
551
+ end
501
552
 
502
- @graph_bottom_margin = @bottom_margin + @marker_caps_height + LABEL_MARGIN
503
- end
553
+ ##
554
+ # Calculates size of drawable area, general font dimensions, etc.
504
555
 
505
- @graph_right = @raw_columns - @graph_right_margin
506
- @graph_width = @raw_columns - @graph_left - @graph_right_margin
556
+ def setup_graph_measurements
557
+ @marker_caps_height = setup_marker_caps_height
558
+ @title_caps_height = setup_title_caps_height
559
+ @legend_caps_height = setup_legend_caps_height
507
560
 
508
- # When @hide title, leave a title_margin space for aesthetics.
509
- # Same with @hide_legend
510
- @graph_top = begin
511
- if @legend_at_bottom
512
- @top_margin
513
- else
514
- @top_margin +
515
- (@hide_title ? title_margin : @title_caps_height + title_margin) +
516
- (@hide_legend ? legend_margin : @legend_caps_height + legend_margin)
517
- end
518
- end
561
+ margin_on_right = graph_right_margin
562
+ @graph_right = @raw_columns - margin_on_right
563
+ @graph_left = setup_left_margin
564
+ @graph_top = setup_top_margin
565
+ @graph_bottom = setup_bottom_margin
519
566
 
520
- x_axis_label_height = @x_axis_label.nil? ? 0.0 : @marker_caps_height + LABEL_MARGIN
521
- # FIXME: Consider chart types other than bar
522
- @graph_bottom = @raw_rows - @graph_bottom_margin - x_axis_label_height - @label_stagger_height
567
+ @graph_width = @raw_columns - @graph_left - margin_on_right
523
568
  @graph_height = @graph_bottom - @graph_top
524
569
  end
525
570
 
@@ -529,17 +574,17 @@ module Gruff
529
574
  # X Axis
530
575
  # Centered vertically and horizontally by setting the
531
576
  # height to 1.0 and the width to the width of the graph.
532
- x_axis_label_y_coordinate = @graph_bottom + LABEL_MARGIN * 2 + @marker_caps_height
577
+ x_axis_label_y_coordinate = @graph_bottom + LABEL_MARGIN + @marker_caps_height
533
578
 
534
579
  # TODO: Center between graph area
535
580
  text_renderer = Gruff::Renderer::Text.new(@x_axis_label, font: @font, size: @marker_font_size, color: @font_color)
536
- text_renderer.render(@raw_columns, 1.0, 0.0, x_axis_label_y_coordinate)
581
+ text_renderer.add_to_render_queue(@raw_columns, 1.0, 0.0, x_axis_label_y_coordinate)
537
582
  end
538
583
 
539
584
  if @y_axis_label
540
585
  # Y Axis, rotated vertically
541
586
  text_renderer = Gruff::Renderer::Text.new(@y_axis_label, font: @font, size: @marker_font_size, color: @font_color, rotation: -90)
542
- text_renderer.render(1.0, @raw_rows, @left_margin + @marker_caps_height / 2.0, 0.0, Magick::CenterGravity)
587
+ text_renderer.add_to_render_queue(1.0, @raw_rows, @left_margin + @marker_caps_height / 2.0, 0.0, Magick::CenterGravity)
543
588
  end
544
589
  end
545
590
 
@@ -550,32 +595,21 @@ module Gruff
550
595
  increment_scaled = @graph_height.to_f / (@spread / @increment)
551
596
 
552
597
  # Draw horizontal line markers and annotate with numbers
553
- (0..@marker_count).each do |index|
598
+ (0..marker_count).each do |index|
554
599
  y = @graph_top + @graph_height - index.to_f * increment_scaled
555
600
 
556
- Gruff::Renderer::Line.new(color: @marker_color).render(@graph_left, y, @graph_right, y)
557
- #If the user specified a marker shadow color, draw a shadow just below it
558
- if @marker_shadow_color
559
- Gruff::Renderer::Line.new(color: @marker_shadow_color).render(@graph_left, y + 1, @graph_right, y + 1)
560
- end
561
-
562
- marker_label = BigDecimal(index.to_s) * BigDecimal(@increment.to_s) + BigDecimal(minimum_value.to_s)
601
+ line_renderer = Gruff::Renderer::Line.new(color: @marker_color, shadow_color: @marker_shadow_color)
602
+ line_renderer.render(@graph_left, y, @graph_right, y)
563
603
 
564
604
  unless @hide_line_numbers
605
+ marker_label = BigDecimal(index.to_s) * BigDecimal(@increment.to_s) + BigDecimal(minimum_value.to_s)
565
606
  label = label(marker_label, @increment)
566
607
  text_renderer = Gruff::Renderer::Text.new(label, font: @font, size: @marker_font_size, color: @font_color)
567
- text_renderer.render(@graph_left - LABEL_MARGIN, 1.0, 0.0, y, Magick::EastGravity)
608
+ text_renderer.add_to_render_queue(@graph_left - LABEL_MARGIN, 1.0, 0.0, y, Magick::EastGravity)
568
609
  end
569
610
  end
570
611
  end
571
612
 
572
- # Return the sum of values in an array.
573
- #
574
- # Duplicated to not conflict with active_support in Rails.
575
- def sum(arr)
576
- arr.reduce(0) { |i, m| m + i }
577
- end
578
-
579
613
  # Return a calculation of center
580
614
  def center(size)
581
615
  (@raw_columns - size) / 2
@@ -587,34 +621,24 @@ module Gruff
587
621
  return if @hide_legend
588
622
 
589
623
  legend_labels = store.data.map(&:label)
590
-
591
624
  legend_square_width = @legend_box_size # small square with color of this item
625
+ label_widths = calculate_legend_label_widths_for_each_line(legend_labels, legend_square_width)
592
626
 
593
- # May fix legend drawing problem at small sizes
594
- label_widths = [[]] # Used to calculate line wrap
595
- legend_labels.each do |label|
596
- metrics = Renderer::Text.metrics(label, @legend_font_size)
597
- label_width = metrics.width + legend_square_width * 2.7
598
- label_widths.last.push label_width
599
-
600
- if sum(label_widths.last) > (@raw_columns * 0.9)
601
- label_widths.push [label_widths.last.pop]
602
- end
603
- end
604
-
605
- current_x_offset = center(sum(label_widths.first))
627
+ current_x_offset = center(label_widths.first.sum)
606
628
  current_y_offset = begin
607
629
  if @legend_at_bottom
608
- @graph_height + title_margin
630
+ @graph_height + @title_margin
609
631
  else
610
- @hide_title ? @top_margin + title_margin : @top_margin + title_margin + @title_caps_height
632
+ hide_title? ? @top_margin + @title_margin : @top_margin + @title_margin + @title_caps_height
611
633
  end
612
634
  end
613
635
 
614
636
  legend_labels.each_with_index do |legend_label, index|
637
+ next if legend_label.empty?
638
+
615
639
  # Draw label
616
640
  text_renderer = Gruff::Renderer::Text.new(legend_label, font: @font, size: @legend_font_size, color: @font_color)
617
- text_renderer.render(@raw_columns, 1.0, current_x_offset + (legend_square_width * 1.7), current_y_offset, Magick::WestGravity)
641
+ text_renderer.add_to_render_queue(@raw_columns, 1.0, current_x_offset + (legend_square_width * 1.7), current_y_offset, Magick::WestGravity)
618
642
 
619
643
  # Now draw box with color of this dataset
620
644
  rect_renderer = Gruff::Renderer::Rectangle.new(color: store.data[index].color)
@@ -623,32 +647,30 @@ module Gruff
623
647
  current_x_offset + legend_square_width,
624
648
  current_y_offset + legend_square_width / 2.0)
625
649
 
626
- metrics = Renderer::Text.metrics(legend_label, legend_font_size)
627
- current_string_offset = metrics.width + (legend_square_width * 2.7)
650
+ width = calculate_width(@legend_font_size, legend_label)
651
+ current_x_offset += width + (legend_square_width * 2.7)
652
+ label_widths.first.shift
628
653
 
629
654
  # Handle wrapping
630
- label_widths.first.shift
631
655
  if label_widths.first.empty?
632
656
  label_widths.shift
633
- current_x_offset = center(sum(label_widths.first)) unless label_widths.empty?
634
- line_height = [@legend_caps_height, legend_square_width].max + legend_margin
657
+ current_x_offset = center(label_widths.first.sum) unless label_widths.empty?
658
+ line_height = [@legend_caps_height, legend_square_width].max + @legend_margin
635
659
  unless label_widths.empty?
636
660
  # Wrap to next line and shrink available graph dimensions
637
661
  current_y_offset += line_height
638
662
  @graph_top += line_height
639
663
  @graph_height = @graph_bottom - @graph_top
640
664
  end
641
- else
642
- current_x_offset += current_string_offset
643
665
  end
644
666
  end
645
667
  end
646
668
 
647
669
  # Draws a title on the graph.
648
670
  def draw_title
649
- return if @hide_title || @title.nil?
671
+ return if hide_title?
650
672
 
651
- font = (@title_font || @font) if @title_font || @font
673
+ font = @title_font || @font
652
674
  font_weight = @bold_title ? Magick::BoldWeight : Magick::NormalWeight
653
675
  font_size = @title_font_size
654
676
 
@@ -657,7 +679,7 @@ module Gruff
657
679
  font_size = font_size * (@raw_columns / metrics.width) * 0.95
658
680
  end
659
681
  text_renderer = Gruff::Renderer::Text.new(@title, font: font, size: font_size, color: @font_color, weight: font_weight)
660
- text_renderer.render(@raw_columns, 1.0, 0, @top_margin)
682
+ text_renderer.add_to_render_queue(@raw_columns, 1.0, 0, @top_margin)
661
683
  end
662
684
 
663
685
  # Draws column labels below graph, centered over x_offset
@@ -672,31 +694,19 @@ module Gruff
672
694
  # TODO: See if index.odd? is the best stragegy
673
695
  y_offset += @label_stagger_height if index.odd?
674
696
 
675
- label_text = labels[index].to_s
676
-
677
- # TESTME
678
- # FIXME: Consider chart types other than bar
679
- if label_text.size > @label_max_size
680
- if @label_truncation_style == :trailing_dots
681
- if @label_max_size > 3
682
- # 4 because '...' takes up 3 chars
683
- label_text = "#{label_text[0..(@label_max_size - 4)]}..."
684
- end
685
- else # @label_truncation_style is :absolute (default)
686
- label_text = label_text[0..(@label_max_size - 1)]
687
- end
688
- end
697
+ label_text = truncate_label_text(@labels[index].to_s)
689
698
 
690
699
  if x_offset >= @graph_left && x_offset <= @graph_right
691
700
  text_renderer = Gruff::Renderer::Text.new(label_text, font: @font, size: @marker_font_size, color: @font_color)
692
- text_renderer.render(1.0, 1.0, x_offset, y_offset, gravity)
701
+ text_renderer.add_to_render_queue(1.0, 1.0, x_offset, y_offset, gravity)
693
702
  end
694
703
  end
695
704
  end
696
705
 
697
706
  def draw_unique_label(index)
698
- return if @hide_line_markers
707
+ return if hide_labels?
699
708
 
709
+ @labels_seen ||= {}
700
710
  if !@labels[index].nil? && @labels_seen[index].nil?
701
711
  yield
702
712
  @labels_seen[index] = 1
@@ -708,18 +718,17 @@ module Gruff
708
718
  return if @hide_line_markers && !bar_value
709
719
 
710
720
  text_renderer = Gruff::Renderer::Text.new(data_point, font: @font, size: @marker_font_size, color: @font_color)
711
- text_renderer.render(1.0, 1.0, x_offset, y_offset)
721
+ text_renderer.add_to_render_queue(1.0, 1.0, x_offset, y_offset)
712
722
  end
713
723
 
714
724
  # Shows an error message because you have no data.
715
725
  def draw_no_data
716
726
  text_renderer = Gruff::Renderer::Text.new(@no_data_message, font: @font, size: 80, color: @font_color)
717
- text_renderer.render(@raw_columns, @raw_rows / 2.0, 0, 10, Magick::CenterGravity)
727
+ text_renderer.render(@raw_columns, @raw_rows, 0, 0, Magick::CenterGravity)
718
728
  end
719
729
 
720
730
  # Resets everything to defaults (except data).
721
731
  def reset_themes
722
- @labels_seen = {}
723
732
  @theme_options = {}
724
733
  end
725
734
 
@@ -768,7 +777,7 @@ module Gruff
768
777
 
769
778
  # Set the color for each data set unless it was given in the data(...) call.
770
779
  def set_colors
771
- store.set_colors!(@colors)
780
+ store.change_colors(@colors)
772
781
  end
773
782
 
774
783
  # Sort with largest overall summed value at front of array so it shows up
@@ -779,6 +788,78 @@ module Gruff
779
788
 
780
789
  private
781
790
 
791
+ def setup_marker_caps_height
792
+ hide_bottom_label_area? ? 0 : calculate_caps_height(@marker_font_size)
793
+ end
794
+
795
+ def setup_title_caps_height
796
+ hide_title? ? 0 : calculate_caps_height(@title_font_size) * @title.lines.to_a.size
797
+ end
798
+
799
+ def setup_legend_caps_height
800
+ @hide_legend ? 0 : calculate_caps_height(@legend_font_size)
801
+ end
802
+
803
+ def graph_right_margin
804
+ @hide_line_markers ? @right_margin : @right_margin + extra_room_for_long_label
805
+ end
806
+
807
+ def extra_room_for_long_label
808
+ # Make space for half the width of the rightmost column label.
809
+ # Might be greater than the number of columns if between-style bar markers are used.
810
+ last_label = @labels.keys.max.to_i
811
+ (last_label >= (column_count - 1) && @center_labels_over_point) ? calculate_width(@marker_font_size, @labels[last_label]) / 2.0 : 0
812
+ end
813
+
814
+ def setup_left_margin
815
+ return @left_margin if hide_left_label_area?
816
+
817
+ text = begin
818
+ if @has_left_labels
819
+ @labels.values.reduce('') { |value, memo| (value.to_s.length > memo.to_s.length) ? value : memo }
820
+ else
821
+ label(maximum_value.to_f, @increment)
822
+ end
823
+ end
824
+ longest_left_label_width = calculate_width(@marker_font_size, text)
825
+ longest_left_label_width *= 1.25 if @has_left_labels
826
+
827
+ # Shift graph if left line numbers are hidden
828
+ line_number_width = @hide_line_numbers && !@has_left_labels ? 0.0 : (longest_left_label_width + LABEL_MARGIN * 2)
829
+
830
+ @left_margin + line_number_width + (@y_axis_label.nil? ? 0.0 : @marker_caps_height + LABEL_MARGIN * 2)
831
+ end
832
+
833
+ def setup_top_margin
834
+ return @top_margin if @legend_at_bottom
835
+
836
+ # When @hide title, leave a title_margin space for aesthetics.
837
+ # Same with @hide_legend
838
+ @top_margin +
839
+ (hide_title? ? @title_margin : @title_caps_height + @title_margin) +
840
+ (@hide_legend ? @legend_margin : @legend_caps_height + @legend_margin)
841
+ end
842
+
843
+ def setup_bottom_margin
844
+ graph_bottom_margin = hide_bottom_label_area? ? @bottom_margin : @bottom_margin + @marker_caps_height + LABEL_MARGIN
845
+
846
+ x_axis_label_height = @x_axis_label.nil? ? 0.0 : @marker_caps_height + LABEL_MARGIN
847
+ # FIXME: Consider chart types other than bar
848
+ @raw_rows - graph_bottom_margin - x_axis_label_height - @label_stagger_height
849
+ end
850
+
851
+ def truncate_label_text(text)
852
+ return text if text.size <= @label_max_size
853
+
854
+ if @label_truncation_style == :trailing_dots
855
+ # 4 because '...' takes up 3 chars
856
+ text = "#{text[0..(@label_max_size - 4)]}..." if @label_max_size > 3
857
+ else
858
+ text = text[0..(@label_max_size - 1)]
859
+ end
860
+ text
861
+ end
862
+
782
863
  # Return a formatted string representing a number value that should be
783
864
  # printed as a label.
784
865
  def label(value, increment)
@@ -796,7 +877,7 @@ module Gruff
796
877
  else
797
878
  value.to_s
798
879
  end
799
- elsif (@spread.to_f % (@marker_count.to_f == 0 ? 1 : @marker_count.to_f) == 0) || !@y_axis_increment.nil?
880
+ elsif (@spread.to_f % (marker_count.to_f == 0 ? 1 : marker_count.to_f) == 0) || !@y_axis_increment.nil?
800
881
  value.to_i.to_s
801
882
  elsif @spread > 10.0
802
883
  sprintf('%0i', value)
@@ -807,10 +888,26 @@ module Gruff
807
888
  end
808
889
 
809
890
  parts = label.split('.')
810
- parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{THOUSAND_SEPARATOR}")
891
+ parts[0] = parts[0].commify
811
892
  parts.join('.')
812
893
  end
813
894
 
895
+ def calculate_legend_label_widths_for_each_line(legend_labels, legend_square_width)
896
+ # May fix legend drawing problem at small sizes
897
+ label_widths = [[]] # Used to calculate line wrap
898
+ legend_labels.each do |label|
899
+ width = calculate_width(@legend_font_size, label)
900
+ label_width = width + legend_square_width * 2.7
901
+ label_widths.last.push label_width
902
+
903
+ if label_widths.last.sum > (@raw_columns * 0.9)
904
+ label_widths.push [label_widths.last.pop]
905
+ end
906
+ end
907
+
908
+ label_widths
909
+ end
910
+
814
911
  # Returns the height of the capital letter 'X' for the current font and
815
912
  # size.
816
913
  #
@@ -821,12 +918,13 @@ module Gruff
821
918
  metrics.height
822
919
  end
823
920
 
824
- # Returns the width of a string at this pointsize.
921
+ # Returns the width of a string at this point size.
825
922
  #
826
923
  # Not scaled since it deals with dimensions that the regular
827
924
  # scaling will handle.
828
925
  def calculate_width(font_size, text)
829
- return 0 if text.nil?
926
+ text = text.to_s
927
+ return 0 if text.empty?
830
928
 
831
929
  metrics = Renderer::Text.metrics(text, font_size)
832
930
  metrics.width
@@ -837,19 +935,10 @@ module Gruff
837
935
  # Try to use a number of horizontal lines that will come out even.
838
936
  #
839
937
  # TODO Do the same for larger numbers...100, 75, 50, 25
840
- if @marker_count.nil?
841
- (3..7).each do |lines|
842
- if @spread % lines == 0.0
843
- @marker_count = lines
844
- break
845
- end
846
- end
847
- @marker_count ||= 4
848
- end
849
- @increment = (@spread > 0 && @marker_count > 0) ? significant(@spread / @marker_count) : 1
938
+ @increment = (@spread > 0 && marker_count > 0) ? significant(@spread / marker_count) : 1
850
939
  else
851
940
  # TODO: Make this work for negative values
852
- @marker_count = (@spread / @y_axis_increment).to_i
941
+ self.marker_count = (@spread / @y_axis_increment).to_i
853
942
  @increment = @y_axis_increment
854
943
  end
855
944
  end