gruff 0.15.0-java → 0.18.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +21 -5
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +0 -12
  5. data/CHANGELOG.md +52 -0
  6. data/README.md +14 -3
  7. data/gruff.gemspec +3 -4
  8. data/lib/gruff/accumulator_bar.rb +1 -1
  9. data/lib/gruff/area.rb +6 -4
  10. data/lib/gruff/bar.rb +53 -32
  11. data/lib/gruff/base.rb +297 -186
  12. data/lib/gruff/bezier.rb +4 -2
  13. data/lib/gruff/box.rb +180 -0
  14. data/lib/gruff/bubble.rb +99 -0
  15. data/lib/gruff/bullet.rb +5 -5
  16. data/lib/gruff/candlestick.rb +120 -0
  17. data/lib/gruff/dot.rb +11 -12
  18. data/lib/gruff/font.rb +3 -0
  19. data/lib/gruff/helper/bar_conversion.rb +6 -10
  20. data/lib/gruff/helper/bar_mixin.rb +25 -0
  21. data/lib/gruff/helper/bar_value_label.rb +24 -43
  22. data/lib/gruff/helper/stacked_mixin.rb +19 -1
  23. data/lib/gruff/histogram.rb +9 -6
  24. data/lib/gruff/line.rb +67 -43
  25. data/lib/gruff/mini/legend.rb +15 -11
  26. data/lib/gruff/net.rb +23 -18
  27. data/lib/gruff/patch/string.rb +1 -0
  28. data/lib/gruff/pie.rb +26 -12
  29. data/lib/gruff/renderer/circle.rb +3 -1
  30. data/lib/gruff/renderer/dash_line.rb +3 -2
  31. data/lib/gruff/renderer/dot.rb +28 -15
  32. data/lib/gruff/renderer/line.rb +1 -3
  33. data/lib/gruff/renderer/rectangle.rb +6 -2
  34. data/lib/gruff/renderer/renderer.rb +0 -4
  35. data/lib/gruff/renderer/text.rb +7 -1
  36. data/lib/gruff/scatter.rb +84 -81
  37. data/lib/gruff/side_bar.rb +64 -31
  38. data/lib/gruff/side_stacked_bar.rb +43 -55
  39. data/lib/gruff/spider.rb +52 -14
  40. data/lib/gruff/stacked_area.rb +18 -8
  41. data/lib/gruff/stacked_bar.rb +59 -29
  42. data/lib/gruff/store/xy_data.rb +8 -9
  43. data/lib/gruff/store/xy_pointsizes_data.rb +60 -0
  44. data/lib/gruff/version.rb +1 -1
  45. data/lib/gruff.rb +11 -12
  46. metadata +9 -6
  47. data/lib/gruff/scene.rb +0 -208
  48. data/lib/gruff/store/custom_data.rb +0 -36
data/lib/gruff/spider.rb CHANGED
@@ -19,6 +19,11 @@ class Gruff::Spider < Gruff::Base
19
19
  attr_writer :hide_axes
20
20
  attr_writer :rotation
21
21
 
22
+ def initialize(max_value, target_width = 800)
23
+ super(target_width)
24
+ @max_value = max_value
25
+ end
26
+
22
27
  def transparent_background=(value)
23
28
  renderer.transparent_background(@columns, @rows) if value
24
29
  end
@@ -27,11 +32,6 @@ class Gruff::Spider < Gruff::Base
27
32
  @hide_title = @hide_text = value
28
33
  end
29
34
 
30
- def initialize(max_value, target_width = 800)
31
- super(target_width)
32
- @max_value = max_value
33
- end
34
-
35
35
  private
36
36
 
37
37
  def initialize_attributes
@@ -46,6 +46,29 @@ private
46
46
  @hide_line_markers.freeze
47
47
  end
48
48
 
