gruff 0.16.0-java → 0.17.0-java

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.
@@ -49,26 +49,4 @@ module Gruff::BarValueLabel
49
49
  yield x, left_y, val, metrics.width, metrics.height
50
50
  end
51
51
  end
52
-
53
- # @private
54
- class StackedBar
55
- def initialize
56
- @bars = []
57
- end
58
-
59
- def add(bar, index)
60
- bars = @bars[index] || []
61
- bars << bar
62
- @bars[index] = bars
63
- end
64
-
65
- def prepare_rendering(format, proc_text_metrics, &block)
66
- @bars.each do |bars|
67
- value = bars.sum(&:value)
68
- bar = bars.last
69
- bar_value_label = bar.class.new(bar.coordinate, value)
70
- bar_value_label.prepare_rendering(format, proc_text_metrics, &block)
71
- end
72
- end
73
- end
74
52
  end
@@ -21,4 +21,20 @@ module Gruff::Base::StackedMixin
21
21
 
22
22
  raise "Can't handle negative values in stacked graph" if minimum_value < 0
23
23
  end
24
+
25
+ def normalized_stacked_bars
26
+ @normalized_stacked_bars ||= begin
27
+ stacked_bars = Array.new(column_count) { [] }
28
+ store.norm_data.each_with_index do |data_row, row_index|
29
+ data_row.points.each_with_index do |data_point, point_index|
30
+ stacked_bars[point_index] << BarData.new(data_point, store.data[row_index].points[point_index], data_row.color)
31
+ end
32
+ end
33
+ stacked_bars
34
+ end
35
+ end
36
+
37
+ # @private
38
+ class BarData < Struct.new(:point, :value, :color)
39
+ end
24
40
  end
@@ -44,11 +44,15 @@ private
44
44
 
45
45
  def setup_data
46
46
  @data.each do |(name, data_points, color)|
47
- bins, freqs = HistogramArray.new(data_points).histogram(bin_width: @bin_width, min: @minimum_bin, max: @maximum_bin)
48
- bins.each_with_index do |bin, index|
49
- @labels[index] = bin
47
+ if data_points.empty?
48
+ store.add(name, [], color)
49
+ else
50
+ bins, freqs = HistogramArray.new(data_points).histogram(bin_width: @bin_width, min: @minimum_bin, max: @maximum_bin)
51
+ bins.each_with_index do |bin, index|
52
+ @labels[index] = bin
53
+ end
54
+ store.add(name, freqs, color)
50
55
  end
51
- store.add(name, freqs, color)
52
56
  end
53
57
 
54
58
  super
data/lib/gruff/line.rb CHANGED
@@ -25,7 +25,7 @@ class Gruff::Line < Gruff::Base
25
25
  attr_writer :line_width
26
26
  attr_writer :dot_radius
27
27
 
28
- # default is +'circle'+, other options include square.
28
+ # default is +'circle'+, other options include +square+ and +diamond+.
29
29
  attr_writer :dot_style
30
30
 
31
31
  # Hide parts of the graph to fit more data points, or for a different appearance.
@@ -273,10 +273,7 @@ private
273
273
  return unless @show_vertical_markers
274
274
 
275
275
  (0..@marker_x_count).each do |index|
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
- Gruff::Renderer::Line.new(renderer, color: @marker_shadow_color).render(x + 1, @graph_bottom, x + 1, @graph_top) if @marker_shadow_color
276
+ draw_marker_vertical_line(@graph_left + @graph_width - (index * @graph_width / @marker_x_count))
280
277
  end
281
278
  end
282
279
 
@@ -21,7 +21,7 @@ module Gruff
21
21
 
22
22
  @legend_labels = store.data.map(&:label)
23
23
 
24
- legend_height = scale_fontsize((store.length * calculate_line_height) + @top_margin + @bottom_margin)
24
+ legend_height = scale((store.length * calculate_line_height) + @top_margin + @bottom_margin)
25
25
 
26
26
  @original_rows = @raw_rows
27
27
  @original_columns = @raw_columns
