gruff 0.11.0-java → 0.14.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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +66 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +24 -8
  5. data/.rubocop_todo.yml +57 -53
  6. data/CHANGELOG.md +34 -0
  7. data/README.md +15 -7
  8. data/assets/fonts/LICENSE.txt +202 -0
  9. data/assets/fonts/Roboto-Bold.ttf +0 -0
  10. data/assets/fonts/Roboto-Regular.ttf +0 -0
  11. data/gruff.gemspec +8 -5
  12. data/lib/gruff.rb +9 -3
  13. data/lib/gruff/accumulator_bar.rb +3 -3
  14. data/lib/gruff/area.rb +5 -12
  15. data/lib/gruff/bar.rb +43 -47
  16. data/lib/gruff/base.rb +267 -146
  17. data/lib/gruff/bezier.rb +4 -10
  18. data/lib/gruff/bullet.rb +13 -19
  19. data/lib/gruff/dot.rb +14 -19
  20. data/lib/gruff/font.rb +39 -0
  21. data/lib/gruff/helper/bar_conversion.rb +28 -13
  22. data/lib/gruff/helper/bar_value_label.rb +68 -0
  23. data/lib/gruff/helper/stacked_mixin.rb +1 -2
  24. data/lib/gruff/histogram.rb +9 -8
  25. data/lib/gruff/line.rb +59 -56
  26. data/lib/gruff/mini/bar.rb +10 -7
  27. data/lib/gruff/mini/legend.rb +19 -10
  28. data/lib/gruff/mini/pie.rb +10 -8
  29. data/lib/gruff/mini/side_bar.rb +10 -8
  30. data/lib/gruff/net.rb +13 -20
  31. data/lib/gruff/patch/rmagick.rb +22 -24
  32. data/lib/gruff/patch/string.rb +7 -4
  33. data/lib/gruff/pie.rb +24 -70
  34. data/lib/gruff/renderer/bezier.rb +11 -11
  35. data/lib/gruff/renderer/circle.rb +11 -11
  36. data/lib/gruff/renderer/dash_line.rb +12 -12
  37. data/lib/gruff/renderer/dot.rb +16 -16
  38. data/lib/gruff/renderer/ellipse.rb +11 -11
  39. data/lib/gruff/renderer/line.rb +12 -12
  40. data/lib/gruff/renderer/polygon.rb +13 -13
  41. data/lib/gruff/renderer/polyline.rb +11 -11
  42. data/lib/gruff/renderer/rectangle.rb +9 -9
  43. data/lib/gruff/renderer/renderer.rb +23 -50
  44. data/lib/gruff/renderer/text.rb +32 -29
  45. data/lib/gruff/scatter.rb +52 -76
  46. data/lib/gruff/scene.rb +15 -14
  47. data/lib/gruff/side_bar.rb +49 -52
  48. data/lib/gruff/side_stacked_bar.rb +29 -20
  49. data/lib/gruff/spider.rb +13 -22
  50. data/lib/gruff/stacked_area.rb +10 -16
  51. data/lib/gruff/stacked_bar.rb +29 -18
  52. data/lib/gruff/store/{base_data.rb → basic_data.rb} +5 -7
  53. data/lib/gruff/store/custom_data.rb +4 -6
  54. data/lib/gruff/store/store.rb +9 -12
  55. data/lib/gruff/store/xy_data.rb +6 -7
  56. data/lib/gruff/themes.rb +6 -6
  57. data/lib/gruff/version.rb +1 -1
  58. data/rails_generators/gruff/templates/controller.rb +1 -1
  59. metadata +24 -14
  60. data/.travis.yml +0 -26
  61. data/Rakefile +0 -47
  62. data/assets/plastik/blue.png +0 -0
  63. data/assets/plastik/green.png +0 -0
  64. data/assets/plastik/red.png +0 -0
  65. data/docker/Dockerfile +0 -14
  66. data/docker/build.sh +0 -4
  67. data/docker/launch.sh +0 -4
  68. data/lib/gruff/helper/bar_value_label_mixin.rb +0 -30
  69. data/lib/gruff/photo_bar.rb +0 -97
data/lib/gruff/spider.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'gruff/base'
4
-
5
3
  # Experimental!!! See also the Net graph.
6
4
  #
7
5
  # Here's how to set up a Gruff::Spider.
@@ -15,14 +13,14 @@ require 'gruff/base'
15
13
  # g.data :Wisdom, [10]
16
14
  # g.data 'Charisma', [16]
17
15
  # g.write("spider.png")
18
-
16
+ #
19
17
  class Gruff::Spider < Gruff::Base
20
18
  # Hide all text.
21
19
  attr_writer :hide_axes
22
20
  attr_writer :rotation
23
21
 
