gruff 0.10.0-java → 0.11.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -3
- data/.rubocop_todo.yml +1 -19
- data/CHANGELOG.md +11 -0
- data/Rakefile +24 -0
- data/lib/gruff/area.rb +2 -2
- data/lib/gruff/bar.rb +5 -5
- data/lib/gruff/base.rb +173 -149
- data/lib/gruff/bullet.rb +12 -7
- data/lib/gruff/dot.rb +8 -28
- data/lib/gruff/helper/bar_conversion.rb +6 -6
- data/lib/gruff/histogram.rb +25 -24
- data/lib/gruff/line.rb +24 -15
- data/lib/gruff/mini/legend.rb +1 -1
- data/lib/gruff/net.rb +15 -15
- data/lib/gruff/photo_bar.rb +12 -12
- data/lib/gruff/pie.rb +18 -25
- data/lib/gruff/renderer/line.rb +10 -2
- data/lib/gruff/renderer/renderer.rb +7 -2
- data/lib/gruff/renderer/text.rb +11 -0
- data/lib/gruff/scatter.rb +20 -15
- data/lib/gruff/side_bar.rb +12 -10
- data/lib/gruff/side_stacked_bar.rb +6 -7
- data/lib/gruff/spider.rb +16 -11
- data/lib/gruff/stacked_area.rb +8 -2
- data/lib/gruff/stacked_bar.rb +6 -7
- data/lib/gruff/store/base_data.rb +4 -0
- data/lib/gruff/store/custom_data.rb +4 -0
- data/lib/gruff/store/store.rb +1 -1
- data/lib/gruff/store/xy_data.rb +4 -0
- data/lib/gruff/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2eb363f545e171df5a5d457b5d34e867a060dc4d84eda87d77b2447172d2c04
|
4
|
+
data.tar.gz: fa7708d508f2a016c11af3c08d2b877ff65eaf62955658c9b57fbd08b9f45659
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06d22482b55dd1f478f9ad8ae660f8fe96a4f4b8c7f651207b3de2d1cacf9c1399cf6d88ebd3fdad3178acb020371924f189fa86ee6107d240850788dd9156f3
|
7
|
+
data.tar.gz: 61461cbe1691e7aec5a6c178778c0f40ede97d496857f6a797867be3ae6f52565b33ad8556654ce592aec2717e11e7512bf2cfb25e7cfcdff9797da1faeb9b01
|
data/.rubocop.yml
CHANGED
@@ -18,9 +18,6 @@ Layout/AccessModifierIndentation:
|
|
18
18
|
Layout/ClassStructure:
|
19
19
|
Enabled: false
|
20
20
|
|
21
|
-
Layout/CommentIndentation:
|
22
|
-
Enabled: false
|
23
|
-
|
24
21
|
Layout/FirstMethodArgumentLineBreak:
|
25
22
|
Enabled: false
|
26
23
|
|
@@ -39,6 +36,9 @@ Lint/AssignmentInCondition:
|
|
39
36
|
Lint/NumberConversion:
|
40
37
|
Enabled: false
|
41
38
|
|
39
|
+
Style/ClassAndModuleChildren:
|
40
|
+
Enabled: false
|
41
|
+
|
42
42
|
Style/ConditionalAssignment:
|
43
43
|
Enabled: false
|
44
44
|
|
data/.rubocop_todo.yml
CHANGED
@@ -41,7 +41,7 @@ Metrics/BlockLength:
|
|
41
41
|
# Offense count: 12
|
42
42
|
# Configuration parameters: CountComments.
|
43
43
|
Metrics/ClassLength:
|
44
|
-
Max:
|
44
|
+
Max: 637
|
45
45
|
|
46
46
|
# Offense count: 12
|
47
47
|
# Configuration parameters: IgnoredMethods.
|
@@ -85,24 +85,6 @@ Security/Eval:
|
|
85
85
|
Exclude:
|
86
86
|
- 'test/gruff_test_case.rb'
|
87
87
|
|
88
|
-
# Offense count: 1
|
89
|
-
# Cop supports --auto-correct.
|
90
|
-
# Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, IgnoredMethods, AllowBracesOnProceduralOneLiners, BracesRequiredMethods.
|
91
|
-
# SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
|
92
|
-
# ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
|
93
|
-
# FunctionalMethods: let, let!, subject, watch
|
94
|
-
# IgnoredMethods: lambda, proc, it
|
95
|
-
Style/BlockDelimiters:
|
96
|
-
Exclude:
|
97
|
-
- 'test/test_accumulator_bar.rb'
|
98
|
-
|
99
|
-
# Offense count: 33
|
100
|
-
# Cop supports --auto-correct.
|
101
|
-
# Configuration parameters: AutoCorrect, EnforcedStyle.
|
102
|
-
# SupportedStyles: nested, compact
|
103
|
-
Style/ClassAndModuleChildren:
|
104
|
-
Enabled: false
|
105
|
-
|
106
88
|
# Offense count: 39
|
107
89
|
Style/Documentation:
|
108
90
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.11.0
|
4
|
+
- Fix regression in empty data handling (#445)
|
5
|
+
- Rendering text in front most (#439)
|
6
|
+
- Allow to change settings even after entered the data in Gruff::Histogram (#437)
|
7
|
+
- Adjust label position in Gruff::Net (#436)
|
8
|
+
- Adjust LABEL_MARGIN value (#435)
|
9
|
+
- Add shadow line in marker line into Gruff::{Dot, SideBar, Scatter} (#430)
|
10
|
+
- Move no data message to the vertical center (#428)
|
11
|
+
- Remove the getter method in attributes for configuration (#424)
|
12
|
+
- Fix title margin in Gruff::Bullet if empty title was given (#422)
|
13
|
+
|
3
14
|
## 0.10.0
|
4
15
|
|
5
16
|
* Add Histogram chart (#419)
|
data/Rakefile
CHANGED
@@ -20,4 +20,28 @@ namespace :test do
|
|
20
20
|
system "ruby #{file}"
|
21
21
|
end
|
22
22
|
end
|
23
|
+
|
24
|
+
desc 'Update expected image with output'
|
25
|
+
task :"image:update" do
|
26
|
+
require 'rmagick'
|
27
|
+
require 'fileutils'
|
28
|
+
|
29
|
+
update_expected_images = lambda do |expect_dir, output_dir|
|
30
|
+
Dir.glob("#{output_dir}/*.png") do |output_path|
|
31
|
+
file_name = File.basename(output_path)
|
32
|
+
expected_path = "#{expect_dir}/#{file_name}"
|
33
|
+
|
34
|
+
expected_image = Magick::Image.read(expected_path).first
|
35
|
+
output_image = Magick::Image.read(output_path).first
|
36
|
+
_, error = expected_image.compare_channel(output_image, Magick::PeakAbsoluteErrorMetric)
|
37
|
+
|
38
|
+
if error != 0.0
|
39
|
+
FileUtils.copy(output_path, expected_path)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
update_expected_images.call('test/expected', 'test/output')
|
45
|
+
update_expected_images.call('test/expected_java', 'test/output_java')
|
46
|
+
end
|
23
47
|
end
|
data/lib/gruff/area.rb
CHANGED
@@ -17,10 +17,10 @@ require 'gruff/base'
|
|
17
17
|
#
|
18
18
|
class Gruff::Area < Gruff::Base
|
19
19
|
# Specifies the filling opacity in area graph. Default is +0.85+.
|
20
|
-
|
20
|
+
attr_writer :fill_opacity
|
21
21
|
|
22
22
|
# Specifies the stroke width in line around area graph. Default is +2.0+.
|
23
|
-
|
23
|
+
attr_writer :stroke_width
|
24
24
|
|
25
25
|
def initialize_ivars
|
26
26
|
super
|
data/lib/gruff/bar.rb
CHANGED
@@ -20,22 +20,23 @@ require 'gruff/helper/bar_conversion'
|
|
20
20
|
#
|
21
21
|
class Gruff::Bar < Gruff::Base
|
22
22
|
# Spacing factor applied between bars.
|
23
|
-
|
23
|
+
attr_writer :bar_spacing
|
24
24
|
|
25
25
|
# Spacing factor applied between a group of bars belonging to the same label.
|
26
|
-
|
26
|
+
attr_writer :group_spacing
|
27
27
|
|
28
28
|
# Set the number output format for labels using sprintf.
|
29
29
|
# Default is +"%.2f"+.
|
30
|
-
|
30
|
+
attr_writer :label_formatting
|
31
31
|
|
32
32
|
# Output the values for the bars on a bar graph.
|
33
33
|
# Default is +false+.
|
34
|
-
|
34
|
+
attr_writer :show_labels_for_bar_values
|
35
35
|
|
36
36
|
def initialize_ivars
|
37
37
|
super
|
38
38
|
@spacing_factor = 0.9
|
39
|
+
@group_spacing = 10
|
39
40
|
@label_formatting = nil
|
40
41
|
@show_labels_for_bar_values = false
|
41
42
|
end
|
@@ -72,7 +73,6 @@ protected
|
|
72
73
|
#
|
73
74
|
# Columns sit side-by-side.
|
74
75
|
@bar_spacing ||= @spacing_factor # space between the bars
|
75
|
-
@group_spacing ||= 10
|
76
76
|
|
77
77
|
bar_width = (@graph_width - calculate_spacing) / (column_count * store.length).to_f
|
78
78
|
padding = (bar_width * (1 - @bar_spacing)) / 2
|
data/lib/gruff/base.rb
CHANGED
@@ -20,28 +20,28 @@ module Gruff
|
|
20
20
|
class Base
|
21
21
|
# Space around text elements. Mostly used for vertical spacing.
|
22
22
|
LEGEND_MARGIN = TITLE_MARGIN = 20.0
|
23
|
-
LABEL_MARGIN =
|
23
|
+
LABEL_MARGIN = 15.0
|
24
24
|
DEFAULT_MARGIN = 20.0
|
25
25
|
|
26
26
|
DEFAULT_TARGET_WIDTH = 800.0
|
27
27
|
|
28
28
|
# Blank space above the graph. Default is +20+.
|
29
|
-
|
29
|
+
attr_writer :top_margin
|
30
30
|
|
31
31
|
# Blank space below the graph. Default is +20+.
|
32
|
-
|
32
|
+
attr_writer :bottom_margin
|
33
33
|
|
34
34
|
# Blank space to the right of the graph. Default is +20+.
|
35
|
-
|
35
|
+
attr_writer :right_margin
|
36
36
|
|
37
37
|
# Blank space to the left of the graph. Default is +20+.
|
38
|
-
|
38
|
+
attr_writer :left_margin
|
39
39
|
|
40
40
|
# Blank space below the title. Default is +20+.
|
41
|
-
|
41
|
+
attr_writer :title_margin
|
42
42
|
|
43
43
|
# Blank space below the legend. Default is +20+.
|
44
|
-
|
44
|
+
attr_writer :legend_margin
|
45
45
|
|
46
46
|
# A hash of names for the individual columns, where the key is the array
|
47
47
|
# index for the column this label represents.
|
@@ -50,118 +50,113 @@ module Gruff
|
|
50
50
|
#
|
51
51
|
# @example
|
52
52
|
# { 0 => 2005, 3 => 2006, 5 => 2007, 7 => 2008 }
|
53
|
-
|
53
|
+
attr_writer :labels
|
54
54
|
|
55
55
|
# Used internally for spacing.
|
56
56
|
#
|
57
57
|
# By default, labels are centered over the point they represent.
|
58
|
-
|
58
|
+
attr_writer :center_labels_over_point
|
59
59
|
|
60
60
|
# Used internally for horizontal graph types. Default is +false+.
|
61
|
-
|
61
|
+
attr_writer :has_left_labels
|
62
62
|
|
63
63
|
# Set a label for the bottom of the graph.
|
64
|
-
|
64
|
+
attr_writer :x_axis_label
|
65
65
|
|
66
66
|
# Set a label for the left side of the graph.
|
67
|
-
|
67
|
+
attr_writer :y_axis_label
|
68
68
|
|
69
69
|
# Set increment of the vertical marking lines.
|
70
|
-
|
70
|
+
attr_writer :x_axis_increment
|
71
71
|
|
72
72
|
# Set increment of the horizontal marking lines.
|
73
|
-
|
73
|
+
attr_writer :y_axis_increment
|
74
74
|
|
75
75
|
# Height of staggering between labels (Bar graph only).
|
76
|
-
|
76
|
+
attr_writer :label_stagger_height
|
77
77
|
|
78
78
|
# Truncates labels if longer than max specified.
|
79
|
-
|
79
|
+
attr_writer :label_max_size
|
80
80
|
|
81
|
-
# How truncated labels visually appear if they exceed {#label_max_size}.
|
81
|
+
# How truncated labels visually appear if they exceed {#label_max_size=}.
|
82
82
|
#
|
83
83
|
# - +:absolute+ - does not show trailing dots to indicate truncation. This is the default.
|
84
|
-
# - +:trailing_dots+ - shows trailing dots to indicate truncation (note that {#label_max_size}
|
84
|
+
# - +:trailing_dots+ - shows trailing dots to indicate truncation (note that {#label_max_size=}
|
85
85
|
# must be greater than 3).
|
86
|
-
|
86
|
+
attr_writer :label_truncation_style
|
87
87
|
|
88
88
|
# Get or set the list of colors that will be used to draw the bars or lines.
|
89
89
|
attr_accessor :colors
|
90
90
|
|
91
91
|
# Set the large title of the graph displayed at the top.
|
92
|
-
|
92
|
+
attr_writer :title
|
93
93
|
|
94
|
-
#
|
95
|
-
|
96
|
-
# libraries for this to work properly.
|
97
|
-
attr_reader :font
|
98
|
-
|
99
|
-
# Same as {#font} but for the title.
|
100
|
-
attr_accessor :title_font
|
94
|
+
# Same as {#font=} but for the title.
|
95
|
+
attr_writer :title_font
|
101
96
|
|
102
97
|
# Specifies whether to draw the title bolded or not. Default is +true+.
|
103
|
-
|
98
|
+
attr_writer :bold_title
|
104
99
|
|
105
100
|
# Specifies the text color.
|
106
|
-
|
101
|
+
attr_writer :font_color
|
107
102
|
|
108
103
|
# Prevent drawing of line markers. Default is +false+.
|
109
|
-
|
104
|
+
attr_writer :hide_line_markers
|
110
105
|
|
111
106
|
# Prevent drawing of the legend. Default is +false+.
|
112
|
-
|
107
|
+
attr_writer :hide_legend
|
113
108
|
|
114
109
|
# Prevent drawing of the title. Default is +false+.
|
115
|
-
|
110
|
+
attr_writer :hide_title
|
116
111
|
|
117
112
|
# Prevent drawing of line numbers. Default is +false+.
|
118
|
-
|
113
|
+
attr_writer :hide_line_numbers
|
119
114
|
|
120
115
|
# Set a message shown when there is no data. Fits up to 20 characters. Defaults
|
121
116
|
# to +"No Data."+.
|
122
|
-
|
117
|
+
attr_writer :no_data_message
|
123
118
|
|
124
119
|
# Set the font size of the large title at the top of the graph. Default is +36+.
|
125
|
-
|
120
|
+
attr_writer :title_font_size
|
126
121
|
|
127
122
|
# Optionally set the size of the font. Based on an 800x600px graph.
|
128
123
|
# Default is +20+.
|
129
124
|
#
|
130
125
|
# Will be scaled down if the graph is smaller than 800px wide.
|
131
|
-
|
126
|
+
attr_writer :legend_font_size
|
132
127
|
|
133
128
|
# Display the legend under the graph. Default is +false+.
|
134
|
-
|
129
|
+
attr_writer :legend_at_bottom
|
135
130
|
|
136
131
|
# The font size of the labels around the graph. Default is +21+.
|
137
|
-
|
132
|
+
attr_writer :marker_font_size
|
138
133
|
|
139
134
|
# Set the color of the auxiliary lines.
|
140
|
-
|
135
|
+
attr_writer :marker_color
|
141
136
|
|
142
137
|
# Set the shadow color of the auxiliary lines.
|
143
|
-
|
138
|
+
attr_writer :marker_shadow_color
|
144
139
|
|
145
140
|
# Set the number of horizontal lines shown for reference.
|
146
|
-
|
141
|
+
attr_writer :marker_count
|
147
142
|
|
148
143
|
# Set to +true+ if you want the data sets sorted with largest avg values drawn
|
149
144
|
# first. Default is +false+.
|
150
|
-
|
145
|
+
attr_writer :sort
|
151
146
|
|
152
147
|
# Set to +true+ if you want the data sets drawn with largest avg values drawn
|
153
148
|
# first. This does not affect the legend. Default is +false+.
|
154
|
-
|
149
|
+
attr_writer :sorted_drawing
|
155
150
|
|
156
151
|
# Optionally set the size of the colored box by each item in the legend.
|
157
152
|
# Default is +20.0+.
|
158
153
|
#
|
159
154
|
# Will be scaled down if graph is smaller than 800px wide.
|
160
|
-
|
155
|
+
attr_writer :legend_box_size
|
161
156
|
|
162
157
|
# With Side Bars use the data label for the marker value to the left of the bar.
|
163
158
|
# Default is +false+.
|
164
|
-
|
159
|
+
attr_writer :use_data_label
|
165
160
|
|
166
161
|
# If one numerical argument is given, the graph is drawn at 4/3 ratio
|
167
162
|
# according to the given width (+800+ results in 800x600, +400+ gives 400x300,
|
@@ -173,9 +168,7 @@ module Gruff
|
|
173
168
|
#
|
174
169
|
def initialize(target_width = DEFAULT_TARGET_WIDTH)
|
175
170
|
if target_width.is_a?(String)
|
176
|
-
|
177
|
-
@columns = geometric_width.to_f
|
178
|
-
@rows = geometric_height.to_f
|
171
|
+
@columns, @rows = target_width.split('x').map(&:to_f)
|
179
172
|
else
|
180
173
|
@columns = target_width.to_f
|
181
174
|
@rows = target_width.to_f * 0.75
|
@@ -183,19 +176,14 @@ module Gruff
|
|
183
176
|
@columns.freeze
|
184
177
|
@rows.freeze
|
185
178
|
|
179
|
+
initialize_graph_scale
|
186
180
|
initialize_ivars
|
181
|
+
initialize_store
|
187
182
|
|
188
183
|
self.theme = Themes::KEYNOTE
|
189
184
|
end
|
190
185
|
|
191
|
-
|
192
|
-
#
|
193
|
-
# Subclasses can override this, call super, then set values separately.
|
194
|
-
#
|
195
|
-
# This makes it possible to set defaults in a subclass but still allow
|
196
|
-
# developers to change this values in their program.
|
197
|
-
def initialize_ivars
|
198
|
-
# Internal for calculations
|
186
|
+
def initialize_graph_scale
|
199
187
|
@raw_columns = DEFAULT_TARGET_WIDTH
|
200
188
|
@raw_rows = DEFAULT_TARGET_WIDTH * (@rows / @columns)
|
201
189
|
@raw_columns.freeze
|
@@ -203,10 +191,23 @@ module Gruff
|
|
203
191
|
|
204
192
|
@scale = @columns / @raw_columns
|
205
193
|
@scale.freeze
|
194
|
+
end
|
195
|
+
protected :initialize_graph_scale
|
196
|
+
|
197
|
+
def initialize_store
|
198
|
+
@store = Gruff::Store.new(Gruff::Store::BaseData)
|
199
|
+
end
|
200
|
+
protected :initialize_store
|
206
201
|
|
202
|
+
# Initialize instance variable of attribures
|
203
|
+
#
|
204
|
+
# Subclasses can override this, call super, then set values separately.
|
205
|
+
#
|
206
|
+
# This makes it possible to set defaults in a subclass but still allow
|
207
|
+
# developers to change this values in their program.
|
208
|
+
def initialize_ivars
|
207
209
|
@marker_count = nil
|
208
210
|
@maximum_value = @minimum_value = nil
|
209
|
-
@increment = nil
|
210
211
|
@labels = {}
|
211
212
|
@sort = false
|
212
213
|
@sorted_drawing = false
|
@@ -235,14 +236,10 @@ module Gruff
|
|
235
236
|
@label_max_size = 0
|
236
237
|
@label_truncation_style = :absolute
|
237
238
|
|
238
|
-
@theme_options = {}
|
239
|
-
|
240
239
|
@use_data_label = false
|
241
240
|
@x_axis_increment = nil
|
242
241
|
@x_axis_label = @y_axis_label = nil
|
243
242
|
@y_axis_increment = nil
|
244
|
-
|
245
|
-
@store = Gruff::Store.new(Gruff::Store::BaseData)
|
246
243
|
end
|
247
244
|
protected :initialize_ivars
|
248
245
|
|
@@ -298,11 +295,20 @@ module Gruff
|
|
298
295
|
# graph.theme = {
|
299
296
|
# colors: %w(orange purple green white red),
|
300
297
|
# marker_color: 'blue',
|
301
|
-
# background_colors: ['black', 'grey',
|
298
|
+
# background_colors: ['black', 'grey'],
|
299
|
+
# background_direction: :top_bottom
|
302
300
|
# }
|
303
301
|
#
|
304
302
|
# +background_image: 'squirrel.png'+ is also possible.
|
305
303
|
#
|
304
|
+
# +background_direction+ accepts one of following parameters.
|
305
|
+
# - +:top_bottom+
|
306
|
+
# - +:bottom_top+
|
307
|
+
# - +:left_right+
|
308
|
+
# - +:right_left+
|
309
|
+
# - +:topleft_bottomright+
|
310
|
+
# - +:topright_bottomleft+
|
311
|
+
#
|
306
312
|
# (Or hopefully something better looking than that.)
|
307
313
|
#
|
308
314
|
# @param options [Hash] The optional setting for theme
|
@@ -413,9 +419,11 @@ module Gruff
|
|
413
419
|
end
|
414
420
|
|
415
421
|
# Return the graph as a rendered binary blob.
|
416
|
-
|
422
|
+
#
|
423
|
+
# @param image_format [String] The image format of binary blob.
|
424
|
+
def to_blob(image_format = 'PNG')
|
417
425
|
draw
|
418
|
-
Gruff::Renderer.to_blob(
|
426
|
+
Gruff::Renderer.to_blob(image_format)
|
419
427
|
end
|
420
428
|
|
421
429
|
protected
|
@@ -496,57 +504,17 @@ module Gruff
|
|
496
504
|
# Calculates size of drawable area, general font dimensions, etc.
|
497
505
|
|
498
506
|
def setup_graph_measurements
|
499
|
-
@marker_caps_height =
|
500
|
-
@title_caps_height =
|
501
|
-
@legend_caps_height =
|
502
|
-
|
503
|
-
if @hide_line_markers
|
504
|
-
@graph_left = @left_margin
|
505
|
-
@graph_right_margin = @right_margin
|
506
|
-
@graph_bottom_margin = @bottom_margin
|
507
|
-
else
|
508
|
-
if @has_left_labels
|
509
|
-
longest_left_label_width = calculate_width(@marker_font_size,
|
510
|
-
labels.values.reduce('') { |value, memo| (value.to_s.length > memo.to_s.length) ? value : memo }) * 1.25
|
511
|
-
else
|
512
|
-
longest_left_label_width = calculate_width(@marker_font_size,
|
513
|
-
label(maximum_value.to_f, @increment))
|
514
|
-
end
|
515
|
-
|
516
|
-
# Shift graph if left line numbers are hidden
|
517
|
-
line_number_width = @hide_line_numbers && !@has_left_labels ? 0.0 : (longest_left_label_width + LABEL_MARGIN * 2)
|
518
|
-
|
519
|
-
@graph_left = @left_margin + line_number_width + (@y_axis_label.nil? ? 0.0 : @marker_caps_height + LABEL_MARGIN * 2)
|
520
|
-
|
521
|
-
# Make space for half the width of the rightmost column label.
|
522
|
-
# Might be greater than the number of columns if between-style bar markers are used.
|
523
|
-
last_label = @labels.keys.max.to_i
|
524
|
-
extra_room_for_long_label = begin
|
525
|
-
(last_label >= (column_count - 1) && @center_labels_over_point) ? calculate_width(@marker_font_size, @labels[last_label]) / 2.0 : 0
|
526
|
-
end
|
527
|
-
@graph_right_margin = @right_margin + extra_room_for_long_label
|
528
|
-
|
529
|
-
@graph_bottom_margin = @bottom_margin + @marker_caps_height + LABEL_MARGIN
|
530
|
-
end
|
531
|
-
|
532
|
-
@graph_right = @raw_columns - @graph_right_margin
|
533
|
-
@graph_width = @raw_columns - @graph_left - @graph_right_margin
|
507
|
+
@marker_caps_height = setup_marker_caps_height
|
508
|
+
@title_caps_height = setup_title_caps_height
|
509
|
+
@legend_caps_height = setup_legend_caps_height
|
534
510
|
|
535
|
-
|
536
|
-
|
537
|
-
@
|
538
|
-
|
539
|
-
|
540
|
-
else
|
541
|
-
@top_margin +
|
542
|
-
(hide_title? ? title_margin : @title_caps_height + title_margin) +
|
543
|
-
(@hide_legend ? legend_margin : @legend_caps_height + legend_margin)
|
544
|
-
end
|
545
|
-
end
|
511
|
+
margin_on_right = graph_right_margin
|
512
|
+
@graph_right = @raw_columns - margin_on_right
|
513
|
+
@graph_left = setup_left_margin
|
514
|
+
@graph_top = setup_top_margin
|
515
|
+
@graph_bottom = setup_bottom_margin
|
546
516
|
|
547
|
-
|
548
|
-
# FIXME: Consider chart types other than bar
|
549
|
-
@graph_bottom = @raw_rows - @graph_bottom_margin - x_axis_label_height - @label_stagger_height
|
517
|
+
@graph_width = @raw_columns - @graph_left - margin_on_right
|
550
518
|
@graph_height = @graph_bottom - @graph_top
|
551
519
|
end
|
552
520
|
|
@@ -556,17 +524,17 @@ module Gruff
|
|
556
524
|
# X Axis
|
557
525
|
# Centered vertically and horizontally by setting the
|
558
526
|
# height to 1.0 and the width to the width of the graph.
|
559
|
-
x_axis_label_y_coordinate = @graph_bottom + LABEL_MARGIN
|
527
|
+
x_axis_label_y_coordinate = @graph_bottom + LABEL_MARGIN + @marker_caps_height
|
560
528
|
|
561
529
|
# TODO: Center between graph area
|
562
530
|
text_renderer = Gruff::Renderer::Text.new(@x_axis_label, font: @font, size: @marker_font_size, color: @font_color)
|
563
|
-
text_renderer.
|
531
|
+
text_renderer.add_to_render_queue(@raw_columns, 1.0, 0.0, x_axis_label_y_coordinate)
|
564
532
|
end
|
565
533
|
|
566
534
|
if @y_axis_label
|
567
535
|
# Y Axis, rotated vertically
|
568
536
|
text_renderer = Gruff::Renderer::Text.new(@y_axis_label, font: @font, size: @marker_font_size, color: @font_color, rotation: -90)
|
569
|
-
text_renderer.
|
537
|
+
text_renderer.add_to_render_queue(1.0, @raw_rows, @left_margin + @marker_caps_height / 2.0, 0.0, Magick::CenterGravity)
|
570
538
|
end
|
571
539
|
end
|
572
540
|
|
@@ -580,17 +548,14 @@ module Gruff
|
|
580
548
|
(0..@marker_count).each do |index|
|
581
549
|
y = @graph_top + @graph_height - index.to_f * increment_scaled
|
582
550
|
|
583
|
-
Gruff::Renderer::Line.new(color: @marker_color
|
584
|
-
|
585
|
-
if @marker_shadow_color
|
586
|
-
Gruff::Renderer::Line.new(color: @marker_shadow_color).render(@graph_left, y + 1, @graph_right, y + 1)
|
587
|
-
end
|
551
|
+
line_renderer = Gruff::Renderer::Line.new(color: @marker_color, shadow_color: @marker_shadow_color)
|
552
|
+
line_renderer.render(@graph_left, y, @graph_right, y)
|
588
553
|
|
589
554
|
unless @hide_line_numbers
|
590
555
|
marker_label = BigDecimal(index.to_s) * BigDecimal(@increment.to_s) + BigDecimal(minimum_value.to_s)
|
591
556
|
label = label(marker_label, @increment)
|
592
557
|
text_renderer = Gruff::Renderer::Text.new(label, font: @font, size: @marker_font_size, color: @font_color)
|
593
|
-
text_renderer.
|
558
|
+
text_renderer.add_to_render_queue(@graph_left - LABEL_MARGIN, 1.0, 0.0, y, Magick::EastGravity)
|
594
559
|
end
|
595
560
|
end
|
596
561
|
end
|
@@ -613,27 +578,15 @@ module Gruff
|
|
613
578
|
return if @hide_legend
|
614
579
|
|
615
580
|
legend_labels = store.data.map(&:label)
|
616
|
-
|
617
581
|
legend_square_width = @legend_box_size # small square with color of this item
|
618
|
-
|
619
|
-
# May fix legend drawing problem at small sizes
|
620
|
-
label_widths = [[]] # Used to calculate line wrap
|
621
|
-
legend_labels.each do |label|
|
622
|
-
width = calculate_width(@legend_font_size, label)
|
623
|
-
label_width = width + legend_square_width * 2.7
|
624
|
-
label_widths.last.push label_width
|
625
|
-
|
626
|
-
if sum(label_widths.last) > (@raw_columns * 0.9)
|
627
|
-
label_widths.push [label_widths.last.pop]
|
628
|
-
end
|
629
|
-
end
|
582
|
+
label_widths = calculate_legend_label_widths_for_each_line(legend_labels, legend_square_width)
|
630
583
|
|
631
584
|
current_x_offset = center(sum(label_widths.first))
|
632
585
|
current_y_offset = begin
|
633
586
|
if @legend_at_bottom
|
634
|
-
@graph_height + title_margin
|
587
|
+
@graph_height + @title_margin
|
635
588
|
else
|
636
|
-
hide_title? ? @top_margin + title_margin : @top_margin + title_margin + @title_caps_height
|
589
|
+
hide_title? ? @top_margin + @title_margin : @top_margin + @title_margin + @title_caps_height
|
637
590
|
end
|
638
591
|
end
|
639
592
|
|
@@ -642,7 +595,7 @@ module Gruff
|
|
642
595
|
|
643
596
|
# Draw label
|
644
597
|
text_renderer = Gruff::Renderer::Text.new(legend_label, font: @font, size: @legend_font_size, color: @font_color)
|
645
|
-
text_renderer.
|
598
|
+
text_renderer.add_to_render_queue(@raw_columns, 1.0, current_x_offset + (legend_square_width * 1.7), current_y_offset, Magick::WestGravity)
|
646
599
|
|
647
600
|
# Now draw box with color of this dataset
|
648
601
|
rect_renderer = Gruff::Renderer::Rectangle.new(color: store.data[index].color)
|
@@ -651,23 +604,21 @@ module Gruff
|
|
651
604
|
current_x_offset + legend_square_width,
|
652
605
|
current_y_offset + legend_square_width / 2.0)
|
653
606
|
|
654
|
-
width = calculate_width(legend_font_size, legend_label)
|
655
|
-
|
607
|
+
width = calculate_width(@legend_font_size, legend_label)
|
608
|
+
current_x_offset += width + (legend_square_width * 2.7)
|
609
|
+
label_widths.first.shift
|
656
610
|
|
657
611
|
# Handle wrapping
|
658
|
-
label_widths.first.shift
|
659
612
|
if label_widths.first.empty?
|
660
613
|
label_widths.shift
|
661
614
|
current_x_offset = center(sum(label_widths.first)) unless label_widths.empty?
|
662
|
-
line_height = [@legend_caps_height, legend_square_width].max + legend_margin
|
615
|
+
line_height = [@legend_caps_height, legend_square_width].max + @legend_margin
|
663
616
|
unless label_widths.empty?
|
664
617
|
# Wrap to next line and shrink available graph dimensions
|
665
618
|
current_y_offset += line_height
|
666
619
|
@graph_top += line_height
|
667
620
|
@graph_height = @graph_bottom - @graph_top
|
668
621
|
end
|
669
|
-
else
|
670
|
-
current_x_offset += current_string_offset
|
671
622
|
end
|
672
623
|
end
|
673
624
|
end
|
@@ -685,7 +636,7 @@ module Gruff
|
|
685
636
|
font_size = font_size * (@raw_columns / metrics.width) * 0.95
|
686
637
|
end
|
687
638
|
text_renderer = Gruff::Renderer::Text.new(@title, font: font, size: font_size, color: @font_color, weight: font_weight)
|
688
|
-
text_renderer.
|
639
|
+
text_renderer.add_to_render_queue(@raw_columns, 1.0, 0, @top_margin)
|
689
640
|
end
|
690
641
|
|
691
642
|
# Draws column labels below graph, centered over x_offset
|
@@ -700,11 +651,11 @@ module Gruff
|
|
700
651
|
# TODO: See if index.odd? is the best stragegy
|
701
652
|
y_offset += @label_stagger_height if index.odd?
|
702
653
|
|
703
|
-
label_text = truncate_label_text(labels[index].to_s)
|
654
|
+
label_text = truncate_label_text(@labels[index].to_s)
|
704
655
|
|
705
656
|
if x_offset >= @graph_left && x_offset <= @graph_right
|
706
657
|
text_renderer = Gruff::Renderer::Text.new(label_text, font: @font, size: @marker_font_size, color: @font_color)
|
707
|
-
text_renderer.
|
658
|
+
text_renderer.add_to_render_queue(1.0, 1.0, x_offset, y_offset, gravity)
|
708
659
|
end
|
709
660
|
end
|
710
661
|
end
|
@@ -724,13 +675,13 @@ module Gruff
|
|
724
675
|
return if @hide_line_markers && !bar_value
|
725
676
|
|
726
677
|
text_renderer = Gruff::Renderer::Text.new(data_point, font: @font, size: @marker_font_size, color: @font_color)
|
727
|
-
text_renderer.
|
678
|
+
text_renderer.add_to_render_queue(1.0, 1.0, x_offset, y_offset)
|
728
679
|
end
|
729
680
|
|
730
681
|
# Shows an error message because you have no data.
|
731
682
|
def draw_no_data
|
732
683
|
text_renderer = Gruff::Renderer::Text.new(@no_data_message, font: @font, size: 80, color: @font_color)
|
733
|
-
text_renderer.render(@raw_columns, @raw_rows
|
684
|
+
text_renderer.render(@raw_columns, @raw_rows, 0, 0, Magick::CenterGravity)
|
734
685
|
end
|
735
686
|
|
736
687
|
# Resets everything to defaults (except data).
|
@@ -794,6 +745,63 @@ module Gruff
|
|
794
745
|
|
795
746
|
private
|
796
747
|
|
748
|
+
def setup_marker_caps_height
|
749
|
+
@hide_line_markers ? 0 : calculate_caps_height(@marker_font_size)
|
750
|
+
end
|
751
|
+
|
752
|
+
def setup_title_caps_height
|
753
|
+
hide_title? ? 0 : calculate_caps_height(@title_font_size) * @title.lines.to_a.size
|
754
|
+
end
|
755
|
+
|
756
|
+
def setup_legend_caps_height
|
757
|
+
@hide_legend ? 0 : calculate_caps_height(@legend_font_size)
|
758
|
+
end
|
759
|
+
|
760
|
+
def graph_right_margin
|
761
|
+
@hide_line_markers ? @right_margin : @right_margin + extra_room_for_long_label
|
762
|
+
end
|
763
|
+
|
764
|
+
def extra_room_for_long_label
|
765
|
+
# Make space for half the width of the rightmost column label.
|
766
|
+
# Might be greater than the number of columns if between-style bar markers are used.
|
767
|
+
last_label = @labels.keys.max.to_i
|
768
|
+
(last_label >= (column_count - 1) && @center_labels_over_point) ? calculate_width(@marker_font_size, @labels[last_label]) / 2.0 : 0
|
769
|
+
end
|
770
|
+
|
771
|
+
def setup_left_margin
|
772
|
+
return @left_margin if @hide_line_markers
|
773
|
+
|
774
|
+
if @has_left_labels
|
775
|
+
longest_left_label_width = calculate_width(@marker_font_size,
|
776
|
+
@labels.values.reduce('') { |value, memo| (value.to_s.length > memo.to_s.length) ? value : memo }) * 1.25
|
777
|
+
else
|
778
|
+
longest_left_label_width = calculate_width(@marker_font_size,
|
779
|
+
label(maximum_value.to_f, @increment))
|
780
|
+
end
|
781
|
+
# Shift graph if left line numbers are hidden
|
782
|
+
line_number_width = @hide_line_numbers && !@has_left_labels ? 0.0 : (longest_left_label_width + LABEL_MARGIN * 2)
|
783
|
+
|
784
|
+
@left_margin + line_number_width + (@y_axis_label.nil? ? 0.0 : @marker_caps_height + LABEL_MARGIN * 2)
|
785
|
+
end
|
786
|
+
|
787
|
+
def setup_top_margin
|
788
|
+
return @top_margin if @legend_at_bottom
|
789
|
+
|
790
|
+
# When @hide title, leave a title_margin space for aesthetics.
|
791
|
+
# Same with @hide_legend
|
792
|
+
@top_margin +
|
793
|
+
(hide_title? ? @title_margin : @title_caps_height + @title_margin) +
|
794
|
+
(@hide_legend ? @legend_margin : @legend_caps_height + @legend_margin)
|
795
|
+
end
|
796
|
+
|
797
|
+
def setup_bottom_margin
|
798
|
+
graph_bottom_margin = @hide_line_markers ? @bottom_margin : @bottom_margin + @marker_caps_height + LABEL_MARGIN
|
799
|
+
|
800
|
+
x_axis_label_height = @x_axis_label.nil? ? 0.0 : @marker_caps_height + LABEL_MARGIN
|
801
|
+
# FIXME: Consider chart types other than bar
|
802
|
+
@raw_rows - graph_bottom_margin - x_axis_label_height - @label_stagger_height
|
803
|
+
end
|
804
|
+
|
797
805
|
def truncate_label_text(text)
|
798
806
|
return text if text.size <= @label_max_size
|
799
807
|
|
@@ -838,6 +846,22 @@ module Gruff
|
|
838
846
|
parts.join('.')
|
839
847
|
end
|
840
848
|
|
849
|
+
def calculate_legend_label_widths_for_each_line(legend_labels, legend_square_width)
|
850
|
+
# May fix legend drawing problem at small sizes
|
851
|
+
label_widths = [[]] # Used to calculate line wrap
|
852
|
+
legend_labels.each do |label|
|
853
|
+
width = calculate_width(@legend_font_size, label)
|
854
|
+
label_width = width + legend_square_width * 2.7
|
855
|
+
label_widths.last.push label_width
|
856
|
+
|
857
|
+
if sum(label_widths.last) > (@raw_columns * 0.9)
|
858
|
+
label_widths.push [label_widths.last.pop]
|
859
|
+
end
|
860
|
+
end
|
861
|
+
|
862
|
+
label_widths
|
863
|
+
end
|
864
|
+
|
841
865
|
# Returns the height of the capital letter 'X' for the current font and
|
842
866
|
# size.
|
843
867
|
#
|