49
+ def setup_drawing
50
+ @center_labels_over_point = false
51
+ super
52
+ end
53
+
54
+ def setup_graph_measurements
55
+ super
56
+
57
+ @graph_left += LABEL_MARGIN
58
+ @graph_top += LABEL_MARGIN
59
+ @graph_right -= LABEL_MARGIN
60
+ @graph_bottom -= LABEL_MARGIN
61
+
62
+ @graph_width = @graph_right - @graph_left
63
+ @graph_height = @graph_bottom - @graph_top
64
+ end
65
+
66
+ def setup_data
67
+ raise(Gruff::IncorrectNumberOfDatasetsException, 'Requires 3 or more data sets') if store.length < 3
68
+
69
+ super
70
+ end
71
+
49
72
  def draw_graph
50
73
  # Setup basic positioning
51
74
  radius = @graph_height / 2.0
@@ -64,23 +87,38 @@ private
64
87
  end
65
88
 
66
89
  def normalize_points(value)
67
- value * @unit_length
90
+ value.to_f * @unit_length
68
91
  end
69
92
 
70
93
  def draw_label(center_x, center_y, angle, radius, amount)
71
- r_offset = 50 # The distance out from the center of the pie to get point
72
- x_offset = center_x # The label points need to be tweaked slightly
73
- y_offset = center_y + 0 # This one doesn't though
94
+ degree = rad2deg(angle)
95
+ metrics = text_metrics(@marker_font, amount)
96
+
97
+ r_offset = LABEL_MARGIN # The distance out from the center of the pie to get point
98
+ x_offset = center_x # The label points need to be tweaked slightly
99
+
100
+ x_offset -= begin
101
+ case degree
102
+ when 0..45, 315..360
103
+ 0
104
+ when 135..225
105
+ metrics.width
106
+ else
107
+ metrics.width / 2
108
+ end
109
+ end
110
+
111
+ y_offset = center_y - (metrics.height / 2.0) # This one doesn't though
74
112
  x = x_offset + ((radius + r_offset) * Math.cos(angle))
75
113
  y = y_offset + ((radius + r_offset) * Math.sin(angle))
76
114
 
77
- draw_label_at(1.0, 1.0, x, y, amount, Magick::CenterGravity)
115
+ draw_label_at(metrics.width, metrics.height, x, y, amount, gravity: Magick::CenterGravity)
78
116
  end
79
117
 
80
118
  def draw_axes(center_x, center_y, radius, additive_angle, line_color = nil)
81
119
  return if @hide_axes
82
120
 
83
- current_angle = @rotation * Math::PI / 180.0
121
+ current_angle = deg2rad(@rotation)
84
122
 
85
123
  store.data.each do |data_row|
86
124
  x_offset = radius * Math.cos(current_angle)
@@ -97,11 +135,11 @@ private
97
135
 
98
136
  def draw_polygon(center_x, center_y, additive_angle, color = nil)
99
137
  points = []
100
- current_angle = @rotation * Math::PI / 180.0
138
+ current_angle = deg2rad(@rotation)
101
139
 
102
140
  store.data.each do |data_row|
103
- points << center_x + normalize_points(data_row.points.first) * Math.cos(current_angle)
104
- points << center_y + normalize_points(data_row.points.first) * Math.sin(current_angle)
141
+ points << (center_x + (normalize_points(data_row.points.first) * Math.cos(current_angle)))
142
+ points << (center_y + (normalize_points(data_row.points.first) * Math.sin(current_angle)))
105
143
  current_angle += additive_angle
106
144
  end
107
145
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'helper/stacked_mixin'
4
+
3
5
  #
4
6
  # Here's how to set up a Gruff::StackedArea.
5
7
  #
@@ -20,25 +22,31 @@ class Gruff::StackedArea < Gruff::Base
20
22
 
21
23
  private
22
24
 
25
+ def initialize_attributes
26
+ super
27
+ @minimum_value = 0.0
28
+ end
29
+
23
30
  def setup_data
24
31
  calculate_maximum_by_stack
25
32
  super
26
33
  end
27
34
 
28
35
  def draw_graph
29
- x_increment = @graph_width / (column_count - 1).to_f
36
+ x_increment = (@graph_width / (column_count - 1)).to_f
30
37
 
31
38
  height = Array.new(column_count, 0)
32
39
 
