gruff 0.9.0 → 0.12.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +21 -4
  3. data/.rubocop_todo.yml +103 -49
  4. data/.travis.yml +3 -6
  5. data/CHANGELOG.md +30 -0
  6. data/README.md +4 -0
  7. data/gruff.gemspec +8 -3
  8. data/lib/gruff.rb +9 -3
  9. data/lib/gruff/accumulator_bar.rb +13 -5
  10. data/lib/gruff/area.rb +22 -5
  11. data/lib/gruff/bar.rb +38 -10
  12. data/lib/gruff/base.rb +325 -236
  13. data/lib/gruff/bezier.rb +18 -4
  14. data/lib/gruff/bullet.rb +22 -14
  15. data/lib/gruff/dot.rb +20 -33
  16. data/lib/gruff/helper/bar_conversion.rb +7 -7
  17. data/lib/gruff/helper/bar_value_label_mixin.rb +3 -0
  18. data/lib/gruff/helper/stacked_mixin.rb +1 -1
  19. data/lib/gruff/histogram.rb +59 -0
  20. data/lib/gruff/line.rb +33 -28
  21. data/lib/gruff/mini/bar.rb +10 -2
  22. data/lib/gruff/mini/legend.rb +9 -4
  23. data/lib/gruff/mini/pie.rb +9 -3
  24. data/lib/gruff/mini/side_bar.rb +18 -4
  25. data/lib/gruff/net.rb +41 -21
  26. data/lib/gruff/patch/rmagick.rb +22 -24
  27. data/lib/gruff/patch/string.rb +9 -4
  28. data/lib/gruff/photo_bar.rb +12 -16
  29. data/lib/gruff/pie.rb +24 -34
  30. data/lib/gruff/renderer/bezier.rb +4 -3
  31. data/lib/gruff/renderer/circle.rb +4 -3
  32. data/lib/gruff/renderer/dash_line.rb +4 -3
  33. data/lib/gruff/renderer/dot.rb +4 -3
  34. data/lib/gruff/renderer/ellipse.rb +4 -3
  35. data/lib/gruff/renderer/line.rb +14 -5
  36. data/lib/gruff/renderer/polygon.rb +5 -4
  37. data/lib/gruff/renderer/polyline.rb +4 -3
  38. data/lib/gruff/renderer/rectangle.rb +3 -2
  39. data/lib/gruff/renderer/renderer.rb +31 -38
  40. data/lib/gruff/renderer/text.rb +29 -7
  41. data/lib/gruff/scatter.rb +26 -24
  42. data/lib/gruff/scene.rb +0 -1
  43. data/lib/gruff/side_bar.rb +51 -20
  44. data/lib/gruff/side_stacked_bar.rb +42 -15
  45. data/lib/gruff/spider.rb +29 -17
  46. data/lib/gruff/stacked_area.rb +19 -8
  47. data/lib/gruff/stacked_bar.rb +34 -13
  48. data/lib/gruff/store/{base_data.rb → basic_data.rb} +9 -7
  49. data/lib/gruff/store/custom_data.rb +8 -6
  50. data/lib/gruff/store/store.rb +7 -6
  51. data/lib/gruff/store/xy_data.rb +10 -7
  52. data/lib/gruff/version.rb +1 -1
  53. metadata +50 -11
  54. data/Rakefile +0 -23
  55. data/docker/Dockerfile +0 -14
  56. data/docker/build.sh +0 -4
  57. data/docker/launch.sh +0 -4
@@ -1,11 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- ##
4
3
  #
5
4
  # Makes a small bar graph suitable for display at 200px or even smaller.
6
5
  #
6
+ # Here's how to set up a Gruff::Mini::Bar.
7
+ #
8
+ # g = Gruff::Mini::Bar.new
9
+ # g.title = 'Mini Bar Graph'
10
+ # g.data :Art, [0, 5, 8, 15]
11
+ # g.data :Philosophy, [10, 3, 2, 8]
12
+ # g.data :Science, [2, 15, 8, 11]
13
+ # g.write('mini_bar.png')
14
+ #
7
15
  module Gruff
8
16
  module Mini
