Source for file Plot.class.php
Documentation is available at Plot.class.php 
 * This work is hereby released into the Public Domain.  
 * To view a copy of the public domain dedication,  
 * visit http://creativecommons.org/licenses/publicdomain/ or send a letter to  
 * Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.  
require_once dirname(__FILE__ ). "/Component.class.php";  
define("PLOT_RIGHT", 'right');  
define("PLOT_BOTTOM", 'bottom');  
 * Graph using X and Y axis  
 * @package linea21.externals  
     * Change min value for Y axis  
     * Change max value for Y axis  
     * Change min value for X axis  
     * Change max value for X axis  
     * Both left/right or top/bottom axis  
        $this->grid->setBackgroundColor(new awWhite);  
        $this->padding->add(20, 0, 0, 20);  
        $this->xAxis->label->setFont(new awTuffy(7));  
        $this->yAxis->auto(TRUE);  
        $this->yAxis->setNumberByTick('minor', 'major', 3);  
        $this->yAxis->label->setFont(new awTuffy(7));  
        $this->yAxis->title->setAngle(90);  
     * Reduce number of values in the plot  
     * @param int $number Reduce number of values to $number  
    public function reduce($number) {  
        $ratio =  ceil($count /  $number);  
            $cbLabel =  $this->xAxis->label->getCallbackFunction();  
            for($i =  0; $i <  $count; $i +=  $ratio) {  
                // Reduce data on X axis if needed  
                    $datax[] =  $cbLabel($i +  round($ratio /  2));  
                $this->xAxis->setLabelText($datax);  
     * Count values in the plot  
        list ($min, $max) =  $this->xAxis->getRange(); 
        return ($max -  $min +  1);  
     * Change min value for Y axis  
     * Set NULL for auto selection.  
        $this->yAxis->auto(FALSE);  
     * Change max value for Y axis  
     * Set NULL for auto selection.  
        $this->yAxis->auto(FALSE);  
     * Change min value for X axis  
     * Set NULL for auto selection.  
     * Change max value for X axis  
     * Set NULL for auto selection.  
     * Get min value for Y axis  
     * Get max value for Y axis  
     * Get min value for X axis  
     * Get max value for X axis  
     * Get min value with spaces for Y axis  
        if($this->space->bottom !==  NULL) {  
            $interval =  ($this->getYMax() -  $min) *  $this->space->bottom /  100;  
            return is_null($this->yMin) ?  $min : (float) $this->yMin;  
     * Get max value with spaces for Y axis  
        if($this->space->top !==  NULL) {  
            $interval =  ($max -  $this->getYMin()) *  $this->space->top /  100;  
            return is_null($this->yMax) ?  $max : (float) $this->yMax;  
    public function init(awDriver $driver) {  
        list ($x1, $y1, $x2, $y2) =  $this->getPosition(); 
        // Get space informations  
        list ($leftSpace, $rightSpace, $topSpace, $bottomSpace) =  $this->getSpace($x2 -  $x1, $y2 -  $y1); 
        $this->xAxis->setPadding($leftSpace, $rightSpace);  
        if($this->space->bottom >  0 or $this->space->top >  0) {  
            list ($min, $max) =  $this->yAxis->getRange(); 
                $min -  $interval *  $this->space->bottom /  100,  
                $max +  $interval *  $this->space->top /  100  
        $this->yAxis->autoScale();  
        // Number of labels is not specified  
        if($this->yAxis->getLabelNumber() ===  NULL) {  
            $number =  round(($y2 -  $y1) /  75) +  2;  
            $this->yAxis->setLabelNumber($number);  
        $this->xAxis->line->setX($x1, $x2);  
        $this->yAxis->line->setY($y2, $y1);  
        $this->yAxis->tick('major')->setNumber($this->yAxis->getLabelNumber());  
        $this->xAxis->ticks['major']->setNumber($this->getXAxisNumber());  
        $this->yAxis->ticks['major']->setNumber($this->yAxis->getLabelNumber());  
        list ($xMin, $xMax) =  $this->xAxis->getRange(); 
        for($i =  $xMin; $i <=  $xMax; $i++ ) {  
        $this->xAxis->label->set($labels);  
        list ($x1, $y1, $x2, $y2) =  $this->getPosition(); 
        list ($leftSpace, $rightSpace) =  $this->getSpace($x2 -  $x1, $y2 -  $y1); 
        $this->grid->setSpace($leftSpace, $rightSpace, 0, 0);  
        $this->grid->draw($driver, $x1, $y1, $x2, $y2);  
        list ($x1, $y1, $x2, $y2) =  $this->getPosition(); 
            $size =  $this->xAxis->getDistance(0, 1);  
            $this->xAxis->label->move($size /  2, 0);  
            $this->xAxis->label->hideLast(TRUE);  
            $top =  clone $this->xAxis;  
                $top->line->setY($y1, $y1);  
            $top->label->setAlign(NULL, awLabel::TOP);  
            $top->label->move(0, - 3);  
            $top->title->move(0, - 25);  
            $bottom =  clone $this->xAxis;  
                $bottom->line->setY($y2, $y2);  
            $bottom->label->setAlign(NULL, awLabel::BOTTOM);  
            $bottom->label->move(0, 3);  
            $bottom->reverseTickStyle();  
            $bottom->title->move(0, 25);  
            $left =  clone $this->yAxis;  
                $left->line->setX($x1, $x1);  
            $left->label->setAlign(awLabel::RIGHT);  
            $left->label->move(- 6, 0);  
            $left->title->move(- 25, 0);  
            $right =  clone $this->yAxis;  
                $right->line->setX($x2, $x2);  
            $right->label->setAlign(awLabel::LEFT);  
            $right->label->move(6, 0);  
            $right->reverseTickStyle();  
            $right->title->move(25, 0);  
        $number =  $this->yAxis->getLabelNumber() -  1;  
        // Horizontal lines of the grid  
        for($i =  0; $i <=  $number; $i++ ) {  
        $major =  $this->yAxis->tick('major');  
        $interval =  $major->getInterval();  
            for($i =  0; $i <=  $number; $i++ ) {  
        $this->grid->setGrid($w, $h);  
     * Change values of Y axis  
     * This method ignores not numeric values  
    public function setValues($datay, $datax =  NULL) {  
        $this->checkArray($datay);  
        foreach($datay as $key =>  $value) {  
            $datay[(int) $key] =  $value;  
            for($i =  0; $i <  count($datay); $i++ ) {  
            foreach($datax as $key =>  $value) {  
                $datax[(int) $key] =  $value;  
        $this->checkArray($datax);  
            // Update axis with the new awvalues  
            awImage::drawError("Class Plot: Plots must have the same number of X and Y points.");  
     * Return begin and end values  
        return array($start, $stop);  
     * Return TRUE if labels must be centered on X axis, FALSE otherwise  
    private function updateAxis() {  
    private function checkArray(&$array) {  
            awImage::drawError("Class Plot: You tried to set a value that is not an array.");  
        foreach($array as $key =>  $value) {  
     * Build the group of axis  
        $this->left->label->move(- 6, 0);  
        $this->left->title->move(- 25, 0);  
        $this->right->auto(TRUE);  
        $this->right->label->move(6, 0);  
        $this->right->title->move(25, 0);  
        $this->top->label->move(0, - 3);  
        $this->top->title->move(0, - 25);  
        $this->bottom->label->move(0, 3);  
        $this->bottom->title->move(0, 25);  
    protected function xAxis(awAxis $axis) {  
        $axis->addTick('major', new awTick(0, 5));  
        $axis->addTick('minor', new awTick(0, 3));  
        $axis->label->setFont(new awTuffy(7));  
    protected function yAxis(awAxis $axis) {  
        $axis->addTick('major', new awTick(0, 5));  
        $axis->addTick('minor', new awTick(0, 3));  
        $axis->setNumberByTick('minor', 'major', 3);  
        $axis->label->setFont(new awTuffy(7));  
        $axis->title->setAngle(90);  
 * A graph with axis can contain some groups of components  
 * @package linea21.externals  
     * Left, right, top and bottom axis  
     * Real axis used for Y axis  
    private $yRealAxis =  awPlot::LEFT;  
     * Real axis used for X axis  
    private $xRealAxis =  awPlot::BOTTOM;  
     * Change min value for Y axis  
     * Change max value for Y axis  
     * Change min value for X axis  
     * Change max value for X axis  
        $this->grid->setBackgroundColor(new awWhite);  
     * Set the X axis on zero or not  
     * Set the Y axis on zero or not  
     * Change min value for Y axis  
     * Set NULL for auto selection.  
        $this->axis->left->auto(FALSE);  
        $this->axis->right->auto(FALSE);  
     * Change max value for Y axis  
     * Set NULL for auto selection.  
        $this->axis->left->auto(FALSE);  
        $this->axis->right->auto(FALSE);  
     * Change min value for X axis  
     * Set NULL for auto selection.  
     * Change max value for X axis  
     * Set NULL for auto selection.  
     * Get min value for X axis  
        return $this->getX('min');  
     * Get max value for X axis  
        return $this->getX('max');  
    private function getX($type) {  
                if($this->xMax !==  NULL) {  
                if($this->xMin !==  NULL) {  
                $value =  $component->$get();  
                $value =  $type($value, $component->$get());  
     * Get min value with spaces for Y axis  
     * @param string $axis Axis name  
        $min =  $this->getRealY('min', $axis);  
        $max =  $this->getRealY('max', $axis);  
        if($this->space->bottom !==  NULL) {  
            $interval =  ($min -  $max) *  $this->space->bottom /  100;  
     * Get max value with spaces for Y axis  
     * @param string $axis Axis name  
        $min =  $this->getRealY('min', $axis);  
        $max =  $this->getRealY('max', $axis);  
        if($this->space->top !==  NULL) {  
            $interval =  ($max -  $min) *  $this->space->top /  100;  
    private function getRealY($type, $axis) {  
                if($this->yMax !==  NULL) {  
                if($this->yMin !==  NULL) {  
                    $test =  ($component->getYAxis() ===  $axis);  
                $auto =  $component->yAxis->isAuto();  
                $this->axis->{$axis}->auto($auto);  
                    $value =  $component->$get();  
                    $value =  $type($value, $component->$get());  
    public function init(awDriver $driver) {  
        list ($leftSpace, $rightSpace, $topSpace, $bottomSpace) =  $this->getSpace($x2 -  $x1, $y2 -  $y1); 
        // Count values in the group  
        $this->axis->top->line->setX($x1, $x2);  
        $this->axis->bottom->line->setX($x1, $x2);  
        $this->axis->left->line->setY($y2, $y1);  
        $this->axis->right->line->setY($y2, $y1);  
        $this->axis->top->setRange($xMin, $xMax);  
        $this->axis->bottom->setRange($xMin, $xMax);  
            $component = &$this->components[$i];  
            // Copy space to the component  
            $component->xAxis->setPadding($leftSpace, $rightSpace);  
            $component->xAxis->line->setX($x1, $x2);  
            $component->yAxis->line->setY($y2, $y1);  
        foreach(array('left', 'right') as $axis) {  
                $this->axis->{$axis}->setRange(  
                    $min -  $interval *  $this->space->bottom /  100,  
                    $max +  $interval *  $this->space->top /  100  
                if($this->axis->{$axis}->isAuto()) {  
                    $this->axis->{$axis}->autoScale();  
        if($this->axis->left->getLabelNumber() ===  NULL) {  
            $number =  round(($y2 -  $y1) /  75) +  2;  
            $this->axis->left->setLabelNumber($number);  
        if($this->axis->right->getLabelNumber() ===  NULL) {  
            $number =  round(($y2 -  $y1) /  75) +  2;  
            $this->axis->right->setLabelNumber($number);  
        // Center labels on X axis if needed  
        $test =  array(awPlot::TOP =>  FALSE, awPlot::BOTTOM =>  FALSE);  
            $component = &$this->components[$i];  
            if($component->getValues() !==  NULL) {  
                $axis =  $component->getXAxis();  
                if($test[$axis] ===  FALSE) {  
                    // Center labels for bar plots  
                    if($component->getXCenter()) {  
                        $size =  $this->axis->{$axis}->getDistance(0, 1);  
                        $this->axis->{$axis}->label->move($size /  2, 0);  
                        $this->axis->{$axis}->label->hideLast(TRUE);  
        for($i =  $xMin; $i <=  $xMax; $i++ ) {  
            $this->axis->top->label->set($labels);  
        if($this->axis->bottom->label->count() ===  0) {  
            $this->axis->bottom->label->set($labels);  
        $this->axis->top->tick('major')->setNumber($values);  
        $this->axis->bottom->tick('major')->setNumber($values);  
        $this->axis->left->tick('major')->setNumber($this->axis->left->getLabelNumber());  
        $this->axis->right->tick('major')->setNumber($this->axis->right->getLabelNumber());  
        $this->axis->top->ticks['major']->setNumber($values);  
        $this->axis->bottom->ticks['major']->setNumber($values);  
        $this->axis->left->ticks['major']->setNumber($this->axis->left->getLabelNumber());  
        $this->axis->right->ticks['major']->setNumber($this->axis->right->getLabelNumber());  
            $this->axis->bottom->setYCenter($axis, 0);  
            $this->axis->top->setYCenter($axis, 0);  
            $this->axis->left->setXCenter($axis, 1);  
            $this->axis->right->setXCenter($axis, 1);  
        list ($leftSpace, $rightSpace, $topSpace, $bottomSpace) =  $this->getSpace($x2 -  $x1, $y2 -  $y1); 
        $this->grid->draw($driver, $x1, $y1, $x2, $y2);  
    public function drawComponent(awDriver $driver, $x1, $y1, $x2, $y2, $aliasing) {  
            $min =  $component->getYMin();  
            $max =  $component->getYMax();  
            // Set component minimum and maximum  
            if($component->getYAxis() ===  awPlot::LEFT) {  
                list ($min, $max) =  $this->axis->left->getRange(); 
                list ($min, $max) =  $this->axis->right->getRange(); 
            $component->xAxis->setRange($xMin, $xMax);  
                $this->axis->{$axis}->hide(TRUE);  
            $top->line->setY($y1, $y1);  
        $bottom =  $this->axis->bottom;  
            $bottom->line->setY($y2, $y2);  
            $left->line->setX($x1, $x1);  
        $right =  $this->axis->right;  
            $right->line->setX($x2, $x2);  
     * Is the specified axis used ?  
     * @param string $axis Axis name  
                    if($component->getYAxis() ===  $axis) {  
                    if($component->getXAxis() ===  $axis) {  
        // Select axis (left if possible, right otherwise)  
        $number =  $axis->getLabelNumber() -  1;  
        // Horizontal lines of grid  
        for($i =  0; $i <=  $number; $i++ ) {  
        $major =  $axis->tick('major');  
        $interval =  $major->getInterval();  
            for($i =  0; $i <=  $number; $i++ ) {  
        $this->grid->setGrid($w, $h);  
        // Select axis (left if possible, right otherwise)  
            $axis =  $this->axis->right;  
        // Select axis (bottom if possible, top otherwise)  
            $axis =  $this->axis->bottom;  
 
 
        
       |