Вход Регистрация
Файл: IPBMafia.ru_IPB_3.4.6_Final_Rus _Nulled/board/upload/ips_kernel/classGraph.php
Строк: 1887
<?php

/**
 * Graph class.
 * This code was written by Remco Wilting (Wizzy) and used with permission in IP.Board.
 * Last Updated   : $Date: 2012-02-10 20:05:52 -0500 (Fri, 10 Feb 2012) $
 * Last Updated by: $Author: bfarber $
 *
 * @author         Remco Wilting
 * @copyright    (c) 2008 Remco Wilting
 * @package        IP.Board
 * @since        Sunday 6th July 2008 16:35
 * @version        $Revision: 10288 $
 */

//+---------------------------------------------------------------------------
// USAGE:
// $graph = new classGraph();
// $graph->options['title'] = 'test graph';
// $graph->options['width'] = 400;
// $graph->options['height'] = 300;
// $graph->options['style3D'] = 1;
// $graph->addLabels( array( 'alpha', 'beta', 'gamma' ) );
// $graph->addSeries( 'first bars', array( 5, 3, 0 ) );
// $graph->addSeries( 'second bars', array( 20, 3, 5 ) );
// $graph->options['charttype'] = 'Bar';
// $graph->display();
//+---------------------------------------------------------------------------


class classGraph
{
    
/**
     * Graph options array
     *
     * @var         array         Options array
     */
    
public $options            = array( 'titlecolor'        => '#000000',            // The color of the title
                                     
'title'            => 'График',                // The title text (no title of empty)
                                     
'titleshadow'        => '#AAAAAA',            // The shadowcolor of the title
                                     
'titlesize'        => 16,                    // The fontsize in points for the title
                                     
'width'            => 600,                    // The width of the graph image
                                     
'height'            => 400,                    // The height of the graph image
                                     
'charttype'        => 'Pie',                // The type of graph
                                     
'style3D'            => 1,                    // 3D style graph (yes/no)
                                     
'bgcolor'            => '#FFFFFF',            // Background color of the graph image
                                     
'textcolor'        => '#FFFFFF',            // Textcolor for data labels
                                     
'font'                => 'fonts/xsuni.ttf',    // Font file used (if TTF)
                                     
'xaxistitle'        => '',                    // Title for the x-axis (no title if empty)
                                     
'yaxistitle'        => '',                    // Title for the y-axis (no title if empty)
                                     
'showdatalabels'    => 1,                    // Display the datalabels (yes/no)
                                     
'showlegend'        => 1,                    // Display the legend (yes/no)
                                     
'maxlegendwidth'    => 20,                    // Percentage indicating the maximum width for the legend
                                     
'showgridlinesx'    => 1,                    // Show gridlines for the x-axis (yes/no)
                                     
'showgridlinesy'    => 1,                    // Show gridlines for the y-axis (yes/no)
                                     
'numticks'            => 5,                    // Number of ticks used for numeric axes,
                                     
'xaxisskip'        => 0,                    // Number of x-axis bars to skip before drawing next one (only implemented for line graphs so far)
                                   
);

    
/**
     * Enable Debug Mode
     *
     * @var         boolean         Enable Debug Mode
     */
    
protected $debug        0;

    
/**
     * Debug Timer
     *
     * @var         int             Debug Timer
     */
    
protected $starttime    0;

    
/**
     * Use TTF Fonts
     *
     * @var         boolean         Use TTF fonts
     */
    
protected $use_ttf        0;

    
/**
     * Graph data array
     *
     * @var         boolean         Graph data array
     */
    
protected $data            = array();

    
/**
     * Number of Y-axis data array's
     *
     * @var         int         Holds the number of y-axis data array's in $data
     */
    
protected $yaxis_count    0;

    
/**
     * Vertical size of the title
     *
     * @var         int         Holds the size of the title
     */
    
protected $titlesize    0;

    
/**
     * Pre-set colors
     *
     * @var         boolean         Holds pre-set colors
     */
    
protected $colors        = array( '80,120,200',
                                     
'160,80,160',
                                     
'0,120,80',
                                     
'240,160,60',
                                     
'40,160,240',
                                     
'200,100,100',
                                     
'100,200,100',
                                     
'240,200,100',
                                     
'60,60,160',
                                     
'240,240,100'
                                   
);

    
/**
     * Used colors
     *
     * @var         boolean         Holds used colors
     */
    
protected $used_colors    = array( => '0,0,0' );

    
/**
     * Current chart colors
     *
     * @var         boolean         Current chart colors
     */
    
protected $color        = array();

    
/**
     * Graph area positions
     *
     * @var         array             Positions of the grapharea (x0, x1, y0, y1)
     */
    
protected $grapharea    = array();

    
/**
     * Legend data store
     *
     * @var         array             Holds the legend names
     */
    
protected $legend        = array();

    
/**
     * X-Axis data store
     *
     * @var         array             Holds the specific data for the X-Axis
     */
    
protected $x_axis        = array();

    
/**
     * Y-Axis data store
     *
     * @var         array             Holds the specific data for the Y-Axis
     */
    
protected $y_axis        = array();

    
/**
     * Graph image resource
     *
     * @var         resource        Holds the graph image resource id
     */
    
protected $image        null;

    
/**
     * Fontsize of non-TTF fonts
     *
     * @var         int             The fontsize of non-TTF fonts
     */
    
protected $fontsize        3;

    
/**
     * Color resource for the color black
     *
     * @var         resource        Color resource for the color black
     */
    
protected $black        null;


    
/**
     * Constructor
     *
     * @param    boolean        [Optional] Enable Debug Mode
     * @return    @e void
    */
    
public function __construct$debug )
    {
        
$this->debug = ( $debug );

        if ( 
$this->debug )
        {
            
$mtime microtime ();
            
$mtime explode (' '$mtime);
            
$mtime $mtime[1] + $mtime[0];
            
$this->starttime $mtime;
        }
    }

    
/**
     * Add labels to the graph data
     *
     * @param    array        Array of data labels
     * @return    @e void
    */
    
public function addLabels$data = array() )
    {
        
$_cleanData    = array();
        
        foreach( 
$data as $k => $v )
        {
            if( !
defined('IPS_DOC_CHAR_SET') )
            {
                
define'IPS_DOC_CHAR_SET''' );
            }

            
$_cleanData$k ]    = @html_entity_decode$vENT_QUOTESIPS_DOC_CHAR_SET );
        }
        
        
$this->data['xaxis'] = $_cleanData;
    }

    
/**
     * Add a serie to the graph data
     *
     * @param    string        Name of the data series
     * @param    array        Array of data values
     * @param    string        Hex color code to use for this series
     * @return    @e void
     */
    
public function addSeries$name ''$data = array(), $color '' )
    {
        
$this->data['yaxis'][$this->yaxis_count]['name'] = $name;
        
$this->data['yaxis'][$this->yaxis_count]['data'] = $data;
        
$this->data['yaxis'][$this->yaxis_count]['color'] = $color;
        
$this->yaxis_count++;
    }

    
/**
     * Output the graph as png image
     *
     * @return    @e bool
     */
    
public function display()
    {
        
//-----------------------------------------
        // Check font
        //-----------------------------------------
        
if ( $this->options['font'] and is_readable$this->options['font'] ) and function_exists('imagettfbbox') )
        {
            
$this->use_ttf 1;
        }

        
//-----------------------------------------
        // Check pre-requisites width, height
        //-----------------------------------------
        
if ( $this->options['width'] < 400 or $this->options['height'] < 200 )
        {
            
$this->_error'Минимальная ширина графика - 400, а минимальная высота - 200.' );
            return 
false;
        }

        
//-----------------------------------------
        // Check supplied colors
        //-----------------------------------------
        
if ( !$this->_checkColor$this->options['titlecolor'] ) ||
             !
$this->_checkColor$this->options['titleshadow'] ) ||
             !
$this->_checkColor$this->options['bgcolor'] ) ||
             !
$this->_checkColor$this->options['textcolor'] ) )
        {
            return 
false;
        }

        
//-----------------------------------------
        // Determine graph area
        //-----------------------------------------
        
$this->grapharea = array( 'x0' => 5'x1' => $this->options['width'] - 5'y0' => 5'y1' => $this->options['height'] - );

        
//-----------------------------------------
        // Start GD process
        //-----------------------------------------
        
$this->image imagecreatetruecolor$this->options['width'], $this->options['height'] );

        if ( 
function_exists('imageantialias') )
        {
            @
imageantialias$this->imageTRUE );
        }

        
//-----------------------------------------
        // Allocate BG color and black
        //-----------------------------------------
        
$bgcolor imagecolorallocate($this->imagehexdec(substr($this->options['bgcolor'],1,2)), hexdec(substr($this->options['bgcolor'],3,2)), hexdec(substr($this->options['bgcolor'],5,2)));
        
imagefilledrectangle$this->image00$this->options['width'], $this->options['height'], $bgcolor );

        
$this->black imagecolorallocate$this->image00);

        
//-----------------------------------------
        // Draw the title
        //-----------------------------------------
        
$this->_drawTitle();

        
//-----------------------------------------
        // Draw the graph based on type
        //-----------------------------------------
        
switch ( $this->options['charttype'] )
        {
            case 
'Pie':
                if ( !
$this->_checkSeries1) ) return false;
                if ( !
$this->_drawPie() ) return false;
                break;
            case 
'Doughnut':
                if ( !
$this->_checkSeries1) ) return false;
                if ( !
$this->_drawDoughnut() ) return false;
                break;
            case 
'Bar':
                if ( !
$this->_checkSeries1) ) return false;
                if ( !
$this->_drawBars() ) return false;
                break;
            case 
'HBar':
                if ( !
$this->_checkSeries1) ) return false;
                if ( !
$this->_drawHorizontalBars() ) return false;
                break;
            case 
'Line':
                if ( !
$this->_checkSeries1) ) return false;
                if ( !
$this->_drawLines() ) return false;
                break;
            case 
'Area':
                if ( !
$this->_checkSeries1) ) return false;
                if ( !
$this->_drawArea() ) return false;
                break;
            case 
'XY':
                if ( !
$this->_checkSeries2) ) return false;
                if ( !
$this->_drawXY() ) return false;
                break;
            case 
'Bubble':
                if ( !
$this->_checkSeries3) ) return false;
                if ( !
$this->_drawBubble() ) return false;
                break;
            case 
'Funnel':
                if ( !
$this->_checkSeries1) ) return false;
                if ( !
$this->_drawFunnel() ) return false;
                break;
            case 
'Radar':
                if ( !
$this->_checkSeries1) ) return false;
                if ( !
$this->_drawRadar() ) return false;
                break;
            default:
                
$this->_error'Указан неизвестный тип графика ''.$this->options['charttype'].''.' );
                return 
false;
        }

        
//-----------------------------------------
        // Debug Mode?
        //-----------------------------------------
        
if ( $this->debug )
        {
            
$mtime microtime ();
            
$mtime explode (' '$mtime);
            
$mtime $mtime[1] + $mtime[0];
            
$endtime $mtime;
            
$totaltime sprintf"%.4f"round (($endtime $this->starttime), 5) ) . ' sec';

            if ( 
$this->use_ttf )
            {
                
$txtsize    imagettfbbox'10'0$this->options['font'], $totaltime );
                
$textx $this->options['width'] - ( $txtsize[4] - $txtsize[0] ) - 5;
                
$texty + ( $txtsize[1] - $txtsize[5] );
                
imagettftext($this->image"10"0$textx$texty$this->black  $this->options['font'], $totaltime );
                
imagerectangle$this->image$textx-5$texty+5$this->options['width']-10$this->black );
            }
            else
            {
                
$textx $this->options['width'] - imagefontwidth($this->fontsize)*strlen($totaltime) - 5;
                
$texty 5;
                
ImageString$this->image$this->fontsize$textx$texty$totaltime$this->black);
                
imagerectangle$this->image$textx-5$texty+5+imagefontheight($this->fontsize), $this->options['width']-10$this->black );
            }
        }

        
//-----------------------------------------
        // Flush image
        //-----------------------------------------
        
header('Content-type: image/png');
        
imagepng($this->image);
        
imagedestroy($this->image);

        return 
true;
    }

    
/**
     * Draw the graph title
     *
     * @return    @e void
     */
    
protected function _drawTitle()
    {
        if ( 
$this->options['title'] != '' )
        {
            
//-----------------------------------------
            // Allocate text and shadow cols
            //-----------------------------------------

            
$textcolor   imagecolorallocate$this->imagehexdec(substr($this->options['titlecolor'],1,2)), hexdec(substr($this->options['titlecolor'],3,2)), hexdec(substr($this->options['titlecolor'],5,2)));
            
$shadowcolor imagecolorallocate$this->imagehexdec(substr($this->options['titleshadow'],1,2)), hexdec(substr($this->options['titleshadow'],3,2)), hexdec(substr($this->options['titleshadow'],5,2)));

            
//-----------------------------------------
            // Generate title w/shadow
            //-----------------------------------------

            
if ( $this->use_ttf )
            {
                
$txtsize    imagettfbbox($this->options['titlesize'], 0$this->options['font'], $this->options['title'] );
                
$textx        round($this->options['width']/2,0) - round(($txtsize[2]-$txtsize[0])/2,0);
                
$texty        $txtsize[1] - $txtsize[5] + $this->grapharea['y0'];

                
imagettftext($this->image$this->options['titlesize'], 0$textx+1$texty+1$shadowcolor$this->options['font'], $this->options['title']);
                
imagettftext($this->image$this->options['titlesize'], 0$textx  $texty  $textcolor  $this->options['font'], $this->options['title']);

                
$this->grapharea['y0'] = $texty 10;
            }
            else
            {
                
$textx        round($this->options['width']/2,0) - round((imagefontwidth(5)*strlen($this->options['title']))/2,0);
                
$texty        $this->grapharea['y0'];

                
imagestring$this->image5$textx+1$texty+1$this->options['title'], $shadowcolor );
                
imagestring$this->image5$textx$texty$this->options['title'], $textcolor   );
                
$this->grapharea['y0'] = $texty imagefontheight(5) + 10;
            }
        }
    }

    
/**
     * Draw the legend
     *
     * @return    @e void
     */
    
protected function _drawLegend()
    {
        if ( 
$this->options['showlegend'] )
        {
            
//-----------------------------------------
            // Work out legend position
            //-----------------------------------------
            
$ci      0;
            
$legendx 0;
            
$legendy 0;
            
$maxtxty 10;
            
            
$maxlegendwidth = ( $this->grapharea['x1'] / 100 ) * $this->options['maxlegendwidth'];
                        
            
$lines = array();

            foreach ( 
$this->legend as $k => $name )
            {
                if ( 
$this->use_ttf )
                {
                    
$txtsize = array();
                    
$lines$k ] = explode"n"wordwrap$nameceil( ( $maxlegendwidth 10 ) / imagefontwidth($this->fontsize) ) ) );
                    foreach ( 
$lines$k ] as $line )
                    {
                        
$_txtsize imagettfbbox('10'0$this->options['font'], $line );
                        if ( 
$_txtsize[2]-$_txtsize[0] > $txtsize[2]-$txtsize[0] )
                        {
                            
$txtsize $_txtsize;
                        }
                    }
                    
                    
$legendx = ($txtsize[2]-$txtsize[0]) > $legendx ?  $txtsize[2]-$txtsize[0]  : $legendx;                    
                    
$maxtxty = ($txtsize[1]-$txtsize[7]) > $maxtxty ? ($txtsize[1]-$txtsize[7]) : $maxtxty;
                }
                else
                {
                    
$txtsize strlen$name ) * imagefontwidth($this->fontsize);
                    
$txtsize = ( $txtsize $maxlegendwidth ) ? $maxlegendwidth $txtsize;
                    
$legendx = ($txtsize $legendx) ?  $txtsize $legendx;
                    
$maxtxty imagefontheight($this->fontsize);
                    
$lines$k ] = explode"n"wordwrap$nameceil( ( $maxlegendwidth 10 ) / imagefontwidth($this->fontsize) ) ) );
                }

                
$ci ++;

            }
                                    
            
$legendx $this->grapharea['x1'] - ($legendx 25);
            
$legendy round( ($this->options['height'] / 2) - ((($maxtxty+5) * $ci) / 2) );

            
//-----------------------------------------
            // Do shade
            //-----------------------------------------

            
$textcolor   imagecolorallocate$this->image00);
            
$shadowcolor imagecolorallocate$this->image170170170);
            
$ypos        $legendy;
            
$ci          0;
            
$color       = array();

            
//-----------------------------------------
            // Draw legends
            //-----------------------------------------

            
foreach ( $this->legend as $k => $name )
            {
                
//-----------------------------------------
                // Get Pie slice colors
                //-----------------------------------------
                
if ( isset( $this->data['yaxis'][$ci]['color'] ) && $this->data['yaxis'][$ci]['color'] != '' &&
                     
$this->options['charttype'] != 'Pie' && $this->options['charttype'] != 'Doughnut' && $this->options['charttype'] != 'Funnel' )
                {
                    if ( !
$this->_checkColor$this->data['yaxis'][$ci]['color'] ) ) return false;
                    if ( !isset( 
$this->color$ci ] ) ) $this->color$ci ] = explode","$this->_getSliceColor$this->data['yaxis'][$ci]['color'] ) );
                }
                else
                {
                    if ( !isset( 
$this->color$ci ] ) ) $this->color$ci ] = explode","$this->_getSliceColor() );
                }

                
$color imagecolorallocate$this->image$this->color[$ci][0], $this->color[$ci][1], $this->color[$ci][2] );
                
