gruff 0.15.0-java → 0.18.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +21 -5
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +0 -12
  5. data/CHANGELOG.md +52 -0
  6. data/README.md +14 -3
  7. data/gruff.gemspec +3 -4
  8. data/lib/gruff/accumulator_bar.rb +1 -1
  9. data/lib/gruff/area.rb +6 -4
  10. data/lib/gruff/bar.rb +53 -32
  11. data/lib/gruff/base.rb +297 -186
  12. data/lib/gruff/bezier.rb +4 -2
  13. data/lib/gruff/box.rb +180 -0
  14. data/lib/gruff/bubble.rb +99 -0
  15. data/lib/gruff/bullet.rb +5 -5
  16. data/lib/gruff/candlestick.rb +120 -0
  17. data/lib/gruff/dot.rb +11 -12
  18. data/lib/gruff/font.rb +3 -0
  19. data/lib/gruff/helper/bar_conversion.rb +6 -10
  20. data/lib/gruff/helper/bar_mixin.rb +25 -0
  21. data/lib/gruff/helper/bar_value_label.rb +24 -43
  22. data/lib/gruff/helper/stacked_mixin.rb +19 -1
  23. data/lib/gruff/histogram.rb +9 -6
  24. data/lib/gruff/line.rb +67 -43
  25. data/lib/gruff/mini/legend.rb +15 -11
  26. data/lib/gruff/net.rb +23 -18
  27. data/lib/gruff/patch/string.rb +1 -0
  28. data/lib/gruff/pie.rb +26 -12
  29. data/lib/gruff/renderer/circle.rb +3 -1
  30. data/lib/gruff/renderer/dash_line.rb +3 -2
  31. data/lib/gruff/renderer/dot.rb +28 -15
  32. data/lib/gruff/renderer/line.rb +1 -3
  33. data/lib/gruff/renderer/rectangle.rb +6 -2
  34. data/lib/gruff/renderer/renderer.rb +0 -4
  35. data/lib/gruff/renderer/text.rb +7 -1
  36. data/lib/gruff/scatter.rb +84 -81
  37. data/lib/gruff/side_bar.rb +64 -31
  38. data/lib/gruff/side_stacked_bar.rb +43 -55
  39. data/lib/gruff/spider.rb +52 -14
  40. data/lib/gruff/stacked_area.rb +18 -8
  41. data/lib/gruff/stacked_bar.rb +59 -29
  42. data/lib/gruff/store/xy_data.rb +8 -9
  43. data/lib/gruff/store/xy_pointsizes_data.rb +60 -0
  44. data/lib/gruff/version.rb +1 -1
  45. data/lib/gruff.rb +11 -12
  46. metadata +9 -6
  47. data/lib/gruff/scene.rb +0 -208
  48. data/lib/gruff/store/custom_data.rb +0 -36
@@ -23,10 +23,6 @@ module Gruff
23
23
  end
24
24
  end
25
25
 
26
- def background_image=(image)
27
- @image = image
28
- end
29
-
30
26
  def background(columns, rows, scale, theme_options)
31
27
  case theme_options[:background_colors]
32
28
  when Array
@@ -25,6 +25,7 @@ module Gruff
25
25
  end
26
26
 
27
27
  def render(width, height, x, y, gravity = Magick::NorthGravity)
28
+ @renderer.draw.push
28
29
  @renderer.draw.rotation = @rotation if @rotation
29
30
  @renderer.draw.fill = @font.color
30
31
  @renderer.draw.stroke = 'transparent'
@@ -37,9 +38,11 @@ module Gruff
37
38
  x, y,
38
39
  @text, @renderer.scale)
39
40
  @renderer.draw.rotation = -@rotation if @rotation
41
+ @renderer.draw.pop
40
42
  end
41
43
 
42
44
  def metrics
45
+ @renderer.draw.push
43
46
  @renderer.draw.font = @font.file_path
44
47
  @renderer.draw.font_weight = @font.weight
45
48
  @renderer.draw.pointsize = @font.size
@@ -50,7 +53,10 @@ module Gruff
50
53
  # So, in here, it just escape % in order to avoid SEGV.
51
54
  text = @text.to_s.gsub(/(%+)/) { ('%' * Regexp.last_match(1).size * 2).to_s }
