gruff 0.9.0-java → 0.12.2-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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +21 -4
  3. data/.rubocop_todo.yml +103 -49
  4. data/.travis.yml +3 -6
  5. data/CHANGELOG.md +30 -0
  6. data/README.md +4 -0
  7. data/gruff.gemspec +8 -3
  8. data/lib/gruff.rb +9 -3
  9. data/lib/gruff/accumulator_bar.rb +13 -5
  10. data/lib/gruff/area.rb +22 -5
  11. data/lib/gruff/bar.rb +38 -10
  12. data/lib/gruff/base.rb +325 -236
  13. data/lib/gruff/bezier.rb +18 -4
  14. data/lib/gruff/bullet.rb +22 -14
  15. data/lib/gruff/dot.rb +20 -33
  16. data/lib/gruff/helper/bar_conversion.rb +7 -7
  17. data/lib/gruff/helper/bar_value_label_mixin.rb +3 -0
  18. data/lib/gruff/helper/stacked_mixin.rb +1 -1
  19. data/lib/gruff/histogram.rb +59 -0
  20. data/lib/gruff/line.rb +33 -28
  21. data/lib/gruff/mini/bar.rb +10 -2
  22. data/lib/gruff/mini/legend.rb +9 -4
  23. data/lib/gruff/mini/pie.rb +9 -3
  24. data/lib/gruff/mini/side_bar.rb +18 -4
  25. data/lib/gruff/net.rb +41 -21
  26. data/lib/gruff/patch/rmagick.rb +22 -24
  27. data/lib/gruff/patch/string.rb +9 -4
  28. data/lib/gruff/photo_bar.rb +12 -16
  29. data/lib/gruff/pie.rb +24 -34
  30. data/lib/gruff/renderer/bezier.rb +4 -3
  31. data/lib/gruff/renderer/circle.rb +4 -3
  32. data/lib/gruff/renderer/dash_line.rb +4 -3
  33. data/lib/gruff/renderer/dot.rb +4 -3
  34. data/lib/gruff/renderer/ellipse.rb +4 -3
  35. data/lib/gruff/renderer/line.rb +14 -5
  36. data/lib/gruff/renderer/polygon.rb +5 -4
  37. data/lib/gruff/renderer/polyline.rb +4 -3
  38. data/lib/gruff/renderer/rectangle.rb +3 -2
  39. data/lib/gruff/renderer/renderer.rb +31 -38
  40. data/lib/gruff/renderer/text.rb +29 -7
  41. data/lib/gruff/scatter.rb +26 -24
  42. data/lib/gruff/scene.rb +0 -1
  43. data/lib/gruff/side_bar.rb +51 -20
  44. data/lib/gruff/side_stacked_bar.rb +42 -15
  45. data/lib/gruff/spider.rb +29 -17
  46. data/lib/gruff/stacked_area.rb +19 -8
  47. data/lib/gruff/stacked_bar.rb +34 -13
  48. data/lib/gruff/store/{base_data.rb → basic_data.rb} +9 -7
  49. data/lib/gruff/store/custom_data.rb +8 -6
  50. data/lib/gruff/store/store.rb +7 -6
  51. data/lib/gruff/store/xy_data.rb +10 -7
  52. data/lib/gruff/version.rb +1 -1
  53. metadata +33 -8
  54. data/Rakefile +0 -23
  55. data/docker/Dockerfile +0 -14
  56. data/docker/build.sh +0 -4
  57. data/docker/launch.sh +0 -4
@@ -1,52 +1,81 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'gruff/side_bar'
4
- require 'gruff/helper/stacked_mixin'
5
-
3
+ #
6
4
  # New gruff graph type added to enable sideways stacking bar charts
7
5
  # (basically looks like a x/y flip of a standard stacking bar chart)
8
6
  #
