linea21-externals
[ class tree: linea21-externals ] [ index: linea21-externals ] [ all elements ]

Source for file MathPlot.class.php

Documentation is available at MathPlot.class.php

  1. <?php
  2. /*
  3.  * This work is hereby released into the Public Domain.
  4.  * To view a copy of the public domain dedication,
  5.  * visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
  6.  * Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
  7.  *
  8.  */
  9.  
  10. require_once dirname(__FILE__)."/Component.class.php";
  11.  
  12. /**
  13.  * A mathematic function
  14.  *
  15.  * @package linea21.externals
  16.  * @subpackage artichow
  17.  */
  18. class awMathFunction {
  19.  
  20.     /**
  21.      * Function line
  22.      *
  23.      * @var Line 
  24.      */
  25.     var $line;
  26.     
  27.     /**
  28.      * Marks for your plot
  29.      *
  30.      * @var Mark 
  31.      */
  32.     var $mark;
  33.     
  34.     /**
  35.      * Callback function
  36.      *
  37.      * @var string 
  38.      */
  39.     var $f;
  40.     
  41.     /**
  42.      * Start the drawing from this value
  43.      *
  44.      * @var float 
  45.      */
  46.     var $fromX;
  47.     
  48.     /**
  49.      * Stop the drawing at this value
  50.      *
  51.      * @var float 
  52.      */
  53.     var $toX;
  54.  
  55.     /**
  56.      * Line color
  57.      *
  58.      * @var Color 
  59.      */
  60.     var $color;
  61.     
  62.     /**
  63.      * Construct the function
  64.      *
  65.      * @param string $f Callback function
  66.      * @param float $fromX 
  67.      * @param float $toX 
  68.      */
  69.      function awMathFunction($f, $fromX = NULL, $toX = NULL) {
  70.     
  71.         $this->f = (string)$f;
  72.         $this->fromX = is_null($fromX) ? NULL : (float)$fromX;
  73.         $this->toX = is_null($toX) ? NULL : (float)$toX;
  74.         
  75.         $this->line = new awLine;
  76.         $this->mark = new awMark;
  77.         $this->color = new awBlack;
  78.     
  79.     }
  80.     
  81.     /**
  82.      * Change line color
  83.      *
  84.      * @param $color A new awcolor
  85.      */
  86.      function setColor($color) {
  87.         $this->color = $color;
  88.     }
  89.     
  90.     /**
  91.      * Get line color
  92.      *
  93.      * @return Color 
  94.      */
  95.      function getColor() {
  96.         return $this->color;
  97.     }
  98.  
  99.     /**
  100.      * Get the background color or gradient of an element of the component
  101.      *
  102.      * @return Color, Gradient
  103.      */
  104.      function getLegendBackground() {
  105.     }
  106.  
  107.     /**
  108.      * Get the line thickness
  109.      *
  110.      * @return NULL 
  111.      */
  112.      function getLegendLineThickness() {
  113.         return $this->line->getThickness();
  114.     }
  115.  
  116.     /**
  117.      * Get the line type
  118.      *
  119.      * @return NULL 
  120.      */
  121.      function getLegendLineStyle() {
  122.         return $this->line->getStyle();
  123.     }
  124.  
  125.     /**
  126.      * Get the color of line
  127.      *
  128.      * @return NULL 
  129.      */
  130.      function getLegendLineColor() {
  131.         return $this->color;
  132.     }
  133.  
  134.     /**
  135.      * Get a mark object
  136.      *
  137.      * @return NULL 
  138.      */
  139.      function getLegendMark() {
  140.         return $this->mark;
  141.     }
  142.  
  143. }
  144.  
  145. registerClass('MathFunction');
  146.  
  147. /**
  148.  * For mathematics functions
  149.  *
  150.  * @package linea21.externals
  151.  * @subpackage artichow
  152.  */
  153. class awMathPlot extends awComponent {
  154.     
  155.     /**
  156.      * Functions
  157.      *
  158.      * @var array 
  159.      */
  160.     var $functions = array();
  161.     
  162.     /**
  163.      * Grid properties
  164.      *
  165.      * @var Grid 
  166.      */
  167.     var $grid;
  168.     
  169.     /**
  170.      * X axis
  171.      *
  172.      * @var Axis 
  173.      */
  174.     var $xAxis;
  175.     
  176.     /**
  177.      * Y axis
  178.      *
  179.      * @var Axis 
  180.      */
  181.     var $yAxis;
  182.     
  183.     /**
  184.      * Extremum
  185.      *
  186.      * @var Side 
  187.      */
  188.     var $extremum = NULL;
  189.     
  190.     /**
  191.      * Interval
  192.      *
  193.      * @var float 
  194.      */
  195.     var $interval = 1;
  196.     
  197.     /**
  198.      * Build the plot
  199.      *
  200.      * @param int $xMin Minimum X value
  201.      * @param int $xMax Maximum X value
  202.      * @param int $yMax Maximum Y value
  203.      * @param int $yMin Minimum Y value
  204.      */
  205.      function awMathPlot($xMin, $xMax, $yMax, $yMin) {
  206.     
  207.         parent::awComponent();
  208.         
  209.         $this->setPadding(8, 8, 8, 8);
  210.         
  211.         $this->grid = new awGrid;
  212.         
  213.         // Hide grid by default
  214.         $this->grid->hide(TRUE);
  215.         
  216.         // Set extremum
  217.         $this->extremum = new awSide($xMin, $xMax, $yMax, $yMin);
  218.         
  219.         // Create axis
  220.         $this->xAxis = new awAxis;
  221.         $this->xAxis->setTickStyle(TICK_IN);
  222.         $this->xAxis->label->hideValue(0);
  223.         $this->initAxis($this->xAxis);
  224.         
  225.         $this->yAxis = new awAxis;
  226.         $this->yAxis->setTickStyle(TICK_IN);
  227.         $this->yAxis->label->hideValue(0);
  228.         $this->initAxis($this->yAxis);
  229.         
  230.     }
  231.     
  232.      function initAxis(&$axis) {
  233.     
  234.         $axis->setLabelPrecision(1);
  235.         $axis->addTick('major', new awTick(0, 5));
  236.         $axis->addTick('minor', new awTick(0, 3));
  237.         $axis->addTick('micro', new awTick(0, 1));
  238.         $axis->setNumberByTick('minor', 'major', 1);
  239.         $axis->setNumberByTick('micro', 'minor', 4);
  240.         $axis->label->setFont(new awTuffy(7));
  241.         
  242.     }
  243.     
  244.     /**
  245.      * Interval to calculate values
  246.      *
  247.      * @param float $interval 
  248.      */
  249.      function setInterval($interval) {
  250.         $this->interval = (float)$interval;
  251.     }
  252.     
  253.     /**
  254.      * Add a formula f(x)
  255.      *
  256.      * @param &$function 
  257.      * @param string $name Name for the legend (can be NULL if you don't want to set a legend)
  258.      * @param int $type Type for the legend
  259.      */
  260.      function add(&$function, $name = NULL, $type = LEGEND_LINE) {
  261.     
  262.         $this->functions[] = $function;
  263.         
  264.         if($name !== NULL) {
  265.             $this->legend->add($function, $name, $type);
  266.         }
  267.     
  268.     }
  269.     
  270.      function init($driver) {
  271.         
  272.         list($x1, $y1, $x2, $y2) = $this->getPosition();
  273.         
  274.         $this->xAxis->line->setX($x1, $x2);
  275.         $this->xAxis->label->setAlign(NULL, LABEL_BOTTOM);
  276.         $this->xAxis->label->move(0, 3);
  277.         $this->xAxis->setRange($this->extremum->left, $this->extremum->right);
  278.         
  279.         $this->yAxis->line->setY($y2, $y1);
  280.         $this->yAxis->label->setAlign(LABEL_RIGHT);
  281.         $this->yAxis->label->move(-6, 0);
  282.         $this->yAxis->reverseTickStyle();
  283.         $this->yAxis->setRange($this->extremum->bottom, $this->extremum->top);
  284.         
  285.         
  286.         $this->xAxis->setYCenter($this->yAxis, 0);
  287.         $this->yAxis->setXCenter($this->xAxis, 0);
  288.         
  289.         if($this->yAxis->getLabelNumber() === NULL) {
  290.             $number = $this->extremum->top - $this->extremum->bottom + 1;
  291.             $this->yAxis->setLabelNumber($number);
  292.         }
  293.         
  294.         if($this->xAxis->getLabelNumber() === NULL) {
  295.             $number = $this->extremum->right - $this->extremum->left + 1;
  296.             $this->xAxis->setLabelNumber($number);
  297.         }
  298.         
  299.         // Set ticks
  300.         
  301.         $this->xAxis->ticks['major']->setNumber($this->xAxis->getLabelNumber());
  302.         $this->yAxis->ticks['major']->setNumber($this->yAxis->getLabelNumber());
  303.         
  304.         
  305.         // Set axis labels
  306.         $labels = array();
  307.         for($i = 0, $count = $this->xAxis->getLabelNumber(); $i < $count; $i++) {
  308.             $labels[] = $i;
  309.         }
  310.         $this->xAxis->label->set($labels);
  311.         
  312.         $labels = array();
  313.         for($i = 0, $count = $this->yAxis->getLabelNumber(); $i < $count; $i++) {
  314.             $labels[] = $i;
  315.         }
  316.         $this->yAxis->label->set($labels);
  317.     
  318.         parent::init($driver);
  319.         
  320.         // Create the grid
  321.         $this->createGrid();
  322.     
  323.         // Draw the grid
  324.         $this->grid->draw($driver, $x1, $y1, $x2, $y2);
  325.         
  326.     }
  327.     
  328.      function drawEnvelope($driver) {
  329.         
  330.         // Draw axis
  331.         $this->xAxis->draw($driver);
  332.         $this->yAxis->draw($driver);
  333.     
  334.     }
  335.     
  336.      function drawComponent($driver, $x1, $y1, $x2, $y2, $aliasing) {
  337.     
  338.         foreach($this->functions as $function) {
  339.         
  340.             $f = $function->f;
  341.             $fromX = is_null($function->fromX) ? $this->extremum->left : $function->fromX;
  342.             $toX = is_null($function->toX) ? $this->extremum->right : $function->toX;
  343.             
  344.             $old = NULL;
  345.             
  346.             for($i = $fromX; $i <= $toX; $i += $this->interval) {
  347.             
  348.                 $p = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($i, $f($i)));
  349.                 
  350.                 if($p->y >= $y1 and $p->y <= $y2) {
  351.                     $function->mark->draw($driver, $p);
  352.                 }
  353.             
  354.                 if($old !== NULL) {
  355.                 
  356.                     $line = $function->line;
  357.                     $line->setLocation($old, $p);
  358.                 
  359.                     if(
  360.                         ($line->p1->y >= $y1 and $line->p1->y <= $y2) or
  361.                         ($line->p2->y >= $y1 and $line->p2->y <= $y2)
  362.                     ) {
  363.                         $driver->line(
  364.                             $function->getColor(),
  365.                             $line
  366.                         );
  367.                     }
  368.                 
  369.                 }
  370.                 
  371.                 $old = $p;
  372.             
  373.             }
  374.             
  375.             // Draw last point if needed
  376.             if($old !== NULL and $i - $this->interval != $toX) {
  377.             
  378.                 $p = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($toX, $f($toX)));
  379.                 
  380.                 if($p->y >= $y1 and $p->y <= $y2) {
  381.                     $function->mark->draw($driver, $p);
  382.                 }
  383.                 
  384.                 
  385.                 $line = $function->line;
  386.                 $line->setLocation($old, $p);
  387.                 
  388.                 if(
  389.                     ($line->p1->y >= $y1 and $line->p1->y <= $y2) or
  390.                     ($line->p2->y >= $y1 and $line->p2->y <= $y2)
  391.                 ) {
  392.                     $driver->line(
  393.                         $function->getColor(),
  394.                         $line
  395.                     );
  396.                 }
  397.                 
  398.             }
  399.         
  400.         }
  401.     
  402.     }
  403.     
  404.      function createGrid() {
  405.         
  406.         // Horizontal lines of the grid
  407.  
  408.         $major = $this->yAxis->tick('major');
  409.         $interval = $major->getInterval();
  410.         $number = $this->yAxis->getLabelNumber() - 1;
  411.         
  412.         $h = array();
  413.         if($number > 0) {
  414.             for($i = 0; $i <= $number; $i++) {
  415.                 $h[] = $i / $number;
  416.             }
  417.         }
  418.         
  419.         // Vertical lines
  420.     
  421.         $major = $this->xAxis->tick('major');
  422.         $interval = $major->getInterval();
  423.         $number = $this->xAxis->getLabelNumber() - 1;
  424.         
  425.         $w = array();
  426.         if($number > 0) {
  427.             for($i = 0; $i <= $number; $i++) {
  428.                 if($i%$interval === 0) {
  429.                     $w[] = $i / $number;
  430.                 }
  431.             }
  432.         }
  433.     
  434.         $this->grid->setGrid($w, $h);
  435.     
  436.     }
  437.  
  438. }
  439.  
  440. registerClass('MathPlot');
  441. ?>

Documentation generated on Fri, 16 Oct 2009 09:36:26 +0200 by phpDocumentor 1.4.1