gruff 0.2.4 → 0.2.5

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.
data/Manifest.txt CHANGED
@@ -19,6 +19,11 @@ lib/gruff/side_stacked_bar.rb
19
19
  lib/gruff/spider.rb
20
20
  lib/gruff/stacked_bar.rb
21
21
 
22
+ lib/gruff/mini/bar.rb
23
+ lib/gruff/mini/pie.rb
24
+ lib/gruff/mini/side_bar.rb
25
+ lib/gruff/mini/legend.rb
26
+
22
27
  test/test_area.rb
23
28
  test/test_bar.rb
24
29
  test/test_base.rb
@@ -33,3 +38,7 @@ test/test_scene.rb
33
38
  test/test_sidestacked_bar.rb
34
39
  test/test_spider.rb
35
40
  test/test_stacked_bar.rb
41
+
42
+ test/test_mini_bar.rb
43
+ test/test_mini_pie.rb
44
+ test/test_mini_side_bar.rb
data/lib/gruff.rb CHANGED
@@ -1,15 +1,23 @@
1
- # Extra full path added to fix some require errors on some installations.
1
+ # Extra full path added to fix loading errors on some installations.
2
2
 
3
- require File.dirname(__FILE__) + '/gruff/base'
3
+ %w(
4
+ base
5
+ area
6
+ bar
7
+ line
8
+ pie
9
+ spider
10
+ net
11
+ stacked_bar
12
+ side_stacked_bar
13
+ side_bar
4
14
 
5
- require File.dirname(__FILE__) + '/gruff/area'
6
- require File.dirname(__FILE__) + '/gruff/bar'
7
- require File.dirname(__FILE__) + '/gruff/line'
8
- require File.dirname(__FILE__) + '/gruff/pie'
9
- require File.dirname(__FILE__) + '/gruff/spider'
10
- require File.dirname(__FILE__) + '/gruff/net'
11
- require File.dirname(__FILE__) + '/gruff/stacked_bar'
12
- require File.dirname(__FILE__) + '/gruff/side_stacked_bar'
13
- # require File.dirname(__FILE__) + '/gruff/photo_bar'
15
+ scene
14
16
 
15
- require File.dirname(__FILE__) + '/gruff/scene'
17
+ mini/legend
18
+ mini/bar
19
+ mini/pie
20
+ mini/side_bar
21
+ ).each do |filename|
22
+ require File.dirname(__FILE__) + "/gruff/#{filename}"
23
+ end
data/lib/gruff/bar.rb CHANGED
@@ -13,10 +13,16 @@ class Gruff::Bar < Gruff::Base
13
13
  super
14
14
  return unless @has_data
15
15
 
16
+ draw_bars
17
+ end
18
+
19
+ protected
20
+
21
+ def draw_bars
16
22
  # Setup spacing.
17
23
  #
18
24
  # Columns sit side-by-side.
19
- spacing_factor = 0.9
25
+ spacing_factor = 0.9 # space between the bars
20
26
  @bar_width = @graph_width / (@column_count * @data.length).to_f
21
27
 
22
28
  @d = @d.stroke_opacity 0.0
@@ -72,7 +78,7 @@ class Gruff::Bar < Gruff::Base
72
78
  # Draw the last label if requested
73
79
  draw_label(@graph_right, @column_count) if @center_labels_over_point
74
80
 
75
- @d.draw(@base_image)
81
+ @d.draw(@base_image)
76
82
  end
77
83
 
78
84
  end
@@ -1,22 +1,13 @@
1
- ##############################################################################
1
+ ##
2
+ # Original Author: David Stokar
2
3
  #
3
- # Ruby Gruff/bar_conversion
4
+ # This class perfoms the y coordinats conversion for the bar class.
4
5
  #
5
- # Copyright: David Stokar
6
+ # There are three cases:
6
7
  #
7
- # Date Written: 2006/01/27
8
- #
9
- # $Revision: 0.2 $
10
- #
11
- # $Log: bar_conversion.rb $
12
- # $Log: Added comments $
13
- ##############################################################################
14
-
15
- #
16
- # This class perfoms the y coordinats conversion for the bar class
17
- # There are 3 cases: 1. Bars all go from zero in positiv direction
18
- # 2. Bars all go from zero to negativ direction
19
- # 3. Bars either go from zero to positiv or from zero to negativ
8
+ # 1. Bars all go from zero in positive direction
9
+ # 2. Bars all go from zero to negative direction
10
+ # 3. Bars either go from zero to positive or from zero to negative
20
11
  #
