
#==============================================================================#
# $Id: chart.rb,v 1.3 2004/01/23 04:47:45 yuya Exp $
# $Source: /cvsroot/gruby/gruby/lib/grb/chart/pie_base/chart.rb,v $
#==============================================================================#

require 'grb/chart/base/chart'
require 'grb/chart/base/utility/text'
require 'grb/math_ex'

#==============================================================================#

module GRb

  module Chart

    class PieChartBase < ChartBase

      def initialize(property)
        super(property)
        @values = []
      end

      def calculate_box(box, stretch)
        dx = (stretch ? box.dx : [box.dx, box.dy].min) # width of drawing area
        dy = (stretch ? box.dy : [box.dx, box.dy].min) # height of drawing area
        rx = dx / 2.0                                  # radius of circle(x)
        ry = dy / 2.0                                  # radius of circle(y)
        cx = box.x + box.dx / 2.0                      # center of circle(x)
        cy = box.y + box.dy / 2.0                      # center of circle(y)
        return [dx, dy, rx, ry, cx, cy]
      end
      protected :calculate_box

      def calculate_total(data)
         return data.inject(0) { |sum, item|
           sum + item.value
         }
      end
      protected :calculate_total

      def calculate_ratio(data, total)
        return data.collect { |value|
          Ratio.new(value, value.value.to_f / total * 360)
        }
      end
      protected :calculate_ratio

      def draw_label(image, cx, cy, rx, ry, angle, text)
        length1    = @property.label.line.length1
        length2    = @property.label.line.length2
        line_color = @property.label.line.color
        font       = @property.label.font.create_font
        spacing    = 4

        e1 = length1 - MathEx.sin(angle).abs * length1
        e2 = length2

        ex0 = cx + MathEx.cos(angle - 90) * rx
        ey0 = cy + MathEx.sin(angle - 90) * ry
        ex1 = cx + MathEx.cos(angle - 90) * (rx + e1)
        ey1 = cy + MathEx.sin(angle - 90) * (ry + e1)

        case angle % 360
        when 0...180
          ex2   = cx + rx + e2
          ey2   = ey1
          lx    = spacing
          align = GRb::Font::ALIGN_LEFT
        when 180...360
          ex2   = cx - rx - e2
          ey2   = ey1
          lx    = -spacing
          align = GRb::Font::ALIGN_RIGHT
        else
          raise 'bug?'
        end

        image.line(ex0, ey0, ex1, ey1, line_color)
        image.line(ex1, ey1, ex2, ey2, line_color)
        font.draw(image, ex2 + lx, ey2, text, align, GRb::Font::VALIGN_MIDDLE)
      end
      protected :draw_label

      def add_value(name, value, color)
        @values << Value.new(name, value, color)
      end

      class Value

        def initialize(name, value, color)
          @name  = name
          @value = value
          @color = color
        end

        attr_accessor :name, :value, :color

        def <=>(other)
          return @value <=> other.value
        end

      end # Value

      class Ratio

        def initialize(value, ratio)
          @value = value
          @ratio = ratio
        end

        attr_reader :value, :ratio

        def <=>(other)
          return @ratio <=> other.ratio
        end

      end # Raito

    end # PieChartBase

  end # Chart

end # GRb

#==============================================================================#
#==============================================================================#