17
+ # A class for drawing a small bar graph.
9
18
  class Bar < Gruff::Bar
10
19
  include Gruff::Mini::Legend
11
20
 
@@ -29,7 +38,6 @@ module Gruff
29
38
  super
30
39
 
31
40
  draw_vertical_legend
32
- Gruff::Renderer.finish
33
41
  end
34
42
  end
35
43
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Gruff
4
4
  module Mini
5
+ # A module to handle the small legend.
5
6
  module Legend
6
7
  attr_accessor :hide_mini_legend, :legend_position
7
8
 
@@ -25,7 +26,7 @@ module Gruff
25
26
  @original_columns = @raw_columns
26
27
 
27
28
  case @legend_position
28
- when :right then
29
+ when :right
29
30
  @rows = [@rows, legend_height].max
30
31
  @columns += calculate_legend_width + @left_margin
31
32
  else
@@ -55,7 +56,7 @@ module Gruff
55
56
  legend_top_margin = 40.0
56
57
 
57
58
  case @legend_position
58
- when :right then
59
+ when :right
59
60
  current_x_offset = @original_columns + @left_margin
60
61
  current_y_offset = @top_margin + legend_top_margin
61
62
  else
@@ -67,7 +68,8 @@ module Gruff
67
68
  # Draw label
68
69
  label = truncate_legend_label(legend_label)
69
70
  text_renderer = Gruff::Renderer::Text.new(label, font: @font, size: @legend_font_size, color: @font_color)
70
- text_renderer.render(@raw_columns, 1.0, current_x_offset + (legend_square_width * 1.7), current_y_offset, Magick::WestGravity)
71
+ x_offset = current_x_offset + (legend_square_width * 1.7)
72
+ text_renderer.add_to_render_queue(@raw_columns, 1.0, x_offset, current_y_offset, Magick::WestGravity)
71
73
 
72
74
  # Now draw box with color of this dataset
73
75
  rect_renderer = Gruff::Renderer::Rectangle.new(color: store.data[index].color)
@@ -87,7 +89,10 @@ module Gruff
87
89
 
88
90
  def truncate_legend_label(label)
89
91
  truncated_label = label.to_s
90
- while calculate_width(scale_fontsize(@legend_font_size), truncated_label) > (@columns - @legend_left_margin - @right_margin) && (truncated_label.length > 1)
92
+
93
+ font_size = scale_fontsize(@legend_font_size)
94
+ max_width = @columns - @legend_left_margin - @right_margin
95
+ while calculate_width(font_size, truncated_label) > max_width && truncated_label.length > 1
91
96
  truncated_label = truncated_label[0..truncated_label.length - 2]
92
97
  end
93
98
  truncated_label + (truncated_label.length < label.to_s.length ? '...' : '')
@@ -1,11 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- ##
4
3
  #
5
4
  # Makes a small pie graph suitable for display at 200px or even smaller.
6
5
  #
6
+ # Here's how to set up a Gruff::Mini::Pie.
7
+ #
8
+ # g = Gruff::Mini::Pie.new
9
+ # g.title = "Visual Pie Graph Test"
10
+ # g.data 'Fries', 20
11
+ # g.data 'Hamburgers', 50
12
+ # g.write("mini_pie_keynote.png")
13
+ #
7
14
  module Gruff
8
15
  module Mini
16
+ # A class for drawing a small pie graph.
9
17
  class Pie < Gruff::Pie
10
18
  include Gruff::Mini::Legend
11
19
 
@@ -27,8 +35,6 @@ module Gruff
27
35
  super
28
36
 
29
37
  draw_vertical_legend
30
-
31
- Gruff::Renderer.finish
32
38
  end
33
39
  end
34
40
  end
@@ -1,11 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- ##
4
3
  #