52
55
 
53
- @renderer.draw.get_type_metrics(@renderer.image, text)
56
+ metrics = @renderer.draw.get_type_metrics(@renderer.image, text)
57
+ @renderer.draw.pop
58
+
59
+ metrics
54
60
  end
55
61
  end
56
62
  end
data/lib/gruff/scatter.rb CHANGED
@@ -24,24 +24,35 @@ class Gruff::Scatter < Gruff::Base
24
24
  attr_writer :circle_radius
25
25
  attr_writer :stroke_width
26
26
 
27
- # Allow disabling the significant rounding when labeling the X axis.
28
- # This is useful when working with a small range of high values (for example, a date range of months, while seconds as units).
29
- attr_writer :disable_significant_rounding_x_axis
30
-
31
27
  # Allow for vertical marker lines.
32
28
  attr_writer :show_vertical_markers
33
29
 
34
- # Allow using vertical labels in the X axis (and setting the label margin).
35
- attr_writer :x_label_margin
36
- attr_writer :use_vertical_x_labels
37
-
38
30
  # Allow enabling vertical lines. When you have a lot of data, they can work great.
39
- # @deprecated Please use +show_vertical_markers+ attribute instead.
31
+ # @deprecated Please use {#show_vertical_markers=} instead.
40
32
  def enable_vertical_line_markers=(value)
41
33
  warn '#enable_vertical_line_markers= is deprecated. Please use `show_vertical_markers` attribute instead'
42
34
  @show_vertical_markers = value
43
35
  end
44
36
 
37
+ # Allow using vertical labels in the X axis.
38
+ # @deprecated Please use {Gruff::Base#label_rotation=} instead.
39
+ def use_vertical_x_labels=(_value)
40
+ warn '#use_vertical_x_labels= is deprecated. It is no longer effective. Please use `#label_rotation=` instead'
41
+ end
42
+
43
+ # Allow using vertical labels in the X axis (and setting the label margin).
44
+ # @deprecated
45
+ def x_label_margin=(_value)
46
+ warn '#x_label_margin= is deprecated. It is no longer effective.'
47
+ end
48
+
49
+ # Allow disabling the significant rounding when labeling the X axis.
50
+ # This is useful when working with a small range of high values (for example, a date range of months, while seconds as units).
51
+ # @deprecated
52
+ def disable_significant_rounding_x_axis=(_value)
53
+ warn '#disable_significant_rounding_x_axis= is deprecated. It is no longer effective.'
54
+ end
55
+
45
56
  # The first parameter is the name of the dataset. The next two are the
46
57
  # x and y axis data points contain in their own array in that respective
47
58
  # order. The final parameter is the color.
@@ -55,11 +66,10 @@ class Gruff::Scatter < Gruff::Base
55
66
  # @note If you want to use a preset theme, you must set it before calling {#data}.
56
67
  #
57
68
  # @param name [String, Symbol] containing the name of the dataset.
58
- # @param x_data_points [Array] An Array of of x-axis data points.
59
- # @param y_data_points [Array] An Array of of y-axis data points.
69
+ # @param x_data_points [Array] An Array of x-axis data points.
70
+ # @param y_data_points [Array] An Array of y-axis data points.
60
71
  # @param color [String] The hex string for the color of the dataset. Defaults to nil.
61
72
  #
62
- #
63
73
  # @raise [ArgumentError] Data points contain nil values.
64
74
  # This error will get raised if either the x or y axis data points array
65
75
  # contains a +nil+ value. The graph will not make an assumption
@@ -88,7 +98,7 @@ class Gruff::Scatter < Gruff::Base
88
98
  raise ArgumentError, 'x_data_points.length != y_data_points.length!' if x_data_points.length != y_data_points.length
89
99
 
90
100
  # Call the existing data routine for the x/y axis data
91
- store.add(name, y_data_points, color, x_data_points)
101
+ store.add(name, x_data_points, y_data_points, color)
92
102
  end
93
103
 
94
104
  alias dataxy data
@@ -102,56 +112,55 @@ private
102
112
  def initialize_attributes
103
113
  super
104
114
 
105
- @baseline_x_color = @baseline_y_color = 'red'
106
- @baseline_x_value = @baseline_y_value = nil
107
115
  @circle_radius = nil