33
- data_points = nil
40
+ prev_data_points = nil
34
41
  store.norm_data.each do |data_row|
35
- prev_data_points = data_points
42
+ next if data_row.points.empty?
43
+
36
44
  data_points = []
37
45
 
38
46
  data_row.points.each_with_index do |data_point, index|
39
47
  # Use incremented x and scaled y
40
48
  new_x = @graph_left + (x_increment * index)
41
- new_y = @graph_top + (@graph_height - data_point * @graph_height - height[index])
49
+ new_y = @graph_top + (@graph_height - (data_point * @graph_height) - height[index])
42
50
 
43
51
  height[index] += (data_point * @graph_height)
44
52
 
@@ -50,20 +58,22 @@ private
50
58
 
51
59
  poly_points = data_points.dup
52
60
  if prev_data_points
53
- (prev_data_points.length / 2 - 1).downto(0) do |i|
61
+ ((prev_data_points.length / 2) - 1).downto(0) do |i|
54
62
  poly_points << prev_data_points[2 * i]
55
- poly_points << prev_data_points[2 * i + 1]
63
+ poly_points << prev_data_points[(2 * i) + 1]
56
64
  end
57
65
  else
58
66
  poly_points << @graph_right
59
- poly_points << @graph_bottom - 1
67
+ poly_points << (@graph_bottom - 1)
60
68
  poly_points << @graph_left
61
- poly_points << @graph_bottom - 1
69
+ poly_points << (@graph_bottom - 1)
62
70
  end
63
71
  poly_points << data_points[0]
64
72
  poly_points << data_points[1]
65
73
 
66
74
  Gruff::Renderer::Polygon.new(renderer, color: data_row.color).render(poly_points)
75
+
76
+ prev_data_points = data_points
67
77
  end
68
78
  end
69
79
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'helper/stacked_mixin'
4
+
3
5
  #
4
6
  # Here's how to set up a Gruff::StackedBar.
5
7
  #
@@ -39,6 +41,16 @@ private
39
41
  @label_formatting = nil
40
42
  @show_labels_for_bar_values = false
41
43
  @hide_labels = false
44
+ @minimum_value = 0.0
45
+ end
46
+
47
+ def setup_drawing
48
+ # Labels will be centered over the left of the bar if
49
+ # there are more labels than columns. This is basically the same
50
+ # as where it would be for a line graph.
51
+ @center_labels_over_point = (@labels.keys.length > column_count)
52
+
53
+ super
42
54
  end
43
55
 
44
56
  def setup_data
@@ -46,47 +58,61 @@ private
46
58
  super
47
59
  end
48
60
 
61
+ def setup_graph_measurements
62
+ super
63
+ return if @hide_line_markers
64
+
65
+ if @show_labels_for_bar_values
66
+ if maximum_value >= 0
67
+ _, metrics = Gruff::BarValueLabel.metrics(maximum_value, @label_formatting, proc_text_metrics)
68
+ @graph_top += metrics.height
69
+ end
70
+
71
+ @graph_height = @graph_bottom - @graph_top
72
+ end
73
+ end
74
+
49
75
  # Draws a bar graph, but multiple sets are stacked on top of each other.
50
76
  def draw_graph
51
77
  # Setup spacing.
52
78
  #
53
79
  # Columns sit stacked.
54
- bar_width = @graph_width / column_count.to_f
80
+ bar_width = @graph_width / column_count
55
81
  padding = (bar_width * (1 - @bar_spacing)) / 2
56
82
 
57
- height = Array.new(column_count, 0)
58
- stack_bar_value_label = Gruff::BarValueLabel::StackedBar.new
83
+ # Setup the BarConversion Object
84
+ conversion = Gruff::BarConversion.new(
85
+ top: @graph_top, bottom: @graph_bottom,
86
+ minimum_value: minimum_value, maximum_value: maximum_value, spread: @spread
87
+ )
59
88
 
