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

Source for file Axis.class.php

Documentation is available at Axis.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__)."/../Graph.class.php";
  11.  
  12. /**
  13.  * Handle axis
  14.  *
  15.  * @package linea21.externals
  16.  * @subpackage artichow
  17.  */
  18. class awAxis {
  19.  
  20.   /**
  21.    * Axis line
  22.    *
  23.    * @var Line 
  24.    */
  25.   var $line;
  26.  
  27.   /**
  28.    * Axis labels
  29.    *
  30.    * @var Label 
  31.    */
  32.   var $label;
  33.  
  34.   /**
  35.    * Axis title
  36.    *
  37.    * @var Label 
  38.    */
  39.   var $title;
  40.  
  41.   /**
  42.    * Title position
  43.    *
  44.    * @var float 
  45.    */
  46.   var $titlePosition = 0.5;
  47.  
  48.   /**
  49.    * Labels number
  50.    *
  51.    * @var int 
  52.    */
  53.   var $labelNumber;
  54.  
  55.   /**
  56.    * Axis ticks
  57.    *
  58.    * @var array 
  59.    */
  60.   var $ticks = array();
  61.  
  62.   /**
  63.    * Axis and ticks color
  64.    *
  65.    * @var Color 
  66.    */
  67.   var $color;
  68.  
  69.   /**
  70.    * Axis left and right padding
  71.    *
  72.    * @var Side 
  73.    */
  74.   var $padding;
  75.  
  76.   /**
  77.    * Axis range
  78.    *
  79.    * @var array 
  80.    */
  81.   var $range;
  82.  
  83.   /**
  84.    * Hide axis
  85.    *
  86.    * @var bool 
  87.    */
  88.   var $hide = FALSE;
  89.  
  90.   /**
  91.    * Auto-scaling mode
  92.    *
  93.    * @var bool 
  94.    */
  95.   var $auto = TRUE;
  96.  
  97.   /**
  98.    * Axis range callback function
  99.    *
  100.    * @var array 
  101.    */
  102.   var $rangeCallback = array(
  103.         'toValue' => 'toProportionalValue',
  104.         'toPosition' => 'toProportionalPosition'
  105.         );
  106.  
  107.         /**
  108.          * Build the axis
  109.          *
  110.          * @param float $min Begin of the range of the axis
  111.          * @param float $max End of the range of the axis
  112.          */
  113.      function awAxis($min NULL$max NULL{
  114.  
  115.        $this->line = new awVector(
  116.        new awPoint(00),
  117.        new awPoint(00)
  118.        );
  119.  
  120.        $this->label = new awLabel;
  121.        $this->padding = new awSide;
  122.  
  123.        $this->title = new awLabel(
  124.        NULL,
  125.        NULL,
  126.        NULL,
  127.        0
  128.        );
  129.  
  130.        $this->setColor(new awBlack);
  131.  
  132.        if($min !== NULL and $max !== NULL{
  133.          $this->setRange($min$max);
  134.        }
  135.  
  136.      }
  137.  
  138.      /**
  139.       * Enable/disable auto-scaling mode
  140.       *
  141.       * @param bool $auto 
  142.       */
  143.      function auto($auto{
  144.        $this->auto = (bool)$auto;
  145.      }
  146.  
  147.      /**
  148.       * Get auto-scaling mode status
  149.       *
  150.       * @return bool 
  151.       */
  152.      function isAuto({
  153.        return $this->auto;
  154.      }
  155.  
  156.      /**
  157.       * Hide axis
  158.       *
  159.       * @param bool $hide 
  160.       */
  161.      function hide($hide TRUE{
  162.        $this->hide = (bool)$hide;
  163.      }
  164.  
  165.      /**
  166.       * Show axis
  167.       *
  168.       * @param bool $show 
  169.       */
  170.      function show($show TRUE{
  171.        $this->hide = !(bool)$show;
  172.      }
  173.  
  174.      /**
  175.       * Return a tick object from its name
  176.       *
  177.       * @param string $name Tick object name
  178.       * @return Tick 
  179.       */
  180.      function tick($name{
  181.  
  182.        if(array_key_exists($name$this->ticks)) {
  183.          return $tick &$this->ticks[$name];
  184.        else {
  185.          return NULL;
  186.        }
  187.  
  188.      }
  189.  
  190.      /**
  191.       * Add a tick object
  192.       *
  193.       * @param string $name Tick object name
  194.       * @param &$tick Tick object
  195.       */
  196.      function addTick($name&$tick{
  197.  
  198.        $this->ticks[$name&$tick;
  199.  
  200.      }
  201.  
  202.      /**
  203.       * Delete a tick object
  204.       *
  205.       * @param string $name Tick object name
  206.       */
  207.      function deleteTick($name{
  208.        if(array_key_exists($name$this->ticks)) {
  209.          unset($this->ticks[$name]);
  210.        }
  211.      }
  212.  
  213.      /**
  214.       * Hide all ticks
  215.       *
  216.       * @param bool $hide Hide or not ?
  217.       */
  218.      function hideTicks($hide TRUE{
  219.  
  220.        foreach($this->ticks as $key => $tick{
  221.          $this->ticks[$key]->hide($hide);
  222.        }
  223.  
  224.      }
  225.  
  226.      /**
  227.       * Change ticks style
  228.       *
  229.       * @param int $style Ticks style
  230.       */
  231.      function setTickStyle($style{
  232.  
  233.        foreach($this->ticks as $key => $tick{
  234.          $this->ticks[$key]->setStyle($style);
  235.        }
  236.  
  237.      }
  238.  
  239.      /**
  240.       * Change ticks interval
  241.       *
  242.       * @param int $interval Ticks interval
  243.       */
  244.      function setTickInterval($interval{
  245.  
  246.        foreach($this->ticks as $key => $tick{
  247.          $this->ticks[$key]->setInterval($interval);
  248.        }
  249.  
  250.      }
  251.  
  252.      /**
  253.       * Change number of ticks relative to others ticks
  254.       *
  255.       * @param &$to Change number of theses ticks
  256.       * @param &$from Ticks reference
  257.       * @param float $number Number of ticks by the reference
  258.       */
  259.      function setNumberByTick($to$from$number{
  260.        $this->ticks[$to]->setNumberByTick($this->ticks[$from]$number);
  261.      }
  262.  
  263.      /**
  264.       * Reverse ticks style
  265.       */
  266.      function reverseTickStyle({
  267.  
  268.        foreach($this->ticks as $key => $tick{
  269.          if($this->ticks[$key]->getStyle(=== TICK_IN{
  270.            $this->ticks[$key]->setStyle(TICK_OUT);
  271.          else if($this->ticks[$key]->getStyle(=== TICK_OUT{
  272.            $this->ticks[$key]->setStyle(TICK_IN);
  273.          }
  274.        }
  275.  
  276.      }
  277.  
  278.      /**
  279.       * Change interval of labels
  280.       *
  281.       * @param int $interval Interval
  282.       */
  283.      function setLabelInterval($interval{
  284.        $this->auto(FALSE);
  285.        $this->setTickInterval($interval);
  286.        $this->label->setInterval($interval);
  287.      }
  288.  
  289.      /**
  290.       * Change number of labels
  291.       *
  292.       * @param int $number Number of labels to display (can be NULL)
  293.       */
  294.      function setLabelNumber($number{
  295.        $this->auto(FALSE);
  296.        $this->labelNumber = is_null($numberNULL : (int)$number;
  297.      }
  298.  
  299.      /**
  300.       * Get number of labels
  301.       *
  302.       * @return int 
  303.       */
  304.      function getLabelNumber({
  305.        return $this->labelNumber;
  306.      }
  307.  
  308.      /**
  309.       * Change precision of labels
  310.       *
  311.       * @param int $precision Precision
  312.       */
  313.      function setLabelPrecision($precision{
  314.        $this->auto(FALSE);
  315.        $function 'axis'.time().'_'.(microtime(1000000);
  316.        eval('function '.$function.'($value) {
  317.             return sprintf("%.'.(int)$precision.'f", $value);
  318.         }');
  319.        $this->label->setCallbackFunction($function);
  320.      }
  321.  
  322.      /**
  323.       * Change text of labels
  324.       *
  325.       * @param array $texts Some texts
  326.       */
  327.      function setLabelText($texts{
  328.        if(is_array($texts)) {
  329.          $this->auto(FALSE);
  330.          $function 'axis'.time().'_'.(microtime(1000000);
  331.          eval('function '.$function.'($value) {
  332.                 $texts = '.var_export($textsTRUE).';
  333.                 return isset($texts[$value]) ? $texts[$value] : \'?\';
  334.             }');
  335.          $this->label->setCallbackFunction($function);
  336.        }
  337.      }
  338.  
  339.      /**
  340.       * Get the position of a point
  341.       *
  342.       * @param &$xAxis X axis
  343.       * @param &$yAxis Y axis
  344.       * @param $p Position of the point
  345.       * @return Point Position on the axis
  346.       */
  347.      function toPosition(&$xAxis&$yAxis$p{
  348.  
  349.        $p1 $xAxis->getPointFromValue($p->x);
  350.        $p2 $yAxis->getPointFromValue($p->y);
  351.  
  352.        return new awPoint(
  353.        round($p1->x),
  354.        round($p2->y)
  355.        );
  356.  
  357.      }
  358.  
  359.      /**
  360.       * Change title alignment
  361.       *
  362.       * @param int $alignment New Alignment
  363.       */
  364.      function setTitleAlignment($alignment{
  365.  
  366.        switch($alignment{
  367.  
  368.          case LABEL_TOP :
  369.            $this->setTitlePosition(1);
  370.            $this->title->setAlign(NULLLABEL_BOTTOM);
  371.            break;
  372.  
  373.          case LABEL_BOTTOM :
  374.            $this->setTitlePosition(0);
  375.            $this->title->setAlign(NULLLABEL_TOP);
  376.            break;
  377.  
  378.          case LABEL_LEFT :
  379.            $this->setTitlePosition(0);
  380.            $this->title->setAlign(LABEL_LEFT);
  381.            break;
  382.  
  383.          case LABEL_RIGHT :
  384.            $this->setTitlePosition(1);
  385.            $this->title->setAlign(LABEL_RIGHT);
  386.            break;
  387.  
  388.        }
  389.  
  390.      }
  391.  
  392.      /**
  393.       * Change title position on the axis
  394.       *
  395.       * @param float $position A new awposition between 0 and 1
  396.       */
  397.      function setTitlePosition($position{
  398.        $this->titlePosition = (float)$position;
  399.      }
  400.  
  401.      /**
  402.       * Change axis and axis title color
  403.       *
  404.       * @param $color 
  405.       */
  406.      function setColor($color{
  407.        $this->color = $color;
  408.        $this->title->setColor($color);
  409.      }
  410.  
  411.      /**
  412.       * Change axis padding
  413.       *
  414.       * @param int $left Left padding in pixels
  415.       * @param int $right Right padding in pixels
  416.       */
  417.      function setPadding($left$right{
  418.        $this->padding->set($left$right);
  419.      }
  420.  
  421.      /**
  422.       * Get axis padding
  423.       *
  424.       * @return Side 
  425.       */
  426.      function getPadding({
  427.        return $this->padding;
  428.      }
  429.  
  430.      /**
  431.       * Change axis range
  432.       *
  433.       * @param float $min 
  434.       * @param float $max 
  435.       */
  436.      function setRange($min$max{
  437.        if($min !== NULL{
  438.          $this->range[0= (float)$min;
  439.        }
  440.        if($max !== NULL{
  441.          $this->range[1= (float)$max;
  442.        }
  443.      }
  444.  
  445.      /**
  446.       * Get axis range
  447.       *
  448.       * @return array 
  449.       */
  450.      function getRange({
  451.        return $this->range;
  452.      }
  453.  
  454.      /**
  455.       * Change axis range callback function
  456.       *
  457.       * @param string $toValue Transform a position between 0 and 1 to a value
  458.       * @param string $toPosition Transform a value to a position between 0 and 1 on the axis
  459.       */
  460.      function setRangeCallback($toValue$toPosition{
  461.        $this->rangeCallback = array(
  462.             'toValue' => (string)$toValue,
  463.             'toPosition' => (string)$toPosition
  464.        );
  465.      }
  466.  
  467.      /**
  468.       * Center X values of the axis
  469.       *
  470.       * @param &$axis An axis
  471.       * @param float $value The reference value on the axis
  472.       */
  473.      function setXCenter(&$axis$value{
  474.  
  475.        // Check vector angle
  476.        if($this->line->isVertical(=== FALSE{
  477.          awImage::drawError("Class Axis: setXCenter() can only be used on vertical axes.");
  478.        }
  479.  
  480.        $p $axis->getPointFromValue($value);
  481.  
  482.        $this->line->setX(
  483.        $p->x,
  484.        $p->x
  485.        );
  486.  
  487.      }
  488.  
  489.      /**
  490.       * Center Y values of the axis
  491.       *
  492.       * @param &$axis An axis
  493.       * @param float $value The reference value on the axis
  494.       */
  495.      function setYCenter(&$axis$value{
  496.  
  497.        // Check vector angle
  498.        if($this->line->isHorizontal(=== FALSE{
  499.          awImage::drawError("Class Axis: setYCenter() can only be used on horizontal axes.");
  500.        }
  501.  
  502.        $p $axis->getPointFromValue($value);
  503.  
  504.        $this->line->setY(
  505.        $p->y,
  506.        $p->y
  507.        );
  508.  
  509.      }
  510.  
  511.      /**
  512.       * Get the distance between to values on the axis
  513.       *
  514.       * @param float $from The first value
  515.       * @param float $to The last value
  516.       * @return Point 
  517.       */
  518.      function getDistance($from$to{
  519.  
  520.        $p1 $this->getPointFromValue($from);
  521.        $p2 $this->getPointFromValue($to);
  522.  
  523.        return $p1->getDistance($p2);
  524.  
  525.      }
  526.  
  527.      /**
  528.       * Get a point on the axis from a value
  529.       *
  530.       * @param float $value 
  531.       * @return Point 
  532.       */
  533.      function getPointFromValue($value{
  534.  
  535.        $callback $this->rangeCallback['toPosition'];
  536.  
  537.        list($min$max$this->range;
  538.        $position $callback($value$min$max);
  539.  
  540.        return $this->getPointFromPosition($position);
  541.  
  542.      }
  543.  
  544.      /**
  545.       * Get a point on the axis from a position
  546.       *
  547.       * @param float $position A position between 0 and 1
  548.       * @return Point 
  549.       */
  550.      function getPointFromPosition($position{
  551.  
  552.        $vector $this->getVector();
  553.  
  554.        $angle $vector->getAngle();
  555.        $size $vector->getSize();
  556.  
  557.        return $vector->p1->move(
  558.        cos($angle$size $position,
  559.        -sin($angle$size $position
  560.        );
  561.  
  562.      }
  563.  
  564.      /**
  565.       * Draw axis
  566.       *
  567.       * @param $driver A driver
  568.       */
  569.      function draw($driver{
  570.  
  571.        if($this->hide{
  572.          return;
  573.        }
  574.  
  575.        $vector $this->getVector();
  576.  
  577.        // Draw axis ticks
  578.        $this->drawTicks($driver$vector);
  579.  
  580.        // Draw axis line
  581.        $this->line($driver);
  582.  
  583.        // Draw labels
  584.        $this->drawLabels($driver);
  585.  
  586.        // Draw axis title
  587.        $p $this->getPointFromPosition($this->titlePosition);
  588.        $this->title->draw($driver$p);
  589.  
  590.      }
  591.  
  592.      function autoScale({
  593.  
  594.        if($this->isAuto(=== FALSE{
  595.          return;
  596.        }
  597.  
  598.        list($min$max$this->getRange();
  599.        $interval $max $min;
  600.  
  601.        if($interval 0{
  602.          $partMax $max $interval;
  603.          $partMin $min $interval;
  604.        else {
  605.          $partMax 0;
  606.          $partMin 0;
  607.        }
  608.  
  609.        $difference log($intervallog(10);
  610.        $difference floor($difference);
  611.  
  612.        $pow pow(10$difference);
  613.  
  614.        if($pow 0{
  615.          $intervalNormalize $interval $pow;
  616.        else {
  617.          $intervalNormalize 0;
  618.        }
  619.  
  620.        if($difference <= 0{
  621.  
  622.          $precision $difference * -1;
  623.  
  624.          if($intervalNormalize 2{
  625.            $precision--;
  626.          }
  627.  
  628.        else {
  629.          $precision 0;
  630.        }
  631.  
  632.        if($min != and $max != 0{
  633.          $precision++;
  634.        }
  635.  
  636.        if($this->label->getCallbackFunction(=== NULL{
  637.          $this->setLabelPrecision($precision);
  638.        }
  639.  
  640.        if($intervalNormalize <= 1.5{
  641.          $intervalReal 1.5;
  642.          $labelNumber 4;
  643.        else if($intervalNormalize <= 2{
  644.          $intervalReal 2;
  645.          $labelNumber 5;
  646.        else if($intervalNormalize <= 3{
  647.          $intervalReal 3;
  648.          $labelNumber 4;
  649.        else if($intervalNormalize <= 4{
  650.          $intervalReal 4;
  651.          $labelNumber 5;
  652.        else if($intervalNormalize <= 5{
  653.          $intervalReal 5;
  654.          $labelNumber 6;
  655.        else if($intervalNormalize <= 8{
  656.          $intervalReal 8;
  657.          $labelNumber 5;
  658.        else if($intervalNormalize <= 10{
  659.          $intervalReal 10;
  660.          $labelNumber 6;
  661.        }
  662.  
  663.        if($min == 0{
  664.  
  665.          $this->setRange(
  666.          $min,
  667.          $intervalReal $pow
  668.          );
  669.  
  670.        else if($max == 0{
  671.  
  672.          $this->setRange(
  673.          $intervalReal $pow * -1,
  674.          0
  675.          );
  676.  
  677.        }
  678.  
  679.        $this->setLabelNumber($labelNumber);
  680.  
  681.      }
  682.  
  683.      function line($driver{
  684.  
  685.        $driver->line(
  686.        $this->color,
  687.        $this->line
  688.        );
  689.  
  690.      }
  691.  
  692.      function drawTicks($driver&$vector{
  693.  
  694.        foreach($this->ticks as $tick{
  695.          $tick->setColor($this->color);
  696.          $tick->draw($driver$vector);
  697.        }
  698.  
  699.      }
  700.  
  701.      function drawLabels($driver{
  702.  
  703.        if($this->labelNumber !== NULL{
  704.          list($min$max$this->range;
  705.          $number $this->labelNumber - 1;
  706.          if($number 1{
  707.            return;
  708.          }
  709.          $function $this->rangeCallback['toValue'];
  710.          $labels array();
  711.          for($i 0$i <= $number$i++{
  712.            $labels[$function($i $number$min$max);
  713.          }
  714.          $this->label->set($labels);
  715.        }
  716.  
  717.        $labels $this->label->count();
  718.  
  719.        for($i 0$i $labels$i++{
  720.  
  721.          $p $this->getPointFromValue($this->label->get($i));
  722.          $this->label->draw($driver$p$i);
  723.  
  724.        }
  725.  
  726.      }
  727.  
  728.      function getVector({
  729.  
  730.        $angle $this->line->getAngle();
  731.  
  732.        // Compute paddings
  733.        $vector new awVector(
  734.        $this->line->p1->move(
  735.                 cos($angle$this->padding->left,
  736.                 -sin($angle$this->padding->left
  737.                 ),
  738.                 $this->line->p2->move(
  739.                 -cos($angle$this->padding->right,
  740.                 -* -sin($angle$this->padding->right
  741.                 )
  742.                 );
  743.  
  744.                 return $vector;
  745.  
  746.      }
  747.  
  748.      function __clone({
  749.  
  750.        $this->label = $this->label;
  751.        $this->line = $this->line;
  752.        $this->title = $this->title;
  753.  
  754.        foreach($this->ticks as $name => $tick{
  755.          $this->ticks[$name$tick;
  756.        }
  757.  
  758.      }
  759.  
  760. }
  761.  
  762. registerClass('Axis');
  763.  
  764. function toProportionalValue($position$min$max{
  765.   return $min ($max $min$position;
  766. }
  767.  
  768. function toProportionalPosition($value$min$max{
  769.   if($max $min == 0{
  770.     return 0;
  771.   }
  772.   return ($value $min($max $min);
  773. }
  774. ?>

Documentation generated on Thu, 03 May 2012 15:02:07 +0200 by phpDocumentor 1.4.1