topfunky-gruff 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -37,6 +37,7 @@ lib/gruff/area.rb
37
37
  lib/gruff/bar.rb
38
38
  lib/gruff/bar_conversion.rb
39
39
  lib/gruff/base.rb
40
+ lib/gruff/bullet.rb
40
41
  lib/gruff/deprecated.rb
41
42
  lib/gruff/line.rb
42
43
  lib/gruff/mini/bar.rb
@@ -61,6 +62,7 @@ test/test_accumulator_bar.rb
61
62
  test/test_area.rb
62
63
  test/test_bar.rb
63
64
  test/test_base.rb
65
+ test/test_bullet.rb
64
66
  test/test_legend.rb
65
67
  test/test_line.rb
66
68
  test/test_mini_bar.rb
@@ -73,4 +75,5 @@ test/test_scene.rb
73
75
  test/test_side_bar.rb
74
76
  test/test_sidestacked_bar.rb
75
77
  test/test_spider.rb
78
+ test/test_stacked_area.rb
76
79
  test/test_stacked_bar.rb
@@ -16,7 +16,7 @@ class Gruff::Area < Gruff::Base
16
16
  prev_x = prev_y = 0.0
17
17
  @d = @d.fill data_row[DATA_COLOR_INDEX]
18
18
 
19
- data_row[1].each_with_index do |data_point, index|
19
+ data_row[DATA_VALUES_INDEX].each_with_index do |data_point, index|
20
20
  # Use incremented x and scaled y
21
21
  new_x = @graph_left + (@x_increment * index)
22
22
  new_y = @graph_top + (@graph_height - data_point * @graph_height)
@@ -51,7 +51,7 @@ protected
51
51
  # iterate over all normalised data
52
52
  @norm_data.each_with_index do |data_row, row_index|
53
53
 
54
- data_row[1].each_with_index do |data_point, point_index|
54
+ data_row[DATA_VALUES_INDEX].each_with_index do |data_point, point_index|
55
55
  # Use incremented x and scaled y
56
56
  # x
57
57
  left_x = @graph_left + (@bar_width * (row_index + point_index + ((@data.length - 1) * point_index)))
@@ -3,6 +3,7 @@ require 'RMagick'
3
3
 
4
4
  require File.dirname(__FILE__) + '/deprecated'
5
5
 
6
+ ##
6
7
  # = Gruff. Graphs.
7
8
  #
8
9
  # Author:: Geoffrey Grosenbach boss@topfunky.com
@@ -15,10 +16,11 @@ require File.dirname(__FILE__) + '/deprecated'
15
16
  # Breijs, Richard Cowin, and a cast of thousands.
16
17
  #
17
18
  # See Gruff::Base#theme= for setting themes.
19
+
18
20
  module Gruff
19
21
 
20
22
  # This is the version of Gruff you are using.
21
- VERSION = '0.3.2'
23
+ VERSION = '0.3.3'
22
24
 
23
25
  class Base
24
26
 
@@ -26,7 +28,7 @@ module Gruff
26
28
  include Deprecated
27
29
 
28
30
  # Draw extra lines showing where the margins and text centers are
29
- DEBUG = false
31
+ DEBUG = true
30
32
 
31
33
  # Used for navigating the array of data to plot
32
34
  DATA_LABEL_INDEX = 0
@@ -176,7 +178,7 @@ module Gruff
176
178
  @rows = geometric_height.to_f
177
179
  else
178
180
  @columns = target_width.to_f
179
- @rows = target_width.to_f * 0.75
181
+ @rows = target_width.to_f * 0.75
180
182
  end
181
183
 
182
184
  initialize_ivars
@@ -213,7 +215,7 @@ module Gruff
213
215
  @marker_font_size = 21.0
214
216
  @legend_font_size = 20.0
215
217
  @title_font_size = 36.0
216
-
218
+
217
219
  @legend_box_size = 20.0
218
220
 
219
221
  @no_data_message = "No Data"
@@ -222,10 +224,10 @@ module Gruff
222
224
  @center_labels_over_point = true
223
225
  @has_left_labels = false
224
226
 
225
- @additional_line_values = []
227
+ @additional_line_values = []
226
228
  @additional_line_colors = []
227
229
  @theme_options = {}
228
-
230
+
229
231
  @x_axis_label = @y_axis_label = nil
230
232
  @y_axis_increment = nil
231
233
  @stacked = nil
@@ -276,7 +278,7 @@ module Gruff
276
278
  #
277
279
  def theme=(options)
278
280
  reset_themes()