9
- # alun.eyre@googlemail.com
7
+ # Here's how to set up a Gruff::SideStackedBar.
8
+ #
9
+ # g = Gruff::SideStackedBar.new
10
+ # g.title = 'SideStackedBar Graph'
11
+ # g.labels = {
12
+ # 0 => '5/6',
13
+ # 1 => '5/15',
14
+ # 2 => '5/24',
15
+ # 3 => '5/30',
16
+ # }
17
+ # g.data :Art, [0, 5, 8, 15]
18
+ # g.data :Philosophy, [10, 3, 2, 8]
19
+ # g.data :Science, [2, 15, 8, 11]
20
+ # g.write('side_stacked_bar.png')
21
+ #
10
22
  class Gruff::SideStackedBar < Gruff::SideBar
11
23
  include StackedMixin
12
24
  include BarValueLabelMixin
13
25
 
14
26
  # Spacing factor applied between bars.
15
- attr_accessor :bar_spacing
27
+ attr_writer :bar_spacing
16
28
 
17
29
  # Number of pixels between bar segments.
18
- attr_accessor :segment_spacing
30
+ attr_writer :segment_spacing
19
31
 
20
32
  # Set the number output format for labels using sprintf.
21
33
  # Default is +"%.2f"+.
22
- attr_accessor :label_formatting
34
+ attr_writer :label_formatting
23
35
 
24
36
  # Output the values for the bars on a bar graph.
25
37
  # Default is +false+.
26
- attr_accessor :show_labels_for_bar_values
38
+ attr_writer :show_labels_for_bar_values
39
+
40
+ # Prevent drawing of column labels left of a side stacked bar graph. Default is +false+.
41
+ attr_writer :hide_labels
27
42
 
28
43
  def initialize_ivars
29
44
  super
45
+ @bar_spacing = 0.9
46
+ @segment_spacing = 2.0
30
47
  @label_formatting = nil
31
48
  @show_labels_for_bar_values = false
49
+ @hide_labels = false
32
50
  end
33
51
  private :initialize_ivars
34
52
 
35
53
  def draw
36
54
  @has_left_labels = true
37
- get_maximum_by_stack
55
+ calculate_maximum_by_stack
38
56
  super
39
57
  end
40
58
 
59
+ protected
60
+
61
+ def hide_labels?
62
+ @hide_labels
63
+ end
64
+
65
+ def hide_left_label_area?
66
+ hide_labels?
67
+ end
68
+
69
+ def hide_bottom_label_area?
70
+ @hide_line_markers
71
+ end
72
+
41
73
  private
42
74
 
43
75
  def draw_bars
44
76
  # Setup spacing.
45
77
  #
46
78
  # Columns sit stacked.
47
- @bar_spacing ||= 0.9
48
- @segment_spacing ||= 2.0
49
-
50
79
  bar_width = @graph_height / column_count.to_f
51
80
  height = Array.new(column_count, 0)
52
81
  length = Array.new(column_count, @graph_left)
@@ -55,7 +84,7 @@ private
55
84
 
56
85
  store.norm_data.each_with_index do |data_row, row_index|
57
86
  data_row.points.each_with_index do |data_point, point_index|
58
- ## using the original calcs from the stacked bar chart to get the difference between
87
+ ## using the original calculations from the stacked bar chart to get the difference between
59
88
  ## part of the bart chart we wish to stack.