21
12
  class Gruff::BarConversion
22
13
  attr_writer :mode
data/lib/gruff/base.rb CHANGED
@@ -20,7 +20,7 @@ require File.dirname(__FILE__) + '/deprecated'
20
20
 
21
21
  module Gruff
22
22
 
23
- VERSION = '0.2.4'
23
+ VERSION = '0.2.5'
24
24
 
25
25
  class Base
26
26
 
@@ -53,6 +53,9 @@ module Gruff
53
53
  # By default, labels are centered over the point they represent.
54
54
  attr_accessor :center_labels_over_point
55
55
 
56
+ # Used internally for horizontal graph types.
57
+ attr_accessor :has_left_labels
58
+
56
59
  # A label for the bottom of the graph
57
60
  attr_accessor :x_axis_label
58
61
 
@@ -77,6 +80,8 @@ module Gruff
77
80
  # ENV['MAGICK_FONT_PATH']. Uses default RMagick font otherwise.
78
81
  attr_reader :font
79
82
 
83
+ attr_accessor :font_color
84
+
80
85
  # Hide various elements
81
86
  attr_accessor :hide_line_markers, :hide_legend, :hide_title, :hide_line_numbers
82
87
 
@@ -91,7 +96,7 @@ module Gruff
91
96
  # The font size of the labels around the graph
92
97
  attr_accessor :marker_font_size
93
98
 
94
- # The color of the auxiliary labels and lines
99
+ # The color of the auxiliary lines
95
100
  attr_accessor :marker_color
96
101
 
97
102
  # The number of horizontal lines shown for reference
@@ -162,9 +167,11 @@ module Gruff
162
167
 
163
168
  @hide_line_markers = @hide_legend = @hide_title = @hide_line_numbers = false
164
169
  @center_labels_over_point = true
170
+ @has_left_labels = false
165
171
 
166
172
  @additional_line_values = []
167
173
  @additional_line_colors = []
174
+ @theme_options = {}
168
175
 
169
176
  @x_axis_label = @y_axis_label = nil
170
177
  @y_axis_increment = nil
@@ -175,42 +182,6 @@ module Gruff
175
182
  theme_keynote()
176
183
  end
177
184
 
178
-
179
-
180
- # You can set a theme manually. Assign a hash to this method before you send your data.
181
- #
182
- # graph.theme = {
183
- # :colors => %w(orange purple green white red),
184
- # :marker_color => 'blue',
185
- # :background_colors => %w(black grey)
186
- # }
187
- #
188
- # :background_image => 'squirrel.png' is also possible.
189
- #
190
- # (Or hopefully something better looking than that.)
191
- #
192
- def theme=(options)
193
- defaults = {
194
- :colors => ['black', 'white'],
195
- :additional_line_colors => ['grey'],
196
- :marker_color => 'white',
197
- :background_colors => nil,
198
- :background_image => nil
199
- }
200
- options = defaults.merge options
201
-
202
- reset_themes()
203
-
204
- @colors = options[:colors]
205
- @marker_color = options[:marker_color]
206
- @additional_line_colors = options[:additional_line_colors]
207
- if not options[:background_colors].nil?
208
- @base_image = render_gradiated_background(*options[:background_colors])
209
- else
210
- @base_image = render_image_background(*options[:background_image])
211
- end
212
- end
213
-
214
185
  def font=(font_path)
215
186
  @font = font_path
216
187
  @d.font = @font
@@ -234,18 +205,42 @@ module Gruff
234
205
  @colors = color_list
235
206
  end
236
207
 
208
+
209
+ # You can set a theme manually. Assign a hash to this method before you send your data.
210
+ #
211
+ # graph.theme = {
212
+ # :colors => %w(orange purple green white red),
213
+ # :marker_color => 'blue',
214
+ # :background_colors => %w(black grey)
215
+ # }
216
+ #
217
+ # :background_image => 'squirrel.png' is also possible.
218
+ #
219
+ # (Or hopefully something better looking than that.)
220
+ #
221
+ def theme=(options)
222
+ reset_themes()
223
+
224
+ defaults = {
225
+ :colors => ['black', 'white'],
226
+ :additional_line_colors => [],
227
+ :marker_color => 'white',
228
+ :font_color => 'black',
229
+ :background_colors => nil,
230
+ :background_image => nil
231
+ }
232
+ @theme_options = defaults.merge options
233
+
234
+ @colors = @theme_options[:colors]
235
+ @marker_color = @theme_options[:marker_color]
236
+ @font_color = @theme_options[:font_color] || @marker_color
237
+ @additional_line_colors = @theme_options[:additional_line_colors]
238
+
239
+ render_background
240
+ end
237
241
 
