fhs-gruff 0.3.6.2

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 +85 -0
  38. data/lib/gruff/bar_conversion.rb +46 -0
  39. data/lib/gruff/base.rb +1125 -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 +121 -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 +125 -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 +555 -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 +43 -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 +201 -0
@@ -0,0 +1,121 @@
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
+ draw_bars
17
+ end
18
+
19
+ protected
20
+
21
+ def draw_bars
22
+ # Setup spacing.
23
+ #
24
+ @bar_spacing ||= 0.9
25
+
26
+ @bars_width = @graph_height / @column_count.to_f
27
+ @bar_width = @bars_width / @norm_data.size
28
+ @d = @d.stroke_opacity 0.0
29
+ height = Array.new(@column_count, 0)
30
+ length = Array.new(@column_count, @graph_left)
31
+ padding = (@bar_width * (1 - @bar_spacing)) / 2
32
+
33
+ @norm_data.each_with_index do |data_row, row_index|
34
+ @d = @d.fill data_row[DATA_COLOR_INDEX]
35
+
36
+ data_row[DATA_VALUES_INDEX].each_with_index do |data_point, point_index|
37
+
38
+ # Using the original calcs from the stacked bar chart
39
+ # to get the difference between
40
+ # part of the bart chart we wish to stack.
41
+ temp1 = @graph_left + (@graph_width - data_point * @graph_width - height[point_index])
42
+ temp2 = @graph_left + @graph_width - height[point_index]
43
+ difference = temp2 - temp1
44
+
45
+ left_x = length[point_index] - 1
46
+ left_y = @graph_top + (@bars_width * point_index) + (@bar_width * row_index) + padding
47
+ right_x = left_x + difference
48
+ right_y = left_y + @bar_width * @bar_spacing
49
+
50
+ height[point_index] += (data_point * @graph_width)
51
+
52
+ @d = @d.rectangle(left_x, left_y, right_x, right_y)
53
+
54
+ # Calculate center based on bar_width and current row
55
+ label_center = @graph_top + (@bars_width * point_index + @bars_width / 2)
56
+ draw_label(label_center, point_index)
57
+ end
58
+
59
+ end
60
+
61
+ @d.draw(@base_image)
62
+ end
63
+
64
+ # Instead of base class version, draws vertical background lines and label
65
+ def draw_line_markers
66
+
67
+ return if @hide_line_markers
68
+
69
+ @d = @d.stroke_antialias false
70
+
71
+ # Draw horizontal line markers and annotate with numbers
72
+ @d = @d.stroke(@marker_color)
73
+ @d = @d.stroke_width 1
74
+ number_of_lines = 5
75
+
76
+ # TODO Round maximum marker value to a round number like 100, 0.1, 0.5, etc.
77
+ increment = significant(@spread.to_f / number_of_lines)
78
+ (0..number_of_lines).each do |index|
79
+
80
+ line_diff = (@graph_right - @graph_left) / number_of_lines
81
+ x = @graph_right - (line_diff * index) - 1
82
+ @d = @d.line(x, @graph_bottom, x, @graph_top)
83
+ diff = index - number_of_lines
84
+ marker_label = diff.abs * increment + @minimum_value
85
+
86
+ unless @hide_line_numbers
87
+ @d.fill = @font_color
88
+ @d.font = @font if @font
89
+ @d.stroke = 'transparent'
90
+ @d.pointsize = scale_fontsize(@marker_font_size)
91
+ @d.gravity = CenterGravity
92
+ # TODO Center text over line
93
+ @d = @d.annotate_scaled( @base_image,
94
+ 0, 0, # Width of box to draw text in
95
+ x, @graph_bottom + (LABEL_MARGIN * 2.0), # Coordinates of text
96
+ marker_label.to_s, @scale)
97
+ end # unless
98
+ @d = @d.stroke_antialias true
99
+ end
100
+ end
101
+
102
+ ##
103
+ # Draw on the Y axis instead of the X
104
+
105
+ def draw_label(y_offset, index)
106
+ if !@labels[index].nil? && @labels_seen[index].nil?
107
+ @d.fill = @font_color
108
+ @d.font = @font if @font
109
+ @d.stroke = 'transparent'
110
+ @d.font_weight = NormalWeight
111
+ @d.pointsize = scale_fontsize(@marker_font_size)
112
+ @d.gravity = EastGravity
113
+ @d = @d.annotate_scaled(@base_image,
114
+ 1, 1,
115
+ -@graph_left + LABEL_MARGIN * 2.0, y_offset,
116
+ @labels[index], @scale)
117
+ @labels_seen[index] = 1
118
+ end
119
+ end
120
+
121
+ 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
+ end
22
+
23
+ protected
24
+
25
+ def draw_bars
26
+ # Setup spacing.
27
+ #
28
+ # Columns sit stacked.
29
+ @bar_spacing ||= 0.9
30
+
31
+ @bar_width = @graph_height / @column_count.to_f
32
+ @d = @d.stroke_opacity 0.0
33
+ height = Array.new(@column_count, 0)
34
+ length = Array.new(@column_count, @graph_left)
35
+ padding = (@bar_width * (1 - @bar_spacing)) / 2
36
+
37
+ @norm_data.each_with_index do |data_row, row_index|
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
+ @d = @d.fill data_row[DATA_COLOR_INDEX]
49
+
50
+ left_x = length[point_index] #+ 1
51
+ left_y = @graph_top + (@bar_width * point_index) + padding
52
+ right_x = left_x + difference
53
+ right_y = left_y + @bar_width * @bar_spacing
54
+ length[point_index] += difference
55
+ height[point_index] += (data_point * @graph_width - 2)
56
+
57
+ @d = @d.rectangle(left_x, left_y, right_x, right_y)
58
+
59
+ # Calculate center based on bar_width and current row
60
+ label_center = @graph_top + (@bar_width * point_index) + (@bar_width * @bar_spacing / 2.0)
61
+ draw_label(label_center, point_index)
62
+ end
63
+
64
+ end
65
+
66
+ @d.draw(@base_image)
67
+ end
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