gruff 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 31e192a4a5b3e9546c0217dc1b25b7b60f18f302
4
- data.tar.gz: 7abadd195627de5bb279d419aea29a658baefe70
3
+ metadata.gz: 1c618f771c03abae8519d369261cbc112e0cbc41
4
+ data.tar.gz: 406a006220455d8360e8b19cd4b25f88663befca
5
5
  SHA512:
6
- metadata.gz: 04e35cbfeeeefc7ae8acc51cda3b2ba809416673a70eb5d289ade1cef72c3dd6cd0839ce99521bbf222c65a30e28b4a8918dfa517e2570d0ba02486405d3f3ca
7
- data.tar.gz: 466e588fe729a90ef3ef1efc7333961a401623a794474506754faaa25236a2647347f60e25a1fe9d8b1aa898be7bfe2d67bdffb13b5098d962ebf44fd58c1db7
6
+ metadata.gz: cd1ceca4d3c901e2067df8f44d264e7ef66829367232fb237528453598109f4a432ed4d5f23008890fbafa960b395f65945f15d8e25efa3357acee8594d39e5d
7
+ data.tar.gz: 5fe22dbd8fa28469dbe85aa2511cd0815bcb702ac958b10b32305be9d6d0e74bea47cdfbdc673396d81df64281a53e007c30ab045002cd9de7c9c692b0e65303
@@ -1,14 +1,17 @@
1
1
  language: ruby
2
- notifications:
3
- email:
4
- - uwe@kubosch.no
2
+ sudo: false
5
3
  rvm:
6
4
  - "1.8.7"
7
5
  - "1.9.3"
8
6
  - "2.0.0"
9
- - jruby-18mode # JRuby in 1.8 mode
10
- - jruby-19mode # JRuby in 1.9 mode
11
- - jruby-20mode # JRuby in 2.0 mode
12
- - rbx-18mode
13
- - rbx-19mode
14
- - rbx-20mode
7
+ - "2.1"
8
+ - "2.2"
9
+ - jruby-18mode
10
+ - jruby-19mode
11
+ - jruby-20mode
12
+ - jruby-head
13
+ - rbx
14
+ - rbx-2
15
+ notifications:
16
+ email:
17
+ - uwe@kubosch.no
data/Gemfile CHANGED
@@ -4,7 +4,7 @@ source 'http://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  group :test do
7
- if RUBY_VERSION =~ /^1\.9\./ || RUBY_VERSION =~ /^2\.0\./
8
- gem 'minitest-reporters'
7
+ if RUBY_VERSION =~ /^1\.9\./ || RUBY_VERSION =~ /^2\./
8
+ gem 'minitest-reporters', '<1.0.0'
9
9
  end
10
10
  end
@@ -11,23 +11,20 @@ Gem::Specification.new do |s|
11
11
  s.date = Date.today.to_s
12
12
  s.description = %q{Beautiful graphs for one or multiple datasets. Can be used on websites or in documents.}
13
13
  s.email = %q{boss@topfunky.com}