279
-
281
+
280
282
  defaults = {
281
283
  :colors => ['black', 'white'],
282
284
  :additional_line_colors => [],
@@ -291,7 +293,7 @@ module Gruff
291
293
  @marker_color = @theme_options[:marker_color]
292
294
  @font_color = @theme_options[:font_color] || @marker_color
293
295
  @additional_line_colors = @theme_options[:additional_line_colors]
294
-
296
+
295
297
  render_background
296
298
  end
297
299
 
@@ -347,7 +349,7 @@ module Gruff
347
349
  @light_grey = '#999999'
348
350
  @black = 'black'
349
351
  @colors = [@green, @grey, @orange, @red, @white, @light_grey, @black]
350
-
352
+
351
353
  self.theme = {
352
354
  :colors => @colors,
353
355
  :marker_color => 'white',
@@ -367,7 +369,7 @@ module Gruff
367
369
  @dark_blue = '#3a5b87'
368
370
  @black = 'black'
369
371
  @colors = [@grey, @white, @dark_blue, @dark_pink, @green, @light_grey, @black]
370
-
372
+
371
373
  self.theme = {
372
374
  :colors => @colors,
373
375
  :marker_color => 'white',
@@ -380,15 +382,15 @@ module Gruff
380
382
  def theme_pastel
381
383
  # Colors
382
384
  @colors = [
383
- '#a9dada', # blue
384
- '#aedaa9', # green
385
- '#daaea9', # peach
386
- '#dadaa9', # yellow
387
- '#a9a9da', # dk purple
388
- '#daaeda', # purple
389
- '#dadada' # grey
390
- ]
391
-
385
+ '#a9dada', # blue
386
+ '#aedaa9', # green
387
+ '#daaea9', # peach
388
+ '#dadaa9', # yellow
389
+ '#a9a9da', # dk purple
390
+ '#daaeda', # purple
391
+ '#dadada' # grey
392
+ ]
393
+
392
394
  self.theme = {
393
395
  :colors => @colors,
394
396
  :marker_color => '#aea9a9', # Grey
@@ -401,14 +403,14 @@ module Gruff
401
403
  def theme_greyscale
402
404
  # Colors
403
405
  @colors = [
404
- '#282828', #
405
- '#383838', #
406
- '#686868', #
407
- '#989898', #
408
- '#c8c8c8', #
409
- '#e8e8e8', #
410
- ]
411
-
406
+ '#282828', #
407
+ '#383838', #
408
+ '#686868', #
409
+ '#989898', #
410
+ '#c8c8c8', #
411
+ '#e8e8e8', #
412
+ ]
413
+
412
414
  self.theme = {
413
415
  :colors => @colors,
414
416
  :marker_color => '#aea9a9', # Grey
@@ -440,7 +442,7 @@ module Gruff
440
442
  # Pre-normalize
441
443
  data_points.each_with_index do |data_point, index|
442
444
  next if data_point.nil?
443
-
445
+
444
446
  # Setup max/min so spread starts at the low end of the data points
445
447
  if @maximum_value.nil? && @minimum_value.nil?
446
448
  @maximum_value = @minimum_value = data_point
@@ -450,9 +452,9 @@ module Gruff
450
452
  # Original: @maximum_value = larger_than_max?(data_point, index) ? max(data_point, index) : @maximum_value
451
453
  @maximum_value = larger_than_max?(data_point) ? data_point : @maximum_value
452
454
  @has_data = true if @maximum_value > 0
453
-
455
+
454
456
  @minimum_value = less_than_min?(data_point) ? data_point : @minimum_value
455
- @has_data = true if @minimum_value < 0
457
+ @has_data = true if @minimum_value < 0
456
458
  end
457
459
  end
458
460
 
@@ -469,13 +471,13 @@ module Gruff
469
471
  def to_blob(fileformat='PNG')
470
472
  draw()
471
473
  return @base_image.to_blob do
472
- self.format = fileformat
474
+ self.format = fileformat
473
475
  end
474
476
  end
475
477
 
476
-
477
478
 
478
- protected
479
+
480
+ protected
479
481
 
480
482
  # Overridden by subclasses to do the actual plotting of the graph.
481
483
  #
@@ -483,11 +485,11 @@ protected
483
485
  def draw
484
486
  make_stacked if @stacked
485
487
  setup_drawing
486
-
488
+
487
489
  debug {
488
490
  # Outer margin
489
- @d.rectangle( @left_margin, @top_margin,
490
- @raw_columns - @right_margin, @raw_rows - @bottom_margin)
491
+ @d.rectangle( @left_margin, @top_margin,
492
+ @raw_columns - @right_margin, @raw_rows - @bottom_margin)
491
493
  # Graph area box
492
494
  @d.rectangle( @graph_left, @graph_top, @graph_right, @graph_bottom)
493
495
  }
@@ -504,11 +506,11 @@ protected
504
506
  draw_no_data()
505
507
  return
506
508
  end
507
-
509
+
508
510
  normalize()
509
511
  setup_graph_measurements()
510
512
  sort_norm_data() if @sort # Sort norm_data with avg largest values set first (for display)
511
-
513
+
512
514
  draw_legend()
513
515
  draw_line_markers()
514
516
  draw_axis_labels()
@@ -520,9 +522,9 @@ protected
520
522
  if @norm_data.nil? || force
521
523
  @norm_data = []
522
524
  return unless @has_data
523
-
525
+
524
526
  calculate_spread
525
-
527
+
526
528
  @data.each do |data_row|
527
529
  norm_data_points = []
528
530
  data_row[DATA_VALUES_INDEX].each do |data_point|
@@ -542,47 +544,50 @@ protected
542
544
  @spread = @spread > 0 ? @spread : 1
543
545
  end
544
546
 
547
+ ##
545
548
  # Calculates size of drawable area, general font dimensions, etc.
549
+
546
550
  def setup_graph_measurements
547
551
  @marker_caps_height = @hide_line_markers ? 0 :
548
- calculate_caps_height(@marker_font_size)
552
+ calculate_caps_height(@marker_font_size)
549
553
  @title_caps_height = @hide_title ? 0 :
550
- calculate_caps_height(@title_font_size)
554
+ calculate_caps_height(@title_font_size)
551
555
  @legend_caps_height = @hide_legend ? 0 :
552
- calculate_caps_height(@legend_font_size)
556
+ calculate_caps_height(@legend_font_size)
553
557
 
554
558
  if @hide_line_markers
555
559
  (@graph_left,
556
- @graph_right_margin,
557
- @graph_bottom_margin) = [@left_margin, @right_margin, @bottom_margin]
560
+ @graph_right_margin,
561
+ @graph_bottom_margin) = [@left_margin, @right_margin, @bottom_margin]
558
562
  else
559
563
  longest_left_label_width = 0
560
564
  if @has_left_labels
561
565
  longest_left_label_width = calculate_width(@marker_font_size,
562
- labels.values.inject('') { |value, memo| (value.to_s.length > memo.to_s.length) ? value : memo }) * 1.25
566
+ labels.values.inject('') { |value, memo| (value.to_s.length > memo.to_s.length) ? value : memo }) * 1.25
563
567
  else
564
- longest_left_label_width = calculate_width(@marker_font_size,
565
- label(@maximum_value.to_f))
568
+ longest_left_label_width = calculate_width(@marker_font_size,
569
+ label(@maximum_value.to_f))
566
570
  end
567
571
 
568
572
  # Shift graph if left line numbers are hidden
569
- line_number_width = @hide_line_numbers && !@has_left_labels ?
570
- 0.0 :
571
- (longest_left_label_width + LABEL_MARGIN * 2)
573
+ line_number_width = @hide_line_numbers && !@has_left_labels ?
574
+ 0.0 :
575
+ (longest_left_label_width + LABEL_MARGIN * 2)
576
+
577
+ @graph_left = @left_margin +
578
+ line_number_width +
579
+ (@y_axis_label.nil? ? 0.0 : @marker_caps_height + LABEL_MARGIN * 2)
572
580
 
573
- @graph_left = @left_margin +
574
- line_number_width +
575
- (@y_axis_label.nil? ? 0.0 : @marker_caps_height + LABEL_MARGIN * 2)
576
581
  # Make space for half the width of the rightmost column label.
577
582
  # Might be greater than the number of columns if between-style bar markers are used.
578
583
  last_label = @labels.keys.sort.last.to_i
579
584
  extra_room_for_long_label = (last_label >= (@column_count-1) && @center_labels_over_point) ?
580
- calculate_width(@marker_font_size, @labels[last_label])/2.0 :
581
- 0
582
- @graph_right_margin = @right_margin + extra_room_for_long_label
583
-
584
- @graph_bottom_margin = @bottom_margin +
585
- @marker_caps_height + LABEL_MARGIN
585
+ calculate_width(@marker_font_size, @labels[last_label]) / 2.0 :
586
+ 0
587
+ @graph_right_margin = @right_margin + extra_room_for_long_label
588
+
589
+ @graph_bottom_margin = @bottom_margin +
590
+ @marker_caps_height + LABEL_MARGIN
586
591
  end
587
592
 
588
593
  @graph_right = @raw_columns - @graph_right_margin
@@ -590,12 +595,12 @@ protected
590
595
 
591
596
  # When @hide title, leave a TITLE_MARGIN space for aesthetics.
592
597
  # Same with @hide_legend
593
- @graph_top = @top_margin +
594
- (@hide_title ? TITLE_MARGIN : @title_caps_height + TITLE_MARGIN * 2) +
595
- (@hide_legend ? LEGEND_MARGIN : @legend_caps_height + LEGEND_MARGIN * 2)
598
+ @graph_top = @top_margin +
599
+ (@hide_title ? TITLE_MARGIN : @title_caps_height + TITLE_MARGIN * 2) +
600
+ (@hide_legend ? LEGEND_MARGIN : @legend_caps_height + LEGEND_MARGIN * 2)
596
601
 
597
602
  x_axis_label_height = @x_axis_label.nil? ? 0.0 :
598
- @marker_caps_height + LABEL_MARGIN
603
+ @marker_caps_height + LABEL_MARGIN
599
604
  @graph_bottom = @raw_rows - @graph_bottom_margin - x_axis_label_height
600
605
  @graph_height = @graph_bottom - @graph_top
601
606
  end
@@ -614,10 +619,10 @@ protected
614
619
  @d.stroke('transparent')
615
620
  @d.pointsize = scale_fontsize(@marker_font_size)
616
621
  @d.gravity = NorthGravity
617
- @d = @d.annotate_scaled( @base_image,
618
- @raw_columns, 1.0,
619
- 0.0, x_axis_label_y_coordinate,
620
- @x_axis_label, @scale)
622
+ @d = @d.annotate_scaled( @base_image,
623
+ @raw_columns, 1.0,
624
+ 0.0, x_axis_label_y_coordinate,
625
+ @x_axis_label, @scale)
621
626
  debug { @d.line 0.0, x_axis_label_y_coordinate, @raw_columns, x_axis_label_y_coordinate }
622
627
  end
623
628
 
@@ -625,10 +630,10 @@ protected
625
630
  # Y Axis, rotated vertically
626
631
  @d.rotation = 90.0
627
632
  @d.gravity = CenterGravity
628
- @d = @d.annotate_scaled( @base_image,
629
- 1.0, @raw_rows,
630
- @left_margin + @marker_caps_height / 2.0, 0.0,
631
- @y_axis_label, @scale)
633
+ @d = @d.annotate_scaled( @base_image,
634
+ 1.0, @raw_rows,
635
+ @left_margin + @marker_caps_height / 2.0, 0.0,
636
+ @y_axis_label, @scale)
632
637
  @d.rotation = -90.0
633
638
  end
634
639
  end
@@ -636,9 +641,9 @@ protected
636
641
  # Draws horizontal background lines and labels
637
642
  def draw_line_markers
638
643
  return if @hide_line_markers
639
-
644
+
640
645
  @d = @d.stroke_antialias false
641
-
646
+
642
647
  if @y_axis_increment.nil?
643
648
  # Try to use a number of horizontal lines that will come out even.
644
649
  #
@@ -659,7 +664,7 @@ protected
659
664
  @minimum_value = @minimum_value.floor
660
665
  calculate_spread
661
666
  normalize(true)
662
-
667
+
663
668
  @marker_count = (@spread / @y_axis_increment).to_i
664
669
  @increment = @y_axis_increment
665
670
  end
@@ -668,7 +673,7 @@ protected
668
673
  # Draw horizontal line markers and annotate with numbers
669
674
  (0..@marker_count).each do |index|
670
675
  y = @graph_top + @graph_height - index.to_f * @increment_scaled
671
-
676
+
672
677
  @d = @d.stroke(@marker_color)
673
678
  @d = @d.stroke_width 1
674
679
  @d = @d.line(@graph_left, y, @graph_right, y)
@@ -681,43 +686,61 @@ protected
681
686
  @d.stroke('transparent')
682
687
  @d.pointsize = scale_fontsize(@marker_font_size)
683
688
  @d.gravity = EastGravity
684
-
689
+
685
690
  # Vertically center with 1.0 for the height
686
- @d = @d.annotate_scaled( @base_image,
687
- @graph_left - LABEL_MARGIN, 1.0,
688
- 0.0, y,
689
- label(marker_label), @scale)
691
+ @d = @d.annotate_scaled( @base_image,
692
+ @graph_left - LABEL_MARGIN, 1.0,
693
+ 0.0, y,
694
+ label(marker_label), @scale)
690
695
  end
691
696
  end
692
-
697
+
693
698
  # # Submitted by a contibutor...the utility escapes me
694
699
  # i = 0
695
700
  # @additional_line_values.each do |value|
696
701
  # @increment_scaled = @graph_height.to_f / (@maximum_value.to_f / value)
697
- #
702
+ #
698
703
  # y = @graph_top + @graph_height - @increment_scaled
699
- #
704
+ #
700
705
  # @d = @d.stroke(@additional_line_colors[i])
701
706
  # @d = @d.line(@graph_left, y, @graph_right, y)
702
- #
703
- #
707
+ #
708
+ #
704
709
  # @d.fill = @additional_line_colors[i]
705
710
  # @d.font = @font if @font
706
711
  # @d.stroke('transparent')
707
712
  # @d.pointsize = scale_fontsize(@marker_font_size)
708
713
  # @d.gravity = EastGravity
709
- # @d = @d.annotate_scaled( @base_image,
714
+ # @d = @d.annotate_scaled( @base_image,
710
715
  # 100, 20,
711
- # -10, y - (@marker_font_size/2.0),
716
+ # -10, y - (@marker_font_size/2.0),
712
717
  # "", @scale)
713
- # i += 1
718
+ # i += 1
714
719
  # end
715
-
720
+
716
721
  @d = @d.stroke_antialias true
717
722
  end
718
723
 
719
- # Draws a legend with the names of the datasets matched to the colors used
720
- # to draw them.
724
+ ##
725
+ # Return the sum of values in an array.
726
+ #
727
+ # Duplicated to not conflict with active_support in Rails.
728
+
729
+ def sum(arr)
730
+ arr.inject(0) { |i, m| m + i }
731
+ end
732
+
733
+ ##
734
+ # Return a calculation of center
735
+
736
+ def center(size)
737
+ (@raw_columns - size) / 2
738
+ end
739
+
740
+ ##
741
+ # Draws a legend with the names of the datasets matched
742
+ # to the colors used to draw them.
743
+
721
744
  def draw_legend
722
745
  return if @hide_legend
723
746
 
@@ -729,23 +752,23 @@ protected
729
752
  @d.font = @font if @font
730
753
  @d.pointsize = @legend_font_size
731
754
 
732
- metrics = @d.get_type_metrics(@base_image, @legend_labels.join(''))
733
- legend_text_width = metrics.width
734
- legend_width = legend_text_width +
735
- (@legend_labels.length * legend_square_width * 2.7)
736
- legend_left = (@raw_columns - legend_width) / 2
737
- legend_increment = legend_width / @legend_labels.length.to_f
755
+ label_widths = [[]] # Used to calculate line wrap
756
+ @legend_labels.each do |label|
757
+ metrics = @d.get_type_metrics(@base_image, label.to_s)
758
+ label_width = metrics.width + legend_square_width * 2.7
759
+ label_widths.last.push label_width
760
+
761
+ if sum(label_widths.last) > (@raw_columns * 0.9)
762
+ label_widths.push [label_widths.last.pop]
763
+ end
764
+ end
738
765
 
739
- current_x_offset = legend_left
740
- current_y_offset = @hide_title ?
741
- @top_margin + LEGEND_MARGIN :
742
- @top_margin +
743
- TITLE_MARGIN + @title_caps_height +
744
- LEGEND_MARGIN
766
+ current_x_offset = center(sum(label_widths.first))
767
+ current_y_offset = @hide_title ?
768
+ @top_margin + LEGEND_MARGIN :
769
+ @top_margin + TITLE_MARGIN + @title_caps_height + LEGEND_MARGIN
745
770
 
746
- debug { @d.line 0.0, current_y_offset, @raw_columns, current_y_offset }
747
-
748
- @legend_labels.each_with_index do |legend_label, index|
771
+ @legend_labels.each_with_index do |legend_label, index|
749
772
 
750
773
  # Draw label
751
774
  @d.fill = @font_color
@@ -754,23 +777,40 @@ protected
754
777
  @d.stroke('transparent')
755
778
  @d.font_weight = NormalWeight
756
779
  @d.gravity = WestGravity
757
- @d = @d.annotate_scaled( @base_image,
758
- @raw_columns, 1.0,
759
- current_x_offset + (legend_square_width * 1.7), current_y_offset,
760
- legend_label.to_s, @scale)
761
-
780
+ @d = @d.annotate_scaled( @base_image,
781
+ @raw_columns, 1.0,
782
+ current_x_offset + (legend_square_width * 1.7), current_y_offset,
783
+ legend_label.to_s, @scale)
784
+
762
785
  # Now draw box with color of this dataset
763
786
  @d = @d.stroke('transparent')
764
787
  @d = @d.fill @data[index][DATA_COLOR_INDEX]
765
- @d = @d.rectangle(current_x_offset,
766
- current_y_offset - legend_square_width / 2.0,
767
- current_x_offset + legend_square_width,
768
- current_y_offset + legend_square_width / 2.0)
788
+ @d = @d.rectangle(current_x_offset,
789
+ current_y_offset - legend_square_width / 2.0,
790
+ current_x_offset + legend_square_width,
791
+ current_y_offset + legend_square_width / 2.0)
769
792
 
770
793
  @d.pointsize = @legend_font_size
771
794
  metrics = @d.get_type_metrics(@base_image, legend_label.to_s)
772
795
  current_string_offset = metrics.width + (legend_square_width * 2.7)
773
- current_x_offset += current_string_offset
796
+
797
+ # Handle wrapping
798
+ label_widths.first.shift
799
+ if label_widths.first.empty?
800
+ debug { @d.line 0.0, current_y_offset, @raw_columns, current_y_offset }
801
+
802
+ label_widths.shift
803
+ current_x_offset = center(sum(label_widths.first)) unless label_widths.empty?
804
+ line_height = [@legend_caps_height, legend_square_width].max + LEGEND_MARGIN
805
+ if label_widths.length > 0
806
+ # Wrap to next line and shrink available graph dimensions
807
+ current_y_offset += line_height
808
+ @graph_top += line_height
809
+ @graph_height = @graph_bottom - @graph_top
810
+ end
811
+ else
812
+ current_x_offset += current_string_offset
813
+ end
774
814
  end
775
815
  @color_index = 0
776
816
  end
@@ -785,10 +825,10 @@ protected
785
825
  @d.pointsize = scale_fontsize(@title_font_size)
786
826
  @d.font_weight = BoldWeight
787
827
  @d.gravity = NorthGravity
788
- @d = @d.annotate_scaled( @base_image,
789
- @raw_columns, 1.0,
790
- 0, @top_margin,
791
- @title, @scale)
828
+ @d = @d.annotate_scaled( @base_image,
829
+ @raw_columns, 1.0,
830
+ 0, @top_margin,
831
+ @title, @scale)
792
832
  end
793
833
 
794
834
  # Draws column labels below graph, centered over x_offset
@@ -807,9 +847,9 @@ protected
807
847
  @d.pointsize = scale_fontsize(@marker_font_size)
808
848
  @d.gravity = NorthGravity
809
849
  @d = @d.annotate_scaled(@base_image,
810
- 1.0, 1.0,
811
- x_offset, y_offset,
812
- @labels[index], @scale)
850
+ 1.0, 1.0,
851
+ x_offset, y_offset,
852
+ @labels[index], @scale)
813
853
  @labels_seen[index] = 1