108
- @disable_significant_rounding_x_axis = false
109
116
  @show_vertical_markers = false
110
117
  @marker_x_count = nil
111
118
  @maximum_x_value = @minimum_x_value = nil
112
119
  @stroke_width = nil
113
- @use_vertical_x_labels = false
114
- @x_label_margin = nil
115
120
  end
116
121
 
117
- def draw_graph
118
- # Check to see if more than one datapoint was given. NaN can result otherwise.
119
- @x_increment = @x_spread > 1 ? (@graph_width / (@x_spread - 1).to_f) : @graph_width
122
+ def setup_drawing
123
+ @center_labels_over_point = false
124
+ super
125
+ end
120
126
 
127
+ def setup_data
128
+ # TODO: Need to get x-axis labels working. Current behavior will be to not allow.
129
+ @labels = {}
130
+
131
+ # Update the global min/max values for the x data
132
+ @maximum_x_value = (@maximum_x_value || store.max_x).to_f
133
+ @minimum_x_value = (@minimum_x_value || store.min_x).to_f
134
+
135
+ if @x_axis_increment
136
+ # TODO: Make this work for negative values
137
+ @maximum_x_value = [@maximum_x_value.ceil, @x_axis_increment.to_f].max
138
+ @minimum_x_value = @minimum_x_value.floor
139
+ end
140
+
141
+ super
142
+ end
143
+
144
+ def draw_graph
121
145
  store.norm_data.each do |data_row|
122
146
  data_row.coordinates.each do |x_value, y_value|
123
147
  next if y_value.nil? || x_value.nil?
124
148
 
125
- new_x = get_x_coord(x_value, @graph_width, @graph_left)
126
- new_y = @graph_top + (@graph_height - y_value * @graph_height)
149
+ new_x = @graph_left + (x_value * @graph_width)
150
+ new_y = @graph_bottom - (y_value * @graph_height)
127
151
 
128
152
  # Reset each time to avoid thin-line errors
129
- stroke_width = @stroke_width || clip_value_if_greater_than(@columns / (store.norm_data.first[1].size * 4), 5.0)
153
+ stroke_width = @stroke_width || clip_value_if_greater_than(@columns / (store.norm_data.first[1].size * 4.0), 5.0)
130
154
  circle_radius = @circle_radius || clip_value_if_greater_than(@columns / (store.norm_data.first[1].size * 2.5), 5.0)
131
155
  Gruff::Renderer::Circle.new(renderer, color: data_row.color, width: stroke_width).render(new_x, new_y, new_x - circle_radius, new_y)
132
156
  end
133
157
  end
134
158
  end
135
159
 
136
- def setup_data
137
- # Update the global min/max values for the x data
138
- @maximum_x_value ||= store.max_x
139
- @minimum_x_value ||= store.min_x
140
-
141
- super
142
- end
143
-
144
- def setup_drawing
145
- # TODO: Need to get x-axis labels working. Current behavior will be to not allow.
146
- @labels = {}
147
-
148
- super
149
- end
150
-
151
160
  def calculate_spread
152
161
  super
153
162
  @x_spread = @maximum_x_value.to_f - @minimum_x_value.to_f
154
- @x_spread = @x_spread > 0 ? @x_spread : 1
163
+ @x_spread = @x_spread > 0 ? @x_spread : 1.0
155
164
  end
156
165
 
157
166
  def normalize
@@ -165,57 +174,51 @@ private
165
174
  super
166
175
  return if @hide_line_markers
167
176
 
168
- if @x_axis_increment.nil?
169
- # TODO: Do the same for larger numbers...100, 75, 50, 25
170
- if @marker_x_count.nil?
171
- (3..7).each do |lines|
172
- if @x_spread % lines == 0.0
173
- @marker_x_count = lines
174
- break
175
- end
176
- end
177
- @marker_x_count ||= 4
178
- end
179
- @x_increment = @x_spread > 0 ? (@x_spread / @marker_x_count) : 1
180
- unless @disable_significant_rounding_x_axis
181
- @x_increment = significant(@x_increment)
182
- end
183
- else
184
- # TODO: Make this work for negative values
185
- @maximum_x_value = [@maximum_x_value.ceil, @x_axis_increment].max
186
- @minimum_x_value = @minimum_x_value.floor
187
- calculate_spread
188
- normalize
189
-
190
- @marker_x_count = (@x_spread / @x_axis_increment).to_i
191
- @x_increment = @x_axis_increment
192
- end
193
- increment_x_scaled = @graph_width.to_f / (@x_spread / @x_increment)
177
+ increment_x_scaled = (@graph_width / (@x_spread / x_increment)).to_f
194
178
 
