gruff 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,10 +6,18 @@ module Gruff
6
6
 
7
7
  def initialize(args = {})
8
8
  @color = args[:color]
9
+ @shadow_color = args[:shadow_color]
9
10
  @width = args[:width]
10
11
  end
11
12
 
12
13
  def render(start_x, start_y, end_x, end_y)
14
+ render_line(start_x, start_y, end_x, end_y, @color)
15
+ render_line(start_x, start_y + 1, end_x, end_y + 1, @shadow_color) if @shadow_color
16
+ end
17
+
18
+ private
19
+
20
+ def render_line(start_x, start_y, end_x, end_y, color)
13
21
  # FIXME(uwe): Workaround for Issue #66
14
22
  # https://github.com/topfunky/gruff/issues/66
15
23
  # https://github.com/rmagick/rmagick/issues/82
@@ -24,8 +32,8 @@ module Gruff
24
32
  draw = Renderer.instance.draw
25
33
 
26
34
  draw.push
27
- draw.stroke(@color)
28
- draw.fill(@color)
35
+ draw.stroke(color)
36
+ draw.fill(color)
29
37
  draw.stroke_width(@width) if @width
30
38
  draw.line(start_x, start_y, end_x, end_y)
31
39
  draw.pop
@@ -7,7 +7,7 @@ module Gruff
7
7
  class Renderer
8
8
  include Singleton
9
9
 
10
- attr_accessor :draw, :image, :scale
10
+ attr_accessor :draw, :image, :scale, :text_renderers
11
11
 
12
12
  class << self
13
13
  def setup(columns, rows, font, scale, theme_options)
@@ -21,6 +21,7 @@ module Gruff
21
21
  Renderer.instance.draw = draw
22
22
  Renderer.instance.scale = scale
23
23
  Renderer.instance.image = image
24
+ Renderer.instance.text_renderers = []
24
25
  end
25
26
 
26
27
  def setup_transparent_background(columns, rows)
@@ -42,6 +43,10 @@ module Gruff
42
43
  image = Renderer.instance.image
43
44
 
44
45
  draw.draw(image)
46
+
47
+ Renderer.instance.text_renderers.each do |renderer|
48
+ renderer.render(renderer.width, renderer.height, renderer.x, renderer.y, renderer.gravity)
49
+ end
45
50
  end
46
51
 
47
52
  def write(file_name)
@@ -102,7 +107,7 @@ module Gruff
102
107
 
103
108
  if @gradated_background_retry_count < 3
104
109
  @gradated_background_retry_count += 1
105
- gradated_background(top_color, bottom_color, direct)
110
+ gradated_background(columns, rows, top_color, bottom_color, direct)
106
111
  else
107
112
  raise e
108
113
  end
@@ -11,6 +11,17 @@ module Gruff
11
11
  @rotation = args[:rotation]
12
12
  end
13
13
 
14
+ attr_reader :width, :height, :x, :y, :gravity
15
+ def add_to_render_queue(width, height, x, y, gravity = Magick::NorthGravity)
16
+ @width = width
17
+ @height = height
18
+ @x = x
19
+ @y = y
20
+ @gravity = gravity
21
+
22
+ Renderer.instance.text_renderers << self
23
+ end
24
+
14
25
  def render(width, height, x, y, gravity = Magick::NorthGravity)
15
26
  draw = Renderer.instance.draw
16
27
  image = Renderer.instance.image
@@ -13,33 +13,38 @@ require 'gruff/base'
13
13
  class Gruff::Scatter < Gruff::Base
14
14
  # Maximum X Value. The value will get overwritten by the max in the
15
15
  # datasets.
16
- attr_accessor :maximum_x_value
16
+ attr_writer :maximum_x_value
17
17
 
18
18
  # Minimum X Value. The value will get overwritten by the min in the
19
19
  # datasets.
20
- attr_accessor :minimum_x_value
20
+ attr_writer :minimum_x_value
21
21
 