814
854
  debug { @d.line 0.0, y_offset, @raw_columns, y_offset }
815
855
  end
@@ -817,16 +857,16 @@ protected
817
857
 
818
858
  # Shows an error message because you have no data.
819
859
  def draw_no_data
820
- @d.fill = @font_color
821
- @d.font = @font if @font
822
- @d.stroke('transparent')
823
- @d.font_weight = NormalWeight
824
- @d.pointsize = scale_fontsize(80)
825
- @d.gravity = CenterGravity
826
- @d = @d.annotate_scaled( @base_image,
827
- @raw_columns, @raw_rows/2.0,
828
- 0, 10,
829
- @no_data_message, @scale)
860
+ @d.fill = @font_color
861
+ @d.font = @font if @font
862
+ @d.stroke('transparent')
863
+ @d.font_weight = NormalWeight
864
+ @d.pointsize = scale_fontsize(80)
865
+ @d.gravity = CenterGravity
866
+ @d = @d.annotate_scaled( @base_image,
867
+ @raw_columns, @raw_rows/2.0,
868
+ 0, 10,
869
+ @no_data_message, @scale)
830
870
  end
831
871
 
832
872
  # Finds the best background to render based on the provided theme options.
@@ -852,8 +892,8 @@ protected
852
892
 
853
893
  # Use with a theme definition method to draw a gradiated background.