imagefilledrectangle$this->image$legendx+5$ypos+7  $legendx+15 $ypos+17$color );
                
                foreach ( 
$lines$k ] as $line )
                {
                    if ( 
$this->use_ttf )
                    {
                        
$txty $ypos $maxtxty/2;
                        
imagettftext($this->image"10"0$legendx+20+1$txty+5+1$shadowcolor$this->options['font'], $line );
                        
imagettftext($this->image"10"0$legendx+20  $txty+5  $textcolor  $this->options['font'], $line );
                    }
                    else
                    {
                        
ImageString$this->image$this->fontsize$legendx+20 $ypos+7$line$this->black);
                    }
                    
                    
$ypos $ypos $maxtxty 5;
    
                    
imagecolordeallocate$this->image$color );
                   }
                   
$ci ++;
            }

            
imagerectangle$this->image$legendx$legendy$this->grapharea['x1']-1$ypos 5$textcolor );

            
$this->grapharea['x1'] = $legendx 5;
        }

        return 
true;
    }

    
/**
     * Draw X and Y axes
     *
     * @return    @e void
     */
    
protected function _drawAxes()
    {
        
//-----------------------------------------
        // Allocate text and shadow cols
        //-----------------------------------------
        
$textcolor   imagecolorallocate$this->imagehexdec(substr($this->options['titlecolor'],1,2)), hexdec(substr($this->options['titlecolor'],3,2)), hexdec(substr($this->options['titlecolor'],5,2)));
        
$shadowcolor imagecolorallocate$this->imagehexdec(substr($this->options['titleshadow'],1,2)), hexdec(substr($this->options['titleshadow'],3,2)), hexdec(substr($this->options['titleshadow'],5,2)));

        
//-----------------------------------------
        // Do we have axes titles?
        //-----------------------------------------
        
if ( $this->options['xaxistitle'] )
        {
            if ( 
$this->use_ttf )
            {
                
$txtsize imagettfbbox(100$this->options['font'], $this->options['xaxistitle'] );
                
$textx round( ( $this->grapharea['x1']-$this->grapharea['x0'] ) / 2) - round( ( $txtsize[4]-$txtsize[0] ) / 2);
                
$texty $this->grapharea['y1'];
                
imagettftext($this->image100$textx+1$texty+1$shadowcolor$this->options['font'], $this->options['xaxistitle'] );
                
imagettftext($this->image100$textx  $texty  $textcolor  $this->options['font'], $this->options['xaxistitle'] );
                
$this->grapharea['y1'] = $this->grapharea['y1'] - ( $txtsize[1] - $txtsize[5] ) - 5;
            }
            else
            {
                
$txtwidth imagefontwidth$this->fontsize ) * strlen$this->options['xaxistitle'] );
                
$textx round( ( $this->grapharea['x1']-$this->grapharea['x0'] ) / 2) - round$txtwidth 2);
                
$texty $this->grapharea['y1'] - imagefontheight($this->fontsize);
                
imagestring$this->image$this->fontsize$textx+1$texty+1$this->options['xaxistitle'], $shadowcolor );
                
imagestring$this->image$this->fontsize$textx$texty$this->options['xaxistitle'], $textcolor   );
                
$this->grapharea['y1'] = $this->grapharea['y1'] - imagefontheight($this->fontsize) - 5;
            }
        }

        if ( 
$this->options['yaxistitle'] )
        {
            if ( 
$this->use_ttf )
            {
                
$txtsize imagettfbbox(100$this->options['font'], $this->options['yaxistitle'] );
                
$textx $this->grapharea['x0'] + ( $txtsize[1] - $txtsize[5] );
                
$texty round( ( $this->grapharea['y1'] - $this->grapharea['y0'] ) / 2) + ( $txtsize[4] - $txtsize[0] );
                
imagettftext($this->image1090$textx+1$texty+1$shadowcolor$this->options['font'], $this->options['yaxistitle'] );
                
imagettftext($this->image1090$textx  $texty  $textcolor  $this->options['font'], $this->options['yaxistitle'] );
                
$this->grapharea['x0'] = $textx 5;
            }
            else
            {
                
$txtheight imagefontwidth$this->fontsize ) * strlen$this->options['yaxistitle'] );
                
$textx $this->grapharea['x0'];
                
$texty round( ( $this->grapharea['y1'] - $this->grapharea['y0'] ) / 2) + round$txtheight 2);
                
imagestringup$this->image$this->fontsize$textx+1$texty+1$this->options['yaxistitle'], $shadowcolor );
                
imagestringup$this->image$this->fontsize$textx$texty$this->options['yaxistitle'], $textcolor );
                
$this->grapharea['x0'] = $this->grapharea['x0'] + imagefontheight($this->fontsize) + 5;
            }
        }

        
//-----------------------------------------
        // Determine height of the x-axis
        //-----------------------------------------
        
$xaxisheight 0;
        if ( isset( 
$this->x_axis['type'] ) )
        {
            if ( 
$this->x_axis['type'] == 'numeric' )
            {
                if ( 
$this->use_ttf )
                {
                    
$txtsize     imagettfbbox(100$this->options['font'], $this->x_axis['max'] );
                    
$xaxisheight $txtsize[1]-$txtsize[5];
                }
                else
                {
                    
$xaxisheight imagefontheight($this->fontsize);
                }
            }
            else
            {
                
$xaxisheight 0;
                foreach( 
$this->x_axis['labels'] as $label )
                {
                    if ( 
$this->use_ttf )
                    {
                        
$textsize imagettfbbox(1045$this->options['font'], $label );
                        if ( (
$textsize[1] - $textsize[5]) > $xaxisheight $xaxisheight $textsize[1] - $textsize[5];
                    }
                    else
                    {
                        
$textsize imagefontwidth$this->fontsize ) * strlen$label );
                        if ( 
$textsize $xaxisheight $xaxisheight $textsize;
                    }
                }
            }
            
$xaxisheight += 8;
            
$this->grapharea['y1'] -= $xaxisheight;
        }

        
//-----------------------------------------
        // Determine width of the y-axis
        //-----------------------------------------
        
$yaxiswidth 0;
        if ( isset( 
$this->y_axis['type'] ) )
        {
            if ( 
$this->y_axis['type'] == 'numeric' )
            {
                if ( 
$this->use_ttf )
                {
                    
$txtsize    imagettfbbox(100$this->options['font'], $this->y_axis['max'] );
                    
$yaxiswidth $txtsize[2]-$txtsize[0];
                }
                else
                {
                    
$yaxiswidth imagefontwidth($this->fontsize) * strlen$this->y_axis['max'] );
                }
            }
            else
            {
                
$yaxiswidth 0;
                foreach( 
$this->y_axis['labels'] as $label )
                {
                    if ( 
$this->use_ttf )
                    {
                        
$textsize imagettfbbox(100$this->options['font'], $label );
                        if ( (
$textsize[2] - $textsize[0]) > $yaxiswidth $yaxiswidth $textsize[2] - $textsize[0];
                    }
                    else
                    {
                        
$textsize imagefontwidth$this->fontsize ) * strlen$label );
                        if ( 
$textsize $yaxiswidth $yaxiswidth $textsize;
                    }
                }
            }
            
$yaxiswidth += 8;
            
$this->grapharea['x0'] += $yaxiswidth;
        }

        
//-----------------------------------------
        // Determine 3D effect size (different for different graph types)
        //-----------------------------------------
        
$effect3DSize 0;
        
$numdepth 1;
        if ( 
$this->options['style3D'] == )
        {
            if ( 
$this->options['charttype'] == 'Line' )
            {
                
$effect3DSize 20;
                
$numdepth count$this->data['yaxis'] );
            }
            elseif ( 
$this->options['charttype'] == 'Area' )
            {
                
$effect3DSize 20;
            }
            elseif ( 
$this->options['charttype'] == 'HBar' )
            {
                
//calculate 1 bar height
                
$numbars count$this->data['yaxis'][0]['data'] );
                
$stepsize round( ( ( $this->grapharea['y1'] - $this->grapharea['y0'] - 20 ) / $numbars ) * 0.9);
                
$barheight round$stepsize count$this->data['yaxis'] ), );

                
$effect3DSize round$barheight 2) < 20 round$barheight 2) : 20;
            }
            elseif ( 
$this->options['charttype'] == 'Bar' )
            {
                
//calculate 1 bar width
                
$numbars count$this->data['yaxis'][0]['data'] );
                
$stepsize round( ( ( $this->grapharea['x1'] - $this->grapharea['x0'] - 20 ) / $numbars ) * 0.9);
                
$barwidth round$stepsize count$this->data['yaxis'] ), );

                
$effect3DSize round$barwidth 2) < 20 round$barwidth 2) : 20;
            }
            elseif ( 
$this->options['charttype'] == 'Funnel' )
            {
                
$effect3DSize 40;
            }
        }

        
$this->grapharea['x1'] -= $effect3DSize*$numdepth;
        
$this->grapharea['y0'] += $effect3DSize*$numdepth;

        
$depth $numdepth $effect3DSize;

        
//-----------------------------------------
        // Draw x-axis ticks & labels
        //-----------------------------------------
        
if ( isset( $this->x_axis['type'] ) )
        {
            if ( 
$this->y_axis['type'] == 'labels' )
            {
                
$numlabels count$this->y_axis['labels'] );
                
$stepheight floor( ( ( $this->grapharea['y1'] - $this->grapharea['y0'] ) / $numlabels ) );
                
$this->grapharea['y0'] = $this->grapharea['y1'] - $numlabels $stepheight;
            }

            if ( 
$this->x_axis['type'] == 'numeric' )
            {
                
// 0 - Labels
                
if ( $this->use_ttf )
                {
                    
$txtsize    imagettfbbox(100$this->options['font'], '0' );
                    
$textx $this->grapharea['x0'] - round( ( $txtsize[2]-$txtsize[0] ) / 20);
                    
$texty $txtsize[1]-$txtsize[5] + $this->grapharea['y1'] + 8;
                    
imagettftext($this->image100$textx+1$texty+1$shadowcolor$this->options['font'], '0' );
                    
imagettftext($this->image100$textx  $texty  $textcolor  $this->options['font'], '0' );
                }
                else
                {
                    
$txtwidth imagefontwidth$this->fontsize ) * strlen'0' );
                    
$textx $this->grapharea['x0'] - round$txtwidth 20);
                    
$texty $this->grapharea['y1'] + 8;
                    
imagestring$this->image$this->fontsize$textx+1$texty+1'0'$shadowcolor );
                    
imagestring$this->image$this->fontsize$textx$texty'0'$textcolor   );
                }

                
$numticks $this->options['numticks'] > $this->x_axis['max'] ? floor($this->x_axis['max']) : $this->options['numticks'];
                
$step floor$this->x_axis['max'] / $numticks );
                
$steps ceil$this->x_axis['max'] / $step );
                
$stepwidth = ( $this->grapharea['x1'] - $this->grapharea['x0'] ) / $steps;
                for ( 
$i 1$i <= $steps$i++ )
                {
                    
$value $i*$step;
                    
$x round( ( $value $step ) * $stepwidth $this->grapharea['x0'], 0);

                    
// Ticks
                    
imageline$this->image$x$this->grapharea['y1'], $x$this->grapharea['y1']+5$this->black );
                    if ( 
$depth )
                    {
                        
imageline$this->image$x$this->grapharea['y1'], $x+$depth$this->grapharea['y1']-$depth$this->black );
                    }
                    if ( 
$this->options['showgridlinesx'] )
                    {
                        
imageline$this->image$x+$depth$this->grapharea['y1']-$depth$x+$depth$this->grapharea['y0']-$depth$this->black );
                    }

                    
// Labels
                    
if ( $this->use_ttf )
                    {
                        
$txtsize    imagettfbbox(100$this->options['font'], $value );
                        
$textx $x round( ( $txtsize[2]-$txtsize[0] ) / 20);
                        
$texty $txtsize[1]-$txtsize[5] + $this->grapharea['y1'] + 8;
                        
imagettftext($this->image100$textx+1$texty+1$shadowcolor$this->options['font'], $value );
                        
imagettftext($this->image100$textx  $texty  $textcolor  $this->options['font'], $value );
                    }
                    else
                    {
                        
$txtwidth imagefontwidth$this->fontsize ) * strlen$value );
                        
$textx $x round$txtwidth 20);
                        
$texty $this->grapharea['y1'] + 8;
                        
imagestring$this->image$this->fontsize$textx+1$texty+1$value$shadowcolor );
                        
imagestring$this->image$this->fontsize$textx$texty$value$textcolor   );
                    }
                }
            }
            elseif ( 
$this->x_axis['type'] == 'ticklabels' )
            {
                
$numlabels count$this->x_axis['labels'] );
                
$stepwidth floor( ( ( $this->grapharea['x1'] - $this->grapharea['x0'] ) / ($numlabels 1) ) );
                
$this->grapharea['x1'] = $this->grapharea['x0'] + ($numlabels 1) * $stepwidth;

                for ( 
$i 0$i $numlabels$i++ )
                {
                    
$label $this->x_axis['labels'][$i];
                    
$x $i $stepwidth $this->grapharea['x0'];

                    
// Ticks
                    
imageline$this->image$x$this->grapharea['y1'], $x$this->grapharea['y1']+5$this->black );
                    if ( 
$depth )
                    {
                        
imageline$this->image$x$this->grapharea['y1'], $x+$depth$this->grapharea['y1']-$depth$this->black );
                    }
                    if ( 
$this->options['showgridlinesx'] )
                    {
                        
imageline$this->image$x+$depth$this->grapharea['y1']-$depth$x+$depth$this->grapharea['y0']-$depth$this->black );
                    }

                    
// Labels
                    
if ( $this->use_ttf )
                    {
                        
$txtsize    imagettfbbox(1045$this->options['font'], $label );
                        
$textx $x - ( $txtsize[4] - $txtsize[0] );
                        
$texty $txtsize[1]-$txtsize[5] + $this->grapharea['y1'] + 8;
                        
imagettftext($this->image1045$textx+1$texty+1$shadowcolor$this->options['font'], $label );
                        
imagettftext($this->image1045$textx  $texty  $textcolor  $this->options['font'], $label );
                    }
                    else
                    {
                        
$textx $x roundimagefontheight($this->fontsize) / 2);
                        
$texty       $this->grapharea['y1'] + imagefontwidth($this->fontsize)*strlen$label );
                        
imagestringup($this->image$this->fontsize$textx+1$texty+1$label $shadowcolor);
                        
imagestringup($this->image$this->fontsize$textx$texty$label $this->black);
                    }
                }
            }
            else
            {
                
$numlabels count$this->x_axis['labels'] );
                
$stepwidth floor( ( ( $this->grapharea['x1'] - $this->grapharea['x0'] ) / $numlabels ) );
                
$this->grapharea['x1'] = $this->grapharea['x0'] + $numlabels $stepwidth;


                for ( 
$i 0$i $numlabels$i++ )
                {
                    
$label $this->x_axis['labels'][$i];
                    
$x = ($i 1) * $stepwidth $this->grapharea['x0'];

                    
// Ticks
                    
imageline$this->image$x$this->grapharea['y1'], $x$this->grapharea['y1']+5$this->black );
                    if ( 
$depth )
                    {
                        
imageline$this->image$x$this->grapharea['y1'], $x+$depth$this->grapharea['y1']-$depth$this->black );
                    }
                    if ( 
$this->options['showgridlinesx'] )
                    {
                        
imageline$this->image$x+$depth$this->grapharea['y1']-$depth$x+$depth$this->grapharea['y0']-$depth$this->black );
                    }
        
                    if( 
$this->options['xaxisskip'] )
                    {
                        if( 
$i $this->options['xaxisskip'] != )
                        {
                            continue;
                        }
                    }

                    
// Labels
                    
if ( $this->use_ttf )
                    {
                        
$txtsize    imagettfbbox(1045$this->options['font'], $label );
                        
$textx $x round$stepwidth ) - ( $txtsize[4] - $txtsize[0] );
                        
$texty $txtsize[1]-$txtsize[5] + $this->grapharea['y1'] + 8;
                        
imagettftext($this->image1045$textx+1$texty+1$shadowcolor$this->options['font'], $label );
                        
imagettftext($this->image1045$textx  $texty  $textcolor  $this->options['font'], $label );
                    }
                    else
                    {
                        
$textx $x round$stepwidth ) - roundimagefontheight($this->fontsize) / 2);
                        
$texty       $this->grapharea['y1'] + imagefontwidth($this->fontsize)*strlen$label );
                        
imagestringup($this->image$this->fontsize$textx+1$texty+1$label $shadowcolor);
                        
imagestringup($this->image$this->fontsize$textx$texty$label $this->black);
                    }
                }
            }
        }

        
//-----------------------------------------
        // Draw y-axis ticks & labels
        //-----------------------------------------
        
if ( isset ( $this->y_axis['type'] ) )
        {
            if ( 
$this->y_axis['type'] == 'numeric' )
            {
                
// 0 - Labels
                
if ( $this->use_ttf )
                {
                    
$txtsize    imagettfbbox(100$this->options['font'], '0' );
                    
$textx $this->grapharea['x0'] - ( $txtsize[2]-$txtsize[0] ) - 8;
                    
$texty $this->grapharea['y1'] + round( ( $txtsize[1] - $txtsize[5] ) / 2);
                    
imagettftext($this->image100$textx+1$texty+1$shadowcolor$this->options['font'], '0' );
                    
imagettftext($this->image100$textx  $texty  $textcolor  $this->options['font'], '0' );
                }
                else
                {
                    
$txtwidth imagefontwidth$this->fontsize ) * strlen'0' );
                    
$textx $this->grapharea['x0'] - $txtwidth 8;
                    
$texty $this->grapharea['y1'] - round imagefontheight$this->fontsize ) / 20);
                    