5
- # Makes a small pie graph suitable for display at 200px or even smaller.
4
+ # Makes a small side bar graph suitable for display at 200px or even smaller.
5
+ #
6
+ # Here's how to set up a Gruff::Mini::SideBar.
7
+ #
8
+ # g = Gruff::Mini::SideBar.new
9
+ # g.title = 'SideBar Graph'
10
+ # g.labels = {
11
+ # 0 => '5/6',
12
+ # 1 => '5/15',
13
+ # 2 => '5/24',
14
+ # 3 => '5/30',
15
+ # }
16
+ # g.group_spacing = 20
17
+ # g.data :Art, [0, 5, 8, 15]
18
+ # g.data :Philosophy, [10, 3, 2, 8]
19
+ # g.data :Science, [2, 15, 8, 11]
20
+ # g.write('mini_sidebar.png')
6
21
  #
7
22
  module Gruff
8
23
  module Mini
24
+ # A class for drawing a small side bar graph.
9
25
  class SideBar < Gruff::SideBar
10
26
  include Gruff::Mini::Legend
11
27
 
@@ -26,8 +42,6 @@ module Gruff
26
42
  super
27
43
 
28
44
  draw_vertical_legend
29
-
30
- Gruff::Renderer.finish
31
45
  end
32
46
  end
33
47
  end
data/lib/gruff/net.rb CHANGED
@@ -1,20 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'gruff/base'
4
-
5
- # Experimental!!! See also the Spider graph.
3
+ # See also the Spider graph.
4
+ #
5
+ # Here's how to make a Gruff::Net.
6
+ #
7
+ # g = Gruff::Net.new
8
+ # g.title = "Net Graph"
9
+ # g.labels = {
10
+ # 0 => '5/6',
11
+ # 1 => '5/15',
12
+ # 2 => '5/24',
13
+ # 3 => '5/30',
14
+ # 4 => '6/4',
15
+ # 5 => '6/12',
16
+ # 6 => '6/21',
17
+ # 7 => '6/28'
18
+ # }
19
+ # g.line_width = 3
20
+ # g.dot_radius = 4
21
+ # g.data :Jimmy, [25, 36, 86, 39, 25, 31, 79, 88]
22
+ # g.data :Julie, [22, 29, 35, 38, 36, 40, 46, 57]
23
+ # g.write("net.png")
24
+ #
6
25
  class Gruff::Net < Gruff::Base
7
- # Hide parts of the graph to fit more datapoints, or for a different appearance.
8
- attr_accessor :hide_dots
26
+ # Hide parts of the graph to fit more data points, or for a different appearance.
27
+ attr_writer :hide_dots
9
28
 
10
29
  # Dimensions of lines and dots; calculated based on dataset size if left unspecified.
11
- attr_accessor :line_width
12
- attr_accessor :dot_radius
30
+ attr_writer :line_width
31
+ attr_writer :dot_radius
13
32
 
14
33
  def initialize_ivars
15
34
  super
16
35
 
17
36
  @hide_dots = false
37
+ @line_width = nil
38
+ @dot_radius = nil
18
39
  @hide_line_numbers = true
19
40
  @sorted_drawing = true
20
41
  end
@@ -25,9 +46,6 @@ class Gruff::Net < Gruff::Base
25
46
 
26
47
  return unless data_given?
27
48
 
28
- stroke_width = line_width || clip_value_if_greater_than(@columns / (store.norm_data.first.points.size * 4), 5.0)
29
- circle_radius = dot_radius || clip_value_if_greater_than(@columns / (store.norm_data.first.points.size * 2.5), 5.0)
30
-
31
49
  store.norm_data.each do |data_row|
32
50
  data_row.points.each_with_index do |data_point, index|
33
51
  next if data_point.nil?
@@ -44,13 +62,14 @@ class Gruff::Net < Gruff::Base
44
62
  end_x = @center_x + Math.sin(next_rad_pos) * next_point_distance
45
63
  end_y = @center_y - Math.cos(next_rad_pos) * next_point_distance
46
64
 
47
- Gruff::Renderer::Line.new(color: data_row.color, width: stroke_width).render(start_x, start_y, end_x, end_y)
65
+ Gruff::Renderer::Line.new(color: data_row.color, width: @stroke_width).render(start_x, start_y, end_x, end_y)
48
66
 
49
- Gruff::Renderer::Circle.new(color: data_row.color, width: stroke_width).render(start_x, start_y, start_x - circle_radius, start_y) unless @hide_dots
67
+ unless @hide_dots
68
+ circle_renderer = Gruff::Renderer::Circle.new(color: data_row.color, width: @stroke_width)
69
+ circle_renderer.render(start_x, start_y, start_x - @circle_radius, start_y)
70
+ end
50
71
  end