854
894
  def render_gradiated_background(top_color, bottom_color)
855
- Image.new(@columns, @rows,
856
- GradientFill.new(0, 0, 100, 0, top_color, bottom_color))
895
+ Image.new(@columns, @rows,
896
+ GradientFill.new(0, 0, 100, 0, top_color, bottom_color))
857
897
  end
858
898
 
859
899
  # Use with a theme to use an image (800x600 original) background.
@@ -903,7 +943,7 @@ protected
903
943
  data_point > @maximum_value
904
944
  end
905
945
 
906
- def less_than_min?(data_point, index=0) # :nodoc:
946
+ def less_than_min?(data_point, index=0) # :nodoc:
907
947
  data_point < @minimum_value
908
948
  end
909
949
 
@@ -913,7 +953,7 @@ protected
913
953
  end
914
954
 
915
955
  # Overridden by subclasses that need it.
916
- def min(data_point, index) # :nodoc:
956
+ def min(data_point, index) # :nodoc:
917
957
  data_point
918
958
  end
919
959
 
@@ -941,7 +981,7 @@ protected
941
981
  # Sort with largest overall summed value at front of array so it shows up
942
982
  # correctly in the drawn graph.
943
983
  def sort_norm_data
944
- @norm_data.sort! { |a,b| sums(b[1]) <=> sums(a[1]) }
984
+ @norm_data.sort! { |a,b| sums(b[DATA_VALUES_INDEX]) <=> sums(a[DATA_VALUES_INDEX]) }
945
985
  end