@@ -32,7 +32,7 @@ module Gruff
32
32
  @columns += calculate_legend_width + @left_margin
33
33
  else
34
34
  font = @legend_font.dup
35
- font.size = scale_fontsize(font.size)
35
+ font.size = scale(font.size)
36
36
  @rows += store.length * calculate_caps_height(font) * 1.7
37
37
  end
38
38
 
@@ -45,7 +45,7 @@ module Gruff
45
45
 
46
46
  def calculate_legend_width
47
47
  width = @legend_labels.map { |label| calculate_width(@legend_font, label) }.max
48
- scale_fontsize(width + (40 * 1.7))
48
+ scale(width + (40 * 1.7))
49
49
  end
50
50
 
51
51
  ##
@@ -69,9 +69,9 @@ module Gruff
69
69
 
70
70
  @legend_labels.each_with_index do |legend_label, index|
71
71
  # Draw label
72
- label = truncate_legend_label(legend_label)
73
- text_renderer = Gruff::Renderer::Text.new(renderer, label, font: @legend_font)
74
72
  x_offset = current_x_offset + (legend_square_width * 1.7)
73
+ label = truncate_legend_label(legend_label, x_offset)
74
+ text_renderer = Gruff::Renderer::Text.new(renderer, label, font: @legend_font)
75
75
  text_renderer.add_to_render_queue(@raw_columns, 1.0, x_offset, current_y_offset, Magick::WestGravity)
76
76
 
77
77
  # Now draw box with color of this dataset
@@ -90,13 +90,13 @@ module Gruff
90
90
  #
91
91
  # Department of Hu...
92
92
 
93
- def truncate_legend_label(label)
93
+ def truncate_legend_label(label, x_offset)
94
94
  truncated_label = label.to_s
95
95
 
96
96
  font = @legend_font.dup
97
- font.size = scale_fontsize(font.size)
98
- max_width = @columns - @legend_left_margin - @right_margin
99
- while calculate_width(font, truncated_label) > max_width && truncated_label.length > 1
97
+ font.size = scale(font.size)
98
+ max_width = @columns - scale(x_offset) - @right_margin
99
+ while calculate_width(font, "#{truncated_label}...") > max_width && truncated_label.length > 1
100
100
  truncated_label = truncated_label[0..truncated_label.length - 2]
101
101
  end
102
102
  truncated_label + (truncated_label.length < label.to_s.length ? '...' : '')
data/lib/gruff/net.rb CHANGED
@@ -43,6 +43,21 @@ private
43
43
  @marker_font.bold = true
44
44
  end
45
45
 
46
+ def setup_drawing
47
+ @center_labels_over_point = false
48
+ super
49
+ end
50
+
51
+ def setup_graph_measurements
52
+ super
53
+
54
+ @radius = @graph_height / 2.0
55
+ @circle_radius = @dot_radius || clip_value_if_greater_than(@columns / (store.norm_data.first.points.size * 2.5), 5.0)
56
+ @stroke_width = @line_width || clip_value_if_greater_than(@columns / (store.norm_data.first.points.size * 4.0), 5.0)
57
+ @center_x = @graph_left + (@graph_width / 2.0)
58
+ @center_y = @graph_top + (@graph_height / 2.0) + 10
59
+ end
60
+
46
61
  def draw_graph
47
62
  store.norm_data.each do |data_row|
48
63
  data_row.points.each_with_index do |data_point, index|
@@ -70,16 +85,6 @@ private
70
85
  end
71
86
  end
72
87
 
73
- def setup_drawing
74
- super
75
-
76
- @radius = @graph_height / 2.0
77
- @circle_radius = @dot_radius || clip_value_if_greater_than(@columns / (store.norm_data.first.points.size * 2.5), 5.0)
78
- @stroke_width = @line_width || clip_value_if_greater_than(@columns / (store.norm_data.first.points.size * 4), 5.0)
79
- @center_x = @graph_left + (@graph_width / 2.0)
80
- @center_y = @graph_top + (@graph_height / 2.0) + 10
81
- end
82
-
83
88
  # the lines connecting in the center, with the first line vertical
