gruff 0.12.2 → 0.15.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 +66 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +34 -27
- data/CHANGELOG.md +29 -0
- data/README.md +15 -7
- data/assets/fonts/LICENSE.txt +202 -0
- data/assets/fonts/Roboto-Bold.ttf +0 -0
- data/assets/fonts/Roboto-Regular.ttf +0 -0
- data/gruff.gemspec +9 -10
- data/lib/gruff/accumulator_bar.rb +3 -1
- data/lib/gruff/area.rb +5 -8
- data/lib/gruff/bar.rb +32 -49
- data/lib/gruff/base.rb +199 -115
- data/lib/gruff/bezier.rb +4 -6
- data/lib/gruff/bullet.rb +12 -11
- data/lib/gruff/dot.rb +13 -14
- data/lib/gruff/font.rb +39 -0
- data/lib/gruff/helper/bar_conversion.rb +27 -12
- data/lib/gruff/helper/bar_value_label.rb +71 -0
- data/lib/gruff/helper/stacked_mixin.rb +1 -2
- data/lib/gruff/histogram.rb +9 -7
- data/lib/gruff/line.rb +57 -50
- data/lib/gruff/mini/bar.rb +9 -6
- data/lib/gruff/mini/legend.rb +12 -8
- data/lib/gruff/mini/pie.rb +9 -6
- data/lib/gruff/mini/side_bar.rb +9 -6
- data/lib/gruff/net.rb +9 -15
- data/lib/gruff/patch/rmagick.rb +0 -1
- data/lib/gruff/patch/string.rb +1 -1
- data/lib/gruff/pie.rb +23 -65
- data/lib/gruff/renderer/bezier.rb +8 -9
- data/lib/gruff/renderer/circle.rb +8 -9
- data/lib/gruff/renderer/dash_line.rb +9 -10
- data/lib/gruff/renderer/dot.rb +13 -14
- data/lib/gruff/renderer/ellipse.rb +8 -9
- data/lib/gruff/renderer/line.rb +8 -9
- data/lib/gruff/renderer/polygon.rb +9 -10
- data/lib/gruff/renderer/polyline.rb +8 -9
- data/lib/gruff/renderer/rectangle.rb +7 -8
- data/lib/gruff/renderer/renderer.rb +25 -40
- data/lib/gruff/renderer/text.rb +21 -29
- data/lib/gruff/scatter.rb +55 -75
- data/lib/gruff/scene.rb +28 -18
- data/lib/gruff/side_bar.rb +35 -54
- data/lib/gruff/side_stacked_bar.rb +14 -17
- data/lib/gruff/spider.rb +11 -20
- data/lib/gruff/stacked_area.rb +10 -11
- data/lib/gruff/stacked_bar.rb +14 -15
- data/lib/gruff/store/store.rb +6 -10
- data/lib/gruff/store/xy_data.rb +2 -0
- data/lib/gruff/themes.rb +6 -6
- data/lib/gruff/version.rb +1 -1
- data/lib/gruff.rb +68 -55
- data/rails_generators/gruff/templates/controller.rb +1 -1
- metadata +34 -20
- data/.rubocop_todo.yml +0 -190
- data/.travis.yml +0 -23
- data/assets/plastik/blue.png +0 -0
- data/assets/plastik/green.png +0 -0
- data/assets/plastik/red.png +0 -0
- data/lib/gruff/helper/bar_value_label_mixin.rb +0 -33
- data/lib/gruff/photo_bar.rb +0 -93
data/lib/gruff/bullet.rb
CHANGED
@@ -27,12 +27,13 @@ class Gruff::Bullet < Gruff::Base
|
|
27
27
|
self.theme = Gruff::Themes::GREYSCALE
|
28
28
|
end
|
29
29
|
|
30
|
-
def
|
30
|
+
def initialize_attributes
|
31
31
|
super
|
32
32
|
|
33
|
-
@
|
33
|
+
@title_font.size = 20
|
34
|
+
@title_font.bold = false
|
34
35
|
end
|
35
|
-
private :
|
36
|
+
private :initialize_attributes
|
36
37
|
|
37
38
|
def data(value, maximum_value, options = {})
|
38
39
|
@value = value.to_f
|
@@ -51,7 +52,7 @@ class Gruff::Bullet < Gruff::Base
|
|
51
52
|
|
52
53
|
draw_title
|
53
54
|
|
54
|
-
title_width = calculate_width(@
|
55
|
+
title_width = calculate_width(@title_font, @title)
|
55
56
|
margin = 30.0
|
56
57
|
thickness = @raw_rows / 6.0
|
57
58
|
right_margin = margin
|
@@ -60,15 +61,15 @@ class Gruff::Bullet < Gruff::Base
|
|
60
61
|
graph_height = thickness * 3.0
|
61
62
|
|
62
63
|
# Background
|
63
|
-
rect_renderer = Gruff::Renderer::Rectangle.new(color: @colors[0])
|
64
|
+
rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: @colors[0])
|
64
65
|
rect_renderer.render(graph_left, 0, graph_left + graph_width, graph_height)
|
65
66
|
|
66
|
-
[
|
67
|
+
%i[high low].each_with_index do |indicator, index|
|
67
68
|
next unless @options.key?(indicator)
|
68
69
|
|
69
70
|
indicator_width_x = graph_left + graph_width * (@options[indicator] / maximum_value)
|
70
71
|
|
71
|
-
rect_renderer = Gruff::Renderer::Rectangle.new(color: @colors[index + 1])
|
72
|
+
rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: @colors[index + 1])
|
72
73
|
rect_renderer.render(graph_left, 0, indicator_width_x, graph_height)
|
73
74
|
end
|
74
75
|
|
@@ -76,12 +77,12 @@ class Gruff::Bullet < Gruff::Base
|
|
76
77
|
target_x = graph_left + graph_width * (@options[:target] / maximum_value)
|
77
78
|
half_thickness = thickness / 2.0
|
78
79
|
|
79
|
-
rect_renderer = Gruff::Renderer::Rectangle.new(color: @
|
80
|
+
rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: @marker_color)
|
80
81
|
rect_renderer.render(target_x, half_thickness, target_x + half_thickness, thickness * 2 + half_thickness)
|
81
82
|
end
|
82
83
|
|
83
84
|
# Value
|
84
|
-
rect_renderer = Gruff::Renderer::Rectangle.new(color: @
|
85
|
+
rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: @marker_color)
|
85
86
|
rect_renderer.render(graph_left, thickness, graph_left + graph_width * (@value / maximum_value), thickness * 2)
|
86
87
|
end
|
87
88
|
|
@@ -90,9 +91,9 @@ private
|
|
90
91
|
def draw_title
|
91
92
|
return if hide_title?
|
92
93
|
|
93
|
-
font_height = calculate_caps_height(
|
94
|
+
font_height = calculate_caps_height(@title_font)
|
94
95
|
|
95
|
-
text_renderer = Gruff::Renderer::Text.new(@title, font: @
|
96
|
+
text_renderer = Gruff::Renderer::Text.new(renderer, @title, font: @title_font)
|
96
97
|
text_renderer.add_to_render_queue(1.0, 1.0, font_height / 2, font_height / 2, Magick::NorthWestGravity)
|
97
98
|
end
|
98
99
|
end
|
data/lib/gruff/dot.rb
CHANGED
@@ -14,12 +14,14 @@
|
|
14
14
|
# g.write('dot.png')
|
15
15
|
#
|
16
16
|
class Gruff::Dot < Gruff::Base
|
17
|
-
|
18
|
-
@has_left_labels = true
|
19
|
-
super
|
17
|
+
private
|
20
18
|
|
21
|
-
|
19
|
+
def initialize_attributes
|
20
|
+
super
|
21
|
+
@has_left_labels = true
|
22
|
+
end
|
22
23
|
|
24
|
+
def draw_graph
|
23
25
|
# Setup spacing.
|
24
26
|
#
|
25
27
|
spacing_factor = 1.0
|
@@ -34,32 +36,30 @@ class Gruff::Dot < Gruff::Base
|
|
34
36
|
y_pos = @graph_top + (items_width * point_index) + padding + (items_width.to_f / 2.0).round
|
35
37
|
|
36
38
|
if row_index == 0
|
37
|
-
Gruff::Renderer::Line.new(color: @marker_color).render(@graph_left, y_pos, @graph_left + @graph_width, y_pos)
|
39
|
+
Gruff::Renderer::Line.new(renderer, color: @marker_color).render(@graph_left, y_pos, @graph_left + @graph_width, y_pos)
|
38
40
|
end
|
39
41
|
|
40
|
-
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
|
+
Gruff::Renderer::Circle.new(renderer, color: data_row.color).render(x_pos, y_pos, x_pos + (item_width.to_f / 3.0).round, y_pos)
|
41
43
|
|
42
44
|
draw_label(y_pos, point_index)
|
43
45
|
end
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
47
|
-
protected
|
48
|
-
|
49
49
|
# Instead of base class version, draws vertical background lines and label
|
50
50
|
def draw_line_markers
|
51
51
|
return if @hide_line_markers
|
52
52
|
|
53
53
|
(0..marker_count).each do |index|
|
54
|
-
marker_label =
|
54
|
+
marker_label = BigDecimal(index.to_s) * BigDecimal(@increment.to_s) + BigDecimal(minimum_value.to_s)
|
55
55
|
x = @graph_left + (marker_label - minimum_value) * @graph_width / @spread
|
56
56
|
|
57
|
-
line_renderer = Gruff::Renderer::Line.new(color: @marker_color, shadow_color: @marker_shadow_color)
|
57
|
+
line_renderer = Gruff::Renderer::Line.new(renderer, color: @marker_color, shadow_color: @marker_shadow_color)
|
58
58
|
line_renderer.render(x, @graph_bottom, x, @graph_bottom + 5)
|
59
59
|
|
60
60
|
unless @hide_line_numbers
|
61
|
-
label =
|
62
|
-
text_renderer = Gruff::Renderer::Text.new(label, font: @
|
61
|
+
label = y_axis_label(marker_label, @increment)
|
62
|
+
text_renderer = Gruff::Renderer::Text.new(renderer, label, font: @marker_font)
|
63
63
|
text_renderer.add_to_render_queue(0, 0, x, @graph_bottom + (LABEL_MARGIN * 1.5), Magick::CenterGravity)
|
64
64
|
end
|
65
65
|
end
|
@@ -70,8 +70,7 @@ protected
|
|
70
70
|
|
71
71
|
def draw_label(y_offset, index)
|
72
72
|
draw_unique_label(index) do
|
73
|
-
|
74
|
-
text_renderer.add_to_render_queue(@graph_left - LABEL_MARGIN, 1.0, 0.0, y_offset, Magick::EastGravity)
|
73
|
+
draw_label_at(@graph_left - LABEL_MARGIN, 1.0, 0.0, y_offset, @labels[index], Magick::EastGravity)
|
75
74
|
end
|
76
75
|
end
|
77
76
|
end
|
data/lib/gruff/font.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Handle font setting to draw texts
|
4
|
+
class Gruff::Font
|
5
|
+
BOLD_PATH = File.expand_path(File.join(__FILE__, '../../../assets/fonts/Roboto-Bold.ttf')).freeze
|
6
|
+
REGULAR_PATH = File.expand_path(File.join(__FILE__, '../../../assets/fonts/Roboto-Regular.ttf')).freeze
|
7
|
+
|
8
|
+
# Get/set font path.
|
9
|
+
attr_accessor :path
|
10
|
+
|
11
|
+
# Get/set font size.
|
12
|
+
attr_accessor :size
|
13
|
+
|
14
|
+
# Get/set font setting whether render bold text.
|
15
|
+
attr_accessor :bold
|
16
|
+
|
17
|
+
# Get/set font color.
|
18
|
+
attr_accessor :color
|
19
|
+
|
20
|
+
def initialize(path: nil, size: 20.0, bold: false, color: 'white')
|
21
|
+
@path = path
|
22
|
+
@bold = bold
|
23
|
+
@size = size
|
24
|
+
@color = color
|
25
|
+
end
|
26
|
+
|
27
|
+
# Get font weight.
|
28
|
+
# @return [Magick::WeightType] font weight
|
29
|
+
def weight
|
30
|
+
@bold ? Magick::BoldWeight : Magick::NormalWeight
|
31
|
+
end
|
32
|
+
|
33
|
+
# @private
|
34
|
+
def file_path
|
35
|
+
return @path if @path
|
36
|
+
|
37
|
+
@bold ? BOLD_PATH : REGULAR_PATH
|
38
|
+
end
|
39
|
+
end
|
@@ -14,29 +14,44 @@
|
|
14
14
|
# @private
|
15
15
|
class Gruff::BarConversion
|
16
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
17
|
|
23
|
-
def
|
18
|
+
def initialize(top:, bottom:, minimum_value:, maximum_value:, spread:)
|
19
|
+
@graph_top = top
|
20
|
+
@graph_height = bottom - top
|
21
|
+
@spread = spread
|
22
|
+
@minimum_value = minimum_value
|
23
|
+
@maximum_value = maximum_value
|
24
|
+
|
25
|
+
if minimum_value >= 0
|
26
|
+
# all bars go from zero to positive
|
27
|
+
@mode = 1
|
28
|
+
elsif maximum_value <= 0
|
29
|
+
# all bars go from 0 to negative
|
30
|
+
@mode = 2
|
31
|
+
else
|
32
|
+
# bars either go from zero to negative or to positive
|
33
|
+
@mode = 3
|
34
|
+
@zero = -minimum_value / @spread
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_top_bottom_scaled(data_point)
|
24
39
|
result = []
|
25
40
|
|
26
41
|
case @mode
|
27
42
|
when 1
|
28
43
|
# minimum value >= 0 ( only positive values )
|
29
|
-
result[0] = @graph_top + @graph_height * (1 - data_point)
|
30
|
-
result[1] = @graph_top + @graph_height
|
44
|
+
result[0] = @graph_top + @graph_height * (1 - data_point)
|
45
|
+
result[1] = @graph_top + @graph_height
|
31
46
|
when 2
|
32
47
|
# only negative values
|
33
|
-
result[0] = @graph_top
|
34
|
-
result[1] = @graph_top + @graph_height * (1 - data_point)
|
48
|
+
result[0] = @graph_top
|
49
|
+
result[1] = @graph_top + @graph_height * (1 - data_point)
|
35
50
|
when 3
|
36
51
|
# positive and negative values
|
37
52
|
val = data_point - @minimum_value / @spread
|
38
|
-
result[0] = @graph_top + @graph_height * (1 - (val - @zero))
|
39
|
-
result[1] = @graph_top + @graph_height * (1 - @zero)
|
53
|
+
result[0] = @graph_top + @graph_height * (1 - (val - @zero))
|
54
|
+
result[1] = @graph_top + @graph_height * (1 - @zero)
|
40
55
|
else
|
41
56
|
result[0] = 0.0
|
42
57
|
result[1] = 0.0
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @private
|
4
|
+
module Gruff::BarValueLabel
|
5
|
+
using String::GruffCommify
|
6
|
+
|
7
|
+
# @private
|
8
|
+
class Base
|
9
|
+
attr_reader :coordinate, :value
|
10
|
+
|
11
|
+
def initialize(coordinate, value)
|
12
|
+
@coordinate = coordinate
|
13
|
+
@value = value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# @private
|
18
|
+
class Bar < Base
|
19
|
+
def prepare_rendering(format, _bar_width = 0)
|
20
|
+
left_x, left_y, right_x, _right_y = @coordinate
|
21
|
+
val = begin
|
22
|
+
if format.is_a?(Proc)
|
23
|
+
format.call(@value)
|
24
|
+
else
|
25
|
+
sprintf(format || '%.2f', @value).commify
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
y = @value >= 0 ? left_y - 30 : left_y + 12
|
30
|
+
yield left_x + (right_x - left_x) / 2, y, val
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# @private
|
35
|
+
class SideBar < Base
|
36
|
+
def prepare_rendering(format, bar_width = 0)
|
37
|
+
left_x, _left_y, right_x, right_y = @coordinate
|
38
|
+
val = begin
|
39
|
+
if format.is_a?(Proc)
|
40
|
+
format.call(@value)
|
41
|
+
else
|
42
|
+
sprintf(format || '%.2f', @value).commify
|
43
|
+
end
|
44
|
+
end
|
45
|
+
x = @value >= 0 ? right_x + 40 : left_x - 40
|
46
|
+
yield x, right_y - bar_width / 2, val
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# @private
|
51
|
+
class StackedBar
|
52
|
+
def initialize
|
53
|
+
@bars = []
|
54
|
+
end
|
55
|
+
|
56
|
+
def add(bar, index)
|
57
|
+
bars = @bars[index] || []
|
58
|
+
bars << bar
|
59
|
+
@bars[index] = bars
|
60
|
+
end
|
61
|
+
|
62
|
+
def prepare_rendering(format, bar_width = 0, &block)
|
63
|
+
@bars.each do |bars|
|
64
|
+
value = bars.sum(&:value)
|
65
|
+
bar = bars.last
|
66
|
+
bar_value_label = bar.class.new(bar.coordinate, value)
|
67
|
+
bar_value_label.prepare_rendering(format, bar_width, &block)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -7,10 +7,9 @@ module Gruff::Base::StackedMixin
|
|
7
7
|
# tsal: moved from Base 03 FEB 2007
|
8
8
|
def calculate_maximum_by_stack
|
9
9
|
# Get sum of each stack
|
10
|
-
max_hash = {}
|
10
|
+
max_hash = Hash.new { |h, k| h[k] = 0.0 }
|
11
11
|
store.data.each do |data_set|
|
12
12
|
data_set.points.each_with_index do |data_point, i|
|
13
|
-
max_hash[i] = 0.0 unless max_hash[i]
|
14
13
|
max_hash[i] += data_point.to_f
|
15
14
|
end
|
16
15
|
end
|
data/lib/gruff/histogram.rb
CHANGED
@@ -28,19 +28,21 @@ class Gruff::Histogram < Gruff::Bar
|
|
28
28
|
@data = []
|
29
29
|
end
|
30
30
|
|
31
|
-
def
|
31
|
+
def data(name, data_points = [], color = nil)
|
32
|
+
@data << [name, data_points, color]
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def initialize_attributes
|
32
38
|
super
|
33
39
|
@bin_width = 10
|
34
40
|
@minimum_bin = nil
|
35
41
|
@maximum_bin = nil
|
36
42
|
end
|
37
|
-
private :
|
38
|
-
|
39
|
-
def data(name, data_points = [], color = nil)
|
40
|
-
@data << [name, data_points, color]
|
41
|
-
end
|
43
|
+
private :initialize_attributes
|
42
44
|
|
43
|
-
def
|
45
|
+
def setup_data
|
44
46
|
@data.each do |(name, data_points, color)|
|
45
47
|
bins, freqs = HistogramArray.new(data_points).histogram(bin_width: @bin_width, min: @minimum_bin, max: @maximum_bin)
|
46
48
|
bins.each_with_index do |bin, index|
|
data/lib/gruff/line.rb
CHANGED
@@ -37,6 +37,9 @@ class Gruff::Line < Gruff::Base
|
|
37
37
|
# accessors for support of xy data.
|
38
38
|
attr_writer :maximum_x_value
|
39
39
|
|
40
|
+
# The number of vertical lines shown.
|
41
|
+
attr_writer :marker_x_count
|
42
|
+
|
40
43
|
# Get the value if somebody has defined it.
|
41
44
|
def baseline_value
|
42
45
|
if @reference_lines.key?(:baseline)
|
@@ -78,29 +81,6 @@ class Gruff::Line < Gruff::Base
|
|
78
81
|
end
|
79
82
|
end
|
80
83
|
|
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
|
88
|
-
@reference_lines = {}
|
89
|
-
@reference_line_default_color = 'red'
|
90
|
-
@reference_line_default_width = 5
|
91
|
-
|
92
|
-
@hide_dots = @hide_lines = false
|
93
|
-
@maximum_x_value = nil
|
94
|
-
@minimum_x_value = nil
|
95
|
-
|
96
|
-
@line_width = nil
|
97
|
-
@dot_radius = nil
|
98
|
-
@dot_style = 'circle'
|
99
|
-
|
100
|
-
@show_vertical_markers = false
|
101
|
-
end
|
102
|
-
private :initialize_ivars
|
103
|
-
|
104
84
|
# This method allows one to plot a dataset with both X and Y data.
|
105
85
|
#
|
106
86
|
# @overload dataxy(name, x_data_points = [], y_data_points = [], color = nil)
|
@@ -138,12 +118,14 @@ class Gruff::Line < Gruff::Base
|
|
138
118
|
def dataxy(name, x_data_points = [], y_data_points = [], color = nil)
|
139
119
|
# make sure it's an array
|
140
120
|
x_data_points = Array(x_data_points)
|
141
|
-
y_data_points = Array(y_data_points)
|
142
121
|
|
143
122
|
raise ArgumentError, 'x_data_points is nil!' if x_data_points.empty?
|
144
123
|
|
145
124
|
if x_data_points.all? { |p| p.is_a?(Array) && p.size == 2 }
|
125
|
+
color = y_data_points if y_data_points.is_a?(String)
|
146
126
|
x_data_points, y_data_points = x_data_points.transpose
|
127
|
+
else
|
128
|
+
y_data_points = Array(y_data_points)
|
147
129
|
end
|
148
130
|
|
149
131
|
raise ArgumentError, 'x_data_points.length != y_data_points.length!' if x_data_points.length != y_data_points.length
|
@@ -152,10 +134,34 @@ class Gruff::Line < Gruff::Base
|
|
152
134
|
store.add(name, y_data_points, color, x_data_points)
|
153
135
|
end
|
154
136
|
|
137
|
+
private
|
138
|
+
|
139
|
+
def initialize_store
|
140
|
+
@store = Gruff::Store.new(Gruff::Store::XYData)
|
141
|
+
end
|
142
|
+
|
143
|
+
def initialize_attributes
|
144
|
+
super
|
145
|
+
@reference_lines = {}
|
146
|
+
@reference_line_default_color = 'red'
|
147
|
+
@reference_line_default_width = 5
|
148
|
+
|
149
|
+
@hide_dots = @hide_lines = false
|
150
|
+
@maximum_x_value = nil
|
151
|
+
@minimum_x_value = nil
|
152
|
+
@marker_x_count = nil
|
153
|
+
|
154
|
+
@line_width = nil
|
155
|
+
@dot_radius = nil
|
156
|
+
@dot_style = 'circle'
|
157
|
+
|
158
|
+
@show_vertical_markers = false
|
159
|
+
end
|
160
|
+
|
155
161
|
def draw_reference_line(reference_line, left, right, top, bottom)
|
156
162
|
color = reference_line[:color] || @reference_line_default_color
|
157
163
|
width = reference_line[:width] || @reference_line_default_width
|
158
|
-
Gruff::Renderer::DashLine.new(color: color, width: width).render(left, top, right, bottom)
|
164
|
+
Gruff::Renderer::DashLine.new(renderer, color: color, width: width).render(left, top, right, bottom)
|
159
165
|
end
|
160
166
|
|
161
167
|
def draw_horizontal_reference_line(reference_line)
|
@@ -168,31 +174,15 @@ class Gruff::Line < Gruff::Base
|
|
168
174
|
draw_reference_line(reference_line, index, index, @graph_top, @graph_top + @graph_height)
|
169
175
|
end
|
170
176
|
|
171
|
-
def
|
172
|
-
super
|
173
|
-
|
174
|
-
return unless data_given?
|
175
|
-
|
177
|
+
def draw_graph
|
176
178
|
# Check to see if more than one datapoint was given. NaN can result otherwise.
|
177
|
-
@x_increment =
|
179
|
+
@x_increment = column_count > 1 ? (@graph_width / (column_count - 1).to_f) : @graph_width
|
178
180
|
|
179
181
|
@reference_lines.each_value do |curr_reference_line|
|
180
182
|
draw_horizontal_reference_line(curr_reference_line) if curr_reference_line.key?(:norm_value)
|
181
183
|
draw_vertical_reference_line(curr_reference_line) if curr_reference_line.key?(:index)
|
182
184
|
end
|
183
185
|
|
184
|
-
if @show_vertical_markers
|
185
|
-
(0..column_count).each do |column|
|
186
|
-
x = @graph_left + @graph_width - column.to_f * @x_increment
|
187
|
-
|
188
|
-
Gruff::Renderer::Line.new(color: @marker_color).render(x, @graph_bottom, x, @graph_top)
|
189
|
-
#If the user specified a marker shadow color, draw a shadow just below it
|
190
|
-
if @marker_shadow_color
|
191
|
-
Gruff::Renderer::Line.new(color: @marker_shadow_color).render(x + 1, @graph_bottom, x + 1, @graph_top)
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
186
|
store.norm_data.each do |data_row|
|
197
187
|
prev_x = prev_y = nil
|
198
188
|
|
@@ -200,7 +190,7 @@ class Gruff::Line < Gruff::Base
|
|
200
190
|
|
201
191
|
data_row.coordinates.each_with_index do |(x_data, y_data), index|
|
202
192
|
if x_data.nil?
|
203
|
-
#use the old method: equally spaced points along the x-axis
|
193
|
+
# use the old method: equally spaced points along the x-axis
|
204
194
|
new_x = @graph_left + (@x_increment * index)
|
205
195
|
draw_label(new_x, index)
|
206
196
|
else
|
@@ -221,12 +211,12 @@ class Gruff::Line < Gruff::Base
|
|
221
211
|
circle_radius = @dot_radius || clip_value_if_greater_than(@columns / (store.norm_data.first.y_points.size * 2.5), 5.0)
|
222
212
|
|
223
213
|
if !@hide_lines && prev_x && prev_y
|
224
|
-
Gruff::Renderer::Line.new(color: data_row.color, width: stroke_width)
|
214
|
+
Gruff::Renderer::Line.new(renderer, color: data_row.color, width: stroke_width)
|
225
215
|
.render(prev_x, prev_y, new_x, new_y)
|
226
216
|
end
|
227
217
|
|
228
218
|
if one_point || !@hide_dots
|
229
|
-
Gruff::Renderer::Dot.new(@dot_style, color: data_row.color, width: stroke_width).render(new_x, new_y, circle_radius)
|
219
|
+
Gruff::Renderer::Dot.new(renderer, @dot_style, color: data_row.color, width: stroke_width).render(new_x, new_y, circle_radius)
|
230
220
|
end
|
231
221
|
|
232
222
|
prev_x = new_x
|
@@ -235,8 +225,6 @@ class Gruff::Line < Gruff::Base
|
|
235
225
|
end
|
236
226
|
end
|
237
227
|
|
238
|
-
private
|
239
|
-
|
240
228
|
def setup_data
|
241
229
|
# Update the global min/max values for the x data
|
242
230
|
@maximum_x_value ||= store.max_x
|
@@ -259,6 +247,11 @@ private
|
|
259
247
|
super
|
260
248
|
end
|
261
249
|
|
250
|
+
def setup_drawing
|
251
|
+
@marker_x_count ||= column_count - 1
|
252
|
+
super
|
253
|
+
end
|
254
|
+
|
262
255
|
def normalize
|
263
256
|
return unless data_given?
|
264
257
|
|
@@ -273,8 +266,22 @@ private
|
|
273
266
|
end
|
274
267
|
end
|
275
268
|
|
276
|
-
def
|
277
|
-
|
269
|
+
def draw_line_markers
|
270
|
+
# do all of the stuff for the horizontal lines on the y-axis
|
271
|
+
super
|
272
|
+
return if @hide_line_markers
|
273
|
+
|
274
|
+
(0..@marker_x_count).each do |index|
|
275
|
+
if @show_vertical_markers
|
276
|
+
x = @graph_left + @graph_width - index * @graph_width / @marker_x_count
|
277
|
+
|
278
|
+
Gruff::Renderer::Line.new(renderer, color: @marker_color).render(x, @graph_bottom, x, @graph_top)
|
279
|
+
# If the user specified a marker shadow color, draw a shadow just below it
|
280
|
+
if @marker_shadow_color
|
281
|
+
Gruff::Renderer::Line.new(renderer, color: @marker_shadow_color).render(x + 1, @graph_bottom, x + 1, @graph_top)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
278
285
|
end
|
279
286
|
|
280
287
|
def get_x_coord(x_data_point, width, offset)
|
data/lib/gruff/mini/bar.rb
CHANGED
@@ -16,27 +16,30 @@ module Gruff
|
|
16
16
|
module Mini
|
17
17
|
# A class for drawing a small bar graph.
|
18
18
|
class Bar < Gruff::Bar
|
19
|
+
private
|
20
|
+
|
19
21
|
include Gruff::Mini::Legend
|
20
22
|
|
21
|
-
def
|
23
|
+
def initialize_attributes
|
22
24
|
super
|
23
25
|
|
24
26
|
@hide_legend = true
|
25
27
|
@hide_title = true
|
26
28
|
@hide_line_numbers = true
|
27
29
|
|
28
|
-
@
|
29
|
-
@
|
30
|
+
@marker_font.size = 50.0
|
31
|
+
@legend_font.size = 60.0
|
30
32
|
|
31
33
|
@minimum_value = 0.0
|
32
34
|
end
|
33
|
-
private :initialize_ivars
|
34
35
|
|
35
|
-
def
|
36
|
+
def setup_data
|
36
37
|
expand_canvas_for_vertical_legend
|
37
|
-
|
38
38
|
super
|
39
|
+
end
|
39
40
|
|
41
|
+
def draw_graph
|
42
|
+
super
|
40
43
|
draw_vertical_legend
|
41
44
|
end
|
42
45
|
end
|
data/lib/gruff/mini/legend.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
module Gruff
|
4
4
|
module Mini
|
5
5
|
# A module to handle the small legend.
|
6
|
+
# @private
|
6
7
|
module Legend
|
7
8
|
attr_accessor :hide_mini_legend, :legend_position
|
8
9
|
|
@@ -30,18 +31,20 @@ module Gruff
|
|
30
31
|
@rows = [@rows, legend_height].max
|
31
32
|
@columns += calculate_legend_width + @left_margin
|
32
33
|
else
|
33
|
-
|
34
|
+
font = @legend_font.dup
|
35
|
+
font.size = scale_fontsize(font.size)
|
36
|
+
@rows += store.length * calculate_caps_height(font) * 1.7
|
34
37
|
end
|
35
38
|
|
36
|
-
Gruff::Renderer.
|
39
|
+
@renderer = Gruff::Renderer.new(@columns, @rows, @scale, @theme_options)
|
37
40
|
end
|
38
41
|
|
39
42
|
def calculate_line_height
|
40
|
-
calculate_caps_height(@
|
43
|
+
calculate_caps_height(@legend_font) * 1.7
|
41
44
|
end
|
42
45
|
|
43
46
|
def calculate_legend_width
|
44
|
-
width = @legend_labels.map { |label| calculate_width(@
|
47
|
+
width = @legend_labels.map { |label| calculate_width(@legend_font, label) }.max
|
45
48
|
scale_fontsize(width + 40 * 1.7)
|
46
49
|
end
|
47
50
|
|
@@ -67,12 +70,12 @@ module Gruff
|
|
67
70
|
@legend_labels.each_with_index do |legend_label, index|
|
68
71
|
# Draw label
|
69
72
|
label = truncate_legend_label(legend_label)
|
70
|
-
text_renderer = Gruff::Renderer::Text.new(label, font: @
|
73
|
+
text_renderer = Gruff::Renderer::Text.new(renderer, label, font: @legend_font)
|
71
74
|
x_offset = current_x_offset + (legend_square_width * 1.7)
|
72
75
|
text_renderer.add_to_render_queue(@raw_columns, 1.0, x_offset, current_y_offset, Magick::WestGravity)
|
73
76
|
|
74
77
|
# Now draw box with color of this dataset
|
75
|
-
rect_renderer = Gruff::Renderer::Rectangle.new(color: store.data[index].color)
|
78
|
+
rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: store.data[index].color)
|
76
79
|
rect_renderer.render(current_x_offset,
|
77
80
|
current_y_offset - legend_square_width / 2.0,
|
78
81
|
current_x_offset + legend_square_width,
|
@@ -90,9 +93,10 @@ module Gruff
|
|
90
93
|
def truncate_legend_label(label)
|
91
94
|
truncated_label = label.to_s
|
92
95
|
|
93
|
-
|
96
|
+
font = @legend_font.dup
|
97
|
+
font.size = scale_fontsize(font.size)
|
94
98
|
max_width = @columns - @legend_left_margin - @right_margin
|
95
|
-
while calculate_width(
|
99
|
+
while calculate_width(font, truncated_label) > max_width && truncated_label.length > 1
|
96
100
|
truncated_label = truncated_label[0..truncated_label.length - 2]
|
97
101
|
end
|
98
102
|
truncated_label + (truncated_label.length < label.to_s.length ? '...' : '')
|
data/lib/gruff/mini/pie.rb
CHANGED
@@ -15,25 +15,28 @@ module Gruff
|
|
15
15
|
module Mini
|
16
16
|
# A class for drawing a small pie graph.
|
17
17
|
class Pie < Gruff::Pie
|
18
|
+
private
|
19
|
+
|
18
20
|
include Gruff::Mini::Legend
|
19
21
|
|
20
|
-
def
|
22
|
+
def initialize_attributes
|
21
23
|
super
|
22
24
|
|
23
25
|
@hide_legend = true
|
24
26
|
@hide_title = true
|
25
27
|
@hide_line_numbers = true
|
26
28
|
|
27
|
-
@
|
28
|
-
@
|
29
|
+
@marker_font.size = 60.0
|
30
|
+
@legend_font.size = 60.0
|
29
31
|
end
|
30
|
-
private :initialize_ivars
|
31
32
|
|
32
|
-
def
|
33
|
+
def setup_data
|
33
34
|
expand_canvas_for_vertical_legend
|
34
|
-
|
35
35
|
super
|
36
|
+
end
|
36
37
|
|
38
|
+
def draw_graph
|
39
|
+
super
|
37
40
|
draw_vertical_legend
|
38
41
|
end
|
39
42
|
end
|