Rev 60 | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?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";/*** A mathematic function** @package Artichow*/class awMathFunction implements awLegendable {/*** Function line** @var Line*/public $line;/*** Marks for your plot** @var Mark*/public $mark;/*** Callback function** @var string*/public $f;/*** Start the drawing from this value** @var float*/public $fromX;/*** Stop the drawing at this value** @var float*/public $toX;/*** Line color** @var Color*/protected $color;/*** Construct the function** @param string $f Callback function* @param float $fromX* @param float $toX*/public function __construct($f, $fromX = NULL, $toX = NULL) {$this->f = (string)$f;$this->fromX = is_null($fromX) ? NULL : (float)$fromX;$this->toX = is_null($toX) ? NULL : (float)$toX;$this->line = new awLine;$this->mark = new awMark;$this->color = new awBlack;}/*** Change line color** @param awColor $color A new awcolor*/public function setColor(awColor $color) {$this->color = $color;}/*** Get line color** @return Color*/public function getColor() {return $this->color;}/*** Get the background color or gradient of an element of the component** @return Color, Gradient*/public function getLegendBackground() {}/*** Get the line thickness** @return NULL*/public function getLegendLineThickness() {return $this->line->getThickness();}/*** Get the line type** @return NULL*/public function getLegendLineStyle() {return $this->line->getStyle();}/*** Get the color of line** @return NULL*/public function getLegendLineColor() {return $this->color;}/*** Get a mark object** @return NULL*/public function getLegendMark() {return $this->mark;}}registerClass('MathFunction');/*** For mathematics functions** @package Artichow*/class awMathPlot extends awComponent {/*** Functions** @var array*/protected $functions = array();/*** Grid properties** @var Grid*/public $grid;/*** X axis** @var Axis*/public $xAxis;/*** Y axis** @var Axis*/public $yAxis;/*** Extremum** @var Side*/private $extremum = NULL;/*** Interval** @var float*/private $interval = 1;/*** Build the plot** @param int $xMin Minimum X value* @param int $xMax Maximum X value* @param int $yMax Maximum Y value* @param int $yMin Minimum Y value*/public function __construct($xMin, $xMax, $yMax, $yMin) {parent::__construct();$this->setPadding(8, 8, 8, 8);$this->grid = new awGrid;// Hide grid by default$this->grid->hide(TRUE);// Set extremum$this->extremum = new awSide($xMin, $xMax, $yMax, $yMin);// Create axis$this->xAxis = new awAxis;$this->xAxis->setTickStyle(awTick::IN);$this->xAxis->label->hideValue(0);$this->initAxis($this->xAxis);$this->yAxis = new awAxis;$this->yAxis->setTickStyle(awTick::IN);$this->yAxis->label->hideValue(0);$this->initAxis($this->yAxis);}protected function initAxis(awAxis $axis) {$axis->setLabelPrecision(1);$axis->addTick('major', new awTick(0, 5));$axis->addTick('minor', new awTick(0, 3));$axis->addTick('micro', new awTick(0, 1));$axis->setNumberByTick('minor', 'major', 1);$axis->setNumberByTick('micro', 'minor', 4);$axis->label->setFont(new awTuffy(7));}/*** Interval to calculate values** @param float $interval*/public function setInterval($interval) {$this->interval = (float)$interval;}/*** Add a formula f(x)** @param awMathFunction $function* @param string $name Name for the legend (can be NULL if you don't want to set a legend)* @param int $type Type for the legend*/public function add(awMathFunction $function, $name = NULL, $type = awLegend::LINE) {$this->functions[] = $function;if($name !== NULL) {$this->legend->add($function, $name, $type);}}public function init(awDriver $driver) {list($x1, $y1, $x2, $y2) = $this->getPosition();$this->xAxis->line->setX($x1, $x2);$this->xAxis->label->setAlign(NULL, awLabel::BOTTOM);$this->xAxis->label->move(0, 3);$this->xAxis->setRange($this->extremum->left, $this->extremum->right);$this->yAxis->line->setY($y2, $y1);$this->yAxis->label->setAlign(awLabel::RIGHT);$this->yAxis->label->move(-6, 0);$this->yAxis->reverseTickStyle();$this->yAxis->setRange($this->extremum->bottom, $this->extremum->top);$this->xAxis->setYCenter($this->yAxis, 0);$this->yAxis->setXCenter($this->xAxis, 0);if($this->yAxis->getLabelNumber() === NULL) {$number = $this->extremum->top - $this->extremum->bottom + 1;$this->yAxis->setLabelNumber($number);}if($this->xAxis->getLabelNumber() === NULL) {$number = $this->extremum->right - $this->extremum->left + 1;$this->xAxis->setLabelNumber($number);}// Set ticks$this->xAxis->tick('major')->setNumber($this->xAxis->getLabelNumber());$this->yAxis->tick('major')->setNumber($this->yAxis->getLabelNumber());// Set axis labels$labels = array();for($i = 0, $count = $this->xAxis->getLabelNumber(); $i < $count; $i++) {$labels[] = $i;}$this->xAxis->label->set($labels);$labels = array();for($i = 0, $count = $this->yAxis->getLabelNumber(); $i < $count; $i++) {$labels[] = $i;}$this->yAxis->label->set($labels);parent::init($driver);// Create the grid$this->createGrid();// Draw the grid$this->grid->draw($driver, $x1, $y1, $x2, $y2);}public function drawEnvelope(awDriver $driver) {// Draw axis$this->xAxis->draw($driver);$this->yAxis->draw($driver);}public function drawComponent(awDriver $driver, $x1, $y1, $x2, $y2, $aliasing) {foreach($this->functions as $function) {$f = $function->f;$fromX = is_null($function->fromX) ? $this->extremum->left : $function->fromX;$toX = is_null($function->toX) ? $this->extremum->right : $function->toX;$old = NULL;for($i = $fromX; $i <= $toX; $i += $this->interval) {$p = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($i, $f($i)));if($p->y >= $y1 and $p->y <= $y2) {$function->mark->draw($driver, $p);}if($old !== NULL) {$line = $function->line;$line->setLocation($old, $p);if(($line->p1->y >= $y1 and $line->p1->y <= $y2) or($line->p2->y >= $y1 and $line->p2->y <= $y2)) {$driver->line($function->getColor(),$line);}}$old = $p;}// Draw last point if neededif($old !== NULL and $i - $this->interval != $toX) {$p = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($toX, $f($toX)));if($p->y >= $y1 and $p->y <= $y2) {$function->mark->draw($driver, $p);}$line = $function->line;$line->setLocation($old, $p);if(($line->p1->y >= $y1 and $line->p1->y <= $y2) or($line->p2->y >= $y1 and $line->p2->y <= $y2)) {$driver->line($function->getColor(),$line);}}}}protected function createGrid() {// Horizontal lines of the grid$major = $this->yAxis->tick('major');$interval = $major->getInterval();$number = $this->yAxis->getLabelNumber() - 1;$h = array();if($number > 0) {for($i = 0; $i <= $number; $i++) {$h[] = $i / $number;}}// Vertical lines$major = $this->xAxis->tick('major');$interval = $major->getInterval();$number = $this->xAxis->getLabelNumber() - 1;$w = array();if($number > 0) {for($i = 0; $i <= $number; $i++) {if($i%$interval === 0) {$w[] = $i / $number;}}}$this->grid->setGrid($w, $h);}}registerClass('MathPlot');?>