84
89
  def draw_line_markers
85
90
  return if @hide_line_markers
@@ -102,6 +107,6 @@ private
102
107
  x = x_offset + ((radius + LABEL_MARGIN) * Math.sin(deg2rad(angle)))
103
108
  y = y_offset - ((radius + LABEL_MARGIN) * Math.cos(deg2rad(angle)))
104
109
 
105
- draw_label_at(1.0, 1.0, x, y, amount, Magick::CenterGravity)
110
+ draw_label_at(1.0, 1.0, x, y, amount, gravity: Magick::CenterGravity)
106
111
  end
107
112
  end
data/lib/gruff/pie.rb CHANGED
@@ -61,6 +61,11 @@ private
61
61
  @label_formatting = ->(value, percentage) { @show_values_as_labels ? value.to_s : "#{percentage}%" }
62
62
  end
63
63
 
64
+ def setup_drawing
65
+ @center_labels_over_point = false
66
+ super
67
+ end
68
+
64
69
  def draw_graph
65
70
  slices.each do |slice|
66
71
  if slice.value > 0
@@ -136,7 +141,7 @@ private
136
141
  if slice.percentage >= @hide_labels_less_than
137
142
  x, y = label_coordinates_for slice
138
143
  label = @label_formatting.call(slice.value, slice.percentage)
139
- draw_label_at(1.0, 1.0, x, y, label, Magick::CenterGravity)
144
+ draw_label_at(1.0, 1.0, x, y, label, gravity: Magick::CenterGravity)
140
145
  end
141
146
  end
142
147
 
@@ -11,31 +11,42 @@ module Gruff
11
11
  @opacity = opacity
12
12
  end
13
13
 
14
- def render(new_x, new_y, circle_radius)
15
- # @renderer.draw.push # TODO
14
+ def render(new_x, new_y, radius)
15
+ @renderer.draw.push
16
16
  @renderer.draw.stroke_width(@width)
17
17
  @renderer.draw.stroke(@color)
18
18
  @renderer.draw.fill(@color)
19
19
  @renderer.draw.fill_opacity(@opacity)
20
- if @style.to_s == 'square'
21
- square(new_x, new_y, circle_radius)
20
+ case @style.to_sym
21
+ when :square
22
+ square(new_x, new_y, radius)
23
+ when :diamond
24
+ diamond(new_x, new_y, radius)
22
25
  else
23
- circle(new_x, new_y, circle_radius)
26
+ circle(new_x, new_y, radius)
24
27
  end
25
- # @renderer.draw.pop # TODO
28
+ @renderer.draw.pop
26
29
  end
27
30
 
28
- def circle(new_x, new_y, circle_radius)
29
- @renderer.draw.circle(new_x, new_y, new_x - circle_radius, new_y)
31
+ def circle(new_x, new_y, radius)
32
+ @renderer.draw.circle(new_x, new_y, new_x - radius, new_y)
30
33
  end
31
34
 
32
- def square(new_x, new_y, circle_radius)
33
- offset = (circle_radius * 0.8).to_i
34
- corner1 = new_x - offset
35
- corner2 = new_y - offset
36
- corner3 = new_x + offset
37
- corner4 = new_y + offset
35
+ def square(new_x, new_y, radius)
36
+ corner1 = new_x - radius
37
+ corner2 = new_y - radius
38
+ corner3 = new_x + radius
39
+ corner4 = new_y + radius
38
40
  @renderer.draw.rectangle(corner1, corner2, corner3, corner4)
39
41
  end
42
+
43
+ def diamond(new_x, new_y, radius)
44
+ polygon = []
45
+ polygon += [new_x - radius, new_y]
46
+ polygon += [new_x, new_y + radius]
47
+ polygon += [new_x + radius, new_y]
48
+ polygon += [new_x, new_y - radius]
49
+ @renderer.draw.polygon(*polygon)
50
+ end
40
51
  end
41
52
  end
@@ -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
@@ -114,20 +114,9 @@ private
114
114
  @x_label_margin = nil
115
115
  end
116
116
 
