2 require File.dirname(__FILE__) + '/base'
4 # Experimental!!! See also the Net graph.
6 # Submitted by Kevin Clark http://glu.ttono.us/
7 class Gruff::Spider < Gruff::Base
10 attr_reader :hide_text
11 attr_accessor :hide_axes
12 attr_reader :transparent_background
14 def transparent_background=(value)
15 @transparent_background = value
16 @base_image = render_transparent_background if value
20 @hide_title = @hide_text = value
23 def initialize(max_value, target_width = 800)
25 @max_value = max_value
30 @hide_line_markers = true
34 return unless @has_data
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
43 @unit_length = radius / @max_value
46 total_sum = sums_for_spider
48 additive_angle = (2 * Math::PI)/ @data.size
53 draw_axes(center_x, center_y, radius, additive_angle) unless hide_axes
56 draw_polygon(center_x, center_y, additive_angle)
64 def normalize_points(value)
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))
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,
88 def draw_axes(center_x, center_y, radius, additive_angle, line_color = nil)
93 @data.each do |data_row|
94 @d.stroke(line_color || data_row[DATA_COLOR_INDEX])
97 x_offset = radius * Math.cos(current_angle)
98 y_offset = radius * Math.sin(current_angle)
100 @d.line(center_x, center_y,
104 draw_label(center_x, center_y, current_angle, radius, data_row[0].to_s) unless hide_text
106 current_angle += additive_angle
110 def draw_polygon(center_x, center_y, additive_angle, color = nil)
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)
116 current_angle += additive_angle
120 @d.stroke(color || @marker_color)
121 @d.fill(color || @marker_color)
127 @data.inject(0.0) {|sum, data_row| sum += data_row[1][0]}