gruff 0.30.0 → 0.32.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/workflows/ci.yml +3 -3
- data/.github/workflows/release.yml +24 -0
- data/.rubocop.yml +4 -0
- data/.rubocop_todo.yml +0 -6
- data/CHANGELOG.md +21 -0
- data/lib/gruff/accumulator_bar.rb +1 -0
- data/lib/gruff/area.rb +2 -0
- data/lib/gruff/bar.rb +5 -5
- data/lib/gruff/base.rb +144 -90
- data/lib/gruff/bezier.rb +1 -0
- data/lib/gruff/box.rb +8 -0
- data/lib/gruff/bubble.rb +4 -0
- data/lib/gruff/bullet.rb +4 -0
- data/lib/gruff/candlestick.rb +17 -5
- data/lib/gruff/dot.rb +4 -5
- data/lib/gruff/font.rb +2 -0
- data/lib/gruff/helper/bar_value_label.rb +2 -0
- data/lib/gruff/helper/stacked_mixin.rb +1 -0
- data/lib/gruff/histogram.rb +3 -0
- data/lib/gruff/line.rb +28 -0
- data/lib/gruff/mini/bar.rb +3 -0
- data/lib/gruff/mini/legend.rb +13 -2
- data/lib/gruff/mini/pie.rb +3 -0
- data/lib/gruff/mini/side_bar.rb +3 -0
- data/lib/gruff/net.rb +6 -0
- data/lib/gruff/patch/rmagick.rb +10 -0
- data/lib/gruff/patch/string.rb +2 -0
- data/lib/gruff/pie.rb +8 -0
- data/lib/gruff/renderer/bezier.rb +1 -0
- data/lib/gruff/renderer/circle.rb +1 -0
- data/lib/gruff/renderer/dash_line.rb +1 -0
- data/lib/gruff/renderer/dot.rb +13 -0
- data/lib/gruff/renderer/ellipse.rb +1 -0
- data/lib/gruff/renderer/line.rb +7 -0
- data/lib/gruff/renderer/polygon.rb +1 -0
- data/lib/gruff/renderer/polyline.rb +1 -0
- data/lib/gruff/renderer/rectangle.rb +15 -5
- data/lib/gruff/renderer/renderer.rb +26 -3
- data/lib/gruff/renderer/text.rb +5 -1
- data/lib/gruff/scatter.rb +17 -0
- data/lib/gruff/side_bar.rb +9 -5
- data/lib/gruff/side_stacked_bar.rb +3 -0
- data/lib/gruff/spider.rb +26 -2
- data/lib/gruff/stacked_area.rb +5 -0
- data/lib/gruff/stacked_bar.rb +5 -5
- data/lib/gruff/store/basic_data.rb +4 -0
- data/lib/gruff/store/store.rb +8 -0
- data/lib/gruff/store/xy_data.rb +2 -0
- data/lib/gruff/store/xy_pointsizes_data.rb +2 -0
- data/lib/gruff/version.rb +1 -1
- data/lib/gruff.rb +2 -0
- data/sig/generated/gruff/accumulator_bar.rbs +2 -1
- data/sig/generated/gruff/area.rbs +4 -2
- data/sig/generated/gruff/bar.rbs +10 -8
- data/sig/generated/gruff/base.rbs +129 -64
- data/sig/generated/gruff/bezier.rbs +2 -1
- data/sig/generated/gruff/box.rbs +13 -5
- data/sig/generated/gruff/bubble.rbs +8 -4
- data/sig/generated/gruff/bullet.rbs +8 -4
- data/sig/generated/gruff/candlestick.rbs +24 -12
- data/sig/generated/gruff/dot.rbs +8 -7
- data/sig/generated/gruff/font.rbs +3 -1
- data/sig/generated/gruff/helper/bar_value_label.rbs +4 -2
- data/sig/generated/gruff/helper/stacked_mixin.rbs +2 -1
- data/sig/generated/gruff/histogram.rbs +6 -3
- data/sig/generated/gruff/line.rbs +44 -16
- data/sig/generated/gruff/mini/bar.rbs +6 -3
- data/sig/generated/gruff/mini/legend.rbs +20 -10
- data/sig/generated/gruff/mini/pie.rbs +6 -3
- data/sig/generated/gruff/mini/side_bar.rbs +6 -3
- data/sig/generated/gruff/net.rbs +12 -6
- data/sig/generated/gruff/patch/rmagick.rbs +12 -2
- data/sig/generated/gruff/patch/string.rbs +3 -1
- data/sig/generated/gruff/pie.rbs +15 -7
- data/sig/generated/gruff/renderer/bezier.rbs +2 -1
- data/sig/generated/gruff/renderer/circle.rbs +2 -1
- data/sig/generated/gruff/renderer/dash_line.rbs +2 -1
- data/sig/generated/gruff/renderer/dot.rbs +17 -4
- data/sig/generated/gruff/renderer/ellipse.rbs +2 -1
- data/sig/generated/gruff/renderer/line.rbs +9 -2
- data/sig/generated/gruff/renderer/polygon.rbs +2 -1
- data/sig/generated/gruff/renderer/polyline.rbs +2 -1
- data/sig/generated/gruff/renderer/rectangle.rbs +4 -2
- data/sig/generated/gruff/renderer/renderer.rbs +31 -8
- data/sig/generated/gruff/renderer/text.rbs +7 -3
- data/sig/generated/gruff/scatter.rbs +30 -13
- data/sig/generated/gruff/side_bar.rbs +15 -9
- data/sig/generated/gruff/side_stacked_bar.rbs +6 -3
- data/sig/generated/gruff/spider.rbs +35 -11
- data/sig/generated/gruff/stacked_area.rbs +9 -4
- data/sig/generated/gruff/stacked_bar.rbs +10 -8
- data/sig/generated/gruff/store/basic_data.rbs +8 -4
- data/sig/generated/gruff/store/store.rbs +12 -4
- data/sig/generated/gruff/store/xy_data.rbs +4 -2
- data/sig/generated/gruff/store/xy_pointsizes_data.rbs +4 -2
- data/sig/generated/gruff.rbs +3 -1
- metadata +3 -2
data/lib/gruff/base.rb
CHANGED
|
@@ -23,7 +23,7 @@ module Gruff
|
|
|
23
23
|
# A common base class inherited from class of drawing a graph.
|
|
24
24
|
class Base
|
|
25
25
|
# Space around text elements. Mostly used for vertical spacing.
|
|
26
|
-
LEGEND_MARGIN =
|
|
26
|
+
LEGEND_MARGIN = 10.0
|
|
27
27
|
TITLE_MARGIN = 20.0
|
|
28
28
|
LABEL_MARGIN = 15.0
|
|
29
29
|
DEFAULT_MARGIN = 20.0
|
|
@@ -48,9 +48,6 @@ module Gruff
|
|
|
48
48
|
# Blank space below the title. Default is +20+.
|
|
49
49
|
attr_writer :title_margin #: Float | Integer
|
|
50
50
|
|
|
51
|
-
# Blank space below the legend. Default is +20+.
|
|
52
|
-
attr_writer :legend_margin #: Float | Integer
|
|
53
|
-
|
|
54
51
|
# Truncates labels if longer than max specified.
|
|
55
52
|
attr_writer :label_max_size #: Float | Integer
|
|
56
53
|
|
|
@@ -115,13 +112,16 @@ module Gruff
|
|
|
115
112
|
# first. This does not affect the legend. Default is +false+.
|
|
116
113
|
attr_writer :sorted_drawing #: bool
|
|
117
114
|
|
|
118
|
-
#
|
|
119
|
-
attr_writer :
|
|
115
|
+
# Blank space below the legend. Default is +20+.
|
|
116
|
+
attr_writer :legend_margin #: Float | Integer
|
|
120
117
|
|
|
121
|
-
#
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
#
|
|
118
|
+
# Set the vertical spacing between individual legend items. Default is +5.0+.
|
|
119
|
+
attr_writer :legend_spacing #: Float | Integer
|
|
120
|
+
|
|
121
|
+
# Set the inner padding between the legend frame and its contents. Default is +7.0+.
|
|
122
|
+
attr_writer :legend_padding #: Float | Integer
|
|
123
|
+
|
|
124
|
+
# Optionally set the size of the colored box by each item in the legend. Default is +20.0+.
|
|
125
125
|
attr_writer :legend_box_size #: Float | Integer
|
|
126
126
|
|
|
127
127
|
# If one numerical argument is given, the graph is drawn at 4/3 ratio
|
|
@@ -154,6 +154,7 @@ module Gruff
|
|
|
154
154
|
self.theme = Themes::KEYNOTE
|
|
155
155
|
end
|
|
156
156
|
|
|
157
|
+
# @rbs return: void
|
|
157
158
|
def initialize_graph_scale
|
|
158
159
|
@raw_columns = DEFAULT_TARGET_WIDTH
|
|
159
160
|
@raw_rows = DEFAULT_TARGET_WIDTH * (@rows / @columns)
|
|
@@ -165,6 +166,7 @@ module Gruff
|
|
|
165
166
|
end
|
|
166
167
|
protected :initialize_graph_scale
|
|
167
168
|
|
|
169
|
+
# @rbs return: void
|
|
168
170
|
def initialize_store
|
|
169
171
|
@store = Gruff::Store.new(Gruff::Store::BasicData)
|
|
170
172
|
end
|
|
@@ -176,6 +178,8 @@ module Gruff
|
|
|
176
178
|
#
|
|
177
179
|
# This makes it possible to set defaults in a subclass but still allow
|
|
178
180
|
# developers to change this values in their program.
|
|
181
|
+
#
|
|
182
|
+
# @rbs return: void
|
|
179
183
|
def initialize_attributes
|
|
180
184
|
@marker_count = nil
|
|
181
185
|
@maximum_value = @minimum_value = nil
|
|
@@ -186,19 +190,22 @@ module Gruff
|
|
|
186
190
|
|
|
187
191
|
@title_font = Gruff::Font.new(size: 36.0, bold: true)
|
|
188
192
|
@marker_font = Gruff::Font.new(size: 21.0)
|
|
189
|
-
@legend_font = Gruff::Font.new(size:
|
|
193
|
+
@legend_font = Gruff::Font.new(size: 12.0)
|
|
190
194
|
@no_data_font = Gruff::Font.new(size: 80.0)
|
|
191
195
|
|
|
192
196
|
@label_margin = LABEL_MARGIN
|
|
193
197
|
@top_margin = @bottom_margin = @left_margin = @right_margin = DEFAULT_MARGIN
|
|
194
|
-
@legend_margin = LEGEND_MARGIN
|
|
195
198
|
@title_margin = TITLE_MARGIN
|
|
196
199
|
|
|
197
|
-
@
|
|
200
|
+
@legend_margin = LEGEND_MARGIN
|
|
201
|
+
@legend_spacing = 5.0
|
|
202
|
+
@legend_padding = 7.0
|
|
203
|
+
@legend_box_size = 10.0
|
|
204
|
+
@legend_position = :top_right
|
|
198
205
|
|
|
199
206
|
@no_data_message = 'No Data'
|
|
200
207
|
|
|
201
|
-
@hide_line_markers = @hide_legend = @hide_title = @hide_line_numbers =
|
|
208
|
+
@hide_line_markers = @hide_legend = @hide_title = @hide_line_numbers = false
|
|
202
209
|
@label_max_size = 0
|
|
203
210
|
@label_truncation_style = :absolute
|
|
204
211
|
@label_rotation = 0
|
|
@@ -228,6 +235,7 @@ module Gruff
|
|
|
228
235
|
# g = Gruff::Bar.new
|
|
229
236
|
# g.labels = ['2005', nil, nil, '2006', nil, nil, '2007', nil, nil, '2008'] # same labels for columns
|
|
230
237
|
#
|
|
238
|
+
# @rbs return: void
|
|
231
239
|
def labels=(labels)
|
|
232
240
|
if labels.is_a?(Array)
|
|
233
241
|
labels = labels.each_with_index.with_object({}) do |(label, index), hash|
|
|
@@ -243,18 +251,41 @@ module Gruff
|
|
|
243
251
|
#
|
|
244
252
|
# @param rotation [Numeric] the rotation.
|
|
245
253
|
# @rbs rotation: Float | Integer
|
|
254
|
+
# @rbs return: void
|
|
246
255
|
def label_rotation=(rotation)
|
|
247
256
|
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
|
|
248
257
|
|
|
249
258
|
@label_rotation = rotation.to_f
|
|
250
259
|
end
|
|
251
260
|
|
|
261
|
+
# Set the corner position of the floating legend. Accepts +:top_right+ (default),
|
|
262
|
+
# +:top_left+, +:bottom_right+, or +:bottom_left+.
|
|
263
|
+
#
|
|
264
|
+
# @param position [Symbol] the position.
|
|
265
|
+
# @rbs position: Symbol
|
|
266
|
+
# @rbs return: void
|
|
267
|
+
def legend_position=(position)
|
|
268
|
+
unless %i[top_right top_left bottom_right bottom_left].include?(position)
|
|
269
|
+
raise ArgumentError, 'Invalid legend position. Must be :top_right, :top_left, :bottom_right, or :bottom_left.'
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
@legend_position = position
|
|
273
|
+
end
|
|
274
|
+
|
|
252
275
|
# Height of staggering between labels.
|
|
253
276
|
# @deprecated
|
|
277
|
+
# @rbs return: void
|
|
254
278
|
def label_stagger_height=(_value)
|
|
255
279
|
warn '#label_stagger_height= is deprecated. It is no longer effective.'
|
|
256
280
|
end
|
|
257
281
|
|
|
282
|
+
# Set the legend position to the bottom of the graph.
|
|
283
|
+
# @deprecated
|
|
284
|
+
# @rbs return: void
|
|
285
|
+
def legend_at_bottom=(_value)
|
|
286
|
+
warn '#legend_at_bottom= is deprecated. It is no longer effective.'
|
|
287
|
+
end
|
|
288
|
+
|
|
258
289
|
# Set the large title of the graph displayed at the top.
|
|
259
290
|
# You can draw a multi-line title by putting a line break in the string
|
|
260
291
|
# or by setting an array as argument.
|
|
@@ -269,6 +300,7 @@ module Gruff
|
|
|
269
300
|
# g = Gruff::Bar.new
|
|
270
301
|
# g.title = ['The first line of title', 'The second line of title']
|
|
271
302
|
#
|
|
303
|
+
# @rbs return: void
|
|
272
304
|
def title=(title)
|
|
273
305
|
if title.is_a?(Array)
|
|
274
306
|
title = title.join("\n")
|
|
@@ -281,6 +313,7 @@ module Gruff
|
|
|
281
313
|
#
|
|
282
314
|
# @param margin [Numeric] The margin size.
|
|
283
315
|
# @rbs margin: Float | Integer
|
|
316
|
+
# @rbs return: void
|
|
284
317
|
def margins=(margin)
|
|
285
318
|
@top_margin = @left_margin = @right_margin = @bottom_margin = margin
|
|
286
319
|
end
|
|
@@ -289,6 +322,7 @@ module Gruff
|
|
|
289
322
|
#
|
|
290
323
|
# @param font_path [String] The path to font.
|
|
291
324
|
# @rbs font_path: String
|
|
325
|
+
# @rbs return: void
|
|
292
326
|
def font=(font_path)
|
|
293
327
|
@title_font.path = font_path unless @title_font.path
|
|
294
328
|
@marker_font.path = font_path
|
|
@@ -300,6 +334,7 @@ module Gruff
|
|
|
300
334
|
#
|
|
301
335
|
# @param font_path [String] The path to font.
|
|
302
336
|
# @rbs font_path: String
|
|
337
|
+
# @rbs return: void
|
|
303
338
|
def title_font=(font_path)
|
|
304
339
|
@title_font.path = font_path
|
|
305
340
|
end
|
|
@@ -308,6 +343,7 @@ module Gruff
|
|
|
308
343
|
#
|
|
309
344
|
# @param value [Numeric] title font size
|
|
310
345
|
# @rbs value: Float | Integer
|
|
346
|
+
# @rbs return: void
|
|
311
347
|
def title_font_size=(value)
|
|
312
348
|
@title_font.size = value
|
|
313
349
|
end
|
|
@@ -316,6 +352,7 @@ module Gruff
|
|
|
316
352
|
#
|
|
317
353
|
# @param value [Numeric] marker font size
|
|
318
354
|
# @rbs value: Float | Integer
|
|
355
|
+
# @rbs return: void
|
|
319
356
|
def marker_font_size=(value)
|
|
320
357
|
@marker_font.size = value
|
|
321
358
|
end
|
|
@@ -327,6 +364,7 @@ module Gruff
|
|
|
327
364
|
#
|
|
328
365
|
# @param value [Numeric] legend font size
|
|
329
366
|
# @rbs value: Float | Integer
|
|
367
|
+
# @rbs return: void
|
|
330
368
|
def legend_font_size=(value)
|
|
331
369
|
@legend_font.size = value
|
|
332
370
|
end
|
|
@@ -335,6 +373,7 @@ module Gruff
|
|
|
335
373
|
#
|
|
336
374
|
# @param value [Numeric] no data font size
|
|
337
375
|
# @rbs value: Float | Integer
|
|
376
|
+
# @rbs return: void
|
|
338
377
|
def no_data_font_size=(value)
|
|
339
378
|
@no_data_font.size = value
|
|
340
379
|
end
|
|
@@ -343,6 +382,7 @@ module Gruff
|
|
|
343
382
|
#
|
|
344
383
|
# @param value [Boolean] specifies whether to draw the title bolded or not.
|
|
345
384
|
# @rbs value: bool
|
|
385
|
+
# @rbs return: void
|
|
346
386
|
def bold_title=(value)
|
|
347
387
|
@title_font.bold = value
|
|
348
388
|
end
|
|
@@ -351,6 +391,7 @@ module Gruff
|
|
|
351
391
|
#
|
|
352
392
|
# @param value [String] color
|
|
353
393
|
# @rbs value: String
|
|
394
|
+
# @rbs return: void
|
|
354
395
|
def font_color=(value)
|
|
355
396
|
@title_font.color = value
|
|
356
397
|
@marker_font.color = value
|
|
@@ -365,6 +406,7 @@ module Gruff
|
|
|
365
406
|
#
|
|
366
407
|
# @example
|
|
367
408
|
# add_color('#c0e9d3')
|
|
409
|
+
# @rbs return: void
|
|
368
410
|
def add_color(colorname)
|
|
369
411
|
@colors << colorname
|
|
370
412
|
end
|
|
@@ -385,6 +427,7 @@ module Gruff
|
|
|
385
427
|
#
|
|
386
428
|
# @example
|
|
387
429
|
# replace_colors ['#cc99cc', '#d9e043', '#34d8a2']
|
|
430
|
+
# @rbs return: void
|
|
388
431
|
def replace_colors(color_list = [])
|
|
389
432
|
@colors = color_list
|
|
390
433
|
end
|
|
@@ -393,6 +436,7 @@ module Gruff
|
|
|
393
436
|
#
|
|
394
437
|
# @param value [Boolean] Specify whether to make background transparent.
|
|
395
438
|
# @rbs value: bool
|
|
439
|
+
# @rbs return: void
|
|
396
440
|
def transparent_background=(value)
|
|
397
441
|
@renderer.transparent_background(@columns, @rows) if value
|
|
398
442
|
end
|
|
@@ -428,6 +472,7 @@ module Gruff
|
|
|
428
472
|
#
|
|
429
473
|
# @param options [Hash] The optional setting for theme
|
|
430
474
|
# @rbs options: Hash[Symbol, untyped]
|
|
475
|
+
# @rbs return: void
|
|
431
476
|
def theme=(options)
|
|
432
477
|
reset_themes
|
|
433
478
|
|
|
@@ -451,31 +496,37 @@ module Gruff
|
|
|
451
496
|
end
|
|
452
497
|
|
|
453
498
|
# Apply Apple's keynote theme.
|
|
499
|
+
# @rbs return: void
|
|
454
500
|
def theme_keynote
|
|
455
501
|
self.theme = Themes::KEYNOTE
|
|
456
502
|
end
|
|
457
503
|
|
|
458
504
|
# Apply 37signals theme.
|
|
505
|
+
# @rbs return: void
|
|
459
506
|
def theme_37signals
|
|
460
507
|
self.theme = Themes::THIRTYSEVEN_SIGNALS
|
|
461
508
|
end
|
|
462
509
|
|
|
463
510
|
# Apply Rails theme.
|
|
511
|
+
# @rbs return: void
|
|
464
512
|
def theme_rails_keynote
|
|
465
513
|
self.theme = Themes::RAILS_KEYNOTE
|
|
466
514
|
end
|
|
467
515
|
|
|
468
516
|
# Apply Odeo theme.
|
|
517
|
+
# @rbs return: void
|
|
469
518
|
def theme_odeo
|
|
470
519
|
self.theme = Themes::ODEO
|
|
471
520
|
end
|
|
472
521
|
|
|
473
522
|
# Apply pastel theme.
|
|
523
|
+
# @rbs return: void
|
|
474
524
|
def theme_pastel
|
|
475
525
|
self.theme = Themes::PASTEL
|
|
476
526
|
end
|
|
477
527
|
|
|
478
528
|
# Apply greyscale theme.
|
|
529
|
+
# @rbs return: void
|
|
479
530
|
def theme_greyscale
|
|
480
531
|
self.theme = Themes::GREYSCALE
|
|
481
532
|
end
|
|
@@ -503,6 +554,7 @@ module Gruff
|
|
|
503
554
|
#
|
|
504
555
|
# @example
|
|
505
556
|
# data("Bart S.", [95, 45, 78, 89, 88, 76], '#ffcc00')
|
|
557
|
+
# @rbs return: void
|
|
506
558
|
def data(name, data_points = [], color = nil)
|
|
507
559
|
store.add(name, data_points, color)
|
|
508
560
|
end
|
|
@@ -540,6 +592,7 @@ module Gruff
|
|
|
540
592
|
#
|
|
541
593
|
# @example
|
|
542
594
|
# write('graphs/my_pretty_graph.png')
|
|
595
|
+
# @rbs return: void
|
|
543
596
|
def write(file_name = 'graph.png')
|
|
544
597
|
to_image.write(file_name)
|
|
545
598
|
end
|
|
@@ -561,6 +614,7 @@ module Gruff
|
|
|
561
614
|
# image = image.resize(400, 300).quantize(128, Magick::RGBColorspace)
|
|
562
615
|
# image.write('test.png')
|
|
563
616
|
#
|
|
617
|
+
# @rbs return: untyped
|
|
564
618
|
def to_image(format = 'PNG')
|
|
565
619
|
@to_image ||= begin
|
|
566
620
|
draw
|
|
@@ -587,6 +641,7 @@ module Gruff
|
|
|
587
641
|
end
|
|
588
642
|
|
|
589
643
|
# Draw a graph.
|
|
644
|
+
# @rbs return: void
|
|
590
645
|
def draw
|
|
591
646
|
setup_data
|
|
592
647
|
|
|
@@ -598,11 +653,11 @@ module Gruff
|
|
|
598
653
|
|
|
599
654
|
setup_drawing
|
|
600
655
|
|
|
601
|
-
draw_legend
|
|
602
656
|
draw_line_markers
|
|
603
657
|
draw_axis_labels
|
|
604
658
|
draw_title
|
|
605
659
|
draw_graph
|
|
660
|
+
draw_legend
|
|
606
661
|
end
|
|
607
662
|
|
|
608
663
|
protected
|
|
@@ -610,6 +665,7 @@ module Gruff
|
|
|
610
665
|
attr_reader :renderer #: Gruff::Renderer
|
|
611
666
|
|
|
612
667
|
# Perform data manipulation before calculating chart measurements
|
|
668
|
+
# @rbs return: void
|
|
613
669
|
def setup_data
|
|
614
670
|
if @y_axis_increment && !@hide_line_markers
|
|
615
671
|
self.maximum_value = [@y_axis_increment, maximum_value, (maximum_value / @y_axis_increment).round * @y_axis_increment].max
|
|
@@ -624,6 +680,7 @@ module Gruff
|
|
|
624
680
|
# * line markers
|
|
625
681
|
# * legend
|
|
626
682
|
# * title
|
|
683
|
+
# @rbs return: void
|
|
627
684
|
def setup_drawing
|
|
628
685
|
calculate_spread
|
|
629
686
|
calculate_increment
|
|
@@ -666,10 +723,12 @@ module Gruff
|
|
|
666
723
|
|
|
667
724
|
# Make copy of data with values scaled between 0-100
|
|
668
725
|
# @rbs return: Array[Gruff::Store::BasicData | Gruff::Store::XYData | Gruff::Store::XYPointsizeData]
|
|
726
|
+
# @rbs return: void
|
|
669
727
|
def normalize
|
|
670
728
|
store.normalize(minimum: minimum_value, spread: @spread)
|
|
671
729
|
end
|
|
672
730
|
|
|
731
|
+
# @rbs return: Float
|
|
673
732
|
def calculate_spread
|
|
674
733
|
@spread = maximum_value.to_f - minimum_value.to_f
|
|
675
734
|
@spread = @spread > 0 ? @spread : 1.0
|
|
@@ -698,6 +757,7 @@ module Gruff
|
|
|
698
757
|
##
|
|
699
758
|
# Calculates size of drawable area, general font dimensions, etc.
|
|
700
759
|
|
|
760
|
+
# @rbs return: void
|
|
701
761
|
def setup_graph_measurements
|
|
702
762
|
@graph_right = setup_right_margin
|
|
703
763
|
@graph_left = setup_left_margin
|
|
@@ -709,6 +769,7 @@ module Gruff
|
|
|
709
769
|
end
|
|
710
770
|
|
|
711
771
|
# Draw the optional labels for the x axis and y axis.
|
|
772
|
+
# @rbs return: void
|
|
712
773
|
def draw_axis_labels
|
|
713
774
|
if @x_axis_label
|
|
714
775
|
# X Axis
|
|
@@ -728,6 +789,7 @@ module Gruff
|
|
|
728
789
|
end
|
|
729
790
|
|
|
730
791
|
# Draws horizontal background lines and labels
|
|
792
|
+
# @rbs return: void
|
|
731
793
|
def draw_line_markers
|
|
732
794
|
return if @hide_line_markers
|
|
733
795
|
|
|
@@ -747,11 +809,16 @@ module Gruff
|
|
|
747
809
|
end
|
|
748
810
|
end
|
|
749
811
|
|
|
812
|
+
# @rbs y: Float | Integer
|
|
813
|
+
# @rbs return: void
|
|
750
814
|
def draw_marker_horizontal_line(y)
|
|
751
815
|
Gruff::Renderer::Line.new(renderer, color: @marker_color).render(@graph_left, y, @graph_right, y)
|
|
752
816
|
Gruff::Renderer::Line.new(renderer, color: @marker_shadow_color).render(@graph_left, y + 1, @graph_right, y + 1) if @marker_shadow_color
|
|
753
817
|
end
|
|
754
818
|
|
|
819
|
+
# @rbs x: Float | Integer
|
|
820
|
+
# @rbs tick_mark_mode: bool
|
|
821
|
+
# @rbs return: void
|
|
755
822
|
def draw_marker_vertical_line(x, tick_mark_mode: false)
|
|
756
823
|
if tick_mark_mode
|
|
757
824
|
Gruff::Renderer::Line.new(renderer, color: @marker_color).render(x, @graph_bottom, x, @graph_bottom + 5)
|
|
@@ -775,55 +842,68 @@ module Gruff
|
|
|
775
842
|
|
|
776
843
|
# Draws a legend with the names of the datasets matched
|
|
777
844
|
# to the colors used to draw them.
|
|
845
|
+
# @rbs return: void
|
|
778
846
|
def draw_legend
|
|
779
847
|
return if @hide_legend
|
|
780
848
|
|
|
781
|
-
legend_labels = store.data.map(&:label)
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
line_height = [legend_caps_height,
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
849
|
+
legend_labels = store.data.map(&:label).reject(&:empty?)
|
|
850
|
+
return if legend_labels.empty?
|
|
851
|
+
|
|
852
|
+
line_height = [legend_caps_height, @legend_box_size].max + @legend_spacing
|
|
853
|
+
max_legend_label_width = legend_labels.map { |l| calculate_width(@legend_font, l) }.max || 0.0
|
|
854
|
+
|
|
855
|
+
legend_content_width = (@legend_box_size * 1.5) + max_legend_label_width
|
|
856
|
+
legend_content_height = (line_height * (legend_labels.size - 1)) + @legend_box_size
|
|
857
|
+
|
|
858
|
+
case @legend_position
|
|
859
|
+
when :top_left
|
|
860
|
+
current_x_offset = @graph_left + @legend_margin
|
|
861
|
+
current_y_offset = @graph_top + @legend_margin + @legend_spacing
|
|
862
|
+
when :bottom_right
|
|
863
|
+
current_x_offset = @graph_right - @legend_margin - legend_content_width
|
|
864
|
+
current_y_offset = @graph_bottom - @legend_margin - legend_content_height
|
|
865
|
+
when :bottom_left
|
|
866
|
+
current_x_offset = @graph_left + @legend_margin
|
|
867
|
+
current_y_offset = @graph_bottom - @legend_margin - legend_content_height
|
|
868
|
+
else # :top_right (default)
|
|
869
|
+
current_x_offset = @graph_right - @legend_margin - legend_content_width
|
|
870
|
+
current_y_offset = @graph_top + @legend_margin + @legend_spacing
|
|
792
871
|
end
|
|
793
872
|
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
873
|
+
legend_items_end_x = current_x_offset + legend_content_width
|
|
874
|
+
legend_items_end_y = current_y_offset + legend_content_height
|
|
875
|
+
|
|
876
|
+
frame_renderer = Gruff::Renderer::Rectangle.new(renderer, color: @marker_color, width: 1.1, opacity: 0.2, round: true)
|
|
877
|
+
frame_renderer.render(current_x_offset - @legend_padding,
|
|
878
|
+
current_y_offset - @legend_padding,
|
|
879
|
+
legend_items_end_x + @legend_padding,
|
|
880
|
+
legend_items_end_y + @legend_padding)
|
|
881
|
+
|
|
882
|
+
store.data.each do |data_row|
|
|
883
|
+
legend_label = data_row.label
|
|
884
|
+
next if legend_label.empty?
|
|
885
|
+
|
|
886
|
+
legend_label_width = calculate_width(@legend_font, legend_label)
|
|
887
|
+
|
|
888
|
+
text_renderer = Gruff::Renderer::Text.new(renderer, legend_label, font: @legend_font)
|
|
889
|
+
text_renderer.add_to_render_queue(legend_label_width,
|
|
890
|
+
@legend_box_size,
|
|
891
|
+
current_x_offset + (@legend_box_size * 1.5),
|
|
892
|
+
current_y_offset,
|
|
893
|
+
Magick::CenterGravity)
|
|
894
|
+
|
|
895
|
+
rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: data_row.color)
|
|
896
|
+
rect_renderer.render(current_x_offset,
|
|
897
|
+
current_y_offset,
|
|
898
|
+
current_x_offset + @legend_box_size,
|
|
899
|
+
current_y_offset + @legend_box_size)
|
|
821
900
|
|
|
822
901
|
current_y_offset += line_height
|
|
823
902
|
end
|
|
824
903
|
end
|
|
825
904
|
|
|
826
905
|
# Draws a title on the graph.
|
|
906
|
+
# @rbs return: void
|
|
827
907
|
def draw_title
|
|
828
908
|
return if hide_title?
|
|
829
909
|
|
|
@@ -842,6 +922,7 @@ module Gruff
|
|
|
842
922
|
# @rbs index: Integer
|
|
843
923
|
# @rbs gravity: untyped
|
|
844
924
|
# @rbs &: () -> void
|
|
925
|
+
# @rbs return: void
|
|
845
926
|
def draw_label(x, index, gravity = Magick::NorthGravity, &block)
|
|
846
927
|
draw_unique_label(index) do
|
|
847
928
|
if x.between?(@graph_left, @graph_right)
|
|
@@ -856,6 +937,7 @@ module Gruff
|
|
|
856
937
|
|
|
857
938
|
# @rbs index: Integer
|
|
858
939
|
# @rbs yields: () -> void
|
|
940
|
+
# @rbs return: void
|
|
859
941
|
def draw_unique_label(index)
|
|
860
942
|
return if hide_labels?
|
|
861
943
|
|
|
@@ -873,6 +955,7 @@ module Gruff
|
|
|
873
955
|
# @rbs text: String | _ToS
|
|
874
956
|
# @rbs gravity: untyped
|
|
875
957
|
# @rbs rotation: Float | Integer
|
|
958
|
+
# @rbs return: void
|
|
876
959
|
def draw_label_at(width, height, x, y, text, gravity: Magick::NorthGravity, rotation: 0)
|
|
877
960
|
label_text = truncate_label_text(text)
|
|
878
961
|
text_renderer = Gruff::Renderer::Text.new(renderer, label_text, font: @marker_font, rotation: rotation)
|
|
@@ -887,6 +970,7 @@ module Gruff
|
|
|
887
970
|
# @rbs y_offset: Float | Integer
|
|
888
971
|
# @rbs data_point: String | _ToS
|
|
889
972
|
# @rbs gravity: untyped
|
|
973
|
+
# @rbs return: void
|
|
890
974
|
def draw_value_label(width, height, x_offset, y_offset, data_point, gravity: Magick::CenterGravity)
|
|
891
975
|
return if @hide_line_markers
|
|
892
976
|
|
|
@@ -894,17 +978,20 @@ module Gruff
|
|
|
894
978
|
end
|
|
895
979
|
|
|
896
980
|
# Shows an error message because you have no data.
|
|
981
|
+
# @rbs return: void
|
|
897
982
|
def draw_no_data
|
|
898
983
|
font = @no_data_font
|
|
899
984
|
text_renderer = Gruff::Renderer::Text.new(renderer, @no_data_message, font: font)
|
|
900
985
|
text_renderer.render(@raw_columns, @raw_rows, 0, 0, Magick::CenterGravity)
|
|
901
986
|
end
|
|
902
987
|
|
|
988
|
+
# @rbs return: void
|
|
903
989
|
def draw_graph
|
|
904
990
|
raise 'Should implement this method at inherited class.'
|
|
905
991
|
end
|
|
906
992
|
|
|
907
993
|
# Resets everything to defaults (except data).
|
|
994
|
+
# @rbs return: void
|
|
908
995
|
def reset_themes
|
|
909
996
|
@theme_options = {}
|
|
910
997
|
end
|
|
@@ -945,17 +1032,20 @@ module Gruff
|
|
|
945
1032
|
end
|
|
946
1033
|
|
|
947
1034
|
# Sort with largest overall summed value at front of array.
|
|
1035
|
+
# @rbs return: void
|
|
948
1036
|
def sort_data
|
|
949
1037
|
store.sort_data!
|
|
950
1038
|
end
|
|
951
1039
|
|
|
952
1040
|
# Set the color for each data set unless it was given in the data(...) call.
|
|
1041
|
+
# @rbs return: void
|
|
953
1042
|
def set_colors
|
|
954
1043
|
store.change_colors(@colors)
|
|
955
1044
|
end
|
|
956
1045
|
|
|
957
1046
|
# Sort with largest overall summed value at front of array so it shows up
|
|
958
1047
|
# correctly in the drawn graph.
|
|
1048
|
+
# @rbs return: void
|
|
959
1049
|
def sort_norm_data
|
|
960
1050
|
store.sort_norm_data!
|
|
961
1051
|
end
|
|
@@ -1068,14 +1158,12 @@ module Gruff
|
|
|
1068
1158
|
# When @hide title, leave a title_margin space for aesthetics.
|
|
1069
1159
|
# Same with @hide_legend
|
|
1070
1160
|
@top_margin +
|
|
1071
|
-
(hide_title? ? @title_margin : title_caps_height + @title_margin)
|
|
1072
|
-
(@hide_legend || @legend_at_bottom ? @legend_margin : calculate_legend_height + @legend_margin)
|
|
1161
|
+
(hide_title? ? @title_margin : title_caps_height + @title_margin)
|
|
1073
1162
|
end
|
|
1074
1163
|
|
|
1075
1164
|
# @rbs return: Float
|
|
1076
1165
|
def setup_bottom_margin
|
|
1077
1166
|
graph_bottom_margin = hide_bottom_label_area? ? @bottom_margin : @bottom_margin + labels_caps_height + @label_margin
|
|
1078
|
-
graph_bottom_margin += (calculate_legend_height + @legend_margin) if @legend_at_bottom
|
|
1079
1167
|
|
|
1080
1168
|
x_axis_label_height = @x_axis_label.nil? ? 0.0 : marker_caps_height + (@label_margin * 2)
|
|
1081
1169
|
@raw_rows - graph_bottom_margin - x_axis_label_height
|
|
@@ -1156,40 +1244,6 @@ module Gruff
|
|
|
1156
1244
|
end
|
|
1157
1245
|
end
|
|
1158
1246
|
|
|
1159
|
-
# TODO: RBS signature
|
|
1160
|
-
def calculate_legend_label_widths_for_each_line(legend_labels, legend_square_width)
|
|
1161
|
-
label_widths = [[]]
|
|
1162
|
-
label_lines = [[]]
|
|
1163
|
-
legend_labels.each do |label|
|
|
1164
|
-
if label.empty?
|
|
1165
|
-
label_width = 0.0
|
|
1166
|
-
else
|
|
1167
|
-
width = calculate_width(@legend_font, label)
|
|
1168
|
-
label_width = width + (legend_square_width * 2.7)
|
|
1169
|
-
end
|
|
1170
|
-
label_widths.last.push label_width
|
|
1171
|
-
label_lines.last.push label
|
|
1172
|
-
|
|
1173
|
-
if label_widths.last.sum > (@raw_columns * 0.9)
|
|
1174
|
-
label_widths.push [label_widths.last.pop]
|
|
1175
|
-
label_lines.push [label_lines.last.pop]
|
|
1176
|
-
end
|
|
1177
|
-
end
|
|
1178
|
-
|
|
1179
|
-
label_widths.map(&:sum).zip(label_lines)
|
|
1180
|
-
end
|
|
1181
|
-
|
|
1182
|
-
# TODO: RBS signature
|
|
1183
|
-
def calculate_legend_height
|
|
1184
|
-
return 0.0 if @hide_legend
|
|
1185
|
-
|
|
1186
|
-
legend_labels = store.data.map(&:label)
|
|
1187
|
-
legend_label_lines = calculate_legend_label_widths_for_each_line(legend_labels, @legend_box_size)
|
|
1188
|
-
line_height = [legend_caps_height, @legend_box_size].max
|
|
1189
|
-
|
|
1190
|
-
(line_height * legend_label_lines.count) + (@legend_margin * (legend_label_lines.count - 1))
|
|
1191
|
-
end
|
|
1192
|
-
|
|
1193
1247
|
# Returns the height of the capital letter 'X' for the current font and
|
|
1194
1248
|
# size.
|
|
1195
1249
|
#
|
data/lib/gruff/bezier.rb
CHANGED
data/lib/gruff/box.rb
CHANGED
|
@@ -26,6 +26,7 @@ class Gruff::Box < Gruff::Base
|
|
|
26
26
|
# Default value is +0.8+.
|
|
27
27
|
#
|
|
28
28
|
# @rbs space_percent: Float | Integer
|
|
29
|
+
# @rbs return: void
|
|
29
30
|
def spacing_factor=(space_percent)
|
|
30
31
|
raise ArgumentError, 'spacing_factor must be between 0.00 and 1.00' if (space_percent < 0) || (space_percent > 1)
|
|
31
32
|
|
|
@@ -34,6 +35,7 @@ class Gruff::Box < Gruff::Base
|
|
|
34
35
|
|
|
35
36
|
private
|
|
36
37
|
|
|
38
|
+
# @rbs return: void
|
|
37
39
|
def initialize_attributes
|
|
38
40
|
super
|
|
39
41
|
@fill_opacity = 0.2
|
|
@@ -41,6 +43,7 @@ private
|
|
|
41
43
|
@spacing_factor = 0.8
|
|
42
44
|
end
|
|
43
45
|
|
|
46
|
+
# @rbs return: void
|
|
44
47
|
def draw_graph
|
|
45
48
|
# Setup the BarConversion Object
|
|
46
49
|
conversion = Gruff::BarConversion.new(
|
|
@@ -93,6 +96,7 @@ private
|
|
|
93
96
|
end
|
|
94
97
|
end
|
|
95
98
|
|
|
99
|
+
# @rbs return: Array[Gruff::Box::BoxData]
|
|
96
100
|
def normalized_boxes
|
|
97
101
|
@normalized_boxes ||= store.norm_data.map { |data| Gruff::Box::BoxData.new(data.label, data.points, data.color) }
|
|
98
102
|
end
|
|
@@ -113,6 +117,10 @@ private
|
|
|
113
117
|
attr_accessor :points #: Array[Float | Integer]
|
|
114
118
|
attr_accessor :color #: String
|
|
115
119
|
|
|
120
|
+
# @rbs label: String
|
|
121
|
+
# @rbs points: Array[Float | Integer]
|
|
122
|
+
# @rbs color: String
|
|
123
|
+
# @rbs return: void
|
|
116
124
|
def initialize(label, points, color)
|
|
117
125
|
@label = label
|
|
118
126
|
@points = points.compact.sort
|