195
179
  # Draw vertical line markers and annotate with numbers
196
- (0..@marker_x_count).each do |index|
180
+ (0..marker_x_count).each do |index|
197
181
  # TODO: Fix the vertical lines, and enable them by default. Not pretty when they don't match up with top y-axis line
198
182
  if @show_vertical_markers
199
- x = @graph_left + @graph_width - index.to_f * increment_x_scaled
200
-
201
- line_renderer = Gruff::Renderer::Line.new(renderer, color: @marker_color, shadow_color: @marker_shadow_color)
202
- line_renderer.render(x, @graph_top, x, @graph_bottom)
183
+ draw_marker_vertical_line(@graph_left + (index * increment_x_scaled))
203
184
  end
204
185
 
205
186
  unless @hide_line_numbers
206
- marker_label = BigDecimal(index.to_s) * BigDecimal(@x_increment.to_s) + BigDecimal(@minimum_x_value.to_s)
207
- y_offset = @graph_bottom + (@x_label_margin || LABEL_MARGIN)
208
- x_offset = get_x_coord(index.to_f, increment_x_scaled, @graph_left)
209
-
210
- label = x_axis_label(marker_label, @x_increment)
211
- rotation = -90.0 if @use_vertical_x_labels
212
- text_renderer = Gruff::Renderer::Text.new(renderer, label, font: @marker_font, rotation: rotation)
213
- text_renderer.add_to_render_queue(1.0, 1.0, x_offset, y_offset)
187
+ marker_label = (BigDecimal(index.to_s) * BigDecimal(x_increment.to_s)) + BigDecimal(@minimum_x_value.to_s)
188
+ label = x_axis_label(marker_label, x_increment)
189
+ x = @graph_left + (increment_x_scaled * index)
190
+ y = @graph_bottom
191
+ x_offset, y_offset = calculate_label_offset(@marker_font, label, LABEL_MARGIN, @label_rotation)
192
+
193
+ draw_label_at(1.0, 1.0, x + x_offset, y + y_offset, label, rotation: @label_rotation)
214
194
  end
215
195
  end
216
196
  end
217
197
 
218
- def get_x_coord(x_data_point, width, offset)
219
- x_data_point * width + offset
198
+ def marker_x_count
199
+ # TODO: Do the same for larger numbers...100, 75, 50, 25
200
+ @marker_x_count ||= begin
201
+ if @x_axis_increment.nil?
202
+ count = nil
203
+ (3..7).each do |lines|
204
+ if @x_spread % lines == 0.0
205
+ count = lines and break
206
+ end
207
+ end
208
+ count || 4
209
+ else
210
+ (@x_spread / @x_axis_increment).to_i
211
+ end
212
+ end
213
+ end
214
+
215
+ def x_increment
216
+ @x_increment ||= begin
217
+ if @x_axis_increment.nil?
218
+ @x_spread > 0 ? significant(@x_spread / marker_x_count) : 1.0
219
+ else
220
+ @x_axis_increment.to_f
221
+ end
222
+ end
220
223
  end
221
224
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'helper/bar_mixin'
4
+
3
5
  # Graph with individual horizontal bars instead of vertical bars.
4
6
  #
5
7
  # Here's how to set up a Gruff::SideBar.
@@ -19,6 +21,8 @@
19
21
  # g.write('sidebar.png')
20
22
  #
21
23
  class Gruff::SideBar < Gruff::Base
24
+ include BarMixin
25
+
22
26
  # Spacing factor applied between bars.
23
27
  attr_writer :bar_spacing
24
28
 
@@ -36,6 +40,15 @@ class Gruff::SideBar < Gruff::Base
36
40
  # Prevent drawing of column labels left of a side bar graph. Default is +false+.
37
41
  attr_writer :hide_labels
38
42
 
