pfsc_gruff 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. data/History.txt +117 -0
  2. data/MIT-LICENSE +21 -0
  3. data/Manifest.txt +81 -0
  4. data/README.txt +40 -0
  5. data/Rakefile +55 -0
  6. data/assets/bubble.png +0 -0
  7. data/assets/city_scene/background/0000.png +0 -0
  8. data/assets/city_scene/background/0600.png +0 -0
  9. data/assets/city_scene/background/2000.png +0 -0
  10. data/assets/city_scene/clouds/cloudy.png +0 -0
  11. data/assets/city_scene/clouds/partly_cloudy.png +0 -0
  12. data/assets/city_scene/clouds/stormy.png +0 -0
  13. data/assets/city_scene/grass/default.png +0 -0
  14. data/assets/city_scene/haze/true.png +0 -0
  15. data/assets/city_scene/number_sample/1.png +0 -0
  16. data/assets/city_scene/number_sample/2.png +0 -0
  17. data/assets/city_scene/number_sample/default.png +0 -0
  18. data/assets/city_scene/sky/0000.png +0 -0
  19. data/assets/city_scene/sky/0200.png +0 -0
  20. data/assets/city_scene/sky/0400.png +0 -0
  21. data/assets/city_scene/sky/0600.png +0 -0
  22. data/assets/city_scene/sky/0800.png +0 -0
  23. data/assets/city_scene/sky/1000.png +0 -0
  24. data/assets/city_scene/sky/1200.png +0 -0
  25. data/assets/city_scene/sky/1400.png +0 -0
  26. data/assets/city_scene/sky/1500.png +0 -0
  27. data/assets/city_scene/sky/1700.png +0 -0
  28. data/assets/city_scene/sky/2000.png +0 -0
  29. data/assets/pc306715.jpg +0 -0
  30. data/assets/plastik/blue.png +0 -0
  31. data/assets/plastik/green.png +0 -0
  32. data/assets/plastik/red.png +0 -0
  33. data/init.rb +2 -0
  34. data/lib/gruff.rb +28 -0
  35. data/lib/gruff/accumulator_bar.rb +27 -0
  36. data/lib/gruff/area.rb +58 -0
  37. data/lib/gruff/bar.rb +87 -0
  38. data/lib/gruff/bar_conversion.rb +46 -0
  39. data/lib/gruff/base.rb +1123 -0
  40. data/lib/gruff/bullet.rb +109 -0
  41. data/lib/gruff/deprecated.rb +39 -0
  42. data/lib/gruff/dot.rb +113 -0
  43. data/lib/gruff/line.rb +135 -0
  44. data/lib/gruff/mini/bar.rb +37 -0
  45. data/lib/gruff/mini/legend.rb +109 -0
  46. data/lib/gruff/mini/pie.rb +36 -0
  47. data/lib/gruff/mini/side_bar.rb +35 -0
  48. data/lib/gruff/net.rb +140 -0
  49. data/lib/gruff/photo_bar.rb +100 -0
  50. data/lib/gruff/pie.rb +126 -0
  51. data/lib/gruff/scene.rb +209 -0
  52. data/lib/gruff/side_bar.rb +118 -0
  53. data/lib/gruff/side_stacked_bar.rb +77 -0
  54. data/lib/gruff/spider.rb +130 -0
  55. data/lib/gruff/stacked_area.rb +67 -0
  56. data/lib/gruff/stacked_bar.rb +57 -0
  57. data/lib/gruff/stacked_mixin.rb +23 -0
  58. data/rails_generators/gruff/gruff_generator.rb +63 -0
  59. data/rails_generators/gruff/templates/controller.rb +32 -0
  60. data/rails_generators/gruff/templates/functional_test.rb +24 -0
  61. data/test/gruff_test_case.rb +123 -0
  62. data/test/test_accumulator_bar.rb +50 -0
  63. data/test/test_area.rb +134 -0
  64. data/test/test_bar.rb +321 -0
  65. data/test/test_base.rb +8 -0
  66. data/test/test_bullet.rb +26 -0
  67. data/test/test_dot.rb +273 -0
  68. data/test/test_legend.rb +68 -0
  69. data/test/test_line.rb +556 -0
  70. data/test/test_mini_bar.rb +33 -0
  71. data/test/test_mini_pie.rb +26 -0
  72. data/test/test_mini_side_bar.rb +37 -0
  73. data/test/test_net.rb +230 -0
  74. data/test/test_photo.rb +41 -0
  75. data/test/test_pie.rb +154 -0
  76. data/test/test_scene.rb +100 -0
  77. data/test/test_side_bar.rb +29 -0
  78. data/test/test_sidestacked_bar.rb +89 -0
  79. data/test/test_spider.rb +216 -0
  80. data/test/test_stacked_area.rb +52 -0
  81. data/test/test_stacked_bar.rb +52 -0
  82. metadata +186 -0
