gruff 0.12.2 → 0.15.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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +66 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +34 -27
  5. data/CHANGELOG.md +29 -0
  6. data/README.md +15 -7
  7. data/assets/fonts/LICENSE.txt +202 -0
  8. data/assets/fonts/Roboto-Bold.ttf +0 -0
  9. data/assets/fonts/Roboto-Regular.ttf +0 -0
  10. data/gruff.gemspec +9 -10
  11. data/lib/gruff/accumulator_bar.rb +3 -1
  12. data/lib/gruff/area.rb +5 -8
  13. data/lib/gruff/bar.rb +32 -49
  14. data/lib/gruff/base.rb +199 -115
  15. data/lib/gruff/bezier.rb +4 -6
  16. data/lib/gruff/bullet.rb +12 -11
  17. data/lib/gruff/dot.rb +13 -14
  18. data/lib/gruff/font.rb +39 -0
  19. data/lib/gruff/helper/bar_conversion.rb +27 -12
  20. data/lib/gruff/helper/bar_value_label.rb +71 -0
  21. data/lib/gruff/helper/stacked_mixin.rb +1 -2
  22. data/lib/gruff/histogram.rb +9 -7
  23. data/lib/gruff/line.rb +57 -50
  24. data/lib/gruff/mini/bar.rb +9 -6
  25. data/lib/gruff/mini/legend.rb +12 -8
  26. data/lib/gruff/mini/pie.rb +9 -6
  27. data/lib/gruff/mini/side_bar.rb +9 -6
  28. data/lib/gruff/net.rb +9 -15
  29. data/lib/gruff/patch/rmagick.rb +0 -1
  30. data/lib/gruff/patch/string.rb +1 -1
  31. data/lib/gruff/pie.rb +23 -65
  32. data/lib/gruff/renderer/bezier.rb +8 -9
  33. data/lib/gruff/renderer/circle.rb +8 -9
  34. data/lib/gruff/renderer/dash_line.rb +9 -10
  35. data/lib/gruff/renderer/dot.rb +13 -14
  36. data/lib/gruff/renderer/ellipse.rb +8 -9
  37. data/lib/gruff/renderer/line.rb +8 -9
  38. data/lib/gruff/renderer/polygon.rb +9 -10
  39. data/lib/gruff/renderer/polyline.rb +8 -9
  40. data/lib/gruff/renderer/rectangle.rb +7 -8
  41. data/lib/gruff/renderer/renderer.rb +25 -40
  42. data/lib/gruff/renderer/text.rb +21 -29
  43. data/lib/gruff/scatter.rb +55 -75
  44. data/lib/gruff/scene.rb +28 -18
  45. data/lib/gruff/side_bar.rb +35 -54
  46. data/lib/gruff/side_stacked_bar.rb +14 -17
  47. data/lib/gruff/spider.rb +11 -20
  48. data/lib/gruff/stacked_area.rb +10 -11
  49. data/lib/gruff/stacked_bar.rb +14 -15
  50. data/lib/gruff/store/store.rb +6 -10
  51. data/lib/gruff/store/xy_data.rb +2 -0
  52. data/lib/gruff/themes.rb +6 -6
  53. data/lib/gruff/version.rb +1 -1
  54. data/lib/gruff.rb +68 -55
  55. data/rails_generators/gruff/templates/controller.rb +1 -1
  56. metadata +34 -20
  57. data/.rubocop_todo.yml +0 -190
  58. data/.travis.yml +0 -23
  59. data/assets/plastik/blue.png +0 -0
  60. data/assets/plastik/green.png +0 -0
  61. data/assets/plastik/red.png +0 -0
  62. data/lib/gruff/helper/bar_value_label_mixin.rb +0 -33
  63. data/lib/gruff/photo_bar.rb +0 -93
data/lib/gruff/bullet.rb CHANGED
@@ -27,12 +27,13 @@ class Gruff::Bullet < Gruff::Base
27
27
  self.theme = Gruff::Themes::GREYSCALE
28
28
  end
29
29
 