imagestring$this->image$this->fontsize$textx+1$texty+1'0'$shadowcolor );
                    
imagestring$this->image$this->fontsize$textx$texty'0'$textcolor   );
                }

                
$numticks $this->options['numticks'] > $this->y_axis['max'] ? floor($this->y_axis['max']) : $this->options['numticks'];
                
$numticks $numticks $numticks 1;
                
$step floor$this->y_axis['max'] / $numticks );
                
$step $step $step 1;
                
$steps ceil$this->y_axis['max'] / $step );
                
$steps $steps $steps 1;
                
$stepheight = ( $this->grapharea['y1'] - $this->grapharea['y0'] ) / $steps;
                for ( 
$i 1$i <= $steps$i++ )
                {
                    
$value $i*$step;
                    
$y round$this->grapharea['y1'] - ( $value $step ) * $stepheight);

                    
// Ticks
                    
imageline$this->image$this->grapharea['x0'], $y$this->grapharea['x0']-5$y$this->black );
                    if ( 
$depth )
                    {
                        
imageline$this->image$this->grapharea['x0'], $y$this->grapharea['x0']+$depth$y-$depth$this->black );
                    }
                    if ( 
$this->options['showgridlinesy'] )
                    {
                        
imageline$this->image$this->grapharea['x0']+$depth$y-$depth$this->grapharea['x1']+$depth$y-$depth$this->black );
                    }

                    
// Labels
                    
if ( $this->use_ttf )
                    {
                        
$txtsize    imagettfbbox(100$this->options['font'], $value );
                        
$textx $this->grapharea['x0'] - ( $txtsize[2]-$txtsize[0] ) - 8;
                        
$texty $y round( ( $txtsize[1] - $txtsize[5] ) / 2);
                        
imagettftext($this->image100$textx+1$texty+1$shadowcolor$this->options['font'], $value );
                        
imagettftext($this->image100$textx  $texty  $textcolor  $this->options['font'], $value );
                    }
                    else
                    {
                        
$txtwidth imagefontwidth$this->fontsize ) * strlen$value );
                        
$textx $this->grapharea['x0'] - $txtwidth 8;
                        
$texty $y round imagefontheight$this->fontsize ) / 20);
                        
imagestring$this->image$this->fontsize$textx+1$texty+1$value$shadowcolor );
                        
imagestring$this->image$this->fontsize$textx$texty$value$textcolor   );
                    }
                }
            }
            else
            {
                
$numlabels count$this->y_axis['labels'] );
                
$stepheight floor( ( ( $this->grapharea['y1'] - $this->grapharea['y0'] ) / $numlabels ) );
                
$this->grapharea['y0'] = $this->grapharea['y1'] - $numlabels $stepheight;

                for ( 
$i 0$i $numlabels$i++ )
                {
                    
$label $this->y_axis['labels'][$i];
                    
$y $this->grapharea['y1'] - ($i 1) * $stepheight;

                    
// Ticks
                    
imageline$this->image$this->grapharea['x0'], $y$this->grapharea['x0']-5$y$this->black );
                    if ( 
$depth )
                    {
                        
imageline$this->image$this->grapharea['x0'], $y$this->grapharea['x0']+$depth$y-$depth$this->black );
                    }
                    if ( 
$this->options['showgridlinesy'] )
                    {
                        
imageline$this->image$this->grapharea['x0']+$depth$y-$depth$this->grapharea['x1']+$depth$y-$depth$this->black );
                    }

                    
// Labels
                    
if ( $this->use_ttf )
                    {
                        
$txtsize    imagettfbbox(100$this->options['font'], $label );
                        
$textx $this->grapharea['x0'] - ( $txtsize[4] - $txtsize[0] ) - 8;
                        
$texty $y round$stepheight );
                        
imagettftext($this->image100$textx+1$texty+1$shadowcolor$this->options['font'], $label );
                        
imagettftext($this->image100$textx  $texty  $textcolor  $this->options['font'], $label );
                    }
                    else
                    {
                        
$texty $y round$stepheight ) - roundimagefontheight($this->fontsize) / 2);
                        
$textx $this->grapharea['x0'] - imagefontwidth($this->fontsize)*strlen$label ) - 8;
                        
imagestring($this->image$this->fontsize$textx+1$texty+1$label $shadowcolor);
                        
imagestring($this->image$this->fontsize$textx$texty$label $this->black);
                    }
                }
            }
        }

        
//-----------------------------------------
        // Draw the lines
        //-----------------------------------------
        
imageline$this->image$this->grapharea['x0'] - 5$this->grapharea['y1'], $this->grapharea['x1'], $this->grapharea['y1'], $this->black );
        
imageline$this->image$this->grapharea['x0'], $this->grapharea['y0'], $this->grapharea['x0'], $this->grapharea['y1'] + 5$this->black );

        if ( 
$effect3DSize )
        {
            for ( 
$i 1$i <= $numdepth$i++ )
            {
                
$depth $effect3DSize $i;
                
imageline$this->image$this->grapharea['x0'], $this->grapharea['y1'], $this->grapharea['x0']+$depth$this->grapharea['y1']-$depth$this->black );
                
imageline$this->image$this->grapharea['x0']+$depth$this->grapharea['y1']-$depth$this->grapharea['x0']+$depth$this->grapharea['y0']-$depth$this->black );
                
imageline$this->image$this->grapharea['x0']+$depth$this->grapharea['y0']-$depth$this->grapharea['x0'], $this->grapharea['y0'], $this->black );
                
imageline$this->image$this->grapharea['x0']+$depth$this->grapharea['y1']-$depth$this->grapharea['x1']+$depth$this->grapharea['y1']-$depth$this->black );
                
imageline$this->image$this->grapharea['x1']+$depth$this->grapharea['y1']-$depth$this->grapharea['x1'], $this->grapharea['y1'], $this->black );
            }
        }
    }

    
/**
     * Generate Pie Chart
     *
     * @return    @e void
     */
    
protected function _drawPie()
    {
        
//-----------------------------------------
        // Draw Legend
        //-----------------------------------------
        
$this->legend $this->data['xaxis'];
        if ( !
$this->_drawLegend() ) return false;

        
//-----------------------------------------
        // Map data into PIE array
        //-----------------------------------------
        
if ( is_array$this->data['yaxis'][0]['data'] ) && count$this->data['yaxis'][0]['data'] ) > )
        {
            
$total  array_sum$this->data['yaxis'][0]['data'] );
            
$start  0;
            
$i 0;
            foreach ( 
$this->data['yaxis'][0]['data'] as $key => $value )
            {
                
$pies[] = array( 'start' => $start>360?360:$start,
                                 
'end'   => $start round(($value $total) * 360) > 360 360 $start round(($value $total) * 360) ,
                                 
'perc'  => round(($value $total)*100,1),
                                 
'name'  => isset( $this->data['xaxis'][$i] ) ? $this->data['xaxis'][$i] : $i
                               
);

                
$start $start round(($value $total) * 360);

                if ( !isset( 
$this->color$i ] ) ) $this->color$i ] = explode","$this->_getSliceColor() );

                
$i++;
            }
            
$pies[$i-1]['end'] = 360;

            
//-----------------------------------------
            // Slice of pie, anyone?
            //-----------------------------------------

            
$textcolor   imagecolorallocate$this->image00);
            
$shadowcolor imagecolorallocate$this->image170170170);
            
$midx  round$this->grapharea['x1'] / 20);
            
$midy  round( ( $this->options['height'] - $this->grapharea['y0'] ) / 20) + $this->grapharea['y0'];

            if ( 
$this->options['style3D'] == )
            {
                
$sizex round$this->grapharea['x1'] / 100 900);
                
$sizey round$this->grapharea['x1'] / 100 500);

                
//-----------------------------------------
                // Make the 3D effect
                //-----------------------------------------

                
for ( $i $midy+20$i $midy$i-- )
                {
                    
$ci 0;

                    foreach ( 
$pies as $pie )
                    {
                        if ( 
$pie['start'] > 180 or $pie['start'] == $pie['end'] )
                        {
                            
$ci++;
                            
# Can't see shadow or nothing to draw, so don't bother
                            
continue;
                        }


                        
$shadowcolor imagecolorallocate$this->image, ($this->color[$ci][0]-50)<0?0:$this->color[$ci][0]-50, ($this->color[$ci][1]-50)<0?0:$this->color[$ci][1]-50, ($this->color[$ci][2]-50)<0?0:$this->color[$ci][2]-50 );
                        
imagefilledarc($this->image$midx$i$sizex$sizey$pie['start'], $pie['end'], $shadowcolorIMG_ARC_PIE);
                        
imagecolordeallocate$this->image$shadowcolor );
                        
$ci++;
                    }
                }
            }
            else
            {
                
$maxsize = ( $this->grapharea['y1'] - $this->grapharea['y0'] < $this->grapharea['x1'] ) ? $this->grapharea['y1'] - $this->grapharea['y0'] : $this->grapharea['x1'];
                
$sizex round($maxsize 100 900);
                
$sizey round($maxsize 100 900);
            }

            
//-----------------------------------------
            // Slice
            //-----------------------------------------
            
$ci 0;

            foreach ( 
$pies as $pie )
            {
                if ( 
$pie['start'] == $pie['end'] )
                {
                    
# Nothing to draw, so don't bother
                    
$ci++;
                    continue;
                }
                
$piecolor imagecolorallocate$this->image$this->color[$ci][0], $this->color[$ci][1], $this->color[$ci][2] );
                
imagefilledarc($this->image$midx$midy$sizex$sizey$pie['start'], $pie['end'], $piecolorIMG_ARC_PIE);
                
imagecolordeallocate$this->image$piecolor );
                
$ci++;
            }

            
//-----------------------------------------
            // Data labels
            //-----------------------------------------
            
if ( $this->options['showdatalabels'] )
            {
                
$textcolor  ImageColorAllocate($this->imagehexdec(substr($this->options['textcolor'],1,2)), hexdec(substr($this->options['textcolor'],3,2)), hexdec(substr($this->options['textcolor'],5,2)));

                
$ci 0;

                foreach ( 
$pies as $key => $pie )
                {
                    
$textx $midx cos(deg2rad($pie['start']+($pie['end']-$pie['start'])/2))*($sizex/3);
                    
$texty $midy sin(deg2rad($pie['start']+($pie['end']-$pie['start'])/2))*($sizey/3);

                    
$shadowcolor imagecolorallocate$this->image, ($this->color[$ci][0]-50)<0?0:$this->color[$ci][0]-50, ($this->color[$ci][1]-50)<0?0:$this->color[$ci][1]-50, ($this->color[$ci][2]-50)<0?0:$this->color[$ci][2]-50 );

                    if ( 
$this->use_ttf )
                    {
                        
$txtsize     imagettfbbox("10"0$this->options['font'], $pie['perc']."%" );
                        
$textx       $textx round(($txtsize[2]-$txtsize[0])/2,0);
                        
$texty       $texty round(($txtsize[3]-$txtsize[1])/2,0);

                        
imagettftext($this->image"10"0$textx-1$texty-1$shadowcolor$this->options['font'], $pie['perc']."%");
                        
imagettftext($this->image"10"0$textx+1$texty+1$shadowcolor$this->options['font'], $pie['perc']."%");
                        
imagettftext($this->image"10"0$textx+2$texty+2$shadowcolor$this->options['font'], $pie['perc']."%");
                        
imagettftext($this->image"10"0$textx$texty$textcolor$this->options['font'], $pie['perc']."%");
                    }
                    else
                    {
                        
$textx       $textx round(imagefontwidth($this->fontsize)*strlen($pie['perc']."%")/2,0);
                        
$texty       $texty round(imagefontheight($this->fontsize)/2,0);

                        
imagestring($this->image$this->fontsize$textx-1$texty-1$pie['perc']."%"$shadowcolor);
                        
imagestring($this->image$this->fontsize$textx+1$texty+1$pie['perc']."%"$shadowcolor);
                        
imagestring($this->image$this->fontsize$textx+2$texty+2$pie['perc']."%"$shadowcolor);
                        
imagestring($this->image$this->fontsize$textx$texty$pie['perc']."%"$textcolor);
                    }

                    
imagecolordeallocate$this->image$shadowcolor );

                    
$ci++;
                }
            }
        }

        return 
true;
    }

    
/**
     * Generate Doughnut Chart
     *
     * @return    @e void
     */
    
protected function _drawDoughnut()
    {
        
//-----------------------------------------
        // Draw Legend
        //-----------------------------------------
        
$this->legend $this->data['xaxis'];
        if ( !
$this->_drawLegend() ) return false;

        
//-----------------------------------------
        // Calculates display variables
        //-----------------------------------------
        
$numrings count$this->data['yaxis'] );
        
$textcolor   imagecolorallocate$this->image00);
        
$shadowcolor imagecolorallocate$this->image170170170);
        
$bgcolor imagecolorallocate($this->imagehexdec(substr($this->options['bgcolor'],1,2)), hexdec(substr($this->options['bgcolor'],3,2)), hexdec(substr($this->options['bgcolor'],5,2)));
        
$midx  round$this->grapharea['x1'] / 20);
        
$midy  round( ( $this->options['height'] - $this->grapharea['y0'] ) / 20) + $this->grapharea['y0'];

        if ( 
$this->options['style3D'] == )
        {
            
$sizex round$this->grapharea['x1'] / 100 900);
            
$sizey round$this->grapharea['x1'] / 100 500);
        }
        else
        {
            
$maxsize = ( $this->grapharea['y1'] - $this->grapharea['y0'] < $this->grapharea['x1'] ) ? $this->grapharea['y1'] - $this->grapharea['y0'] : $this->grapharea['x1'];
            
$sizex round($maxsize 100 900);
            
$sizey round($maxsize 100 900);
        }

        
$holesizex round$sizex 0.2);
        
$holesizey round$sizey 0.2);

        
$ringsizex = ( $sizex $holesizex ) / $numrings;
        
$ringsizey = ( $sizey $holesizey ) / $numrings;

        
//-----------------------------------------
        // Lord of the Rings
        //-----------------------------------------
        
for ( $ci 0$ci $numrings$ci++ )
        {
            
//-----------------------------------------
            // Map data into PIE array
            //-----------------------------------------
            
$total  array_sum$this->data['yaxis'][$ci]['data'] );
            
$start  0;
            
$i 0;
            
$pies = array();
            foreach ( 
$this->data['yaxis'][$ci]['data'] as $key => $value )
            {
                
$pies[] = array( 'start' => $start>360?360:$start,
                                 
'end'   => $start round(($value $total) * 360) > 360 360 $start round(($value $total) * 360) ,
                                 
'perc'  => round(($value $total)*100,1),
                                 
'name'  => isset( $this->data['xaxis'][$i] ) ? $this->data['xaxis'][$i] : $i
                               
);

                
$start $start round(($value $total) * 360);

                if ( !isset( 
$this->color$i ] ) ) $this->color$i ] = explode","$this->_getSliceColor() );

                
$i++;
            }
            
$pies[$i-1]['end'] = 360;

            
//-----------------------------------------
            // Slice of pie, anyone?
            //-----------------------------------------
            
if ( $this->options['style3D'] == )
            {
                if ( 
$ci==)
                {
                    
//-----------------------------------------
                    // Make the 3D effect
                    //-----------------------------------------

                    
for ( $i $midy+20$i $midy$i-- )
                    {
                        
$pi 0;

                        foreach ( 
$pies as $pie )
                        {
                            if ( 
$pie['start'] > 180 or $pie['start'] == $pie['end'] )
                            {
                                
$pi++;
                                
# Can't see shadow or nothing to draw, so don't bother
                                
continue;
                            }


                            
$shadowcolor imagecolorallocate$this->image, ($this->color[$pi][0]-50)<0?0:$this->color[$pi][0]-50, ($this->color[$pi][1]-50)<0?0:$this->color[$pi][1]-50, ($this->color[$pi][2]-50)<0?0:$this->color[$pi][2]-50 );
                            
imagefilledarc($this->image$midx$i$sizex-$ci*$ringsizex$sizey-$ci*$ringsizey$pie['start'], $pie['end'], $shadowcolorIMG_ARC_PIE);
                            
imagecolordeallocate$this->image$shadowcolor );
                            
$pi++;
                        }
                    }
                }
            }

            
//-----------------------------------------
            // Slice
            //-----------------------------------------
            
$pi 0;

            foreach ( 
$pies as $pie )
            {
                if ( 
$pie['start'] == $pie['end'] )
                {
                    
# Nothing to draw, so don't bother
                    
$pi++;
                    continue;
                }
                
$piecolor imagecolorallocate$this->image$this->color[$pi][0], $this->color[$pi][1], $this->color[$pi][2] );
                
imagefilledarc($this->image$midx$midy$sizex-$ci*$ringsizex$sizey-$ci*$ringsizey$pie['start'], $pie['end'], $piecolorIMG_ARC_PIE);
                
imagecolordeallocate$this->image$piecolor );

                if ( 
$ci )
                {
                    
# little dark line to distinguish between the series
                    
$shadowcolor imagecolorallocate$this->image, ($this->color[$pi][0]-50)<0?0:$this->color[$pi][0]-50, ($this->color[$pi][1]-50)<0?0:$this->color[$pi][1]-50, ($this->color[$pi][2]-50)<0?0:$this->color[$pi][2]-50 );
                    
imagearc($this->image$midx$midy$sizex-$ci*$ringsizex$sizey-$ci*$ringsizey$pie['start'], $pie['end'], $shadowcolor );
                    
imagecolordeallocate$this->image$shadowcolor );
                }

                
$pi++;
            }

            
//-----------------------------------------
            // Data labels
            //-----------------------------------------
            
