### Home Classes Methods

### In Files

- lib/SVG/Graph/Pie.rb

### Parent

SVG::Graph

### Methods

- #add_data
- #add_defs
- #draw_data
- #draw_graph
- #get_css
- #get_x_labels
- #get_y_labels
- #keys
- #round
- #set_defaults

### Class/Module Index

Quicksearch

- SVG
- SVG::Graph
- SVG::Graph::Bar
- SVG::Graph::BarBase
- SVG::Graph::BarHorizontal
- SVG::Graph::Graph
- SVG::Graph::Line
- SVG::Graph::Pie
- SVG::Graph::Plot
- SVG::Graph::Schedule
- SVG::Graph::TimeSeries
- DataPoint
- Object

No matching classes.

# SVG::Graph::Pie

### Create presentation quality SVG pie graphs easily

## Synopsis

    require 'SVG/Graph/Pie'

    fields = %w(Jan Feb Mar)
    data_sales_02 = [12, 45, 21]

    graph = SVG::Graph::Pie.new({
            :height => 500,
      :width  => 300,
      :fields => fields,
    })

    graph.add_data({
            :data => data_sales_02,
      :title => 'Sales 2002',
    })

    print "Content-type: image/svg+xml\r\n\r\n"
    print graph.burn();

## Description

This object aims to allow you to easily create high quality SVG pie graphs. You can either use the default style sheet or supply your own. Either way there are many options which can be configured to give you control over how the graph is generated - with or without a key, display percent on pie chart, title, subtitle etc.

# Examples

www.germane-software/repositories/public/SVG/test/single.rb

## See also

- SVG::Graph::Graph

- SVG::Graph::BarHorizontal

- SVG::Graph::Bar

- SVG::Graph::Line

- SVG::Graph::Plot

- SVG::Graph::TimeSeries

## Author

Sean E. Russell <serATgermaneHYPHENsoftwareDOTcom>

Copyright 2004 Sean E. Russell This software is available under the Ruby license

### Constants

RADIANS

### Attributes

datapoint_font_size[RW]

The font size of the data point labels

expand_gap[RW]

The amount of space between expanded wedges

expand_greatest[RW]

If true, expand the largest pie wedge

expanded[RW]

If true, "explode" the pie (put space between the wedges)

shadow_offset[RW]

Sets the offset of the shadow from the pie chart

show_actual_values[RW]

If true, display the actual field values in the data labels

show_data_labels[RW]

If true, display the data labels on the chart

show_key_actual_values[RW]

If true, display the actual value of the field in the key

show_key_data_labels[RW]

If true, display the labels in the key

show_key_percent[RW]

If true, display the percentage value of the wedges in the key

show_percent[RW]

If true, display the percentage value of each pie wedge in the data labels

show_shadow[RW]

If true, displays a drop shadow for the chart

### Public Instance Methods

add_data(arg) click to toggle source

Adds a data set to the graph.

    graph.add_data( { :data => [1,2,3,4] } )

Note that the :title is not necessary. If multiple data sets are added to the graph, the pie chart will display the `sums` of the data. EG:

    graph.add_data( { :data => [1,2,3,4] } )
    graph.add_data( { :data => [2,3,5,9] } )

is the same as:

    graph.add_data( { :data => [3,5,8,13] } )

    # File lib/SVG/Graph/Pie.rb, line 111
    def add_data arg
      arg[:data].each_index {|idx|
        @data[idx] = 0 unless @data[idx]
        @data[idx] += arg[:data][idx]
      }
    end

set_defaults() click to toggle source

Defaults are those set by Graph::initialize, and

show_shadow

  true

shadow_offset

  10

show_data_labels

  false

show_actual_values

  false

show_percent

  true

show_key_data_labels

  true

show_key_actual_values

  true

show_key_percent

  false

expanded

  false

expand_greatest

  false

expand_gap

  10

show_x_labels

  false