60
89
  temp1 = @graph_left + (@graph_width -
61
90
  data_point * @graph_width -
@@ -93,7 +122,5 @@ private
93
122
  draw_value_label(x, y, text, true)
94
123
  end
95
124
  end
96
-
97
- Gruff::Renderer.finish
98
125
  end
99
126
  end
data/lib/gruff/spider.rb CHANGED
@@ -1,16 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'gruff/base'
4
-
5
3
  # Experimental!!! See also the Net graph.
6
4
  #
7
- # Submitted by Kevin Clark http://glu.ttono.us/
5
+ # Here's how to set up a Gruff::Spider.
6
+ #
7
+ # g = Gruff::Spider.new(30)
8
+ # g.title = "Spider Graph"
9
+ # g.data :Strength, [10]
10
+ # g.data :Dexterity, [16]
11
+ # g.data :Constitution, [12]
12
+ # g.data :Intelligence, [12]
13
+ # g.data :Wisdom, [10]
14
+ # g.data 'Charisma', [16]
15
+ # g.write("spider.png")
16
+ #
8
17
  class Gruff::Spider < Gruff::Base
9
18
  # Hide all text.
10
- attr_reader :hide_text
11
- attr_accessor :hide_axes
12
- attr_reader :transparent_background
13
- attr_accessor :rotation
19
+ attr_writer :hide_axes
20
+ attr_writer :rotation
14
21
 
15
22
  def transparent_background=(value)
16
23
  Gruff::Renderer.setup_transparent_background(@columns, @rows) if value
@@ -23,9 +30,16 @@ class Gruff::Spider < Gruff::Base
23
30
  def initialize(max_value, target_width = 800)
24
31
  super(target_width)
25
32
  @max_value = max_value
33
+ end
34
+
35
+ def initialize_ivars
36
+ super
26
37
  @hide_legend = true
38
+ @hide_axes = false
39
+ @hide_text = false
27
40
  @rotation = 0
28
41
  end
42
+ private :initialize_ivars
29
43
 
30
44
  def draw
31
45
  @hide_line_markers = true
@@ -44,12 +58,10 @@ class Gruff::Spider < Gruff::Base
44
58
  additive_angle = (2 * Math::PI) / store.length
45
59
 
46
60
  # Draw axes
47
- draw_axes(center_x, center_y, radius, additive_angle) unless hide_axes
61
+ draw_axes(center_x, center_y, radius, additive_angle) unless @hide_axes
48
62
 
49
63
  # Draw polygon
50
64
  draw_polygon(center_x, center_y, additive_angle)
51
-
52
- Gruff::Renderer.finish
53
65
  end
54
66
 
55
67
  private
@@ -66,14 +78,14 @@ private
66
78
  y = y_offset + ((radius + r_offset) * Math.sin(angle))
67
79
 
68
80
  # Draw label
69
- text_renderer = Gruff::Renderer::Text.new(amount, font: @font, size: legend_font_size, color: @marker_color, weight: Magick::BoldWeight)
70
- text_renderer.render(0, 0, x, y, Magick::CenterGravity)
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)
71
83
  end
72
84
 
73
85
  def draw_axes(center_x, center_y, radius, additive_angle, line_color = nil)
74
- return if hide_axes
86
+ return if @hide_axes
75
87
 
76
- current_angle = rotation * Math::PI / 180.0
88
+ current_angle = @rotation * Math::PI / 180.0
77
89
 
78
90
  store.data.each do |data_row|
79
91
  x_offset = radius * Math.cos(current_angle)
@@ -82,7 +94,7 @@ private
82
94
  Gruff::Renderer::Line.new(color: line_color || data_row.color, width: 5.0)
83
95
  .render(center_x, center_y, center_x + x_offset, center_y + y_offset)
84
96
 
85
- draw_label(center_x, center_y, current_angle, radius, data_row.label.to_s) unless hide_text
97
+ draw_label(center_x, center_y, current_angle, radius, data_row.label.to_s) unless @hide_text
86
98
 
87
99
  current_angle += additive_angle
88
100
  end
@@ -90,7 +102,7 @@ private
90
102
 
91
103
  def draw_polygon(center_x, center_y, additive_angle, color = nil)
92
104
  points = []
93
- current_angle = rotation * Math::PI / 180.0
105
+ current_angle = @rotation * Math::PI / 180.0
94
106
 
95
107
  store.data.each do |data_row|
96
108
  points << center_x + normalize_points(data_row.points.first) * Math.cos(current_angle)
@@ -102,6 +114,6 @@ private
102
114
  end
103
115
 
104
116
  def sums_for_spider
105
- store.data.reduce(0.0) { |sum, data_row| sum + data_row.points.first }
117
+ store.data.sum { |data_row| data_row.points.first }
106
118
  end
107
119
  end