if ( $this->options['showdatalabels'] )
            {
                
$textcolor  ImageColorAllocate($this->imagehexdec(substr($this->options['textcolor'],1,2)), hexdec(substr($this->options['textcolor'],3,2)), hexdec(substr($this->options['textcolor'],5,2)));

                
$pi 0;

                foreach ( 
$pies as $key => $pie )
                {
                    
$textx $midx cos(deg2rad($pie['start']+($pie['end']-$pie['start'])/2))*($sizex/2-($ci+0.5)*$ringsizex/2);
                    
$texty $midy sin(deg2rad($pie['start']+($pie['end']-$pie['start'])/2))*($sizey/2-($ci+0.5)*$ringsizey/2);

                    
$textshadowcolor imagecolorallocate$this->image, ($this->color[$pi][0]-50)<0?0:$this->color[$pi][0]-50, ($this->color[$pi][1]-50)<0?0:$this->color[$pi][1]-50, ($this->color[$pi][2]-50)<0?0:$this->color[$pi][2]-50 );

                    if ( 
$this->use_ttf )
                    {
                        
$txtsize     imagettfbbox("10"0$this->options['font'], $pie['perc']."%" );
                        
$textx       $textx round(($txtsize[2]-$txtsize[0])/2,0);
                        
$texty       $texty round(($txtsize[3]-$txtsize[1])/2,0);

                        
imagettftext($this->image"10"0$textx-1$texty-1$textshadowcolor$this->options['font'], $pie['perc']."%");
                        
imagettftext($this->image"10"0$textx+1$texty+1$textshadowcolor$this->options['font'], $pie['perc']."%");
                        
imagettftext($this->image"10"0$textx+2$texty+2$textshadowcolor$this->options['font'], $pie['perc']."%");
                        
imagettftext($this->image"10"0$textx$texty$textcolor$this->options['font'], $pie['perc']."%");
                    }
                    else
                    {
                        
$textx       $textx round(imagefontwidth($this->fontsize)*strlen($pie['perc']."%")/2,0);
                        
$texty       $texty round(imagefontheight($this->fontsize)/2,0);

                        
imagestring($this->image$this->fontsize$textx-1$texty-1$pie['perc']."%"$textshadowcolor);
                        
imagestring($this->image$this->fontsize$textx+1$texty+1$pie['perc']."%"$textshadowcolor);
                        
imagestring($this->image$this->fontsize$textx+2$texty+2$pie['perc']."%"$textshadowcolor);
                        
imagestring($this->image$this->fontsize$textx$texty$pie['perc']."%"$textcolor);
                    }

                    
imagecolordeallocate$this->image$textshadowcolor );

                    
$pi++;
                }
            }
            
imagecolordeallocate$this->image$textcolor );
        }

        
//-----------------------------------------
        // The hole
        //-----------------------------------------
        
if ( $this->options['style3D'] == )
        {
            
//-----------------------------------------
            // Make the 3D effect for the hole
            //-----------------------------------------
            
$hole imagecreatetruecolor$holesizex$holesizey );
            
$holemidx round$holesizex 2);
            
$holemidy round$holesizey 2);

            if ( 
function_exists('imageantialias') )
            {
                @
imageantialias$holeTRUE );
            }

            
$bgcolor imagecolorallocate($holehexdec(substr($this->options['bgcolor'],1,2)), hexdec(substr($this->options['bgcolor'],3,2)), hexdec(substr($this->options['bgcolor'],5,2)));
            
$black imagecolorallocate$hole00);

            for ( 
$i 0$i <= 20$i++ )
            {
                
$pi 0;

                foreach ( 
$pies as $pie )
                {
                    if ( 
$pie['end'] < 180 or $pie['start'] == $pie['end'] )
                    {
                        
$pi++;
                        
# Can't see shadow or nothing to draw, so don't bother
                        
continue;
                    }
                    if ( 
$pie['start'] < 180 $pie['start'] = 180;

                    
$shadowcolor imagecolorallocate$hole, ($this->color[$pi][0]-50)<0?0:$this->color[$pi][0]-50, ($this->color[$pi][1]-50)<0?0:$this->color[$pi][1]-50, ($this->color[$pi][2]-50)<0?0:$this->color[$pi][2]-50 );
                    
imagefilledarc($hole$holemidx$holemidy+$i$holesizex$holesizey$pie['start'], $pie['end'], $shadowcolorIMG_ARC_PIE );
                    
imagecolordeallocate$hole$shadowcolor );
                    
$pi++;
                }
            }
            
imagefilledellipse($hole$holemidx$holemidy+21$holesizex$holesizey$bgcolor );

            
$maxlength ceil$holesizey );
            for ( 
$i 1$i <= $maxlength$i++ )
            {
                
imagearc$hole$holemidx$holemidy+$i$holesizex$holesizey0180$black );
                
imagearc$hole$holemidx$holemidy-$i$holesizex$holesizey180360$black );
            }

            
imagecolortransparent$hole$black );
            
imagecopymerge$this->image$hole$midx-$holemidx$midy-$holemidy-100$holesizex$holesizey100 );
            
imagedestroy$hole );
        }
        else
        {
            
// in 2D this is a breeze
            
imagefilledellipse($this->image$midx$midy$holesizex$holesizey$bgcolor );
        }

        
//-----------------------------------------
        // Draw series labels
        //-----------------------------------------
        
$textcolor   imagecolorallocate$this->image00);
        
$textshadowcolor imagecolorallocate$this->image170170170);
        
$textx floor$midx 0.8 $sizex );
        
$texty $this->grapharea['y0'];
        for ( 
$ci 0$ci $numrings$ci++ )
        {
            
// draw the label
            
$label $this->data['yaxis'][$ci]['name'];
            if ( 
$this->use_ttf )
            {
                
$txtsize imagettfbbox("10"0$this->options['font'], $label );
                
$txtsizey   $txtsize[1]-$txtsize[5];

                
imagettftext($this->image"10"0$textx+1$texty+$txtsizey+1$textshadowcolor$this->options['font'], $label );
                
imagettftext($this->image"10"0$textx$texty+$txtsizey$textcolor$this->options['font'], $label );
            }
            else
            {
                
$txtsizey imagefontheight($this->fontsize);

                
imagestring($this->image$this->fontsize$textx+1$texty+1$label$textshadowcolor);
                
imagestring($this->image$this->fontsize$textx$texty$label$textcolor);
            }

            
// Draw the line to text
            
$x1 $midx cos(deg2rad(300))*($sizex/2-($ci+0.5)*$ringsizex/2);
            
$y1 $midy sin(deg2rad(300))*($sizey/2-($ci+0.5)*$ringsizey/2);
            
$x2 $textx 5;
            
$y2 $texty 0.5 $txtsizey;
            
imageline$this->image$x1$y1$x2$y2$this->black );

            
$texty $texty $txtsizey 5;
        }

        
imagecolordeallocate$this->image$textshadowcolor );
        
imagecolordeallocate$this->image$textcolor );

        return 
true;
    }

    
/**
     * Generate Bar Chart
     *
     * @return    @e void
     */
    
protected function _drawBars()
    {
        
//-----------------------------------------
        // Draw Legends and Axes
        //-----------------------------------------
        
foreach ( $this->data['yaxis'] as $key => $series )
        {
            
$this->legend$key ] = $series['name'];
        }
        if ( !
$this->_drawLegend() ) return false;
        
$this->x_axis = array( 'type'    => 'labels',
                               
'labels'    => $this->data['xaxis']
                             );
        
$this->y_axis = array( 'type'    => 'numeric',
                               
'min'    => 0,
                               
'max'    => $this->_getMax$this->data['yaxis'] )
                             );
        
$this->_drawAxes();

        
//-----------------------------------------
        // Allocate text and shadow cols
        //-----------------------------------------
        
$textcolor   imagecolorallocate$this->imagehexdec(substr($this->options['titlecolor'],1,2)), hexdec(substr($this->options['titlecolor'],3,2)), hexdec(substr($this->options['titlecolor'],5,2)));
        
$shadowcolor imagecolorallocate$this->imagehexdec(substr($this->options['titleshadow'],1,2)), hexdec(substr($this->options['titleshadow'],3,2)), hexdec(substr($this->options['titleshadow'],5,2)));

        
//-----------------------------------------
        // Calculate bar display variables
        //-----------------------------------------
        
$numybars count$this->data['yaxis'] );
        
$numbars count$this->data['yaxis'][0]['data'] );
        
$maxvalue $this->_getMax$this->data['yaxis'] );
        
$stepwidth floor( ( ( $this->grapharea['x1'] - $this->grapharea['x0'] ) / $numbars ) );
        
$barwidth floor( ( $stepwidth 0.9 ) / $numybars );
        
$ident round ( ( $stepwidth - ( $numybars $barwidth ) ) / 2) + 1;
        
$effect3DSize round$barwidth 2) < 20 round$barwidth 2) : 20;

        
$numticks $this->options['numticks'] > $maxvalue floor($maxvalue) : $this->options['numticks'];
        
$step floor$maxvalue $numticks );
        
$steps ceil$maxvalue $step );
        
$stepheight = ( $this->grapharea['y1'] - $this->grapharea['y0'] ) / $steps;

        
//-----------------------------------------
        // Candybar?
        //-----------------------------------------
        
for ( $i=0$i<$numbars$i++ )
        {
            for ( 
$ci=0$ci<$numybars$ci++ )
            {
                if ( !isset( 
$this->color$ci ] ) ) $this->color$ci ] = explode","$this->_getSliceColor$this->data['yaxis'][$ci]['color'] ) );

                
$value $this->data['yaxis'][$ci]['data'][$i];

                
//-----------------------------------------
                // Find out the bar location and size
                //-----------------------------------------
                
$x1 $this->grapharea['x0'] + ($stepwidth $i ) + ($ci $barwidth ) + $ident;
                
$x2 $x1 $barwidth 1;
                
$y1 round$this->grapharea['y1'] - $value $stepheight/$step0);
                
$y2 $this->grapharea['y1'];

                if ( 
$this->options['style3D'] == )
                {
                    
//-----------------------------------------
                    // Make the 3D effect
                    //-----------------------------------------
                    
$shadowcolor imagecolorallocate$this->image, ($this->color[$ci][0]-50)<0?0:$this->color[$ci][0]-50, ($this->color[$ci][1]-50)<0?0:$this->color[$ci][1]-50, ($this->color[$ci][2]-50)<0?0:$this->color[$ci][2]-50 );
                    
$shadowsize = ($x2-$x1)/20 20 Round(($x2-$x1)/20);

                    for ( 
$j $shadowsize-1$j 0$j-- )
                    {
                        
imageline$this->image$x2 $j$y1 $j$x2 $j$y2 $j$shadowcolor );
                    }
                    
imagecolordeallocate$this->image$shadowcolor );

                    
$shadowcolor imagecolorallocate$this->image, ($this->color[$ci][0]-25)<0?0:$this->color[$ci][0]-25, ($this->color[$ci][1]-25)<0?0:$this->color[$ci][1]-25, ($this->color[$ci][2]-25)<0?0:$this->color[$ci][2]-25 );
                    for ( 
$j $shadowsize$j 0$j-- )
                    {
                        
imageline$this->image$x1 $j$y1 $j$x2 $j$y1 $j$shadowcolor );
                    }
                    
imagecolordeallocate$this->image$shadowcolor );
                }

                
//-----------------------------------------
                // Bar
                //-----------------------------------------
                
$barcolor imagecolorallocate$this->image$this->color[$ci][0], $this->color[$ci][1], $this->color[$ci][2] );
                
imagefilledrectangle$this->image$x1$y1$x2$y2-1$barcolor );
                
imagecolordeallocate$this->image$barcolor );

                
//-----------------------------------------
                // Datalabels
                //-----------------------------------------
                
if ( $this->options['showdatalabels'] )
                {
                    
$textcolor  ImageColorAllocate($this->imagehexdec(substr($this->options['textcolor'],1,2)), hexdec(substr($this->options['textcolor'],3,2)), hexdec(substr($this->options['textcolor'],5,2)));

                    
$textx $x1 round( ($x2-$x1) /20);
                    
$texty $y1 round( ($y2-$y1) /20);

                    if ( 
$this->use_ttf )
                    {
                        
$txtsize     imagettfbbox('10'0$this->options['font'], $value );
                        
$textx       $textx round(($txtsize[2]-$txtsize[0])/2,0);
                        
$texty       $texty round(($txtsize[1]-$txtsize[5])/2,0);
                        
$texty         = ($texty $this->grapharea['y1']-2) ? $this->grapharea['y1']-$texty;

                        
$shadowcolor imagecolorallocate$this->image, ($this->color[$ci][0]-50)<0?0:$this->color[$ci][0]-50, ($this->color[$ci][1]-50)<0?0:$this->color[$ci][1]-50, ($this->color[$ci][2]-50)<0?0:$this->color[$ci][2]-50 );
                        
imagettftext($this->image"10"0$textx-1$texty-1$shadowcolor$this->options['font'], $value);
                        
imagettftext($this->image"10"0$textx+1$texty+1$shadowcolor$this->options['font'], $value);
                        
imagettftext($this->image"10"0$textx+2$texty+2$shadowcolor$this->options['font'], $value);
                        
imagettftext($this->image"10"0$textx$texty$textcolor$this->options['font'], $value);

                        
imagecolordeallocate$this->image$shadowcolor );
                    }
                    else
                    {
                        
$textx       $textx round(imagefontwidth($this->fontsize)*strlen($value)/2,0);
                        
$texty       $texty round(imagefontheight($this->fontsize)/2,0);
                        
$texty         = ($texty $texty-imagefontheight($this->fontsize)-2) ? $texty-imagefontheight($this->fontsize)-$texty;

                        
$shadowcolor imagecolorallocate$this->image, ($this->color[0][0]-50)<0?0:$this->color[0][0]-50, ($this->color[0][1]-50)<0?0:$this->color[0][1]-50, ($this->color[0][2]-50)<0?0:$this->color[0][2]-50 );
                        
imagestring($this->image$this->fontsize$textx-1$texty-1$value$shadowcolor);
                        
imagestring($this->image$this->fontsize$textx+1$texty+1$value$shadowcolor);
                        
imagestring($this->image$this->fontsize$textx+2$texty+2$value$shadowcolor);
                        
imagestring($this->image$this->fontsize$textx$texty$value$textcolor);

                        
imagecolordeallocate$this->image$shadowcolor );
                    }
                }
            }
        }

        return 
true;
    }

    
/**
     * Generate Horizontal Bar Charts
     *
     * @return    @e void
     */
    
protected function _drawHorizontalBars()
    {
        
//-----------------------------------------
        // Draw Legend & Axes
        //-----------------------------------------
        
foreach ( $this->data['yaxis'] as $key => $series )
        {
            
$this->legend$key ] = $series['name'];
        }
        if ( !
$this->_drawLegend() ) return false;
        
$this->x_axis = array( 'type'    => 'numeric',
                               
'min'    => 0,
                               
'max'    => $this->_getMax$this->data['yaxis'] )
                             );
        
$this->y_axis = array( 'type'    => 'labels',
                               
'labels'    => $this->data['xaxis']
                             );
        
$this->_drawAxes();

        
//-----------------------------------------
        // Allocate text and shadow cols
        //-----------------------------------------
        
$textcolor   imagecolorallocate$this->imagehexdec(substr($this->options['titlecolor'],1,2)), hexdec(substr($this->options['titlecolor'],3,2)), hexdec(substr($this->options['titlecolor'],5,2)));
        
$shadowcolor imagecolorallocate$this->imagehexdec(substr($this->options['titleshadow'],1,2)), hexdec(substr($this->options['titleshadow'],3,2)), hexdec(substr($this->options['titleshadow'],5,2)));

        
//-----------------------------------------
        // Calculate bar display variables
        //-----------------------------------------
        
$numybars count$this->data['yaxis'] );
        
$numbars count$this->data['yaxis'][0]['data'] );
        
$maxvalue $this->_getMax$this->data['yaxis'] );
        
$stepheight floor( ( ( $this->grapharea['y1'] - $this->grapharea['y0'] ) / $numbars ) );
        
$barheight floor( ( $stepheight 0.9 ) / $numybars );
        
$ident round ( ( $stepheight - ( $numybars $barheight ) ) / 2) + 1;
        
$effect3DSize round$barheight 2) < 20 round$barheight 2) : 20;

        
$numticks $this->options['numticks'] > $maxvalue floor($maxvalue) : $this->options['numticks'];
        
$step floor$maxvalue $numticks );
        
$steps ceil$maxvalue $step );
        
$stepwidth = ( $this->grapharea['x1'] - $this->grapharea['x0'] ) / $steps;

        
//-----------------------------------------
        // Candybar?
        //-----------------------------------------
        
for ( $i=0$i<$numbars$i++ )
        {
            for ( 
$ci=0$ci<$numybars$ci++ )
            {
                
//-----------------------------------------
                // Get me a nice color will ya
                //-----------------------------------------
                
if ( !isset( $this->color$ci ] ) ) $this->color$ci ] = explode","$this->_getSliceColor$this->data['yaxis'][$ci]['color'] ) );

                
$value $this->data['yaxis'][$ci]['data'][$i];

                
//-----------------------------------------
                // Find out the bar location and size
                //-----------------------------------------
                
$x1 $this->grapharea['x0'] + 1;
                
$x2 round$this->grapharea['x0'] + $value $stepwidth $step0);
                
$y1 $this->grapharea['y1'] - ($stepheight $i ) - ($ci $barheight ) - $ident;
                
$y2 $y1 $barheight 1;

                
//-----------------------------------------
                // Bar
                //-----------------------------------------
                
$barcolor imagecolorallocate$this->image$this->color[$ci][0], $this->color[$ci][1], $this->color[$ci][2] );
                
