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.
- checksums.yaml +4 -4
- data/.rubocop.yml +21 -4
- data/.rubocop_todo.yml +103 -49
- data/.travis.yml +3 -6
- data/CHANGELOG.md +30 -0
- data/README.md +4 -0
- data/gruff.gemspec +8 -3
- data/lib/gruff.rb +9 -3
- data/lib/gruff/accumulator_bar.rb +13 -5
- data/lib/gruff/area.rb +22 -5
- data/lib/gruff/bar.rb +38 -10
- data/lib/gruff/base.rb +325 -236
- data/lib/gruff/bezier.rb +18 -4
- data/lib/gruff/bullet.rb +22 -14
- data/lib/gruff/dot.rb +20 -33
- data/lib/gruff/helper/bar_conversion.rb +7 -7
- data/lib/gruff/helper/bar_value_label_mixin.rb +3 -0
- data/lib/gruff/helper/stacked_mixin.rb +1 -1
- data/lib/gruff/histogram.rb +59 -0
- data/lib/gruff/line.rb +33 -28
- data/lib/gruff/mini/bar.rb +10 -2
- data/lib/gruff/mini/legend.rb +9 -4
- data/lib/gruff/mini/pie.rb +9 -3
- data/lib/gruff/mini/side_bar.rb +18 -4
- data/lib/gruff/net.rb +41 -21
- data/lib/gruff/patch/rmagick.rb +22 -24
- data/lib/gruff/patch/string.rb +9 -4
- data/lib/gruff/photo_bar.rb +12 -16
- data/lib/gruff/pie.rb +24 -34
- data/lib/gruff/renderer/bezier.rb +4 -3
- data/lib/gruff/renderer/circle.rb +4 -3
- data/lib/gruff/renderer/dash_line.rb +4 -3
- data/lib/gruff/renderer/dot.rb +4 -3
- data/lib/gruff/renderer/ellipse.rb +4 -3
- data/lib/gruff/renderer/line.rb +14 -5
- data/lib/gruff/renderer/polygon.rb +5 -4
- data/lib/gruff/renderer/polyline.rb +4 -3
- data/lib/gruff/renderer/rectangle.rb +3 -2
- data/lib/gruff/renderer/renderer.rb +31 -38
- data/lib/gruff/renderer/text.rb +29 -7
- data/lib/gruff/scatter.rb +26 -24
- data/lib/gruff/scene.rb +0 -1
- data/lib/gruff/side_bar.rb +51 -20
- data/lib/gruff/side_stacked_bar.rb +42 -15
- data/lib/gruff/spider.rb +29 -17
- data/lib/gruff/stacked_area.rb +19 -8
- data/lib/gruff/stacked_bar.rb +34 -13
- data/lib/gruff/store/{base_data.rb → basic_data.rb} +9 -7
- data/lib/gruff/store/custom_data.rb +8 -6
- data/lib/gruff/store/store.rb +7 -6
- data/lib/gruff/store/xy_data.rb +10 -7
- data/lib/gruff/version.rb +1 -1
- metadata +33 -8
- data/Rakefile +0 -23
- data/docker/Dockerfile +0 -14
- data/docker/build.sh +0 -4
- data/docker/launch.sh +0 -4
@@ -1,52 +1,81 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
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
|
-
#
|
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
|
-
|
27
|
+
attr_writer :bar_spacing
|
16
28
|
|
17
29
|
# Number of pixels between bar segments.
|
18
|
-
|
30
|
+
attr_writer :segment_spacing
|
19
31
|
|
20
32
|
# Set the number output format for labels using sprintf.
|
21
33
|
# Default is +"%.2f"+.
|
22
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
#
|
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
|
-
|
11
|
-
|
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.
|
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.
|
117
|
+
store.data.sum { |data_row| data_row.points.first }
|
106
118
|
end
|
107
119
|
end
|
data/lib/gruff/stacked_area.rb
CHANGED
@@ -1,14 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/gruff/stacked_bar.rb
CHANGED
@@ -1,46 +1,55 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
-
|
18
|
+
attr_writer :bar_spacing
|
13
19
|
|
14
20
|
# Number of pixels between bar segments.
|
15
|
-
|
21
|
+
attr_writer :segment_spacing
|
16
22
|
|
17
23
|
# Set the number output format for labels using sprintf.
|
18
24
|
# Default is +"%.2f"+.
|
19
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
5
|
+
# @private
|
6
|
+
class BasicData < Struct.new(:label, :points, :color)
|
7
7
|
def initialize(label, points, color)
|
8
|
-
|
9
|
-
|
10
|
-
|
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(
|
27
|
+
def normalize(minimum:, spread:)
|
26
28
|
norm_points = points.map do |point|
|
27
|
-
point.nil? ? nil : (point.to_f -
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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(
|
27
|
+
def normalize(minimum:, spread:)
|
26
28
|
norm_points = points.map do |point|
|
27
|
-
point.nil? ? nil : (point.to_f -
|
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)
|
data/lib/gruff/store/store.rb
CHANGED
@@ -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(
|
19
|
+
def normalize(**keywords)
|
19
20
|
unless @normalized
|
20
21
|
@data.each do |data_row|
|
21
|
-
@norm_data << data_row.normalize(
|
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.
|
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.
|
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
|
71
|
+
def change_colors(colors)
|
71
72
|
index = 0
|
72
73
|
@data.each do |data_row|
|
73
74
|
data_row.color ||= begin
|