22
22
  # The number of vertical lines shown for reference.
23
- attr_accessor :marker_x_count
23
+ attr_writer :marker_x_count
24
24
 
25
25
  # Attributes to allow customising the size of the points.
26
- attr_accessor :circle_radius
27
- attr_accessor :stroke_width
26
+ attr_writer :circle_radius
27
+ attr_writer :stroke_width
28
28
 
29
29
  # Allow disabling the significant rounding when labeling the X axis.
30
30
  # This is useful when working with a small range of high values (for example, a date range of months, while seconds as units).
31
- attr_accessor :disable_significant_rounding_x_axis
31
+ attr_writer :disable_significant_rounding_x_axis
32
32
 
33
33
  # Allow enabling vertical lines. When you have a lot of data, they can work great.
34
- attr_accessor :enable_vertical_line_markers
34
+ attr_writer :enable_vertical_line_markers
35
35
 
36
36
  # Allow using vertical labels in the X axis (and setting the label margin).
37
- attr_accessor :x_label_margin
38
- attr_accessor :use_vertical_x_labels
37
+ attr_writer :x_label_margin
38
+ attr_writer :use_vertical_x_labels
39
39
 
40
40
  # Allow passing lambdas to format labels.
41
- attr_accessor :y_axis_label_format
42
- attr_accessor :x_axis_label_format
41
+ attr_writer :y_axis_label_format
42
+ attr_writer :x_axis_label_format
43
+
44
+ def initialize_store
45
+ @store = Gruff::Store.new(Gruff::Store::XYData)
46
+ end
47
+ private :initialize_store
43
48
 
44
49
  def initialize_ivars
45
50
  super
@@ -56,8 +61,6 @@ class Gruff::Scatter < Gruff::Base
56
61
  @x_axis_label_format = nil
57
62
  @x_label_margin = nil
58
63
  @y_axis_label_format = nil
59
-
60
- @store = Gruff::Store.new(Gruff::Store::XYData)
61
64
  end
62
65
  private :initialize_ivars
63
66
 
@@ -202,7 +205,9 @@ private
202
205
  # TODO: Fix the vertical lines, and enable them by default. Not pretty when they don't match up with top y-axis line
203
206
  if @enable_vertical_line_markers
204
207
  x = @graph_left + @graph_width - index.to_f * increment_x_scaled
205
- Gruff::Renderer::Line.new(color: @marker_color).render(x, @graph_top, x, @graph_bottom)
208
+
209
+ line_renderer = Gruff::Renderer::Line.new(color: @marker_color, shadow_color: @marker_shadow_color)
210
+ line_renderer.render(x, @graph_top, x, @graph_bottom)
206
211
  end
207
212
 
208
213
  unless @hide_line_numbers
@@ -213,7 +218,7 @@ private
213
218
  label = vertical_label(marker_label, @x_increment)
214
219
  rotation = -90.0 if @use_vertical_x_labels
215
220
  text_renderer = Gruff::Renderer::Text.new(label, font: @font, size: @marker_font_size, color: @font_color, rotation: rotation)
216
- text_renderer.render(1.0, 1.0, x_offset, y_offset)
221
+ text_renderer.add_to_render_queue(1.0, 1.0, x_offset, y_offset)
217
222
  end
218
223
  end
219
224
  end
@@ -22,21 +22,23 @@ require 'gruff/base'
22
22
  #
23
23
  class Gruff::SideBar < Gruff::Base
24
24
  # Spacing factor applied between bars.
25
- attr_accessor :bar_spacing
25
+ attr_writer :bar_spacing
26
26
 
27
27
  # Spacing factor applied between a group of bars belonging to the same label.
28
- attr_accessor :group_spacing
28
+ attr_writer :group_spacing
29
29
 
30
30
  # Set the number output format for labels using sprintf.
31
31
  # Default is +"%.2f"+.