@@ -1,14 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'gruff/base'
4
- require 'gruff/helper/stacked_mixin'
5
-
3
+ #
4
+ # Here's how to set up a Gruff::StackedArea.
5
+ #
6
+ # g = Gruff::StackedArea.new
7
+ # g.title = 'StackedArea Graph'
8
+ # g.data :Jimmy, [25, 36, 86, 39, 25, 31, 79, 88]
9
+ # g.data :Charles, [80, 54, 67, 54, 68, 70, 90, 95]
10
+ # g.data :Julie, [22, 29, 35, 38, 36, 40, 46, 57]
11
+ # g.write('stacked_area.png')
12
+ #
6
13
  class Gruff::StackedArea < Gruff::Base
7
14
  include StackedMixin
8
- attr_accessor :last_series_goes_on_bottom
15
+ attr_writer :last_series_goes_on_bottom
16
+
17
+ def initialize_ivars
18
+ super
19
+ @last_series_goes_on_bottom = false
20
+ end
21
+ private :initialize_ivars
9
22
 
10
23
  def draw
11
- get_maximum_by_stack
24
+ calculate_maximum_by_stack
12
25
  super
13
26
 
14
27
  return unless data_given?
@@ -18,7 +31,7 @@ class Gruff::StackedArea < Gruff::Base
18
31
  height = Array.new(column_count, 0)
19
32
 
20
33
  data_points = nil
21
- iterator = last_series_goes_on_bottom ? :reverse_each : :each
34
+ iterator = @last_series_goes_on_bottom ? :reverse_each : :each
22
35
  store.norm_data.public_send(iterator) do |data_row|
23
36
  prev_data_points = data_points
24
37
  data_points = []
@@ -53,7 +66,5 @@ class Gruff::StackedArea < Gruff::Base
53
66
 
54
67
  Gruff::Renderer::Polygon.new(color: data_row.color).render(poly_points)
55
68
  end
56
-
57
- Gruff::Renderer.finish
58
69
  end
59
70
  end
@@ -1,46 +1,55 @@
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
-
3
+ #
4
+ # Here's how to set up a Gruff::StackedBar.
5
+ #
6
+ # g = Gruff::StackedBar.new
7
+ # g.title = 'StackedBar Graph'
8
+ # g.data :Art, [0, 5, 8, 15]
9
+ # g.data :Philosophy, [10, 3, 2, 8]
10
+ # g.data :Science, [2, 15, 8, 11]
11
+ # g.write('stacked_bar.png')
12
+ #
7
13
  class Gruff::StackedBar < Gruff::Base
8
14
  include StackedMixin
9
15
  include BarValueLabelMixin
10
16
 
11
17
  # Spacing factor applied between bars.
12
- attr_accessor :bar_spacing
18
+ attr_writer :bar_spacing
13
19
 
14
20
  # Number of pixels between bar segments.
15
- attr_accessor :segment_spacing
21
+ attr_writer :segment_spacing
16
22
 
17
23
  # Set the number output format for labels using sprintf.
18
24
  # Default is +"%.2f"+.
19
- attr_accessor :label_formatting
25
+ attr_writer :label_formatting
20
26
 
21
27
  # Output the values for the bars on a bar graph.
22
28
  # Default is +false+.
23
- attr_accessor :show_labels_for_bar_values
29
+ attr_writer :show_labels_for_bar_values
30
+
31
+ # Prevent drawing of column labels below a stacked bar graph. Default is +false+.
32
+ attr_writer :hide_labels
24
33
 
25
34
  def initialize_ivars
26
35
  super
36
+ @bar_spacing = 0.9
37
+ @segment_spacing = 2
27
38
  @label_formatting = nil
28
39
  @show_labels_for_bar_values = false
40
+ @hide_labels = false
29
41
  end
30
42
  private :initialize_ivars
31
43
 
32
44
  # Draws a bar graph, but multiple sets are stacked on top of each other.
33
45
  def draw
34
- get_maximum_by_stack
46
+ calculate_maximum_by_stack
35
47
  super
36
48
  return unless data_given?
37
49
 
38
50
  # Setup spacing.
39
51
  #
40
52
  # Columns sit stacked.
41
- @bar_spacing ||= 0.9
42
- @segment_spacing ||= 2
43
-
44
53
  bar_width = @graph_width / column_count.to_f
