gruff 0.5.1-java → 0.10.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 +5 -5
- data/.editorconfig +14 -0
- data/.github/ISSUE_TEMPLATE.md +18 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +109 -0
- data/.rubocop_todo.yml +130 -0
- data/.travis.yml +24 -12
- data/.yardopts +1 -0
- data/{History.txt → CHANGELOG.md} +61 -25
- data/Gemfile +3 -7
- data/README.md +57 -25
- data/Rakefile +6 -201
- data/assets/plastik/blue.png +0 -0
- data/assets/plastik/green.png +0 -0
- data/assets/plastik/red.png +0 -0
- data/docker/Dockerfile +14 -0
- data/docker/build.sh +4 -0
- data/docker/launch.sh +4 -0
- data/gruff.gemspec +19 -14
- data/init.rb +2 -0
- data/lib/gruff.rb +26 -2
- data/lib/gruff/accumulator_bar.rb +18 -8
- data/lib/gruff/area.rb +33 -19
- data/lib/gruff/bar.rb +76 -45
- data/lib/gruff/base.rb +337 -613
- data/lib/gruff/bezier.rb +34 -19
- data/lib/gruff/bullet.rb +51 -62
- data/lib/gruff/dot.rb +38 -62
- data/lib/gruff/helper/bar_conversion.rb +47 -0
- data/lib/gruff/helper/bar_value_label_mixin.rb +30 -0
- data/lib/gruff/helper/stacked_mixin.rb +23 -0
- data/lib/gruff/histogram.rb +59 -0
- data/lib/gruff/line.rb +130 -150
- data/lib/gruff/mini/bar.rb +17 -10
- data/lib/gruff/mini/legend.rb +24 -36
- data/lib/gruff/mini/pie.rb +18 -12
- data/lib/gruff/mini/side_bar.rb +26 -12
- data/lib/gruff/net.rb +60 -84
- data/lib/gruff/patch/rmagick.rb +33 -0
- data/lib/gruff/patch/string.rb +10 -0
- data/lib/gruff/photo_bar.rb +27 -30
- data/lib/gruff/pie.rb +190 -93
- data/lib/gruff/renderer/bezier.rb +21 -0
- data/lib/gruff/renderer/circle.rb +21 -0
- data/lib/gruff/renderer/dash_line.rb +22 -0
- data/lib/gruff/renderer/dot.rb +39 -0
- data/lib/gruff/renderer/ellipse.rb +21 -0
- data/lib/gruff/renderer/line.rb +34 -0
- data/lib/gruff/renderer/polygon.rb +23 -0
- data/lib/gruff/renderer/polyline.rb +21 -0
- data/lib/gruff/renderer/rectangle.rb +19 -0
- data/lib/gruff/renderer/renderer.rb +127 -0
- data/lib/gruff/renderer/text.rb +42 -0
- data/lib/gruff/scatter.rb +156 -180
- data/lib/gruff/scene.rb +31 -41
- data/lib/gruff/side_bar.rb +77 -63
- data/lib/gruff/side_stacked_bar.rb +77 -60
- data/lib/gruff/spider.rb +37 -50
- data/lib/gruff/stacked_area.rb +32 -30
- data/lib/gruff/stacked_bar.rb +87 -49
- data/lib/gruff/store/base_data.rb +34 -0
- data/lib/gruff/store/custom_data.rb +34 -0
- data/lib/gruff/store/store.rb +80 -0
- data/lib/gruff/store/xy_data.rb +55 -0
- data/lib/gruff/themes.rb +32 -33
- data/lib/gruff/version.rb +3 -1
- metadata +88 -94
- data/Manifest.txt +0 -81
- data/RELEASE.md +0 -30
- data/assets/bubble.png +0 -0
- data/assets/city_scene/background/0000.png +0 -0
- data/assets/city_scene/background/0600.png +0 -0
- data/assets/city_scene/background/2000.png +0 -0
- data/assets/city_scene/clouds/cloudy.png +0 -0
- data/assets/city_scene/clouds/partly_cloudy.png +0 -0
- data/assets/city_scene/clouds/stormy.png +0 -0
- data/assets/city_scene/grass/default.png +0 -0
- data/assets/city_scene/haze/true.png +0 -0
- data/assets/city_scene/number_sample/1.png +0 -0
- data/assets/city_scene/number_sample/2.png +0 -0
- data/assets/city_scene/number_sample/default.png +0 -0
- data/assets/city_scene/sky/0000.png +0 -0
- data/assets/city_scene/sky/0200.png +0 -0
- data/assets/city_scene/sky/0400.png +0 -0
- data/assets/city_scene/sky/0600.png +0 -0
- data/assets/city_scene/sky/0800.png +0 -0
- data/assets/city_scene/sky/1000.png +0 -0
- data/assets/city_scene/sky/1200.png +0 -0
- data/assets/city_scene/sky/1400.png +0 -0
- data/assets/city_scene/sky/1500.png +0 -0
- data/assets/city_scene/sky/1700.png +0 -0
- data/assets/city_scene/sky/2000.png +0 -0
- data/assets/pc306715.jpg +0 -0
- data/lib/gruff/bar_conversion.rb +0 -46
- data/lib/gruff/deprecated.rb +0 -39
- data/lib/gruff/stacked_mixin.rb +0 -23
- data/test/gruff_test_case.rb +0 -154
- data/test/image_compare.rb +0 -58
- data/test/test_accumulator_bar.rb +0 -51
- data/test/test_area.rb +0 -134
- data/test/test_bar.rb +0 -505
- data/test/test_base.rb +0 -8
- data/test/test_bezier.rb +0 -33
- data/test/test_bullet.rb +0 -26
- data/test/test_dot.rb +0 -263
- data/test/test_legend.rb +0 -68
- data/test/test_line.rb +0 -657
- data/test/test_mini_bar.rb +0 -33
- data/test/test_mini_pie.rb +0 -25
- data/test/test_mini_side_bar.rb +0 -36
- data/test/test_net.rb +0 -231
- data/test/test_photo.rb +0 -41
- data/test/test_pie.rb +0 -154
- data/test/test_scatter.rb +0 -233
- data/test/test_scene.rb +0 -100
- data/test/test_side_bar.rb +0 -56
- data/test/test_sidestacked_bar.rb +0 -105
- data/test/test_spider.rb +0 -226
- data/test/test_stacked_area.rb +0 -52
- data/test/test_stacked_bar.rb +0 -52
data/lib/gruff/bezier.rb
CHANGED
|
@@ -1,25 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'gruff/base'
|
|
4
|
+
|
|
5
|
+
#
|
|
6
|
+
# Gruff::Bezier is a special line graph that have
|
|
7
|
+
# the bezier curve.
|
|
8
|
+
#
|
|
9
|
+
# Here's how to set up a Gruff::Bezier.
|
|
10
|
+
#
|
|
11
|
+
# dataset = [
|
|
12
|
+
# +0.00, +0.09, +0.19, +0.29, +0.38, +0.47, +0.56, +0.64, +0.71, +0.78,
|
|
13
|
+
# +0.84, +0.89, +0.93, +0.96, +0.98, +0.99, +0.99, +0.99, +0.97, +0.94,
|
|
14
|
+
# +0.90, +0.86, +0.80, +0.74, +0.67, +0.59, +0.51, +0.42, +0.33, +0.23,
|
|
15
|
+
# +0.14, +0.04, -0.06, -0.16, -0.26, -0.36, -0.45, -0.53, -0.62, -0.69,
|
|
16
|
+
# -0.76, -0.82, -0.88, -0.92, -0.96, -0.98, -1.00, -1.00, -1.00, -0.99,
|
|
17
|
+
# -0.96, -0.93, -0.89, -0.84, -0.78, -0.71, -0.64, -0.56, -0.47, -0.38,
|
|
18
|
+
# ]
|
|
19
|
+
# g = Gruff::Bezier.new
|
|
20
|
+
# g.data 'sin', dataset
|
|
21
|
+
# g.write('bezier.png')
|
|
22
|
+
#
|
|
3
23
|
class Gruff::Bezier < Gruff::Base
|
|
4
24
|
def draw
|
|
5
25
|
super
|
|
6
26
|
|
|
7
|
-
return unless
|
|
27
|
+
return unless data_given?
|
|
8
28
|
|
|
9
|
-
|
|
29
|
+
x_increment = @graph_width / (column_count - 1).to_f
|
|
10
30
|
|
|
11
|
-
|
|
12
|
-
poly_points =
|
|
13
|
-
@d = @d.fill data_row[DATA_COLOR_INDEX]
|
|
31
|
+
store.norm_data.each do |data_row|
|
|
32
|
+
poly_points = []
|
|
14
33
|
|
|
15
34
|
data_row[1].each_with_index do |data_point, index|
|
|
16
35
|
# Use incremented x and scaled y
|
|
17
|
-
new_x = @graph_left + (
|
|
36
|
+
new_x = @graph_left + (x_increment * index)
|
|
18
37
|
new_y = @graph_top + (@graph_height - data_point * @graph_height)
|
|
19
38
|
|
|
20
39
|
if index == 0 && RUBY_PLATFORM != 'java'
|
|
21
|
-
poly_points <<
|
|
22
|
-
poly_points <<
|
|
40
|
+
poly_points << new_x
|
|
41
|
+
poly_points << new_y
|
|
23
42
|
end
|
|
24
43
|
|
|
25
44
|
poly_points << new_x
|
|
@@ -27,20 +46,16 @@ class Gruff::Bezier < Gruff::Base
|
|
|
27
46
|
|
|
28
47
|
draw_label(new_x, index)
|
|
29
48
|
end
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
@d = @d.stroke data_row[DATA_COLOR_INDEX]
|
|
33
|
-
@d = @d.stroke_width clip_value_if_greater_than(@columns / (@norm_data.first[1].size * 4), 5.0)
|
|
49
|
+
|
|
50
|
+
stroke_width = clip_value_if_greater_than(@columns / (store.norm_data.first[1].size * 4), 5.0)
|
|
34
51
|
|
|
35
52
|
if RUBY_PLATFORM == 'java'
|
|
36
|
-
|
|
53
|
+
Gruff::Renderer::Polyline.new(color: data_row.color, width: stroke_width).render(poly_points)
|
|
37
54
|
else
|
|
38
|
-
|
|
55
|
+
Gruff::Renderer::Bezier.new(color: data_row.color, width: stroke_width).render(poly_points)
|
|
39
56
|
end
|
|
40
57
|
end
|
|
41
58
|
|
|
42
|
-
|
|
59
|
+
Gruff::Renderer.finish
|
|
43
60
|
end
|
|
44
|
-
|
|
45
|
-
|
|
46
61
|
end
|
data/lib/gruff/bullet.rb
CHANGED
|
@@ -1,11 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'gruff/base'
|
|
2
4
|
require 'gruff/themes'
|
|
3
5
|
|
|
6
|
+
#
|
|
7
|
+
# A bullet graph is a variation of a bar graph.
|
|
4
8
|
# http://en.wikipedia.org/wiki/Bullet_graph
|
|
9
|
+
#
|
|
10
|
+
# Here's how to set up a Gruff::Bullet.
|
|
11
|
+
#
|
|
12
|
+
# g = Gruff::Bullet.new
|
|
13
|
+
# g.title = 'Monthly Revenue'
|
|
14
|
+
# g.data 75, 100, { target: 80, low: 50, high: 90 }
|
|
15
|
+
# g.write('bullet.png')
|
|
16
|
+
#
|
|
5
17
|
class Gruff::Bullet < Gruff::Base
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if not Numeric === target_width
|
|
18
|
+
def initialize(target_width = '400x40')
|
|
19
|
+
if target_width.is_a?(String)
|
|
9
20
|
geometric_width, geometric_height = target_width.split('x')
|
|
10
21
|
@columns = geometric_width.to_f
|
|
11
22
|
@rows = geometric_height.to_f
|
|
@@ -13,6 +24,8 @@ class Gruff::Bullet < Gruff::Base
|
|
|
13
24
|
@columns = target_width.to_f
|
|
14
25
|
@rows = target_width.to_f / 5.0
|
|
15
26
|
end
|
|
27
|
+
@columns.freeze
|
|
28
|
+
@rows.freeze
|
|
16
29
|
|
|
17
30
|
initialize_ivars
|
|
18
31
|
|
|
@@ -21,32 +34,15 @@ class Gruff::Bullet < Gruff::Base
|
|
|
21
34
|
@title_font_size = 20
|
|
22
35
|
end
|
|
23
36
|
|
|
24
|
-
def data(value, maximum_value, options={})
|
|
37
|
+
def data(value, maximum_value, options = {})
|
|
25
38
|
@value = value.to_f
|
|
26
|
-
|
|
39
|
+
self.maximum_value = maximum_value.to_f
|
|
27
40
|
@options = options
|
|
28
|
-
@options.map { |k, v| @options[k] = v.to_f if v
|
|
41
|
+
@options.map { |k, v| @options[k] = v.to_f if v.is_a?(Numeric) }
|
|
29
42
|
end
|
|
30
43
|
|
|
31
|
-
# def setup_drawing
|
|
32
|
-
# # Maybe should be done in one of the following functions for more granularity.
|
|
33
|
-
# unless @has_data
|
|
34
|
-
# draw_no_data()
|
|
35
|
-
# return
|
|
36
|
-
# end
|
|
37
|
-
#
|
|
38
|
-
# normalize()
|
|
39
|
-
# setup_graph_measurements()
|
|
40
|
-
# sort_norm_data() if @sort # Sort norm_data with avg largest values set first (for display)
|
|
41
|
-
#
|
|
42
|
-
# draw_legend()
|
|
43
|
-
# draw_line_markers()
|
|
44
|
-
# draw_axis_labels()
|
|
45
|
-
# draw_title
|
|
46
|
-
# end
|
|
47
|
-
|
|
48
44
|
def draw
|
|
49
|
-
# TODO Left label
|
|
45
|
+
# TODO: Left label
|
|
50
46
|
# TODO Bottom labels and markers
|
|
51
47
|
# @graph_bottom
|
|
52
48
|
# Calculations are off 800x???
|
|
@@ -55,57 +51,50 @@ class Gruff::Bullet < Gruff::Base
|
|
|
55
51
|
|
|
56
52
|
draw_title
|
|
57
53
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
@
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
54
|
+
title_width = calculate_width(@title_font_size, @title)
|
|
55
|
+
margin = 30.0
|
|
56
|
+
thickness = @raw_rows / 6.0
|
|
57
|
+
right_margin = margin
|
|
58
|
+
graph_left = (@title && (title_width * 1.3)) || margin
|
|
59
|
+
graph_width = @raw_columns - graph_left - right_margin
|
|
60
|
+
graph_height = thickness * 3.0
|
|
64
61
|
|
|
65
62
|
# Background
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
rect_renderer = Gruff::Renderer::Rectangle.new(color: @colors[0])
|
|
64
|
+
rect_renderer.render(graph_left, 0, graph_left + graph_width, graph_height)
|
|
68
65
|
|
|
69
66
|
[:high, :low].each_with_index do |indicator, index|
|
|
70
|
-
next unless @options.
|
|
71
|
-
|
|
72
|
-
indicator_width_x
|
|
73
|
-
|
|
67
|
+
next unless @options.key?(indicator)
|
|
68
|
+
|
|
69
|
+
indicator_width_x = graph_left + graph_width * (@options[indicator] / maximum_value)
|
|
70
|
+
|
|
71
|
+
rect_renderer = Gruff::Renderer::Rectangle.new(color: @colors[index + 1])
|
|
72
|
+
rect_renderer.render(graph_left, 0, indicator_width_x, graph_height)
|
|
74
73
|
end
|
|
75
74
|
|
|
76
|
-
if @options.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
if @options.key?(:target)
|
|
76
|
+
target_x = graph_left + graph_width * (@options[:target] / maximum_value)
|
|
77
|
+
half_thickness = thickness / 2.0
|
|
78
|
+
|
|
79
|
+
rect_renderer = Gruff::Renderer::Rectangle.new(color: @font_color)
|
|
80
|
+
rect_renderer.render(target_x, half_thickness, target_x + half_thickness, thickness * 2 + half_thickness)
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
# Value
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
rect_renderer = Gruff::Renderer::Rectangle.new(color: @font_color)
|
|
85
|
+
rect_renderer.render(graph_left, thickness, graph_left + graph_width * (@value / maximum_value), thickness * 2)
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
Gruff::Renderer.finish
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
+
private
|
|
91
|
+
|
|
90
92
|
def draw_title
|
|
91
93
|
return unless @title
|
|
92
94
|
|
|
93
|
-
|
|
94
|
-
@title_width = calculate_width(@title_font_size, @title)
|
|
95
|
-
|
|
96
|
-
@d.fill = @font_color
|
|
97
|
-
@d.font = @font if @font
|
|
98
|
-
@d.stroke('transparent')
|
|
99
|
-
@d.font_weight = NormalWeight
|
|
100
|
-
@d.pointsize = scale_fontsize(@title_font_size)
|
|
101
|
-
@d.gravity = NorthWestGravity
|
|
102
|
-
@d = @d.annotate_scaled(*[
|
|
103
|
-
@base_image,
|
|
104
|
-
1.0, 1.0,
|
|
105
|
-
@font_height/2, @font_height/2,
|
|
106
|
-
@title,
|
|
107
|
-
@scale
|
|
108
|
-
])
|
|
109
|
-
end
|
|
95
|
+
font_height = calculate_caps_height(scale_fontsize(@title_font_size))
|
|
110
96
|
|
|
97
|
+
text_renderer = Gruff::Renderer::Text.new(@title, font: @font, size: @title_font_size, color: @font_color)
|
|
98
|
+
text_renderer.render(1.0, 1.0, font_height / 2, font_height / 2, Magick::NorthWestGravity)
|
|
99
|
+
end
|
|
111
100
|
end
|
data/lib/gruff/dot.rb
CHANGED
|
@@ -1,64 +1,60 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
# Graph with dots and labels along a vertical access
|
|
5
|
-
# see: 'Creating More Effective Graphs' by Robbins
|
|
3
|
+
require 'gruff/base'
|
|
6
4
|
|
|
5
|
+
#
|
|
6
|
+
# Graph with dots and labels along a vertical access.
|
|
7
|
+
# see: 'Creating More Effective Graphs' by Robbins
|
|
8
|
+
#
|
|
9
|
+
# Here's how to set up a Gruff::Dot.
|
|
10
|
+
#
|
|
11
|
+
# g = Gruff::Dot.new
|
|
12
|
+
# g.title = 'Dot Graph'
|
|
13
|
+
# g.data :Art, [0, 5, 8, 15]
|
|
14
|
+
# g.data :Philosophy, [10, 3, 2, 8]
|
|
15
|
+
# g.data :Science, [2, 15, 8, 11]
|
|
16
|
+
# g.write('dot.png')
|
|
17
|
+
#
|
|
7
18
|
class Gruff::Dot < Gruff::Base
|
|
8
|
-
|
|
9
19
|
def draw
|
|
10
20
|
@has_left_labels = true
|
|
11
21
|
super
|
|
12
22
|
|
|
13
|
-
return unless
|
|
23
|
+
return unless data_given?
|
|
14
24
|
|
|
15
25
|
# Setup spacing.
|
|
16
26
|
#
|
|
17
27
|
spacing_factor = 1.0
|
|
18
28
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
padding = (@items_width * (1 - spacing_factor)) / 2
|
|
29
|
+
items_width = @graph_height / column_count.to_f
|
|
30
|
+
item_width = items_width * spacing_factor / store.length
|
|
31
|
+
padding = (items_width * (1 - spacing_factor)) / 2
|
|
23
32
|
|
|
24
|
-
|
|
25
|
-
data_row
|
|
33
|
+
store.norm_data.each_with_index do |data_row, row_index|
|
|
34
|
+
data_row.points.each_with_index do |data_point, point_index|
|
|
26
35
|
x_pos = @graph_left + (data_point * @graph_width)
|
|
27
|
-
y_pos = @graph_top + (
|
|
36
|
+
y_pos = @graph_top + (items_width * point_index) + padding + (items_width.to_f / 2.0).round
|
|
28
37
|
|
|
29
38
|
if row_index == 0
|
|
30
|
-
|
|
31
|
-
@d = @d.fill(@marker_color)
|
|
32
|
-
@d = @d.stroke_width 1.0
|
|
33
|
-
@d = @d.stroke_opacity 0.1
|
|
34
|
-
@d = @d.fill_opacity 0.1
|
|
35
|
-
@d = @d.line(@graph_left, y_pos, @graph_left + @graph_width, y_pos)
|
|
36
|
-
@d = @d.fill_opacity 1
|
|
39
|
+
Gruff::Renderer::Line.new(color: @marker_color).render(@graph_left, y_pos, @graph_left + @graph_width, y_pos)
|
|
37
40
|
end
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
@d = @d.stroke('transparent')
|
|
41
|
-
@d = @d.circle(x_pos, y_pos, x_pos + (@item_width.to_f/3.0).round, y_pos)
|
|
42
|
+
Gruff::Renderer::Circle.new(color: data_row.color).render(x_pos, y_pos, x_pos + (item_width.to_f / 3.0).round, y_pos)
|
|
42
43
|
|
|
43
44
|
draw_label(y_pos, point_index)
|
|
44
45
|
end
|
|
45
|
-
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
Gruff::Renderer.finish
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
protected
|
|
52
52
|
|
|
53
53
|
# Instead of base class version, draws vertical background lines and label
|
|
54
54
|
def draw_line_markers
|
|
55
55
|
return if @hide_line_markers
|
|
56
56
|
|
|
57
|
-
@d = @d.stroke_antialias false
|
|
58
|
-
|
|
59
57
|
# Draw horizontal line markers and annotate with numbers
|
|
60
|
-
@d = @d.stroke(@marker_color)
|
|
61
|
-
@d = @d.stroke_width 1
|
|
62
58
|
if @y_axis_increment
|
|
63
59
|
increment = @y_axis_increment
|
|
64
60
|
number_of_lines = (@spread / @y_axis_increment).to_i
|
|
@@ -75,31 +71,21 @@ class Gruff::Dot < Gruff::Base
|
|
|
75
71
|
end
|
|
76
72
|
@marker_count ||= 5
|
|
77
73
|
end
|
|
78
|
-
# TODO Round maximum marker value to a round number like 100, 0.1, 0.5, etc.
|
|
79
|
-
|
|
80
|
-
|
|
74
|
+
# TODO: Round maximum marker value to a round number like 100, 0.1, 0.5, etc.
|
|
75
|
+
increment = (@spread > 0 && @marker_count > 0) ? significant(@spread / @marker_count) : 1
|
|
81
76
|
number_of_lines = @marker_count
|
|
82
|
-
increment = @increment
|
|
83
77
|
end
|
|
84
78
|
|
|
85
79
|
(0..number_of_lines).each do |index|
|
|
86
|
-
marker_label =
|
|
87
|
-
x = @graph_left + (marker_label -
|
|
88
|
-
|
|
80
|
+
marker_label = minimum_value + index * increment
|
|
81
|
+
x = @graph_left + (marker_label - minimum_value) * @graph_width / @spread
|
|
82
|
+
Gruff::Renderer::Line.new(color: @marker_color).render(x, @graph_bottom, x, @graph_bottom + 0.5 * LABEL_MARGIN)
|
|
89
83
|
|
|
90
84
|
unless @hide_line_numbers
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
@
|
|
94
|
-
|
|
95
|
-
@d.gravity = CenterGravity
|
|
96
|
-
# TODO Center text over line
|
|
97
|
-
@d = @d.annotate_scaled(@base_image,
|
|
98
|
-
0, 0, # Width of box to draw text in
|
|
99
|
-
x, @graph_bottom + (LABEL_MARGIN * 2.0), # Coordinates of text
|
|
100
|
-
label(marker_label, increment), @scale)
|
|
101
|
-
end # unless
|
|
102
|
-
@d = @d.stroke_antialias true
|
|
85
|
+
label = label(marker_label, increment)
|
|
86
|
+
text_renderer = Gruff::Renderer::Text.new(label, font: @font, size: @marker_font_size, color: @font_color)
|
|
87
|
+
text_renderer.render(0, 0, x, @graph_bottom + (LABEL_MARGIN * 2.0), Magick::CenterGravity)
|
|
88
|
+
end
|
|
103
89
|
end
|
|
104
90
|
end
|
|
105
91
|
|
|
@@ -107,19 +93,9 @@ class Gruff::Dot < Gruff::Base
|
|
|
107
93
|
# Draw on the Y axis instead of the X
|
|
108
94
|
|
|
109
95
|
def draw_label(y_offset, index)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
@
|
|
113
|
-
@d.stroke = 'transparent'
|
|
114
|
-
@d.font_weight = NormalWeight
|
|
115
|
-
@d.pointsize = scale_fontsize(@marker_font_size)
|
|
116
|
-
@d.gravity = EastGravity
|
|
117
|
-
@d = @d.annotate_scaled(@base_image,
|
|
118
|
-
1, 1,
|
|
119
|
-
-@graph_left + LABEL_MARGIN * 2.0, y_offset,
|
|
120
|
-
@labels[index], @scale)
|
|
121
|
-
@labels_seen[index] = 1
|
|
96
|
+
draw_unique_label(index) do
|
|
97
|
+
text_renderer = Gruff::Renderer::Text.new(@labels[index], font: @font, size: @marker_font_size, color: @font_color)
|
|
98
|
+
text_renderer.render(@graph_left - LABEL_MARGIN * 2, 1.0, 0.0, y_offset, Magick::EastGravity)
|
|
122
99
|
end
|
|
123
100
|
end
|
|
124
|
-
|
|
125
101
|
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# Original Author: David Stokar
|
|
5
|
+
#
|
|
6
|
+
# This class perfoms the y coordinats conversion for the bar class.
|
|
7
|
+
#
|
|
8
|
+
# There are three cases:
|
|
9
|
+
#
|
|
10
|
+
# 1. Bars all go from zero in positive direction
|
|
11
|
+
# 2. Bars all go from zero to negative direction
|
|
12
|
+
# 3. Bars either go from zero to positive or from zero to negative
|
|
13
|
+
#
|
|
14
|
+
# @private
|
|
15
|
+
class Gruff::BarConversion
|
|
16
|
+
attr_writer :mode
|
|
17
|
+
attr_writer :zero
|
|
18
|
+
attr_writer :graph_top
|
|
19
|
+
attr_writer :graph_height
|
|
20
|
+
attr_writer :minimum_value
|
|
21
|
+
attr_writer :spread
|
|
22
|
+
|
|
23
|
+
def get_left_y_right_y_scaled(data_point)
|
|
24
|
+
result = []
|
|
25
|
+
|
|
26
|
+
case @mode
|
|
27
|
+
when 1 then # Case one
|
|
28
|
+
# minimum value >= 0 ( only positive values )
|
|
29
|
+
result[0] = @graph_top + @graph_height * (1 - data_point) + 1
|
|
30
|
+
result[1] = @graph_top + @graph_height - 1
|
|
31
|
+
when 2 then # Case two
|
|
32
|
+
# only negative values
|
|
33
|
+
result[0] = @graph_top + 1
|
|
34
|
+
result[1] = @graph_top + @graph_height * (1 - data_point) - 1
|
|
35
|
+
when 3 then # Case three
|
|
36
|
+
# positive and negative values
|
|
37
|
+
val = data_point - @minimum_value / @spread
|
|
38
|
+
result[0] = @graph_top + @graph_height * (1 - (val - @zero)) + 1
|
|
39
|
+
result[1] = @graph_top + @graph_height * (1 - @zero) - 1
|
|
40
|
+
else
|
|
41
|
+
result[0] = 0.0
|
|
42
|
+
result[1] = 0.0
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
result
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# @private
|
|
4
|
+
module Gruff::Base::BarValueLabelMixin
|
|
5
|
+
class BarValueLabel
|
|
6
|
+
attr_accessor :coordinates, :values
|
|
7
|
+
|
|
8
|
+
def initialize(size, bar_width)
|
|
9
|
+
@coordinates = Array.new(size)
|
|
10
|
+
@values = Hash.new(0)
|
|
11
|
+
@bar_width = bar_width
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def prepare_rendering(format)
|
|
15
|
+
@coordinates.each_with_index do |(left_x, left_y, right_x, _right_y), index|
|
|
16
|
+
value = @values[index]
|
|
17
|
+
val = (format || '%.2f') % value
|
|
18
|
+
y = value >= 0 ? left_y - 30 : left_y + 12
|
|
19
|
+
yield left_x + (right_x - left_x) / 2, y, val.commify
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def prepare_sidebar_rendering(format)
|
|
24
|
+
@coordinates.each_with_index do |(_left_x, _left_y, right_x, right_y), index|
|
|
25
|
+
val = (format || '%.2f') % @values[index]
|
|
26
|
+
yield right_x + 40, right_y - @bar_width / 2, val.commify
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|