60
- store.norm_data.each_with_index do |data_row, row_index|
61
- data_row.points.each_with_index do |data_point, point_index|
62
- next if data_point == 0
89
+ normalized_stacked_bars.each_with_index do |stacked_bars, stacked_index|
90
+ total = 0
91
+ left_x = @graph_left + (bar_width * stacked_index) + padding
92
+ right_x = left_x + (bar_width * @bar_spacing)
63
93
 
64
- # Use incremented x and scaled y
65
- left_x = @graph_left + (bar_width * point_index) + padding
66
- left_y = @graph_top + (@graph_height -
67
- data_point * @graph_height -
68
- height[point_index]) + @segment_spacing
69
- right_x = left_x + bar_width * @bar_spacing
70
- right_y = @graph_top + @graph_height - height[point_index]
94
+ top_y = 0
95
+ stacked_bars.each do |bar|
96
+ next if bar.point == 0
71
97
 
72
- # update the total height of the current stacked bar
73
- height[point_index] += (data_point * @graph_height)
98
+ bottom_y, = conversion.get_top_bottom_scaled(total)
99
+ bottom_y -= @segment_spacing
100
+ top_y, = conversion.get_top_bottom_scaled(total + bar.point)
74
101
 
75
- rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: data_row.color)
76
- rect_renderer.render(left_x, left_y, right_x, right_y)
102
+ rect_renderer = Gruff::Renderer::Rectangle.new(renderer, color: bar.color)
103
+ rect_renderer.render(left_x, bottom_y, right_x, top_y)
77
104
 
78
- # Calculate center based on bar_width and current row
79
- label_center = left_x + bar_width * @bar_spacing / 2.0
80
- draw_label(label_center, point_index)
81
-
82
- bar_value_label = Gruff::BarValueLabel::Bar.new([left_x, left_y, right_x, right_y], store.data[row_index].points[point_index])
83
- stack_bar_value_label.add(bar_value_label, point_index)
105
+ total += bar.point
84
106
  end
85
- end
86
107
 
87
- if @show_labels_for_bar_values
88
- stack_bar_value_label.prepare_rendering(@label_formatting, bar_width) do |x, y, text|
89
- draw_value_label(x, y, text)
108
+ label_center = left_x + (bar_width * @bar_spacing / 2.0)
109
+ draw_label(label_center, stacked_index)
110
+
111
+ if @show_labels_for_bar_values
112
+ bar_value_label = Gruff::BarValueLabel::Bar.new([left_x, top_y, right_x, @graph_bottom], stacked_bars.sum(&:value))
113
+ bar_value_label.prepare_rendering(@label_formatting, proc_text_metrics) do |x, y, text, _text_width, text_height|
114
+ draw_value_label(bar_width * @bar_spacing, text_height, x, y, text)
115
+ end
90
116
  end
91
117
  end
92
118
  end
@@ -96,10 +122,14 @@ private
96
122
  end
97
123
 
98
124
  def hide_left_label_area?
99
- @hide_line_markers
125
+ @hide_line_markers && @y_axis_label.nil?
100
126
  end
101
127
 
102
128
  def hide_bottom_label_area?
103
- hide_labels?
129
+ hide_labels? && @x_axis_label.nil? && @legend_at_bottom == false
130
+ end
131
+
132
+ def proc_text_metrics
133
+ ->(text) { text_metrics(@marker_font, text) }
104
134
  end
105
135
  end
@@ -3,18 +3,17 @@
3
3
  module Gruff
4
4
  class Store
5
5
  # @private
6
- class XYData < Struct.new(:label, :y_points, :color, :x_points)
7
- def initialize(label, y_points, color, x_points = nil)
8
- x_points = Array(x_points) if x_points
9
- super(label.to_s, Array(y_points), color, x_points)
6
+ class XYData < Struct.new(:label, :x_points, :y_points, :color)
7
+ def initialize(label, x_points, y_points, color)
8
+ y_points = Array(y_points)
9
+ x_points = x_points ? Array(x_points) : Array.new(y_points.length)
10
+ raise ArgumentError, 'x_points.length != y_points.length!' if x_points.length != y_points.length
11
+
12
+ super(label.to_s, x_points, y_points, color)
10
13
  end
11
14
 
