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
@@ -14,30 +14,33 @@
14
14
  #
15
15
  module Gruff
16
16
  module Mini
17
+ # A class for drawing a small bar graph.
17
18
  class Bar < Gruff::Bar
19
+ private
20
+
18
21
  include Gruff::Mini::Legend
19
22
 
20
- def initialize_ivars
23
+ def initialize_attributes
21
24
  super
22
25
 
23
26
  @hide_legend = true
24
27
  @hide_title = true
25
28
  @hide_line_numbers = true
26
29
 
27
- @marker_font_size = 50.0
28
- @legend_font_size = 60.0
30
+ @marker_font.size = 50.0
31
+ @legend_font.size = 60.0
29
32
 
30
33
  @minimum_value = 0.0
31
34
  end
32
- private :initialize_ivars
33
35
 
34
- def draw
36
+ def setup_data
35
37
  expand_canvas_for_vertical_legend
36
-
37
38
  super
39
+ end
38
40
 
41
+ def draw_graph
42
+ super
39
43
  draw_vertical_legend
40
- Gruff::Renderer.finish
41
44
  end
42
45
  end
43
46
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Gruff
4
4
  module Mini
5
+ # A module to handle the small legend.
6
+ # @private
5
7
  module Legend
6
8
  attr_accessor :hide_mini_legend, :legend_position
7
9
 
@@ -25,22 +27,24 @@ module Gruff
25
27
  @original_columns = @raw_columns
26
28
 
27
29
  case @legend_position
28
- when :right then
30
+ when :right
29
31
  @rows = [@rows, legend_height].max
30
32
  @columns += calculate_legend_width + @left_margin
31
33
  else
32
- @rows += store.length * calculate_caps_height(scale_fontsize(@legend_font_size)) * 1.7
34
+ font = @legend_font.dup
35
+ font.size = scale_fontsize(font.size)
36
+ @rows += store.length * calculate_caps_height(font) * 1.7
33
37
  end
34
38
 
35
- Gruff::Renderer.setup(@columns, @rows, @font, @scale, @theme_options)
39
+ @renderer = Gruff::Renderer.new(@columns, @rows, @scale, @theme_options)
36
40
  end
37
41
 
38
42
  def calculate_line_height
39
- calculate_caps_height(@legend_font_size) * 1.7
43
+ calculate_caps_height(@legend_font) * 1.7
40
44
  end
41
45
 
42
46
  def calculate_legend_width
43
- width = @legend_labels.map { |label| calculate_width(@legend_font_size, label) }.max
47
+ width = @legend_labels.map { |label| calculate_width(@legend_font, label) }.max
44
48
  scale_fontsize(width + 40 * 1.7)
45
49
  end
46
50
 
@@ -55,7 +59,7 @@ module Gruff
55
59
  legend_top_margin = 40.0
56
60
 
57
61
  case @legend_position
58
- when :right then
62
+ when :right
59
63
  current_x_offset = @original_columns + @left_margin
60
64
  current_y_offset = @top_margin + legend_top_margin
61
65
  else
@@ -66,11 +70,12 @@ module Gruff
66
70
  @legend_labels.each_with_index do |legend_label, index|
67
71
  # Draw label
68
72
  label = truncate_legend_label(legend_label)
69
- text_renderer = Gruff::Renderer::Text.new(label, font: @font, size: @legend_font_size, color: @font_color)
70
- text_renderer.add_to_render_queue(@raw_columns, 1.0, current_x_offset + (legend_square_width * 1.7), current_y_offset, Magick::WestGravity)
73
+ text_renderer = Gruff::Renderer::Text.new(renderer, label, font: @legend_font)
74
+ x_offset = current_x_offset + (legend_square_width * 1.7)
75
+ text_renderer.add_to_render_queue(@raw_columns, 1.0, x_offset, current_y_offset, Magick::WestGravity)
71
76
 
72
77
  # Now draw box with color of this dataset
