gruff 0.13.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +66 -0
  3. data/.rubocop.yml +6 -10
  4. data/.rubocop_todo.yml +19 -85
  5. data/CHANGELOG.md +10 -0
  6. data/README.md +6 -7
  7. data/gruff.gemspec +2 -4
  8. data/lib/gruff.rb +1 -0
  9. data/lib/gruff/accumulator_bar.rb +3 -1
  10. data/lib/gruff/area.rb +5 -8
  11. data/lib/gruff/bar.rb +19 -23
  12. data/lib/gruff/base.rb +134 -96
  13. data/lib/gruff/bezier.rb +4 -6
  14. data/lib/gruff/bullet.rb +11 -10
  15. data/lib/gruff/dot.rb +10 -10
  16. data/lib/gruff/font.rb +39 -0
  17. data/lib/gruff/helper/stacked_mixin.rb +1 -2
  18. data/lib/gruff/histogram.rb +9 -7
  19. data/lib/gruff/line.rb +55 -46
  20. data/lib/gruff/mini/bar.rb +9 -6
  21. data/lib/gruff/mini/legend.rb +12 -8
  22. data/lib/gruff/mini/pie.rb +9 -6
  23. data/lib/gruff/mini/side_bar.rb +9 -6
  24. data/lib/gruff/net.rb +9 -15
  25. data/lib/gruff/patch/string.rb +1 -1
  26. data/lib/gruff/pie.rb +23 -65
  27. data/lib/gruff/renderer/bezier.rb +8 -9
  28. data/lib/gruff/renderer/circle.rb +8 -9
  29. data/lib/gruff/renderer/dash_line.rb +9 -10
  30. data/lib/gruff/renderer/dot.rb +13 -14
  31. data/lib/gruff/renderer/ellipse.rb +8 -9
  32. data/lib/gruff/renderer/line.rb +8 -9
  33. data/lib/gruff/renderer/polygon.rb +9 -10
  34. data/lib/gruff/renderer/polyline.rb +8 -9
  35. data/lib/gruff/renderer/rectangle.rb +7 -8
  36. data/lib/gruff/renderer/renderer.rb +21 -36
  37. data/lib/gruff/renderer/text.rb +21 -37
  38. data/lib/gruff/scatter.rb +41 -46
  39. data/lib/gruff/scene.rb +15 -13
  40. data/lib/gruff/side_bar.rb +14 -30
  41. data/lib/gruff/side_stacked_bar.rb +8 -11
  42. data/lib/gruff/spider.rb +11 -16
  43. data/lib/gruff/stacked_area.rb +10 -11
  44. data/lib/gruff/stacked_bar.rb +9 -9
  45. data/lib/gruff/store/store.rb +6 -10
  46. data/lib/gruff/themes.rb +6 -6
  47. data/lib/gruff/version.rb +1 -1
  48. data/rails_generators/gruff/templates/controller.rb +1 -1
  49. metadata +13 -16
  50. data/.travis.yml +0 -23
  51. data/assets/plastik/blue.png +0 -0
  52. data/assets/plastik/green.png +0 -0
  53. data/assets/plastik/red.png +0 -0
  54. data/lib/gruff/photo_bar.rb +0 -93
data/lib/gruff/scene.rb CHANGED
@@ -52,7 +52,7 @@ class Gruff::Scene < Gruff::Base
52
52
  # Join all the custom paths and filter out the empty ones
53
53
  image_paths = @layers.map(&:path).reject(&:empty?)
54
54
  images = Magick::ImageList.new(*image_paths)
55
- Gruff::Renderer.background_image = images.flatten_images
55
+ renderer.background_image = images.flatten_images
56
56
  end
57
57
 
58
58
  def layers=(ordered_list)
@@ -132,18 +132,20 @@ class Gruff::Layer
132
132
 
133
133
  # Choose the appropriate filename for this layer, based on the input
134
134
  def update(value)