12
15
  alias points y_points
13
16
 
14
- def x_points
15
- self[:x_points] || Array.new(y_points.length)
16
- end
17
-
18
17
  def coordinates
19
18
  x_points.zip(y_points)
20
19
  end
@@ -53,7 +52,7 @@ module Gruff
53
52
  y.nil? ? nil : (y.to_f - minimum_y.to_f) / spread_y
54
53
  end
55
54
 
56
- self.class.new(label, norm_y_points, color, norm_x_points)
55
+ self.class.new(label, norm_x_points, norm_y_points, color)
57
56
  end
58
57
  end
59
58
  end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gruff
4
+ class Store
5
+ # @private
6
+ class XYPointsizeData < Struct.new(:label, :x_points, :y_points, :point_sizes, :color)
7
+ def initialize(label, x_points, y_points, point_sizes, color)
8
+ y_points = Array(y_points)
9
+ x_points = x_points ? Array(x_points) : Array.new(y_points.length)
10
+ raise ArgumentError, 'x_points.length != y_points.length!' if x_points.length != y_points.length
11
+ raise ArgumentError, 'x_points.length != point_sizes.length!' if x_points.length != point_sizes.length
12
+
13
+ super(label.to_s, x_points, y_points, point_sizes, color)
14
+ end
15
+
16
+ alias points y_points
17
+
18
+ def coordinate_and_pointsizes
19
+ x_points.zip(y_points, point_sizes)
20
+ end
21
+
22
+ def empty?
23
+ y_points.empty?
24
+ end
25
+
26
+ def columns
27
+ y_points.length
28
+ end
29
+
30
+ def min
31
+ y_points.compact.min
32
+ end
33
+ alias min_y min
34
+
35
+ def max
36
+ y_points.compact.max
37
+ end
38
+ alias max_y max
39
+
40
+ def min_x
41
+ x_points.compact.min
42
+ end
43
+
44
+ def max_x
45
+ x_points.compact.max
46
+ end
47
+
48
+ def normalize(minimum_x:, minimum_y:, spread_x:, spread_y:)
49
+ norm_x_points = x_points.map do |x|
50
+ x.nil? ? nil : (x.to_f - minimum_x.to_f) / spread_x
51
+ end
52
+ norm_y_points = y_points.map do |y|
53
+ y.nil? ? nil : (y.to_f - minimum_y.to_f) / spread_y
54
+ end
55
+
56
+ self.class.new(label, norm_x_points, norm_y_points, point_sizes, color)
57
+ end
58
+ end
59
+ end
60
+ end
data/lib/gruff/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Gruff
4
- VERSION = '0.15.0'
4
+ VERSION = '0.18.0'
5
5
  end
data/lib/gruff.rb CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  require 'rmagick'
4
4
 
5
- require 'gruff/patch/rmagick'
6
- require 'gruff/patch/string'
7
- require 'gruff/renderer/renderer'
8
- require 'gruff/store/store'
9
- require 'gruff/font'
10
- require 'gruff/base'
11
- require 'gruff/version'
5
+ require_relative 'gruff/patch/rmagick'
6
+ require_relative 'gruff/patch/string'
7
+ require_relative 'gruff/renderer/renderer'
8
+ require_relative 'gruff/store/store'
9
+ require_relative 'gruff/font'
10
+ require_relative 'gruff/base'
11
+ require_relative 'gruff/version'
12
12
 
13
13
  ##
14
14
  # = Gruff. Graphs.
@@ -21,22 +21,21 @@ module Gruff
21
21
 
22
22
  autoload :BarConversion, Gruff.libpath('helper/bar_conversion')
23
23
  autoload :BarValueLabel, Gruff.libpath('helper/bar_value_label')
24
- class Base
25
- autoload :StackedMixin, Gruff.libpath('helper/stacked_mixin')
26
- end
27
24
 
28
25
  autoload :AccumulatorBar, Gruff.libpath('accumulator_bar')
29
26
  autoload :Area, Gruff.libpath('area')
30
27
  autoload :Bar, Gruff.libpath('bar')