117
- def draw_graph
118
- store.norm_data.each do |data_row|
119
- data_row.coordinates.each do |x_value, y_value|
120
- next if y_value.nil? || x_value.nil?
121
-
122
- new_x = get_x_coord(x_value, @graph_width, @graph_left)
123
- new_y = @graph_top + (@graph_height - (y_value * @graph_height))
124
-
125
- # Reset each time to avoid thin-line errors
126
- stroke_width = @stroke_width || clip_value_if_greater_than(@columns / (store.norm_data.first[1].size * 4), 5.0)
127
- circle_radius = @circle_radius || clip_value_if_greater_than(@columns / (store.norm_data.first[1].size * 2.5), 5.0)
128
- Gruff::Renderer::Circle.new(renderer, color: data_row.color, width: stroke_width).render(new_x, new_y, new_x - circle_radius, new_y)
129
- end
130
- end
117
+ def setup_drawing
118
+ @center_labels_over_point = false
119
+ super
131
120
  end
132
121
 
133
122
  def setup_data
@@ -147,6 +136,22 @@ private
147
136
  super
148
137
  end
149
138
 
139
+ def draw_graph
140
+ store.norm_data.each do |data_row|
141
+ data_row.coordinates.each do |x_value, y_value|
142
+ next if y_value.nil? || x_value.nil?
143
+
144
+ new_x = get_x_coord(x_value, @graph_width, @graph_left)
145
+ new_y = @graph_top + (@graph_height - (y_value * @graph_height))
146
+
147
+ # Reset each time to avoid thin-line errors
148
+ stroke_width = @stroke_width || clip_value_if_greater_than(@columns / (store.norm_data.first[1].size * 4), 5.0)
149
+ circle_radius = @circle_radius || clip_value_if_greater_than(@columns / (store.norm_data.first[1].size * 2.5), 5.0)
150
+ Gruff::Renderer::Circle.new(renderer, color: data_row.color, width: stroke_width).render(new_x, new_y, new_x - circle_radius, new_y)
151
+ end
152
+ end
153
+ end
154
+
150
155
  def calculate_spread
151
156
  super
152
157
  @x_spread = @maximum_x_value.to_f - @minimum_x_value.to_f
@@ -170,10 +175,7 @@ private
170
175
  (0..marker_x_count).each do |index|
171
176
  # TODO: Fix the vertical lines, and enable them by default. Not pretty when they don't match up with top y-axis line
172
177
  if @show_vertical_markers
173
- x = @graph_left + @graph_width - (index * increment_x_scaled)
174
-
175
- Gruff::Renderer::Line.new(renderer, color: @marker_color).render(x, @graph_top, x, @graph_bottom)
176
- Gruff::Renderer::Line.new(renderer, color: @marker_shadow_color).render(x, @graph_top + 1, x, @graph_bottom + 1) if @marker_shadow_color
178
+ draw_marker_vertical_line(@graph_left + @graph_width - (index * increment_x_scaled))
177
179
  end
178
180
 
179
181
  unless @hide_line_numbers
@@ -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
 
@@ -79,8 +83,6 @@ private
79
83
  return if @hide_line_markers
80
84
 
81
85
  if @show_labels_for_bar_values
82
- proc_text_metrics = ->(text) { text_metrics(@marker_font, text) }
83
-
84
86
  if maximum_value >= 0
85
87
  _, metrics = Gruff::BarValueLabel.metrics(maximum_value, @label_formatting, proc_text_metrics)
86
88
  @graph_right -= metrics.width
@@ -109,32 +111,33 @@ private
109
111
  minimum_value: minimum_value, maximum_value: maximum_value, spread: @spread
110
112
  )
111
113
 
112
- proc_text_metrics = ->(text) { text_metrics(@marker_font, text) }
114
+ group_spacing = @group_spacing * @scale
115
+ group_left_y = @graph_top
113
116
 
