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
$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;
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->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->line->setY($y1, $y1);
$top->label->move(0, - 3);
$top->title->move(0, - 25);
$bottom->line->setY($y2, $y2);
$bottom->label->move(0, 3);
$bottom->reverseTickStyle();
$bottom->title->move(0, 25);
$left->line->setX($x1, $x1);
$left->label->move(- 6, 0);
$left->title->move(- 25, 0);
$right->line->setX($x2, $x2);
$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
$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
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);
$axis->addTick('major', new awTick(0, 5));
$axis->addTick('minor', new awTick(0, 3));
$axis->label->setFont(new awTuffy(7));
$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
var $yRealAxis = PLOT_LEFT;
* Real axis used for X axis
var $xRealAxis = PLOT_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
parent::awComponentGroup();
$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');
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;
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());
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);
// 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
$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->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);
$min = $component->getYMin();
$max = $component->getYMax();
// Set component minimum and maximum
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;
|