51
72
  end
52
-
53
- Gruff::Renderer.finish
54
73
  end
55
74
 
56
75
  private
@@ -59,8 +78,10 @@ private
59
78
  super
60
79
 
61
80
  @radius = @graph_height / 2.0
81
+ @circle_radius = @dot_radius || clip_value_if_greater_than(@columns / (store.norm_data.first.points.size * 2.5), 5.0)
82
+ @stroke_width = @line_width || clip_value_if_greater_than(@columns / (store.norm_data.first.points.size * 4), 5.0)
62
83
  @center_x = @graph_left + (@graph_width / 2.0)
63
- @center_y = @graph_top + (@graph_height / 2.0) - 10 # Move graph up a bit
84
+ @center_y = @graph_top + (@graph_height / 2.0) + 10
64
85
  end
65
86
 
66
87
  # the lines connecting in the center, with the first line vertical
@@ -74,20 +95,19 @@ private
74
95
  Gruff::Renderer::Line.new(color: @marker_color)
75
96
  .render(@center_x, @center_y, @center_x + Math.sin(rad_pos) * @radius, @center_y - Math.cos(rad_pos) * @radius)
76
97
 
77
- marker_label = labels[index] ? labels[index].to_s : '000'
78
- draw_label(@center_x, @center_y, rad_pos * 360 / (2 * Math::PI), @radius, marker_label)
98
+ marker_label = @labels[index] ? @labels[index].to_s : '000'
99
+ draw_label(@center_x, @center_y, rad_pos * 360 / (2 * Math::PI), @radius + @circle_radius, marker_label)
79
100
  end
80
101
  end
81
102
 
82
103
  def draw_label(center_x, center_y, angle, radius, amount)
83
- r_offset = 1.1
84
104
  x_offset = center_x # + 15 # The label points need to be tweaked slightly
85
105
  y_offset = center_y # + 0 # This one doesn't though
86
- x = x_offset + (radius * r_offset * Math.sin(deg2rad(angle)))
87
- y = y_offset - (radius * r_offset * Math.cos(deg2rad(angle)))
106
+ x = x_offset + (radius + LABEL_MARGIN) * Math.sin(deg2rad(angle))
107
+ y = y_offset - (radius + LABEL_MARGIN) * Math.cos(deg2rad(angle))
88
108
 
89
109
  # Draw label
90
110
  text_renderer = Gruff::Renderer::Text.new(amount, font: @font, size: 20, color: @marker_color, weight: Magick::BoldWeight)
91
- text_renderer.render(0, 0, x, y, Magick::CenterGravity)
111
+ text_renderer.add_to_render_queue(0, 0, x, y, Magick::CenterGravity)
92
112
  end
93
113
  end
@@ -1,33 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # @private
3
4
  module Magick
4
- class Draw
5
- # Additional method to scale annotation text since Draw.scale doesn't.
6
- def annotate_scaled(img, width, height, x, y, text, scale)
7
- scaled_width = (width * scale) >= 1 ? (width * scale) : 1
8
- scaled_height = (height * scale) >= 1 ? (height * scale) : 1
5
+ # @private
6
+ module GruffAnnotate
7
+ refine Draw do
8
+ # Additional method to scale annotation text since Draw.scale doesn't.
9
+ def annotate_scaled(img, width, height, x, y, text, scale)
10
+ scaled_width = (width * scale) >= 1 ? (width * scale) : 1
11
+ scaled_height = (height * scale) >= 1 ? (height * scale) : 1
9
12
 
10
- annotate(img,
11
- scaled_width, scaled_height,
12
- x * scale, y * scale,
13
- text.gsub('%', '%%'))
14
- end
15
-
16
- remove_method :stroke_opacity
17
- def stroke_opacity(_opacity)
18
- raise '#stroke_opacity method has different behavior between RMagick and RMagick4J. Should not use this method.'
19
- end
13
+ annotate(img,
14
+ scaled_width, scaled_height,
15
+ x * scale, y * scale,
16
+ text.gsub('%', '%%'))
17
+ end
20
18
 