imagefilledrectangle$this->image$x1$y1$x2$y2$barcolor );
                
imagecolordeallocate$this->image$barcolor );

                if ( 
$this->options['style3D'] == )
                {
                    
//-----------------------------------------
                    // Make the 3D effect
                    //-----------------------------------------
                    
$shadowcolor imagecolorallocate$this->image, ($this->color[$ci][0]-50)<0?0:$this->color[$ci][0]-50, ($this->color[$ci][1]-50)<0?0:$this->color[$ci][1]-50, ($this->color[$ci][2]-50)<0?0:$this->color[$ci][2]-50 );
                    
$shadowsize = ($y1-$y2)/20 20 Round(($y1-$y2)/20);
                    for ( 
$j $shadowsize$j 0$j-- )
                    {
                        
imageline$this->image$x2 $j$y1 $j 1$x2 $j$y2 $j$shadowcolor );
                    }
                    
imagecolordeallocate$this->image$shadowcolor );

                    
$shadowcolor imagecolorallocate$this->image, ($this->color[$ci][0]-25)<0?0:$this->color[$ci][0]-25, ($this->color[$ci][1]-25)<0?0:$this->color[$ci][1]-25, ($this->color[$ci][2]-25)<0?0:$this->color[$ci][2]-25 );
                    for ( 
$j $shadowsize$j 0$j-- )
                    {
                        
imageline$this->image$x1 $j$y2 $j$x2 $j$y2 $j$shadowcolor );
                    }
                    
imagecolordeallocate$this->image$shadowcolor );
                }

                
//-----------------------------------------
                // Datalabels
                //-----------------------------------------
                
if ( $this->options['showdatalabels'] )
                {
                    
$textcolor  ImageColorAllocate($this->imagehexdec(substr($this->options['textcolor'],1,2)), hexdec(substr($this->options['textcolor'],3,2)), hexdec(substr($this->options['textcolor'],5,2)));

                    
$textx $x1 round( ($x2-$x1) /20);
                    
$texty $y1 round( ($y2-$y1) /20);

                    if ( 
$this->use_ttf )
                    {
                        
$txtsize     imagettfbbox('10'0$this->options['font'], $value );
                        
$textx       $textx round(($txtsize[2]-$txtsize[0])/2,0);
                        
$textx         = ( $textx $this->grapharea['x0'] + ) ? $this->grapharea['x0'] + $textx;
                        
$texty       $texty round(($txtsize[1]-$txtsize[5])/2,0);

                        
$shadowcolor imagecolorallocate$this->image, ($this->color[$ci][0]-50)<0?0:$this->color[$ci][0]-50, ($this->color[$ci][1]-50)<0?0:$this->color[$ci][1]-50, ($this->color[$ci][2]-50)<0?0:$this->color[$ci][2]-50 );
                        
imagettftext($this->image"10"0$textx-1$texty-1$shadowcolor$this->options['font'], $value);
                        
imagettftext($this->image"10"0$textx+1$texty+1$shadowcolor$this->options['font'], $value);
                        
imagettftext($this->image"10"0$textx+2$texty+2$shadowcolor$this->options['font'], $value);
                        
imagettftext($this->image"10"0$textx$texty$textcolor$this->options['font'], $value);

                        
imagecolordeallocate$this->image$shadowcolor );
                    }
                    else
                    {
                        
$textx       $textx round(imagefontwidth($this->fontsize)*strlen($value)/2,0);
                        
$texty       = ($textx $this->grapharea['x0']+2) ? $this->grapharea['x0']+$textx;
                        
$texty       $texty round(imagefontheight($this->fontsize)/2,0);

                        
$shadowcolor imagecolorallocate$this->image, ($this->color[0][0]-50)<0?0:$this->color[0][0]-50, ($this->color[0][1]-50)<0?0:$this->color[0][1]-50, ($this->color[0][2]-50)<0?0:$this->color[0][2]-50 );
                        
imagestring($this->image$this->fontsize$textx-1$texty-1$value$shadowcolor);
                        
imagestring($this->image$this->fontsize$textx+1$texty+1$value$shadowcolor);
                        
imagestring($this->image$this->fontsize$textx+2$texty+2$value$shadowcolor);
                        
imagestring($this->image$this->fontsize$textx$texty$value$textcolor);

                        
imagecolordeallocate$this->image$shadowcolor );
                    }
                }
            }
        }

        return 
true;
    }

    
/**
     * Generate Line Chart
     *
     * @return    @e void
     */
    
protected function _drawLines()
    {
        
//-----------------------------------------
        // Draw Legend and Axes
        //-----------------------------------------
        
foreach ( $this->data['yaxis'] as $key => $series )
        {
            
$this->legend$key ] = $series['name'];
        }
        if ( !
$this->_drawLegend() ) return false;
        
$this->x_axis = array( 'type'    => 'labels',
                               
'labels'    => $this->data['xaxis']
                             );
        
$this->y_axis = array( 'type'    => 'numeric',
                               
'min'    => 0,
                               
'max'    => $this->_getMax$this->data['yaxis'] )
                             );
        
$this->_drawAxes();

        
//-----------------------------------------
        // Allocate text and shadow cols
        //-----------------------------------------
        
$textcolor   imagecolorallocate$this->imagehexdec(substr($this->options['titlecolor'],1,2)), hexdec(substr($this->options['titlecolor'],3,2)), hexdec(substr($this->options['titlecolor'],5,2)));
        
$shadowcolor imagecolorallocate$this->imagehexdec(substr($this->options['titleshadow'],1,2)), hexdec(substr($this->options['titleshadow'],3,2)), hexdec(substr($this->options['titleshadow'],5,2)));

        
//-----------------------------------------
        // Calculate bar display variables
        //-----------------------------------------
        
$numybars count$this->data['yaxis'] );
        
$numbars count$this->data['yaxis'][0]['data'] );
        
$maxvalue $this->_getMax$this->data['yaxis'] );
        
$stepwidth floor( ( ( $this->grapharea['x1'] - $this->grapharea['x0'] ) / $numbars ) );

        
$numticks $this->options['numticks'] > $maxvalue floor($maxvalue) : $this->options['numticks'];
        
$numticks $numticks $numticks 1;
        
$step floor$maxvalue $numticks );
        
$step $step $step 1;
        
$steps ceil$maxvalue $step );
        
$steps $steps $steps 1;
        
$stepheight = ( $this->grapharea['y1'] - $this->grapharea['y0'] ) / $steps;

        
$effect3DSize 20;

        
//-----------------------------------------
        // Lines
        //-----------------------------------------
        
for ( $ci=0$ci<$numybars$ci++ )
        {
            for ( 
$i=0$i<$numbars$i++ )
            {
                
// No need to draw a line on only the first value
                
if ( $i )
                {
                    if ( !isset( 
$this->color$ci ] ) ) $this->color$ci ] = explode","$this->_getSliceColor$this->data['yaxis'][$ci]['color'] ) );

                    
$value1 $this->data['yaxis'][$ci]['data'][$i-1];
                    
$value2 $this->data['yaxis'][$ci]['data'][$i];

                    
//-----------------------------------------
                    // Find out the bar location and size
                    //-----------------------------------------
                    
$x1 $this->grapharea['x0'] + round$stepwidth 0.50) + ($i-1) * ( $stepwidth );
                    
$x2 $this->grapharea['x0'] + round$stepwidth 0.50) + ($i) * ( $stepwidth );
                    
$y1 round$this->grapharea['y1'] - $value1 $stepheight $step0);
                    
$y2 round$this->grapharea['y1'] - $value2 $stepheight $step0);

                    
$linecolor imagecolorallocate$this->image$this->color[$ci][0], $this->color[$ci][1], $this->color[$ci][2] );
                    
$lineshadowcolor imagecolorallocate$this->image, ($this->color[$ci][0]-25)<0?0:$this->color[$ci][0]-25, ($this->color[$ci][1]-25)<0?0:$this->color[$ci][1]-25, ($this->color[$ci][2]-25)<0?0:$this->color[$ci][2]-25 );
                    
$lineshadowcolor2 imagecolorallocate$this->image, ($this->color[$ci][0]-50)<0?0:$this->color[$ci][0]-50, ($this->color[$ci][1]-50)<0?0:$this->color[$ci][1]-50, ($this->color[$ci][2]-50)<0?0:$this->color[$ci][2]-50 );

                    if ( 
$this->options['style3D'] == )
                    {
                        
//-----------------------------------------
                        // Make the 3D effect
                        //-----------------------------------------

                        
$shadowsize 20;

                        
$x1 $x1 + ($numybars-$ci-1) * $shadowsize;
                        
$x2 $x2 + ($numybars-$ci-1) * $shadowsize;
                        
$y1 $y1 - ($numybars-$ci-1) * $shadowsize;
                        
$y2 $y2 - ($numybars-$ci-1) * $shadowsize;

                        if ( ( 
$y1 $y2 ) / ( $x2 $x1 ) > )
                        {
                            
imagefilledpolygon$this->image, array( $x1$y1$x2$y2$x2+$shadowsize$y2-$shadowsize$x1+$shadowsize$y1-$shadowsize), 4$lineshadowcolor2 );
                        }
                        else
                        {
                            
imagefilledpolygon$this->image, array( $x1$y1$x2$y2$x2+$shadowsize$y2-$shadowsize$x1+$shadowsize$y1-$shadowsize), 4$lineshadowcolor );
                        }
                    }

                    
//-----------------------------------------
                    // Line & Dots
                    //-----------------------------------------

                    
imageline$this->image$x1$y1$x2$y2$linecolor );
                    if ( 
$this->options['style3D'] != )
                    {
                        
imageline$this->image$x1+1$y1+1$x2+1$y2+1$lineshadowcolor );
                        
imagefilledellipse$this->image$x1+1$y1+177$lineshadowcolor );
                        
imagefilledellipse$this->image$x1$y177$linecolor );
                        if ( 
$i == $numbars )
                        {
                            
imagefilledellipse$this->image$x2+1$y2+177$lineshadowcolor );
                            
imagefilledellipse$this->image$x2$y277$linecolor );
                        }
                    }

                    
imagecolordeallocate$this->image$linecolor );
                    
imagecolordeallocate$this->image$lineshadowcolor );
                    
imagecolordeallocate$this->image$lineshadowcolor2 );
                }

                
//-----------------------------------------
                // Datalabels
                //-----------------------------------------
                
if ( $this->options['showdatalabels'] )
                {
                    
// First value is not calculated yet
                    
if ( $i == )
                    {
                        
$value2 $this->data['yaxis'][$ci]['data'][$i];
                        
$x2 $this->grapharea['x0'] + round$stepwidth 0.50) + ($i) * ( $stepwidth );
                        
$y2 round$this->grapharea['y1'] - $value2 $stepheight $step0);
                        if ( 
$this->options['style3D'] == )
                        {
                            
$x2 $x2 + ($numybars-$ci-1) * 20;
                            
$y2 $y2 - ($numybars-$ci-1) * 20;
                        }
                    }

                    
$valuecolor  imagecolorallocate($this->imagehexdec(substr($this->options['textcolor'],1,2)), hexdec(substr($this->options['textcolor'],3,2)), hexdec(substr($this->options['textcolor'],5,2)));
                    
$valshadecolor imagecolorallocate$this->image, ($this->color[$ci][0]-50)<0?0:$this->color[$ci][0]-50, ($this->color[$ci][1]-50)<0?0:$this->color[$ci][1]-50, ($this->color[$ci][2]-50)<0?0:$this->color[$ci][2]-50 );

                    if ( 
$this->use_ttf )
                    {
                        
$txtsize     imagettfbbox('10'0$this->options['font'], $value2 );
                        
$textx       $x2 - ( round(($txtsize[2]-$txtsize[0])/2,0) * ( strlen($value2)/1.2 ) );
                        
$texty       $y2 3;

                        
imagettftext($this->image"10"0$textx-1$texty-1$valshadecolor$this->options['font'], $value2);
                        
//imagettftext($this->image, "10", 0, $textx+1, $texty+1, $valshadecolor, $this->options['font'], $value2);
                        //imagettftext($this->image, "10", 0, $textx+2, $texty+2, $valshadecolor, $this->options['font'], $value2);
                        
imagettftext($this->image"10"0$textx$texty$valuecolor$this->options['font'], $value2);
                    }
                    else
                    {
                        
$textx       $x2 round(imagefontwidth($this->fontsize)*strlen($value2)/2,0);
                        
$texty       $y2 imagefontheight($this->fontsize)-3;

                        
imagestring($this->image$this->fontsize$textx-1$texty-1$value2$valshadecolor );
                        
imagestring($this->image$this->fontsize$textx+1$texty+1$value2$valshadecolor );
                        
imagestring($this->image$this->fontsize$textx+2$texty+2$value2$valshadecolor );
                        
imagestring($this->image$this->fontsize$textx$texty$value2$valuecolor);
                    }
                    
imagecolordeallocate$this->image$valuecolor );
                    
imagecolordeallocate$this->image$valshadecolor );
                }
            }
        }

        return 
true;
    }

    
/**
     * Generate Area Chart
     *
     * @return    @e void
     */
    
protected function _drawArea()
    {
        
//-----------------------------------------
        // Draw Legend and Axes
        //-----------------------------------------
        
foreach ( $this->data['yaxis'] as $key => $series )
        {
            
$this->legend$key ] = $series['name'];
        }
        if ( !
$this->_drawLegend() ) return false;
        
$this->x_axis = array( 'type'    => 'ticklabels',
                               
'labels'    => $this->data['xaxis']
                             );
        
$maxarray = array();
        foreach ( 
$this->data['yaxis'] as $series )
        {
            foreach( 
$series['data'] as $id => $value )
            {
                if ( isset ( 
$maxarray[$id] ) )
                {
                    
$maxarray[$id] += $value;
                }
                else
                {
                    
$maxarray[$id] = $value;
                }
            }
        }

        
$this->y_axis = array( 'type'    => 'numeric',
                               
'min'    => 0,
                               
'max'    => $this->_getMax$maxarray )
                             );
        
$this->_drawAxes();

        
//-----------------------------------------
        // Allocate text and shadow cols
        //-----------------------------------------
        
$textcolor   imagecolorallocate$this->imagehexdec(substr($this->options['titlecolor'],1,2)), hexdec(substr($this->options['titlecolor'],3,2)), hexdec(substr($this->options['titlecolor'],5,2)));
        
$shadowcolor imagecolorallocate$this->imagehexdec(substr($this->options['titleshadow'],1,2)), hexdec(substr($this->options['titleshadow'],3,2)), hexdec(substr($this->options['titleshadow'],5,2)));

        
//-----------------------------------------
        // Calculate area display variables
        //-----------------------------------------
        
$numareas count$this->data['yaxis'] );
        
$numbars count$this->data['yaxis'][0]['data'] );
        
$maxvalue $this->_getMax$maxarray );

        
$stepwidth floor( ( ( $this->grapharea['x1'] - $this->grapharea['x0'] ) / ( $numbars ) ) );

        
$numticks $this->options['numticks'] > $maxvalue floor($maxvalue) : $this->options['numticks'];
        
$step floor$maxvalue $numticks );
        
$steps ceil$maxvalue $step );
        
$stepheight = ( $this->grapharea['y1'] - $this->grapharea['y0'] ) / $steps;

        
$effect3DSize 20;

        
//-----------------------------------------
        // Areas
        //-----------------------------------------
        
for ( $ci=0$ci<$numareas$ci++ )
        {
            for ( 
$i=0$i<$numbars$i++ )
            {
                
// Calculate the positions of the area
                
$value $this->data['yaxis'][$ci]['data'][$i];

                
$area[$ci][$i*2] = $this->grapharea['x0'] + ($i $stepwidth);
                if ( isset( 
$area[$ci-1][$i*2+1] ) )
                {
                    
$area[$ci][$i*2+1] = round$area[$ci-1][$i*2+1] - $value $stepheight/$step0);
                }
                else
                {
                    
$area[$ci][$i*2+1] = round$this->grapharea['y1'] - $value $stepheight/$step0);
                }
            }
            
// Make the lower positions
            
if ( isset( $area[$ci-1] ) )
            {
                for ( 
$i=$numbars-1$i>=0$i-- )
                {
                    
$area[$ci][] = $area[$ci-1][$i*2];
                    
$area[$ci][] = $area[$ci-1][$i*2+1];
                }
            }
            else
            {
                
$area[$ci][] = $area[$ci][($numbars-1)*2];
                
$area[$ci][] = $this->grapharea['y1'];
                
$area[$ci][] = $area[$ci][0];
                
$area[$ci][] = $this->grapharea['y1'];
            }

            if ( 
$this->options['style3D'] == )
            {
                
//-----------------------------------------
                // Make the 3D effect
                //-----------------------------------------
                
if ( !isset( $this->color$ci ] ) ) $this->color$ci ] = explode","$this->_getSliceColor$this->data['yaxis'][$ci]['color'] ) );
                
$areashadowcolor imagecolorallocate$this->image, ($this->color[$ci][0]-50)<0?0:$this->color[$ci][0]-50, ($this->color[$ci][1]-50)<0?0:$this->color[$ci][1]-50, ($this->color[$ci][2]-50)<0?0:$this->color[$ci][2]-50 );

                
$areashadow = array( $area[$ci][($numbars-1)*2], $area[$ci][($numbars-1)*2+1], $area[$ci][$numbars*2], $area[$ci][$numbars*2+1],
                                     
$area[$ci][$numbars*2]+20$area[$ci][$numbars*2+1]-20$area[$ci][($numbars-1)*2]+20$area[$ci][($numbars-1)*2+1]-20 );
                