114
- store.norm_data.each_with_index do |data_row, row_index|
115
- data_row.points.each_with_index do |data_point, point_index|
116
- group_spacing = @group_spacing * @scale * point_index
117
-
118
- left_y = @graph_top + (bars_width * point_index) + (bar_width * row_index) + padding + group_spacing
117
+ normalized_group_bars.each_with_index do |group_bars, group_index|
118
+ right_y = 0
119
+ group_bars.each_with_index do |bar, index|
120
+ left_y = group_left_y + (bar_width * index) + padding
119
121
  right_y = left_y + (bar_width * @bar_spacing)
120
122
 
121
- left_x, right_x = conversion.get_top_bottom_scaled(data_point).sort
122
-
123
- rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: data_row.color)
124
- rect_renderer.render(left_x + AXIS_MARGIN, left_y, right_x + AXIS_MARGIN, right_y)
125
-
126
- # Calculate center based on bar_width and current row
127
- label_center = left_y + (bars_width / 2.0)
123
+ bottom_x, top_x = conversion.get_top_bottom_scaled(bar.point).sort
124
+ if bar.point != 0
125
+ rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: bar.color)
126
+ rect_renderer.render(bottom_x + AXIS_MARGIN, left_y, top_x, right_y)
127
+ end
128
128
 
129
- # Subtract half a bar width to center left if requested
130
- draw_label(label_center, point_index)
131
- if @show_labels_for_bar_values
132
- bar_value_label = Gruff::BarValueLabel::SideBar.new([left_x, left_y, right_x, right_y], store.data[row_index].points[point_index])
129
+ if @show_labels_for_bar_values && bar.value
130
+ bar_value_label = Gruff::BarValueLabel::SideBar.new([bottom_x, left_y, top_x, right_y], bar.value)
133
131
  bar_value_label.prepare_rendering(@label_formatting, proc_text_metrics) do |x, y, text, text_width, _text_height|
134
132
  draw_value_label(text_width, bar_width * @bar_spacing, x, y, text)
135
133
  end
136
134
  end
137
135
  end
136
+
137
+ label_center = group_left_y + (bars_width / 2.0)
138
+ draw_label(label_center, group_index)
139
+
140
+ group_left_y = right_y + padding + group_spacing
138
141
  end
139
142
  end
140
143
 
@@ -151,9 +154,7 @@ private
151
154
  (0..number_of_lines).each do |index|
152
155
  line_diff = (@graph_right - @graph_left) / number_of_lines
153
156
  x = @graph_right - (line_diff * index) - 1
154
-
155
- Gruff::Renderer::Line.new(renderer, color: @marker_color).render(x, @graph_bottom, x, @graph_top)
156
- Gruff::Renderer::Line.new(renderer, color: @marker_shadow_color).render(x, @graph_bottom + 1, x, @graph_top + 1) if @marker_shadow_color
157
+ draw_marker_vertical_line(x)
157
158
 
158
159
  unless @hide_line_numbers
159
160
  diff = index - number_of_lines
@@ -170,11 +171,15 @@ private
170
171
 
171
172
  def draw_label(y_offset, index)
172
173
  draw_unique_label(index) do
173
- draw_label_at(@graph_left - LABEL_MARGIN, 1.0, 0.0, y_offset, @labels[index], Magick::EastGravity)
174
+ draw_label_at(@graph_left - LABEL_MARGIN, 1.0, 0.0, y_offset, @labels[index], gravity: Magick::EastGravity)
174
175
  end
175
176
  end
176
177
 
177
178
  def calculate_spacing
178
179
  @scale * @group_spacing * (column_count - 1)
179
180
  end
181
+
182
+ def proc_text_metrics
183
+ ->(text) { text_metrics(@marker_font, text) }
184
+ end
180
185
  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)
@@ -66,50 +68,43 @@ private
66
68
  #
67
69
  # Columns sit stacked.
68
70
  bar_width = @graph_height / column_count
69
- height = Array.new(column_count, 0)
70
- length = Array.new(column_count, @graph_left)
71
71
  padding = (bar_width * (1 - @bar_spacing)) / 2
