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 Thu, 03 May 2012 15:06:16 +0200 by phpDocumentor 1.4.1