gruff 0.25.0-java → 0.27.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.
- checksums.yaml +4 -4
- data/.editorconfig +2 -2
- data/.github/ISSUE_TEMPLATE/report.yml +41 -0
- data/.github/workflows/ci.yml +62 -9
- data/.rubocop.yml +5 -1
- data/CHANGELOG.md +22 -1
- data/Gemfile +8 -3
- data/README.md +9 -3
- 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 +205 -71
- 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 +45 -2
data/lib/gruff/base.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rbs_inline: enabled
|
4
|
+
|
3
5
|
require 'bigdecimal'
|
4
6
|
|
5
7
|
##
|
@@ -21,105 +23,106 @@ module Gruff
|
|
21
23
|
# A common base class inherited from class of drawing a graph.
|
22
24
|
class Base
|
23
25
|
# Space around text elements. Mostly used for vertical spacing.
|
24
|
-
LEGEND_MARGIN =
|
26
|
+
LEGEND_MARGIN = 20.0
|
27
|
+
TITLE_MARGIN = 20.0
|
25
28
|
LABEL_MARGIN = 15.0
|
26
29
|
DEFAULT_MARGIN = 20.0
|
27
30
|
|
28
31
|
DEFAULT_TARGET_WIDTH = 800.0
|
29
32
|
|
30
33
|
# Blank space between graph and labels. Default is +15+.
|
31
|
-
attr_writer :label_margin
|
34
|
+
attr_writer :label_margin #: Float | Integer
|
32
35
|
|
33
36
|
# Blank space above the graph. Default is +20+.
|
34
|
-
attr_writer :top_margin
|
37
|
+
attr_writer :top_margin #: Float | Integer
|
35
38
|
|
36
39
|
# Blank space below the graph. Default is +20+.
|
37
|
-
attr_writer :bottom_margin
|
40
|
+
attr_writer :bottom_margin #: Float | Integer
|
38
41
|
|
39
42
|
# Blank space to the right of the graph. Default is +20+.
|
40
|
-
attr_writer :right_margin
|
43
|
+
attr_writer :right_margin #: Float | Integer
|
41
44
|
|
42
45
|
# Blank space to the left of the graph. Default is +20+.
|
43
|
-
attr_writer :left_margin
|
46
|
+
attr_writer :left_margin #: Float | Integer
|
44
47
|
|
45
48
|
# Blank space below the title. Default is +20+.
|
46
|
-
attr_writer :title_margin
|
49
|
+
attr_writer :title_margin #: Float | Integer
|
47
50
|
|
48
51
|
# Blank space below the legend. Default is +20+.
|
49
|
-
attr_writer :legend_margin
|
52
|
+
attr_writer :legend_margin #: Float | Integer
|
50
53
|
|
51
54
|
# Truncates labels if longer than max specified.
|
52
|
-
attr_writer :label_max_size
|
55
|
+
attr_writer :label_max_size #: Float | Integer
|
53
56
|
|
54
57
|
# How truncated labels visually appear if they exceed {#label_max_size=}.
|
55
58
|
#
|
56
59
|
# - +:absolute+ - does not show trailing dots to indicate truncation. This is the default.
|
57
60
|
# - +:trailing_dots+ - shows trailing dots to indicate truncation (note that {#label_max_size=}
|
58
61
|
# must be greater than 3).
|
59
|
-
attr_writer :label_truncation_style
|
62
|
+
attr_writer :label_truncation_style #: (:absolute | :trailing_dots)
|
60
63
|
|
61
64
|
# Set a label for the bottom of the graph.
|
62
|
-
attr_writer :x_axis_label
|
65
|
+
attr_writer :x_axis_label #: String
|
63
66
|
|
64
67
|
# Set a label for the left side of the graph.
|
65
|
-
attr_writer :y_axis_label
|
68
|
+
attr_writer :y_axis_label #: String
|
66
69
|
|
67
70
|
# Allow passing lambda to format labels for x axis.
|
68
|
-
attr_writer :x_axis_label_format
|
71
|
+
attr_writer :x_axis_label_format #: Proc
|
69
72
|
|
70
73
|
# Allow passing lambda to format labels for y axis.
|
71
|
-
attr_writer :y_axis_label_format
|
74
|
+
attr_writer :y_axis_label_format #: Proc
|
72
75
|
|
73
76
|
# Set increment of the vertical marking lines.
|
74
|
-
attr_writer :x_axis_increment
|
77
|
+
attr_writer :x_axis_increment #: Float | Integer
|
75
78
|
|
76
79
|
# Set increment of the horizontal marking lines.
|
77
|
-
attr_writer :y_axis_increment
|
80
|
+
attr_writer :y_axis_increment #: Float | Integer
|
78
81
|
|
79
82
|
# Get or set the list of colors that will be used to draw the bars or lines.
|
80
|
-
attr_accessor :colors
|
83
|
+
attr_accessor :colors #: [String]
|
81
84
|
|
82
85
|
# Prevent drawing of line markers. Default is +false+.
|
83
|
-
attr_writer :hide_line_markers
|
86
|
+
attr_writer :hide_line_markers #: bool
|
84
87
|
|
85
88
|
# Prevent drawing of the legend. Default is +false+.
|
86
|
-
attr_writer :hide_legend
|
89
|
+
attr_writer :hide_legend #: bool
|
87
90
|
|
88
91
|
# Prevent drawing of the title. Default is +false+.
|
89
|
-
attr_writer :hide_title
|
92
|
+
attr_writer :hide_title #: bool
|
90
93
|
|
91
94
|
# Prevent drawing of line numbers. Default is +false+.
|
92
|
-
attr_writer :hide_line_numbers
|
95
|
+
attr_writer :hide_line_numbers #: bool
|
93
96
|
|
94
97
|
# Set a message shown when there is no data. Fits up to 20 characters. Defaults
|
95
98
|
# to +"No Data."+.
|
96
|
-
attr_writer :no_data_message
|
99
|
+
attr_writer :no_data_message #: String
|
97
100
|
|
98
101
|
# Set the color of the auxiliary lines.
|
99
|
-
attr_writer :marker_color
|
102
|
+
attr_writer :marker_color #: String
|
100
103
|
|
101
104
|
# Set the shadow color of the auxiliary lines.
|
102
|
-
attr_writer :marker_shadow_color
|
105
|
+
attr_writer :marker_shadow_color #: String
|
103
106
|
|
104
107
|
# Set the number of horizontal lines shown for reference.
|
105
|
-
attr_writer :marker_count
|
108
|
+
attr_writer :marker_count #: Float | Integer
|
106
109
|
|
107
110
|
# Set to +true+ if you want the data sets sorted with largest avg values drawn
|
108
111
|
# first. Default is +false+.
|
109
|
-
attr_writer :sort
|
112
|
+
attr_writer :sort #: bool
|
110
113
|
|
111
114
|
# Set to +true+ if you want the data sets drawn with largest avg values drawn
|
112
115
|
# first. This does not affect the legend. Default is +false+.
|
113
|
-
attr_writer :sorted_drawing
|
116
|
+
attr_writer :sorted_drawing #: bool
|
114
117
|
|
115
118
|
# Display the legend under the graph. Default is +false+.
|
116
|
-
attr_writer :legend_at_bottom
|
119
|
+
attr_writer :legend_at_bottom #: bool
|
117
120
|
|
118
121
|
# Optionally set the size of the colored box by each item in the legend.
|
119
122
|
# Default is +20.0+.
|
120
123
|
#
|
121
124
|
# Will be scaled down if graph is smaller than 800px wide.
|
122
|
-
attr_writer :legend_box_size
|
125
|
+
attr_writer :legend_box_size #: Float | Integer
|
123
126
|
|
124
127
|
# If one numerical argument is given, the graph is drawn at 4/3 ratio
|
125
128
|
# according to the given width (+800+ results in 800x600, +400+ gives 400x300,
|
@@ -129,6 +132,8 @@ module Gruff
|
|
129
132
|
#
|
130
133
|
# @param target_width [Numeric, String] The graph image width.
|
131
134
|
#
|
135
|
+
# @rbs target_width: (String | Float | Integer)
|
136
|
+
# @rbs return: void
|
132
137
|
def initialize(target_width = DEFAULT_TARGET_WIDTH)
|
133
138
|
if target_width.is_a?(String)
|
134
139
|
@columns, @rows = target_width.split('x').map(&:to_f)
|
@@ -182,6 +187,7 @@ module Gruff
|
|
182
187
|
@title_font = Gruff::Font.new(size: 36.0, bold: true)
|
183
188
|
@marker_font = Gruff::Font.new(size: 21.0)
|
184
189
|
@legend_font = Gruff::Font.new(size: 20.0)
|
190
|
+
@no_data_font = Gruff::Font.new(size: 80.0)
|
185
191
|
|
186
192
|
@label_margin = LABEL_MARGIN
|
187
193
|
@top_margin = @bottom_margin = @left_margin = @right_margin = DEFAULT_MARGIN
|
@@ -213,13 +219,15 @@ module Gruff
|
|
213
219
|
# Or, an array corresponding to the data values.
|
214
220
|
#
|
215
221
|
# @param labels [Hash, Array] the labels.
|
222
|
+
# @rbs labels: (Hash[Integer, String] | [String | nil])
|
216
223
|
#
|
217
224
|
# @example
|
218
225
|
# g = Gruff::Bar.new
|
219
|
-
# g.labels = { 0 => 2005, 3 => 2006, 5 => 2007, 7 => 2008 }
|
226
|
+
# g.labels = { 0 => '2005', 3 => '2006', 5 => '2007', 7 => '2008' }
|
220
227
|
#
|
221
228
|
# g = Gruff::Bar.new
|
222
229
|
# g.labels = ['2005', nil, nil, '2006', nil, nil, '2007', nil, nil, '2008'] # same labels for columns
|
230
|
+
#
|
223
231
|
def labels=(labels)
|
224
232
|
if labels.is_a?(Array)
|
225
233
|
labels = labels.each_with_index.with_object({}) do |(label, index), hash|
|
@@ -234,7 +242,7 @@ module Gruff
|
|
234
242
|
# You can use a rotation between +0.0+ and +45.0+, or between +0.0+ and +-45.0+.
|
235
243
|
#
|
236
244
|
# @param rotation [Numeric] the rotation.
|
237
|
-
#
|
245
|
+
# @rbs rotation: Float | Integer
|
238
246
|
def label_rotation=(rotation)
|
239
247
|
raise ArgumentError, 'rotation must be between 0.0 and 45.0 or between 0.0 and -45.0' if rotation > 45.0 || rotation < -45.0
|
240
248
|
|
@@ -252,6 +260,7 @@ module Gruff
|
|
252
260
|
# or by setting an array as argument.
|
253
261
|
#
|
254
262
|
# @param title [String, Array] the title.
|
263
|
+
# @rbs title: (String | Array[String])
|
255
264
|
#
|
256
265
|
# @example
|
257
266
|
# g = Gruff::Bar.new
|
@@ -259,6 +268,7 @@ module Gruff
|
|
259
268
|
#
|
260
269
|
# g = Gruff::Bar.new
|
261
270
|
# g.title = ['The first line of title', 'The second line of title']
|
271
|
+
#
|
262
272
|
def title=(title)
|
263
273
|
if title.is_a?(Array)
|
264
274
|
title = title.join("\n")
|
@@ -270,7 +280,7 @@ module Gruff
|
|
270
280
|
# Sets the top, bottom, left and right margins to +margin+.
|
271
281
|
#
|
272
282
|
# @param margin [Numeric] The margin size.
|
273
|
-
#
|
283
|
+
# @rbs margin: Float | Integer
|
274
284
|
def margins=(margin)
|
275
285
|
@top_margin = @left_margin = @right_margin = @bottom_margin = margin
|
276
286
|
end
|
@@ -278,17 +288,18 @@ module Gruff
|
|
278
288
|
# Sets the font for graph text to the font at +font_path+.
|
279
289
|
#
|
280
290
|
# @param font_path [String] The path to font.
|
281
|
-
#
|
291
|
+
# @rbs font_path: String
|
282
292
|
def font=(font_path)
|
283
293
|
@title_font.path = font_path unless @title_font.path
|
284
294
|
@marker_font.path = font_path
|
285
295
|
@legend_font.path = font_path
|
296
|
+
@no_data_font.path = font_path
|
286
297
|
end
|
287
298
|
|
288
299
|
# Same as {#font=} but for the title.
|
289
300
|
#
|
290
301
|
# @param font_path [String] The path to font.
|
291
|
-
#
|
302
|
+
# @rbs font_path: String
|
292
303
|
def title_font=(font_path)
|
293
304
|
@title_font.path = font_path
|
294
305
|
end
|
@@ -296,7 +307,7 @@ module Gruff
|
|
296
307
|
# Set the font size of the large title at the top of the graph. Default is +36+.
|
297
308
|
#
|
298
309
|
# @param value [Numeric] title font size
|
299
|
-
#
|
310
|
+
# @rbs value: Float | Integer
|
300
311
|
def title_font_size=(value)
|
301
312
|
@title_font.size = value
|
302
313
|
end
|
@@ -304,7 +315,7 @@ module Gruff
|
|
304
315
|
# The font size of the labels around the graph. Default is +21+.
|
305
316
|
#
|
306
317
|
# @param value [Numeric] marker font size
|
307
|
-
#
|
318
|
+
# @rbs value: Float | Integer
|
308
319
|
def marker_font_size=(value)
|
309
320
|
@marker_font.size = value
|
310
321
|
end
|
@@ -315,15 +326,23 @@ module Gruff
|
|
315
326
|
# Will be scaled down if the graph is smaller than 800px wide.
|
316
327
|
#
|
317
328
|
# @param value [Numeric] legend font size
|
318
|
-
#
|
329
|
+
# @rbs value: Float | Integer
|
319
330
|
def legend_font_size=(value)
|
320
331
|
@legend_font.size = value
|
321
332
|
end
|
322
333
|
|
334
|
+
# Set the font size of the no data message. Default is +80+.
|
335
|
+
#
|
336
|
+
# @param value [Numeric] no data font size
|
337
|
+
# @rbs value: Float | Integer
|
338
|
+
def no_data_font_size=(value)
|
339
|
+
@no_data_font.size = value
|
340
|
+
end
|
341
|
+
|
323
342
|
# Specifies whether to draw the title bolded or not. Default is +true+.
|
324
343
|
#
|
325
344
|
# @param value [Boolean] specifies whether to draw the title bolded or not.
|
326
|
-
#
|
345
|
+
# @rbs value: bool
|
327
346
|
def bold_title=(value)
|
328
347
|
@title_font.bold = value
|
329
348
|
end
|
@@ -331,16 +350,18 @@ module Gruff
|
|
331
350
|
# Specifies the text color.
|
332
351
|
#
|
333
352
|
# @param value [String] color
|
334
|
-
#
|
353
|
+
# @rbs value: String
|
335
354
|
def font_color=(value)
|
336
355
|
@title_font.color = value
|
337
356
|
@marker_font.color = value
|
338
357
|
@legend_font.color = value
|
358
|
+
@no_data_font.color = value
|
339
359
|
end
|
340
360
|
|
341
361
|
# Add a color to the list of available colors for lines.
|
342
362
|
#
|
343
363
|
# @param colorname [String] The color.
|
364
|
+
# @rbs colorname: String
|
344
365
|
#
|
345
366
|
# @example
|
346
367
|
# add_color('#c0e9d3')
|
@@ -360,6 +381,7 @@ module Gruff
|
|
360
381
|
# was in place at the time data was called.
|
361
382
|
#
|
362
383
|
# @param color_list [Array] The array of colors.
|
384
|
+
# @rbs color_list: Array[String]
|
363
385
|
#
|
364
386
|
# @example
|
365
387
|
# replace_colors ['#cc99cc', '#d9e043', '#34d8a2']
|
@@ -370,7 +392,7 @@ module Gruff
|
|
370
392
|
# Set whether to make background transparent.
|
371
393
|
#
|
372
394
|
# @param value [Boolean] Specify whether to make background transparent.
|
373
|
-
#
|
395
|
+
# @rbs value: bool
|
374
396
|
def transparent_background=(value)
|
375
397
|
@renderer.transparent_background(@columns, @rows) if value
|
376
398
|
end
|
@@ -405,7 +427,7 @@ module Gruff
|
|
405
427
|
# (Or hopefully something better looking than that.)
|
406
428
|
#
|
407
429
|
# @param options [Hash] The optional setting for theme
|
408
|
-
#
|
430
|
+
# @rbs options: Hash[Symbol, untyped]
|
409
431
|
def theme=(options)
|
410
432
|
reset_themes
|
411
433
|
|
@@ -470,8 +492,11 @@ module Gruff
|
|
470
492
|
# be used.
|
471
493
|
#
|
472
494
|
# @param name [String, Symbol] The name of the dataset.
|
495
|
+
# @rbs name: (String | Symbol)
|
473
496
|
# @param data_points [Array] The array of dataset.
|
497
|
+
# @rbs data_points: Array[Float | Integer] | nil
|
474
498
|
# @param color [String] The color for drawing graph of dataset.
|
499
|
+
# @rbs color: String
|
475
500
|
#
|
476
501
|
# @note
|
477
502
|
# If you want to use a preset theme, you must set it before calling {#data}.
|
@@ -486,25 +511,32 @@ module Gruff
|
|
486
511
|
# guessed for you.
|
487
512
|
#
|
488
513
|
# Set it after you have given all your data to the graph object.
|
514
|
+
#
|
515
|
+
# @return [Float] The minimum value.
|
516
|
+
# @rbs return: Float
|
489
517
|
def minimum_value
|
490
518
|
min = [0.0, store.min.to_f].min
|
491
519
|
(@minimum_value || min).to_f
|
492
520
|
end
|
493
|
-
attr_writer :minimum_value
|
521
|
+
attr_writer :minimum_value #: Float | Integer
|
494
522
|
|
495
523
|
# You can manually set a maximum value, such as a percentage-based graph
|
496
524
|
# that always goes to 100.
|
497
525
|
#
|
498
526
|
# If you use this, you must set it after you have given all your data to
|
499
527
|
# the graph object.
|
528
|
+
#
|
529
|
+
# @return [Float] The maximum value.
|
530
|
+
# @rbs return: Float
|
500
531
|
def maximum_value
|
501
532
|
(@maximum_value || store.max).to_f
|
502
533
|
end
|
503
|
-
attr_writer :maximum_value
|
534
|
+
attr_writer :maximum_value #: Float | Integer
|
504
535
|
|
505
536
|
# Writes the graph to a file. Defaults to +'graph.png'+
|
506
537
|
#
|
507
538
|
# @param file_name [String] The file name of output image.
|
539
|
+
# @rbs file_name: String
|
508
540
|
#
|
509
541
|
# @example
|
510
542
|
# write('graphs/my_pretty_graph.png')
|
@@ -516,8 +548,10 @@ module Gruff
|
|
516
548
|
# This can use RMagick's methods to adjust the image before saving.
|
517
549
|
#
|
518
550
|
# @param format [String] The output image format.
|
551
|
+
# @rbs format: String
|
519
552
|
#
|
520
553
|
# @return [Magick::Image] The rendered image.
|
554
|
+
# TODO: RBS signature
|
521
555
|
#
|
522
556
|
# @example
|
523
557
|
# g = Gruff::Line.new
|
@@ -540,6 +574,10 @@ module Gruff
|
|
540
574
|
# Return the graph as a rendered binary blob.
|
541
575
|
#
|
542
576
|
# @param format [String] The image format of binary blob.
|
577
|
+
# @rbs format: String
|
578
|
+
#
|
579
|
+
# @return [String] The binary string.
|
580
|
+
# @rbs return: String
|
543
581
|
#
|
544
582
|
# @deprecated Please use +to_image.to_blob+ instead.
|
545
583
|
def to_blob(format = 'PNG')
|
@@ -569,7 +607,7 @@ module Gruff
|
|
569
607
|
|
570
608
|
protected
|
571
609
|
|
572
|
-
attr_reader :renderer
|
610
|
+
attr_reader :renderer #: Gruff::Renderer
|
573
611
|
|
574
612
|
# Perform data manipulation before calculating chart measurements
|
575
613
|
def setup_data
|
@@ -595,8 +633,9 @@ module Gruff
|
|
595
633
|
sort_norm_data if @sorted_drawing # Sort norm_data with avg largest values set first (for display)
|
596
634
|
end
|
597
635
|
|
598
|
-
attr_reader :store
|
636
|
+
attr_reader :store #: Gruff::Store
|
599
637
|
|
638
|
+
# @rbs return: bool
|
600
639
|
def data_given?
|
601
640
|
@data_given ||= begin
|
602
641
|
if store.empty?
|
@@ -607,10 +646,12 @@ module Gruff
|
|
607
646
|
end
|
608
647
|
end
|
609
648
|
|
649
|
+
# @rbs return: Integer
|
610
650
|
def column_count
|
611
651
|
store.columns
|
612
652
|
end
|
613
653
|
|
654
|
+
# @rbs return: Integer
|
614
655
|
def marker_count
|
615
656
|
@marker_count ||= begin
|
616
657
|
count = nil
|
@@ -624,6 +665,7 @@ module Gruff
|
|
624
665
|
end
|
625
666
|
|
626
667
|
# Make copy of data with values scaled between 0-100
|
668
|
+
# @rbs return: Array[Gruff::Store::BasicData | Gruff::Store::XYData | Gruff::Store::XYPointsizeData]
|
627
669
|
def normalize
|
628
670
|
store.normalize(minimum: minimum_value, spread: @spread)
|
629
671
|
end
|
@@ -633,18 +675,22 @@ module Gruff
|
|
633
675
|
@spread = @spread > 0 ? @spread : 1.0
|
634
676
|
end
|
635
677
|
|
678
|
+
# @rbs return: bool
|
636
679
|
def hide_title?
|
637
680
|
@hide_title || @title.nil? || @title.empty?
|
638
681
|
end
|
639
682
|
|
683
|
+
# @rbs return: bool
|
640
684
|
def hide_labels?
|
641
685
|
@hide_line_markers
|
642
686
|
end
|
643
687
|
|
688
|
+
# @rbs return: bool
|
644
689
|
def hide_left_label_area?
|
645
690
|
@hide_line_markers && @y_axis_label.nil?
|
646
691
|
end
|
647
692
|
|
693
|
+
# @rbs return: bool
|
648
694
|
def hide_bottom_label_area?
|
649
695
|
@hide_line_markers && @x_axis_label.nil?
|
650
696
|
end
|
@@ -721,8 +767,10 @@ module Gruff
|
|
721
767
|
end
|
722
768
|
|
723
769
|
# Return a calculation of center
|
770
|
+
# @rbs size: Float | Integer
|
771
|
+
# @rbs return: Float
|
724
772
|
def center(size)
|
725
|
-
(@raw_columns - size) / 2
|
773
|
+
(@raw_columns - size) / 2.0
|
726
774
|
end
|
727
775
|
|
728
776
|
# Draws a legend with the names of the datasets matched
|
@@ -789,9 +837,14 @@ module Gruff
|
|
789
837
|
end
|
790
838
|
|
791
839
|
# Draws column labels below graph, centered over x
|
840
|
+
#
|
841
|
+
# @rbs x: Float | Integer
|
842
|
+
# @rbs index: Integer
|
843
|
+
# @rbs gravity: untyped
|
844
|
+
# @rbs &: () -> void
|
792
845
|
def draw_label(x, index, gravity = Magick::NorthGravity, &block)
|
793
846
|
draw_unique_label(index) do
|
794
|
-
if x
|
847
|
+
if x.between?(@graph_left, @graph_right)
|
795
848
|
y = @graph_bottom
|
796
849
|
x_offset, y_offset = calculate_label_offset(@marker_font, @labels[index], @label_margin, @label_rotation)
|
797
850
|
|
@@ -801,6 +854,8 @@ module Gruff
|
|
801
854
|
end
|
802
855
|
end
|
803
856
|
|
857
|
+
# @rbs index: Integer
|
858
|
+
# @rbs &: () -> void
|
804
859
|
def draw_unique_label(index)
|
805
860
|
return if hide_labels?
|
806
861
|
|
@@ -811,6 +866,13 @@ module Gruff
|
|
811
866
|
end
|
812
867
|
end
|
813
868
|
|
869
|
+
# @rbs width: Float | Integer
|
870
|
+
# @rbs height: Float | Integer
|
871
|
+
# @rbs x: Float | Integer
|
872
|
+
# @rbs y: Float | Integer
|
873
|
+
# @rbs text: String | _ToS
|
874
|
+
# @rbs gravity: untyped
|
875
|
+
# @rbs rotation: Float | Integer
|
814
876
|
def draw_label_at(width, height, x, y, text, gravity: Magick::NorthGravity, rotation: 0)
|
815
877
|
label_text = truncate_label_text(text)
|
816
878
|
text_renderer = Gruff::Renderer::Text.new(renderer, label_text, font: @marker_font, rotation: rotation)
|
@@ -818,6 +880,13 @@ module Gruff
|
|
818
880
|
end
|
819
881
|
|
820
882
|
# Draws the data value over the data point in bar graphs
|
883
|
+
#
|
884
|
+
# @rbs width: Float | Integer
|
885
|
+
# @rbs height: Float | Integer
|
886
|
+
# @rbs x_offset: Float | Integer
|
887
|
+
# @rbs y_offset: Float | Integer
|
888
|
+
# @rbs data_point: String | _ToS
|
889
|
+
# @rbs gravity: untyped
|
821
890
|
def draw_value_label(width, height, x_offset, y_offset, data_point, gravity: Magick::CenterGravity)
|
822
891
|
return if @hide_line_markers
|
823
892
|
|
@@ -826,9 +895,7 @@ module Gruff
|
|
826
895
|
|
827
896
|
# Shows an error message because you have no data.
|
828
897
|
def draw_no_data
|
829
|
-
font = @
|
830
|
-
font.size = 80
|
831
|
-
font.bold = false
|
898
|
+
font = @no_data_font
|
832
899
|
text_renderer = Gruff::Renderer::Text.new(renderer, @no_data_message, font: font)
|
833
900
|
text_renderer.render(@raw_columns, @raw_rows, 0, 0, Magick::CenterGravity)
|
834
901
|
end
|
@@ -842,10 +909,16 @@ module Gruff
|
|
842
909
|
@theme_options = {}
|
843
910
|
end
|
844
911
|
|
912
|
+
# @rbs value: Float | Integer
|
913
|
+
# @rbs max_value: Float | Integer
|
914
|
+
# @rbs return: Float | Integer
|
845
915
|
def clip_value_if_greater_than(value, max_value)
|
846
916
|
[value, max_value].min
|
847
917
|
end
|
848
918
|
|
919
|
+
# @rbs i: Integer
|
920
|
+
# @rbs return: Integer | Float | BigDecimal
|
921
|
+
# TODO: Fix return RBS signature
|
849
922
|
def significant(i)
|
850
923
|
return 1.0 if i == 0 # Keep from going into infinite loop
|
851
924
|
|
@@ -889,22 +962,27 @@ module Gruff
|
|
889
962
|
|
890
963
|
private
|
891
964
|
|
965
|
+
# @rbs return: Float
|
892
966
|
def marker_caps_height
|
893
|
-
hide_bottom_label_area? ? 0 : calculate_caps_height(@marker_font)
|
967
|
+
hide_bottom_label_area? ? 0.0 : calculate_caps_height(@marker_font)
|
894
968
|
end
|
895
969
|
|
970
|
+
# @rbs return: Float
|
896
971
|
def labels_caps_height
|
897
|
-
hide_bottom_label_area? ? 0 : calculate_labels_height(@marker_font)
|
972
|
+
hide_bottom_label_area? ? 0.0 : calculate_labels_height(@marker_font)
|
898
973
|
end
|
899
974
|
|
975
|
+
# @rbs return: Float
|
900
976
|
def title_caps_height
|
901
|
-
hide_title? ? 0 : calculate_caps_height(@title_font) * @title.lines.to_a.size
|
977
|
+
hide_title? ? 0.0 : Float(calculate_caps_height(@title_font) * @title.lines.to_a.size)
|
902
978
|
end
|
903
979
|
|
980
|
+
# @rbs return: Float
|
904
981
|
def legend_caps_height
|
905
|
-
@hide_legend ? 0 : calculate_caps_height(@legend_font)
|
982
|
+
@hide_legend ? 0.0 : calculate_caps_height(@legend_font)
|
906
983
|
end
|
907
984
|
|
985
|
+
# @rbs return: Float | Integer
|
908
986
|
def setup_left_margin
|
909
987
|
return @left_margin if hide_left_label_area?
|
910
988
|
|
@@ -932,49 +1010,60 @@ module Gruff
|
|
932
1010
|
@left_margin + [margin, bottom_label_width].max
|
933
1011
|
end
|
934
1012
|
|
1013
|
+
# @rbs return: Float
|
935
1014
|
def setup_right_margin
|
936
1015
|
@raw_columns - (@hide_line_markers ? @right_margin : @right_margin + extra_right_room_for_long_label)
|
937
1016
|
end
|
938
1017
|
|
1018
|
+
# @rbs return: Float | Integer
|
939
1019
|
def extra_left_room_for_long_label
|
940
1020
|
if require_extra_side_margin?
|
941
1021
|
width = calculate_width(@marker_font, truncate_label_text(@labels[0]), rotation: @label_rotation)
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
0
|
947
|
-
|
948
|
-
|
1022
|
+
result = begin
|
1023
|
+
case @label_rotation
|
1024
|
+
when 0
|
1025
|
+
width / 2.0
|
1026
|
+
when 0..45
|
1027
|
+
0
|
1028
|
+
when -45..0
|
1029
|
+
width
|
1030
|
+
end
|
949
1031
|
end
|
1032
|
+
result || 0
|
950
1033
|
else
|
951
1034
|
0
|
952
1035
|
end
|
953
1036
|
end
|
954
1037
|
|
1038
|
+
# @rbs return: Float | Integer
|
955
1039
|
def extra_right_room_for_long_label
|
956
1040
|
# Make space for half the width of the rightmost column label.
|
957
1041
|
# Might be greater than the number of columns if between-style bar markers are used.
|
958
1042
|
last_label = @labels.keys.max.to_i
|
959
1043
|
if last_label >= (column_count - 1) && require_extra_side_margin?
|
960
1044
|
width = calculate_width(@marker_font, truncate_label_text(@labels[last_label]), rotation: @label_rotation)
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
0
|
1045
|
+
result = begin
|
1046
|
+
case @label_rotation
|
1047
|
+
when 0
|
1048
|
+
width / 2.0
|
1049
|
+
when 0..45
|
1050
|
+
width
|
1051
|
+
when -45..0
|
1052
|
+
0
|
1053
|
+
end
|
968
1054
|
end
|
1055
|
+
result || 0
|
969
1056
|
else
|
970
1057
|
0
|
971
1058
|
end
|
972
1059
|
end
|
973
1060
|
|
1061
|
+
# @rbs return: bool
|
974
1062
|
def require_extra_side_margin?
|
975
1063
|
!hide_bottom_label_area? && @center_labels_over_point
|
976
1064
|
end
|
977
1065
|
|
1066
|
+
# @rbs return: Float
|
978
1067
|
def setup_top_margin
|
979
1068
|
# When @hide title, leave a title_margin space for aesthetics.
|
980
1069
|
# Same with @hide_legend
|
@@ -983,6 +1072,7 @@ module Gruff
|
|
983
1072
|
(@hide_legend || @legend_at_bottom ? @legend_margin : calculate_legend_height + @legend_margin)
|
984
1073
|
end
|
985
1074
|
|
1075
|
+
# @rbs return: Float
|
986
1076
|
def setup_bottom_margin
|
987
1077
|
graph_bottom_margin = hide_bottom_label_area? ? @bottom_margin : @bottom_margin + labels_caps_height + @label_margin
|
988
1078
|
graph_bottom_margin += (calculate_legend_height + @legend_margin) if @legend_at_bottom
|
@@ -991,6 +1081,8 @@ module Gruff
|
|
991
1081
|
@raw_rows - graph_bottom_margin - x_axis_label_height
|
992
1082
|
end
|
993
1083
|
|
1084
|
+
# @rbs text: String | _ToS
|
1085
|
+
# @rbs return: String
|
994
1086
|
def truncate_label_text(text)
|
995
1087
|
text = text.to_s
|
996
1088
|
return text if text.size <= @label_max_size
|
@@ -1001,11 +1093,15 @@ module Gruff
|
|
1001
1093
|
else
|
1002
1094
|
text = text[0..(@label_max_size - 1)]
|
1003
1095
|
end
|
1004
|
-
text
|
1096
|
+
text || ''
|
1005
1097
|
end
|
1006
1098
|
|
1007
1099
|
# Return a formatted string representing a number value that should be
|
1008
1100
|
# printed as a label.
|
1101
|
+
#
|
1102
|
+
# @rbs value: Float | Integer | BigDecimal
|
1103
|
+
# @rbs increment: Float | Integer | BigDecimal
|
1104
|
+
# @rbs return: String
|
1009
1105
|
def label(value, increment)
|
1010
1106
|
label = begin
|
1011
1107
|
if increment
|
@@ -1034,10 +1130,13 @@ module Gruff
|
|
1034
1130
|
end
|
1035
1131
|
|
1036
1132
|
parts = label.split('.')
|
1037
|
-
parts[0] = parts[0].commify
|
1133
|
+
parts[0] = parts[0].commify # steep:ignore
|
1038
1134
|
parts.join('.')
|
1039
1135
|
end
|
1040
1136
|
|
1137
|
+
# @rbs value: Float | Integer | BigDecimal
|
1138
|
+
# @rbs increment: Float | Integer | BigDecimal
|
1139
|
+
# @rbs return: String
|
1041
1140
|
def x_axis_label(value, increment)
|
1042
1141
|
if @x_axis_label_format
|
1043
1142
|
@x_axis_label_format.call(value)
|
@@ -1046,6 +1145,9 @@ module Gruff
|
|
1046
1145
|
end
|
1047
1146
|
end
|
1048
1147
|
|
1148
|
+
# @rbs value: Float | Integer | BigDecimal
|
1149
|
+
# @rbs increment: Float | Integer
|
1150
|
+
# @rbs return: String
|
1049
1151
|
def y_axis_label(value, increment)
|
1050
1152
|
if @y_axis_label_format
|
1051
1153
|
@y_axis_label_format.call(value)
|
@@ -1054,6 +1156,7 @@ module Gruff
|
|
1054
1156
|
end
|
1055
1157
|
end
|
1056
1158
|
|
1159
|
+
# TODO: RBS signature
|
1057
1160
|
def calculate_legend_label_widths_for_each_line(legend_labels, legend_square_width)
|
1058
1161
|
label_widths = [[]]
|
1059
1162
|
label_lines = [[]]
|
@@ -1076,6 +1179,7 @@ module Gruff
|
|
1076
1179
|
label_widths.map(&:sum).zip(label_lines)
|
1077
1180
|
end
|
1078
1181
|
|
1182
|
+
# TODO: RBS signature
|
1079
1183
|
def calculate_legend_height
|
1080
1184
|
return 0.0 if @hide_legend
|
1081
1185
|
|
@@ -1091,10 +1195,15 @@ module Gruff
|
|
1091
1195
|
#
|
1092
1196
|
# Not scaled since it deals with dimensions that the regular scaling will
|
1093
1197
|
# handle.
|
1198
|
+
#
|
1199
|
+
# @rbs font: Gruff::Font
|
1200
|
+
# @rbs return: Float
|
1094
1201
|
def calculate_caps_height(font)
|
1095
1202
|
calculate_height(font, 'X')
|
1096
1203
|
end
|
1097
1204
|
|
1205
|
+
# @rbs font: Gruff::Font
|
1206
|
+
# @rbs return: Float
|
1098
1207
|
def calculate_labels_height(font)
|
1099
1208
|
@labels.values.map { |label| calculate_height(font, label, rotation: @label_rotation) }.max || marker_caps_height
|
1100
1209
|
end
|
@@ -1103,9 +1212,14 @@ module Gruff
|
|
1103
1212
|
#
|
1104
1213
|
# Not scaled since it deals with dimensions that the regular scaling will
|
1105
1214
|
# handle.
|
1215
|
+
#
|
1216
|
+
# @rbs font: Gruff::Font
|
1217
|
+
# @rbs text: String
|
1218
|
+
# @rbs rotation: Float | Integer
|
1219
|
+
# @rbs return: Float
|
1106
1220
|
def calculate_height(font, text, rotation: 0)
|
1107
1221
|
text = text.to_s
|
1108
|
-
return 0 if text.empty?
|
1222
|
+
return 0.0 if text.empty?
|
1109
1223
|
|
1110
1224
|
metrics = text_metrics(font, text, rotation: rotation)
|
1111
1225
|
# Calculate manually because it does not return the height after rotation.
|
@@ -1116,6 +1230,11 @@ module Gruff
|
|
1116
1230
|
#
|
1117
1231
|
# Not scaled since it deals with dimensions that the regular
|
1118
1232
|
# scaling will handle.
|
1233
|
+
#
|
1234
|
+
# @rbs font: Gruff::Font
|
1235
|
+
# @rbs text: String
|
1236
|
+
# @rbs rotation: Float | Integer
|
1237
|
+
# @rbs return: Float | Integer
|
1119
1238
|
def calculate_width(font, text, rotation: 0)
|
1120
1239
|
text = text.to_s
|
1121
1240
|
return 0 if text.empty?
|
@@ -1125,10 +1244,15 @@ module Gruff
|
|
1125
1244
|
(metrics.width * Math.cos(deg2rad(rotation))).abs - (metrics.height * Math.sin(deg2rad(rotation))).abs
|
1126
1245
|
end
|
1127
1246
|
|
1247
|
+
# @rbs font: Gruff::Font
|
1248
|
+
# @rbs text: String
|
1249
|
+
# @rbs rotation: Float | Integer
|
1250
|
+
# @rbs return: untyped
|
1128
1251
|
def text_metrics(font, text, rotation: 0)
|
1129
1252
|
Gruff::Renderer::Text.new(renderer, text, font: font, rotation: rotation).metrics
|
1130
1253
|
end
|
1131
1254
|
|
1255
|
+
# @rbs return: Float | Integer | BigDecimal
|
1132
1256
|
def calculate_increment
|
1133
1257
|
if @y_axis_increment.nil?
|
1134
1258
|
# Try to use a number of horizontal lines that will come out even.
|
@@ -1142,6 +1266,11 @@ module Gruff
|
|
1142
1266
|
end
|
1143
1267
|
end
|
1144
1268
|
|
1269
|
+
# @rbs font: Gruff::Font
|
1270
|
+
# @rbs label: String
|
1271
|
+
# @rbs margin: Float | Integer
|
1272
|
+
# @rbs rotation: Float | Integer
|
1273
|
+
# @rbs return: [Float | Integer, Float | Integer]
|
1145
1274
|
def calculate_label_offset(font, label, margin, rotation)
|
1146
1275
|
width = calculate_width(font, label, rotation: rotation)
|
1147
1276
|
height = calculate_height(font, label, rotation: rotation)
|
@@ -1155,16 +1284,21 @@ module Gruff
|
|
1155
1284
|
-(width / 2.0)
|
1156
1285
|
end
|
1157
1286
|
end
|
1287
|
+
x_offset ||= 0
|
1158
1288
|
y_offset = [(height / 2.0), margin].max
|
1159
1289
|
|
1160
1290
|
[x_offset, y_offset]
|
1161
1291
|
end
|
1162
1292
|
|
1163
1293
|
# Used for degree <=> radian conversions
|
1294
|
+
# @rbs angle: Float | Integer
|
1295
|
+
# @rbs return: Float
|
1164
1296
|
def deg2rad(angle)
|
1165
1297
|
(angle * Math::PI) / 180.0
|
1166
1298
|
end
|
1167
1299
|
|
1300
|
+
# @rbs angle: Float | Integer
|
1301
|
+
# @rbs return: Float
|
1168
1302
|
def rad2deg(angle)
|
1169
1303
|
(angle / Math::PI) * 180.0
|
1170
1304
|
end
|