946
986
 
947
987
  def sums(data_set) # :nodoc:
@@ -973,14 +1013,14 @@ protected
973
1013
  def make_stacked # :nodoc:
974
1014
  stacked_values = Array.new(@column_count, 0)
975
1015
  @data.each do |value_set|
976
- value_set[1].each_with_index do |value, index|
1016
+ value_set[DATA_VALUES_INDEX].each_with_index do |value, index|
977
1017
  stacked_values[index] += value
978
1018
  end
979
- value_set[1] = stacked_values.dup
1019
+ value_set[DATA_VALUES_INDEX] = stacked_values.dup
980
1020
  end
981
1021
  end
982
1022
 
983
- private
1023
+ private
984
1024
 
985
1025
  # Takes a block and draws it if DEBUG is true.
986
1026
  #
@@ -1039,7 +1079,7 @@ private
1039
1079
 
1040
1080
  # Returns the width of a string at this pointsize.
1041
1081
  #
1042
- # Not scaled since it deals with dimensions that the regular
1082
+ # Not scaled since it deals with dimensions that the regular
1043
1083
  # scaling will handle.
1044
1084
  def calculate_width(font_size, text)
1045
1085
  @d.pointsize = font_size
@@ -1062,12 +1102,11 @@ module Magick
1062
1102
  scaled_height = (height * scale) >= 1 ? (height * scale) : 1
1063
1103
 
1064
1104
  self.annotate( img,
1065
- scaled_width, scaled_height,
1066
- x * scale, y * scale,
1067
- text)
1105
+ scaled_width, scaled_height,
1106
+ x * scale, y * scale,
1107
+ text)
1068
1108
  end
1069
1109
 
1070
1110
  end
1071
1111
 
1072
1112
  end # Magick
1073
-
@@ -0,0 +1,109 @@
1
+ require File.dirname(__FILE__) + '/base'
2
+
3
+ class Gruff::Bullet < Gruff::Base
4
+
5
+ def initialize(target_width="400x40")
6
+ if not Numeric === target_width
7
+ geometric_width, geometric_height = target_width.split('x')
8
+ @columns = geometric_width.to_f
9
+ @rows = geometric_height.to_f
10
+ else
11
+ @columns = target_width.to_f
12
+ @rows = target_width.to_f / 5.0
13
+ end
14
+
15
+ initialize_ivars
16
+
17
+ reset_themes
18
+ theme_greyscale
19
+ @title_font_size = 20
20
+ end
21
+
22
+ def data(value, maximum_value, options={})
23
+ @value = value.to_f
24
+ @maximum_value = maximum_value.to_f
25
+ @options = options
26
+ @options.map { |k, v| @options[k] = v.to_f if v === Numeric }
27
+ end
28
+
29
+ # def setup_drawing
30
+ # # Maybe should be done in one of the following functions for more granularity.
31
+ # unless @has_data
32
+ # draw_no_data()
33
+ # return
34
+ # end
35
+ #
36
+ # normalize()
37
+ # setup_graph_measurements()
38
+ # sort_norm_data() if @sort # Sort norm_data with avg largest values set first (for display)
39
+ #
40
+ # draw_legend()
41
+ # draw_line_markers()
42
+ # draw_axis_labels()
43
+ # draw_title
44
+ # end
45
+
46
+ def draw
47
+ # TODO Left label
48
+ # TODO Bottom labels and markers
49
+ # @graph_bottom
50
+ # Calculations are off 800x???
51
+
52
+ @colors.reverse!
53
+
54
+ draw_title
55
+
56
+ @margin = 30.0
57
+ @thickness = @raw_rows / 6.0
58
+ @right_margin = @margin
59
+ @graph_left = @title_width * 1.3 rescue @margin # HACK Need to calculate real width
60
+ @graph_width = @raw_columns - @graph_left - @right_margin
61
+ @graph_height = @thickness * 3.0
62
+
63
+ # Background
64
+ @d = @d.fill @colors[0]
65
+ @d = @d.rectangle(@graph_left, 0, @graph_left + @graph_width, @graph_height)
66
+
67
+ [:high, :low].each_with_index do |indicator, index|
68
+ next unless @options.has_key?(indicator)
69
+ @d = @d.fill @colors[index + 1]
70
+ indicator_width_x = @graph_left + @graph_width * (@options[indicator] / @maximum_value)
71
+ @d = @d.rectangle(@graph_left, 0, indicator_width_x, @graph_height)
72
+ end
73
+
74
+ if @options.has_key?(:target)
75
+ @d = @d.fill @font_color
76
+ target_x = @graph_left + @graph_width * (@options[:target] / @maximum_value)
77
+ half_thickness = @thickness / 2.0
78
+ @d = @d.rectangle(target_x, half_thickness, target_x + half_thickness, @thickness * 2 + half_thickness)
79
+ end
80
+
81
+ # Value
82
+ @d = @d.fill @font_color
83
+ @d = @d.rectangle(@graph_left, @thickness, @graph_left + @graph_width * (@value / @maximum_value), @thickness * 2)
84
+
85
+ @d.draw(@base_image)
86
+ end
87
+
88
+ def draw_title
89
+ return unless @title
90
+
91
+ @font_height = calculate_caps_height(scale_fontsize(@title_font_size))
92
+ @title_width = calculate_width(@title_font_size, @title)
93
+
94
+ @d.fill = @font_color
95
+ @d.font = @font if @font
96
+ @d.stroke('transparent')
97
+ @d.font_weight = NormalWeight
98
+ @d.pointsize = scale_fontsize(@title_font_size)
99
+ @d.gravity = NorthWestGravity
100
+ @d = @d.annotate_scaled(*[
101
+ @base_image,
102
+ 1.0, 1.0,
103
+ @font_height/2, @font_height/2,
104
+ @title,
105
+ @scale
106
+ ])
107
+ end
108
+
109
+ end
@@ -67,7 +67,7 @@ class Gruff::Line < Gruff::Base
67
67
  @norm_data.each do |data_row|