135
- @selected_filename = case value.to_s
136
- when /^(true|false)$/
137
- select_boolean value
138
- when /^(\w|\s)+$/
139
- select_string value
140
- when /^-?(\d+\.)?\d+$/
141
- select_numeric value
142
- when /(\d\d):(\d\d):\d\d/
143
- select_time "#{Regexp.last_match(1)}#{Regexp.last_match(2)}"
144
- else
145
- select_default
146
- end
135
+ @selected_filename = begin
136
+ case value.to_s
137
+ when /^(true|false)$/
138
+ select_boolean value
139
+ when /^(\w|\s)+$/
140
+ select_string value
141
+ when /^-?(\d+\.)?\d+$/
142
+ select_numeric value
143
+ when /(\d\d):(\d\d):\d\d/
144
+ select_time "#{Regexp.last_match(1)}#{Regexp.last_match(2)}"
145
+ else
146
+ select_default
147
+ end
148
+ end
147
149
  # Finally, try to use 'default' if we're still blank
148
150
  @selected_filename ||= select_default
149
151
  end
@@ -36,33 +36,24 @@ class Gruff::SideBar < Gruff::Base
36
36
  # Prevent drawing of column labels left of a side bar graph. Default is +false+.
37
37
  attr_writer :hide_labels
38
38
 
39
- def initialize_ivars
39
+ # With Side Bars use the data label for the marker value to the left of the bar.
40
+ # @deprecated
41
+ def use_data_label=(_value)
42
+ warn '#use_data_label is deprecated. It is no longer effective.'
43
+ end
44
+
45
+ private
46
+
47
+ def initialize_attributes
40
48
  super
41
49
  @bar_spacing = 0.9
42
50
  @group_spacing = 10
43
51
  @label_formatting = nil
44
52
  @show_labels_for_bar_values = false
45
53
  @hide_labels = false
46
- end
47
- private :initialize_ivars
48
-
49
- def draw
50
54
  @has_left_labels = true
51
- super
52
-
53
- return unless data_given?
54
-
55
- draw_bars
56
55
  end
57
56
 
58
- # With Side Bars use the data label for the marker value to the left of the bar.
59
- # @deprecated
60
- def use_data_label=(_value)
61
- warn '#use_data_label is deprecated. It is no longer effective.'
62
- end
63
-
64
- protected
65
-
66
57
  def hide_labels?
67
58
  @hide_labels
68
59
  end
@@ -75,12 +66,10 @@ protected
75
66
  @hide_line_markers
76
67
  end
77
68
 
78
- private
79
-
80
69
  # Value to avoid completely overwriting the coordinate axis
81
70
  AXIS_MARGIN = 0.5
82
71
 
83
- def draw_bars
72
+ def draw_graph
84
73
  # Setup spacing.
85
74
  #
86
75
  bars_width = (@graph_height - calculate_spacing) / column_count.to_f
@@ -93,11 +82,6 @@ private
93
82
  minimum_value: minimum_value, maximum_value: maximum_value, spread: @spread
94
83
  )
95
84
 
96
- # if we're a side stacked bar then we don't need to draw ourself at all
97
- # because sometimes (due to different heights/min/max) you can actually
98
- # see both graphs and it looks like crap
99
- return if is_a?(Gruff::SideStackedBar)
100
-
101
85
  store.norm_data.each_with_index do |data_row, row_index|
102
86
  data_row.points.each_with_index do |data_point, point_index|
103
87
  group_spacing = @group_spacing * @scale * point_index
@@ -107,7 +91,7 @@ private
107
91
 
108
92
  left_x, right_x = conversion.get_top_bottom_scaled(data_point).sort
109
93
 
110
- rect_renderer = Gruff::Renderer::Rectangle.new(color: data_row.color)
94
+ rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: data_row.color)
111
95
  rect_renderer.render(left_x + AXIS_MARGIN, left_y, right_x + AXIS_MARGIN, right_y)
112
96
 
113
97
  # Calculate center based on bar_width and current row
@@ -118,7 +102,7 @@ private
118
102
  if @show_labels_for_bar_values
119
103
  bar_value_label = Gruff::BarValueLabel::SideBar.new([left_x, left_y, right_x, right_y], store.data[row_index].points[point_index])
120
104
  bar_value_label.prepare_rendering(@label_formatting, bar_width) do |x, y, text|
121
- draw_value_label(x, y, text, true)
105
+ draw_value_label(x, y, text)
122
106
  end
123
107
  end
124
108
  end
@@ -139,14 +123,14 @@ private
139
123
  line_diff = (@graph_right - @graph_left) / number_of_lines
140
124
  x = @graph_right - (line_diff * index) - 1
141
125
 