30
- def initialize_ivars
30
+ def initialize_attributes
31
31
  super
32
32
 
33
- @title_font_size = 20
33
+ @title_font.size = 20
34
+ @title_font.bold = false
34
35
  end
35
- private :initialize_ivars
36
+ private :initialize_attributes
36
37
 
37
38
  def data(value, maximum_value, options = {})
38
39
  @value = value.to_f
@@ -51,7 +52,7 @@ class Gruff::Bullet < Gruff::Base
51
52
 
52
53
  draw_title
53
54
 
54
- title_width = calculate_width(@title_font_size, @title)
55
+ title_width = calculate_width(@title_font, @title)
55
56
  margin = 30.0
56
57
  thickness = @raw_rows / 6.0
57
58
  right_margin = margin
@@ -60,15 +61,15 @@ class Gruff::Bullet < Gruff::Base
60
61
  graph_height = thickness * 3.0
61
62
 
62
63
  # Background
63
- rect_renderer = Gruff::Renderer::Rectangle.new(color: @colors[0])
64
+ rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: @colors[0])
64
65
  rect_renderer.render(graph_left, 0, graph_left + graph_width, graph_height)
65
66
 
66
- [:high, :low].each_with_index do |indicator, index|
67
+ %i[high low].each_with_index do |indicator, index|
67
68
  next unless @options.key?(indicator)
68
69
 
69
70
  indicator_width_x = graph_left + graph_width * (@options[indicator] / maximum_value)
70
71
 
71
- rect_renderer = Gruff::Renderer::Rectangle.new(color: @colors[index + 1])
72
+ rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: @colors[index + 1])
72
73
  rect_renderer.render(graph_left, 0, indicator_width_x, graph_height)
73
74
  end
74
75
 
@@ -76,12 +77,12 @@ class Gruff::Bullet < Gruff::Base
76
77
  target_x = graph_left + graph_width * (@options[:target] / maximum_value)
77
78
  half_thickness = thickness / 2.0
78
79
 
79
- rect_renderer = Gruff::Renderer::Rectangle.new(color: @font_color)
80
+ rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: @marker_color)
80
81
  rect_renderer.render(target_x, half_thickness, target_x + half_thickness, thickness * 2 + half_thickness)
81
82
  end
82
83
 
83
84
  # Value
84
- rect_renderer = Gruff::Renderer::Rectangle.new(color: @font_color)
85
+ rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: @marker_color)
85
86
  rect_renderer.render(graph_left, thickness, graph_left + graph_width * (@value / maximum_value), thickness * 2)
86
87
  end
87
88
 
@@ -90,9 +91,9 @@ private
90
91
  def draw_title
91
92
  return if hide_title?
92
93
 
93
- font_height = calculate_caps_height(scale_fontsize(@title_font_size))
94
+ font_height = calculate_caps_height(@title_font)
94
95
 
95
- text_renderer = Gruff::Renderer::Text.new(@title, font: @font, size: @title_font_size, color: @font_color)
96
+ text_renderer = Gruff::Renderer::Text.new(renderer, @title, font: @title_font)
96
97
  text_renderer.add_to_render_queue(1.0, 1.0, font_height / 2, font_height / 2, Magick::NorthWestGravity)
97
98
  end
98
99
  end
data/lib/gruff/dot.rb CHANGED
@@ -14,12 +14,14 @@
14
14
  # g.write('dot.png')
15
15
  #
16
16
  class Gruff::Dot < Gruff::Base
17
- def draw
18
- @has_left_labels = true
19
- super
17
+ private
20
18
 
21
- return unless data_given?
19
+ def initialize_attributes
20
+ super
21
+ @has_left_labels = true
22
+ end
22
23
 
24
+ def draw_graph
23
25
  # Setup spacing.
24
26
  #
25
27
  spacing_factor = 1.0
@@ -34,32 +36,30 @@ class Gruff::Dot < Gruff::Base
34
36
  y_pos = @graph_top + (items_width * point_index) + padding + (items_width.to_f / 2.0).round
35
37
 