31
28
  autoload :Bezier, Gruff.libpath('bezier')
29
+ autoload :Box, Gruff.libpath('box')
30
+ autoload :Bubble, Gruff.libpath('bubble')
32
31
  autoload :Bullet, Gruff.libpath('bullet')
32
+ autoload :Candlestick, Gruff.libpath('candlestick')
33
33
  autoload :Dot, Gruff.libpath('dot')
34
34
  autoload :Histogram, Gruff.libpath('histogram')
35
35
  autoload :Line, Gruff.libpath('line')
36
36
  autoload :Net, Gruff.libpath('net')
37
37
  autoload :Pie, Gruff.libpath('pie')
38
38
  autoload :Scatter, Gruff.libpath('scatter')
39
- autoload :Scene, Gruff.libpath('scene')
40
39
  autoload :SideBar, Gruff.libpath('side_bar')
41
40
  autoload :SideStackedBar, Gruff.libpath('side_stacked_bar')
42
41
  autoload :Spider, Gruff.libpath('spider')
@@ -61,8 +60,8 @@ module Gruff
61
60
 
62
61
  class Store
63
62
  autoload :BasicData, Gruff.libpath('store/basic_data')
64
- autoload :CustomData, Gruff.libpath('store/custom_data')
65
63
  autoload :XYData, Gruff.libpath('store/xy_data')
64
+ autoload :XYPointsizeData, Gruff.libpath('store/xy_pointsizes_data')
66
65
  end
67
66
 
68
67
  module Mini
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gruff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 0.18.0
5
5
  platform: java
6
6
  authors:
7
7
  - Geoffrey Grosenbach
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-04-17 00:00:00.000000000 Z
12
+ date: 2022-06-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  requirement: !ruby/object:Gem::Requirement
@@ -86,7 +86,7 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 0.9.25
89
+ version: 0.9.28
90
90
  name: yard
91
91
  prerelease: false
92
92
  type: :development
@@ -94,7 +94,7 @@ dependencies:
94
94
  requirements:
95
95
  - - "~>"
96
96
  - !ruby/object:Gem::Version
97
- version: 0.9.25
97
+ version: 0.9.28
98
98
  description: Beautiful graphs for one or multiple datasets. Can be used on websites
99
99
  or in documents.
100
100
  email: boss@topfunky.com
@@ -123,10 +123,14 @@ files:
123
123
  - lib/gruff/bar.rb
124
124
  - lib/gruff/base.rb
125
125
  - lib/gruff/bezier.rb
126
+ - lib/gruff/box.rb
127
+ - lib/gruff/bubble.rb
126
128
  - lib/gruff/bullet.rb
129
+ - lib/gruff/candlestick.rb
127
130
  - lib/gruff/dot.rb
128
131
  - lib/gruff/font.rb
129
132
  - lib/gruff/helper/bar_conversion.rb
133
+ - lib/gruff/helper/bar_mixin.rb
130
134
  - lib/gruff/helper/bar_value_label.rb
131
135
  - lib/gruff/helper/stacked_mixin.rb
132
136
  - lib/gruff/histogram.rb
@@ -151,16 +155,15 @@ files:
151
155
  - lib/gruff/renderer/renderer.rb
152
156
  - lib/gruff/renderer/text.rb
153
157
  - lib/gruff/scatter.rb
154
- - lib/gruff/scene.rb
155
158
  - lib/gruff/side_bar.rb
156
159
  - lib/gruff/side_stacked_bar.rb
157
160
  - lib/gruff/spider.rb
158
161
  - lib/gruff/stacked_area.rb
159
162
  - lib/gruff/stacked_bar.rb
160
163
  - lib/gruff/store/basic_data.rb
161
- - lib/gruff/store/custom_data.rb
162
164
  - lib/gruff/store/store.rb
163
165
  - lib/gruff/store/xy_data.rb
166
+ - lib/gruff/store/xy_pointsizes_data.rb
164
167
  - lib/gruff/themes.rb
165
168
  - lib/gruff/version.rb
166
169
  - rails_generators/gruff/gruff_generator.rb