imagefilledpolygon$this->image$areashadow4$areashadowcolor );
            }
        }

        if ( 
$this->options['style3D'] == )
        {
            
//-----------------------------------------
            // Make the upper 3D effect
            //-----------------------------------------
            
$areashadowcolor imagecolorallocate$this->image, ($this->color[$numareas-1][0]-25)<0?0:$this->color[$numareas-1][0]-25, ($this->color[$numareas-1][1]-25)<0?0:$this->color[$numareas-1][1]-25, ($this->color[$numareas-1][2]-25)<0?0:$this->color[$numareas-1][2]-25 );

            for ( 
$i=1$i<$numbars$i++ )
            {
                
$areashadow = array( $area[$numareas-1][($i-1)*2], $area[$numareas-1][($i-1)*2+1],
                                     
$area[$numareas-1][$i*2], $area[$numareas-1][$i*2+1],
                                     
$area[$numareas-1][$i*2]+20$area[$numareas-1][$i*2+1]-20,
                                     
$area[$numareas-1][($i-1)*2]+20$area[$numareas-1][($i-1)*2+1]-20 );
                
imagefilledpolygon$this->image$areashadowcount($areashadow)/2$areashadowcolor );
            }
        }

        
//-----------------------------------------
        // Draw the area's
        //-----------------------------------------
        
foreach( $area as $ci => $series )
        {
            if ( !isset( 
$this->color$ci ] ) ) $this->color$ci ] = explode","$this->_getSliceColor$this->data['yaxis'][$ci]['color'] ) );
            
$areacolor imagecolorallocate$this->image$this->color[$ci][0], $this->color[$ci][1], $this->color[$ci][2] );
            
imagefilledpolygon$this->image$seriescount($series)/2$areacolor );
            
imagecolordeallocate$this->image$areacolor );
        }

        
//-----------------------------------------
        // Fix the axes
        //-----------------------------------------
        
imageline$this->image$this->grapharea['x0'], $this->grapharea['y1'], $this->grapharea['x1'], $this->grapharea['y1'], $this->black );
        
imageline$this->image$this->grapharea['x0'], $this->grapharea['y0'], $this->grapharea['x0'], $this->grapharea['y1'], $this->black );

        if ( 
$this->options['style3D'] == )
        {
            
imageline$this->image$this->grapharea['x1']+20$this->grapharea['y1']-20$this->grapharea['x1'], $this->grapharea['y1'], $this->black );
            
imageline$this->image$this->grapharea['x1']+20$this->grapharea['y1']-20$this->grapharea['x1']+20$this->grapharea['y0']-20$this->black );
        }
        else
        {
            
imageline$this->image$this->grapharea['x1'], $this->grapharea['y1'], $this->grapharea['x1'], $this->grapharea['y0'], $this->black );
        }

        
//-----------------------------------------
        // Datalabels
        //-----------------------------------------
        
if ( $this->options['showdatalabels'] )
        {
            
$value = array();
            for ( 
$ci=0$ci<$numareas$ci++ )
            {
                for ( 
$i=0$i<$numbars$i++ )
                {
                    
// Calculate the positions of the area
                    
if ( isset( $value[$i] ) )
                    {
                        
$value[$i] += $this->data['yaxis'][$ci]['data'][$i];
                    }
                    else
                    {
                        
$value[$i] = $this->data['yaxis'][$ci]['data'][$i];
                    }

                    
$valuecolor  ImageColorAllocate($this->imagehexdec(substr($this->options['textcolor'],1,2)), hexdec(substr($this->options['textcolor'],3,2)), hexdec(substr($this->options['textcolor'],5,2)));
                    
$valshadecolor imagecolorallocate$this->image, ($this->color[$ci][0]-50)<0?0:$this->color[$ci][0]-50, ($this->color[$ci][1]-50)<0?0:$this->color[$ci][1]-50, ($this->color[$ci][2]-50)<0?0:$this->color[$ci][2]-50 );
                    if ( 
$this->use_ttf )
                    {
                        
$txtsize     imagettfbbox('10'0$this->options['font'], $value[$i] );
                        
$textx       $area[$ci][$i*2] - round(($txtsize[2]-$txtsize[0])/2,0);
                        
$texty       $area[$ci][$i*2+1] - 3;

                        
imagettftext($this->image"10"0$textx-1$texty-1$valshadecolor$this->options['font'], $value[$i] );
                        
imagettftext($this->image"10"0$textx+1$texty+1$valshadecolor$this->options['font'], $value[$i] );
                        
imagettftext($this->image"10"0$textx+2$texty+2$valshadecolor$this->options['font'], $value[$i] );
                        
imagettftext($this->image"10"0$textx$texty$valuecolor$this->options['font'], $value[$i] );
                    }
                    else
                    {
                        
$textx       $area[$ci][$i*2] - round(imagefontwidth($this->fontsize)*strlen($value[$i])/2,0);
                        
$texty       $area[$ci][$i*2+1] - imagefontheight($this->fontsize) - 3;

                        
imagestring($this->image$this->fontsize$textx-1$texty-1$value[$i], $valshadecolor );
                        
imagestring($this->image$this->fontsize$textx+1$texty+1$value[$i], $valshadecolor );
                        
imagestring($this->image$this->fontsize$textx+2$texty+2$value[$i], $valshadecolor );
                        
imagestring($this->image$this->fontsize$textx$texty$value[$i], $valuecolor);
                    }
                    
imagecolordeallocate$this->image$valuecolor );
                    
imagecolordeallocate$this->image$valshadecolor );
                }
            }
        }

        return 
true;
    }

    
/**
     * Generate Scatter Plot (XY Chart)
     *
     * @return    @e void
     */
    
protected function _drawXY()
    {
        
//-----------------------------------------
        // Draw Legend and Axes
        //-----------------------------------------
        
$this->legend = array ( $this->data['yaxis'][1]['name'] );
        if ( !
$this->_drawLegend() ) return false;
        
$this->x_axis = array( 'type'    => 'numeric',
                               
'min'    => 0,
                               
'max'    => $this->_getMax$this->data['yaxis'][0]['data'] )
                             );
        
$this->y_axis = array( 'type'    => 'numeric',
                               
'min'    => 0,
                               
'max'    => $this->_getMax$this->data['yaxis'][1]['data'] )
                             );
        
$this->_drawAxes();

        
//-----------------------------------------
        // Allocate text and shadow cols
        //-----------------------------------------
        
$textcolor   imagecolorallocate$this->imagehexdec(substr($this->options['titlecolor'],1,2)), hexdec(substr($this->options['titlecolor'],3,2)), hexdec(substr($this->options['titlecolor'],5,2)));
        
$shadowcolor imagecolorallocate$this->imagehexdec(substr($this->options['titleshadow'],1,2)), hexdec(substr($this->options['titleshadow'],3,2)), hexdec(substr($this->options['titleshadow'],5,2)));
        if ( !isset( 
$this->color] ) ) $this->color] = explode","$this->_getSliceColor$this->data['yaxis'][$ci]['color'] ) );

        
//-----------------------------------------
        // Calculate bar display variables
        //-----------------------------------------
        
$numbars count$this->data['yaxis'][0]['data'] );
        
$maxvalue1 $this->_getMax$this->data['yaxis'][0]['data'] );
        
$maxvalue2 $this->_getMax$this->data['yaxis'][1]['data'] );

        
$numticks $this->options['numticks'] > $maxvalue1 floor($maxvalue1) : $this->options['numticks'];
        
$step1 floor$maxvalue1 $numticks );
        
$steps ceil$maxvalue1 $step1 );
        
$stepwidth = ( $this->grapharea['x1'] - $this->grapharea['x0'] ) / $steps;

        
$numticks $this->options['numticks'] > $maxvalue2 floor($maxvalue2) : $this->options['numticks'];
        
$step2 floor$maxvalue2 $numticks );
        
$steps ceil$maxvalue2 $step2 );
        
$stepheight = ( $this->grapharea['y1'] - $this->grapharea['y0'] ) / $steps;

        
$dotcolor imagecolorallocate$this->image$this->color[0][0], $this->color[0][1], $this->color[0][2] );
        
$dotshadowcolor imagecolorallocate$this->image, ($this->color[0][0]-50)<0?0:$this->color[0][0]-50, ($this->color[0][1]-50)<0?0:$this->color[0][1]-50, ($this->color[0][2]-50)<0?0:$this->color[0][2]-50 );

        
//-----------------------------------------
        // Dots
        //-----------------------------------------
        
for ( $i=0$i<$numbars$i++ )
        {

            
$value1 $this->data['yaxis'][0]['data'][$i];
            
$value2 $this->data['yaxis'][1]['data'][$i];

            
//-----------------------------------------
            // Find out the bar location and size
            //-----------------------------------------
            
$x1 round$this->grapharea['x0'] + $value1 $stepwidth/$step1);
            
$y1 round$this->grapharea['y1'] - $value2 $stepheight/$step2);

            
//-----------------------------------------
            // Dot
            //-----------------------------------------

            
imagefilledellipse$this->image$x1+1$y1+177$dotshadowcolor );
            
imagefilledellipse$this->image$x1$y177$dotcolor );

            
//-----------------------------------------
            // Datalabels
            //-----------------------------------------
            
if ( $this->options['showdatalabels'] )
            {
                
$valuecolor  ImageColorAllocate($this->imagehexdec(substr($this->options['textcolor'],1,2)), hexdec(substr($this->options['textcolor'],3,2)), hexdec(substr($this->options['textcolor'],5,2)));
                
$valshadecolor imagecolorallocate$this->image, ($this->color[0][0]-50)<0?0:$this->color[0][0]-50, ($this->color[0][1]-50)<0?0:$this->color[0][1]-50, ($this->color[0][2]-50)<0?0:$this->color[0][2]-50 );

                
$datalabel '('.$value1.','.$value2.')';

                if ( 
$this->use_ttf )
                {
                    
$txtsize     imagettfbbox('10'0$this->options['font'], $datalabel );
                    
$textx       $x1 round(($txtsize[2]-$txtsize[0])/2,0);
                    
$texty       $y1 7;

                    
imagettftext($this->image"10"0$textx-1$texty-1$valshadecolor$this->options['font'], $datalabel);
                    
imagettftext($this->image"10"0$textx+1$texty+1$valshadecolor$this->options['font'], $datalabel);
                    
imagettftext($this->image"10"0$textx+2$texty+2$valshadecolor$this->options['font'], $datalabel);
                    
imagettftext($this->image"10"0$textx$texty$valuecolor$this->options['font'], $datalabel);
                }
                else
                {
                    
$textx       $x1 round(imagefontwidth($this->fontsize)*strlen($datalabel)/2,0);
                    
$texty       $y1 imagefontheight($this->fontsize)-7;

                    
imagestring($this->image$this->fontsize$textx-1$texty-1$datalabel$valshadecolor);
                    
imagestring($this->image$this->fontsize$textx+1$texty+1$datalabel$valshadecolor);
                    
imagestring($this->image$this->fontsize$textx+2$texty+2$datalabel$valshadecolor);
                    
imagestring($this->image$this->fontsize$textx$texty$datalabel$valuecolor);
                }

                
imagecolordeallocate$this->image$valuecolor );
                
imagecolordeallocate$this->image$valshadecolor );
            }
        }
        
imagecolordeallocate$this->image$dotcolor );
        
imagecolordeallocate$this->image$shadowcolor );

        return 
true;
    }

    
/**
     * Generate Bubble Plot
     *
     * @return    @e void
     */
    
protected function _drawBubble()
    {
        
//-----------------------------------------
        // Draw Legend and Axes
        //-----------------------------------------
        
$this->legend = array ( $this->data['yaxis'][2]['name'] );
        if ( !
$this->_drawLegend() ) return false;
        
$this->x_axis = array( 'type'    => 'numeric',
                               
'min'    => 0,
                               
'max'    => $this->_getMax$this->data['yaxis'][0]['data'] )
                             );
        
$this->y_axis = array( 'type'    => 'numeric',
                               
'min'    => 0,
                               
'max'    => $this->_getMax$this->data['yaxis'][1]['data'] )
                             );
        
$this->_drawAxes();

        
//-----------------------------------------
        // Allocate text and shadow cols
        //-----------------------------------------
        
$textcolor   imagecolorallocate$this->imagehexdec(substr($this->options['titlecolor'],1,2)), hexdec(substr($this->options['titlecolor'],3,2)), hexdec(substr($this->options['titlecolor'],5,2)));
        
$shadowcolor imagecolorallocate$this->imagehexdec(substr($this->options['titleshadow'],1,2)), hexdec(substr($this->options['titleshadow'],3,2)), hexdec(substr($this->options['titleshadow'],5,2)));
        if ( !isset( 
$this->color] ) ) $this->color] = explode","$this->_getSliceColor$this->data['yaxis'][$ci]['color'] ) );

        
//-----------------------------------------
        // Calculate bar display variables
        //-----------------------------------------
        
$numbars count$this->data['yaxis'][0]['data'] );
        
$maxvalue1 $this->_getMax$this->data['yaxis'][0]['data'] );
        
$maxvalue2 $this->_getMax$this->data['yaxis'][1]['data'] );
        
$maxvalue3 $this->_getMax$this->data['yaxis'][2]['data'] );

        
$numticks $this->options['numticks'] > $maxvalue1 floor($maxvalue1) : $this->options['numticks'];
        
$step1 floor$maxvalue1 $numticks );
        
$steps ceil$maxvalue1 $step1 );
        
$stepwidth = ( $this->grapharea['x1'] - $this->grapharea['x0'] ) / $steps;

        
$numticks $this->options['numticks'] > $maxvalue2 floor($maxvalue2) : $this->options['numticks'];
        
$step2 floor$maxvalue2 $numticks );
        
$steps ceil$maxvalue2 $step2 );
        
$stepheight = ( $this->grapharea['y1'] - $this->grapharea['y0'] ) / $steps;

        
// Largest bubble size is 1 ticksize (largest x vs y)
        
$maxbubblesize = ( $stepwidth $stepheight ) ? $stepwidth $stepheight;

        
$dotcolor imagecolorallocate$this->image$this->color[0][0], $this->color[0][1], $this->color[0][2] );
        
$dotshadowcolor imagecolorallocate$this->image, ($this->color[0][0]-50)<0?0:$this->color[0][0]-50, ($this->color[0][1]-50)<0?0:$this->color[0][1]-50, ($this->color[0][2]-50)<0?0:$this->color[0][2]-50 );

        
//-----------------------------------------
        // Dots
        //-----------------------------------------
        
for ( $i=0$i<$numbars$i++ )
        {

            
$value1 $this->data['yaxis'][0]['data'][$i];
            
$value2 $this->data['yaxis'][1]['data'][$i];
            
$value3 $this->data['yaxis'][2]['data'][$i];

            
//-----------------------------------------
            // Find out the bar location and size
            //-----------------------------------------
            
$x1 round$this->grapharea['x0'] + $value1 $stepwidth/$step1);
            
$y1 round$this->grapharea['y1'] - $value2 $stepheight/$step2);
            
$bubblesize round( ( $value3 $maxvalue3 ) * $maxbubblesize);

            
//-----------------------------------------
            // Bubble
            //-----------------------------------------
            
imagefilledellipse$this->image$x1+1$y1+1$bubblesize$bubblesize$dotshadowcolor );
            
imagefilledellipse$this->image$x1$y1$bubblesize$bubblesize$dotcolor );

            
//-----------------------------------------
            // Datalabels
            //-----------------------------------------
            
if ( $this->options['showdatalabels'] )
            {
                
$valuecolor  ImageColorAllocate($this->imagehexdec(substr($this->options['textcolor'],1,2)), hexdec(substr($this->options['textcolor'],3,2)), hexdec(substr($this->options['textcolor'],5,2)));
                
$valshadecolor imagecolorallocate$this->image, ($this->color[0][0]-50)<0?0:$this->color[0][0]-50, ($this->color[0][1]-50)<0?0:$this->color[0][1]-50, ($this->color[0][2]-50)<0?0:$this->color[0][2]-50 );

                
$datalabel '('.$value1.','.$value2.','.$value3.')';

                if ( 
$this->use_ttf )
                {
                    
$txtsize     imagettfbbox('10'0$this->options['font'], $datalabel );
                    
$textx       $x1 round(($txtsize[2]-$txtsize[0])/2,0);
                    
$texty       $y1 - ( $bubblesize ) / 2;

                    
imagettftext($this->image"10"0$textx-1$texty-1$valshadecolor$this->options['font'], $datalabel);
                    
imagettftext($this->image"10"0$textx+1$texty+1$valshadecolor$this->options['font'], $datalabel);
                    
imagettftext($this->image"10"0$textx+2$texty+2$valshadecolor$this->options['font'], $datalabel);
                    
imagettftext($this->image"10"0$textx$texty$valuecolor$this->options['font'], $datalabel);
                }
                else
                {
                    
$textx       $x1 round(imagefontwidth($this->fontsize)*strlen($datalabel)/2,0);
                    
$texty       $y1 imagefontheight($this->fontsize)-7;

                    
imagestring($this->image$this->fontsize$textx-1$texty-1$datalabel$valshadecolor);
                    
imagestring($this->image$this->fontsize$textx+1$texty+1$datalabel$valshadecolor);
                    
imagestring($this->image$this->fontsize$textx+2$texty+2$datalabel$valshadecolor);
                    
imagestring($this->image$this->fontsize$textx$texty$datalabel$valuecolor);
                }

                
imagecolordeallocate$this->image$valuecolor );
                
imagecolordeallocate$this->image$valshadecolor );
            }
        }
        
imagecolordeallocate$this->image$dotcolor );
        
imagecolordeallocate$this->image$shadowcolor );

        return 
true;
    }

    