32
- attr_accessor :label_formatting
32
+ attr_writer :label_formatting
33
33
 
34
34
  # Output the values for the bars on a bar graph.
35
35
  # Default is +false+.
36
- attr_accessor :show_labels_for_bar_values
36
+ attr_writer :show_labels_for_bar_values
37
37
 
38
38
  def initialize_ivars
39
39
  super
40
+ @bar_spacing = 0.9
41
+ @group_spacing = 10
40
42
  @label_formatting = nil
41
43
  @show_labels_for_bar_values = false
42
44
  end
@@ -56,9 +58,6 @@ private
56
58
  def draw_bars
57
59
  # Setup spacing.
58
60
  #
59
- @bar_spacing ||= 0.9
60
- @group_spacing ||= 10
61
-
62
61
  bars_width = (@graph_height - calculate_spacing) / column_count.to_f
63
62
  bar_width = bars_width / store.length
64
63
  height = Array.new(column_count, 0)
@@ -123,13 +122,16 @@ private
123
122
  (0..number_of_lines).each do |index|
124
123
  line_diff = (@graph_right - @graph_left) / number_of_lines
125
124
  x = @graph_right - (line_diff * index) - 1
126
- Gruff::Renderer::Line.new(color: @marker_color).render(x, @graph_bottom, x, @graph_top)
125
+
126
+ line_renderer = Gruff::Renderer::Line.new(color: @marker_color, shadow_color: @marker_shadow_color)
127
+ line_renderer.render(x, @graph_bottom, x, @graph_top)
128
+
127
129
  diff = index - number_of_lines
128
130
  marker_label = diff.abs * increment + minimum_value
129
131
 
130
132
  unless @hide_line_numbers
131
133
  text_renderer = Gruff::Renderer::Text.new(marker_label, font: @font, size: @marker_font_size, color: @font_color)
132
- text_renderer.render(0, 0, x, @graph_bottom + (LABEL_MARGIN * 2.0), Magick::CenterGravity)
134
+ text_renderer.add_to_render_queue(0, 0, x, @graph_bottom + LABEL_MARGIN, Magick::CenterGravity)
133
135
  end
134
136
  end
135
137
  end
@@ -142,7 +144,7 @@ private
142
144
  lbl = @use_data_label ? label : @labels[index]
143
145
 
144
146
  text_renderer = Gruff::Renderer::Text.new(lbl, font: @font, size: @marker_font_size, color: @font_color)
145
- text_renderer.render(@graph_left - LABEL_MARGIN * 2, 1.0, 0.0, y_offset, Magick::EastGravity)
147
+ text_renderer.add_to_render_queue(@graph_left - LABEL_MARGIN, 1.0, 0.0, y_offset, Magick::EastGravity)
146
148
  end
147
149
  end
148
150
 
@@ -27,21 +27,23 @@ class Gruff::SideStackedBar < Gruff::SideBar
27
27
  include BarValueLabelMixin
28
28
 
29
29
  # Spacing factor applied between bars.
30
- attr_accessor :bar_spacing
30
+ attr_writer :bar_spacing
31
31
 
32
32
  # Number of pixels between bar segments.
33
- attr_accessor :segment_spacing
33
+ attr_writer :segment_spacing
34
34
 
35
35
  # Set the number output format for labels using sprintf.
36
36
  # Default is +"%.2f"+.
37
- attr_accessor :label_formatting
37
+ attr_writer :label_formatting
38
38
 
39
39
  # Output the values for the bars on a bar graph.
40
40
  # Default is +false+.
41
- attr_accessor :show_labels_for_bar_values
41
+ attr_writer :show_labels_for_bar_values
42
42
 
43
43
  def initialize_ivars
44
44
  super
45
+ @bar_spacing = 0.9
46
+ @segment_spacing = 2.0
45
47
  @label_formatting = nil
46
48
  @show_labels_for_bar_values = false
47
49
  end