21
- if defined? JRUBY_VERSION
22
- # FIXME(uwe): We should NOT need to implement this method.
23
- # Remove this method as soon as RMagick4J Issue #16 is fixed.
24
- # https://github.com/Serabe/RMagick4J/issues/16
25
- def fill=(fill)
26
- fill = { white: '#FFFFFF' }[fill.to_sym] || fill
27
- @draw.fill = Magick4J.ColorDatabase.query_default(fill)
28
- self
19
+ if defined? JRUBY_VERSION
20
+ # FIXME(uwe): We should NOT need to implement this method.
21
+ # Remove this method as soon as RMagick4J Issue #16 is fixed.
22
+ # https://github.com/Serabe/RMagick4J/issues/16
23
+ def fill=(fill)
24
+ fill = { white: '#FFFFFF' }[fill.to_sym] || fill
25
+ @draw.fill = Magick4J.ColorDatabase.query_default(fill)
26
+ self
27
+ end
29
28
  end
30
- # EMXIF
31
29
  end
32
30
  end
33
31
  end
@@ -1,8 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class String
4
- #Taken from http://codesnippets.joyent.com/posts/show/330
5
- def commify(delimiter = ',')
6
- gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
3
+ # @private
4
+ module String::GruffCommify
5
+ THOUSAND_SEPARATOR = ','
6
+
7
+ refine String do
8
+ #Taken from http://codesnippets.joyent.com/posts/show/330
9
+ def commify(delimiter = THOUSAND_SEPARATOR)
10
+ gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
11
+ end
7
12
  end
8
13
  end
@@ -1,28 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'gruff/base'
4
-
5
3
  # EXPERIMENTAL!
6
4
  #
7
5
  # Doesn't work yet.
8
6
  #
9
7
  class Gruff::PhotoBar < Gruff::Base
10
- # TODO
11
- #
12
- # define base and cap in yml
13
- # allow for image directory to be located elsewhere
14
- # more exact measurements for bar heights (go all the way to the bottom of the graph)
15
- # option to tile images instead of use a single image
16
- # drop base label a few px lower so photo bar graphs can have a base dropping over the lower marker line
17
- #
8
+ # TODO
9
+ #
10
+ # define base and cap in yml
11
+ # allow for image directory to be located elsewhere
12
+ # more exact measurements for bar heights (go all the way to the bottom of the graph)
13
+ # option to tile images instead of use a single image
14
+ # drop base label a few px lower so photo bar graphs can have a base dropping over the lower marker line
15
+ #
18
16
 
19
17
  # The name of a pre-packaged photo-based theme.
20
18
  attr_reader :theme
21
19
 
22
- # def initialize(target_width=800)
23
- # super
24
- # init_photo_bar_graphics()
25
- # end
20
+ # def initialize(target_width=800)
21
+ # super
22
+ # init_photo_bar_graphics()
23
+ # end
26
24
 
27
25
  def draw
28
26
  super
@@ -70,8 +68,6 @@ class Gruff::PhotoBar < Gruff::Base
70
68
  draw_label(label_center, point_index)
71
69
  end
72
70
  end
73
-
74
- Gruff::Renderer.finish
75
71
  end
76
72
 
77
73
  # Return the chosen theme or the default
data/lib/gruff/pie.rb CHANGED
@@ -1,17 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'gruff/base'
4
-
5
- ##
6
- # Here's how to make a Pie graph:
3
+ #
4
+ # Here's how to make a Gruff::Pie.
7
5
  #
8
6
  # g = Gruff::Pie.new
9
7
  # g.title = "Visual Pie Graph Test"
10
8
  # g.data 'Fries', 20
11
9
  # g.data 'Hamburgers', 50
12
- # g.write("test/output/pie_keynote.png")
10
+ # g.write("pie_keynote.png")
11
+ #
12
+ # To control where the pie chart starts creating slices, use {#zero_degree=}.
13
13
  #
14
- # To control where the pie chart starts creating slices, use #zero_degree.
15
14
  class Gruff::Pie < Gruff::Base
