<?xml version="1.0" encoding="UTF-8" ?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at
  
      http://www.apache.org/licenses/LICENSE-2.0
    	  
  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an
  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, either express or implied.  See the License for the
  specific language governing permissions and limitations
  under the License.
  
-->
<!---
    @access public
    @topic Components
    @subtopic Charts
  -->
<library>
    
    <!---
          A pie chart represents a chart that is displayed in the 2D
          polar plane. This class inherits immediately from chart class
          and can be instantiated directly. (Warning: Of beta quality.)
          @access public
          -->
    <class name="ompiechart" extends="chart">

        <!--- @keywords private -->
        <method name="init">
            plotarea = this.getNodeOfClass("piechartplotarea");
            _datalabelpool = this.createLabelViewspool();
            super.init();            
        </method>  
        
        <!--- Renders the plot area which is an instance of the piechartplotarea 
              class. The plot area requires to read a group of two data series, one
              for the groups that are represented by the pie slices and the second
              for their values. -->
        <method name="renderPlotArea">
        <![CDATA[
            super.renderPlotArea();
            plotarea.clear();

            var topseries = this.getOMDataSeries();
            
            //var numSeries = topseries.getNumDataSeries();
            var numSeries = 1;
            
            var xseries = topseries.xseries;
            var yseries = topseries.yseries;
            var tooltipseries = topseries.tooltipseries;
                                
            for(var i = 0; i < numSeries; i++)
            {
                plotarea.renderSeries(xseries, yseries, tooltipseries);          
            }
            if ( this.datalabelEnabled ){
                this.renderDataLabels();
            }

        ]]>
        </method>
        
        <!--- Renders the labels that display the values of the data series. -->
        <method name="renderDataLabels">
        
            <![CDATA[
                _datalabelpool.reclaimAll();
            
                var arrPiePieces = this.plotarea.arrPiePieces;
                var topseries = this.getOMDataSeries();
                
                var xseries = topseries.xseries;
                var yseries = topseries.yseries;
                var tooltipseries = topseries.tooltipseries;
                
                if ($debug) Debug.write("arrPiePieces.length ",arrPiePieces.length);

                for(var i = 0; i < arrPiePieces.length; i++){ 
                    piePiece = arrPiePieces[i];  
                    
                    var lbl = _datalabelpool.getView();
                    var ldatastyle = piePiece.style;
                    lbl.setAttribute('style', ldatastyle.label);
                    lbl.render(yseries[i]);
                    piePiece.renderLabel(lbl);
                }
            ]]>
                
        </method>
        
        <!--- The plot area where the pie slices are rendered -->
        <piechartplotarea name="plotarea" x="50" y="20" width="500" height="300">
        	
        </piechartplotarea>

    </class>
    
</library> 