36
38
  if row_index == 0
37
- Gruff::Renderer::Line.new(color: @marker_color).render(@graph_left, y_pos, @graph_left + @graph_width, y_pos)
39
+ Gruff::Renderer::Line.new(renderer, color: @marker_color).render(@graph_left, y_pos, @graph_left + @graph_width, y_pos)
38
40
  end
39
41
 
40
- Gruff::Renderer::Circle.new(color: data_row.color).render(x_pos, y_pos, x_pos + (item_width.to_f / 3.0).round, y_pos)
42
+ Gruff::Renderer::Circle.new(renderer, color: data_row.color).render(x_pos, y_pos, x_pos + (item_width.to_f / 3.0).round, y_pos)
41
43
 
42
44
  draw_label(y_pos, point_index)
43
45
  end
44
46
  end
45
47
  end
46
48
 
47
- protected
48
-
49
49
  # Instead of base class version, draws vertical background lines and label
50
50
  def draw_line_markers
51
51
  return if @hide_line_markers
52
52
 
53
53
  (0..marker_count).each do |index|
54
- marker_label = minimum_value + index * @increment
54
+ marker_label = BigDecimal(index.to_s) * BigDecimal(@increment.to_s) + BigDecimal(minimum_value.to_s)
55
55
  x = @graph_left + (marker_label - minimum_value) * @graph_width / @spread
56
56
 
57
- line_renderer = Gruff::Renderer::Line.new(color: @marker_color, shadow_color: @marker_shadow_color)
57
+ line_renderer = Gruff::Renderer::Line.new(renderer, color: @marker_color, shadow_color: @marker_shadow_color)
58
58
  line_renderer.render(x, @graph_bottom, x, @graph_bottom + 5)
59
59
 
60
60
  unless @hide_line_numbers
61
- label = label(marker_label, @increment)
62
- text_renderer = Gruff::Renderer::Text.new(label, font: @font, size: @marker_font_size, color: @font_color)
61
+ label = y_axis_label(marker_label, @increment)
62
+ text_renderer = Gruff::Renderer::Text.new(renderer, label, font: @marker_font)
63
63
  text_renderer.add_to_render_queue(0, 0, x, @graph_bottom + (LABEL_MARGIN * 1.5), Magick::CenterGravity)
64
64
  end
65
65
  end
@@ -70,8 +70,7 @@ protected
70
70
 
71
71
  def draw_label(y_offset, index)
72
72
  draw_unique_label(index) do
73
- text_renderer = Gruff::Renderer::Text.new(@labels[index], font: @font, size: @marker_font_size, color: @font_color)
74
- text_renderer.add_to_render_queue(@graph_left - LABEL_MARGIN, 1.0, 0.0, y_offset, Magick::EastGravity)
73
+ draw_label_at(@graph_left - LABEL_MARGIN, 1.0, 0.0, y_offset, @labels[index], Magick::EastGravity)
75
74
  end
76
75
  end
77
76
  end
data/lib/gruff/font.rb ADDED
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Handle font setting to draw texts
4
+ class Gruff::Font
5
+ BOLD_PATH = File.expand_path(File.join(__FILE__, '../../../assets/fonts/Roboto-Bold.ttf')).freeze
6
+ REGULAR_PATH = File.expand_path(File.join(__FILE__, '../../../assets/fonts/Roboto-Regular.ttf')).freeze
7
+
8
+ # Get/set font path.
9
+ attr_accessor :path
10
+
11
+ # Get/set font size.
12
+ attr_accessor :size
13
+
14
+ # Get/set font setting whether render bold text.
15
+ attr_accessor :bold
16
+
17
+ # Get/set font color.
18
+ attr_accessor :color
19
+
20
+ def initialize(path: nil, size: 20.0, bold: false, color: 'white')
21
+ @path = path
22
+ @bold = bold
23
+ @size = size
24
+ @color = color
25
+ end
26
+
27
+ # Get font weight.
28
+ # @return [Magick::WeightType] font weight
29
+ def weight
30
+ @bold ? Magick::BoldWeight : Magick::NormalWeight
31
+ end
32
+
33
+ # @private
34
+ def file_path
35
+ return @path if @path
36
+
37
+ @bold ? BOLD_PATH : REGULAR_PATH
38
+ end
39
+ end
@@ -14,29 +14,44 @@
14
14
  # @private