142
- line_renderer = Gruff::Renderer::Line.new(color: @marker_color, shadow_color: @marker_shadow_color)
126
+ line_renderer = Gruff::Renderer::Line.new(renderer, color: @marker_color, shadow_color: @marker_shadow_color)
143
127
  line_renderer.render(x, @graph_bottom, x, @graph_top)
144
128
 
145
129
  unless @hide_line_numbers
146
130
  diff = index - number_of_lines
147
131
  marker_label = BigDecimal(diff.abs.to_s) * BigDecimal(increment.to_s) + BigDecimal(minimum_value.to_s)
148
132
  label = x_axis_label(marker_label, @increment)
149
- text_renderer = Gruff::Renderer::Text.new(label, font: @font, size: @marker_font_size, color: @font_color)
133
+ text_renderer = Gruff::Renderer::Text.new(renderer, label, font: @marker_font)
150
134
  text_renderer.add_to_render_queue(0, 0, x, @graph_bottom + LABEL_MARGIN, Magick::CenterGravity)
151
135
  end
152
136
  end
@@ -39,24 +39,23 @@ class Gruff::SideStackedBar < Gruff::SideBar
39
39
  # Prevent drawing of column labels left of a side stacked bar graph. Default is +false+.
40
40
  attr_writer :hide_labels
41
41
 
42
- def initialize_ivars
42
+ private
43
+
44
+ def initialize_attributes
43
45
  super
44
46
  @bar_spacing = 0.9
45
47
  @segment_spacing = 2.0
46
48
  @label_formatting = nil
47
49
  @show_labels_for_bar_values = false
48
50
  @hide_labels = false
51
+ @has_left_labels = true
49
52
  end
50
- private :initialize_ivars
51
53
 
52
- def draw
53
- @has_left_labels = true
54
+ def setup_data
54
55
  calculate_maximum_by_stack
55
56
  super
56
57
  end
57
58
 
58
- protected
59
-
60
59
  def hide_labels?
61
60
  @hide_labels
62
61
  end
@@ -69,9 +68,7 @@ protected
69
68
  @hide_line_markers
70
69
  end
71
70
 
72
- private
73
-
74
- def draw_bars
71
+ def draw_graph
75
72
  # Setup spacing.
76
73
  #
77
74
  # Columns sit stacked.
@@ -105,7 +102,7 @@ private
105
102
  # that shouldn't even be there being drawn on top of the existing
106
103
  # bar - this is bad
107
104
  if data_point != 0
108
- rect_renderer = Gruff::Renderer::Rectangle.new(color: data_row.color)
105
+ rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: data_row.color)
109
106
  rect_renderer.render(left_x, left_y, right_x, right_y)
110
107
  # Calculate center based on bar_width and current row
111
108
  end
@@ -118,7 +115,7 @@ private
118
115
 
119
116
  if @show_labels_for_bar_values
120
117
  stack_bar_value_label.prepare_rendering(@label_formatting, bar_width) do |x, y, text|
121
- draw_value_label(x, y, text, true)
118
+ draw_value_label(x, y, text)
122
119
  end
123
120
  end
124
121
  end
data/lib/gruff/spider.rb CHANGED
@@ -20,7 +20,7 @@ class Gruff::Spider < Gruff::Base
20
20
  attr_writer :rotation
21
21
 
22
22
  def transparent_background=(value)
23
- Gruff::Renderer.setup_transparent_background(@columns, @rows) if value
23
+ renderer.transparent_background(@columns, @rows) if value
24
24
  end
25
25
 
26
26
  def hide_text=(value)
@@ -32,22 +32,21 @@ class Gruff::Spider < Gruff::Base
32
32
  @max_value = max_value
33
33
  end
34
34
 
35
- def initialize_ivars
35
+ private
36
+
37
+ def initialize_attributes
36
38
  super
37
39
  @hide_legend = true
38
40
  @hide_axes = false
39
41
  @hide_text = false
40
42
  @rotation = 0
41
- end
42
- private :initialize_ivars
43
+ @marker_font.bold = true
43
44
 
44
- def draw
45
45
  @hide_line_markers = true
46
+ @hide_line_markers.freeze
47
+ end
46
48
 
47
- super
48
-
49
- return unless data_given?
50
-
49
+ def draw_graph
51
50
  # Setup basic positioning
52
51
  radius = @graph_height / 2.0
53
52
  center_x = @graph_left + (@graph_width / 2.0)
@@ -64,8 +63,6 @@ class Gruff::Spider < Gruff::Base
64
63
  draw_polygon(center_x, center_y, additive_angle)