24
22
  def transparent_background=(value)
25
- Gruff::Renderer.setup_transparent_background(@columns, @rows) if value
23
+ renderer.transparent_background(@columns, @rows) if value
26
24
  end
27
25
 
28
26
  def hide_text=(value)
@@ -34,22 +32,21 @@ class Gruff::Spider < Gruff::Base
34
32
  @max_value = max_value
35
33
  end
36
34
 
37
- def initialize_ivars
35
+ private
36
+
37
+ def initialize_attributes
38
38
  super
39
39
  @hide_legend = true
40
40
  @hide_axes = false
41
41
  @hide_text = false
42
42
  @rotation = 0
43
- end
44
- private :initialize_ivars
43
+ @marker_font.bold = true
45
44
 
46
- def draw
47
45
  @hide_line_markers = true
46
+ @hide_line_markers.freeze
47
+ end
48
48
 
49
- super
50
-
51
- return unless data_given?
52
-
49
+ def draw_graph
53
50
  # Setup basic positioning
54
51
  radius = @graph_height / 2.0
55
52
  center_x = @graph_left + (@graph_width / 2.0)
@@ -64,12 +61,8 @@ class Gruff::Spider < Gruff::Base
64
61
 
65
62
  # Draw polygon
66
63
  draw_polygon(center_x, center_y, additive_angle)
67
-
68
- Gruff::Renderer.finish
69
64
  end
70
65
 
71
- private
72
-
73
66
  def normalize_points(value)
74
67
  value * @unit_length
75
68
  end
@@ -81,9 +74,7 @@ private
81
74
  x = x_offset + ((radius + r_offset) * Math.cos(angle))
82
75
  y = y_offset + ((radius + r_offset) * Math.sin(angle))
83
76
 
84
- # Draw label
85
- text_renderer = Gruff::Renderer::Text.new(amount, font: @font, size: @legend_font_size, color: @marker_color, weight: Magick::BoldWeight)
86
- 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)
87
78
  end
88
79
 
89
80
  def draw_axes(center_x, center_y, radius, additive_angle, line_color = nil)
@@ -95,7 +86,7 @@ private
95
86
  x_offset = radius * Math.cos(current_angle)
96
87
  y_offset = radius * Math.sin(current_angle)
97
88
 
98
- 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)
99
90
  .render(center_x, center_y, center_x + x_offset, center_y + y_offset)
100
91
 
101
92
  draw_label(center_x, center_y, current_angle, radius, data_row.label.to_s) unless @hide_text
@@ -114,10 +105,10 @@ private
114
105
  current_angle += additive_angle
115
106
  end
116
107
 
117
- 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)
118
109
  end
119
110
 
120
111
  def sums_for_spider
121
- store.data.reduce(0.0) { |sum, data_row| sum + data_row.points.first }
112
+ store.data.sum { |data_row| data_row.points.first }
122
113
  end
123
114
  end
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'gruff/base'
4
- require 'gruff/helper/stacked_mixin'
5
-
6
3
  #
7
4
  # Here's how to set up a Gruff::StackedArea.
8
5
  #
@@ -15,27 +12,26 @@ require 'gruff/helper/stacked_mixin'
15
12
  #
16
13
  class Gruff::StackedArea < Gruff::Base
17
14
  include StackedMixin
18
- attr_writer :last_series_goes_on_bottom
19
15
 
20
- def initialize_ivars
21
- super
22
- @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.'
23
19
  end
24
- private :initialize_ivars
25
20
 
26
- def draw
21
+ private
22
+
23
+ def setup_data
27
24
  calculate_maximum_by_stack
28
25
  super
26
+ end
29
27
 
30
- return unless data_given?
31
-
28
+ def draw_graph
32
29
  x_increment = @graph_width / (column_count - 1).to_f
33
30
 
34
31
  height = Array.new(column_count, 0)
35
32
 
36
33
  data_points = nil
37
- iterator = @last_series_goes_on_bottom ? :reverse_each : :each
38
- store.norm_data.public_send(iterator) do |data_row|
34
+ store.norm_data.each do |data_row|
39
35
  prev_data_points = data_points
40
36
  data_points = []
41
37
 
@@ -67,9 +63,7 @@ class Gruff::StackedArea < Gruff::Base
67
63
  poly_points << data_points[0]
68
64
  poly_points << data_points[1]
69
65
 
70
- Gruff::Renderer::Polygon.new(color: data_row.color).render(poly_points)
66
+ Gruff::Renderer::Polygon.new(renderer, color: data_row.color).render(poly_points)
71
67
  end
72
-
73
- Gruff::Renderer.finish
74
68
  end
75
69
  end
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'gruff/base'
4
- require 'gruff/helper/stacked_mixin'
5
- require 'gruff/helper/bar_value_label_mixin'
6
-
7
3
  #
