Class: Charts::PieChart

Inherits:
Chart
  • Object
show all
Includes:
Legend
Defined in:
lib/charts/pie_chart/pie_chart.rb

Instance Attribute Summary collapse

Attributes inherited from Chart

#data, #options, #prepared_data, #renderer

Instance Method Summary collapse

Methods included from Legend

#draw_labels, #label_rows, #label_total_height

Methods inherited from Chart

#create_options_methods, #draw_background, #draw_title, #initialize, #initialize_instance_variables, #post_draw, #render, #validate_array_and_count

Constructor Details

This class inherits a constructor from Charts::Chart

Instance Attribute Details

#sub_sumsObject (readonly)

Returns the value of attribute sub_sums.



4
5
6
# File 'lib/charts/pie_chart/pie_chart.rb', line 4

def sub_sums
  @sub_sums
end

#sumObject (readonly)

Returns the value of attribute sum.



4
5
6
# File 'lib/charts/pie_chart/pie_chart.rb', line 4

def sum
  @sum
end

Instance Method Details

#center_xObject



63
64
65
# File 'lib/charts/pie_chart/pie_chart.rb', line 63

def center_x
  outer_margin + inner_width / 2
end

#center_yObject



67
68
69
# File 'lib/charts/pie_chart/pie_chart.rb', line 67

def center_y
  outer_margin + inner_height / 2
end

#default_optionsObject



14
15
16
17
18
19
20
21
22
23
# File 'lib/charts/pie_chart/pie_chart.rb', line 14

def default_options
  super.merge(
    width:        600,
    height:       400,
    label_height: 20,
    label_margin: 10,
    explode:      nil,
    border_width: 2
  )
end

#drawObject



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/charts/pie_chart/pie_chart.rb', line 37

def draw
  prepared_data.length.times do |i|
    start_deg = Math::PI * 2 * sub_sums[i]
    end_deg = Math::PI * 2 * sub_sums[i + 1]
    middle_deg = (start_deg + end_deg) / 2
    expl = explode ? explode[i] : 0
    middle_x = center_x + expl * Math.sin(middle_deg)
    middle_y = center_y - expl * Math.cos(middle_deg)
    start_x = middle_x + radius * Math.sin(start_deg)
    start_y = middle_y - radius * Math.cos(start_deg)
    end_x = middle_x + radius * Math.sin(end_deg)
    end_y = middle_y - radius * Math.cos(end_deg)
    more_than_half = prepared_data[i] > 0.5 ? 1 : 0
    path = "M#{middle_x} #{middle_y}
            L#{start_x} #{start_y}
            A#{radius} #{radius} 0 #{more_than_half} 1 #{end_x} #{end_y}
            L#{middle_x} #{middle_y}
            "
    renderer.path(path, fill: colors[i], stroke: background_color, stroke_width: border_width)
  end
end

#inner_heightObject



75
76
77
# File 'lib/charts/pie_chart/pie_chart.rb', line 75

def inner_height
  height - 2 * outer_margin - label_total_height
end

#inner_widthObject



71
72
73
# File 'lib/charts/pie_chart/pie_chart.rb', line 71

def inner_width
  width - 2 * outer_margin
end

#pre_drawObject



32
33
34
35
# File 'lib/charts/pie_chart/pie_chart.rb', line 32

def pre_draw
  super
  draw_labels
end

#prepare_dataObject



25
26
27
28
29
30
# File 'lib/charts/pie_chart/pie_chart.rb', line 25

def prepare_data
  @sum = data.reduce 0, :+
  normalized_data = data.map { |value| value.to_f / sum }
  @sub_sums = (normalized_data.length + 1).times.map { |i| normalized_data.first(i).reduce 0.0, :+ }
  normalized_data
end

#radiusObject



59
60
61
# File 'lib/charts/pie_chart/pie_chart.rb', line 59

def radius
  [inner_width, inner_height].min / 2
end

#validate_arguments(data, options) ⇒ Object

Raises:

  • (ArgumentError)


7
8
9
10
11
12
# File 'lib/charts/pie_chart/pie_chart.rb', line 7

def validate_arguments(data, options)
  super(data, options)
  raise ArgumentError unless data.is_a? Array
  raise ArgumentError if options[:labels] && !options[:labels].empty? && options[:labels].count != data.count
  raise ArgumentError if options[:explode] && !options[:explode].empty? && options[:explode].count != data.count
end