238
242
  # A color scheme similar to the popular presentation software.
239
243
  def theme_keynote
240
- # defaults = {
241
- # :colors => ['black', 'white'],
242
- # :additional_line_colors => ['grey'],
243
- # :marker_color => 'white',
244
- # :background_colors => nil,
245
- # :background_image => nil
246
- # }
247
-
248
- reset_themes()
249
244
  # Colors
250
245
  @blue = '#6886B4'
251
246
  @yellow = '#FDD84E'
@@ -256,14 +251,16 @@ module Gruff
256
251
  @white = 'white'
257
252
  @colors = [@yellow, @blue, @green, @red, @purple, @orange, @white]
258
253
 
259
- @marker_color = 'white'
260
-
261
- @base_image = render_gradiated_background('black', '#4a465a')
254
+ self.theme = {
255
+ :colors => @colors,
256
+ :marker_color => 'white',
257
+ :font_color => 'white',
258
+ :background_colors => ['black', '#4a465a']
259
+ }
262
260
  end
263
261
 
264
262
  # A color scheme plucked from the colors on the popular usability blog.
265
263
  def theme_37signals
266
- reset_themes()
267
264
  # Colors
268
265
  @green = '#339933'
269
266
  @purple = '#cc99cc'
@@ -274,14 +271,16 @@ module Gruff
274
271
  @black = 'black'
275
272
  @colors = [@yellow, @blue, @green, @red, @purple, @orange, @black]
276
273
 
277
- @marker_color = 'black'
278
-
279
- @base_image = render_gradiated_background('#d1edf5', 'white')
274
+ self.theme = {
275
+ :colors => @colors,
276
+ :marker_color => 'black',
277
+ :font_color => 'black',
278
+ :background_colors => ['#d1edf5', 'white']
279
+ }
280
280
  end
281
281
 
282
282
  # A color scheme from the colors used on the 2005 Rails keynote presentation at RubyConf.
283
283
  def theme_rails_keynote
284
- reset_themes()
285
284
  # Colors
286
285
  @green = '#00ff00'
287
286
  @grey = '#333333'
@@ -291,15 +290,17 @@ module Gruff
291
290
  @light_grey = '#999999'
292
291
  @black = 'black'
293
292
  @colors = [@green, @grey, @orange, @red, @white, @light_grey, @black]
294
-
295
- @marker_color = 'white'
296
293
 
297
- @base_image = render_gradiated_background('#0083a3', '#0083a3')
294
+ self.theme = {
295
+ :colors => @colors,
296
+ :marker_color => 'white',
297
+ :font_color => 'white',
298
+ :background_colors => ['#0083a3', '#0083a3']
299
+ }
298
300
  end
299
301
 
300
302
  # A color scheme similar to that used on the popular podcast site.
301
303
  def theme_odeo
302
- reset_themes()
303
304
  # Colors
304
305
  @grey = '#202020'
305
306
  @white = 'white'
@@ -309,10 +310,13 @@ module Gruff
309
310
  @dark_blue = '#3a5b87'
310
311
  @black = 'black'
311
312
  @colors = [@grey, @white, @dark_blue, @dark_pink, @green, @light_grey, @black]
312
-
313
- @marker_color = 'white'
314
313
 
315
- @base_image = render_gradiated_background('#ff47a4', '#ff1f81')
314
+ self.theme = {
315
+ :colors => @colors,
316
+ :marker_color => 'white',
317
+ :font_color => 'white',
318
+ :background_colors => ['#ff47a4', '#ff1f81']
319
+ }
316
320
  end
317
321
 
318
322
  # Parameters are an array where the first element is the name of the dataset
@@ -378,13 +382,13 @@ protected
378
382
  make_stacked if @stacked
379
383
  setup_drawing()
380
384
 
381
- debug do
385
+ debug {
382
386
  # Outer margin
383
387
  @d.rectangle( LEFT_MARGIN, TOP_MARGIN,
384
388
  @raw_columns - RIGHT_MARGIN, @raw_rows - BOTTOM_MARGIN)
385
389
  # Graph area box
386
390
  @d.rectangle( @graph_left, @graph_top, @graph_right, @graph_bottom)
387
- end
391
+ }
388
392
  end