show_y_labels

  false

datapoint_font_size

  12

    # File lib/SVG/Graph/Pie.rb, line 73
    def set_defaults
      init_with(
        :show_shadow                  => true,
        :shadow_offset                => 10,

        :show_data_labels           => false,
        :show_actual_values     => false,
        :show_percent                 => true,

        :show_key_data_labels   => true,
        :show_key_actual_values => true,
        :show_key_percent                 => false,

        :expanded                                     => false,
        :expand_greatest                  => false,
        :expand_gap             => 10,

        :show_x_labels          => false,
        :show_y_labels          => false,
        :datapoint_font_size    => 12
      )
      @data = []
    end

### Protected Instance Methods

add_defs(defs) click to toggle source

    # File lib/SVG/Graph/Pie.rb, line 147
    def add_defs defs
      gradient = defs.add_element( "filter", {
        "id"=>"dropshadow",
        "width" => "1.2",
        "height" => "1.2",
      } )
      gradient.add_element( "feGaussianBlur", {
        "stdDeviation" => "4",
        "result" => "blur"
      })
    end

draw_data() click to toggle source

    # File lib/SVG/Graph/Pie.rb, line 187
    def draw_data
      @graph = @root.add_element( "g" )
      background = @graph.add_element("g")
      midground = @graph.add_element("g")

      diameter = @graph_height > @graph_width ? @graph_width : @graph_height
      diameter -= expand_gap if expanded or expand_greatest
      diameter -= datapoint_font_size if show_data_labels
      diameter -= 10 if show_shadow
      radius = diameter / 2.0

      xoff = (width - diameter) / 2
      yoff = (height - @border_bottom - diameter)
      yoff -= 10 if show_shadow
      @graph.attributes['transform'] = "translate( #{xoff} #{yoff} )"

      wedge_text_pad = 5
      wedge_text_pad = 20 if show_percent and show_data_labels

      total = 0
      max_value = 0
      @data.each {|x|
        max_value = max_value < x ? x : max_value
        total += x
      }
      percent_scale = 100.0 / total

      prev_percent = 0
      rad_mult = 3.6 * RADIANS
      @config[:fields].each_index { |count|
        value = @data[count]
        percent = percent_scale * value

        radians = prev_percent * rad_mult
        x_start = radius+(Math.sin(radians) * radius)
        y_start = radius-(Math.cos(radians) * radius)
        radians = (prev_percent+percent) * rad_mult
        x_end = radius+(Math.sin(radians) * radius)
        x_end -= 0.00001 if @data.length == 1
        y_end = radius-(Math.cos(radians) * radius)
        path = "M#{radius},#{radius} L#{x_start},#{y_start} "+
          "A#{radius},#{radius} "+
          "0, #{percent >= 50 ? '1' : '0'},1, "+
          "#{x_end} #{y_end} Z"

        wedge = @foreground.add_element( "path", {
          "d" => path,
          "class" => "fill#{count+1}"
        })

        translate = nil
        tx = 0
        ty = 0
        half_percent = prev_percent + percent / 2
        radians = half_percent * rad_mult

        if show_shadow
          shadow = background.add_element( "path", {
            "d" => path,
            "filter" => "url(#dropshadow)",
            "style" => "fill: #ccc; stroke: none;"
          })
          clear = midground.add_element( "path", {
            "d" => path,
            "style" => "fill: #fff; stroke: none;"
          })
        end

        if expanded or (expand_greatest && value == max_value)
          tx = (Math.sin(radians) * expand_gap)
          ty = -(Math.cos(radians) * expand_gap)
          translate = "translate( #{tx} #{ty} )"
          wedge.attributes["transform"] = translate
          clear.attributes["transform"] = translate if clear
        end

        if show_shadow
          shadow.attributes["transform"] =
            "translate( #{tx+shadow_offset} #{ty+shadow_offset} )"
        end

        if show_data_labels and value != 0
          label = ""
          label += @config[:fields][count] if show_key_data_labels
          label += " ["+value.to_s+"]" if show_actual_values
          label += " "+percent.round.to_s+"%" if show_percent

          msr = Math.sin(radians)
          mcr = Math.cos(radians)
          tx = radius + (msr * radius)
          ty = radius - (mcr * radius)

          if expanded or (expand_greatest && value == max_value)
            tx += (msr * expand_gap)
            ty -= (mcr * expand_gap)
          end
          @foreground.add_element( "text", {
            "x" => tx.to_s,
            "y" => ty.to_s,
            "class" => "dataPointLabel",
            "style" => "stroke: #fff; stroke-width: 2;"
          }).text = label.to_s
          @foreground.add_element( "text", {
            "x" => tx.to_s,
            "y" => ty.to_s,
            "class" => "dataPointLabel",
          }).text = label.to_s
        end

        prev_percent += percent
      }
    end