@@ -59,9 +61,6 @@ private
59
61
  # Setup spacing.
60
62
  #
61
63
  # Columns sit stacked.
62
- @bar_spacing ||= 0.9
63
- @segment_spacing ||= 2.0
64
-
65
64
  bar_width = @graph_height / column_count.to_f
66
65
  height = Array.new(column_count, 0)
67
66
  length = Array.new(column_count, @graph_left)
@@ -18,10 +18,8 @@ require 'gruff/base'
18
18
 
19
19
  class Gruff::Spider < Gruff::Base
20
20
  # Hide all text.
21
- attr_reader :hide_text
22
- attr_accessor :hide_axes
23
- attr_reader :transparent_background
24
- attr_accessor :rotation
21
+ attr_writer :hide_axes
22
+ attr_writer :rotation
25
23
 
26
24
  def transparent_background=(value)
27
25
  Gruff::Renderer.setup_transparent_background(@columns, @rows) if value
@@ -34,9 +32,16 @@ class Gruff::Spider < Gruff::Base
34
32
  def initialize(max_value, target_width = 800)
35
33
  super(target_width)
36
34
  @max_value = max_value
35
+ end
36
+
37
+ def initialize_ivars
38
+ super
37
39
  @hide_legend = true
40
+ @hide_axes = false
41
+ @hide_text = false
38
42
  @rotation = 0
39
43
  end
44
+ private :initialize_ivars
40
45
 
41
46
  def draw
42
47
  @hide_line_markers = true
@@ -55,7 +60,7 @@ class Gruff::Spider < Gruff::Base
55
60
  additive_angle = (2 * Math::PI) / store.length
56
61
 
57
62
  # Draw axes
58
- draw_axes(center_x, center_y, radius, additive_angle) unless hide_axes
63
+ draw_axes(center_x, center_y, radius, additive_angle) unless @hide_axes
59
64
 
60
65
  # Draw polygon
61
66
  draw_polygon(center_x, center_y, additive_angle)
@@ -77,14 +82,14 @@ private
77
82
  y = y_offset + ((radius + r_offset) * Math.sin(angle))
78
83
 
79
84
  # Draw label
80
- text_renderer = Gruff::Renderer::Text.new(amount, font: @font, size: legend_font_size, color: @marker_color, weight: Magick::BoldWeight)
81
- text_renderer.render(0, 0, x, y, Magick::CenterGravity)
85
+ text_renderer = Gruff::Renderer::Text.new(amount, font: @font, size: @legend_font_size, color: @marker_color, weight: Magick::BoldWeight)
86
+ text_renderer.add_to_render_queue(0, 0, x, y, Magick::CenterGravity)
82
87
  end
83
88
 
84
89
  def draw_axes(center_x, center_y, radius, additive_angle, line_color = nil)
85
- return if hide_axes
90
+ return if @hide_axes
86
91
 
87
- current_angle = rotation * Math::PI / 180.0
92
+ current_angle = @rotation * Math::PI / 180.0
88
93
 
89
94
  store.data.each do |data_row|
90
95
  x_offset = radius * Math.cos(current_angle)
@@ -93,7 +98,7 @@ private
93
98
  Gruff::Renderer::Line.new(color: line_color || data_row.color, width: 5.0)
94
99
  .render(center_x, center_y, center_x + x_offset, center_y + y_offset)
95
100
 
96
- draw_label(center_x, center_y, current_angle, radius, data_row.label.to_s) unless hide_text
101
+ draw_label(center_x, center_y, current_angle, radius, data_row.label.to_s) unless @hide_text
97
102
 
98
103
  current_angle += additive_angle
99
104
  end
@@ -101,7 +106,7 @@ private
101
106
 
102
107
  def draw_polygon(center_x, center_y, additive_angle, color = nil)
103
108
  points = []
104
- current_angle = rotation * Math::PI / 180.0
109
+ current_angle = @rotation * Math::PI / 180.0
105
110
 