15
15
  class Gruff::BarConversion
16
16
  attr_writer :mode
17
- attr_writer :zero
18
- attr_writer :graph_top
19
- attr_writer :graph_height
20
- attr_writer :minimum_value
21
- attr_writer :spread
22
17
 
23
- def get_left_y_right_y_scaled(data_point)
18
+ def initialize(top:, bottom:, minimum_value:, maximum_value:, spread:)
19
+ @graph_top = top
20
+ @graph_height = bottom - top
21
+ @spread = spread
22
+ @minimum_value = minimum_value
23
+ @maximum_value = maximum_value
24
+
25
+ if minimum_value >= 0
26
+ # all bars go from zero to positive
27
+ @mode = 1
28
+ elsif maximum_value <= 0
29
+ # all bars go from 0 to negative
30
+ @mode = 2
31
+ else
32
+ # bars either go from zero to negative or to positive
33
+ @mode = 3
34
+ @zero = -minimum_value / @spread
35
+ end
36
+ end
37
+
38
+ def get_top_bottom_scaled(data_point)
24
39
  result = []
25
40
 
26
41
  case @mode
27
42
  when 1
28
43
  # minimum value >= 0 ( only positive values )
29
- result[0] = @graph_top + @graph_height * (1 - data_point) + 1
30
- result[1] = @graph_top + @graph_height - 1
44
+ result[0] = @graph_top + @graph_height * (1 - data_point)
45
+ result[1] = @graph_top + @graph_height
31
46
  when 2
32
47
  # only negative values
33
- result[0] = @graph_top + 1
34
- result[1] = @graph_top + @graph_height * (1 - data_point) - 1
48
+ result[0] = @graph_top
49
+ result[1] = @graph_top + @graph_height * (1 - data_point)
35
50
  when 3
36
51
  # positive and negative values
37
52
  val = data_point - @minimum_value / @spread
38
- result[0] = @graph_top + @graph_height * (1 - (val - @zero)) + 1
39
- result[1] = @graph_top + @graph_height * (1 - @zero) - 1
53
+ result[0] = @graph_top + @graph_height * (1 - (val - @zero))
54
+ result[1] = @graph_top + @graph_height * (1 - @zero)
40
55
  else
41
56
  result[0] = 0.0
42
57
  result[1] = 0.0
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @private
4
+ module Gruff::BarValueLabel
5
+ using String::GruffCommify
6
+
7
+ # @private
8
+ class Base
9
+ attr_reader :coordinate, :value
10
+
11
+ def initialize(coordinate, value)
12
+ @coordinate = coordinate
13
+ @value = value
14
+ end
15
+ end
16
+
17
+ # @private
18
+ class Bar < Base
19
+ def prepare_rendering(format, _bar_width = 0)
20
+ left_x, left_y, right_x, _right_y = @coordinate
21
+ val = begin
22
+ if format.is_a?(Proc)
23
+ format.call(@value)
24
+ else
25
+ sprintf(format || '%.2f', @value).commify
26
+ end
27
+ end
28
+
29
+ y = @value >= 0 ? left_y - 30 : left_y + 12
30
+ yield left_x + (right_x - left_x) / 2, y, val
31
+ end
32
+ end
33
+
34
+ # @private
35
+ class SideBar < Base
36
+ def prepare_rendering(format, bar_width = 0)
37
+ left_x, _left_y, right_x, right_y = @coordinate
38
+ val = begin
39
+ if format.is_a?(Proc)
40
+ format.call(@value)
41
+ else
42
+ sprintf(format || '%.2f', @value).commify
43
+ end
44
+ end
45
+ x = @value >= 0 ? right_x + 40 : left_x - 40
46
+ yield x, right_y - bar_width / 2, val
47
+ end
48
+ end
49
+
50
+ # @private
51
+ class StackedBar
52
+ def initialize
53
+ @bars = []
54
+ end
55
+
56
+ def add(bar, index)
57
+ bars = @bars[index] || []
58
+ bars << bar
59
+ @bars[index] = bars
60
+ end
61
+
62
+ def prepare_rendering(format, bar_width = 0, &block)
63
+ @bars.each do |bars|
64
+ value = bars.sum(&:value)
65
+ bar = bars.last
66
+ bar_value_label = bar.class.new(bar.coordinate, value)
67
+ bar_value_label.prepare_rendering(format, bar_width, &block)
68
+ end
69
+ end
70
+ end
71
+ end
@@ -7,10 +7,9 @@ module Gruff::Base::StackedMixin
7
7
  # tsal: moved from Base 03 FEB 2007