8
4
  # Here's how to set up a Gruff::StackedBar.
9
5
  #
@@ -16,7 +12,6 @@ require 'gruff/helper/bar_value_label_mixin'
16
12
  #
17
13
  class Gruff::StackedBar < Gruff::Base
18
14
  include StackedMixin
19
- include BarValueLabelMixin
20
15
 
21
16
  # Spacing factor applied between bars.
22
17
  attr_writer :bar_spacing
@@ -24,7 +19,7 @@ class Gruff::StackedBar < Gruff::Base
24
19
  # Number of pixels between bar segments.
25
20
  attr_writer :segment_spacing
26
21
 
27
- # Set the number output format for labels using sprintf.
22
+ # Set the number output format string or lambda.
28
23
  # Default is +"%.2f"+.
29
24
  attr_writer :label_formatting
30
25
 
@@ -32,21 +27,27 @@ class Gruff::StackedBar < Gruff::Base
32
27
  # Default is +false+.
33
28
  attr_writer :show_labels_for_bar_values
34
29
 
35
- def initialize_ivars
30
+ # Prevent drawing of column labels below a stacked bar graph. Default is +false+.
31
+ attr_writer :hide_labels
32
+
33
+ private
34
+
35
+ def initialize_attributes
36
36
  super
37
37
  @bar_spacing = 0.9
38
38
  @segment_spacing = 2
39
39
  @label_formatting = nil
40
40
  @show_labels_for_bar_values = false
41
+ @hide_labels = false
41
42
  end
42
- private :initialize_ivars
43
43
 
44
- # Draws a bar graph, but multiple sets are stacked on top of each other.
45
- def draw
44
+ def setup_data
46
45
  calculate_maximum_by_stack
47
46
  super
48
- return unless data_given?
47
+ end
49
48
 
49
+ # Draws a bar graph, but multiple sets are stacked on top of each other.
50
+ def draw_graph
50
51
  # Setup spacing.
51
52
  #
52
53
  # Columns sit stacked.
@@ -54,7 +55,7 @@ class Gruff::StackedBar < Gruff::Base
54
55
  padding = (bar_width * (1 - @bar_spacing)) / 2
55
56
 
56
57
  height = Array.new(column_count, 0)
57
- bar_value_label = BarValueLabel.new(column_count, bar_width)
58
+ stack_bar_value_label = Gruff::BarValueLabel::StackedBar.new
58
59
 
59
60
  store.norm_data.each_with_index do |data_row, row_index|
60
61
  data_row.points.each_with_index do |data_point, point_index|
@@ -71,24 +72,34 @@ class Gruff::StackedBar < Gruff::Base
71
72
  # update the total height of the current stacked bar
72
73
  height[point_index] += (data_point * @graph_height)
73
74
 
74
- rect_renderer = Gruff::Renderer::Rectangle.new(color: data_row.color)
75
+ rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: data_row.color)
75
76
  rect_renderer.render(left_x, left_y, right_x, right_y)
76
77
 
77
78
  # Calculate center based on bar_width and current row
78
79
  label_center = left_x + bar_width * @bar_spacing / 2.0
79
80
  draw_label(label_center, point_index)
80
81
 
81
- bar_value_label.coordinates[point_index] = [left_x, left_y, right_x, right_y]
82
- bar_value_label.values[point_index] += store.data[row_index].points[point_index]
82
+ bar_value_label = Gruff::BarValueLabel::Bar.new([left_x, left_y, right_x, right_y], store.data[row_index].points[point_index])
83
+ stack_bar_value_label.add(bar_value_label, point_index)
83
84
  end
84
85
  end
85
86
 
86
87
  if @show_labels_for_bar_values
87
- bar_value_label.prepare_rendering(@label_formatting) do |x, y, text|
88
- draw_value_label(x, y, text, true)
88
+ stack_bar_value_label.prepare_rendering(@label_formatting, bar_width) do |x, y, text|
89
+ draw_value_label(x, y, text)
89
90
  end
90
91
  end
92
+ end
93
+
94
+ def hide_labels?
95
+ @hide_labels
96
+ end
97
+
98
+ def hide_left_label_area?
99
+ @hide_line_markers
100
+ end
91
101
 
92
- Gruff::Renderer.finish
102
+ def hide_bottom_label_area?
103
+ hide_labels?
93
104
  end
94
105
  end
@@ -1,13 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Gruff
4
- # @private
5
4
  class Store
6
- class BaseData < Struct.new(:label, :points, :color)
5
+ # @private
6
+ class BasicData < Struct.new(:label, :points, :color)
7
7
  def initialize(label, points, color)