@@ -0,0 +1,118 @@
1
+ require File.dirname(__FILE__) + '/base'
2
+
3
+ ##
4
+ # Graph with individual horizontal bars instead of vertical bars.
5
+
6
+ class Gruff::SideBar < Gruff::Base
7
+
8
+ # Spacing factor applied between bars
9
+ attr_accessor :bar_spacing
10
+
11
+ def draw
12
+ @has_left_labels = true
13
+ super
14
+
15
+ return unless @has_data
16
+
17
+ # Setup spacing.
18
+ #
19
+ @bar_spacing ||= 0.9
20
+
21
+ @bars_width = @graph_height / @column_count.to_f
22
+ @bar_width = @bars_width * @bar_spacing / @norm_data.size
23
+ @d = @d.stroke_opacity 0.0
24
+ height = Array.new(@column_count, 0)
25
+ length = Array.new(@column_count, @graph_left)
26
+ padding = (@bars_width * (1 - @bar_spacing)) / 2
27
+
28
+ @norm_data.each_with_index do |data_row, row_index|
29
+ @d = @d.fill data_row[DATA_COLOR_INDEX]
30
+
31
+ data_row[DATA_VALUES_INDEX].each_with_index do |data_point, point_index|
32
+
33
+ # Using the original calcs from the stacked bar chart
34
+ # to get the difference between
35
+ # part of the bart chart we wish to stack.
36
+ temp1 = @graph_left + (@graph_width - data_point * @graph_width - height[point_index])
37
+ temp2 = @graph_left + @graph_width - height[point_index]
38
+ difference = temp2 - temp1
39
+
40
+ left_x = length[point_index] - 1
41
+ left_y = @graph_top + (@bars_width * point_index) + (@bar_width * row_index) + padding
42
+ right_x = left_x + difference
43
+ right_y = left_y + @bar_width
44
+
45
+ height[point_index] += (data_point * @graph_width)
46
+
47
+ @d = @d.rectangle(left_x, left_y, right_x, right_y) unless difference <= 0
48
+
49
+ # Calculate center based on bar_width and current row
50
+ label_center = @graph_top + (@bars_width * point_index + @bars_width / 2)
51
+ draw_label(label_center, point_index)
52
+ end
53
+
54
+ end
55
+
56
+ @d.draw(@base_image)
57
+ end
58
+
59
+ protected
60
+
61
+ # Instead of base class version, draws vertical background lines and label
62
+ def draw_line_markers
63
+
64
+ return if @hide_line_markers
65
+
66
+ @d = @d.stroke_antialias false
67
+
68
+ # Draw horizontal line markers and annotate with numbers
69
+ @d = @d.stroke(@marker_color)
70
+ @d = @d.stroke_width 1
71
+ number_of_lines = 5
72
+
73
+ # TODO Round maximum marker value to a round number like 100, 0.1, 0.5, etc.
74
+ increment = significant(@maximum_value.to_f / number_of_lines)
75
+ (0..number_of_lines).each do |index|
76
+
77
+ line_diff = (@graph_right - @graph_left) / number_of_lines
78
+ x = @graph_right - (line_diff * index) - 1
79
+ @d = @d.line(x, @graph_bottom, x, @graph_top)
80
+ diff = index - number_of_lines
81
+ marker_label = diff.abs * increment
82
+
83
+ unless @hide_line_numbers
84
+ @d.fill = @font_color
85
+ @d.font = @font if @font
86
+ @d.stroke = 'transparent'
87
+ @d.pointsize = scale_fontsize(@marker_font_size)
88
+ @d.gravity = CenterGravity
89
+ # TODO Center text over line
90
+ @d = @d.annotate_scaled( @base_image,
91
+ 0, 0, # Width of box to draw text in
92
+ x, @graph_bottom + (LABEL_MARGIN * 2.0), # Coordinates of text
93
+ marker_label.to_s, @scale)
94
+ end # unless
95
+ @d = @d.stroke_antialias true
96
+ end
97
+ end
98
+
99
+ ##
100
+ # Draw on the Y axis instead of the X
101
+
102
+ def draw_label(y_offset, index)
103
+ if !@labels[index].nil? && @labels_seen[index].nil?
104
+ @d.fill = @font_color
105
+ @d.font = @font if @font
106
+ @d.stroke = 'transparent'
107
+ @d.font_weight = NormalWeight
108
+ @d.pointsize = scale_fontsize(@marker_font_size)
109
+ @d.gravity = EastGravity
110
+ @d = @d.annotate_scaled(@base_image,
111
+ 1, 1,
112
+ -@graph_left + LABEL_MARGIN * 2.0, y_offset,
113
+ @labels[index], @scale)
114
+ @labels_seen[index] = 1
115
+ end
116
+ end
117
+
118
+ end
@@ -0,0 +1,77 @@
1
+ require File.dirname(__FILE__) + '/base'
2
+ require File.dirname(__FILE__) + '/side_bar'
3
+ require File.dirname(__FILE__) + '/stacked_mixin'
4
+
5
+ ##
6
+ # New gruff graph type added to enable sideways stacking bar charts
7
+ # (basically looks like a x/y flip of a standard stacking bar chart)
8
+ #
9
+ # alun.eyre@googlemail.com
10
+
11
+ class Gruff::SideStackedBar < Gruff::SideBar
12
+ include StackedMixin
13
+
14
+ # Spacing factor applied between bars
15
+ attr_accessor :bar_spacing
16
+
17
+ def draw
18
+ @has_left_labels = true
19
+ get_maximum_by_stack
20
+ super
21
+
22
+ return unless @has_data
23
+
24
+ # Setup spacing.
25
+ #
26
+ # Columns sit stacked.
27
+ @bar_spacing ||= 0.9
28
+
29
+ @bar_width = @graph_height / @column_count.to_f
30
+ @d = @d.stroke_opacity 0.0
31
+ height = Array.new(@column_count, 0)
32
+ length = Array.new(@column_count, @graph_left)
33
+ padding = (@bar_width * (1 - @bar_spacing)) / 2
34
+
35
+ @norm_data.each_with_index do |data_row, row_index|
36
+ @d = @d.fill data_row[DATA_COLOR_INDEX]
37
+
38
+ data_row[DATA_VALUES_INDEX].each_with_index do |data_point, point_index|
39
+
40
+ ## using the original calcs from the stacked bar chart to get the difference between
41
+ ## part of the bart chart we wish to stack.
42
+ temp1 = @graph_left + (@graph_width -
43
+ data_point * @graph_width -
44
+ height[point_index]) + 1
45
+ temp2 = @graph_left + @graph_width - height[point_index] - 1
46
+ difference = temp2 - temp1
47
+
48
+ left_x = length[point_index] #+ 1
49
+ left_y = @graph_top + (@bar_width * point_index) + padding
50
+ right_x = left_x + difference
51
+ right_y = left_y + @bar_width * @bar_spacing
52
+ length[point_index] += difference
53
+ height[point_index] += (data_point * @graph_width - 2)
54
+
55
+ @d = @d.rectangle(left_x, left_y, right_x, right_y) unless difference <= 0
56
+
57
+ # Calculate center based on bar_width and current row
58
+ label_center = @graph_top + (@bar_width * point_index) + (@bar_width * @bar_spacing / 2.0)
59
+ draw_label(label_center, point_index)
60
+ end
61
+
62
+ end
63
+
64
+ @d.draw(@base_image)
65
+ end
66
+
67
+ protected
68
+
69
+ def larger_than_max?(data_point, index=0)
70
+ max(data_point, index) > @maximum_value
71
+ end
72
+
73
+ def max(data_point, index)
74
+ @data.inject(0) {|sum, item| sum + item[DATA_VALUES_INDEX][index]}
75
+ end
76
+
77
+ end
@@ -0,0 +1,130 @@
1
+
2
+ require File.dirname(__FILE__) + '/base'
3
+
4
+ # Experimental!!! See also the Net graph.
5
+ #
6
+ # Submitted by Kevin Clark http://glu.ttono.us/
7
+ class Gruff::Spider < Gruff::Base
8
+
9
+ # Hide all text
10
+ attr_reader :hide_text
11
+ attr_accessor :hide_axes
12
+ attr_reader :transparent_background
13
+
14
+ def transparent_background=(value)
15
+ @transparent_background = value
16
+ @base_image = render_transparent_background if value
17
+ end
18
+
19
+ def hide_text=(value)
20
+ @hide_title = @hide_text = value
21
+ end
22
+
23
+ def initialize(max_value, target_width = 800)
24
+ super(target_width)
25
+ @max_value = max_value
26
+ @hide_legend = true;
27
+ end
28
+
29
+ def draw
30
+ @hide_line_markers = true
31
+
32
+ super
33
+
34
+ return unless @has_data
35
+
36
+ # Setup basic positioning
37
+ diameter = @graph_height
38
+ radius = @graph_height / 2.0
39
+ top_x = @graph_left + (@graph_width - diameter) / 2.0
40
+ center_x = @graph_left + (@graph_width / 2.0)
41
+ center_y = @graph_top + (@graph_height / 2.0) - 25 # Move graph up a bit
42
+
43
+ @unit_length = radius / @max_value
44
+
45
+
46
+ total_sum = sums_for_spider
47
+ prev_degrees = 0.0
48
+ additive_angle = (2 * Math::PI)/ @data.size
49
+
50
+ current_angle = 0.0
51
+
52
+ # Draw axes
53
+ draw_axes(center_x, center_y, radius, additive_angle) unless hide_axes
54
+
55
+ # Draw polygon
56
+ draw_polygon(center_x, center_y, additive_angle)
57
+
58
+
59
+ @d.draw(@base_image)
60
+ end
61
+
62
+ private
63
+
64
+ def normalize_points(value)
65
+ value * @unit_length
66
+ end
67
+
68
+ def draw_label(center_x, center_y, angle, radius, amount)
69
+ r_offset = 50 # The distance out from the center of the pie to get point
70
+ x_offset = center_x # The label points need to be tweaked slightly
71
+ y_offset = center_y + 0 # This one doesn't though
72
+ x = x_offset + ((radius + r_offset) * Math.cos(angle))
73
+ y = y_offset + ((radius + r_offset) * Math.sin(angle))
74
+
75
+ # Draw label
76
+ @d.fill = @marker_color
77
+ @d.font = @font if @font
78
+ @d.pointsize = scale_fontsize(legend_font_size)
79
+ @d.stroke = 'transparent'
80
+ @d.font_weight = BoldWeight
81
+ @d.gravity = CenterGravity
82
+ @d.annotate_scaled( @base_image,
83
+ 0, 0,
84
+ x, y,
85
+ amount, @scale)
86
+ end
87
+
88
+ def draw_axes(center_x, center_y, radius, additive_angle, line_color = nil)
89
+ return if hide_axes
90
+
91
+ current_angle = 0.0
92
+
93
+ @data.each do |data_row|
94
+ @d.stroke(line_color || data_row[DATA_COLOR_INDEX])
95
+ @d.stroke_width 5.0
96
+
97
+ x_offset = radius * Math.cos(current_angle)
98
+ y_offset = radius * Math.sin(current_angle)
99
+
100
+ @d.line(center_x, center_y,
101
+ center_x + x_offset,
102
+ center_y + y_offset)
103
+
104
+ draw_label(center_x, center_y, current_angle, radius, data_row[DATA_LABEL_INDEX].to_s) unless hide_text
105
+
106
+ current_angle += additive_angle
107
+ end
108
+ end
109
+
110
+ def draw_polygon(center_x, center_y, additive_angle, color = nil)
111
+ points = []
112
+ current_angle = 0.0
113
+ @data.each do |data_row|
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
+ current_angle += additive_angle
117
+ end
118
+
119
+ @d.stroke_width 1.0
120
+ @d.stroke(color || @marker_color)
121
+ @d.fill(color || @marker_color)
122
+ @d.fill_opacity 0.4
123
+ @d.polygon(*points)
124
+ end
125
+
126
+ def sums_for_spider
127
+ @data.inject(0.0) {|sum, data_row| sum += data_row[DATA_VALUES_INDEX].first}
128
+ end
129
+
130
+ end
@@ -0,0 +1,67 @@
1
+
2
+ require File.dirname(__FILE__) + '/base'
3
+ require File.dirname(__FILE__) + '/stacked_mixin'
4
+
5
+ class Gruff::StackedArea < Gruff::Base
6
+ include StackedMixin
7
+ attr_accessor :last_series_goes_on_bottom
8
+
9
+ def draw
10
+ get_maximum_by_stack
11
+ super
12
+
13
+ return unless @has_data
14
+
15
+ @x_increment = @graph_width / (@column_count - 1).to_f
16
+ @d = @d.stroke 'transparent'
17
+
18
+ height = Array.new(@column_count, 0)
19
+
20
+ data_points = nil
21
+ iterator = last_series_goes_on_bottom ? :reverse_each : :each
22
+ @norm_data.send(iterator) do |data_row|
23
+ prev_data_points = data_points
24
+ data_points = Array.new
25
+
26
+ @d = @d.fill data_row[DATA_COLOR_INDEX]
27
+
28
+ data_row[DATA_VALUES_INDEX].each_with_index do |data_point, index|
29
+ # Use incremented x and scaled y
30
+ new_x = @graph_left + (@x_increment * index)
31
+ new_y = @graph_top + (@graph_height - data_point * @graph_height - height[index])
32
+
33
+ height[index] += (data_point * @graph_height)
34
+
35
+ data_points << new_x
36
+ data_points << new_y
37
+
38
+ draw_label(new_x, index)
39
+
40
+ end
41
+
42
+ if prev_data_points
43
+ poly_points = data_points.dup
44
+ (prev_data_points.length/2 - 1).downto(0) do |i|
45
+ poly_points << prev_data_points[2*i]
46
+ poly_points << prev_data_points[2*i+1]
47
+ end
48
+ poly_points << data_points[0]
49
+ poly_points << data_points[1]
50
+ else
51
+ poly_points = data_points.dup
52
+ poly_points << @graph_right
53
+ poly_points << @graph_bottom - 1
54
+ poly_points << @graph_left
55
+ poly_points << @graph_bottom - 1
56
+ poly_points << data_points[0]
57
+ poly_points << data_points[1]
58
+ end
59
+ @d = @d.polyline(*poly_points)
60
+
61
+ end
62
+
63
+ @d.draw(@base_image)
64
+ end
65
+
66
+
67
+ end
@@ -0,0 +1,57 @@
1
+
2
+ require File.dirname(__FILE__) + '/base'
3
+ require File.dirname(__FILE__) + '/stacked_mixin'
4
+
5
+ class Gruff::StackedBar < Gruff::Base
6
+ include StackedMixin
7
+
8
+ # Spacing factor applied between bars
9
+ attr_accessor :bar_spacing
10
+
11
+ # Draws a bar graph, but multiple sets are stacked on top of each other.
12
+ def draw
13
+ get_maximum_by_stack
14
+ super
15
+ return unless @has_data
16
+
17
+ # Setup spacing.
18
+ #
19
+ # Columns sit stacked.
20
+ @bar_spacing ||= 0.9
21
+ @bar_width = @graph_width / @column_count.to_f
22
+ padding = (@bar_width * (1 - @bar_spacing)) / 2
23
+
24
+ @d = @d.stroke_opacity 0.0
25
+
26
+ height = Array.new(@column_count, 0)
27
+
28
+ @norm_data.each_with_index do |data_row, row_index|
29
+ data_row[DATA_VALUES_INDEX].each_with_index do |data_point, point_index|
30
+ @d = @d.fill data_row[DATA_COLOR_INDEX]
31
+
32
+ # Calculate center based on bar_width and current row
33
+ label_center = @graph_left + (@bar_width * point_index) + (@bar_width * @bar_spacing / 2.0)
34
+ draw_label(label_center, point_index)
35
+
36
+ next if (data_point == 0)
37
+ # Use incremented x and scaled y
38
+ left_x = @graph_left + (@bar_width * point_index) + padding
39
+ left_y = @graph_top + (@graph_height -
40
+ data_point * @graph_height -
41
+ height[point_index]) + 1
42
+ right_x = left_x + @bar_width * @bar_spacing
43
+ right_y = @graph_top + @graph_height - height[point_index] - 1
44
+
45
+ # update the total height of the current stacked bar
46
+ height[point_index] += (data_point * @graph_height )
47
+
48
+ @d = @d.rectangle(left_x, left_y, right_x, right_y)
49
+
50
+ end
51
+
52
+ end
53
+
54
+ @d.draw(@base_image)
55
+ end
56
+
57
+ end