8
8
  def calculate_maximum_by_stack
9
9
  # Get sum of each stack
10
- max_hash = {}
10
+ max_hash = Hash.new { |h, k| h[k] = 0.0 }
11
11
  store.data.each do |data_set|
12
12
  data_set.points.each_with_index do |data_point, i|
13
- max_hash[i] = 0.0 unless max_hash[i]
14
13
  max_hash[i] += data_point.to_f
15
14
  end
16
15
  end
@@ -28,19 +28,21 @@ class Gruff::Histogram < Gruff::Bar
28
28
  @data = []
29
29
  end
30
30
 
31
- def initialize_ivars
31
+ def data(name, data_points = [], color = nil)
32
+ @data << [name, data_points, color]
33
+ end
34
+
35
+ private
36
+
37
+ def initialize_attributes
32
38
  super
33
39
  @bin_width = 10
34
40
  @minimum_bin = nil
35
41
  @maximum_bin = nil
36
42
  end
37
- private :initialize_ivars
38
-
39
- def data(name, data_points = [], color = nil)
40
- @data << [name, data_points, color]
41
- end
43
+ private :initialize_attributes
42
44
 
43
- def draw
45
+ def setup_data
44
46
  @data.each do |(name, data_points, color)|
45
47
  bins, freqs = HistogramArray.new(data_points).histogram(bin_width: @bin_width, min: @minimum_bin, max: @maximum_bin)
46
48
  bins.each_with_index do |bin, index|
data/lib/gruff/line.rb CHANGED
@@ -37,6 +37,9 @@ class Gruff::Line < Gruff::Base
37
37
  # accessors for support of xy data.
38
38
  attr_writer :maximum_x_value
39
39
 
40
+ # The number of vertical lines shown.
41
+ attr_writer :marker_x_count
42
+
40
43
  # Get the value if somebody has defined it.
41
44
  def baseline_value
42
45
  if @reference_lines.key?(:baseline)
@@ -78,29 +81,6 @@ class Gruff::Line < Gruff::Base
78
81
  end
79
82
  end
80
83
 
81
- def initialize_store
82
- @store = Gruff::Store.new(Gruff::Store::XYData)
83
- end
84
- private :initialize_store
85
-
86
- def initialize_ivars
87
- super
88
- @reference_lines = {}
89
- @reference_line_default_color = 'red'
90
- @reference_line_default_width = 5
91
-
92
- @hide_dots = @hide_lines = false
93
- @maximum_x_value = nil
94
- @minimum_x_value = nil
95
-
96
- @line_width = nil
97
- @dot_radius = nil
98
- @dot_style = 'circle'
99
-
100
- @show_vertical_markers = false
101
- end
102
- private :initialize_ivars
103
-
104
84
  # This method allows one to plot a dataset with both X and Y data.
105
85
  #
106
86
  # @overload dataxy(name, x_data_points = [], y_data_points = [], color = nil)
@@ -138,12 +118,14 @@ class Gruff::Line < Gruff::Base
138
118
  def dataxy(name, x_data_points = [], y_data_points = [], color = nil)
139
119
  # make sure it's an array
140
120
  x_data_points = Array(x_data_points)