draw_graph() click to toggle source

We don't need the graph

    # File lib/SVG/Graph/Pie.rb, line 160
    def draw_graph
    end

get_css() click to toggle source

    # File lib/SVG/Graph/Pie.rb, line 308
    def get_css
      return .dataPointLabel{        fill: #000000;        text-anchor:middle;        font-size: #{datapoint_font_size}px;        font-family: "Arial", sans-serif;        font-weight: normal;}/* key - MUST match fill styles */.key1,.fill1{        fill: #ff0000;        fill-opacity: 0.7;        stroke: none;        stroke-width: 1px;     }.key2,.fill2{        fill: #0000ff;        fill-opacity: 0.7;        stroke: none;        stroke-width: 1px;     }.key3,.fill3{        fill-opacity: 0.7;        fill: #00ff00;        stroke: none;        stroke-width: 1px;     }.key4,.fill4{        fill-opacity: 0.7;        fill: #ffcc00;        stroke: none;        stroke-width: 1px;     }.key5,.fill5{        fill-opacity: 0.7;        fill: #00ccff;        stroke: none;        stroke-width: 1px;     }.key6,.fill6{        fill-opacity: 0.7;        fill: #ff00ff;        stroke: none;        stroke-width: 1px;     }.key7,.fill7{        fill-opacity: 0.7;        fill: #00ff99;        stroke: none;        stroke-width: 1px;     }.key8,.fill8{        fill-opacity: 0.7;        fill: #ffff00;        stroke: none;        stroke-width: 1px;     }.key9,.fill9{        fill-opacity: 0.7;        fill: #cc6666;        stroke: none;        stroke-width: 1px;     }.key10,.fill10{        fill-opacity: 0.7;        fill: #663399;        stroke: none;        stroke-width: 1px;     }.key11,.fill11{        fill-opacity: 0.7;        fill: #339900;        stroke: none;        stroke-width: 1px;     }.key12,.fill12{        fill-opacity: 0.7;        fill: #9966FF;        stroke: none;        stroke-width: 1px;     }
    end

get_x_labels() click to toggle source

    # File lib/SVG/Graph/Pie.rb, line 167
    def get_x_labels
      [""]
    end

get_y_labels() click to toggle source

    # File lib/SVG/Graph/Pie.rb, line 163
    def get_y_labels
      [""]
    end

keys() click to toggle source

    # File lib/SVG/Graph/Pie.rb, line 171
    def keys
      total = 0
      #max_value = 0
      @data.each {|x| total += x }
      percent_scale = 100.0 / total
      count = -1
      @config[:fields].collect{ |x|
        count += 1
        v = @data[count]
        perc = show_key_percent ? " "+(v * percent_scale).round.to_s+"%" : ""
        x + " [" + v.to_s + "]" + perc
      }
    end

round(val, to) click to toggle source

    # File lib/SVG/Graph/Pie.rb, line 302
    def round val, to
      up = 10**to.to_f
      (val * up).to_i / up
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.