68
68
  prev_x = prev_y = nil
69
69
 
70
- data_row[1].each_with_index do |data_point, index|
70
+ data_row[DATA_VALUES_INDEX].each_with_index do |data_point, index|
71
71
  new_x = @graph_left + (@x_increment * index)
72
72
  next if data_point.nil?
73
73
 
@@ -79,12 +79,12 @@ class Gruff::Line < Gruff::Base
79
79
  @d = @d.stroke data_row[DATA_COLOR_INDEX]
80
80
  @d = @d.fill data_row[DATA_COLOR_INDEX]
81
81
  @d = @d.stroke_opacity 1.0
82
- @d = @d.stroke_width clip_value_if_greater_than(@columns / (@norm_data.first[1].size * 4), 5.0)
82
+ @d = @d.stroke_width clip_value_if_greater_than(@columns / (@norm_data.first[DATA_VALUES_INDEX].size * 4), 5.0)
83
83
 
84
84
  if !@hide_lines and !prev_x.nil? and !prev_y.nil? then
85
85
  @d = @d.line(prev_x, prev_y, new_x, new_y)
86
86
  end
87
- circle_radius = clip_value_if_greater_than(@columns / (@norm_data.first[1].size * 2.5), 5.0)
87
+ circle_radius = clip_value_if_greater_than(@columns / (@norm_data.first[DATA_VALUES_INDEX].size * 2.5), 5.0)
88
88
  @d = @d.circle(new_x, new_y, new_x - circle_radius, new_y) unless @hide_dots
89
89
 
90
90
  prev_x = new_x
@@ -24,10 +24,10 @@ class Gruff::Net < Gruff::Base
24
24
  @center_y = @graph_top + (@graph_height / 2.0) - 10 # Move graph up a bit
25
25
 
26
26
  @x_increment = @graph_width / (@column_count - 1).to_f
27
- circle_radius = clip_value_if_greater_than(@columns / (@norm_data.first[1].size * 2.5), 5.0)
27
+ circle_radius = clip_value_if_greater_than(@columns / (@norm_data.first[DATA_VALUES_INDEX].size * 2.5), 5.0)
28
28
 
29
29
  @d = @d.stroke_opacity 1.0
30
- @d = @d.stroke_width clip_value_if_greater_than(@columns / (@norm_data.first[1].size * 4), 5.0)
30
+ @d = @d.stroke_width clip_value_if_greater_than(@columns / (@norm_data.first[DATA_VALUES_INDEX].size * 4), 5.0)
31
31
 
32
32
  if (defined?(@norm_baseline)) then
33
33
  level = @graph_top + (@graph_height - @norm_baseline * @graph_height)
@@ -45,7 +45,7 @@ class Gruff::Net < Gruff::Base
45
45
  @d = @d.stroke data_row[DATA_COLOR_INDEX]
46
46
  @d = @d.fill data_row[DATA_COLOR_INDEX]
47
47
 
48
- data_row[1].each_with_index do |data_point, index|
48
+ data_row[DATA_VALUES_INDEX].each_with_index do |data_point, index|
49
49
  next if data_point.nil?
50
50
 
51
51
  rad_pos = index * Math::PI * 2 / @column_count
@@ -53,10 +53,10 @@ class Gruff::Net < Gruff::Base
53
53
  start_x = @center_x + Math::sin(rad_pos) * point_distance
54
54
  start_y = @center_y - Math::cos(rad_pos) * point_distance
55
55
 
56
- next_index = index + 1 < data_row[1].length ? index + 1 : 0
56
+ next_index = index + 1 < data_row[DATA_VALUES_INDEX].length ? index + 1 : 0
57
57
 
58
58
  next_rad_pos = next_index * Math::PI * 2 / @column_count
59
- next_point_distance = data_row[1][next_index] * @radius
59
+ next_point_distance = data_row[DATA_VALUES_INDEX][next_index] * @radius
60
60
  end_x = @center_x + Math::sin(next_rad_pos) * next_point_distance
61
61
  end_y = @center_y - Math::cos(next_rad_pos) * next_point_distance
62
62
 
@@ -48,7 +48,7 @@ class Gruff::PhotoBar < Gruff::Base
48
48
 
49
49
  @norm_data.each_with_index do |data_row, row_index|
50
50
 
51
- data_row[1].each_with_index do |data_point, point_index|
51
+ data_row[DATA_VALUES_INDEX].each_with_index do |data_point, point_index|
52
52
  data_point = 0 if data_point.nil?
53
53
  # Use incremented x and scaled y
54
54
  left_x = @graph_left + (@bar_width * (row_index + point_index + ((@data.length - 1) * point_index)))
@@ -40,14 +40,14 @@ class Gruff::Pie < Gruff::Base
40
40
  prev_degrees = @zero_degree
41
41
 
42
42
  # Use full data since we can easily calculate percentages
43
- data = (@sort ? @data.sort{ |a, b| a[DATA_VALUES_INDEX][0] <=> b[DATA_VALUES_INDEX][0] } : @data)
43
+ data = (@sort ? @data.sort{ |a, b| a[DATA_VALUES_INDEX].first <=> b[DATA_VALUES_INDEX].first } : @data)
44
44
  data.each do |data_row|
45
- if data_row[DATA_VALUES_INDEX][0] > 0
45
+ if data_row[DATA_VALUES_INDEX].first > 0
46
46
  @d = @d.stroke data_row[DATA_COLOR_INDEX]
47
47
  @d = @d.fill 'transparent'
48
48
  @d.stroke_width(radius) # stroke width should be equal to radius. we'll draw centered on (radius / 2)
49
49
 
50
- current_degrees = (data_row[DATA_VALUES_INDEX][0] / total_sum) * 360.0
50
+ current_degrees = (data_row[DATA_VALUES_INDEX].first / total_sum) * 360.0
51
51
 
52
52
  # ellipse will draw the the stroke centered on the first two parameters offset by the second two.
53
53
  # therefore, in order to draw a circle of the proper diameter we must center the stroke at
@@ -63,7 +63,7 @@ class Gruff::Pie < Gruff::Base
63
63
  # unless @hide_line_markers then
64
64
  # End the string with %% to escape the single %.
65
65
  # RMagick must use sprintf with the string and % has special significance.