43
+ # Value to avoid completely overwriting the coordinate axis
44
+ AXIS_MARGIN = 0.5
45
+ private_constant :AXIS_MARGIN
46
+
47
+ def initialize(*)
48
+ super
49
+ @has_left_labels = true
50
+ end
51
+
39
52
  # With Side Bars use the data label for the marker value to the left of the bar.
40
53
  # @deprecated
41
54
  def use_data_label=(_value)
@@ -51,7 +64,6 @@ private
51
64
  @label_formatting = nil
52
65
  @show_labels_for_bar_values = false
53
66
  @hide_labels = false
54
- @has_left_labels = true
55
67
  end
56
68
 
57
69
  def hide_labels?
@@ -59,20 +71,37 @@ private
59
71
  end
60
72
 
61
73
  def hide_left_label_area?
62
- hide_labels?
74
+ hide_labels? && @y_axis_label.nil?
63
75
  end
64
76
 
65
77
  def hide_bottom_label_area?
66
- @hide_line_markers
78
+ @hide_line_markers && @x_axis_label.nil? && @legend_at_bottom == false
67
79
  end
68
80
 
69
- # Value to avoid completely overwriting the coordinate axis
70
- AXIS_MARGIN = 0.5
81
+ def setup_graph_measurements
82
+ super
83
+ return if @hide_line_markers
84
+
85
+ if @show_labels_for_bar_values
86
+ if maximum_value >= 0
87
+ _, metrics = Gruff::BarValueLabel.metrics(maximum_value, @label_formatting, proc_text_metrics)
88
+ @graph_right -= metrics.width
89
+ end
90
+
91
+ if minimum_value < 0
92
+ _, metrics = Gruff::BarValueLabel.metrics(minimum_value, @label_formatting, proc_text_metrics)
93
+ width = metrics.width + LABEL_MARGIN
94
+ @graph_left += width - @graph_left if width > @graph_left
95
+ end
96
+
97
+ @graph_width = @graph_right - @graph_left
98
+ end
99
+ end
71
100
 
72
101
  def draw_graph
73
102
  # Setup spacing.
74
103
  #
75
- bars_width = (@graph_height - calculate_spacing) / column_count.to_f
104
+ bars_width = (@graph_height - calculate_spacing) / column_count
76
105
  bar_width = bars_width / store.length
77
106
  padding = (bar_width * (1 - @bar_spacing)) / 2
78
107
 
@@ -82,30 +111,32 @@ private
82
111
  minimum_value: minimum_value, maximum_value: maximum_value, spread: @spread
83
112
  )
84
113
 
85
- store.norm_data.each_with_index do |data_row, row_index|
86
- data_row.points.each_with_index do |data_point, point_index|
87
- group_spacing = @group_spacing * @scale * point_index
88
-
89
- left_y = @graph_top + (bars_width * point_index) + (bar_width * row_index) + padding + group_spacing
90
- right_y = left_y + bar_width * @bar_spacing
114
+ group_left_y = @graph_top
91
115
 
92
- left_x, right_x = conversion.get_top_bottom_scaled(data_point).sort
116
+ normalized_group_bars.each_with_index do |group_bars, group_index|
117
+ right_y = 0
118
+ group_bars.each_with_index do |bar, index|
119
+ left_y = group_left_y + (bar_width * index) + padding
120
+ right_y = left_y + (bar_width * @bar_spacing)
93
121
 
94
- rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: data_row.color)
95
- rect_renderer.render(left_x + AXIS_MARGIN, left_y, right_x + AXIS_MARGIN, right_y)
96
-
97
- # Calculate center based on bar_width and current row
98
- label_center = left_y + bars_width / 2
122
+ bottom_x, top_x = conversion.get_top_bottom_scaled(bar.point).sort
123
+ if bar.point != 0
124
+ rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: bar.color)
125
+ rect_renderer.render(bottom_x + AXIS_MARGIN, left_y, top_x, right_y)
126
+ end
99
127
 