65
64
  end
66
65
 
67
- private
68
-
69
66
  def normalize_points(value)
70
67
  value * @unit_length
71
68
  end
@@ -77,9 +74,7 @@ private
77
74
  x = x_offset + ((radius + r_offset) * Math.cos(angle))
78
75
  y = y_offset + ((radius + r_offset) * Math.sin(angle))
79
76
 
80
- # Draw label
81
- text_renderer = Gruff::Renderer::Text.new(amount, font: @font, size: @legend_font_size, color: @marker_color, weight: Magick::BoldWeight)
82
- text_renderer.add_to_render_queue(0, 0, x, y, Magick::CenterGravity)
77
+ draw_label_at(1.0, 1.0, x, y, amount, Magick::CenterGravity)
83
78
  end
84
79
 
85
80
  def draw_axes(center_x, center_y, radius, additive_angle, line_color = nil)
@@ -91,7 +86,7 @@ private
91
86
  x_offset = radius * Math.cos(current_angle)
92
87
  y_offset = radius * Math.sin(current_angle)
93
88
 
94
- Gruff::Renderer::Line.new(color: line_color || data_row.color, width: 5.0)
89
+ Gruff::Renderer::Line.new(renderer, color: line_color || data_row.color, width: 5.0)
95
90
  .render(center_x, center_y, center_x + x_offset, center_y + y_offset)
96
91
 
97
92
  draw_label(center_x, center_y, current_angle, radius, data_row.label.to_s) unless @hide_text
@@ -110,7 +105,7 @@ private
110
105
  current_angle += additive_angle
111
106
  end
112
107
 
113
- Gruff::Renderer::Polygon.new(color: color || @marker_color, opacity: 0.4).render(points)
108
+ Gruff::Renderer::Polygon.new(renderer, color: color || @marker_color, opacity: 0.4).render(points)
114
109
  end
115
110
 
116
111
  def sums_for_spider
@@ -12,27 +12,26 @@
12
12
  #
13
13
  class Gruff::StackedArea < Gruff::Base
14
14
  include StackedMixin
15
- attr_writer :last_series_goes_on_bottom
16
15
 
17
- def initialize_ivars
18
- super
19
- @last_series_goes_on_bottom = false
16
+ # @deprecated
17
+ def last_series_goes_on_bottom=(_value)
18
+ warn '#last_series_goes_on_bottom is deprecated. It is no longer effective.'
20
19
  end
21
- private :initialize_ivars
22
20
 
23
- def draw
21
+ private
22
+
23
+ def setup_data
24
24
  calculate_maximum_by_stack
25
25
  super
26
+ end
26
27
 
27
- return unless data_given?
28
-
28
+ def draw_graph
29
29
  x_increment = @graph_width / (column_count - 1).to_f
30
30
 
31
31
  height = Array.new(column_count, 0)
32
32
 
33
33
  data_points = nil
34
- iterator = @last_series_goes_on_bottom ? :reverse_each : :each
35
- store.norm_data.public_send(iterator) do |data_row|
34
+ store.norm_data.each do |data_row|
36
35
  prev_data_points = data_points
37
36
  data_points = []
38
37
 
@@ -64,7 +63,7 @@ class Gruff::StackedArea < Gruff::Base
64
63
  poly_points << data_points[0]
65
64
  poly_points << data_points[1]
66
65
 
67
- Gruff::Renderer::Polygon.new(color: data_row.color).render(poly_points)
66
+ Gruff::Renderer::Polygon.new(renderer, color: data_row.color).render(poly_points)
68
67
  end
69
68
  end
70
69
  end
@@ -30,7 +30,9 @@ class Gruff::StackedBar < Gruff::Base
30
30
  # Prevent drawing of column labels below a stacked bar graph. Default is +false+.
31
31
  attr_writer :hide_labels
32
32
 
33
- def initialize_ivars
33
+ private
34
+
35
+ def initialize_attributes
34
36
  super
35
37
  @bar_spacing = 0.9
36
38
  @segment_spacing = 2
@@ -38,14 +40,14 @@ class Gruff::StackedBar < Gruff::Base
38
40
  @show_labels_for_bar_values = false
39
41
  @hide_labels = false
40
42
  end
41
- private :initialize_ivars
42
43
 