/**
     * Generate Funnel Chart
     *
     * @return    @e void
     */
    
protected function _drawFunnel()
    {
        
//-----------------------------------------
        // Draw Axes
        //-----------------------------------------
        
$numcats count$this->data['xaxis'] );
        for ( 
$i $numcats 1$i >= 0$i-- )
        {
            
$labels[$i] = $this->data['xaxis'][$numcats-1-$i];
        }
        
$this->y_axis = array( 'type'    => 'labels',
                               
'labels'    => $labels
                             
);
        
$this->_drawAxes();

        
//-----------------------------------------
        // Allocate text and shadow cols
        //-----------------------------------------
        
$textcolor   imagecolorallocate$this->imagehexdec(substr($this->options['titlecolor'],1,2)), hexdec(substr($this->options['titlecolor'],3,2)), hexdec(substr($this->options['titlecolor'],5,2)));
        
$shadowcolor imagecolorallocate$this->imagehexdec(substr($this->options['titleshadow'],1,2)), hexdec(substr($this->options['titleshadow'],3,2)), hexdec(substr($this->options['titleshadow'],5,2)));

        
//-----------------------------------------
        // Calculate bar display variables
        //-----------------------------------------
        
$numbars count$this->data['yaxis'][0]['data'] );
        
$maxvalue $this->_getMax$this->data['yaxis'][0]['data'] );
        
$stepheight floor( ( $this->grapharea['y1'] - $this->grapharea['y0'] ) / $numbars );

        
$numticks $this->options['numticks'] > $maxvalue floor($maxvalue) : $this->options['numticks'];
        
$step floor$maxvalue $numticks );
        
$steps ceil$maxvalue $step );
        
$stepwidth = ( $this->grapharea['x1'] - $this->grapharea['x0'] ) / $steps;

        
$xmid $this->grapharea['x0'] + floor( ( $this->grapharea['x1'] - $this->grapharea['x0'] ) / );

        
// Get the colors
        
for ( $i $numcats 1$i >= 0$i-- )
        {
            if ( !isset( 
$this->color$i ] ) ) $this->color$i ] = explode","$this->_getSliceColor() );
        }


        for ( 
$i 0$i $numcats$i++ )
        {
            
$value $this->data['yaxis'][0]['data'][$numcats-1-$i];

            
$x0 $xmid round( ( $value $stepwidth $step ) / 2);
            
$x2 $xmid round( ( $value $stepwidth $step ) / 2);
            
$y1 $this->grapharea['y1'] - $i $stepheight 1;

            if ( isset( 
$this->data['yaxis'][0]['data'][$numcats-2-$i] ) )
            {
                
$nextval $this->data['yaxis'][0]['data'][$numcats-2-$i];
            }
            else
            {
                
$nextval $maxvalue;
            }

            
$x1 $xmid round( ( $nextval $stepwidth/$step ) / 2);
            
$x3 $xmid round( ( $nextval $stepwidth/$step ) / 2);
            
$y0 $y1 $stepheight 1;

            
$linecolor  ImageColorAllocate($this->image$this->color[$i][0], $this->color[$i][1], $this->color[$i][2] );

            if ( 
$this->options['style3D'] != )
            {
                
// 2D style
                
$points = array ( $x0$y1$x1$y0$x3$y0$x2$y1 );
                
imagefilledpolygon$this->image$points4$linecolor );
            }
            else
            {
                
//3D Style
                
for ( $j 0$j $stepheight$j++ )
                {
                    
$width = ( $x2 $x0 ) + round$j * (( $x3 $x1 ) - ( $x2 $x0 )) / $stepheight);
                    
$height floor ( ( ( $value + ( $j * ( $nextval $value ) / $stepheight ) ) / $maxvalue ) * 40 );
                    
$x $xmid 20;
                    
$y $y1 20 $j;
                    
imagefilledarc$this->image$x$y$width$height0180$linecolorIMG_ARC_PIE );
                }
            }

            
//-----------------------------------------
            // Datalabels
            //-----------------------------------------
            
if ( $this->options['showdatalabels'] )
            {
                
$textcolor  ImageColorAllocate($this->imagehexdec(substr($this->options['textcolor'],1,2)), hexdec(substr($this->options['textcolor'],3,2)), hexdec(substr($this->options['textcolor'],5,2)));
                
$shadowcolor imagecolorallocate$this->image, ($this->color[$i][0]-50)<0?0:$this->color[$i][0]-50, ($this->color[$i][1]-50)<0?0:$this->color[$i][1]-50, ($this->color[$i][2]-50)<0?0:$this->color[$i][2]-50 );

                if ( 
$nextval == )
                {
                    
$label $value.' (100%)';
                }
                else
                {
                    
$label $value.' ('.round(($value/$nextval)*100,1).'%)';
                }
                if ( 
$this->use_ttf )
                {
                    
$txtsize     imagettfbbox('10'0$this->options['font'], $label );
                    
$textx       $xmid round(($txtsize[2]-$txtsize[0])/2,0);
                    
$texty       $y0 floor$stepheight ) + floor(($txtsize[1]-$txtsize[5])/2);

                    if ( 
$this->options['style3D'] )
                    {
                        
$correction floor ( ( ( $nextval - (($nextval $value) / ) ) / $maxvalue ) * 20 );
                        
$textx $textx 20 $correction;
                        
$texty $texty 20 $correction;
                    }

                    
imagettftext($this->image"10"0$textx-1$texty-1$shadowcolor$this->options['font'], $label);
                    
imagettftext($this->image"10"0$textx+1$texty+1$shadowcolor$this->options['font'], $label);
                    
imagettftext($this->image"10"0$textx+2$texty+2$shadowcolor$this->options['font'], $label);
                    
imagettftext($this->image"10"0$textx$texty$textcolor$this->options['font'], $label);
                }
                else
                {
                    
$textx       $xmid round(imagefontwidth($this->fontsize)*strlen($label)/2,0);
                    
$texty       = ($textx $this->grapharea['x0']+2) ? $this->grapharea['x0']+$textx;
                    
$texty       $y0 +  + floor$stepheight ) - floor(imagefontheight($this->fontsize)/2);

                    if ( 
$this->options['style3D'] )
                    {
                        
$correction floor ( ( ( $nextval - (($nextval $value) / ) ) / $maxvalue ) * 20 );
                        
$textx $textx 20 $correction;
                        
$texty $texty 20 $correction;
                    }

                    
$shadowcolor imagecolorallocate$this->image, ($this->color[$i][0]-50)<0?0:$this->color[$i][0]-50, ($this->color[$i][1]-50)<0?0:$this->color[$i][1]-50, ($this->color[$i][2]-50)<0?0:$this->color[$i][2]-50 );
                    
imagestring($this->image$this->fontsize$textx-1$texty-1$label$shadowcolor);
                    
imagestring($this->image$this->fontsize$textx+1$texty+1$label$shadowcolor);
                    
imagestring($this->image$this->fontsize$textx+2$texty+2$label$shadowcolor);
                    
imagestring($this->image$this->fontsize$textx$texty$label$textcolor);
                }

                
imagecolordeallocate$this->image$shadowcolor );
                
imagecolordeallocate$this->image$textcolor );
            }
        }

        if ( 
$this->options['style3D'] )
        {
            
$insidecolor =  imagecolorallocate$this->image, ($this->color[$numcats 1][0]-50)<0?0:$this->color[$numcats 1][0]-50, ($this->color[$numcats 1][1]-50)<0?0:$this->color[$numcats 1][1]-50, ($this->color[$numcats 1][2]-50)<0?0:$this->color[$numcats 1][2]-50 );
            
imagefilledarc$this->image$xmid 20$y0 20$x3 $x1400360$insidecolorIMG_ARC_PIE );
            
$linecolor  ImageColorAllocate($this->image$this->color[$numcats 1][0], $this->color[$numcats 1][1], $this->color[$numcats 1][2] );
            
imagearc$this->image$xmid 20$y0 20$x3 $x1400360$linecolor );
        }

        return 
true;
    }

    
/**
     * Generate Radar Chart
     *
     * @return    @e void
     */
    
protected function _drawRadar()
    {
        
//-----------------------------------------
        // Draw Legend & Axes
        //-----------------------------------------
        
foreach ( $this->data['yaxis'] as $key => $series )
        {
            
$this->legend$key ] = $series['name'];
        }
        if ( !
$this->_drawLegend() ) return false;

        
//-----------------------------------------
        // Figure out center position
        //-----------------------------------------
        
$xmid $this->grapharea['x0'] + round( ( $this->grapharea['x1'] - $this->grapharea['x0'] ) / 20);
        
$ymid $this->grapharea['y0'] + round( ( $this->grapharea['y1'] - $this->grapharea['y0'] ) / 20);

        
//-----------------------------------------
        // Figure out size
        //-----------------------------------------
        
$maxlabelwidth 0;
        
$maxlabelheight 0;
        foreach( 
$this->data['xaxis'] as $label )
        {
            if ( 
$this->use_ttf )
            {
                
$textsize imagettfbbox(100$this->options['font'], $label );
                if ( (
$textsize[2] - $textsize[0]) > $maxlabelwidth $maxlabelwidth $textsize[2] - $textsize[0];
                if ( (
$textsize[1] - $textsize[5]) > $maxlabelheight $maxlabelheight $textsize[1] - $textsize[5];
            }
            else
            {
                
$textsize imagefontwidth$this->fontsize ) * strlen$label );
                if ( 
$textsize $maxlabelwidth $maxlabelwidth $textsize;
                
$maxlabelheight imagefontheight$this->fontsize );
            }
        }

        
$lengthx floor( ( $this->grapharea['x1'] - $this->grapharea['x0'] ) / $maxlabelwidth );
        
$lengthy floor( ( $this->grapharea['y1'] - $this->grapharea['y0'] ) / $maxlabelheight );
        
$armlength $lengthx $lengthy $lengthy $lengthx;
        
$numaxes count$this->data['yaxis'][0]['data'] );
        
$maxvalue $this->_getMax$this->data['yaxis'] );
        
$numticks $this->options['numticks'] > $maxvalue floor($maxvalue) : $this->options['numticks'];
        
$maxvalue ceil $maxvalue $numticks ) * $numticks;

        
//-----------------------------------------
        // Allocate text and shadow cols
        //-----------------------------------------
        
$textcolor   imagecolorallocate$this->imagehexdec(substr($this->options['titlecolor'],1,2)), hexdec(substr($this->options['titlecolor'],3,2)), hexdec(substr($this->options['titlecolor'],5,2)));
        
$shadowcolor imagecolorallocate$this->imagehexdec(substr($this->options['titleshadow'],1,2)), hexdec(substr($this->options['titleshadow'],3,2)), hexdec(substr($this->options['titleshadow'],5,2)));

        
//-----------------------------------------
        // A spider draws a web
        //-----------------------------------------
        
$webxy = array();
        
$webtick = array();
        
$textxy = array();
        for ( 
$i 0$i $numaxes$i++ )
        {
            
$rotation = -90 round$i 360 $numaxes);

            
// Web axes
            
$webxy[$i*2] = $xmid cos(deg2rad$rotation ) ) * $armlength;
            
$webxy[$i*2+1] = $ymid sin(deg2rad$rotation ) ) * $armlength;
            
imageline$this->image$xmid$ymid$webxy[$i*2], $webxy[$i*2+1], $this->black );

            
// Calculate web tick
            
for ( $j 0$j $this->options['numticks']; $j++ )
            {
                
$webtickxy[$j][$i*2] = $xmid cos(deg2rad$rotation ) ) * ( ( $j 1  )* $armlength / ( $this->options['numticks'] ) );
                
$webtickxy[$j][$i*2+1] = $ymid sin(deg2rad$rotation ) ) * ( ( $j ) * $armlength / ( $this->options['numticks'] ) );
            }

            
// Calculate the label positions
            
$label $this->data['xaxis'][$i];
            if ( 
$this->use_ttf )
            {
                
$textsize imagettfbbox(100$this->options['font'], $label );
                
$textwidth $textsize[4] - $textsize[0];
                
$textheight $textsize[1] - $textsize[5];
            }
            else
            {
                
$textwidth imagefontwidth($this->fontsize)*strlen($label);
                
$textheight imagefontheight($this->fontsize);
            }

            if ( 
$rotation > -90 && $rotation 90 )
            {
                
$textxy[] = $webxy[$i*2] + 5;
                
$textxy[] = $webxy[$i*2+1] + floor( ( $textheight ) / );
            }
            elseif ( 
$rotation == -90 )
            {
                
$textxy[] = $webxy[$i*2] - floor( ( $textwidth ) / );
                
$textxy[] = $webxy[$i*2+1] - 5;
            }
            elseif ( 
$rotation == 90 )
            {
                
$textxy[] = $webxy[$i*2] - floor( ( $textwidth ) / );
                
$textxy[] = $webxy[$i*2+1] + $textheight;
            }
            else
            {
                
$textxy[] = $webxy[$i*2] - - ( $textwidth );
                
$textxy[] = $webxy[$i*2+1] + floor( ( $textheight ) / );
            }

            
// Draw the labels
            
if ( $this->use_ttf )
            {
                
imagettftext($this->image"10"0$textxy[$i*2]+1$textxy[$i*2+1]+1$shadowcolor$this->options['font'], $label );
                
imagettftext($this->image"10"0$textxy[$i*2]  , $textxy[$i*2+1]  , $textcolor  $this->options['font'], $label );
            }
            else
            {
                
imagestring($this->image$this->fontsize$textxy[$i*2]+1$textxy[$i*2+1]+1-imagefontheight($this->fontsize), $label$shadowcolor);
                
imagestring($this->image$this->fontsize$textxy[$i*2], $textxy[$i*2+1]-imagefontheight($this->fontsize), $label$textcolor);
            }
        }

        
//-----------------------------------------
        // Draw the web lines
        //-----------------------------------------
        
foreach( $webtickxy as $tickxy )
        {
            
imagepolygon$this->image$tickxy$numaxes$this->black );
        }

        
//-----------------------------------------
        // Draw the axes value text
        //-----------------------------------------
        
$numticks $this->options['numticks'] > $maxvalue floor($maxvalue) : $this->options['numticks'];
        
$tick $maxvalue $numticks;
        for ( 
$j 0$j $this->options['numticks']; $j++ )
        {
            
$value = ($j 1) * $tick;
            if ( 
$this->use_ttf )
            {
                
$textsize imagettfbbox(100$this->options['font'], $value );
                
$textheight $textsize[1] - $textsize[5];
                
imagettftext($this->image"10"0$webtickxy[$j][0]+6$webtickxy[$j][1]+floor($textheight/2)+1$shadowcolor$this->options['font'], $value );
                
imagettftext($this->image"10"0$webtickxy[$j][0]+5$webtickxy[$j][1]+floor($textheight/2)  , $textcolor  $this->options['font'], $value );
            }
            else
            {
                
imagestring($this->image$this->fontsize$webtickxy[$j][0]+6$webtickxy[$j][1]-floor(imagefontheight($this->fontsize)/2)+1$value$shadowcolor );
                
imagestring($this->image$this->fontsize$webtickxy[$j][0]+5$webtickxy[$j][1]-floor(imagefontheight($this->fontsize)/2)  , $value$textcolor );
            }
        }

        
//-----------------------------------------
        // Draw the series
        //-----------------------------------------
        
$numseries count$this->data['yaxis'] );
        for ( 
$ci 0$ci $numseries$ci++ )
        {
            if ( !isset( 
$this->color$ci ] ) ) $this->color$ci ] = explode","$this->_getSliceColor$this->data['yaxis'][$ci]['color'] ) );
            
$linecolor   ImageColorAllocate$this->image$this->color[$ci][0], $this->color[$ci][1], $this->color[$ci][2] );
            
$dotcolor imagecolorallocate$this->image$this->color[$ci][0], $this->color[$ci][1], $this->color[$ci][2] );
            
$dotshadowcolor imagecolorallocate$this->image, ($this->color[$ci][0]-50)<0?0:$this->color[$ci][0]-50, ($this->color[$ci][1]-50)<0?0:$this->color[$ci][1]-50, ($this->color[$ci][2]-50)<0?0:$this->color[$ci][2]-50 );

            
//-----------------------------------------
            // Get the x and y's for the lines
            //-----------------------------------------
            
$linesxy = array();
            
$lineshadowxy = array();
            
$textxy = array();
            for ( 
$i 0$i $numaxes$i++ )
            {
                
$value $this->data['yaxis'][$ci]['data'][$i];

                
$rotation = -90 round$i 360 $numaxes);
                
$linesxy[$i*2] = $xmid cos(deg2rad$rotation ) ) * floor( ( $value $maxvalue ) * $armlength );
                
$linesxy[$i*2+1] = $ymid sin(deg2rad$rotation ) ) * floor( ( $value $maxvalue ) * $armlength );
                
$lineshadowxy[$i*2] = $linesxy[$i*2] + 1;
                
$lineshadowxy[$i*2+1] = $linesxy[$i*2+1] + 1;

                if ( 
$this->options['showdatalabels'] )
                {
                    
// Calculate the datalabel positions
                    
$textxy[$i*2] = $xmid cos(deg2rad$rotation ) ) * floor( ( $value $maxvalue ) * $armlength );
                    