141
- y_data_points = Array(y_data_points)
142
121
 
143
122
  raise ArgumentError, 'x_data_points is nil!' if x_data_points.empty?
144
123
 
145
124
  if x_data_points.all? { |p| p.is_a?(Array) && p.size == 2 }
125
+ color = y_data_points if y_data_points.is_a?(String)
146
126
  x_data_points, y_data_points = x_data_points.transpose
127
+ else
128
+ y_data_points = Array(y_data_points)
147
129
  end
148
130
 
149
131
  raise ArgumentError, 'x_data_points.length != y_data_points.length!' if x_data_points.length != y_data_points.length
@@ -152,10 +134,34 @@ class Gruff::Line < Gruff::Base
152
134
  store.add(name, y_data_points, color, x_data_points)
153
135
  end
154
136
 
137
+ private
138
+
139
+ def initialize_store
140
+ @store = Gruff::Store.new(Gruff::Store::XYData)
141
+ end
142
+
143
+ def initialize_attributes
144
+ super
145
+ @reference_lines = {}
146
+ @reference_line_default_color = 'red'
147
+ @reference_line_default_width = 5
148
+
149
+ @hide_dots = @hide_lines = false
150
+ @maximum_x_value = nil
151
+ @minimum_x_value = nil
152
+ @marker_x_count = nil
153
+
154
+ @line_width = nil
155
+ @dot_radius = nil
156
+ @dot_style = 'circle'
157
+
158
+ @show_vertical_markers = false
159
+ end
160
+
155
161
  def draw_reference_line(reference_line, left, right, top, bottom)
156
162
  color = reference_line[:color] || @reference_line_default_color
157
163
  width = reference_line[:width] || @reference_line_default_width
158
- Gruff::Renderer::DashLine.new(color: color, width: width).render(left, top, right, bottom)
164
+ Gruff::Renderer::DashLine.new(renderer, color: color, width: width).render(left, top, right, bottom)
159
165
  end
160
166
 
161
167
  def draw_horizontal_reference_line(reference_line)
@@ -168,31 +174,15 @@ class Gruff::Line < Gruff::Base
168
174
  draw_reference_line(reference_line, index, index, @graph_top, @graph_top + @graph_height)
169
175
  end
170
176
 
171
- def draw
172
- super
173
-
174
- return unless data_given?
175
-
177
+ def draw_graph
176
178
  # Check to see if more than one datapoint was given. NaN can result otherwise.
177
- @x_increment = (column_count > 1) ? (@graph_width / (column_count - 1).to_f) : @graph_width
179
+ @x_increment = column_count > 1 ? (@graph_width / (column_count - 1).to_f) : @graph_width
178
180
 
179
181
  @reference_lines.each_value do |curr_reference_line|
180
182
  draw_horizontal_reference_line(curr_reference_line) if curr_reference_line.key?(:norm_value)
181
183
  draw_vertical_reference_line(curr_reference_line) if curr_reference_line.key?(:index)
182
184
  end
183
185
 
184
- if @show_vertical_markers
185
- (0..column_count).each do |column|
186
- x = @graph_left + @graph_width - column.to_f * @x_increment
187
-
188
- Gruff::Renderer::Line.new(color: @marker_color).render(x, @graph_bottom, x, @graph_top)
189
- #If the user specified a marker shadow color, draw a shadow just below it
190
- if @marker_shadow_color
191
- Gruff::Renderer::Line.new(color: @marker_shadow_color).render(x + 1, @graph_bottom, x + 1, @graph_top)
192
- end
193
- end
194
- end
195
-
196
186
  store.norm_data.each do |data_row|
197
187
  prev_x = prev_y = nil
198
188
 
@@ -200,7 +190,7 @@ class Gruff::Line < Gruff::Base
200
190
 
201
191
  data_row.coordinates.each_with_index do |(x_data, y_data), index|
202
192
  if x_data.nil?
203
- #use the old method: equally spaced points along the x-axis
193
+ # use the old method: equally spaced points along the x-axis
204
194
  new_x = @graph_left + (@x_increment * index)
