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 needed if ($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');