100
- # Subtract half a bar width to center left if requested
101
- draw_label(label_center, point_index)
102
- if @show_labels_for_bar_values
103
- bar_value_label = Gruff::BarValueLabel::SideBar.new([left_x, left_y, right_x, right_y], store.data[row_index].points[point_index])
104
- bar_value_label.prepare_rendering(@label_formatting, bar_width) do |x, y, text|
105
- draw_value_label(x, y, text)
128
+ if @show_labels_for_bar_values && bar.value
129
+ bar_value_label = Gruff::BarValueLabel::SideBar.new([bottom_x, left_y, top_x, right_y], bar.value)
130
+ bar_value_label.prepare_rendering(@label_formatting, proc_text_metrics) do |x, y, text, text_width, _text_height|
131
+ draw_value_label(text_width, bar_width * @bar_spacing, x, y, text)
106
132
  end
107
133
  end
108
134
  end
135
+
136
+ label_center = group_left_y + (bars_width / 2.0)
137
+ draw_label(label_center, group_index)
138
+
139
+ group_left_y = right_y + padding + @group_spacing
109
140
  end
110
141
  end
111
142
 
@@ -118,17 +149,15 @@ private
118
149
  number_of_lines = 1 if number_of_lines == 0
119
150
 
120
151
  # TODO: Round maximum marker value to a round number like 100, 0.1, 0.5, etc.
121
- increment = significant(@spread.to_f / number_of_lines)
152
+ increment = significant(@spread / number_of_lines)
122
153
  (0..number_of_lines).each do |index|
123
154
  line_diff = (@graph_right - @graph_left) / number_of_lines
124
155
  x = @graph_right - (line_diff * index) - 1
125
-
126
- line_renderer = Gruff::Renderer::Line.new(renderer, color: @marker_color, shadow_color: @marker_shadow_color)
127
- line_renderer.render(x, @graph_bottom, x, @graph_top)
156
+ draw_marker_vertical_line(x)
128
157
 
129
158
  unless @hide_line_numbers
130
159
  diff = index - number_of_lines
131
- marker_label = BigDecimal(diff.abs.to_s) * BigDecimal(increment.to_s) + BigDecimal(minimum_value.to_s)
160
+ marker_label = (BigDecimal(diff.abs.to_s) * BigDecimal(increment.to_s)) + BigDecimal(minimum_value.to_s)
132
161
  label = x_axis_label(marker_label, @increment)
133
162
  text_renderer = Gruff::Renderer::Text.new(renderer, label, font: @marker_font)
134
163
  text_renderer.add_to_render_queue(0, 0, x, @graph_bottom + LABEL_MARGIN, Magick::CenterGravity)
@@ -141,11 +170,15 @@ private
141
170
 
142
171
  def draw_label(y_offset, index)
143
172
  draw_unique_label(index) do
144
- draw_label_at(@graph_left - LABEL_MARGIN, 1.0, 0.0, y_offset, @labels[index], Magick::EastGravity)
173
+ draw_label_at(@graph_left - LABEL_MARGIN, 1.0, 0.0, y_offset, @labels[index], gravity: Magick::EastGravity)
145
174
  end
146
175
  end
147
176
 
148
177
  def calculate_spacing
149
- @scale * @group_spacing * (column_count - 1)
178
+ @group_spacing * (column_count - 1)
179
+ end
180
+
181
+ def proc_text_metrics
182
+ ->(text) { text_metrics(@marker_font, text) }
150
183
  end
151
184
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'helper/stacked_mixin'
4
+
3
5
  #
4
6
  # New gruff graph type added to enable sideways stacking bar charts
5
7
  # (basically looks like a x/y flip of a standard stacking bar chart)
@@ -39,6 +41,11 @@ class Gruff::SideStackedBar < Gruff::SideBar
39
41
  # Prevent drawing of column labels left of a side stacked bar graph. Default is +false+.
40
42
  attr_writer :hide_labels
41
43
 
44
+ def initialize(*)
45
+ super
46
+ @has_left_labels = true
47
+ end
48
+
42
49
  private
43
50
 
44
51
  def initialize_attributes
@@ -48,7 +55,7 @@ private
48
55
  @label_formatting = nil
49
56
  @show_labels_for_bar_values = false
50
57
  @hide_labels = false
51
- @has_left_labels = true
58
+ @minimum_value = 0.0
52
59
  end
53
60
 
54
61
  def setup_data
@@ -56,67 +63,48 @@ private
56
63
  super
57
64
  end
58
65
 