205
195
  draw_label(new_x, index)
206
196
  else
@@ -221,12 +211,12 @@ class Gruff::Line < Gruff::Base
221
211
  circle_radius = @dot_radius || clip_value_if_greater_than(@columns / (store.norm_data.first.y_points.size * 2.5), 5.0)
222
212
 
223
213
  if !@hide_lines && prev_x && prev_y
224
- Gruff::Renderer::Line.new(color: data_row.color, width: stroke_width)
214
+ Gruff::Renderer::Line.new(renderer, color: data_row.color, width: stroke_width)
225
215
  .render(prev_x, prev_y, new_x, new_y)
226
216
  end
227
217
 
228
218
  if one_point || !@hide_dots
229
- Gruff::Renderer::Dot.new(@dot_style, color: data_row.color, width: stroke_width).render(new_x, new_y, circle_radius)
219
+ Gruff::Renderer::Dot.new(renderer, @dot_style, color: data_row.color, width: stroke_width).render(new_x, new_y, circle_radius)
230
220
  end
231
221
 
232
222
  prev_x = new_x
@@ -235,8 +225,6 @@ class Gruff::Line < Gruff::Base
235
225
  end
236
226
  end
237
227
 
238
- private
239
-
240
228
  def setup_data
241
229
  # Update the global min/max values for the x data
242
230
  @maximum_x_value ||= store.max_x
@@ -259,6 +247,11 @@ private
259
247
  super
260
248
  end
261
249
 
250
+ def setup_drawing
251
+ @marker_x_count ||= column_count - 1
252
+ super
253
+ end
254
+
262
255
  def normalize
263
256
  return unless data_given?
264
257
 
@@ -273,8 +266,22 @@ private
273
266
  end
274
267
  end
275
268
 
276
- def sort_norm_data
277
- super unless store.data.any?(&:x_points)
269
+ def draw_line_markers
270
+ # do all of the stuff for the horizontal lines on the y-axis
271
+ super
272
+ return if @hide_line_markers
273
+
274
+ (0..@marker_x_count).each do |index|
275
+ if @show_vertical_markers
276
+ x = @graph_left + @graph_width - index * @graph_width / @marker_x_count
277
+
278
+ Gruff::Renderer::Line.new(renderer, color: @marker_color).render(x, @graph_bottom, x, @graph_top)
279
+ # If the user specified a marker shadow color, draw a shadow just below it
280
+ if @marker_shadow_color
281
+ Gruff::Renderer::Line.new(renderer, color: @marker_shadow_color).render(x + 1, @graph_bottom, x + 1, @graph_top)
282
+ end
283
+ end
284
+ end
278
285
  end
279
286
 
280
287
  def get_x_coord(x_data_point, width, offset)
@@ -16,27 +16,30 @@ module Gruff
16
16
  module Mini
17
17
  # A class for drawing a small bar graph.
18
18
  class Bar < Gruff::Bar
19
+ private
20
+
19
21
  include Gruff::Mini::Legend
20
22
 
21
- def initialize_ivars
23
+ def initialize_attributes
22
24
  super
23
25
 
24
26
  @hide_legend = true
25
27
  @hide_title = true
26
28
  @hide_line_numbers = true
27
29
 
28
- @marker_font_size = 50.0
29
- @legend_font_size = 60.0
30
+ @marker_font.size = 50.0
31
+ @legend_font.size = 60.0
30
32
 
31
33
  @minimum_value = 0.0
32
34
  end
33
- private :initialize_ivars
34
35
 
35
- def draw
36
+ def setup_data
36
37
  expand_canvas_for_vertical_legend
37
-
38
38
  super
39
+ end
39
40
 
41
+ def draw_graph
42
+ super
40
43
  draw_vertical_legend
41
44
  end
42
45
  end
@@ -3,6 +3,7 @@
3
3
  module Gruff
4
4
  module Mini
5
5
  # A module to handle the small legend.
6
+ # @private
6
7
  module Legend
7
8
  attr_accessor :hide_mini_legend, :legend_position
