| Class | Gruff::Pie |
| In: |
lib/gruff/pie.rb
|
| Parent: | Gruff::Base |
Here‘s how to make a Pie graph:
g = Gruff::Pie.new
g.title = "Visual Pie Graph Test"
g.data 'Fries', 20
g.data 'Hamburgers', 50
g.write("test/output/pie_keynote.png")
To control where the pie chart starts creating slices, use zero_degree.
| TEXT_OFFSET_PERCENTAGE | = | 0.15 |
| zero_degree | [RW] | Can be used to make the pie start cutting slices at the top (-90.0) or at another angle. Default is 0.0, which starts at 3 o‘clock. |
# File lib/gruff/pie.rb, line 27
27: def draw
28: @hide_line_markers = true
29:
30: super
31:
32: return unless @has_data
33:
34: diameter = @graph_height
35: radius = ([@graph_width, @graph_height].min / 2.0) * 0.8
36: top_x = @graph_left + (@graph_width - diameter) / 2.0
37: center_x = @graph_left + (@graph_width / 2.0)
38: center_y = @graph_top + (@graph_height / 2.0) - 10 # Move graph up a bit
39: total_sum = sums_for_pie()
40: prev_degrees = @zero_degree
41:
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)
44: data.each do |data_row|
45: if data_row[DATA_VALUES_INDEX][0] > 0
46: @d = @d.stroke data_row[DATA_COLOR_INDEX]
47: @d = @d.fill 'transparent'
48: @d.stroke_width(radius) # stroke width should be equal to radius. we'll draw centered on (radius / 2)
49:
50: current_degrees = (data_row[DATA_VALUES_INDEX][0] / total_sum) * 360.0
51:
52: # ellipse will draw the the stroke centered on the first two parameters offset by the second two.
53: # therefore, in order to draw a circle of the proper diameter we must center the stroke at
54: # half the radius for both x and y
55: @d = @d.ellipse(center_x, center_y,
56: radius / 2.0, radius / 2.0,
57: prev_degrees, prev_degrees + current_degrees + 0.5) # <= +0.5 'fudge factor' gets rid of the ugly gaps
58:
59: half_angle = prev_degrees + ((prev_degrees + current_degrees) - prev_degrees) / 2
60:
61: # Following line is commented to allow display of the percentiles
62: # bug appeared between r90 and r92
63: # unless @hide_line_markers then
64: # End the string with %% to escape the single %.
65: # RMagick must use sprintf with the string and % has special significance.
66: label_string = ((data_row[DATA_VALUES_INDEX][0] / total_sum) *
67: 100.0).round.to_s + '%%'
68: @d = draw_label(center_x,center_y, half_angle,
69: radius + (radius * TEXT_OFFSET_PERCENTAGE),
70: label_string)
71: # end
72:
73: prev_degrees += current_degrees
74: end
75: end
76:
77: # TODO debug a circle where the text is drawn...
78:
79: @d.draw(@base_image)
80: end
Labels are drawn around a slightly wider ellipse to give room for labels on the left and right.
# File lib/gruff/pie.rb, line 87
87: def draw_label(center_x, center_y, angle, radius, amount)
88: # TODO Don't use so many hard-coded numbers
89: r_offset = 20.0 # The distance out from the center of the pie to get point
90: x_offset = center_x # + 15.0 # The label points need to be tweaked slightly
91: y_offset = center_y # This one doesn't though
92: radius_offset = (radius + r_offset)
93: ellipse_factor = radius_offset * 0.15
94: x = x_offset + ((radius_offset + ellipse_factor) * Math.cos(angle.deg2rad))
95: y = y_offset + (radius_offset * Math.sin(angle.deg2rad))
96:
97: # Draw label
98: @d.fill = @font_color
99: @d.font = @font if @font
100: @d.pointsize = scale_fontsize(@marker_font_size)
101: @d.stroke = 'transparent'
102: @d.font_weight = BoldWeight
103: @d.gravity = CenterGravity
104: @d.annotate_scaled( @base_image,
105: 0, 0,
106: x, y,
107: amount, @scale)
108: end