14
- # s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
15
14
  s.files = `git ls-files`.split($/).reject{|f| f =~ /^test#{File::ALT_SEPARATOR || File::SEPARATOR}output/}
16
- # s.has_rdoc = true
17
15
  s.homepage = %q{https://github.com/topfunky/gruff}
18
- # s.rdoc_options = ["--main", "README.txt"]
19
16
  s.require_paths = %w(lib)
20
- # s.rubyforge_project = %q{gruff}
21
17
  s.summary = %q{Beautiful graphs for one or multiple datasets.}
22
18
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
23
19
  s.executables = s.files.grep(%r{^bin/}).map { |f| File.basename(f) }
24
20
  s.specification_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
21
  if defined? JRUBY_VERSION
26
22
  s.platform = 'java'
27
- s.add_dependency 'rmagick4j'
23
+ s.add_dependency 'rmagick4j', '>= 0.3.9'
28
24
  else
29
- s.add_dependency 'rmagick'
25
+ s.add_dependency 'rmagick', '>= 2.13.4'
30
26
  end
31
27
  s.add_development_dependency('rake')
28
+ s.add_development_dependency('test-unit')
32
29
  s.license = 'MIT'
33
30
  end
@@ -1,5 +1,5 @@
1
1
  require 'rubygems'
2
- require 'RMagick'
2
+ require 'rmagick'
3
3
  require 'bigdecimal'
4
4
 
5
5
  require File.dirname(__FILE__) + '/deprecated'
@@ -117,6 +117,12 @@ module Gruff
117
117
  # a reader here.
118
118
  attr_reader :font
119
119
 
120
+ # Same as font but for the title.
121
+ attr_reader :title_font
122
+
123
+ # Specifies whether to draw the title bolded or not.
124
+ attr_accessor :bold_title
125
+
120
126
  attr_accessor :font_color
121
127
 
122
128
  # Prevent drawing of line markers
@@ -249,6 +255,7 @@ module Gruff
249
255
 
250
256
  vera_font_path = File.expand_path('Vera.ttf', ENV['MAGICK_FONT_PATH'])
251
257
  @font = File.exists?(vera_font_path) ? vera_font_path : nil
258
+ @bold_title = true
252
259
 
253
260
  @marker_font_size = 21.0
254
261
  @legend_font_size = 20.0
@@ -290,6 +297,11 @@ module Gruff
290
297
  @d.font = @font
291
298
  end
292
299
 
300
+ # Sets the title font to the font at +font_path+
301
+ def title_font=(font_path)
302
+ @title_font = font_path
303
+ end
304
+
293
305
  # Add a color to the list of available colors for lines.
294
306
  #
295
307
  # Example:
@@ -799,10 +811,10 @@ module Gruff
799
811
  return if (@hide_title || @title.nil?)
800
812
 
801
813
  @d.fill = @font_color
802
- @d.font = @font if @font
814
+ @d.font = @title_font || @font if @title_font || @font
803
815
  @d.stroke('transparent')
804
816
  @d.pointsize = scale_fontsize(@title_font_size)
805
- @d.font_weight = BoldWeight
817
+ @d.font_weight = if @bold_title then BoldWeight else NormalWeight end
806
818
  @d.gravity = NorthGravity
807
819
  @d = @d.annotate_scaled(@base_image,
808
820
  @raw_columns, 1.0,
@@ -1123,6 +1135,11 @@ module Gruff
1123
1135
  @d.get_type_metrics(@base_image, text.to_s).width
1124
1136
  end
1125
1137
 
1138
+ # Used for degree => radian conversions
1139
+ def deg2rad(angle)
1140
+ angle * (Math::PI/180.0)
1141
+ end
1142
+
1126
1143
  end # Gruff::Base
1127
1144
 
1128
1145
  class IncorrectNumberOfDatasetsException < StandardError;
@@ -18,8 +18,8 @@ class Gruff::Bezier < Gruff::Base
18
18
  new_y = @graph_top + (@graph_height - data_point * @graph_height)
19
19
 
20
20
  if index == 0 && RUBY_PLATFORM != 'java'
21
- poly_points << @graph_left
22
- poly_points << @graph_bottom - 1
21
+ poly_points << new_x
22
+ poly_points << new_y
23
23
  end
24
24
 
25
25
  poly_points << new_x
@@ -18,6 +18,9 @@ class Gruff::Line < Gruff::Base
18
18
  attr_accessor :reference_line_default_color
19
19
  attr_accessor :reference_line_default_width
20
20
 
21
+ # Allow for vertical marker lines
22
+ attr_accessor :show_vertical_markers
23
+
21
24
  # Dimensions of lines and dots; calculated based on dataset size if left unspecified
22
25
  attr_accessor :line_width
23
26
  attr_accessor :dot_radius
@@ -167,7 +170,7 @@ class Gruff::Line < Gruff::Base
167
170
 
168
171
  def draw_vertical_reference_line(reference_line)
169
172
  index = @graph_left + (@x_increment * reference_line[:index])
170
- draw_reference_line(reference_line, index, index, @graph_top, @graph_top + graph_height)
173
+ draw_reference_line(reference_line, index, index, @graph_top, @graph_top + @graph_height)
171
174
  end
172
175
 
173
176
  def draw
@@ -183,16 +186,34 @@ class Gruff::Line < Gruff::Base
183
186
  draw_vertical_reference_line(curr_reference_line) if curr_reference_line.key?(:index)
184
187
  end
185
188
 
189
+ if (@show_vertical_markers)
190
+ (0..@column_count).each do |column|
191
+ x = @graph_left + @graph_width - column.to_f * @x_increment
192
+
193
+ @d = @d.fill(@marker_color)
194
+
195
+ # FIXME(uwe): Workaround for Issue #66
196
+ # https://github.com/topfunky/gruff/issues/66
197
+ # https://github.com/rmagick/rmagick/issues/82
198
+ # Remove if the issue gets fixed.
199
+ x += 0.001 unless defined?(JRUBY_VERSION)
200
+ # EMXIF
201
+
202
+ @d = @d.line(x, @graph_bottom, x, @graph_top)
203
+ #If the user specified a marker shadow color, draw a shadow just below it
204
+ unless @marker_shadow_color.nil?
205
+ @d = @d.fill(@marker_shadow_color)
206
+ @d = @d.line(x + 1, @graph_bottom, x + 1, @graph_top)
207
+ end
208
+ end
209
+ end
210
+
186
211
  @norm_data.each do |data_row|
187
212
  prev_x = prev_y = nil
188
213
 
189
214
  @one_point = contains_one_point_only?(data_row)
190
215
 
191
216
  data_row[DATA_VALUES_INDEX].each_with_index do |data_point, index|
192
- unless data_point
193
- prev_x = prev_y = nil
194
- next
195
- end
196
217
  x_data = data_row[DATA_VALUES_X_INDEX]
197
218
  if x_data == nil
198
219
  #use the old method: equally spaced points along the x-axis
@@ -204,6 +225,10 @@ class Gruff::Line < Gruff::Base
204
225
  draw_label(@graph_left + ((label_pos - @minimum_x_value) * @graph_width) / (@maximum_x_value - @minimum_x_value), label_pos)
205
226
  end
206
227
  end
228
+ unless data_point # we can't draw a line for a null data point, we can still label the axis though
229
+ prev_x = prev_y = nil
230
+ next
231
+ end
207
232
 
208
233
  new_y = @graph_top + (@graph_height - data_point * @graph_height)
209
234
 
@@ -111,8 +111,8 @@ class Gruff::Net < Gruff::Base
111
111
  r_offset = 1.1
112
112
  x_offset = center_x # + 15 # The label points need to be tweaked slightly
113
113
  y_offset = center_y # + 0 # This one doesn't though
114
- x = x_offset + (radius * r_offset * Math.sin(angle.deg2rad))
115
- y = y_offset - (radius * r_offset * Math.cos(angle.deg2rad))
114
+ x = x_offset + (radius * r_offset * Math.sin(deg2rad(angle)))
115
+ y = y_offset - (radius * r_offset * Math.cos(deg2rad(angle)))
116
116
 
117
117
  # Draw label
118
118
  @d.fill = @marker_color
@@ -125,14 +125,3 @@ class Gruff::Net < Gruff::Base
125
125
  end
126
126
 
127
127
  end
128
-
129
- # # This method is already in Float
130
- # class Float
131
- # # Used for degree => radian conversions
132
- # def deg2rad
133
- # self * (Math::PI/180.0)
134
- # end
135
- # end
136
-
137
-
138
-
@@ -13,7 +13,7 @@ require File.dirname(__FILE__) + '/base'
13
13
 
14
14
  class Gruff::Pie < Gruff::Base
15
15
 
16
- TEXT_OFFSET_PERCENTAGE = 0.15
16
+ DEFAULT_TEXT_OFFSET_PERCENTAGE = 0.15
17
17
 
18
18
  # Can be used to make the pie start cutting slices at the top (-90.0)
19
19
  # or at another angle. Default is 0.0, which starts at 3 o'clock.
@@ -21,11 +21,18 @@ class Gruff::Pie < Gruff::Base
21
21
  # Do not show labels for slices that are less than this percent. Use 0 to always show all labels.
22
22
  # Defaults to 0
23
23
  attr_accessor :hide_labels_less_than
24
+ # Affect the distance between the percentages and the pie chart
25
+ # Defaults to 0.15
26
+ attr_accessor :text_offset_percentage
27
+ ## Use values instead of percentages
28
+ attr_accessor :show_values_as_labels
24
29
 
25
30
  def initialize_ivars
26
31
  super
27
32
  @zero_degree = 0.0
28
33
  @hide_labels_less_than = 0.0
34
+ @text_offset_percentage = DEFAULT_TEXT_OFFSET_PERCENTAGE
35
+ @show_values_as_labels = false
29
36
  end
30
37
 
31
38
  def draw
@@ -64,9 +71,9 @@ class Gruff::Pie < Gruff::Base
64
71
  label_val = ((data_row[DATA_VALUES_INDEX].first / total_sum) * 100.0).round
65
72
  unless label_val < @hide_labels_less_than
66
73
  # RMagick must use sprintf with the string and % has special significance.
67
- label_string = label_val.to_s + '%'
74
+ label_string = @show_values_as_labels ? data_row[DATA_VALUES_INDEX].first.to_s : label_val.to_s + '%'
68
75
  @d = draw_label(center_x,center_y, half_angle,
69
- radius + (radius * TEXT_OFFSET_PERCENTAGE),
76
+ radius + (radius * @text_offset_percentage),
70
77
  label_string)
71
78
  end
72
79
 
@@ -87,12 +94,12 @@ private
87
94
  def draw_label(center_x, center_y, angle, radius, amount)
88
95
  # TODO Don't use so many hard-coded numbers
89
96
  r_offset = 20.0 # The distance out from the center of the pie to get point
90
- x_offset = center_x # + 15.0 # The label points need to be tweaked slightly
97
+ x_offset = center_x # + 15.0 # The label points need to be tweaked slightly
91
98
  y_offset = center_y # This one doesn't though
92
99
  radius_offset = (radius + r_offset)
93
- ellipse_factor = radius_offset * TEXT_OFFSET_PERCENTAGE
94
- x = x_offset + ((radius_offset + ellipse_factor) * Math.cos(angle.deg2rad))
95
- y = y_offset + (radius_offset * Math.sin(angle.deg2rad))
100
+ ellipse_factor = radius_offset * @text_offset_percentage
101
+ x = x_offset + ((radius_offset + ellipse_factor) * Math.cos(deg2rad(angle)))
102
+ y = y_offset + (radius_offset * Math.sin(deg2rad(angle)))
96
103
 
97
104
  # Draw label
98
105
  @d.fill = @font_color
@@ -114,11 +121,3 @@ private
114
121
  end
115
122
 
116
123
  end
117
-
118
- class Float
119
- # Used for degree => radian conversions
120
- def deg2rad
121
- self * (Math::PI/180.0)
122
- end
123
- end
124
-
@@ -7,6 +7,9 @@ class Gruff::StackedBar < Gruff::Base
7
7
 
8
8
  # Spacing factor applied between bars
9
9
  attr_accessor :bar_spacing
10
+
11
+ # Number of pixels between bar segments
12
+ attr_accessor :segment_spacing
10
13
 
11
14
  # Draws a bar graph, but multiple sets are stacked on top of each other.
12
15
  def draw
@@ -18,6 +21,7 @@ class Gruff::StackedBar < Gruff::Base
18
21
  #
19
22
  # Columns sit stacked.
20
23
  @bar_spacing ||= 0.9
24
+ @segment_spacing ||= 1
21
25
  @bar_width = @graph_width / @column_count.to_f
22
26
  padding = (@bar_width * (1 - @bar_spacing)) / 2
23
27
 
@@ -38,9 +42,9 @@ class Gruff::StackedBar < Gruff::Base
38
42
  left_x = @graph_left + (@bar_width * point_index) + padding
39
43
  left_y = @graph_top + (@graph_height -
40
44
  data_point * @graph_height -
41
- height[point_index]) + 1
45
+ height[point_index]) + @segment_spacing
42
46
  right_x = left_x + @bar_width * @bar_spacing
43
- right_y = @graph_top + @graph_height - height[point_index] - 1
47
+ right_y = @graph_top + @graph_height - height[point_index] - @segment_spacing
44
48
 
45
49
  # update the total height of the current stacked bar
46
50
  height[point_index] += (data_point * @graph_height )
@@ -1,3 +1,3 @@
1
1
  module Gruff
2
- VERSION = '0.5.1'
2
+ VERSION = '0.6.0'
3
3
  end
@@ -0,0 +1,27 @@
1
+ require File.dirname(__FILE__) + "/gruff_test_case"
2
+
3
+ class TestLabelsForNullData < GruffTestCase
4
+
5
+ def setup
6
+ @dataset = [nil, 1, 2, 1, nil]
7
+
8
+ @labels = {
9
+ 0 => '1',
10
+ 1 => '2',
11
+ 2 => '3',
12
+ 3 => '4',
13
+ 4 => '5'
14
+ }
15
+ end
16
+
17
+ def test_labels
18
+ g = Gruff::Line.new
19
+ g.title = 'Labels For Null Data'
20
+ g.labels = @labels
21
+ g.data('data', @dataset)
22
+ g.minimum_value = 0
23
+
24
+ g.write("test/output/TestLabelsForNullData.png")
25
+ end
26
+
27
+ end
@@ -139,7 +139,14 @@ class TestGruffPie < GruffTestCase
139
139
 
140
140
  write_test_file g, "pie_simple.png"
141
141
  end
142
-
142
+
143
+ def test_pie_with_adjusted_text_offset_percentage
144
+ g = setup_basic_graph
145
+ g.title = "Adjusted Text Offset Percentage"
146
+ g.text_offset_percentage = 0.03
147
+ g.write "test/output/pie_adjusted_text_offset_percentage.png"
148
+ end
149
+
143
150
  protected
144
151
 
145
152
  def setup_basic_graph(size=800)
@@ -25,7 +25,7 @@ class TestGruffScatter < Test::Unit::TestCase
25
25
  g.title = 'Many Datapoint Graph Test'
26
26
  y_values = (0..50).map { rand(100) }
27
27
  x_values = (0..50).map { rand(100) }
28
- g.data('many points', y_values, x_values)
28
+ g.data('many points', x_values, y_values)
29
29
 
30
30
  # Default theme
31
31
  g.write('test/output/scatter_many.png')
@@ -48,5 +48,21 @@ class TestGruffStackedBar < GruffTestCase
48
48
  end
49
49
  g.write "test/output/stacked_bar_keynote_small.png"
50
50
  end
51
+
52
+ def test_bar_graph_segment_spacing
53
+ g = Gruff::StackedBar.new
54
+ g.title = "Visual Stacked Bar Graph Test"
55
+ g.segment_spacing = 0
56
+ g.labels = {
57
+ 0 => '5/6',
58
+ 1 => '5/15',
59
+ 2 => '5/24',
60
+ 3 => '5/30',
61
+ }
62
+ @datasets.each do |data|
63
+ g.data(data[0], data[1])
64
+ end
65
+ g.write "test/output/stacked_bar_keynote_no_space.png"
66
+ end
51
67
 
52
68
  end
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.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geoffrey Grosenbach
@@ -9,34 +9,48 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-22 00:00:00.000000000 Z
12
+ date: 2015-05-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rmagick
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - '>='
18
+ - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: '0'
20
+ version: 2.13.4
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - '>='
25
+ - - ">="
26
26
  - !ruby/object:Gem::Version
27
- version: '0'
27
+ version: 2.13.4
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rake
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - '>='
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: test-unit
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
33
47
  - !ruby/object:Gem::Version
34
48
  version: '0'
35
49
  type: :development
36
50
  prerelease: false
37
51
  version_requirements: !ruby/object:Gem::Requirement
38
52
  requirements:
39
- - - '>='
53
+ - - ">="
40
54
  - !ruby/object:Gem::Version
41
55
  version: '0'
42
56
  description: Beautiful graphs for one or multiple datasets. Can be used on websites
@@ -46,8 +60,8 @@ executables: []
46
60
  extensions: []
47
61
  extra_rdoc_files: []
48
62
  files:
49
- - .gitignore
50
- - .travis.yml
63
+ - ".gitignore"
64
+ - ".travis.yml"
51
65
  - Gemfile
52
66
  - History.txt
53
67
  - MIT-LICENSE
@@ -124,6 +138,7 @@ files:
124
138
  - test/test_bezier.rb
125
139
  - test/test_bullet.rb
126
140
  - test/test_dot.rb
141
+ - test/test_labels_for_null_data.rb
127
142
  - test/test_legend.rb
128
143
  - test/test_line.rb
129
144
  - test/test_mini_bar.rb
@@ -149,17 +164,17 @@ require_paths:
149
164
  - lib
150
165
  required_ruby_version: !ruby/object:Gem::Requirement
151
166
  requirements:
152
- - - '>='
167
+ - - ">="
153
168
  - !ruby/object:Gem::Version
154
169
  version: '0'
155
170
  required_rubygems_version: !ruby/object:Gem::Requirement
156
171
  requirements:
157
- - - '>='
172
+ - - ">="
158
173
  - !ruby/object:Gem::Version
159
174
  version: '0'
160
175
  requirements: []
161
176
  rubyforge_project:
162
- rubygems_version: 2.0.6
177
+ rubygems_version: 2.4.6
163
178
  signing_key:
164
179
  specification_version: 4
165
180
  summary: Beautiful graphs for one or multiple datasets.
@@ -173,6 +188,7 @@ test_files:
173
188
  - test/test_bezier.rb
174
189
  - test/test_bullet.rb
175
190
  - test/test_dot.rb
191
+ - test/test_labels_for_null_data.rb
176
192
  - test/test_legend.rb
177
193
  - test/test_line.rb
178
194
  - test/test_mini_bar.rb