72
- stack_bar_value_labels = Gruff::BarValueLabel::StackedBar.new
73
-
74
- store.norm_data.each_with_index do |data_row, row_index|
75
- data_row.points.each_with_index do |data_point, point_index|
76
- ## using the original calculations from the stacked bar chart to get the difference between
77
- ## part of the bart chart we wish to stack.
78
- temp1 = @graph_left + (@graph_width - (data_point * @graph_width) - height[point_index])
79
- temp2 = @graph_left + @graph_width - height[point_index]
80
- difference = temp2 - temp1
81
- difference = 0 if difference < 0
82
-
83
- left_x = length[point_index]
84
- left_y = @graph_top + (bar_width * point_index) + padding
85
- right_x = left_x + difference
86
- right_x -= @segment_spacing if row_index != store.columns - 1
87
- right_y = left_y + (bar_width * @bar_spacing)
88
- length[point_index] += difference
89
- height[point_index] += (data_point * @graph_width)
90
-
91
- bar_value_label = Gruff::BarValueLabel::SideBar.new([left_x, left_y, right_x, right_y], store.data[row_index].points[point_index])
92
- stack_bar_value_labels.add(bar_value_label, point_index)
93
-
94
- # if a data point is 0 it can result in weird really thing lines
95
- # that shouldn't even be there being drawn on top of the existing
96
- # bar - this is bad
97
- if data_point != 0
98
- rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: data_row.color)
99
- rect_renderer.render(left_x, left_y, right_x, right_y)
100
- # Calculate center based on bar_width and current row
101
- end
102
- # we still need to draw the labels
103
- # Calculate center based on bar_width and current row
104
- label_center = left_y + (bar_width / 2.0)
105
- 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
106
98
  end
107
- end
108
99
 
109
- if @show_labels_for_bar_values
110
- proc_text_metrics = ->(text) { text_metrics(@marker_font, text) }
111
- stack_bar_value_labels.prepare_rendering(@label_formatting, proc_text_metrics) do |x, y, text, text_width, _text_height|
112
- draw_value_label(text_width, bar_width * @bar_spacing, 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
113
108
  end
114
109
  end
115
110
  end
data/lib/gruff/spider.rb CHANGED
@@ -46,6 +46,11 @@ private
46
46
  @hide_line_markers.freeze
47
47
  end
48
48
 
49
+ def setup_drawing
50
+ @center_labels_over_point = false
51
+ super
52
+ end
53
+
49
54
  def setup_graph_measurements
50
55
  super
51
56
 
@@ -82,7 +87,7 @@ private
82
87
  end
83
88
 
84
89
  def normalize_points(value)
85
- value * @unit_length
90
+ value.to_f * @unit_length
86
91
  end
87
92
 
88
93
  def draw_label(center_x, center_y, angle, radius, amount)
@@ -107,7 +112,7 @@ private
107
112
  x = x_offset + ((radius + r_offset) * Math.cos(angle))
108
113
  y = y_offset + ((radius + r_offset) * Math.sin(angle))
109
114
 
110
- draw_label_at(metrics.width, metrics.height, x, y, amount, Magick::CenterGravity)
115
+ draw_label_at(metrics.width, metrics.height, x, y, amount, gravity: Magick::CenterGravity)
111
116
  end
112
117
 
113
118
  def draw_axes(center_x, center_y, radius, additive_angle, line_color = nil)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'helper/stacked_mixin'
4
+
3
5
  #
4
6
  # Here's how to set up a Gruff::StackedArea.
5
7
  #
@@ -35,9 +37,10 @@ private
35
37
 
36
38
  height = Array.new(column_count, 0)
37
39
 
38
- data_points = nil
40
+ prev_data_points = nil
39
41
  store.norm_data.each do |data_row|
40
- prev_data_points = data_points
42
+ next if data_row.points.empty?
43
+
41
44
  data_points = []
42
45
 
43
46
  data_row.points.each_with_index do |data_point, index|
@@ -69,6 +72,8 @@ private
69
72
  poly_points << data_points[1]
70
73
 
71
74
  Gruff::Renderer::Polygon.new(renderer, color: data_row.color).render(poly_points)
75
+
76
+ prev_data_points = data_points
72
77
  end
73
78
  end
74
79
  end