389
393
 
390
394
  # Draws the decorations.
@@ -489,9 +493,9 @@ protected
489
493
  x_axis_label_y_coordinate = @graph_bottom + LABEL_MARGIN * 2 + @marker_caps_height
490
494
 
491
495
  # TODO Center between graph area
492
- @d.fill = @marker_color
496
+ @d.fill = @font_color
493
497
  @d.font = @font if @font
494
- @d.stroke = 'transparent'
498
+ @d.stroke('transparent')
495
499
  @d.pointsize = scale_fontsize(@marker_font_size)
496
500
  @d.gravity = NorthGravity
497
501
  @d = @d.annotate_scaled( @base_image,
@@ -516,11 +520,9 @@ protected
516
520
  # Draws horizontal background lines and labels
517
521
  def draw_line_markers
518
522
  return if @hide_line_markers
523
+
524
+ @d = @d.stroke_antialias false
519
525
 
520
- # Draw horizontal line markers and annotate with numbers
521
- @d = @d.stroke(@marker_color)
522
- @d = @d.stroke_width 1
523
-
524
526
  if @y_axis_increment.nil?
525
527
  # Try to use a number of horizontal lines that will come out even.
526
528
  #
@@ -547,16 +549,20 @@ protected
547
549
  end
548
550
  @increment_scaled = @graph_height.to_f / (@spread / @increment)
549
551
 
552
+ # Draw horizontal line markers and annotate with numbers
550
553
  (0..@marker_count).each do |index|
551
554
  y = @graph_top + @graph_height - index.to_f * @increment_scaled
555
+
556
+ @d = @d.stroke(@marker_color)
557
+ @d = @d.stroke_width 1
552
558
  @d = @d.line(@graph_left, y, @graph_right, y)
553
559
 
554
560
  marker_label = index * @increment + @minimum_value.to_f
555
561
 
556
562
  unless @hide_line_numbers
557
- @d.fill = @marker_color
563
+ @d.fill = @font_color
558
564
  @d.font = @font if @font
559
- @d.stroke = 'transparent'
565
+ @d.stroke('transparent')
560
566
  @d.pointsize = scale_fontsize(@marker_font_size)
561
567
  @d.gravity = EastGravity
562
568
 
@@ -568,28 +574,30 @@ protected
568
574
  end
569
575
  end
570
576
 
571
- # Submitted by a contibutor...the utility escapes me
572
- i = 0
573
- @additional_line_values.each do |value|
574
- @increment_scaled = @graph_height.to_f / (@maximum_value.to_f / value)
575
-
576
- y = @graph_top + @graph_height - @increment_scaled
577
-
578
- @d = @d.stroke(@additional_line_colors[i])
579
- @d = @d.line(@graph_left, y, @graph_right, y)
580
-
581
-
582
- @d.fill = @additional_line_colors[i]
583
- @d.font = @font if @font
584
- @d.stroke = 'transparent'
585
- @d.pointsize = scale_fontsize(@marker_font_size)
586
- @d.gravity = EastGravity
587
- @d = @d.annotate_scaled( @base_image,
588
- 100, 20,
589
- -10, y - (@marker_font_size/2.0),
590
- "", @scale)
591
- i += 1
592
- end
577
+ # # Submitted by a contibutor...the utility escapes me
578
+ # i = 0
579
+ # @additional_line_values.each do |value|
580
+ # @increment_scaled = @graph_height.to_f / (@maximum_value.to_f / value)
581
+ #
582
+ # y = @graph_top + @graph_height - @increment_scaled
583
+ #
584
+ # @d = @d.stroke(@additional_line_colors[i])
585
+ # @d = @d.line(@graph_left, y, @graph_right, y)
586
+ #
587
+ #
588
+ # @d.fill = @additional_line_colors[i]
589
+ # @d.font = @font if @font
590
+ # @d.stroke('transparent')
591
+ # @d.pointsize = scale_fontsize(@marker_font_size)
592
+ # @d.gravity = EastGravity
593
+ # @d = @d.annotate_scaled( @base_image,
594
+ # 100, 20,
595
+ # -10, y - (@marker_font_size/2.0),
596
+ # "", @scale)
597
+ # i += 1
598
+ # end
599
+
600
+ @d = @d.stroke_antialias true
593
601
  end
594
602
 
595
603
  # Draws a legend with the names of the datasets
@@ -625,10 +633,10 @@ protected
625
633
  @legend_labels.each_with_index do |legend_label, index|
626
634
 
627
635
  # Draw label
628
- @d.fill = @marker_color
636
+ @d.fill = @font_color
629
637
  @d.font = @font if @font
630
638
  @d.pointsize = scale_fontsize(@legend_font_size)
631
- @d.stroke = 'transparent'
639
+ @d.stroke('transparent')
632
640
  @d.font_weight = NormalWeight
633
641
  @d.gravity = WestGravity
634
642
  @d = @d.annotate_scaled( @base_image,
@@ -637,7 +645,7 @@ protected
637
645
  legend_label.to_s, @scale)
638
646
 
639
647
  # Now draw box with color of this dataset
640
- @d = @d.stroke 'transparent'
648
+ @d = @d.stroke('transparent')
641
649
  @d = @d.fill @data[index][DATA_COLOR_INDEX]
642
650
  @d = @d.rectangle(current_x_offset,
643
651
  current_y_offset - legend_square_width / 2.0,
@@ -655,9 +663,9 @@ protected
655
663
  def draw_title
656
664
  return if (@hide_title || @title.nil?)
657
665
 
658
- @d.fill = @marker_color
666
+ @d.fill = @font_color
659
667
  @d.font = @font if @font
660
- @d.stroke = 'transparent'
668
+ @d.stroke('transparent')
661
669
  @d.pointsize = scale_fontsize(@title_font_size)
662
670
  @d.font_weight = BoldWeight
663
671
  @d.gravity = NorthGravity
@@ -678,9 +686,9 @@ protected
678
686
  if !@labels[index].nil? && @labels_seen[index].nil?
679
687
  y_offset = @graph_bottom + LABEL_MARGIN
680
688
 
681
- @d.fill = @marker_color
689
+ @d.fill = @font_color
682
690
  @d.font = @font if @font
683
- @d.stroke = 'transparent'
691
+ @d.stroke('transparent')
684
692
  @d.font_weight = NormalWeight
685
693
  @d.pointsize = scale_fontsize(@marker_font_size)
686
694
  @d.gravity = NorthGravity
@@ -694,9 +702,9 @@ protected
694
702
  end
695
703
 
696
704
  def draw_no_data
697
- @d.fill = @marker_color
705
+ @d.fill = @font_color
698
706
  @d.font = @font if @font
699
- @d.stroke = 'transparent'
707
+ @d.stroke('transparent')
700
708
  @d.font_weight = NormalWeight
701
709
  @d.pointsize = scale_fontsize(80)
702
710
  @d.gravity = CenterGravity
@@ -706,6 +714,19 @@ protected
706
714
  @no_data_message, @scale)
707
715
  end
708
716
 
717
+ ##
718
+ # Finds the best background to render based on the provided theme options.
719
+ #
720
+ # Creates a @base_image to draw on.
721
+ #
722
+ def render_background
723
+ if not @theme_options[:background_colors].nil?
724
+ @base_image = render_gradiated_background(*@theme_options[:background_colors])
725
+ else
726
+ @base_image = render_image_background(*@theme_options[:background_image])
727
+ end
728
+ end
729
+
709
730
  # Use with a theme definition method to draw a gradiated (or solid color) background.
710
731
  def render_gradiated_background(top_color, bottom_color)
711
732
  Image.new(@columns, @rows,
@@ -730,7 +751,8 @@ protected
730
751
 
731
752
  def reset_themes
732
753
  @color_index = 0
733
- @labels_seen = Hash.new
754
+ @labels_seen = {}
755
+ @theme_options = {}
734
756
 
735
757
  @d = Draw.new
736
758
  # Scale down from 800x600 used to calculate drawing.
@@ -883,7 +905,7 @@ private
883
905
  #
884
906
  # Not scaled since it deals with dimensions that the regular
885
907
  # scaling will handle.
886
-
908
+ #
887
909
  def calculate_caps_height(font_size)
888
910
  @d.pointsize = font_size
889
911
  @d.get_type_metrics(@base_image, 'X').height
@@ -894,7 +916,7 @@ private
894
916
  #
895
917
  # Not scaled since it deals with dimensions that the regular
896
918
  # scaling will handle.
897
-
919
+ #
898
920
  def calculate_width(font_size, text)
899
921
  @d.pointsize = font_size
900
922
  @d.get_type_metrics(@base_image, text.to_s).width