gruff 0.26.0 → 0.27.0
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/.github/ISSUE_TEMPLATE/report.yml +1 -1
- data/.github/workflows/ci.yml +37 -0
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +18 -1
- data/Gemfile +5 -0
- data/README.md +7 -1
- data/gruff.gemspec +1 -1
- data/lib/gruff/accumulator_bar.rb +3 -1
- data/lib/gruff/area.rb +5 -2
- data/lib/gruff/bar.rb +18 -9
- data/lib/gruff/base.rb +193 -68
- data/lib/gruff/bezier.rb +6 -3
- data/lib/gruff/box.rb +40 -16
- data/lib/gruff/bubble.rb +9 -2
- data/lib/gruff/bullet.rb +8 -1
- data/lib/gruff/candlestick.rb +30 -8
- data/lib/gruff/dot.rb +13 -3
- data/lib/gruff/font.rb +12 -4
- data/lib/gruff/helper/bar_conversion.rb +12 -1
- data/lib/gruff/helper/bar_mixin.rb +19 -1
- data/lib/gruff/helper/bar_value_label.rb +22 -4
- data/lib/gruff/helper/stacked_mixin.rb +21 -1
- data/lib/gruff/histogram.rb +14 -5
- data/lib/gruff/line.rb +31 -12
- data/lib/gruff/mini/bar.rb +2 -2
- data/lib/gruff/mini/legend.rb +10 -1
- data/lib/gruff/mini/pie.rb +2 -2
- data/lib/gruff/mini/side_bar.rb +2 -2
- data/lib/gruff/net.rb +12 -7
- data/lib/gruff/patch/rmagick.rb +2 -0
- data/lib/gruff/patch/string.rb +1 -1
- data/lib/gruff/pie.rb +46 -11
- data/lib/gruff/renderer/bezier.rb +7 -0
- data/lib/gruff/renderer/circle.rb +11 -0
- data/lib/gruff/renderer/dash_line.rb +11 -0
- data/lib/gruff/renderer/dot.rb +11 -0
- data/lib/gruff/renderer/ellipse.rb +12 -0
- data/lib/gruff/renderer/line.rb +10 -0
- data/lib/gruff/renderer/polygon.rb +6 -0
- data/lib/gruff/renderer/polyline.rb +8 -0
- data/lib/gruff/renderer/rectangle.rb +11 -0
- data/lib/gruff/renderer/renderer.rb +16 -5
- data/lib/gruff/renderer/text.rb +19 -2
- data/lib/gruff/scatter.rb +16 -8
- data/lib/gruff/side_bar.rb +19 -10
- data/lib/gruff/side_stacked_bar.rb +15 -11
- data/lib/gruff/spider.rb +9 -2
- data/lib/gruff/stacked_area.rb +6 -1
- data/lib/gruff/stacked_bar.rb +16 -10
- data/lib/gruff/store/basic_data.rb +36 -2
- data/lib/gruff/store/store.rb +16 -3
- data/lib/gruff/store/xy_data.rb +32 -2
- data/lib/gruff/store/xy_pointsizes_data.rb +36 -3
- data/lib/gruff/themes.rb +2 -0
- data/lib/gruff/version.rb +3 -1
- data/lib/gruff.rb +3 -1
- data/sig/generated/gruff/accumulator_bar.rbs +19 -0
- data/sig/generated/gruff/area.rbs +27 -0
- data/sig/generated/gruff/bar.rbs +74 -0
- data/sig/generated/gruff/base.rbs +672 -0
- data/sig/generated/gruff/bezier.rbs +24 -0
- data/sig/generated/gruff/box.rbs +88 -0
- data/sig/generated/gruff/bubble.rbs +69 -0
- data/sig/generated/gruff/bullet.rbs +30 -0
- data/sig/generated/gruff/candlestick.rbs +79 -0
- data/sig/generated/gruff/dot.rbs +44 -0
- data/sig/generated/gruff/font.rbs +35 -0
- data/sig/generated/gruff/helper/bar_conversion.rbs +27 -0
- data/sig/generated/gruff/helper/bar_mixin.rbs +22 -0
- data/sig/generated/gruff/helper/bar_value_label.rbs +41 -0
- data/sig/generated/gruff/helper/stacked_mixin.rbs +27 -0
- data/sig/generated/gruff/histogram.rbs +42 -0
- data/sig/generated/gruff/line.rbs +165 -0
- data/sig/generated/gruff/net.rbs +52 -0
- data/sig/generated/gruff/pie.rbs +131 -0
- data/sig/generated/gruff/renderer/bezier.rbs +15 -0
- data/sig/generated/gruff/renderer/circle.rbs +19 -0
- data/sig/generated/gruff/renderer/dash_line.rbs +19 -0
- data/sig/generated/gruff/renderer/dot.rbs +27 -0
- data/sig/generated/gruff/renderer/ellipse.rbs +20 -0
- data/sig/generated/gruff/renderer/line.rbs +24 -0
- data/sig/generated/gruff/renderer/polyline.rbs +16 -0
- data/sig/generated/gruff/renderer/rectangle.rbs +19 -0
- data/sig/generated/gruff/renderer/renderer.rbs +43 -0
- data/sig/generated/gruff/renderer/text.rbs +38 -0
- data/sig/generated/gruff/scatter.rbs +112 -0
- data/sig/generated/gruff/side_bar.rbs +78 -0
- data/sig/generated/gruff/side_stacked_bar.rbs +52 -0
- data/sig/generated/gruff/spider.rbs +50 -0
- data/sig/generated/gruff/stacked_area.rbs +25 -0
- data/sig/generated/gruff/stacked_bar.rbs +56 -0
- data/sig/generated/gruff/store/basic_data.rbs +48 -0
- data/sig/generated/gruff/store/store.rbs +53 -0
- data/sig/generated/gruff/store/xy_data.rbs +58 -0
- data/sig/generated/gruff/store/xy_pointsizes_data.rbs +61 -0
- data/sig/generated/gruff/themes.rbs +24 -0
- data/sig/generated/gruff/version.rbs +5 -0
- data/sig/generated/gruff.rbs +20 -0
- metadata +43 -1
data/lib/gruff/bezier.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rbs_inline: enabled
|
4
|
+
|
3
5
|
#
|
4
6
|
# Gruff::Bezier is a special line graph that have
|
5
7
|
# the bezier curve.
|
@@ -25,14 +27,15 @@ private
|
|
25
27
|
x_increment = (@graph_width / (column_count - 1)).to_f
|
26
28
|
|
27
29
|
renderer_class = RUBY_PLATFORM == 'java' ? Gruff::Renderer::Polyline : Gruff::Renderer::Bezier
|
28
|
-
stroke_width = clip_value_if_greater_than(@columns / (store.norm_data.first
|
30
|
+
stroke_width = clip_value_if_greater_than(@columns / (store.norm_data.first.points.size * 4.0), 5.0)
|
29
31
|
|
30
32
|
store.norm_data.each do |data_row|
|
31
|
-
next if data_row
|
33
|
+
next if data_row.points.empty?
|
32
34
|
|
33
35
|
poly_points = []
|
34
36
|
|
35
|
-
data_row
|
37
|
+
data_row.points.each_with_index do |data_point, index|
|
38
|
+
data_point = data_point.to_f
|
36
39
|
# Use incremented x and scaled y
|
37
40
|
new_x = @graph_left + (x_increment * index)
|
38
41
|
new_y = @graph_top + (@graph_height - (data_point * @graph_height))
|
data/lib/gruff/box.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rbs_inline: enabled
|
4
|
+
|
3
5
|
#
|
4
6
|
# Here's how to set up a Gruff::Box.
|
5
7
|
#
|
@@ -11,10 +13,10 @@
|
|
11
13
|
#
|
12
14
|
class Gruff::Box < Gruff::Base
|
13
15
|
# Specifies the filling opacity in area graph. Default is +0.2+.
|
14
|
-
attr_writer :fill_opacity
|
16
|
+
attr_writer :fill_opacity #: Float | Integer
|
15
17
|
|
16
18
|
# Specifies the stroke width in line. Default is +3.0+.
|
17
|
-
attr_writer :stroke_width
|
19
|
+
attr_writer :stroke_width #: Float | Integer
|
18
20
|
|
19
21
|
# Can be used to adjust the spaces between the bars.
|
20
22
|
# Accepts values between 0.00 and 1.00 where 0.00 means no spacing at all
|
@@ -22,10 +24,12 @@ class Gruff::Box < Gruff::Base
|
|
22
24
|
# line with no x dimension).
|
23
25
|
#
|
24
26
|
# Default value is +0.8+.
|
27
|
+
#
|
28
|
+
# @rbs space_percent: Float | Integer
|
25
29
|
def spacing_factor=(space_percent)
|
26
30
|
raise ArgumentError, 'spacing_factor must be between 0.00 and 1.00' if (space_percent < 0) || (space_percent > 1)
|
27
31
|
|
28
|
-
@spacing_factor = (1 - space_percent)
|
32
|
+
@spacing_factor = (1.0 - space_percent)
|
29
33
|
end
|
30
34
|
|
31
35
|
private
|
@@ -93,86 +97,106 @@ private
|
|
93
97
|
@normalized_boxes ||= store.norm_data.map { |data| Gruff::Box::BoxData.new(data.label, data.points, data.color) }
|
94
98
|
end
|
95
99
|
|
100
|
+
# @rbs return: Integer
|
96
101
|
def column_count
|
97
102
|
normalized_boxes.size
|
98
103
|
end
|
99
104
|
|
105
|
+
# @rbs return: Integer
|
100
106
|
def calculate_spacing
|
101
107
|
column_count - 1
|
102
108
|
end
|
103
109
|
|
104
110
|
# @private
|
105
|
-
class BoxData
|
111
|
+
class BoxData
|
112
|
+
attr_accessor :label #: String
|
113
|
+
attr_accessor :points #: Array[Float | Integer]
|
114
|
+
attr_accessor :color #: String
|
115
|
+
|
106
116
|
def initialize(label, points, color)
|
107
|
-
|
117
|
+
@label = label
|
118
|
+
@points = points.compact.sort
|
119
|
+
@color = color
|
108
120
|
end
|
109
121
|
|
122
|
+
# @rbs return: Float | Integer
|
110
123
|
def min
|
111
|
-
points.first || 0
|
124
|
+
points.first || 0.0
|
112
125
|
end
|
113
126
|
|
127
|
+
# @rbs return: Float | Integer
|
114
128
|
def max
|
115
|
-
points.last || 0
|
129
|
+
points.last || 0.0
|
116
130
|
end
|
117
131
|
|
132
|
+
# @rbs return: Float | Integer
|
118
133
|
def min_whisker
|
119
134
|
[min, first_quartile - (1.5 * interquartile_range)].max
|
120
135
|
end
|
121
136
|
|
137
|
+
# @rbs return: Float | Integer
|
122
138
|
def max_whisker
|
123
139
|
[max, third_quartile + (1.5 * interquartile_range)].min
|
124
140
|
end
|
125
141
|
|
142
|
+
# @rbs return: Float | Integer
|
126
143
|
def upper_whisker
|
127
144
|
max = max_whisker
|
128
145
|
points.select { |point| point <= max }.max
|
129
146
|
end
|
130
147
|
|
148
|
+
# @rbs return: Float | Integer
|
131
149
|
def lower_whisker
|
132
150
|
min = min_whisker
|
133
151
|
points.select { |point| point >= min }.min
|
134
152
|
end
|
135
153
|
|
154
|
+
# @rbs return: Float
|
136
155
|
def median
|
137
156
|
if points.empty?
|
138
|
-
0
|
157
|
+
0.0
|
139
158
|
elsif points.size.odd?
|
140
|
-
points[points.size / 2]
|
159
|
+
points[points.size / 2].to_f
|
141
160
|
else
|
142
|
-
(points[points.size / 2] + points[(points.size / 2) - 1]) / 2.0
|
161
|
+
(points[points.size / 2].to_f + points[(points.size / 2) - 1].to_f) / 2.0
|
143
162
|
end
|
144
163
|
end
|
145
164
|
|
165
|
+
# @rbs return: Float
|
146
166
|
def first_quartile
|
147
167
|
if points.empty?
|
148
|
-
0
|
168
|
+
0.0
|
149
169
|
elsif points.size.odd?
|
150
|
-
points[points.size / 4]
|
170
|
+
points[points.size / 4].to_f
|
151
171
|
else
|
152
|
-
(points[points.size / 4] + points[(points.size / 4) - 1]) / 2.0
|
172
|
+
(points[points.size / 4].to_f + points[(points.size / 4) - 1].to_f) / 2.0
|
153
173
|
end
|
154
174
|
end
|
155
175
|
|
176
|
+
# @rbs return: Float
|
156
177
|
def third_quartile
|
157
178
|
if points.empty?
|
158
|
-
0
|
179
|
+
0.0
|
159
180
|
elsif points.size.odd?
|
160
|
-
points[(points.size * 3) / 4]
|
181
|
+
points[(points.size * 3) / 4].to_f
|
161
182
|
else
|
162
|
-
(points[(points.size * 3) / 4] + points[((points.size * 3) / 4) - 1]) / 2.0
|
183
|
+
(points[(points.size * 3) / 4].to_f + points[((points.size * 3) / 4) - 1].to_f) / 2.0
|
163
184
|
end
|
164
185
|
end
|
165
186
|
|
187
|
+
# @rbs return: Array[Float | Integer]
|
166
188
|
def lower_outliers
|
167
189
|
min = lower_whisker
|
168
190
|
points.select { |point| point < min }
|
169
191
|
end
|
170
192
|
|
193
|
+
# @rbs return: Array[Float | Integer]
|
171
194
|
def upper_outliers
|
172
195
|
max = upper_whisker
|
173
196
|
points.select { |point| point > max }
|
174
197
|
end
|
175
198
|
|
199
|
+
# @rbs return: Float | Integer
|
176
200
|
def interquartile_range
|
177
201
|
third_quartile - first_quartile
|
178
202
|
end
|
data/lib/gruff/bubble.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rbs_inline: enabled
|
4
|
+
|
3
5
|
#
|
4
6
|
# Here's how to set up a Gruff::Bubble.
|
5
7
|
#
|
@@ -9,10 +11,10 @@
|
|
9
11
|
#
|
10
12
|
class Gruff::Bubble < Gruff::Scatter
|
11
13
|
# Specifies the filling opacity in area graph. Default is +0.6+.
|
12
|
-
attr_writer :fill_opacity
|
14
|
+
attr_writer :fill_opacity #: Float | Integer
|
13
15
|
|
14
16
|
# Specifies the stroke width in line. Default is +1.0+.
|
15
|
-
attr_writer :stroke_width
|
17
|
+
attr_writer :stroke_width #: Float | Integer
|
16
18
|
|
17
19
|
# The first parameter is the name of the dataset. The next two are the
|
18
20
|
# x and y axis data points contain in their own array in that respective
|
@@ -53,6 +55,11 @@ class Gruff::Bubble < Gruff::Scatter
|
|
53
55
|
# g.title = "Bubble Graph"
|
54
56
|
# g.data :A, [-1, 19, -4, -23], [-35, 21, 23, -4], [4.5, 1.0, 2.1, 0.9]
|
55
57
|
#
|
58
|
+
# @rbs name: String | Symbol
|
59
|
+
# @rbs x_data_points: Array[nil | Float | Integer] | nil
|
60
|
+
# @rbs y_data_points: Array[nil | Float | Integer] | nil
|
61
|
+
# @rbs point_sizes: Array[nil | Float | Integer] | nil
|
62
|
+
# @rbs color: String
|
56
63
|
def data(name, x_data_points = [], y_data_points = [], point_sizes = [], color = nil)
|
57
64
|
# make sure it's an array
|
58
65
|
x_data_points = Array(x_data_points)
|
data/lib/gruff/bullet.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rbs_inline: enabled
|
4
|
+
|
3
5
|
#
|
4
6
|
# A bullet graph is a variation of a bar graph.
|
5
7
|
# http://en.wikipedia.org/wiki/Bullet_graph
|
@@ -12,6 +14,8 @@
|
|
12
14
|
# g.write('bullet.png')
|
13
15
|
#
|
14
16
|
class Gruff::Bullet < Gruff::Base
|
17
|
+
# @rbs target_width: String | Float | Integer
|
18
|
+
# @rbs return: void
|
15
19
|
def initialize(target_width = '400x40')
|
16
20
|
super
|
17
21
|
|
@@ -35,11 +39,14 @@ class Gruff::Bullet < Gruff::Base
|
|
35
39
|
end
|
36
40
|
private :initialize_attributes
|
37
41
|
|
42
|
+
# @rbs value: Float | Integer
|
43
|
+
# @rbs maximum_value: Float | Integer
|
44
|
+
# @rbs options: Hash[Symbol, Float | Integer]
|
38
45
|
def data(value, maximum_value, options = {})
|
39
46
|
@value = value.to_f
|
40
47
|
self.maximum_value = maximum_value.to_f
|
41
48
|
@options = options
|
42
|
-
@options.map { |k, v| @options[k] = v.to_f if v.
|
49
|
+
@options.map { |k, v| @options[k] = v.to_f if v.respond_to?(:to_f) }
|
43
50
|
end
|
44
51
|
|
45
52
|
def draw
|
data/lib/gruff/candlestick.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rbs_inline: enabled
|
4
|
+
|
3
5
|
#
|
4
6
|
# Here's how to set up a Gruff::Candlestick.
|
5
7
|
#
|
@@ -12,19 +14,19 @@
|
|
12
14
|
#
|
13
15
|
class Gruff::Candlestick < Gruff::Base
|
14
16
|
# Allow for vertical marker lines.
|
15
|
-
attr_writer :show_vertical_markers
|
17
|
+
attr_writer :show_vertical_markers #: bool
|
16
18
|
|
17
19
|
# Specifies the filling opacity in area graph. Default is +0.4+.
|
18
|
-
attr_writer :fill_opacity
|
20
|
+
attr_writer :fill_opacity #: Float | Integer
|
19
21
|
|
20
22
|
# Specifies the stroke width in line. Default is +2.0+.
|
21
|
-
attr_writer :stroke_width
|
23
|
+
attr_writer :stroke_width #: Float | Integer
|
22
24
|
|
23
25
|
# Specifies the color with up bar. Default is +'#579773'+.
|
24
|
-
attr_writer :up_color
|
26
|
+
attr_writer :up_color #: String
|
25
27
|
|
26
28
|
# Specifies the color with down bar. Default is +'#eb5242'+.
|
27
|
-
attr_writer :down_color
|
29
|
+
attr_writer :down_color #: String
|
28
30
|
|
29
31
|
# Can be used to adjust the spaces between the bars.
|
30
32
|
# Accepts values between 0.00 and 1.00 where 0.00 means no spacing at all
|
@@ -32,10 +34,12 @@ class Gruff::Candlestick < Gruff::Base
|
|
32
34
|
# line with no x dimension).
|
33
35
|
#
|
34
36
|
# Default value is +0.9+.
|
37
|
+
#
|
38
|
+
# @rbs space_percent: Float | Integer
|
35
39
|
def spacing_factor=(space_percent)
|
36
40
|
raise ArgumentError, 'spacing_factor must be between 0.00 and 1.00' if (space_percent < 0) || (space_percent > 1)
|
37
41
|
|
38
|
-
@spacing_factor = (1 - space_percent)
|
42
|
+
@spacing_factor = (1.0 - space_percent)
|
39
43
|
end
|
40
44
|
|
41
45
|
# The sort feature is not supported in this graph.
|
@@ -48,6 +52,10 @@ class Gruff::Candlestick < Gruff::Base
|
|
48
52
|
raise 'Not support #sorted_drawing= in Gruff::Candlestick'
|
49
53
|
end
|
50
54
|
|
55
|
+
# @rbs low: Float | Integer
|
56
|
+
# @rbs high: Float | Integer
|
57
|
+
# @rbs open: Float | Integer
|
58
|
+
# @rbs close: Float | Integer
|
51
59
|
def data(low:, high:, open:, close:)
|
52
60
|
super('', [low, high, open, close])
|
53
61
|
end
|
@@ -99,22 +107,36 @@ private
|
|
99
107
|
end
|
100
108
|
|
101
109
|
def normalized_candlesticks
|
102
|
-
@normalized_candlesticks ||= store.norm_data.map { |data| Gruff::Candlestick::CandlestickData.new(*data.points) }
|
110
|
+
@normalized_candlesticks ||= store.norm_data.map { |data| Gruff::Candlestick::CandlestickData.new(*data.points) } # steep:ignore
|
103
111
|
end
|
104
112
|
|
113
|
+
# @rbs return: Integer
|
105
114
|
def column_count
|
106
115
|
normalized_candlesticks.size
|
107
116
|
end
|
108
117
|
|
118
|
+
# @rbs return: Integer
|
109
119
|
def calculate_spacing
|
110
120
|
column_count - 1
|
111
121
|
end
|
112
122
|
|
123
|
+
# @rbs return: bool
|
113
124
|
def show_marker_vertical_line?
|
114
125
|
!@hide_line_markers && @show_vertical_markers
|
115
126
|
end
|
116
127
|
|
117
128
|
# @private
|
118
|
-
class CandlestickData
|
129
|
+
class CandlestickData
|
130
|
+
attr_accessor :low
|
131
|
+
attr_accessor :high
|
132
|
+
attr_accessor :open
|
133
|
+
attr_accessor :close
|
134
|
+
|
135
|
+
def initialize(low, high, open, close)
|
136
|
+
@low = low.to_f
|
137
|
+
@high = high.to_f
|
138
|
+
@open = open.to_f
|
139
|
+
@close = close.to_f
|
140
|
+
end
|
119
141
|
end
|
120
142
|
end
|
data/lib/gruff/dot.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rbs_inline: enabled
|
4
|
+
|
3
5
|
#
|
4
6
|
# Graph with dots and labels along a vertical access.
|
5
7
|
# see: 'Creating More Effective Graphs' by Robbins
|
@@ -15,9 +17,11 @@
|
|
15
17
|
#
|
16
18
|
class Gruff::Dot < Gruff::Base
|
17
19
|
# Prevent drawing of column labels below a stacked bar graph. Default is +false+.
|
18
|
-
attr_writer :hide_labels
|
20
|
+
attr_writer :hide_labels #: bool
|
19
21
|
|
20
|
-
|
22
|
+
# @rbs target_width: (String | Float | Integer)
|
23
|
+
# @rbs return: void
|
24
|
+
def initialize(target_width = DEFAULT_TARGET_WIDTH)
|
21
25
|
super
|
22
26
|
@has_left_labels = true
|
23
27
|
@dot_style = 'circle'
|
@@ -30,14 +34,17 @@ private
|
|
30
34
|
@hide_labels = false
|
31
35
|
end
|
32
36
|
|
37
|
+
# @rbs return: bool
|
33
38
|
def hide_labels?
|
34
39
|
@hide_labels
|
35
40
|
end
|
36
41
|
|
42
|
+
# @rbs return: bool
|
37
43
|
def hide_left_label_area?
|
38
44
|
hide_labels? && @y_axis_label.nil?
|
39
45
|
end
|
40
46
|
|
47
|
+
# @rbs return: bool
|
41
48
|
def hide_bottom_label_area?
|
42
49
|
@hide_line_markers && @x_axis_label.nil? && @legend_at_bottom == false
|
43
50
|
end
|
@@ -53,12 +60,13 @@ private
|
|
53
60
|
|
54
61
|
store.norm_data.each_with_index do |data_row, row_index|
|
55
62
|
data_row.points.each_with_index do |data_point, point_index|
|
56
|
-
x_pos = @graph_left + (data_point * @graph_width)
|
63
|
+
x_pos = @graph_left + (data_point.to_f * @graph_width)
|
57
64
|
y_pos = @graph_top + (items_width * point_index) + padding + (items_width / 2.0)
|
58
65
|
|
59
66
|
if row_index == 0
|
60
67
|
Gruff::Renderer::Line.new(renderer, color: @marker_color).render(@graph_left, y_pos, @graph_left + @graph_width, y_pos)
|
61
68
|
end
|
69
|
+
next if data_point.nil?
|
62
70
|
|
63
71
|
Gruff::Renderer::Dot.new(renderer, @dot_style, color: data_row.color).render(x_pos, y_pos, item_width / 3.0)
|
64
72
|
|
@@ -88,6 +96,8 @@ private
|
|
88
96
|
##
|
89
97
|
# Draw on the Y axis instead of the X
|
90
98
|
|
99
|
+
# @rbs y_offset: Float | Integer
|
100
|
+
# @rbs index: Integer
|
91
101
|
def draw_label(y_offset, index)
|
92
102
|
draw_unique_label(index) do
|
93
103
|
draw_label_at(@graph_left - @label_margin, 1.0, 0.0, y_offset, @labels[index], gravity: Magick::EastGravity)
|
data/lib/gruff/font.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rbs_inline: enabled
|
4
|
+
|
3
5
|
# Handle font setting to draw texts
|
4
6
|
class Gruff::Font
|
5
7
|
BOLD_PATH = File.expand_path(File.join(__FILE__, '../../../assets/fonts/Roboto-Bold.ttf')).freeze
|
@@ -9,17 +11,21 @@ class Gruff::Font
|
|
9
11
|
private_constant :REGULAR_PATH
|
10
12
|
|
11
13
|
# Get/set font path.
|
12
|
-
attr_accessor :path
|
14
|
+
attr_accessor :path #: String
|
13
15
|
|
14
16
|
# Get/set font size.
|
15
|
-
attr_accessor :size
|
17
|
+
attr_accessor :size #: Float | Integer
|
16
18
|
|
17
19
|
# Get/set font setting whether render bold text.
|
18
|
-
attr_accessor :bold
|
20
|
+
attr_accessor :bold #: bool
|
19
21
|
|
20
22
|
# Get/set font color.
|
21
|
-
attr_accessor :color
|
23
|
+
attr_accessor :color #: String
|
22
24
|
|
25
|
+
# @rbs path: String | nil
|
26
|
+
# @rbs size: Float | Integer
|
27
|
+
# @rbs bold: bool
|
28
|
+
# @rbs color: String
|
23
29
|
def initialize(path: nil, size: 20.0, bold: false, color: 'white')
|
24
30
|
@path = path
|
25
31
|
@bold = bold
|
@@ -29,11 +35,13 @@ class Gruff::Font
|
|
29
35
|
|
30
36
|
# Get font weight.
|
31
37
|
# @return [Magick::WeightType] font weight
|
38
|
+
# TODO: type annotation of return value
|
32
39
|
def weight
|
33
40
|
@bold ? Magick::BoldWeight : Magick::NormalWeight
|
34
41
|
end
|
35
42
|
|
36
43
|
# @private
|
44
|
+
# @rbs return: String
|
37
45
|
def file_path
|
38
46
|
return @path if @path
|
39
47
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rbs_inline: enabled
|
4
|
+
|
3
5
|
##
|
4
6
|
# Original Author: David Stokar
|
5
7
|
#
|
@@ -13,6 +15,12 @@
|
|
13
15
|
#
|
14
16
|
# @private
|
15
17
|
class Gruff::BarConversion
|
18
|
+
# @rbs top: Float | Integer
|
19
|
+
# @rbs bottom: Float | Integer
|
20
|
+
# @rbs minimum_value: Float | Integer
|
21
|
+
# @rbs maximum_value: Float | Integer
|
22
|
+
# @rbs spread: Float | Integer
|
23
|
+
# @rbs return: void
|
16
24
|
def initialize(top:, bottom:, minimum_value:, maximum_value:, spread:)
|
17
25
|
@graph_top = top
|
18
26
|
@graph_height = bottom - top
|
@@ -33,6 +41,8 @@ class Gruff::BarConversion
|
|
33
41
|
end
|
34
42
|
end
|
35
43
|
|
44
|
+
# @rbs data_point: Float | Integer
|
45
|
+
# @rbs return: [Float, Float]
|
36
46
|
def get_top_bottom_scaled(data_point)
|
37
47
|
data_point = data_point.to_f
|
38
48
|
result = []
|
@@ -53,6 +63,7 @@ class Gruff::BarConversion
|
|
53
63
|
result[1] = @graph_top + (@graph_height * (1 - @zero))
|
54
64
|
end
|
55
65
|
|
56
|
-
|
66
|
+
# TODO: Remove RBS type annotation
|
67
|
+
result #: [Float, Float]
|
57
68
|
end
|
58
69
|
end
|
@@ -1,8 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rbs_inline: enabled
|
4
|
+
|
3
5
|
# @private
|
4
6
|
module Gruff::Base::BarMixin
|
7
|
+
# @rbs return: Array[Array[Gruff::Base::BarMixin::BarData]]
|
5
8
|
def normalized_group_bars
|
9
|
+
# steep:ignore:start
|
6
10
|
@normalized_group_bars ||= begin
|
7
11
|
group_bars = Array.new(column_count) { [] }
|
8
12
|
store.norm_data.each_with_index do |data_row, row_index|
|
@@ -17,9 +21,23 @@ module Gruff::Base::BarMixin
|
|
17
21
|
end
|
18
22
|
group_bars
|
19
23
|
end
|
24
|
+
# steep:ignore:end
|
20
25
|
end
|
21
26
|
|
22
27
|
# @private
|
23
|
-
class BarData
|
28
|
+
class BarData
|
29
|
+
attr_accessor :point #: Float | Integer
|
30
|
+
attr_accessor :value #: nil | Float | Integer
|
31
|
+
attr_accessor :color #: String
|
32
|
+
|
33
|
+
# @rbs point: Float | Integer
|
34
|
+
# @rbs value: nil | Float | Integer
|
35
|
+
# @rbs color: String
|
36
|
+
# @rbs return: void
|
37
|
+
def initialize(point, value, color)
|
38
|
+
@point = point
|
39
|
+
@value = value
|
40
|
+
@color = color
|
41
|
+
end
|
24
42
|
end
|
25
43
|
end
|
@@ -1,16 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rbs_inline: enabled
|
4
|
+
|
3
5
|
# @private
|
4
6
|
module Gruff::BarValueLabel
|
5
7
|
using String::GruffCommify
|
6
8
|
|
7
9
|
# @private
|
10
|
+
#
|
11
|
+
# @rbs value: Float | Integer
|
12
|
+
# @rbs format: nil | String | Proc
|
13
|
+
# @rbs proc_text_metrics: Proc
|
14
|
+
# @rbs return: [String, untyped]
|
15
|
+
# TODO: Fix the return type
|
8
16
|
def self.metrics(value, format, proc_text_metrics)
|
9
17
|
val = begin
|
10
18
|
if format.is_a?(Proc)
|
11
19
|
format.call(value)
|
12
20
|
else
|
13
|
-
sprintf(format || '%.2f', value).commify
|
21
|
+
sprintf(format || '%.2f', value).commify # steep:ignore
|
14
22
|
end
|
15
23
|
end
|
16
24
|
|
@@ -20,8 +28,12 @@ module Gruff::BarValueLabel
|
|
20
28
|
|
21
29
|
# @private
|
22
30
|
class Base
|
23
|
-
attr_reader :coordinate,
|
31
|
+
attr_reader :coordinate #: [Float | Integer, Float | Integer, Float | Integer, Float | Integer]
|
32
|
+
attr_reader :value #: Float | Integer
|
24
33
|
|
34
|
+
# @rbs coordinate: [nil | Float | Integer, nil | Float | Integer, nil | Float | Integer, nil | Float | Integer]
|
35
|
+
# @rbs value: Float | Integer
|
36
|
+
# @rbs return: void
|
25
37
|
def initialize(coordinate, value)
|
26
38
|
@coordinate = coordinate
|
27
39
|
@value = value
|
@@ -30,22 +42,28 @@ module Gruff::BarValueLabel
|
|
30
42
|
|
31
43
|
# @private
|
32
44
|
class Bar < Base
|
45
|
+
# @rbs format: nil | String | Proc
|
46
|
+
# @rbs proc_text_metrics: Proc
|
47
|
+
# @rbs &: (Float | Integer, Float | Integer, String, Float, Float) -> void
|
33
48
|
def prepare_rendering(format, proc_text_metrics)
|
34
49
|
left_x, left_y, _right_x, _right_y = @coordinate
|
35
50
|
val, metrics = Gruff::BarValueLabel.metrics(@value, format, proc_text_metrics)
|
36
51
|
|
37
|
-
y = @value >= 0 ? left_y - metrics.height - 5 : left_y + 5
|
52
|
+
y = @value >= 0 ? left_y - metrics.height - 5 : left_y + 5 #: Float
|
38
53
|
yield left_x, y, val, metrics.width, metrics.height
|
39
54
|
end
|
40
55
|
end
|
41
56
|
|
42
57
|
# @private
|
43
58
|
class SideBar < Base
|
59
|
+
# @rbs format: nil | String | Proc
|
60
|
+
# @rbs proc_text_metrics: Proc
|
61
|
+
# @rbs &: (Float | Integer, Float | Integer, String, Float, Float) -> void
|
44
62
|
def prepare_rendering(format, proc_text_metrics)
|
45
63
|
left_x, left_y, right_x, _right_y = @coordinate
|
46
64
|
val, metrics = Gruff::BarValueLabel.metrics(@value, format, proc_text_metrics)
|
47
65
|
|
48
|
-
x = @value >= 0 ? right_x + 10 : left_x - metrics.width - 10
|
66
|
+
x = @value >= 0 ? right_x + 10 : left_x - metrics.width - 10 #: Float
|
49
67
|
yield x, left_y, val, metrics.width, metrics.height
|
50
68
|
end
|
51
69
|
end
|
@@ -1,11 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rbs_inline: enabled
|
4
|
+
|
3
5
|
# @private
|
4
6
|
module Gruff::Base::StackedMixin
|
5
7
|
# Used by StackedBar and child classes.
|
6
8
|
#
|
7
9
|
# tsal: moved from Base 03 FEB 2007
|
8
10
|
def calculate_maximum_by_stack
|
11
|
+
# steep:ignore:start
|
9
12
|
# Get sum of each stack
|
10
13
|
max_hash = Hash.new { |h, k| h[k] = 0.0 }
|
11
14
|
store.data.each do |data_set|
|
@@ -20,9 +23,12 @@ module Gruff::Base::StackedMixin
|
|
20
23
|
end
|
21
24
|
|
22
25
|
raise "Can't handle negative values in stacked graph" if minimum_value < 0
|
26
|
+
# steep:ignore:end
|
23
27
|
end
|
24
28
|
|
29
|
+
# @rbs return: Array[Array[Gruff::Base::StackedMixin::BarData]]
|
25
30
|
def normalized_stacked_bars
|
31
|
+
# steep:ignore:start
|
26
32
|
@normalized_stacked_bars ||= begin
|
27
33
|
stacked_bars = Array.new(column_count) { [] }
|
28
34
|
store.norm_data.each_with_index do |data_row, row_index|
|
@@ -32,9 +38,23 @@ module Gruff::Base::StackedMixin
|
|
32
38
|
end
|
33
39
|
stacked_bars
|
34
40
|
end
|
41
|
+
# steep:ignore:end
|
35
42
|
end
|
36
43
|
|
37
44
|
# @private
|
38
|
-
class BarData
|
45
|
+
class BarData
|
46
|
+
attr_accessor :point #: Float | Integer
|
47
|
+
attr_accessor :value #: Float | Integer
|
48
|
+
attr_accessor :color #: String
|
49
|
+
|
50
|
+
# @rbs point: Float | Integer
|
51
|
+
# @rbs value: Float | Integer
|
52
|
+
# @rbs color: String
|
53
|
+
# @rbs return: void
|
54
|
+
def initialize(point, value, color)
|
55
|
+
@point = point
|
56
|
+
@value = value
|
57
|
+
@color = color
|
58
|
+
end
|
39
59
|
end
|
40
60
|
end
|