66
- label_string = ((data_row[DATA_VALUES_INDEX][0] / total_sum) *
66
+ label_string = ((data_row[DATA_VALUES_INDEX].first / total_sum) *
67
67
  100.0).round.to_s + '%%'
68
68
  @d = draw_label(center_x,center_y, half_angle,
69
69
  radius + (radius * TEXT_OFFSET_PERCENTAGE),
@@ -109,7 +109,7 @@ private
109
109
 
110
110
  def sums_for_pie
111
111
  total_sum = 0.0
112
- @data.collect {|data_row| total_sum += data_row[DATA_VALUES_INDEX][0] }
112
+ @data.collect {|data_row| total_sum += data_row[DATA_VALUES_INDEX].first }
113
113
  total_sum
114
114
  end
115
115
 
@@ -24,7 +24,7 @@ class Gruff::SideBar < Gruff::Base
24
24
  @norm_data.each_with_index do |data_row, row_index|
25
25
  @d = @d.fill data_row[DATA_COLOR_INDEX]
26
26
 
27
- data_row[1].each_with_index do |data_point, point_index|
27
+ data_row[DATA_VALUES_INDEX].each_with_index do |data_point, point_index|
28
28
 
29
29
  # Using the original calcs from the stacked bar chart
30
30
  # to get the difference between
@@ -31,7 +31,7 @@ class Gruff::SideStackedBar < Gruff::SideBar
31
31
  @norm_data.each_with_index do |data_row, row_index|
32
32
  @d = @d.fill data_row[DATA_COLOR_INDEX]
33
33
 
34
- data_row[1].each_with_index do |data_point, point_index|
34
+ data_row[DATA_VALUES_INDEX].each_with_index do |data_point, point_index|
35
35
 
36
36
  ## using the original calcs from the stacked bar chart to get the difference between
37
37
  ## part of the bart chart we wish to stack.
@@ -67,7 +67,7 @@ class Gruff::SideStackedBar < Gruff::SideBar
67
67
  end
68
68
 
69
69
  def max(data_point, index)
70
- @data.inject(0) {|sum, item| sum + item[1][index]}
70
+ @data.inject(0) {|sum, item| sum + item[DATA_VALUES_INDEX][index]}
71
71
  end
72
72
 
73
73
  end
@@ -101,7 +101,7 @@ private
101
101
  center_x + x_offset,
102
102
  center_y + y_offset)
103
103
 
104
- draw_label(center_x, center_y, current_angle, radius, data_row[0].to_s) unless hide_text
104
+ draw_label(center_x, center_y, current_angle, radius, data_row[DATA_LABEL_INDEX].to_s) unless hide_text
105
105
 
106
106
  current_angle += additive_angle
107
107
  end
@@ -111,8 +111,8 @@ private
111
111
  points = []
112
112
  current_angle = 0.0
113
113
  @data.each do |data_row|
114
- points << center_x + normalize_points(data_row[1][0]) * Math.cos(current_angle)
115
- points << center_y + normalize_points(data_row[1][0]) * Math.sin(current_angle)
114
+ points << center_x + normalize_points(data_row[DATA_VALUES_INDEX].first) * Math.cos(current_angle)
115
+ points << center_y + normalize_points(data_row[DATA_VALUES_INDEX].first) * Math.sin(current_angle)
116
116
  current_angle += additive_angle
117
117
  end
118
118
 
@@ -124,7 +124,7 @@ private
124
124
  end
125
125
 
126
126
  def sums_for_spider
127
- @data.inject(0.0) {|sum, data_row| sum += data_row[1][0]}
127
+ @data.inject(0.0) {|sum, data_row| sum += data_row[DATA_VALUES_INDEX].first}
128
128
  end
129
129
 
130
130
  end
@@ -7,6 +7,7 @@ class Gruff::StackedArea < Gruff::Base
7
7
  attr_accessor :last_series_goes_on_bottom
8
8
 
9
9
  def draw
10
+ get_maximum_by_stack
10
11
  super
11
12
 
12
13
  return unless @has_data
@@ -24,7 +25,7 @@ class Gruff::StackedArea < Gruff::Base
24
25
 
25
26
  @d = @d.fill data_row[DATA_COLOR_INDEX]
26
27
 
27
- data_row[1].each_with_index do |data_point, index|
28
+ data_row[DATA_VALUES_INDEX].each_with_index do |data_point, index|
28
29
  # Use incremented x and scaled y
29
30
  new_x = @graph_left + (@x_increment * index)
30
31
  new_y = @graph_top + (@graph_height - data_point * @graph_height - height[index])
@@ -21,10 +21,10 @@ class Gruff::StackedBar < Gruff::Base
21
21
 
22
22
  height = Array.new(@column_count, 0)
23
23
 
24
- @norm_data.each_with_index do |data_row, row_index|
25
- @d = @d.fill data_row[DATA_COLOR_INDEX]
26
-
27
- data_row[1].each_with_index do |data_point, point_index|
24
+ @norm_data.each_with_index do |data_row, row_index|
25
+ data_row[DATA_VALUES_INDEX].each_with_index do |data_point, point_index|
26
+ @d = @d.fill data_row[DATA_COLOR_INDEX]
27
+
28
28
  # Calculate center based on bar_width and current row
29
29
  label_center = @graph_left + (@bar_width * point_index) + (@bar_width * spacing_factor / 2.0)
30
30
  draw_label(label_center, point_index)
@@ -114,12 +114,12 @@ class TestGruffBar < GruffTestCase
114
114
 
115
115
  def test_set_legend_box_size
116
116
  g = setup_basic_graph(400)
117
- g.title = "Set Legend Box Size"
117
+ g.title = "Set Small Legend Box Size"
118
118
  g.legend_box_size = 10.0
119
119
  g.write("test/output/bar_set_legend_box_size_sm.png")
120
120
 
121
121
  g = setup_basic_graph(400)
122
- g.title = "Set Legend Box Size"
122
+ g.title = "Set Large Legend Box Size"
123
123
  g.legend_box_size = 50.0
124
124
  g.write("test/output/bar_set_legend_box_size_lg.png")
125
125
  end
@@ -27,45 +27,42 @@ class TestGruffLegend < GruffTestCase
27
27
  }
28
28
  end
29
29
 
30
- ## TODO Fix implementation
30
+ def full_suite_for(name, type)
31
+ [800, 400].each do |width|
32
+ [nil, 4, 16, 30].each do |font_size|
33
+ g = type.new(width)
34
+ g.title = "Wrapped Legend Bar Test #{font_size}pts #{width}px"
35
+ g.labels = @sample_labels
36
+ 0xEFD250.step(0xFF0000, 60) do |num|
37
+ g.colors << "#%x" % num
38
+ end
39
+
40
+ @datasets.each do |data|
41
+ g.data(data[0], data[1])
42
+ end
43
+
44
+ g.legend_font_size = font_size unless font_size.nil?
45
+ g.write("test/output/#{name}_wrapped_legend_#{font_size}_#{width}.png")
46
+ end
47
+ end
48
+ end
31
49
 