8
- self.label = label.to_s
9
- self.points = Array(points)
10
- self.color = color
8
+ super(label.to_s, Array(points), color)
11
9
  end
12
10
 
13
11
  def empty?
@@ -26,9 +24,9 @@ module Gruff
26
24
  points.compact.max
27
25
  end
28
26
 
29
- def normalize(args = {})
27
+ def normalize(minimum:, spread:)
30
28
  norm_points = points.map do |point|
31
- point.nil? ? nil : (point.to_f - args[:minimum].to_f) / args[:spread]
29
+ point.nil? ? nil : (point.to_f - minimum.to_f) / spread
32
30
  end
33
31
 
34
32
  self.class.new(label, norm_points, color)
@@ -2,12 +2,10 @@
2
2
 
3
3
  module Gruff
4
4
  class Store
5
+ # @private
5
6
  class CustomData < Struct.new(:label, :points, :color, :custom)
6
7
  def initialize(label, points, color, custom = nil)
7
- self.label = label.to_s
8
- self.points = Array(points)
9
- self.color = color
10
- self.custom = custom
8
+ super(label.to_s, Array(points), color, custom)
11
9
  end
12
10
 
13
11
  def empty?
@@ -26,9 +24,9 @@ module Gruff
26
24
  points.compact.max
27
25
  end
28
26
 
29
- def normalize(args = {})
27
+ def normalize(minimum:, spread:)
30
28
  norm_points = points.map do |point|
31
- point.nil? ? nil : (point.to_f - args[:minimum].to_f) / args[:spread]
29
+ point.nil? ? nil : (point.to_f - minimum.to_f) / spread
32
30
  end
33
31
 
34
32
  self.class.new(label, norm_points, color, custom)
@@ -1,28 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Gruff
4
+ # @private
4
5
  class Store
5
- attr_reader :data, :norm_data
6
+ attr_reader :data
6
7
 
7
8
  def initialize(data_class)
8
9
  @data_class = data_class
9
10
  @data = []
10
- @norm_data = []
11
- @normalized = false
12
11
  end
13
12
 
14
13
  def add(*args)
15
14
  @data << @data_class.new(*args)
16
15
  end
17
16
 
18
- def normalize(args = {})
19
- unless @normalized
20
- @data.each do |data_row|
21
- @norm_data << data_row.normalize(args)
22
- end
17
+ def norm_data
18
+ @norm_data || []
19
+ end
23
20
 
24
- @normalized = true
25
- end
21
+ def normalize(**keywords)
22
+ @norm_data = @data.map { |data_row| data_row.normalize(**keywords) }
26
23
  end
27
24
 
28
25
  def empty?
@@ -56,11 +53,11 @@ module Gruff
56
53
  end
57
54
 
58
55
  def sort_data!
59
- @data = @data.sort_by { |a| -a.points.reduce(0) { |acc, elem| acc + elem.to_f } }
56
+ @data = @data.sort_by { |a| -a.points.sum(&:to_f) }
60
57
  end
61
58
 
62
59
  def sort_norm_data!
63
- @norm_data = @norm_data.sort_by { |a| -a.points.reduce(0) { |acc, elem| acc + elem.to_f } }
60
+ @norm_data = @norm_data.sort_by { |a| -a.points.sum(&:to_f) }
64
61
  end
65
62
 
66
63
  def reverse!
@@ -2,12 +2,11 @@
2
2
 
3
3
  module Gruff
4
4
  class Store
5
+ # @private
5
6
  class XYData < Struct.new(:label, :y_points, :color, :x_points)
6
7
  def initialize(label, y_points, color, x_points = nil)
7
- self.label = label.to_s
8
- self.y_points = Array(y_points)
9
- self.color = color
10
- self.x_points = Array(x_points) if x_points
8
+ x_points = Array(x_points) if x_points
9
+ super(label.to_s, Array(y_points), color, x_points)
11
10
  end
12
11
 
13
12
  def x_points
@@ -44,12 +43,12 @@ module Gruff
44
43
  x_points.compact.max
45
44
  end
46
45
 
47
- def normalize(args = {})
46
+ def normalize(minimum_x:, minimum_y:, spread_x:, spread_y:)
48
47
  norm_x_points = x_points.map do |x|
49
- x.nil? ? nil : (x.to_f - args[:minimum_x].to_f) / args[:spread_x]
48
+ x.nil? ? nil : (x.to_f - minimum_x.to_f) / spread_x
50
49
  end
51
50
  norm_y_points = y_points.map do |y|
52
- y.nil? ? nil : (y.to_f - args[:minimum_y].to_f) / args[:spread_y]
51
+ y.nil? ? nil : (y.to_f - minimum_y.to_f) / spread_y
53
52
  end
54
53
 
55
54
  self.class.new(label, norm_y_points, color, norm_x_points)
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