59
- def hide_labels?
60
- @hide_labels
61
- end
62
-
63
- def hide_left_label_area?
64
- hide_labels?
65
- end
66
-
67
- def hide_bottom_label_area?
68
- @hide_line_markers
69
- end
70
-
71
66
  def draw_graph
72
67
  # Setup spacing.
73
68
  #
74
69
  # Columns sit stacked.
75
- bar_width = @graph_height / column_count.to_f
76
- height = Array.new(column_count, 0)
77
- length = Array.new(column_count, @graph_left)
70
+ bar_width = @graph_height / column_count
78
71
  padding = (bar_width * (1 - @bar_spacing)) / 2
79
- stack_bar_value_label = Gruff::BarValueLabel::StackedBar.new
80
-
81
- store.norm_data.each_with_index do |data_row, row_index|
82
- data_row.points.each_with_index do |data_point, point_index|
83
- ## using the original calculations from the stacked bar chart to get the difference between
84
- ## part of the bart chart we wish to stack.
85
- temp1 = @graph_left + (@graph_width -
86
- data_point * @graph_width -
87
- height[point_index]) + 1
88
- temp2 = @graph_left + @graph_width - height[point_index] - 1
89
- difference = temp2 - temp1
90
- difference = 0 if row_index == 0 && difference < 0
91
-
92
- left_x = length[point_index]
93
- left_y = @graph_top + (bar_width * point_index) + padding
94
- right_x = left_x + difference - @segment_spacing
95
- right_y = left_y + bar_width * @bar_spacing
96
- length[point_index] += difference
97
- height[point_index] += (data_point * @graph_width - 2)
98
-
99
- bar_value_label = Gruff::BarValueLabel::SideBar.new([left_x, left_y, right_x, right_y], store.data[row_index].points[point_index])
100
- stack_bar_value_label.add(bar_value_label, point_index)
101
-
102
- # if a data point is 0 it can result in weird really thing lines
103
- # that shouldn't even be there being drawn on top of the existing
104
- # bar - this is bad
105
- if data_point != 0
106
- rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: data_row.color)
107
- rect_renderer.render(left_x, left_y, right_x, right_y)
108
- # Calculate center based on bar_width and current row
109
- end
110
- # we still need to draw the labels
111
- # Calculate center based on bar_width and current row
112
- label_center = left_y + bar_width / 2
113
- draw_label(label_center, point_index)
72
+
73
+ # Setup the BarConversion Object
74
+ conversion = Gruff::BarConversion.new(
75
+ top: @graph_right, bottom: @graph_left,
76
+ minimum_value: minimum_value, maximum_value: maximum_value, spread: @spread
77
+ )
78
+
79
+ proc_text_metrics = ->(text) { text_metrics(@marker_font, text) }
80
+
81
+ normalized_stacked_bars.each_with_index do |stacked_bars, stacked_index|
82
+ total = 0
83
+ left_y = @graph_top + (bar_width * stacked_index) + padding
84
+ right_y = left_y + (bar_width * @bar_spacing)
85
+
86
+ top_x = 0
87
+ stacked_bars.each do |bar|
88
+ next if bar.point == 0
89
+
90
+ bottom_x, = conversion.get_top_bottom_scaled(total)
91
+ bottom_x += @segment_spacing
92
+ top_x, = conversion.get_top_bottom_scaled(total + bar.point)
93
+
94
+ rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: bar.color)
95
+ rect_renderer.render(bottom_x, left_y, top_x, right_y)
96
+
97
+ total += bar.point
114
98
  end
115
- end
116
99
 
117
- if @show_labels_for_bar_values
118
- stack_bar_value_label.prepare_rendering(@label_formatting, bar_width) do |x, y, text|
119
- draw_value_label(x, y, text)
100
+ label_center = left_y + (bar_width / 2.0)
101
+ draw_label(label_center, stacked_index)
102
+
103
+ if @show_labels_for_bar_values
104
+ bar_value_label = Gruff::BarValueLabel::SideBar.new([@graph_left, left_y, top_x, right_y], stacked_bars.sum(&:value))
105
+ bar_value_label.prepare_rendering(@label_formatting, proc_text_metrics) do |x, y, text, text_width, _text_height|
106
+ draw_value_label(text_width, bar_width * @bar_spacing, x, y, text)
107
+ end
120
108
  end
121
109
  end
122
110
  end