gruff 0.9.0-java → 0.12.2-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +21 -4
- data/.rubocop_todo.yml +103 -49
- data/.travis.yml +3 -6
- data/CHANGELOG.md +30 -0
- data/README.md +4 -0
- data/gruff.gemspec +8 -3
- data/lib/gruff.rb +9 -3
- data/lib/gruff/accumulator_bar.rb +13 -5
- data/lib/gruff/area.rb +22 -5
- data/lib/gruff/bar.rb +38 -10
- data/lib/gruff/base.rb +325 -236
- data/lib/gruff/bezier.rb +18 -4
- data/lib/gruff/bullet.rb +22 -14
- data/lib/gruff/dot.rb +20 -33
- data/lib/gruff/helper/bar_conversion.rb +7 -7
- data/lib/gruff/helper/bar_value_label_mixin.rb +3 -0
- data/lib/gruff/helper/stacked_mixin.rb +1 -1
- data/lib/gruff/histogram.rb +59 -0
- data/lib/gruff/line.rb +33 -28
- data/lib/gruff/mini/bar.rb +10 -2
- data/lib/gruff/mini/legend.rb +9 -4
- data/lib/gruff/mini/pie.rb +9 -3
- data/lib/gruff/mini/side_bar.rb +18 -4
- data/lib/gruff/net.rb +41 -21
- data/lib/gruff/patch/rmagick.rb +22 -24
- data/lib/gruff/patch/string.rb +9 -4
- data/lib/gruff/photo_bar.rb +12 -16
- data/lib/gruff/pie.rb +24 -34
- data/lib/gruff/renderer/bezier.rb +4 -3
- data/lib/gruff/renderer/circle.rb +4 -3
- data/lib/gruff/renderer/dash_line.rb +4 -3
- data/lib/gruff/renderer/dot.rb +4 -3
- data/lib/gruff/renderer/ellipse.rb +4 -3
- data/lib/gruff/renderer/line.rb +14 -5
- data/lib/gruff/renderer/polygon.rb +5 -4
- data/lib/gruff/renderer/polyline.rb +4 -3
- data/lib/gruff/renderer/rectangle.rb +3 -2
- data/lib/gruff/renderer/renderer.rb +31 -38
- data/lib/gruff/renderer/text.rb +29 -7
- data/lib/gruff/scatter.rb +26 -24
- data/lib/gruff/scene.rb +0 -1
- data/lib/gruff/side_bar.rb +51 -20
- data/lib/gruff/side_stacked_bar.rb +42 -15
- data/lib/gruff/spider.rb +29 -17
- data/lib/gruff/stacked_area.rb +19 -8
- data/lib/gruff/stacked_bar.rb +34 -13
- data/lib/gruff/store/{base_data.rb → basic_data.rb} +9 -7
- data/lib/gruff/store/custom_data.rb +8 -6
- data/lib/gruff/store/store.rb +7 -6
- data/lib/gruff/store/xy_data.rb +10 -7
- data/lib/gruff/version.rb +1 -1
- metadata +33 -8
- data/Rakefile +0 -23
- data/docker/Dockerfile +0 -14
- data/docker/build.sh +0 -4
- data/docker/launch.sh +0 -4
data/lib/gruff/bezier.rb
CHANGED
@@ -1,7 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
#
|
4
|
+
# Gruff::Bezier is a special line graph that have
|
5
|
+
# the bezier curve.
|
6
|
+
#
|
7
|
+
# Here's how to set up a Gruff::Bezier.
|
8
|
+
#
|
9
|
+
# dataset = [
|
10
|
+
# +0.00, +0.09, +0.19, +0.29, +0.38, +0.47, +0.56, +0.64, +0.71, +0.78,
|
11
|
+
# +0.84, +0.89, +0.93, +0.96, +0.98, +0.99, +0.99, +0.99, +0.97, +0.94,
|
12
|
+
# +0.90, +0.86, +0.80, +0.74, +0.67, +0.59, +0.51, +0.42, +0.33, +0.23,
|
13
|
+
# +0.14, +0.04, -0.06, -0.16, -0.26, -0.36, -0.45, -0.53, -0.62, -0.69,
|
14
|
+
# -0.76, -0.82, -0.88, -0.92, -0.96, -0.98, -1.00, -1.00, -1.00, -0.99,
|
15
|
+
# -0.96, -0.93, -0.89, -0.84, -0.78, -0.71, -0.64, -0.56, -0.47, -0.38,
|
16
|
+
# ]
|
17
|
+
# g = Gruff::Bezier.new
|
18
|
+
# g.data 'sin', dataset
|
19
|
+
# g.write('bezier.png')
|
20
|
+
#
|
5
21
|
class Gruff::Bezier < Gruff::Base
|
6
22
|
def draw
|
7
23
|
super
|
@@ -37,7 +53,5 @@ class Gruff::Bezier < Gruff::Base
|
|
37
53
|
Gruff::Renderer::Bezier.new(color: data_row.color, width: stroke_width).render(poly_points)
|
38
54
|
end
|
39
55
|
end
|
40
|
-
|
41
|
-
Gruff::Renderer.finish
|
42
56
|
end
|
43
57
|
end
|
data/lib/gruff/bullet.rb
CHANGED
@@ -1,15 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
#
|
4
|
+
# A bullet graph is a variation of a bar graph.
|
6
5
|
# http://en.wikipedia.org/wiki/Bullet_graph
|
6
|
+
#
|
7
|
+
# Here's how to set up a Gruff::Bullet.
|
8
|
+
#
|
9
|
+
# g = Gruff::Bullet.new
|
10
|
+
# g.title = 'Monthly Revenue'
|
11
|
+
# g.data 75, 100, { target: 80, low: 50, high: 90 }
|
12
|
+
# g.write('bullet.png')
|
13
|
+
#
|
7
14
|
class Gruff::Bullet < Gruff::Base
|
8
15
|
def initialize(target_width = '400x40')
|
16
|
+
super
|
17
|
+
|
9
18
|
if target_width.is_a?(String)
|
10
|
-
|
11
|
-
@columns = geometric_width.to_f
|
12
|
-
@rows = geometric_height.to_f
|
19
|
+
@columns, @rows = target_width.split('x').map(&:to_f)
|
13
20
|
else
|
14
21
|
@columns = target_width.to_f
|
15
22
|
@rows = target_width.to_f / 5.0
|
@@ -17,12 +24,15 @@ class Gruff::Bullet < Gruff::Base
|
|
17
24
|
@columns.freeze
|
18
25
|
@rows.freeze
|
19
26
|
|
20
|
-
initialize_ivars
|
21
|
-
|
22
|
-
reset_themes
|
23
27
|
self.theme = Gruff::Themes::GREYSCALE
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize_ivars
|
31
|
+
super
|
32
|
+
|
24
33
|
@title_font_size = 20
|
25
34
|
end
|
35
|
+
private :initialize_ivars
|
26
36
|
|
27
37
|
def data(value, maximum_value, options = {})
|
28
38
|
@value = value.to_f
|
@@ -45,7 +55,7 @@ class Gruff::Bullet < Gruff::Base
|
|
45
55
|
margin = 30.0
|
46
56
|
thickness = @raw_rows / 6.0
|
47
57
|
right_margin = margin
|
48
|
-
graph_left =
|
58
|
+
graph_left = [title_width * 1.3, margin].max
|
49
59
|
graph_width = @raw_columns - graph_left - right_margin
|
50
60
|
graph_height = thickness * 3.0
|
51
61
|
|
@@ -73,18 +83,16 @@ class Gruff::Bullet < Gruff::Base
|
|
73
83
|
# Value
|
74
84
|
rect_renderer = Gruff::Renderer::Rectangle.new(color: @font_color)
|
75
85
|
rect_renderer.render(graph_left, thickness, graph_left + graph_width * (@value / maximum_value), thickness * 2)
|
76
|
-
|
77
|
-
Gruff::Renderer.finish
|
78
86
|
end
|
79
87
|
|
80
88
|
private
|
81
89
|
|
82
90
|
def draw_title
|
83
|
-
return
|
91
|
+
return if hide_title?
|
84
92
|
|
85
93
|
font_height = calculate_caps_height(scale_fontsize(@title_font_size))
|
86
94
|
|
87
95
|
text_renderer = Gruff::Renderer::Text.new(@title, font: @font, size: @title_font_size, color: @font_color)
|
88
|
-
text_renderer.
|
96
|
+
text_renderer.add_to_render_queue(1.0, 1.0, font_height / 2, font_height / 2, Magick::NorthWestGravity)
|
89
97
|
end
|
90
98
|
end
|
data/lib/gruff/dot.rb
CHANGED
@@ -1,9 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
# Graph with dots and labels along a vertical access
|
3
|
+
#
|
4
|
+
# Graph with dots and labels along a vertical access.
|
6
5
|
# see: 'Creating More Effective Graphs' by Robbins
|
6
|
+
#
|
7
|
+
# Here's how to set up a Gruff::Dot.
|
8
|
+
#
|
9
|
+
# g = Gruff::Dot.new
|
10
|
+
# g.title = 'Dot Graph'
|
11
|
+
# g.data :Art, [0, 5, 8, 15]
|
12
|
+
# g.data :Philosophy, [10, 3, 2, 8]
|
13
|
+
# g.data :Science, [2, 15, 8, 11]
|
14
|
+
# g.write('dot.png')
|
15
|
+
#
|
7
16
|
class Gruff::Dot < Gruff::Base
|
8
17
|
def draw
|
9
18
|
@has_left_labels = true
|
@@ -33,8 +42,6 @@ class Gruff::Dot < Gruff::Base
|
|
33
42
|
draw_label(y_pos, point_index)
|
34
43
|
end
|
35
44
|
end
|
36
|
-
|
37
|
-
Gruff::Renderer.finish
|
38
45
|
end
|
39
46
|
|
40
47
|
protected
|
@@ -43,37 +50,17 @@ protected
|
|
43
50
|
def draw_line_markers
|
44
51
|
return if @hide_line_markers
|
45
52
|
|
46
|
-
|
47
|
-
|
48
|
-
increment = @y_axis_increment
|
49
|
-
number_of_lines = (@spread / @y_axis_increment).to_i
|
50
|
-
else
|
51
|
-
# Try to use a number of horizontal lines that will come out even.
|
52
|
-
#
|
53
|
-
# TODO Do the same for larger numbers...100, 75, 50, 25
|
54
|
-
if @marker_count.nil?
|
55
|
-
(3..7).each do |lines|
|
56
|
-
if @spread % lines == 0.0
|
57
|
-
@marker_count = lines
|
58
|
-
break
|
59
|
-
end
|
60
|
-
end
|
61
|
-
@marker_count ||= 5
|
62
|
-
end
|
63
|
-
# TODO: Round maximum marker value to a round number like 100, 0.1, 0.5, etc.
|
64
|
-
increment = (@spread > 0 && @marker_count > 0) ? significant(@spread / @marker_count) : 1
|
65
|
-
number_of_lines = @marker_count
|
66
|
-
end
|
67
|
-
|
68
|
-
(0..number_of_lines).each do |index|
|
69
|
-
marker_label = minimum_value + index * increment
|
53
|
+
(0..marker_count).each do |index|
|
54
|
+
marker_label = minimum_value + index * @increment
|
70
55
|
x = @graph_left + (marker_label - minimum_value) * @graph_width / @spread
|
71
|
-
|
56
|
+
|
57
|
+
line_renderer = Gruff::Renderer::Line.new(color: @marker_color, shadow_color: @marker_shadow_color)
|
58
|
+
line_renderer.render(x, @graph_bottom, x, @graph_bottom + 5)
|
72
59
|
|
73
60
|
unless @hide_line_numbers
|
74
|
-
label = label(marker_label, increment)
|
61
|
+
label = label(marker_label, @increment)
|
75
62
|
text_renderer = Gruff::Renderer::Text.new(label, font: @font, size: @marker_font_size, color: @font_color)
|
76
|
-
text_renderer.
|
63
|
+
text_renderer.add_to_render_queue(0, 0, x, @graph_bottom + (LABEL_MARGIN * 1.5), Magick::CenterGravity)
|
77
64
|
end
|
78
65
|
end
|
79
66
|
end
|
@@ -84,7 +71,7 @@ protected
|
|
84
71
|
def draw_label(y_offset, index)
|
85
72
|
draw_unique_label(index) do
|
86
73
|
text_renderer = Gruff::Renderer::Text.new(@labels[index], font: @font, size: @marker_font_size, color: @font_color)
|
87
|
-
text_renderer.
|
74
|
+
text_renderer.add_to_render_queue(@graph_left - LABEL_MARGIN, 1.0, 0.0, y_offset, Magick::EastGravity)
|
88
75
|
end
|
89
76
|
end
|
90
77
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
##
|
4
4
|
# Original Author: David Stokar
|
5
5
|
#
|
6
|
-
# This class
|
6
|
+
# This class performs the y coordinates conversion for the bar class.
|
7
7
|
#
|
8
8
|
# There are three cases:
|
9
9
|
#
|
@@ -24,16 +24,16 @@ class Gruff::BarConversion
|
|
24
24
|
result = []
|
25
25
|
|
26
26
|
case @mode
|
27
|
-
when 1
|
28
|
-
|
27
|
+
when 1
|
28
|
+
# minimum value >= 0 ( only positive values )
|
29
29
|
result[0] = @graph_top + @graph_height * (1 - data_point) + 1
|
30
30
|
result[1] = @graph_top + @graph_height - 1
|
31
|
-
when 2
|
32
|
-
|
31
|
+
when 2
|
32
|
+
# only negative values
|
33
33
|
result[0] = @graph_top + 1
|
34
34
|
result[1] = @graph_top + @graph_height * (1 - data_point) - 1
|
35
|
-
when 3
|
36
|
-
|
35
|
+
when 3
|
36
|
+
# positive and negative values
|
37
37
|
val = data_point - @minimum_value / @spread
|
38
38
|
result[0] = @graph_top + @graph_height * (1 - (val - @zero)) + 1
|
39
39
|
result[1] = @graph_top + @graph_height * (1 - @zero) - 1
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'histogram'
|
4
|
+
|
5
|
+
#
|
6
|
+
# Here's how to set up a Gruff::Histogram.
|
7
|
+
#
|
8
|
+
# g = Gruff::Histogram.new
|
9
|
+
# g.title = 'Histogram Graph'
|
10
|
+
# g.minimum_bin = 10
|
11
|
+
# g.bin_width = 20
|
12
|
+
# g.data :A, [10, 10, 20, 30, 40, 40, 40, 40, 40, 40, 50, 10, 10, 10]
|
13
|
+
# g.data :B, [100, 100, 100, 100, 90, 90, 80, 30, 30, 30, 30, 30]
|
14
|
+
# g.write('histogram.png')
|
15
|
+
#
|
16
|
+
class Gruff::Histogram < Gruff::Bar
|
17
|
+
# Specifies interpolation between the min and max of the set. Default is +10+.
|
18
|
+
attr_writer :bin_width
|
19
|
+
|
20
|
+
# Specifies minimum value for bin.
|
21
|
+
attr_writer :minimum_bin
|
22
|
+
|
23
|
+
# Specifies maximum value for bin.
|
24
|
+
attr_writer :maximum_bin
|
25
|
+
|
26
|
+
def initialize(*)
|
27
|
+
super
|
28
|
+
@data = []
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize_ivars
|
32
|
+
super
|
33
|
+
@bin_width = 10
|
34
|
+
@minimum_bin = nil
|
35
|
+
@maximum_bin = nil
|
36
|
+
end
|
37
|
+
private :initialize_ivars
|
38
|
+
|
39
|
+
def data(name, data_points = [], color = nil)
|
40
|
+
@data << [name, data_points, color]
|
41
|
+
end
|
42
|
+
|
43
|
+
def draw
|
44
|
+
@data.each do |(name, data_points, color)|
|
45
|
+
bins, freqs = HistogramArray.new(data_points).histogram(bin_width: @bin_width, min: @minimum_bin, max: @maximum_bin)
|
46
|
+
bins.each_with_index do |bin, index|
|
47
|
+
@labels[index] = bin
|
48
|
+
end
|
49
|
+
store.add(name, freqs, color)
|
50
|
+
end
|
51
|
+
|
52
|
+
super
|
53
|
+
end
|
54
|
+
|
55
|
+
# @private
|
56
|
+
class HistogramArray < Array
|
57
|
+
include ::Histogram
|
58
|
+
end
|
59
|
+
end
|
data/lib/gruff/line.rb
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
# Here's how to make a Line graph:
|
3
|
+
#
|
4
|
+
# Here's how to make a Gruff::Line.
|
6
5
|
#
|
7
6
|
# g = Gruff::Line.new
|
8
7
|
# g.title = "A Line Graph"
|
9
8
|
# g.data 'Fries', [20, 23, 19, 8]
|
10
9
|
# g.data 'Hamburgers', [50, 19, 99, 29]
|
11
|
-
# g.write("
|
10
|
+
# g.write("line.png")
|
12
11
|
#
|
13
12
|
# There are also other options described below, such as {#baseline_value}, {#baseline_color},
|
14
|
-
# {#hide_dots}, and {#hide_lines}.
|
13
|
+
# {#hide_dots=}, and {#hide_lines=}.
|
14
|
+
#
|
15
15
|
class Gruff::Line < Gruff::Base
|
16
16
|
# Allow for reference lines ( which are like baseline ... just allowing for more & on both axes ).
|
17
17
|
attr_accessor :reference_lines
|
18
|
-
|
19
|
-
|
18
|
+
attr_writer :reference_line_default_color
|
19
|
+
attr_writer :reference_line_default_width
|
20
20
|
|
21
21
|
# Allow for vertical marker lines.
|
22
|
-
|
22
|
+
attr_writer :show_vertical_markers
|
23
23
|
|
24
24
|
# Dimensions of lines and dots; calculated based on dataset size if left unspecified.
|
25
|
-
|
26
|
-
|
25
|
+
attr_writer :line_width
|
26
|
+
attr_writer :dot_radius
|
27
27
|
|
28
28
|
# default is +'circle'+, other options include square.
|
29
|
-
|
29
|
+
attr_writer :dot_style
|
30
30
|
|
31
|
-
# Hide parts of the graph to fit more
|
32
|
-
|
31
|
+
# Hide parts of the graph to fit more data points, or for a different appearance.
|
32
|
+
attr_writer :hide_dots, :hide_lines
|
33
33
|
|
34
34
|
# accessors for support of xy data.
|
35
|
-
|
35
|
+
attr_writer :minimum_x_value
|
36
36
|
|
37
37
|
# accessors for support of xy data.
|
38
|
-
|
38
|
+
attr_writer :maximum_x_value
|
39
39
|
|
40
40
|
# Get the value if somebody has defined it.
|
41
41
|
def baseline_value
|
@@ -67,7 +67,7 @@ class Gruff::Line < Gruff::Base
|
|
67
67
|
# g = Gruff::Line.new(400, false) # 400px wide, no lines (for backwards compatibility)
|
68
68
|
# g = Gruff::Line.new(false) # Defaults to 800px wide, no lines (for backwards compatibility)
|
69
69
|
#
|
70
|
-
# The preferred way is to call {#hide_dots} or {#hide_lines} instead.
|
70
|
+
# The preferred way is to call {#hide_dots=} or {#hide_lines=} instead.
|
71
71
|
def initialize(*args)
|
72
72
|
raise ArgumentError, 'Wrong number of arguments' if args.length > 2
|
73
73
|
|
@@ -76,7 +76,15 @@ class Gruff::Line < Gruff::Base
|
|
76
76
|
else
|
77
77
|
super args.shift
|
78
78
|
end
|
79
|
+
end
|
79
80
|
|
81
|
+
def initialize_store
|
82
|
+
@store = Gruff::Store.new(Gruff::Store::XYData)
|
83
|
+
end
|
84
|
+
private :initialize_store
|
85
|
+
|
86
|
+
def initialize_ivars
|
87
|
+
super
|
80
88
|
@reference_lines = {}
|
81
89
|
@reference_line_default_color = 'red'
|
82
90
|
@reference_line_default_width = 5
|
@@ -85,12 +93,13 @@ class Gruff::Line < Gruff::Base
|
|
85
93
|
@maximum_x_value = nil
|
86
94
|
@minimum_x_value = nil
|
87
95
|
|
96
|
+
@line_width = nil
|
97
|
+
@dot_radius = nil
|
88
98
|
@dot_style = 'circle'
|
89
99
|
|
90
100
|
@show_vertical_markers = false
|
91
|
-
|
92
|
-
@store = Gruff::Store.new(Gruff::Store::XYData)
|
93
101
|
end
|
102
|
+
private :initialize_ivars
|
94
103
|
|
95
104
|
# This method allows one to plot a dataset with both X and Y data.
|
96
105
|
#
|
@@ -123,7 +132,7 @@ class Gruff::Line < Gruff::Base
|
|
123
132
|
# g.data("Capples", [1, 1, 2, 2, 3, 3])
|
124
133
|
#
|
125
134
|
# # labels will be drawn at the x locations of the keys passed in.
|
126
|
-
# In this example the
|
135
|
+
# In this example the labels are drawn at x positions 2, 4, and 6:
|
127
136
|
# g.labels = {0 => '2003', 2 => '2004', 4 => '2005', 6 => '2006'}
|
128
137
|
# # The 0 => '2003' label will be ignored since it is outside the chart range.
|
129
138
|
def dataxy(name, x_data_points = [], y_data_points = [], color = nil)
|
@@ -144,11 +153,9 @@ class Gruff::Line < Gruff::Base
|
|
144
153
|
end
|
145
154
|
|
146
155
|
def draw_reference_line(reference_line, left, right, top, bottom)
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
}
|
151
|
-
Gruff::Renderer::DashLine.new(config).render(left, top, right, bottom)
|
156
|
+
color = reference_line[:color] || @reference_line_default_color
|
157
|
+
width = reference_line[:width] || @reference_line_default_width
|
158
|
+
Gruff::Renderer::DashLine.new(color: color, width: width).render(left, top, right, bottom)
|
152
159
|
end
|
153
160
|
|
154
161
|
def draw_horizontal_reference_line(reference_line)
|
@@ -210,8 +217,8 @@ class Gruff::Line < Gruff::Base
|
|
210
217
|
new_y = @graph_top + (@graph_height - y_data * @graph_height)
|
211
218
|
|
212
219
|
# Reset each time to avoid thin-line errors
|
213
|
-
stroke_width = line_width || clip_value_if_greater_than(@columns / (store.norm_data.first.y_points.size * 4), 5.0)
|
214
|
-
circle_radius = dot_radius || clip_value_if_greater_than(@columns / (store.norm_data.first.y_points.size * 2.5), 5.0)
|
220
|
+
stroke_width = @line_width || clip_value_if_greater_than(@columns / (store.norm_data.first.y_points.size * 4), 5.0)
|
221
|
+
circle_radius = @dot_radius || clip_value_if_greater_than(@columns / (store.norm_data.first.y_points.size * 2.5), 5.0)
|
215
222
|
|
216
223
|
if !@hide_lines && prev_x && prev_y
|
217
224
|
Gruff::Renderer::Line.new(color: data_row.color, width: stroke_width)
|
@@ -226,8 +233,6 @@ class Gruff::Line < Gruff::Base
|
|
226
233
|
prev_y = new_y
|
227
234
|
end
|
228
235
|
end
|
229
|
-
|
230
|
-
Gruff::Renderer.finish
|
231
236
|
end
|
232
237
|
|
233
238
|
private
|