106
111
  store.data.each do |data_row|
107
112
  points << center_x + normalize_points(data_row.points.first) * Math.cos(current_angle)
@@ -15,7 +15,13 @@ require 'gruff/helper/stacked_mixin'
15
15
  #
16
16
  class Gruff::StackedArea < Gruff::Base
17
17
  include StackedMixin
18
- attr_accessor :last_series_goes_on_bottom
18
+ attr_writer :last_series_goes_on_bottom
19
+
20
+ def initialize_ivars
21
+ super
22
+ @last_series_goes_on_bottom = false
23
+ end
24
+ private :initialize_ivars
19
25
 
20
26
  def draw
21
27
  calculate_maximum_by_stack
@@ -28,7 +34,7 @@ class Gruff::StackedArea < Gruff::Base
28
34
  height = Array.new(column_count, 0)
29
35
 
30
36
  data_points = nil
31
- iterator = last_series_goes_on_bottom ? :reverse_each : :each
37
+ iterator = @last_series_goes_on_bottom ? :reverse_each : :each
32
38
  store.norm_data.public_send(iterator) do |data_row|
33
39
  prev_data_points = data_points
34
40
  data_points = []
@@ -19,21 +19,23 @@ class Gruff::StackedBar < Gruff::Base
19
19
  include BarValueLabelMixin
20
20
 
21
21
  # Spacing factor applied between bars.
22
- attr_accessor :bar_spacing
22
+ attr_writer :bar_spacing
23
23
 
24
24
  # Number of pixels between bar segments.
25
- attr_accessor :segment_spacing
25
+ attr_writer :segment_spacing
26
26
 
27
27
  # Set the number output format for labels using sprintf.
28
28
  # Default is +"%.2f"+.
29
- attr_accessor :label_formatting
29
+ attr_writer :label_formatting
30
30
 
31
31
  # Output the values for the bars on a bar graph.
32
32
  # Default is +false+.
33
- attr_accessor :show_labels_for_bar_values
33
+ attr_writer :show_labels_for_bar_values
34
34
 
35
35
  def initialize_ivars
36
36
  super
37
+ @bar_spacing = 0.9
38
+ @segment_spacing = 2
37
39
  @label_formatting = nil
38
40
  @show_labels_for_bar_values = false
39
41
  end
@@ -48,9 +50,6 @@ class Gruff::StackedBar < Gruff::Base
48
50
  # Setup spacing.
49
51
  #
50
52
  # Columns sit stacked.
51
- @bar_spacing ||= 0.9
52
- @segment_spacing ||= 2
53
-
54
53
  bar_width = @graph_width / column_count.to_f
55
54
  padding = (bar_width * (1 - @bar_spacing)) / 2
56
55
 
@@ -10,6 +10,10 @@ module Gruff
10
10
  self.color = color
11
11
  end
12
12
 
13
+ def empty?
14
+ points.empty?
15
+ end
16
+
13
17
  def columns
14
18
  points.length
15
19
  end
@@ -10,6 +10,10 @@ module Gruff
10
10
  self.custom = custom
11
11
  end
12
12
 
13
+ def empty?
14
+ points.empty?
15
+ end
16
+
13
17
  def columns
14
18
  points.length
15
19
  end
@@ -26,7 +26,7 @@ module Gruff
26
26
  end
27
27
 
28
28
  def empty?
29
- @data.empty?
29
+ @data.all?(&:empty?)
30
30
  end
31
31
 
32
32
  def length
@@ -18,6 +18,10 @@ module Gruff
18
18
  x_points.zip(y_points)
19
19
  end
20
20
 
21
+ def empty?
22
+ y_points.empty?
23
+ end
24
+
21
25
  def columns
22
26
  y_points.length
23
27
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Gruff
4
- VERSION = '0.10.0'
4
+ VERSION = '0.11.0'
5
5
  end