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

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