43
- # Draws a bar graph, but multiple sets are stacked on top of each other.
44
- def draw
44
+ def setup_data
45
45
  calculate_maximum_by_stack
46
46
  super
47
- return unless data_given?
47
+ end
48
48
 
49
+ # Draws a bar graph, but multiple sets are stacked on top of each other.
50
+ def draw_graph
49
51
  # Setup spacing.
50
52
  #
51
53
  # Columns sit stacked.
@@ -70,7 +72,7 @@ class Gruff::StackedBar < Gruff::Base
70
72
  # update the total height of the current stacked bar
71
73
  height[point_index] += (data_point * @graph_height)
72
74
 
73
- rect_renderer = Gruff::Renderer::Rectangle.new(color: data_row.color)
75
+ rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: data_row.color)
74
76
  rect_renderer.render(left_x, left_y, right_x, right_y)
75
77
 
76
78
  # Calculate center based on bar_width and current row
@@ -84,13 +86,11 @@ class Gruff::StackedBar < Gruff::Base
84
86
 
85
87
  if @show_labels_for_bar_values
86
88
  stack_bar_value_label.prepare_rendering(@label_formatting, bar_width) do |x, y, text|
87
- draw_value_label(x, y, text, true)
89
+ draw_value_label(x, y, text)
88
90
  end
89
91
  end
90
92
  end
91
93
 
92
- protected
93
-
94
94
  def hide_labels?
95
95
  @hide_labels
96
96
  end
@@ -3,27 +3,23 @@
3
3
  module Gruff
4
4
  # @private
5
5
  class Store
6
- attr_reader :data, :norm_data
6
+ attr_reader :data
7
7
 
8
8
  def initialize(data_class)
9
9
  @data_class = data_class
10
10
  @data = []
11
- @norm_data = []
12
- @normalized = false
13
11
  end
14
12
 
15
13
  def add(*args)
16
14
  @data << @data_class.new(*args)
17
15
  end
18
16
 
19
- def normalize(**keywords)
20
- unless @normalized
21
- @data.each do |data_row|
22
- @norm_data << data_row.normalize(**keywords)
23
- end
17
+ def norm_data
18
+ @norm_data || []
19
+ end
24
20
 
25
- @normalized = true
26
- end
21
+ def normalize(**keywords)
22
+ @norm_data = @data.map { |data_row| data_row.normalize(**keywords) }
27
23
  end
28
24
 
29
25
  def empty?
data/lib/gruff/themes.rb CHANGED
@@ -16,7 +16,7 @@ module Gruff
16
16
  marker_color: 'white',
17
17
  font_color: 'white',
18
18
  background_colors: %w[black #4a465a]
19
- }
19
+ }.freeze
20
20
 
21
21
  # A color scheme plucked from the colors on the popular usability blog.
22
22
  THIRTYSEVEN_SIGNALS = {
@@ -32,7 +32,7 @@ module Gruff
32
32
  marker_color: 'black',
33
33
  font_color: 'black',
34
34
  background_colors: %w[#d1edf5 white]
35
- }
35
+ }.freeze
36
36
 
37
37
  # A color scheme from the colors used on the 2005 Rails keynote
38
38
  # presentation at RubyConf.
@@ -49,7 +49,7 @@ module Gruff
49
49
  marker_color: 'white',
50
50
  font_color: 'white',
51
51
  background_colors: %w[#0083a3 #0083a3]
52
- }
52
+ }.freeze
53
53
 
54
54
  # A color scheme similar to that used on the popular podcast site.
55
55
  ODEO = {
@@ -65,7 +65,7 @@ module Gruff
65
65
  marker_color: 'white',
66
66
  font_color: 'white',
67
67
  background_colors: %w[#ff47a4 #ff1f81]
68
- }
68
+ }.freeze
69
69
 
70
70
  # A pastel theme
71
71
  PASTEL = {
@@ -81,7 +81,7 @@ module Gruff
81
81
  marker_color: '#aea9a9', # Grey
82
82
  font_color: 'black',
83
83
  background_colors: 'white'
84
- }
84
+ }.freeze
85
85
 
86
86
  # A greyscale theme
87
87
  GREYSCALE = {
@@ -96,6 +96,6 @@ module Gruff
96
96
  marker_color: '#aea9a9', # Grey
97
97
  font_color: 'black',
98
98
  background_colors: 'white'
99
- }
99
+ }.freeze
100
100
  end
101
101
  end