Class Gruff::Pie
In: lib/gruff/pie.rb
Parent: Gruff::Base
StackedMixin StackedBar SideStackedBar StackedArea AccumulatorBar Base Scene Pie Area PhotoBar Spider SideBar Net Bar Line Pie Observable Group SideBar StandardError IncorrectNumberOfDatasetsException Magick Bar Layer BarConversion lib/gruff/stacked_area.rb lib/gruff/scene.rb lib/gruff/spider.rb lib/gruff/pie.rb lib/gruff/area.rb lib/gruff/net.rb lib/gruff/bar_conversion.rb lib/gruff/bar.rb lib/gruff/side_bar.rb lib/gruff/line.rb lib/gruff/stacked_bar.rb lib/gruff/side_stacked_bar.rb lib/gruff/photo_bar.rb lib/gruff/base.rb lib/gruff/accumulator_bar.rb lib/gruff/mini/bar.rb lib/gruff/mini/side_bar.rb lib/gruff/mini/pie.rb Legend Mini Deprecated Gruff dot/m_10_0.png

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.

Methods

Constants

TEXT_OFFSET_PERCENTAGE = 0.15

Attributes

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.

Public Instance methods

[Source]

    # 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

[Source]

    # File lib/gruff/pie.rb, line 22
22:   def initialize_ivars
23:     super
24:     @zero_degree = 0.0
25:   end

Private Instance methods

Labels are drawn around a slightly wider ellipse to give room for labels on the left and right.

[Source]

     # 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

[Source]

     # File lib/gruff/pie.rb, line 110
110:   def sums_for_pie
111:     total_sum = 0.0
112:     @data.collect {|data_row| total_sum += data_row[DATA_VALUES_INDEX][0] }
113:     total_sum
114:   end

[Validate]