32
- # def test_bar_legend_wrap
33
- # [800, 400].each do |width|
34
- # [nil, 4, 16, 30].each do |font_size|
35
- # g = Gruff::Bar.new(width)
36
- # g.title = "Wrapped Legend Bar Test #{font_size}pts #{width}px"
37
- # g.labels = @sample_labels
38
- # 0xEFD250.step(0xFF0000, 60) do |num|
39
- # g.colors << "#%x" % num
40
- # end
41
- #
42
- # @datasets.each do |data|
43
- # g.data(data[0], data[1])
44
- # end
45
- #
46
- # g.legend_font_size = font_size unless font_size.nil?
47
- # g.write("test/output/bar_wrapped_legend_#{font_size}_#{width}.png")
48
- # end
49
- # end
50
- # end
51
- #
52
- # def test_pie_legend_wrap
53
- # [800, 400].each do |width|
54
- # [nil, 4, 16, 30].each do |font_size|
55
- # g = Gruff::Pie.new(width)
56
- # g.title = "Wrapped Legend Pie Test #{font_size}pts #{width}px"
57
- # g.labels = @sample_labels
58
- # 0xEFD250.step(0xFF0000, 60) do |num|
59
- # g.colors << "#%x" % num
60
- # end
61
- #
62
- # @datasets.each do |data|
63
- # g.data(data[0], data[1])
64
- # end
65
- #
66
- # g.legend_font_size = font_size unless font_size.nil?
67
- # g.write("test/output/pie_wrapped_legend_#{font_size}_#{width}.png")
68
- # end
69
- # end
70
- # end
50
+ def test_bar_legend_wrap
51
+ full_suite_for(:bar, Gruff::Bar)
52
+ end
53
+
54
+ def test_pie_legend_wrap
55
+ full_suite_for(:pie, Gruff::Pie)
56
+ end
57
+
58
+ def test_more_than_two_lines_of_legends
59
+ @datasets = @datasets + [[:Julie2, [22, 29, 35, 38, 36, 40, 46, 57]],
60
+ [:Jane2, [95, 95, 95, 90, 85, 80, 88, 100]],
61
+ [:Philip2, [90, 34, 23, 12, 78, 89, 98, 88]],
62
+ ["Arthur2", [5, 10, 13, 11, 6, 16, 22, 32]],
63
+ ["Vincent2", [5, 10, 13, 11, 6, 16, 22, 32]],
64
+ ["Jake2", [5, 10, 13, 11, 6, 16, 22, 32]],
65
+ ["Stephen2", [5, 10, 13, 11, 6, 16, 22, 32]]]
66
+ full_suite_for(:bar2, Gruff::Bar)
67
+ end
71
68
  end
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require File.dirname(__FILE__) + "/gruff_test_case"
4
+
5
+ class TestGruffStackedArea < GruffTestCase
6
+
7
+ def setup
8
+ @datasets = [
9
+ [:Jimmy, [25, 36, 86, 39]],
10
+ [:Charles, [80, 54, 67, 54]],
11
+ [:Julie, [22, 29, 35, 38]],
12
+ ]
13
+ @sample_labels = {
14
+ 0 => '5/6',
15
+ 1 => '5/15',
16
+ 2 => '5/24'
17
+ }
18
+
19
+ end
20
+
21
+ def test_area_graph
22
+ g = Gruff::StackedArea.new
23
+ g.title = "Visual Stacked Area Graph Test"
24
+ g.labels = {
25
+ 0 => '5/6',
26
+ 1 => '5/15',
27
+ 2 => '5/24',
28
+ 3 => '5/30',
29
+ }
30
+ @datasets.each do |data|
31
+ g.data(data[0], data[1])
32
+ end
33
+ g.write "test/output/stacked_area_keynote.png"
34
+ end
35
+
36
+
37
+ def test_area_graph_small
38
+ g = Gruff::StackedArea.new(400)
39
+ g.title = "Visual Stacked Area Graph Test"
40
+ g.labels = {
41
+ 0 => '5/6',
42
+ 1 => '5/15',
43
+ 2 => '5/24',
44
+ 3 => '5/30',
45
+ }
46
+ @datasets.each do |data|
47
+ g.data(data[0], data[1])
48
+ end
49
+ g.write "test/output/stacked_area_keynote_small.png"
50
+ end
51
+
52
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: topfunky-gruff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geoffrey Grosenbach
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-05-06 00:00:00 -07:00
12
+ date: 2008-08-16 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -19,7 +19,7 @@ dependencies:
19
19
  requirements:
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 1.5.1
22
+ version: 1.7.0
23
23
  version:
24
24
  description: Beautiful graphs for one or multiple datasets. Can be used on websites or in documents.
25
25
  email: boss@topfunky.com
@@ -71,6 +71,7 @@ files:
71
71
  - lib/gruff/bar.rb
72
72
  - lib/gruff/bar_conversion.rb
73
73
  - lib/gruff/base.rb
74
+ - lib/gruff/bullet.rb
74
75
  - lib/gruff/deprecated.rb
75
76
  - lib/gruff/line.rb
76
77
  - lib/gruff/mini/bar.rb
@@ -95,6 +96,7 @@ files:
95
96
  - test/test_area.rb
96
97
  - test/test_bar.rb
97
98
  - test/test_base.rb
99
+ - test/test_bullet.rb
98
100
  - test/test_legend.rb
99
101
  - test/test_line.rb
100
102
  - test/test_mini_bar.rb
@@ -107,8 +109,8 @@ files:
107
109
  - test/test_side_bar.rb
108
110
  - test/test_sidestacked_bar.rb
109
111
  - test/test_spider.rb
112
+ - test/test_stacked_area.rb
110
113
  - test/test_stacked_bar.rb
111
- - test/test_bullet.rb
112
114
  has_rdoc: true
113
115
  homepage: http://nubyonrails.com/pages/gruff
114
116
  post_install_message:
@@ -132,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
132
134
  requirements: []
133
135
 
134
136
  rubyforge_project: gruff
135
- rubygems_version: 1.0.1
137
+ rubygems_version: 1.2.0
136
138
  signing_key:
137
139
  specification_version: 2
138
140
  summary: Beautiful graphs for one or multiple datasets.
@@ -154,4 +156,5 @@ test_files:
154
156
  - test/test_side_bar.rb
155
157
  - test/test_sidestacked_bar.rb
156
158
  - test/test_spider.rb
159
+ - test/test_stacked_area.rb
157
160
  - test/test_stacked_bar.rb