gruff 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +9 -1
- data/Rakefile +11 -1
- data/lib/gruff.rb +4 -0
- data/lib/gruff/bar.rb +0 -1
- data/lib/gruff/base.rb +162 -12
- data/lib/gruff/line.rb +3 -4
- data/lib/gruff/net.rb +133 -0
- data/lib/gruff/pie.rb +8 -46
- data/lib/gruff/scene.rb +196 -0
- data/lib/gruff/spider.rb +130 -0
- data/test/area_test.rb +2 -6
- data/test/bar_test.rb +61 -41
- data/test/base_test.rb +8 -0
- data/test/gruff_test_case.rb +13 -0
- data/test/legend_test.rb +71 -0
- data/test/line_test.rb +13 -54
- data/test/net_test.rb +230 -0
- data/test/photo_test.rb +2 -5
- data/test/pie_test.rb +2 -6
- data/test/scene_test.rb +94 -0
- data/test/sidestacked_bar_test.rb +2 -6
- data/test/spider_test.rb +216 -0
- data/test/stacked_bar_test.rb +2 -6
- metadata +54 -37
data/CHANGELOG
CHANGED
@@ -1,11 +1,19 @@
|
|
1
1
|
CHANGELOG
|
2
2
|
|
3
|
+
== 0.1.2
|
4
|
+
|
5
|
+
* minimum_value and maximum_value can be set after data() to manually scale the graph
|
6
|
+
* Fixed infinite loop bug when values are all equal
|
7
|
+
* Added experimental net and spider graphs
|
8
|
+
* Added non-linear scene graph for a simple interface to complex layered graphs
|
9
|
+
* Initial refactoring of tests
|
10
|
+
* A host of other bug fixes
|
11
|
+
|
3
12
|
== 0.0.8
|
4
13
|
|
5
14
|
* NEW Sidestacked Bar Graphs. [Alun Eyre]
|
6
15
|
* baseline_value larger than data will now show correctly. [Mike Perham]
|
7
16
|
* hide_dots and hide_lines are now options for line graphs.
|
8
|
-
*
|
9
17
|
|
10
18
|
== 0.0.6
|
11
19
|
|
data/Rakefile
CHANGED
@@ -28,6 +28,15 @@ task :clean do
|
|
28
28
|
rm_rf 'doc'
|
29
29
|
end
|
30
30
|
|
31
|
+
desc "Copy documentation to topfunky.com"
|
32
|
+
task :rdoc_deploy => [:rdoc] do
|
33
|
+
dirs = %w{doc}
|
34
|
+
onserver = "topfunky@topfunky.com:/home/topfunky/topfunky.com/clients/rails/gruff"
|
35
|
+
dirs.each do | dir|
|
36
|
+
`rsync -avz -e ssh "#{`pwd`.chomp}/#{dir}" "#{onserver}" --exclude ".svn"`
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
31
40
|
# Run the unit tests
|
32
41
|
Rake::TestTask.new { |t|
|
33
42
|
t.libs << "test"
|
@@ -35,7 +44,6 @@ Rake::TestTask.new { |t|
|
|
35
44
|
t.verbose = true
|
36
45
|
}
|
37
46
|
|
38
|
-
|
39
47
|
# Genereate the RDoc documentation
|
40
48
|
Rake::RDocTask.new { |rdoc|
|
41
49
|
rdoc.rdoc_dir = 'doc'
|
@@ -197,3 +205,5 @@ task :release => [:package] do
|
|
197
205
|
end
|
198
206
|
end
|
199
207
|
end
|
208
|
+
|
209
|
+
|
data/lib/gruff.rb
CHANGED
@@ -6,6 +6,10 @@ require File.dirname(__FILE__) + '/gruff/area'
|
|
6
6
|
require File.dirname(__FILE__) + '/gruff/bar'
|
7
7
|
require File.dirname(__FILE__) + '/gruff/line'
|
8
8
|
require File.dirname(__FILE__) + '/gruff/pie'
|
9
|
+
require File.dirname(__FILE__) + '/gruff/spider'
|
10
|
+
require File.dirname(__FILE__) + '/gruff/net'
|
9
11
|
require File.dirname(__FILE__) + '/gruff/stacked_bar'
|
10
12
|
require File.dirname(__FILE__) + '/gruff/side_stacked_bar'
|
11
13
|
require File.dirname(__FILE__) + '/gruff/photo_bar'
|
14
|
+
|
15
|
+
require File.dirname(__FILE__) + '/gruff/scene'
|
data/lib/gruff/bar.rb
CHANGED
data/lib/gruff/base.rb
CHANGED
@@ -9,7 +9,8 @@
|
|
9
9
|
# and also contributions by
|
10
10
|
# Jarkko Laine, Mike Perham, Andreas Schwarz,
|
11
11
|
# Alun Eyre, Guillaume Theoret, David Stokar,
|
12
|
-
# Paul Rogers, Dave Woodward, Frank Oxener,
|
12
|
+
# Paul Rogers, Dave Woodward, Frank Oxener,
|
13
|
+
# Kevin Clark, Cies Breijs, Richard Cowin,
|
13
14
|
# and a cast of thousands.
|
14
15
|
#
|
15
16
|
|
@@ -17,7 +18,7 @@ require 'RMagick'
|
|
17
18
|
|
18
19
|
module Gruff
|
19
20
|
|
20
|
-
VERSION = '0.1.
|
21
|
+
VERSION = '0.1.2'
|
21
22
|
|
22
23
|
class Base
|
23
24
|
|
@@ -58,10 +59,32 @@ module Gruff
|
|
58
59
|
# Will be scaled down if graph is smaller than 800px wide.
|
59
60
|
attr_accessor :legend_font_size
|
60
61
|
|
62
|
+
# The font size of the labels around the graph
|
61
63
|
attr_accessor :marker_font_size
|
62
64
|
|
65
|
+
# The color of the auxiliary labels and lines
|
66
|
+
attr_accessor :marker_color
|
67
|
+
|
68
|
+
# The font size of the large title at the top of the graph
|
63
69
|
attr_accessor :title_font_size
|
64
70
|
|
71
|
+
# You can manually set a minimum value instead of having the values guessed for you.
|
72
|
+
#
|
73
|
+
# Set it after you have given all your data to the graph object.
|
74
|
+
attr_accessor :minimum_value
|
75
|
+
|
76
|
+
# You can manually set a maximum value, such as a percentage-based graph that always goes to 100.
|
77
|
+
#
|
78
|
+
# If you use this, you must set it after you have given all your data to the graph object.
|
79
|
+
attr_accessor :maximum_value
|
80
|
+
|
81
|
+
# Experimental
|
82
|
+
attr_accessor :additional_line_values
|
83
|
+
|
84
|
+
# Experimental
|
85
|
+
attr_accessor :stacked
|
86
|
+
|
87
|
+
|
65
88
|
# If one numerical argument is given, the graph is drawn at 4/3 ratio according to the given width (800 results in 800x600, 400 gives 400x300, etc.).
|
66
89
|
#
|
67
90
|
# Or, send a geometry string for other ratios ('800x400', '400x225').
|
@@ -100,6 +123,9 @@ module Gruff
|
|
100
123
|
|
101
124
|
@hide_line_markers = @hide_legend = @hide_title = false
|
102
125
|
|
126
|
+
@additional_line_values = []
|
127
|
+
@additional_line_colors = []
|
128
|
+
|
103
129
|
reset_themes()
|
104
130
|
theme_keynote()
|
105
131
|
end
|
@@ -121,6 +147,57 @@ module Gruff
|
|
121
147
|
@colors = color_list
|
122
148
|
end
|
123
149
|
|
150
|
+
# You can set a theme manually. Assign a hash to this method before you send your data.
|
151
|
+
#
|
152
|
+
# graph.theme = {
|
153
|
+
# :colors => %w(orange purple green white red),
|
154
|
+
# :marker_color => 'blue',
|
155
|
+
# :background_colors => %w(black grey)
|
156
|
+
# }
|
157
|
+
#
|
158
|
+
# :background_image => 'squirrel.png' is also possible.
|
159
|
+
#
|
160
|
+
# (Or hopefully something better looking than that.)
|
161
|
+
#
|
162
|
+
def theme=(options)
|
163
|
+
defaults = {
|
164
|
+
:colors => ['black', 'white'],
|
165
|
+
:additional_line_colors => ['grey'],
|
166
|
+
:marker_color => 'white',
|
167
|
+
:background_colors => nil,
|
168
|
+
:background_image => nil
|
169
|
+
}
|
170
|
+
options = defaults.merge options
|
171
|
+
|
172
|
+
reset_themes()
|
173
|
+
|
174
|
+
@colors = options[:colors]
|
175
|
+
@marker_color = options[:marker_color]
|
176
|
+
@additional_line_colors = options[:additional_line_colors]
|
177
|
+
if not options[:background_colors].nil?
|
178
|
+
@base_image = render_gradiated_background *options[:background_colors]
|
179
|
+
else
|
180
|
+
@base_image = render_image_background *options[:background_image]
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# Add a color to the list of available colors for lines.
|
185
|
+
#
|
186
|
+
# Example:
|
187
|
+
# add_color('#c0e9d3')
|
188
|
+
def add_color(colorname)
|
189
|
+
@colors << colorname
|
190
|
+
end
|
191
|
+
|
192
|
+
# Replace the entire color list with a new array of colors. You need to have one more color
|
193
|
+
# than the number of datasets you intend to draw. Also aliased as the colors= setter method.
|
194
|
+
#
|
195
|
+
# Example:
|
196
|
+
# replace_colors('#cc99cc', '#d9e043', '#34d8a2')
|
197
|
+
def replace_colors(color_list=[])
|
198
|
+
@colors = color_list
|
199
|
+
end
|
200
|
+
|
124
201
|
# A color scheme similar to the popular presentation software.
|
125
202
|
def theme_keynote
|
126
203
|
reset_themes()
|
@@ -228,7 +305,7 @@ module Gruff
|
|
228
305
|
end
|
229
306
|
@minimum_value = less_than_min?(data_point) ? data_point : @minimum_value
|
230
307
|
if @minimum_value < 0
|
231
|
-
|
308
|
+
@has_data = true
|
232
309
|
end
|
233
310
|
end
|
234
311
|
end
|
@@ -249,12 +326,50 @@ module Gruff
|
|
249
326
|
end
|
250
327
|
end
|
251
328
|
|
329
|
+
def scale_measurements
|
330
|
+
setup_graph_measurements
|
331
|
+
end
|
332
|
+
|
333
|
+
def total_height
|
334
|
+
@rows + 10
|
335
|
+
end
|
336
|
+
|
337
|
+
def graph_top
|
338
|
+
@graph_top * @scale
|
339
|
+
end
|
340
|
+
|
341
|
+
def graph_height
|
342
|
+
@graph_height * @scale
|
343
|
+
end
|
344
|
+
|
345
|
+
def graph_left
|
346
|
+
@graph_left * @scale
|
347
|
+
end
|
348
|
+
|
349
|
+
def graph_width
|
350
|
+
@graph_width * @scale
|
351
|
+
end
|
352
|
+
|
353
|
+
|
252
354
|
protected
|
253
355
|
|
356
|
+
|
357
|
+
def make_stacked
|
358
|
+
stacked_values = Array.new(@column_count, 0)
|
359
|
+
@data.each do |value_set|
|
360
|
+
value_set[1].each_with_index do |value, index|
|
361
|
+
stacked_values[index] += value
|
362
|
+
end
|
363
|
+
value_set[1] = stacked_values.dup
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
|
254
368
|
# Overridden by subclasses to do the actual plotting of the graph.
|
255
369
|
#
|
256
370
|
# Subclasses should start by calling super() for this method.
|
257
371
|
def draw
|
372
|
+
make_stacked if @stacked
|
258
373
|
setup_drawing()
|
259
374
|
|
260
375
|
# Subclasses will do some drawing here...
|
@@ -276,8 +391,9 @@ protected
|
|
276
391
|
setup_graph_measurements()
|
277
392
|
sort_norm_data() # Sort norm_data with avg largest values set first (for display)
|
278
393
|
|
279
|
-
draw_line_markers()
|
280
394
|
draw_legend()
|
395
|
+
setup_graph_height()
|
396
|
+
draw_line_markers()
|
281
397
|
draw_title
|
282
398
|
end
|
283
399
|
|
@@ -287,7 +403,7 @@ protected
|
|
287
403
|
@norm_data = []
|
288
404
|
return unless @has_data
|
289
405
|
@spread = @maximum_value.to_f - @minimum_value.to_f
|
290
|
-
@spread =
|
406
|
+
@spread = 20.0 if @spread == 0.0 # Protect from divide by zero
|
291
407
|
min_val = @minimum_value.to_f
|
292
408
|
@data.each do |data_row|
|
293
409
|
norm_data_points = []
|
@@ -303,6 +419,10 @@ protected
|
|
303
419
|
end
|
304
420
|
end
|
305
421
|
|
422
|
+
def setup_graph_height
|
423
|
+
@graph_height = @graph_bottom - @graph_top
|
424
|
+
end
|
425
|
+
|
306
426
|
def setup_graph_measurements
|
307
427
|
# TODO Separate horizontal lines from line number labels so they can be shown or hidden independently
|
308
428
|
# TODO Get width of longest left-hand vertical text label and space left margin accordingly
|
@@ -320,7 +440,7 @@ protected
|
|
320
440
|
|
321
441
|
@graph_top = 150.0
|
322
442
|
@graph_bottom = @raw_rows - @graph_bottom_margin
|
323
|
-
|
443
|
+
setup_graph_height()
|
324
444
|
end
|
325
445
|
|
326
446
|
# Draws horizontal background lines and labels
|
@@ -333,12 +453,10 @@ protected
|
|
333
453
|
number_of_lines = 4
|
334
454
|
|
335
455
|
# TODO Round maximum marker value to a round number like 100, 0.1, 0.5, etc.
|
336
|
-
|
337
|
-
# added relative height
|
338
456
|
spread = @maximum_value.to_f - @minimum_value.to_f
|
339
|
-
|
457
|
+
spread = spread > 0 ? spread : 1
|
458
|
+
increment = (spread > 0) ? significant(spread / number_of_lines) : 1
|
340
459
|
inc_graph = @graph_height.to_f / (spread / increment)
|
341
|
-
#inc_graph = @graph_height.to_f / increment
|
342
460
|
|
343
461
|
(0..number_of_lines).each do |index|
|
344
462
|
y = @graph_top + @graph_height - index.to_f * inc_graph
|
@@ -351,11 +469,32 @@ protected
|
|
351
469
|
@d.stroke = 'transparent'
|
352
470
|
@d.pointsize = scale_fontsize(@marker_font_size)
|
353
471
|
@d.gravity = EastGravity
|
472
|
+
|
354
473
|
@d = @d.annotate_scaled( @base_image,
|
355
474
|
100, 20,
|
356
475
|
-10, y - (@marker_font_size/2.0),
|
357
476
|
marker_label.to_s, @scale)
|
358
|
-
|
477
|
+
end
|
478
|
+
i = 0
|
479
|
+
@additional_line_values.each do |value|
|
480
|
+
inc_graph = @graph_height.to_f / (@maximum_value.to_f / value)
|
481
|
+
|
482
|
+
y = @graph_top + @graph_height - inc_graph
|
483
|
+
|
484
|
+
@d = @d.stroke(@additional_line_colors[i])
|
485
|
+
@d = @d.line(@graph_left, y, @graph_right, y)
|
486
|
+
|
487
|
+
|
488
|
+
@d.fill = @additional_line_colors[i]
|
489
|
+
@d.font = @font if @font
|
490
|
+
@d.stroke = 'transparent'
|
491
|
+
@d.pointsize = scale_fontsize(@marker_font_size)
|
492
|
+
@d.gravity = EastGravity
|
493
|
+
@d = @d.annotate_scaled( @base_image,
|
494
|
+
100, 20,
|
495
|
+
-10, y - (@marker_font_size/2.0),
|
496
|
+
"", @scale)
|
497
|
+
i += 1
|
359
498
|
end
|
360
499
|
end
|
361
500
|
|
@@ -468,6 +607,13 @@ protected
|
|
468
607
|
end
|
469
608
|
image[0]
|
470
609
|
end
|
610
|
+
|
611
|
+
# Use with a theme to make a transparent background
|
612
|
+
def render_transparent_background
|
613
|
+
Image.new(@columns, @rows) do
|
614
|
+
self.background_color = 'transparent'
|
615
|
+
end
|
616
|
+
end
|
471
617
|
|
472
618
|
def reset_themes
|
473
619
|
@color_index = 0
|
@@ -511,6 +657,7 @@ protected
|
|
511
657
|
end
|
512
658
|
|
513
659
|
def significant(inc)
|
660
|
+
return 1.0 if inc == 0 # Keep from going into infinite loop
|
514
661
|
factor = 1.0
|
515
662
|
while (inc < 10)
|
516
663
|
inc *= 10
|
@@ -571,7 +718,10 @@ private
|
|
571
718
|
@color_index += 1
|
572
719
|
return @colors[@color_index - 1]
|
573
720
|
else
|
574
|
-
|
721
|
+
# Start over
|
722
|
+
@color_index = 0
|
723
|
+
return @colors[-1]
|
724
|
+
#raise(ColorlistExhaustedException, "There are no more colors left to use.")
|
575
725
|
end
|
576
726
|
end
|
577
727
|
end
|
data/lib/gruff/line.rb
CHANGED
@@ -29,8 +29,7 @@ class Gruff::Line < Gruff::Base
|
|
29
29
|
super args.shift
|
30
30
|
end
|
31
31
|
|
32
|
-
@hide_dots = false
|
33
|
-
@hide_lines = args.empty? ? false : !args.shift # For backwards compatibility. Use g.hide_lines = true from now on.
|
32
|
+
@hide_dots = @hide_lines = false
|
34
33
|
@baseline_color = 'red'
|
35
34
|
end
|
36
35
|
|
@@ -57,7 +56,7 @@ class Gruff::Line < Gruff::Base
|
|
57
56
|
end
|
58
57
|
|
59
58
|
@norm_data.each do |data_row|
|
60
|
-
prev_x = prev_y =
|
59
|
+
prev_x = prev_y = nil
|
61
60
|
@d = @d.stroke data_row[DATA_COLOR_INDEX]
|
62
61
|
@d = @d.fill data_row[DATA_COLOR_INDEX]
|
63
62
|
|
@@ -69,7 +68,7 @@ class Gruff::Line < Gruff::Base
|
|
69
68
|
|
70
69
|
new_y = @graph_top + (@graph_height - data_point * @graph_height)
|
71
70
|
|
72
|
-
if !@hide_lines and prev_x
|
71
|
+
if !@hide_lines and !prev_x.nil? and !prev_y.nil? then
|
73
72
|
@d = @d.line(prev_x, prev_y, new_x, new_y)
|
74
73
|
end
|
75
74
|
@d = @d.circle(new_x, new_y, new_x - circle_radius, new_y) unless @hide_dots
|
data/lib/gruff/net.rb
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
|
2
|
+
require File.dirname(__FILE__) + '/base'
|
3
|
+
|
4
|
+
# Experimental!!! See also the Spider graph.
|
5
|
+
class Gruff::Net < Gruff::Base
|
6
|
+
|
7
|
+
def draw
|
8
|
+
|
9
|
+
super
|
10
|
+
|
11
|
+
return unless @has_data
|
12
|
+
|
13
|
+
@radius = @graph_height / 2.0
|
14
|
+
@center_x = @graph_left + (@graph_width / 2.0)
|
15
|
+
@center_y = @graph_top + (@graph_height / 2.0) - 10 # Move graph up a bit
|
16
|
+
|
17
|
+
@x_increment = @graph_width / (@column_count - 1).to_f
|
18
|
+
circle_radius = clip_value_if_greater_than(@columns / (@norm_data.first[1].size * 2.5), 5.0)
|
19
|
+
|
20
|
+
@d = @d.stroke_opacity 1.0
|
21
|
+
@d = @d.stroke_width clip_value_if_greater_than(@columns / (@norm_data.first[1].size * 4), 5.0)
|
22
|
+
|
23
|
+
if (defined?(@norm_baseline)) then
|
24
|
+
level = @graph_top + (@graph_height - @norm_baseline * @graph_height)
|
25
|
+
@d = @d.push
|
26
|
+
@d.stroke_color @baseline_color
|
27
|
+
@d.fill_opacity 0.0
|
28
|
+
@d.stroke_dasharray(10, 20)
|
29
|
+
@d.stroke_width 5
|
30
|
+
@d.line(@graph_left, level, @graph_left + @graph_width, level)
|
31
|
+
@d = @d.pop
|
32
|
+
end
|
33
|
+
|
34
|
+
@norm_data.each do |data_row|
|
35
|
+
prev_x = prev_y = nil
|
36
|
+
@d = @d.stroke data_row[DATA_COLOR_INDEX]
|
37
|
+
@d = @d.fill data_row[DATA_COLOR_INDEX]
|
38
|
+
|
39
|
+
data_row[1].each_with_index do |data_point, index|
|
40
|
+
next if data_point.nil?
|
41
|
+
|
42
|
+
rad_pos = index * Math::PI * 2 / @column_count
|
43
|
+
point_distance = data_point * @radius
|
44
|
+
start_x = @center_x + Math::sin(rad_pos) * point_distance
|
45
|
+
start_y = @center_y - Math::cos(rad_pos) * point_distance
|
46
|
+
|
47
|
+
next_index = index + 1 < data_row[1].length ? index + 1 : 0
|
48
|
+
|
49
|
+
next_rad_pos = next_index * Math::PI * 2 / @column_count
|
50
|
+
next_point_distance = data_row[1][next_index] * @radius
|
51
|
+
end_x = @center_x + Math::sin(next_rad_pos) * next_point_distance
|
52
|
+
end_y = @center_y - Math::cos(next_rad_pos) * next_point_distance
|
53
|
+
|
54
|
+
@d = @d.line(start_x, start_y, end_x, end_y)
|
55
|
+
|
56
|
+
@d = @d.circle(start_x, start_y, start_x - circle_radius, start_y) unless @hide_dots
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
@d.draw(@base_image)
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
# the lines connecting in the center, with the first line vertical
|
66
|
+
def draw_line_markers
|
67
|
+
return if @hide_line_markers
|
68
|
+
|
69
|
+
|
70
|
+
# have to do this here (AGAIN)... see draw() in this class
|
71
|
+
# because this funtion is called before the @radius, @center_x and @center_y are set
|
72
|
+
@radius = @graph_height / 2.0
|
73
|
+
@center_x = @graph_left + (@graph_width / 2.0)
|
74
|
+
@center_y = @graph_top + (@graph_height / 2.0) - 10 # Move graph up a bit
|
75
|
+
|
76
|
+
|
77
|
+
# Draw horizontal line markers and annotate with numbers
|
78
|
+
@d = @d.stroke(@marker_color)
|
79
|
+
@d = @d.stroke_width 1
|
80
|
+
|
81
|
+
|
82
|
+
(0..@column_count-1).each do |index|
|
83
|
+
rad_pos = index * Math::PI * 2 / @column_count
|
84
|
+
|
85
|
+
@d = @d.line(@center_x, @center_y, @center_x + Math::sin(rad_pos) * @radius, @center_y - Math::cos(rad_pos) * @radius)
|
86
|
+
|
87
|
+
|
88
|
+
marker_label = labels[index] ? labels[index].to_s : '000'
|
89
|
+
|
90
|
+
draw_label(@center_x, @center_y, rad_pos * 360 / (2 * Math::PI), @radius, marker_label)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def draw_label(center_x, center_y, angle, radius, amount)
|
97
|
+
r_offset = 1.1
|
98
|
+
x_offset = center_x # + 15 # The label points need to be tweaked slightly
|
99
|
+
y_offset = center_y # + 0 # This one doesn't though
|
100
|
+
x = x_offset + (radius * r_offset * Math.sin(angle.deg2rad))
|
101
|
+
y = y_offset - (radius * r_offset * Math.cos(angle.deg2rad))
|
102
|
+
|
103
|
+
# Draw label
|
104
|
+
@d.fill = @marker_color
|
105
|
+
@d.font = @font if @font
|
106
|
+
@d.pointsize = scale_fontsize(20)
|
107
|
+
@d.stroke = 'transparent'
|
108
|
+
@d.font_weight = BoldWeight
|
109
|
+
s = angle.deg2rad / (2*Math::PI)
|
110
|
+
@d.gravity = SouthGravity if s >= 0.96 or s < 0.04
|
111
|
+
@d.gravity = SouthWestGravity if s >= 0.04 or s < 0.21
|
112
|
+
@d.gravity = WestGravity if s >= 0.21 or s < 0.29
|
113
|
+
@d.gravity = NorthWestGravity if s >= 0.29 or s < 0.46
|
114
|
+
@d.gravity = NorthGravity if s >= 0.46 or s < 0.54
|
115
|
+
@d.gravity = NorthEastGravity if s >= 0.54 or s < 0.71
|
116
|
+
@d.gravity = EastGravity if s >= 0.71 or s < 0.79
|
117
|
+
@d.gravity = SouthEastGravity if s >= 0.79 or s < 0.96
|
118
|
+
# @d.gravity = NorthGravity
|
119
|
+
@d.annotate_scaled(@base_image, 0, 0, x, y, amount, @scale)
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
class Float
|
126
|
+
# Used for degree => radian conversions
|
127
|
+
def deg2rad
|
128
|
+
self * (Math::PI/180.0)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
|