45
54
  padding = (bar_width * (1 - @bar_spacing)) / 2
46
55
 
@@ -79,7 +88,19 @@ class Gruff::StackedBar < Gruff::Base
79
88
  draw_value_label(x, y, text, true)
80
89
  end
81
90
  end
91
+ end
92
+
93
+ protected
94
+
95
+ def hide_labels?
96
+ @hide_labels
97
+ end
98
+
99
+ def hide_left_label_area?
100
+ @hide_line_markers
101
+ end
82
102
 
83
- Gruff::Renderer.finish
103
+ def hide_bottom_label_area?
104
+ hide_labels?
84
105
  end
85
106
  end
@@ -1,13 +1,15 @@
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
9
- self.points = Array(points)
10
- self.color = color
8
+ super(label.to_s, Array(points), color)
9
+ end
10
+
11
+ def empty?
12
+ points.empty?
11
13
  end
12
14
 
13
15
  def columns
@@ -22,9 +24,9 @@ module Gruff
22
24
  points.compact.max
23
25
  end
24
26
 
25
- def normalize(args = {})
27
+ def normalize(minimum:, spread:)
26
28
  norm_points = points.map do |point|
27
- point.nil? ? nil : (point.to_f - args[:minimum].to_f) / args[:spread]
29
+ point.nil? ? nil : (point.to_f - minimum.to_f) / spread
28
30
  end
29
31
 
30
32
  self.class.new(label, norm_points, color)
@@ -2,12 +2,14 @@
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
8
- self.points = Array(points)
9
- self.color = color
10
- self.custom = custom
8
+ super(label.to_s, Array(points), color, custom)
9
+ end
10
+
11
+ def empty?
12
+ points.empty?
11
13
  end
12
14
 
13
15
  def columns
@@ -22,9 +24,9 @@ module Gruff
22
24
  points.compact.max
23
25
  end
24
26
 
25
- def normalize(args = {})
27
+ def normalize(minimum:, spread:)
26
28
  norm_points = points.map do |point|
27
- point.nil? ? nil : (point.to_f - args[:minimum].to_f) / args[:spread]
29
+ point.nil? ? nil : (point.to_f - minimum.to_f) / spread
28
30
  end
29
31
 
30
32
  self.class.new(label, norm_points, color, custom)
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Gruff
4
+ # @private
4
5
  class Store
5
6
  attr_reader :data, :norm_data
6
7
 
@@ -15,10 +16,10 @@ module Gruff
15
16
  @data << @data_class.new(*args)
16
17
  end
17
18
 
18
- def normalize(args = {})
19
+ def normalize(**keywords)
19
20
  unless @normalized
20
21
  @data.each do |data_row|
21
- @norm_data << data_row.normalize(args)
22
+ @norm_data << data_row.normalize(**keywords)
22
23
  end
23
24
 
24
25
  @normalized = true
@@ -26,7 +27,7 @@ module Gruff
26
27
  end
27
28
 
28
29
  def empty?
29
- @data.empty?
30
+ @data.all?(&:empty?)
30
31
  end
31
32
 
32
33
  def length
@@ -56,18 +57,18 @@ module Gruff
56
57
  end
57
58
 
58
59
  def sort_data!
59
- @data = @data.sort_by { |a| -a.points.reduce(0) { |acc, elem| acc + elem.to_f } }
60
+ @data = @data.sort_by { |a| -a.points.sum(&:to_f) }
60
61
  end
61
62
 
62
63
  def sort_norm_data!
63
- @norm_data = @norm_data.sort_by { |a| -a.points.reduce(0) { |acc, elem| acc + elem.to_f } }
64
+ @norm_data = @norm_data.sort_by { |a| -a.points.sum(&:to_f) }
64
65
  end
65
66
 
66
67
  def reverse!
67
68
  @data.reverse!
68
69
  end
69
70
 
70
- def set_colors!(colors)
71
+ def change_colors(colors)
71
72
  index = 0
72
73
  @data.each do |data_row|
73
74
  data_row.color ||= begin