$textxy[$i*2+1] = $ymid sin(deg2rad$rotation ) ) * floor( ( $value $maxvalue ) * $armlength );

                    if ( 
$this->use_ttf )
                    {
                        
$textsize imagettfbbox(100$this->options['font'], $value );
                        
$textwidth $textsize[4] - $textsize[0];
                        
$textheight $textsize[1] - $textsize[5];
                    }
                    else
                    {
                        
$textwidth imagefontwidth($this->fontsize)*strlen($value);
                        
$textheight imagefontheight($this->fontsize);
                    }

                    if ( 
$rotation > -90 && $rotation 90 )
                    {
                        
$textxy[$i*2] = $textxy[$i*2] + 5;
                        
$textxy[$i*2+1] = $textxy[$i*2+1] + floor( ( $textheight ) / );
                    }
                    elseif ( 
$rotation == -90 )
                    {
                        
$textxy[$i*2] = $textxy[$i*2] - floor( ( $textwidth ) / );
                        
$textxy[$i*2+1] = $textxy[$i*2+1] - 5;
                    }
                    elseif ( 
$rotation == 90 )
                    {
                        
$textxy[$i*2] = $textxy[$i*2] - floor( ( $textwidth ) / );
                        
$textxy[$i*2+1] = $textxy[$i*2+1] + $textheight;
                    }
                    else
                    {
                        
$textxy[$i*2] = $textxy[$i*2] - - ( $textwidth );
                        
$textxy[$i*2+1] = $textxy[$i*2+1] + floor( ( $textheight ) / );
                    }
                }
            }

            
//-----------------------------------------
            // Draw the lines, dots and text
            //-----------------------------------------
            
imagepolygon$this->image$linesxy$numaxes$linecolor );
            
imagepolygon$this->image$lineshadowxy$numaxes$dotshadowcolor );

            
$valuecolor  ImageColorAllocate($this->imagehexdec(substr($this->options['textcolor'],1,2)), hexdec(substr($this->options['textcolor'],3,2)), hexdec(substr($this->options['textcolor'],5,2)));
            
$valshadecolor imagecolorallocate$this->image, ($this->color[$ci][0]-50)<0?0:$this->color[$ci][0]-50, ($this->color[$ci][1]-50)<0?0:$this->color[$ci][1]-50, ($this->color[$ci][2]-50)<0?0:$this->color[$ci][2]-50 );

            for( 
$i 0$i $numaxes$i++ )
            {
                
imagefilledellipse$this->image$linesxy[$i*2]+1$linesxy[$i*2+1]+177$dotshadowcolor );
                
imagefilledellipse$this->image$linesxy[$i*2], $linesxy[$i*2+1], 77$dotcolor );

                if ( 
$this->options['showdatalabels'] )
                {
                    
$value $this->data['yaxis'][$ci]['data'][$i];
                    if ( 
$this->use_ttf )
                    {
                        
imagettftext($this->image"10"0$textxy[$i*2]-1$textxy[$i*2+1]-1$valshadecolor$this->options['font'], $value );
                        
imagettftext($this->image"10"0$textxy[$i*2]+1$textxy[$i*2+1]+1$valshadecolor$this->options['font'], $value );
                        
imagettftext($this->image"10"0$textxy[$i*2]+2$textxy[$i*2+1]+2$valshadecolor$this->options['font'], $value );
                        
imagettftext($this->image"10"0$textxy[$i*2]  , $textxy[$i*2+1]  , $valuecolor  $this->options['font'], $value );
                    }
                    else
                    {
                        
imagestring($this->image$this->fontsize$textxy[$i*2]-1$textxy[$i*2+1]-1-imagefontheight($this->fontsize), $label$valshadecolor);
                        
imagestring($this->image$this->fontsize$textxy[$i*2]+1$textxy[$i*2+1]+1-imagefontheight($this->fontsize), $label$valshadecolor);
                        
imagestring($this->image$this->fontsize$textxy[$i*2]+2$textxy[$i*2+1]+2-imagefontheight($this->fontsize), $label$valshadecolor);
                        
imagestring($this->image$this->fontsize$textxy[$i*2]  , $textxy[$i*2+1]  -imagefontheight($this->fontsize), $label$valuecolor);
                    }
                }
            }

            
imagecolordeallocate$this->image$linecolor );
            
imagecolordeallocate$this->image$dotcolor );
            
imagecolordeallocate$this->image$dotshadowcolor );
            
imagecolordeallocate$this->image$valshadecolor );
            
imagecolordeallocate$this->image$valuecolor );
        }

        return 
true;
    }

    
/**
     * Get a random color
     *
     * @return    @e string
     */
    
protected function _getSliceColor$force_color='' )
    {
        
# Remove 0,0,0 from count
        
$used_count count$this->used_colors ) - 1;
        
$return     "";

        
# Used all std cols
        
if ( $force_color )
        {
            
$r hexdecsubstr$force_color1) );
            
$g hexdecsubstr$force_color3) );
            
$b hexdecsubstr$force_color5) );
            
$return "$r,$g,$b";
            
$this->used_colors[] = $return;
        }
        elseif ( 
$used_count count$this->colors ) )
        {
            
$this->used_colors[] = $this->colors$used_count ];
            
$return $this->colors$used_count ];
        }
        else
        {
            
# 0-12 for each RGB bit == 1728 poss col. combinations
           
for ( $i $i <= 1728 $i++ )
           {
               
$r mt_rand012 ) * 20;
               
$g mt_rand012 ) * 20;
               
$b mt_rand012 ) * 20;

               
$return "$r,$g,$b";

               if ( ! 
in_array$return$this->used_colors ) )
               {
                   
$this->used_colors[] = $return;
                   break;
               }
               else
               {
                   continue;
               }
           }
        }

        return 
$return;
    }

    
/**
     * Get maximum value from the y-axis data array's
     *
     * @param    array        Array of Y-axis data serie(s)
     * @return    @e int
     */
    
protected function _getMax$data=array() )
    {
        
$maxval 0;
        foreach( 
$data as $series )
        {
            if ( 
is_array$series ) )
            {
                foreach( 
$series['data'] as $value )
                {
                    if ( 
$value $maxval $maxval $value;
                }
            }
            else
            {
                if ( 
$series $maxval $maxval $series;
            }
        }
        return 
$maxval;
    }

    
/**
     * Check the series required for graph
     *
     * @param    int            Minimum number of series
     * @param    boolean        Check labels exist
     * @return    @e boolean
     */
    
protected function _checkSeries$minseries=0$labelsRequired=)
    {
        
//-----------------------------------------
        // Check series
        //-----------------------------------------
        
if ( !isset( $this->data['yaxis'][$minseries-1]['data'] ) )
        {
            
$this->_error'Должно быть не менее '.$minseries.' меток для добавления на ''.$this->options['charttype'].'' график.' );
            return 
false;
        }
        if ( 
$labelsRequired && ( !isset( $this->data['xaxis'] ) or !is_array$this->data['xaxis'] ) ) )
        {
            
$this->_error'Необходимо добавить метки на график.' );
            return 
false;
        }
        
$cntseries count$this->data['yaxis'][0]['data'] );
        foreach( 
$this->data['yaxis'] as $series )
        {
            if ( 
$cntseries != count$series['data'] ) )
            {
                
$this->_error'Не все ряды имеют одинаково колчиество чисел.' );
                return 
false;
            }
        }
        if ( 
$labelsRequired && count$this->data['xaxis'] ) != count$this->data['yaxis'][0]['data'] ) )
        {
            
$this->_error'Число меток не совпадает с числом рядов.' );
            return 
false;
        }
        foreach( 
$this->data['yaxis'] as $series )
        {
            foreach( 
$series['data'] as $value )
            {
                if ( !
is_numeric$value ) )
                {
                    
$this->_error'Обнаружено не числовое значение. Данные в рядах должны быть числовыми.' );
                    return 
false;
                }
            }
        }
        return 
true;
    }

    
/**
     * Check if a color string is valid
     *
     * @param    string        Color HEX
     * @return    @e boolean
     */
    
protected function _checkColor$color='' )
    {
        if ( 
strlen$color ) != )
        {
            
$this->_error'Указан не верный код цвета. Код цвета должен быть указан в шестнадцатиричном формате. Например #FFFFFF для белого.' );
            return 
false;
        }
        elseif ( !
preg_match"#[0-9A-F]{6}#i"substr$color) ) )
        {
            
$this->_error'Указан не верный код цвета. Код цвета должен быть указан в шестнадцатиричном формате. Например #FFFFFF для белого.' );
            return 
false;
        }

        return 
true;
    }

    
/**
     * Error routine, display the error message in debug mode
     *
     * @param    string        Error message
     * @return    @e void
     */
    
protected function _error$msg='' )
    {
        
//-----------------------------------------
        // Destroy the original image
        //-----------------------------------------
        
if ( $this->image )
        {
            
imagedestroy$this->image );
        }

        
//-----------------------------------------
        // Start GD process
        //-----------------------------------------
        
$width $this->options['width'] < 400 400 $this->options['width'];
        
$height $this->options['height'] < 200 200 $this->options['height'];
        
$errorimage imagecreatetruecolor$width$height );
        
$bgcolor imagecolorallocate($errorimage255255255);
        
imagefilledrectangle$errorimage00$width$height$bgcolor );

        if ( 
function_exists('imageantialias') )
        {
            @
imageantialias$errorimageTRUE );
        }

        
//-----------------------------------------
        // Allocate black and grey
        //-----------------------------------------
        
$black imagecolorallocate$errorimage00);
        
$grey imagecolorallocate$errorimage170170170);

        
$messageheight 0;
        if ( 
$this->debug )
        {
            
//-----------------------------------------
            // Wordwrap the error message
            //-----------------------------------------
            
$errormessage '';
            while ( 
strlen$msg ) > 44 )
            {
                
$lastspace 0;
                for ( 
$j 0$j 44$j++ )
                {
                    if ( 
substr$msg$j) == ' ' )
                    {
                        
$lastspace $j;
                    }
                }
                
$errormessage .= substr$msg0$lastspace )."rn";
                
$msg substr$msg$lastspace+);
            }
            
$errormessage .= $msg;

            
$errormesssage "Error message:rn".$errormessage;

            
//-----------------------------------------
            // Calculate vertical size
            //-----------------------------------------
            
if ( $this->use_ttf )
            {
                
$txtsize    imagettfbbox'10'0$this->options['font'], $errormessage );
                
$messageheight $txtsize[1] - $txtsize[5];
            }
            else
            {
                
$msgarray explode"rn"$errormessage );
                foreach( 
$msgarray as $msgline )
                {
                    
$messageheight $messageheight imagefontheight) + 10;
                }
                
$messageheight -= 10;
            }

            
$messageheight += 40;
        }

        
//-----------------------------------------
        // Get the error icon
        //-----------------------------------------
        
$errorIconData base64_decode'R0lGODlhKQAlAPf/AP34o/75s6qGFOTi2/32jbKSIvXfTPHqy/Hx8fz3mfz2kvTcQfLx6dTDdf78ybaZNcStXPfjWqF8Df35uv'.
                                        
'7+3fz2kMWsRf34nf//+f33lPn5+cKnO/Hr1NHR0dnGTKyMJOzlzeDe1vvxb/rsedPMabmdN/TcRvjnababQfrrdvLXNbusRPzt'.
                                        
'f/vycv31nP32jsu1V83b6P795LOVNPzzefvydfz3l72kRuLXq+/v7/36renp6amGHXBtOpqOOO3ktPjlY/PaPvPZO/TeSfz0hP'.
                                        
'jmZvX19f78xvnqc/z1iPzwfdfGfcq1XqyLHVhULu3lvuHUlPz0i/31h6eCDJt1Bf76qf32iPz0gtPHmvzzdayJFf31fuHSjf37'.
                                        
'9Pzybvj15vfz4lZPHvHqwv3zkVhUKqB6Bvj13MauTvv57vj27vj168++Sv34mv31pP32iv31gfzzgPvzerStW9XCaP7911dRIv'.
                                        
'32hvz1jO3l0fvzeN3RptG+esOsU7iaMIeER/PYOP///fnobPnpb/LXM/bgT/bgU/vtfPjkXvHWMPzugfHVLvDULvzvg////PDU'.
                                        
'Lf3whffjV/v7+/DTLf//+v39+uzs7Pf39/3xh+Tk5NvWwf360f/+9ePZt9vb28y6df33jIeCP/biTvnsYPvte/XhTv32g9vMiL'.
                                        
'GPHXlwKse1Znt5QvzzfmJbI/3xiaSWN/fmV/rwgLufOvHXM9C5XP7+6/nparaXJreZL1ZPH2RiN3luKfzufvz8/P79/dzZxtfQ'.
                                        
'sbOsT766afvzmPrsc+vr6/ruafzzcqJ+Eb6hMd3bz/z1jvTbQPjoV/nugMS0Rc68QvHYOdfX18i2cOTZpvPfTv376f377oR6MP'.
                                        
'790P31hPjqYPbz3/joZ/rvZuLWm/DaS/3zhNfQrfnpcPnpcuPj4+3lxuLXpv33kvjtffPbQPvybMjGvfXfR/Dka/DUL/77w/37'.
                                        
'xv3yjf78wuDf2ubcsefn5/vwetnIdtzc3K+iQMGoStLDg9fFes/Pz5pzAMnY5iH5BAEAAP8ALAAAAAApACUAAAj/AP8JHEiwoE'.
                                        
'AOKKigAKHBoMOHEAmq+cCpFyceAzTEiMiR4w09RwAc0YNiR6SOKA3Sm7EJAIALm2ZgQZCy5j9KH/AEuHAhgQ48H+Y1tNlxHwQK'.
                                        
'PNkksEEBgrRKRDmiOaYGgFIbChQkSCMhmZGoEJnswXY1g4IKyuDt4WMSrMEDPLr0NFvhBYEoUbrw+EXTLcEHOCbYoPviTpIkRK'.
                                        
'rgmIFpqN9pD2gNzlDhjmEpRK7AkfFgXw6/Nz+AqJLh3ItguZz4IQJnVZxz5ZrMs+S3AQQ6pe32cMKbhOs4eRzwSVWJF1gwEtKw'.
                                        
'MU3AjSreTkjQyFOjRRyuvr5GPbNEXt3mUvw4/yFDhgaN6iJE6Ghwo61NuNYyECBgRUo2OeR7ZMnSQoQ6dV5UI0A4fdXUhzk6fO'.
                                        
'JGfdm8gR8ZoGRhjBfqdCMKM7BAUUBjNUFRAgWffJKEfW9sQQJ5wBSjzSuhsBPEHypMYIsnn6FEiQAcXPCJFVaUUsoWNLRTBy7O'.
                                        
'EDKECQssE4QQf5AixhSzodQAH9jsaAcc9gxTCxCH4BKGB4QYcOQCS8LYxgZ8QMURcmqcA44SI4gTyAlFcHlNGIWEOWaZKqRjRh'.
                                        
'mZaAeRBUsEsMsIKYwjyJx1HuIDKnmKiSSfgzQzRx/uOfSEFjKwMAqiSCxKJ5f5+BDpnkyqMIgsmggwE0S2eP/Txi6GgCpqo2us'.
                                        
'cOqkqQ6CCDdcnEKOYwRx0QcdidBqK6NcRgDJrmT2iogiMtJoUBcCHDBGsrWmECqzh3iwBrSUTjvEkyHQRtAsMLzDCLfLjuqDl7'.
                                        
'p8I2m0MPqqyCLCWKAPMQRtU8YX8byrrLe3AoGLl2E8c2+5+wrxZ6ADbcBPAI8Y3O23o67AShiu6MlrvtMu4gg6l9Zz0g9NyNBK'.
                                        
'xvAiDK6z5Eq7ryPutPoqMqYEcAnMB3PcKM0i46tqyY5IgsQ9tmDyz8Bj/KxxvEM/WzTEJksCzZ/RPI2GC1LHLHSzVj9sc9bU/N'.
                                        
'nBPxsw8QQgcMctt9yN1G33JHhjoPfefP8tAMMtazNwhhb+FG744YgnrjjiU8SyTicC5YBPB/1UbvnlmGeuOeYdQA6aWwEBADs=' );
        
$errorIcon imagecreatefromstring$errorIconData );

        
//-----------------------------------------
        // Draw the error box
        //-----------------------------------------
        
$ysize 80 $messageheight;
        
$x = ( $width 400 ) / 2;
        
$y = ( $height $ysize ) / 2;
        
imagecopymerge$errorimage$errorIcon$x 20$y 2000imagesx$errorIcon ), imagesy$errorIcon ), 100 );
        
imagedestroy$errorIcon );

        
imagerectangle$errorimage$x+1$y+1$x+400$y+$ysize+1$grey );
        
imagerectangle$errorimage$x$y$x+399$y+$ysize$black );

        
//-----------------------------------------
        // Display the error text
        //-----------------------------------------
        
$message 'Error generating graph';
        if ( 
$this->use_ttf )
        {
            
imagettftext$errorimage"20"0$x+101$y+48$grey$this->options['font'], $message );
            
imagettftext$errorimage"20"0$x+100$y+47$black$this->options['font'], $message );
            if ( 
$this->debug )
            {
                
imagettftext$errorimage"14"0$x+21$y+101$grey$this->options['font'], $errormessage );
                
imagettftext$errorimage"14"0$x+20$y+100$black$this->options['font'], $errormessage );
            }
        }
        else
        {
            
ImageString$errorimage5$x+101$y+31$message$grey );
            
ImageString$errorimage5$x+100$y+30$message$black );
            if ( 
$this->debug )
            {
                
$msgarray explode"rn"$errormessage );
                
$line $y+90;
                foreach( 
$msgarray as $msgline )
                {
                    
ImageString$errorimage3$x+21$line+1$msgline$grey );
                    
ImageString$errorimage3$x+20$line$msgline$black );
                    
$line $line imagefontheight) + 10;
                }
            }
        }

        
//-----------------------------------------
        // Flush image
        //-----------------------------------------
        
header('Content-type: image/png');
        
imagepng($errorimage);
        
imagedestroy($errorimage);
    }
}
Онлайн: 1
Реклама