16
15
  DEFAULT_TEXT_OFFSET_PERCENTAGE = 0.15
17
16
 
@@ -28,35 +27,28 @@ class Gruff::Pie < Gruff::Base
28
27
  attr_writer :text_offset_percentage
29
28
 
30
29
  ## Use values instead of percentages.
31
- attr_accessor :show_values_as_labels
30
+ attr_writer :show_values_as_labels
31
+
32
+ def initialize_store
33
+ @store = Gruff::Store.new(Gruff::Store::CustomData)
34
+ end
35
+ private :initialize_store
32
36
 
33
37
  def initialize_ivars
34
38
  super
35
-
39
+ @zero_degree = 0.0
40
+ @hide_labels_less_than = 0.0
41
+ @text_offset_percentage = DEFAULT_TEXT_OFFSET_PERCENTAGE
36
42
  @show_values_as_labels = false
37
-
38
- @store = Gruff::Store.new(Gruff::Store::CustomData)
39
43
  end
40
44
  private :initialize_ivars
41
45
 
42
- def zero_degree
43
- @zero_degree ||= 0.0
44
- end
45
-
46
- def hide_labels_less_than
47
- @hide_labels_less_than ||= 0.0
48
- end
49
-
50
- def text_offset_percentage
51
- @text_offset_percentage ||= DEFAULT_TEXT_OFFSET_PERCENTAGE
52
- end
53
-
54
46
  def options
55
47
  {
56
- zero_degree: zero_degree,
57
- hide_labels_less_than: hide_labels_less_than,
58
- text_offset_percentage: text_offset_percentage,
59
- show_values_as_labels: show_values_as_labels
48
+ zero_degree: @zero_degree,
49
+ hide_labels_less_than: @hide_labels_less_than,
50
+ text_offset_percentage: @text_offset_percentage,
51
+ show_values_as_labels: @show_values_as_labels
60
52
  }
61
53
  end
62
54
 
@@ -75,8 +67,6 @@ class Gruff::Pie < Gruff::Base
75
67
  update_chart_degrees_with slice.degrees
76
68
  end
77
69
  end
78
-
79
- Gruff::Renderer.finish
80
70
  end
81
71
 
82
72
  private
@@ -87,7 +77,7 @@ private
87
77
 
88
78
  slices.sort_by(&:value) if @sort
89
79
 
90
- total = slices.map(&:value).inject(:+).to_f
80
+ total = slices.sum(&:value).to_f
91
81
  slices.each { |slice| slice.total = total }
92
82
  end
93
83
  end
@@ -109,7 +99,7 @@ private
109
99
  # Spatial Value-Related Methods
110
100
 
111
101
  def chart_degrees
112
- @chart_degrees ||= zero_degree
102
+ @chart_degrees ||= @zero_degree
113
103
  end
114
104
 
115
105
  attr_reader :graph_height
@@ -145,17 +135,17 @@ private
145
135
  end
146
136
 
147
137
  def radius_offset
148
- radius + (radius * text_offset_percentage) + distance_from_center
138
+ radius + (radius * @text_offset_percentage) + distance_from_center
149
139
  end
150
140
 
151
141
  def ellipse_factor
152
- radius_offset * text_offset_percentage
142
+ radius_offset * @text_offset_percentage
153
143
  end
154
144
 
155
145
  # Label-Related Methods
156
146
 
157
147
  def process_label_for(slice)
158
- if slice.percentage >= hide_labels_less_than
148
+ if slice.percentage >= @hide_labels_less_than
159
149
  x, y = label_coordinates_for slice
160
150
 
161
151
  draw_label(x, y, slice.label)
@@ -180,7 +170,7 @@ private
180
170
 
181
171
  def draw_label(x, y, value)
182
172
  text_renderer = Gruff::Renderer::Text.new(value, font: @font, size: @marker_font_size, color: @font_color, weight: Magick::BoldWeight)
183
- text_renderer.render(0, 0, x, y, Magick::CenterGravity)
173
+ text_renderer.add_to_render_queue(0, 0, x, y, Magick::CenterGravity)
184
174
  end
185
175
 
186
176
  # Helper Classes