gruff 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
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