8
9
 
@@ -30,18 +31,20 @@ module Gruff
30
31
  @rows = [@rows, legend_height].max
31
32
  @columns += calculate_legend_width + @left_margin
32
33
  else
33
- @rows += store.length * calculate_caps_height(scale_fontsize(@legend_font_size)) * 1.7
34
+ font = @legend_font.dup
35
+ font.size = scale_fontsize(font.size)
36
+ @rows += store.length * calculate_caps_height(font) * 1.7
34
37
  end
35
38
 
36
- Gruff::Renderer.setup(@columns, @rows, @font, @scale, @theme_options)
39
+ @renderer = Gruff::Renderer.new(@columns, @rows, @scale, @theme_options)
37
40
  end
38
41
 
39
42
  def calculate_line_height
40
- calculate_caps_height(@legend_font_size) * 1.7
43
+ calculate_caps_height(@legend_font) * 1.7
41
44
  end
42
45
 
43
46
  def calculate_legend_width
44
- width = @legend_labels.map { |label| calculate_width(@legend_font_size, label) }.max
47
+ width = @legend_labels.map { |label| calculate_width(@legend_font, label) }.max
45
48
  scale_fontsize(width + 40 * 1.7)
46
49
  end
47
50
 
@@ -67,12 +70,12 @@ module Gruff
67
70
  @legend_labels.each_with_index do |legend_label, index|
68
71
  # Draw label
69
72
  label = truncate_legend_label(legend_label)
70
- text_renderer = Gruff::Renderer::Text.new(label, font: @font, size: @legend_font_size, color: @font_color)
73
+ text_renderer = Gruff::Renderer::Text.new(renderer, label, font: @legend_font)
71
74
  x_offset = current_x_offset + (legend_square_width * 1.7)
72
75
  text_renderer.add_to_render_queue(@raw_columns, 1.0, x_offset, current_y_offset, Magick::WestGravity)
73
76
 
74
77
  # Now draw box with color of this dataset
75
- rect_renderer = Gruff::Renderer::Rectangle.new(color: store.data[index].color)
78
+ rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: store.data[index].color)
76
79
  rect_renderer.render(current_x_offset,
77
80
  current_y_offset - legend_square_width / 2.0,
78
81
  current_x_offset + legend_square_width,
@@ -90,9 +93,10 @@ module Gruff
90
93
  def truncate_legend_label(label)
91
94
  truncated_label = label.to_s
92
95
 
93
- font_size = scale_fontsize(@legend_font_size)
96
+ font = @legend_font.dup
97
+ font.size = scale_fontsize(font.size)
94
98
  max_width = @columns - @legend_left_margin - @right_margin
95
- while calculate_width(font_size, truncated_label) > max_width && truncated_label.length > 1
99
+ while calculate_width(font, truncated_label) > max_width && truncated_label.length > 1
96
100
  truncated_label = truncated_label[0..truncated_label.length - 2]
97
101
  end
98
102
  truncated_label + (truncated_label.length < label.to_s.length ? '...' : '')
@@ -15,25 +15,28 @@ module Gruff
15
15
  module Mini
16
16
  # A class for drawing a small pie graph.
17
17
  class Pie < Gruff::Pie
18
+ private
19
+
18
20
  include Gruff::Mini::Legend
19
21
 
20
- def initialize_ivars
22
+ def initialize_attributes
21
23
  super
22
24
 
23
25
  @hide_legend = true
24
26
  @hide_title = true
25
27
  @hide_line_numbers = true
26
28
 
27
- @marker_font_size = 60.0
28
- @legend_font_size = 60.0
29
+ @marker_font.size = 60.0
30
+ @legend_font.size = 60.0
29
31
  end
30
- private :initialize_ivars
31
32
 
32
- def draw
33
+ def setup_data
33
34
  expand_canvas_for_vertical_legend
34
-
35
35
  super
36
+ end
36
37
 
38
+ def draw_graph
39
+ super
37
40
  draw_vertical_legend
38
41
  end
39
42
  end