73
- rect_renderer = Gruff::Renderer::Rectangle.new(color: store.data[index].color)
78
+ rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: store.data[index].color)
74
79
  rect_renderer.render(current_x_offset,
75
80
  current_y_offset - legend_square_width / 2.0,
76
81
  current_x_offset + legend_square_width,
@@ -87,7 +92,11 @@ module Gruff
87
92
 
88
93
  def truncate_legend_label(label)
89
94
  truncated_label = label.to_s
90
- while calculate_width(scale_fontsize(@legend_font_size), truncated_label) > (@columns - @legend_left_margin - @right_margin) && (truncated_label.length > 1)
95
+
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
91
100
  truncated_label = truncated_label[0..truncated_label.length - 2]
92
101
  end
93
102
  truncated_label + (truncated_label.length < label.to_s.length ? '...' : '')
@@ -13,29 +13,31 @@
13
13
  #
14
14
  module Gruff
15
15
  module Mini
16
+ # A class for drawing a small pie graph.
16
17
  class Pie < Gruff::Pie
18
+ private
19
+
17
20
  include Gruff::Mini::Legend
18
21
 
19
- def initialize_ivars
22
+ def initialize_attributes
20
23
  super
21
24
 
22
25
  @hide_legend = true
23
26
  @hide_title = true
24
27
  @hide_line_numbers = true
25
28
 
26
- @marker_font_size = 60.0
27
- @legend_font_size = 60.0
29
+ @marker_font.size = 60.0
30
+ @legend_font.size = 60.0
28
31
  end
29
- private :initialize_ivars
30
32
 
31
- def draw
33
+ def setup_data
32
34
  expand_canvas_for_vertical_legend
33
-
34
35
  super
36
+ end
35
37
 
38
+ def draw_graph
39
+ super
36
40
  draw_vertical_legend
37
-
38
- Gruff::Renderer.finish
39
41
  end
40
42
  end
41
43
  end
@@ -21,28 +21,30 @@
21
21
  #
22
22
  module Gruff
23
23
  module Mini
24
+ # A class for drawing a small side bar graph.
24
25
  class SideBar < Gruff::SideBar
26
+ private
27
+
25
28
  include Gruff::Mini::Legend
26
29
 
27
- def initialize_ivars
30
+ def initialize_attributes
28
31
  super
29
32
  @hide_legend = true
30
33
  @hide_title = true
31
34
  @hide_line_numbers = true
32
35
 
33
- @marker_font_size = 50.0
34
- @legend_font_size = 50.0
36
+ @marker_font.size = 50.0
37
+ @legend_font.size = 50.0
35
38
  end
36
- private :initialize_ivars
37
39
 
38
- def draw
40
+ def setup_data
39
41
  expand_canvas_for_vertical_legend
40
-
41
42
  super
43
+ end
42
44
 
45
+ def draw_graph
46
+ super
43
47
  draw_vertical_legend
44
-
45
- Gruff::Renderer.finish
46
48
  end
47
49
  end
48
50
  end
data/lib/gruff/net.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'gruff/base'
4
-
5
3
  # See also the Spider graph.
6
4
  #
7
5
  # Here's how to make a Gruff::Net.
@@ -25,14 +23,16 @@ require 'gruff/base'
25
23
  # g.write("net.png")
26
24
  #
27
25
  class Gruff::Net < Gruff::Base
28
- # Hide parts of the graph to fit more datapoints, or for a different appearance.
26
+ # Hide parts of the graph to fit more data points, or for a different appearance.
29
27
  attr_writer :hide_dots
30
28
 
31
29
  # Dimensions of lines and dots; calculated based on dataset size if left unspecified.
32
30
  attr_writer :line_width
33
31
  attr_writer :dot_radius
34
32
 
35
- def initialize_ivars
33
+ private
34
+
35
+ def initialize_attributes
36
36
  super
37
37
 
38
38
  @hide_dots = false
@@ -40,14 +40,10 @@ class Gruff::Net < Gruff::Base
40
40
  @dot_radius = nil
41
41
  @hide_line_numbers = true
42
42
  @sorted_drawing = true
43
+ @marker_font.bold = true
43
44
  end
44
- private :initialize_ivars
45
-
46
- def draw
47
- super
48
-
49
- return unless data_given?
50
45
 
46
+ def draw_graph
51
47
  store.norm_data.each do |data_row|
52
48
  data_row.points.each_with_index do |data_point, index|
53
49
  next if data_point.nil?
@@ -64,17 +60,16 @@ class Gruff::Net < Gruff::Base
64
60
  end_x = @center_x + Math.sin(next_rad_pos) * next_point_distance
65
61
  end_y = @center_y - Math.cos(next_rad_pos) * next_point_distance
66
62
 
67
- Gruff::Renderer::Line.new(color: data_row.color, width: @stroke_width).render(start_x, start_y, end_x, end_y)
63
+ Gruff::Renderer::Line.new(renderer, color: data_row.color, width: @stroke_width).render(start_x, start_y, end_x, end_y)
68
64
 
69
- Gruff::Renderer::Circle.new(color: data_row.color, width: @stroke_width).render(start_x, start_y, start_x - @circle_radius, start_y) unless @hide_dots
65
+ unless @hide_dots
66
+ circle_renderer = Gruff::Renderer::Circle.new(renderer, color: data_row.color, width: @stroke_width)
67
+ circle_renderer.render(start_x, start_y, start_x - @circle_radius, start_y)
68
+ end
70
69
  end
71
70
  end
72
-
73
- Gruff::Renderer.finish
74
71
  end
75
72
 
76
- private
77
-
78
73
  def setup_drawing
79
74
  super
80
75
 
@@ -93,7 +88,7 @@ private
93
88
  (0..column_count - 1).each do |index|
94
89
  rad_pos = index * Math::PI * 2 / column_count
95
90
 
96
- Gruff::Renderer::Line.new(color: @marker_color)
91
+ Gruff::Renderer::Line.new(renderer, color: @marker_color)
97
92
  .render(@center_x, @center_y, @center_x + Math.sin(rad_pos) * @radius, @center_y - Math.cos(rad_pos) * @radius)
98
93
 
99
94
  marker_label = @labels[index] ? @labels[index].to_s : '000'
@@ -107,8 +102,6 @@ private
107
102
  x = x_offset + (radius + LABEL_MARGIN) * Math.sin(deg2rad(angle))
108
103
  y = y_offset - (radius + LABEL_MARGIN) * Math.cos(deg2rad(angle))
109
104
 
110
- # Draw label
111
- text_renderer = Gruff::Renderer::Text.new(amount, font: @font, size: 20, color: @marker_color, weight: Magick::BoldWeight)
112
- text_renderer.add_to_render_queue(0, 0, x, y, Magick::CenterGravity)
105
+ draw_label_at(1.0, 1.0, x, y, amount, Magick::CenterGravity)
113
106
  end
114
107
  end
@@ -1,33 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # @private
3
4
  module Magick
4
- class Draw
5
- # Additional method to scale annotation text since Draw.scale doesn't.
6
- def annotate_scaled(img, width, height, x, y, text, scale)
7
- scaled_width = (width * scale) >= 1 ? (width * scale) : 1
8
- scaled_height = (height * scale) >= 1 ? (height * scale) : 1
5
+ # @private
6
+ module GruffAnnotate
7
+ refine Draw do
8
+ # Additional method to scale annotation text since Draw.scale doesn't.
9
+ def annotate_scaled(img, width, height, x, y, text, scale)
10
+ scaled_width = (width * scale) >= 1 ? (width * scale) : 1
11
+ scaled_height = (height * scale) >= 1 ? (height * scale) : 1
9
12
 
10
- annotate(img,
11
- scaled_width, scaled_height,
12
- x * scale, y * scale,
13
- text.gsub('%', '%%'))
14
- end
15
-
16
- remove_method :stroke_opacity
17
- def stroke_opacity(_opacity)
18
- raise '#stroke_opacity method has different behavior between RMagick and RMagick4J. Should not use this method.'
19
- end
13
+ annotate(img,
14
+ scaled_width, scaled_height,
15
+ x * scale, y * scale,
16
+ text.gsub('%', '%%'))
17
+ end
20
18
 
21
- if defined? JRUBY_VERSION
22
- # FIXME(uwe): We should NOT need to implement this method.
23
- # Remove this method as soon as RMagick4J Issue #16 is fixed.
24
- # https://github.com/Serabe/RMagick4J/issues/16
25
- def fill=(fill)
26
- fill = { white: '#FFFFFF' }[fill.to_sym] || fill
27
- @draw.fill = Magick4J.ColorDatabase.query_default(fill)
28
- self
19
+ if defined? JRUBY_VERSION
20
+ # FIXME(uwe): We should NOT need to implement this method.
21
+ # Remove this method as soon as RMagick4J Issue #16 is fixed.
22
+ # https://github.com/Serabe/RMagick4J/issues/16
23
+ def fill=(fill)
24
+ fill = { white: '#FFFFFF' }[fill.to_sym] || fill
25
+ @draw.fill = Magick4J.ColorDatabase.query_default(fill)
26
+ self
27
+ end
29
28
  end
30
- # EMXIF
31
29
  end
32
30
  end
33
31
  end
@@ -1,10 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class String
3
+ # @private
4
+ module String::GruffCommify
4
5
  THOUSAND_SEPARATOR = ','
5
6
 
6
- #Taken from http://codesnippets.joyent.com/posts/show/330
7
- def commify(delimiter = THOUSAND_SEPARATOR)
8
- gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
7
+ refine String do
8
+ # Taken from http://codesnippets.joyent.com/posts/show/330
9
+ def commify(delimiter = THOUSAND_SEPARATOR)
10
+ gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
11
+ end
9
12
  end
10
13
  end
data/lib/gruff/pie.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'gruff/base'
4
-
5
3
  #
6
4
  # Here's how to make a Gruff::Pie.
7
5
  #
@@ -20,6 +18,9 @@ class Gruff::Pie < Gruff::Base
20
18
  # or at another angle. Default is +0.0+, which starts at 3 o'clock.
21
19
  attr_writer :zero_degree
22
20
 
21
+ # Set the number output format lambda.
22
+ attr_writer :label_formatting
23
+
23
24
  # Do not show labels for slices that are less than this percent. Use 0 to always show all labels.
24
25
  # Defaults to +0+.
25
26
  attr_writer :hide_labels_less_than
@@ -31,75 +32,54 @@ class Gruff::Pie < Gruff::Base
31
32
  ## Use values instead of percentages.
32
33
  attr_writer :show_values_as_labels
33
34
 
35
+ private
36
+
34
37
  def initialize_store
35
38
  @store = Gruff::Store.new(Gruff::Store::CustomData)
36
39
  end
37
- private :initialize_store
38
40
 
39
- def initialize_ivars
41
+ def initialize_attributes
40
42
  super
41
43
  @zero_degree = 0.0
42
44
  @hide_labels_less_than = 0.0
43
45
  @text_offset_percentage = DEFAULT_TEXT_OFFSET_PERCENTAGE
44
46
  @show_values_as_labels = false
45
- end
46
- private :initialize_ivars
47
+ @marker_font.bold = true
47
48
 
48
- def options
49
- {
50
- zero_degree: @zero_degree,
51
- hide_labels_less_than: @hide_labels_less_than,
52
- text_offset_percentage: @text_offset_percentage,
53
- show_values_as_labels: @show_values_as_labels
54
- }
55
- end
56
-
57
- def draw
58
- hide_line_markers
59
-
60
- super
49
+ @hide_line_markers = true
50
+ @hide_line_markers.freeze
61
51
 
62
- return unless data_given?
52
+ @label_formatting = ->(value, percentage) { @show_values_as_labels ? value.to_s : "#{percentage}%" }
53
+ end
63
54
 
55
+ def draw_graph
64
56
  slices.each do |slice|
65
57
  if slice.value > 0
66
- Gruff::Renderer::Ellipse.new(color: slice.color, width: radius)
58
+ Gruff::Renderer::Ellipse.new(renderer, color: slice.color, width: radius)
67
59
  .render(center_x, center_y, radius / 2.0, radius / 2.0, chart_degrees, chart_degrees + slice.degrees + 0.5)
68
60
  process_label_for slice
69
61
  update_chart_degrees_with slice.degrees
70
62
  end
71
63
  end
72
-
73
- Gruff::Renderer.finish
74
64
  end
75
65
 
76
- private
77
-
78
66
  def slices
79
67
  @slices ||= begin
80
- slices = store.data.map { |data| slice_class.new(data, options) }
68
+ slices = store.data.map { |data| Gruff::Pie::PieSlice.new(data.label, data.points.first, data.color) }
81
69
 
82
70
  slices.sort_by(&:value) if @sort
83
71
 
84
- total = slices.map(&:value).inject(:+).to_f
72
+ total = slices.sum(&:value).to_f
85
73
  slices.each { |slice| slice.total = total }
86
74
  end
87
75
  end
88
76
 
89
77
  # General Helper Methods
90
78
 
91
- def hide_line_markers
92
- @hide_line_markers = true
93
- end
94
-
95
79
  def update_chart_degrees_with(degrees)
96
80
  @chart_degrees = chart_degrees + degrees
97
81
  end
98
82
 
99
- def slice_class
100
- PieSlice
101
- end
102
-
103
83
  # Spatial Value-Related Methods
104
84
 
105
85
  def chart_degrees
@@ -107,13 +87,8 @@ private
107
87
  end
108
88
 
109
89
  attr_reader :graph_height
110
-
111
90
  attr_reader :graph_width
112
91
 
113
- def diameter
114
- graph_height
115
- end
116
-
117
92
  def half_width
118
93
  graph_width / 2.0
119
94
  end
@@ -151,8 +126,8 @@ private
151
126
  def process_label_for(slice)
152
127
  if slice.percentage >= @hide_labels_less_than
153
128
  x, y = label_coordinates_for slice
154
-
155
- draw_label(x, y, slice.label)
129
+ label = @label_formatting.call(slice.value, slice.percentage)
130
+ draw_label_at(1.0, 1.0, x, y, label, Magick::CenterGravity)
156
131
  end
157
132
  end
158
133
 
@@ -170,45 +145,24 @@ private
170
145
  center_y + (radius_offset * Math.sin(deg2rad(angle)))
171
146
  end
172
147
 
173
- # Drawing-Related Methods
174
-
175
- def draw_label(x, y, value)
176
- text_renderer = Gruff::Renderer::Text.new(value, font: @font, size: @marker_font_size, color: @font_color, weight: Magick::BoldWeight)
177
- text_renderer.add_to_render_queue(0, 0, x, y, Magick::CenterGravity)
178
- end
179
-
180
148
  # Helper Classes
181
149
  #
182
150
  # @private
183
- class PieSlice < Struct.new(:data_array, :options)
151
+ class PieSlice < Struct.new(:label, :value, :color)
184
152
  attr_accessor :total
185
153
 
186
- def name
187
- data_array[0]
188
- end
189
-
190
- def value
191
- data_array[1].first
192
- end
193
-
194
- def color
195
- data_array[2]
196
- end
197
-
198
- def size
199
- @size ||= value / total
200
- end
201
-
202
154
  def percentage
203
- @percentage ||= (size * 100.0).round
155
+ (size * 100.0).round
204
156
  end
205
157
 
206
158
  def degrees
207
- @degrees ||= size * 360.0
159
+ size * 360.0
208
160
  end
209
161
 
210
- def label
211
- options[:show_values_as_labels] ? value.to_s : "#{percentage}%"
162
+ private
163
+
164
+ def size
165
+ value / total
212
166
  end
213
167
  end
214
168
  end