[ Index ]

PHP Cross Reference of MantisBT

title

Body

[close]

/library/ezc/Graph/src/axis/ -> logarithmic.php (source)

   1  <?php
   2  /**
   3   * File containing the ezcGraphChartElementLogarithmicalAxis class
   4   *
   5   * @package Graph
   6   * @version 1.5
   7   * @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved.
   8   * @license http://ez.no/licenses/new_bsd New BSD License
   9   */
  10  /**
  11   * Class to represent a logarithmic axis.
  12   *
  13   * Axis elements represent the axis in a bar, line or radar chart. They are
  14   * chart elements (ezcGraphChartElement) extending from
  15   * ezcGraphChartElementAxis, where additional formatting options can be found.
  16   * You should generally use the axis, which matches your input data best, so
  17   * that the automatic chart layouting works best. Aavailable axis types are:
  18   *
  19   * - ezcGraphChartElementDateAxis
  20   * - ezcGraphChartElementLabeledAxis
  21   * - ezcGraphChartElementLogarithmicalAxis
  22   * - ezcGraphChartElementNumericAxis
  23   *
  24   * Logarithmic axis are normally used to display very large or small values.
  25   * Logarithmic axis can not be used for value spans including zero, so you
  26   * should either pass only positive or only negative values to the chart.
  27   *
  28   * By default the axis uses a base of 10 for scaling, you may assign any other
  29   * base to the $base property of the chart. With a base of 10 the steps on the
  30   * axis may, for example, be at: 1, 10, 100, 1000, 10000, ...
  31   *
  32   * The logarithmic axis may be used like:
  33   *
  34   * <code>
  35   *  $graph = new ezcGraphLineChart();
  36   *  $graph->title = 'The power of x';
  37   *  $graph->legend->position = ezcGraph::BOTTOM;
  38   *  
  39   *  $graph->xAxis = new ezcGraphChartElementNumericAxis();
  40   *  $graph->yAxis = new ezcGraphChartElementLogarithmicalAxis();
  41   *  
  42   *  $graph->data['x^2'] = new ezcGraphNumericDataSet( 
  43   *      -10, 10,
  44   *      create_function( '$x', 'return pow( $x, 2 ) + 1;' )
  45   *  );
  46   *  
  47   *  $graph->data['x^4'] = new ezcGraphNumericDataSet( 
  48   *      -10, 10,
  49   *      create_function( '$x', 'return pow( $x, 4 ) + 1;' )
  50   *  );
  51   *  
  52   *  $graph->data['x^6'] = new ezcGraphNumericDataSet( 
  53   *      -10, 10,
  54   *      create_function( '$x', 'return pow( $x, 6 ) + 1;' )
  55   *  );
  56   *  
  57   *  $graph->render( 400, 250, 'tutorial_axis_logarithmic.svg' );
  58   * </code>
  59   *
  60   * @property float $base
  61   *           Base for logarithmical scaling.
  62   * @property string $logarithmicalFormatString
  63   *           Sprintf formatstring for the axis labels where
  64   *              $1 is the base and
  65   *              $2 is the exponent.
  66   * @property-read float $minValue
  67   *                Minimum Value to display on this axis.
  68   * @property-read float $maxValue
  69   *                Maximum value to display on this axis.
  70   *           
  71   * @version 1.5
  72   * @package Graph
  73   * @mainclass
  74   */
  75  class ezcGraphChartElementLogarithmicalAxis extends ezcGraphChartElementAxis
  76  {
  77  
  78      /**
  79       * Constant used for calculation of automatic definition of major scaling 
  80       * steps
  81       */
  82      const MAX_STEPS = 9;
  83  
  84      /**
  85       * Constructor
  86       * 
  87       * @param array $options Default option array
  88       * @return void
  89       * @ignore
  90       */
  91      public function __construct( array $options = array() )
  92      {
  93          $this->properties['min'] = null;
  94          $this->properties['max'] = null;
  95          $this->properties['base'] = 10;
  96          $this->properties['logarithmicalFormatString'] = '%1$d^%2$d';
  97          $this->properties['minValue'] = null;
  98          $this->properties['maxValue'] = null;
  99  
 100          parent::__construct( $options );
 101      }
 102  
 103      /**
 104       * __set 
 105       * 
 106       * @param mixed $propertyName 
 107       * @param mixed $propertyValue 
 108       * @throws ezcBaseValueException
 109       *          If a submitted parameter was out of range or type.
 110       * @throws ezcBasePropertyNotFoundException
 111       *          If a the value for the property options is not an instance of
 112       * @return void
 113       * @ignore
 114       */
 115      public function __set( $propertyName, $propertyValue )
 116      {
 117          switch ( $propertyName )
 118          {
 119              case 'min':
 120              case 'max':
 121                  if ( !is_numeric( $propertyValue ) )
 122                  {
 123                      throw new ezcBaseValueException( $propertyName, $propertyValue, 'float' );
 124                  }
 125  
 126                  $this->properties[$propertyName] = (float) $propertyValue;
 127                  $this->properties['initialized'] = true;
 128                  break;
 129              case 'base':
 130                  if ( !is_numeric( $propertyValue ) ||
 131                       ( $propertyValue <= 0 ) )
 132                  {
 133                      throw new ezcBaseValueException( $propertyName, $propertyValue, 'float > 0' );
 134                  }
 135  
 136                  $this->properties[$propertyName] = (float) $propertyValue;
 137                  break;
 138              case 'logarithmicalFormatString':
 139                  $this->properties['logarithmicalFormatString'] = (string) $propertyValue;
 140                  break;
 141              default:
 142                  parent::__set( $propertyName, $propertyValue );
 143                  break;
 144          }
 145      }
 146      
 147      /**
 148       * Add data for this axis
 149       * 
 150       * @param array $values Value which will be displayed on this axis
 151       * @return void
 152       */
 153      public function addData( array $values )
 154      {
 155          foreach ( $values as $value )
 156          {
 157              if ( $this->properties['minValue'] === null ||
 158                   $value < $this->properties['minValue'] )
 159              {
 160                  $this->properties['minValue'] = $value;
 161              }
 162  
 163              if ( $this->properties['maxValue'] === null ||
 164                   $value > $this->properties['maxValue'] )
 165              {
 166                  $this->properties['maxValue'] = $value;
 167              }
 168          }
 169  
 170          $this->properties['initialized'] = true;
 171      }
 172  
 173      /**
 174       * Calculate axis bounding values on base of the assigned values 
 175       * 
 176       * @abstract
 177       * @access public
 178       * @return void
 179       */
 180      public function calculateAxisBoundings()
 181      {
 182          // Prevent division by zero, when min == max
 183          if ( $this->properties['minValue'] == $this->properties['maxValue'] )
 184          {
 185              if ( $this->properties['minValue'] == 0 )
 186              {
 187                  $this->properties['maxValue'] = 1;
 188              }
 189              else
 190              {
 191                  $this->properties['minValue'] -= ( $this->properties['minValue'] * .1 );
 192                  $this->properties['maxValue'] += ( $this->properties['maxValue'] * .1 );
 193              }
 194          }
 195  
 196          if ( $this->properties['minValue'] <= 0 )
 197          {
 198              throw new ezcGraphOutOfLogithmicalBoundingsException( $this->properties['minValue'] );
 199          }
 200  
 201          // Use custom minimum and maximum if available
 202          if ( $this->properties['min'] !== null )
 203          {
 204              $this->properties['minValue'] = pow( $this->properties['base'], $this->properties['min'] );
 205          }
 206  
 207          if ( $this->properties['max'] !== null )
 208          {
 209              $this->properties['maxValue'] = pow( $this->properties['base'], $this->properties['max'] );
 210          }
 211  
 212          // Calculate "nice" values for scaling parameters
 213          if ( $this->properties['min'] === null )
 214          {
 215              $this->properties['min'] = floor( log( $this->properties['minValue'], $this->properties['base'] ) );
 216          }
 217  
 218          if ( $this->properties['max'] === null )
 219          {
 220              $this->properties['max'] = ceil( log( $this->properties['maxValue'], $this->properties['base'] ) );
 221          }
 222  
 223          $this->properties['minorStep'] = 1;
 224          if ( ( $modifier = ( ( $this->properties['max'] - $this->properties['min'] ) / self::MAX_STEPS ) ) > 1 )
 225          {
 226              $this->properties['majorStep'] = $modifier = ceil( $modifier );
 227              $this->properties['min'] = floor( $this->properties['min'] / $modifier ) * $modifier;
 228              $this->properties['max'] = floor( $this->properties['max'] / $modifier ) * $modifier;
 229          }
 230          else
 231          {
 232              $this->properties['majorStep'] = 1;
 233          }
 234      }
 235  
 236      /**
 237       * Get coordinate for a dedicated value on the chart
 238       * 
 239       * @param float $value Value to determine position for
 240       * @return float Position on chart
 241       */
 242      public function getCoordinate( $value )
 243      {
 244          // Force typecast, because ( false < -100 ) results in (bool) true
 245          $floatValue = (float) $value;
 246  
 247          if ( $value === false )
 248          {
 249              switch ( $this->position )
 250              {
 251                  case ezcGraph::LEFT:
 252                  case ezcGraph::TOP:
 253                      return 0.;
 254                  case ezcGraph::RIGHT:
 255                  case ezcGraph::BOTTOM:
 256                      return 1.;
 257              }
 258          }
 259          else
 260          {
 261              $position = ( log( $value, $this->properties['base'] ) - $this->properties['min'] ) / ( $this->properties['max'] - $this->properties['min'] );
 262  
 263              switch ( $this->position )
 264              {
 265                  case ezcGraph::LEFT:
 266                  case ezcGraph::TOP:
 267                      return $position;
 268                  case ezcGraph::RIGHT:
 269                  case ezcGraph::BOTTOM:
 270                      return 1 - $position;
 271              }
 272          }
 273      }
 274  
 275      /**
 276       * Return count of minor steps
 277       * 
 278       * @return integer Count of minor steps
 279       */
 280      public function getMinorStepCount()
 281      {
 282          return (int) ( ( $this->properties['max'] - $this->properties['min'] ) / $this->properties['minorStep'] );
 283      }
 284  
 285      /**
 286       * Return count of major steps
 287       * 
 288       * @return integer Count of major steps
 289       */
 290      public function getMajorStepCount()
 291      {
 292          return (int) ( ( $this->properties['max'] - $this->properties['min'] ) / $this->properties['majorStep'] );
 293      }
 294  
 295      /**
 296       * Get label for a dedicated step on the axis
 297       * 
 298       * @param integer $step Number of step
 299       * @return string label
 300       */
 301      public function getLabel( $step )
 302      {
 303          if ( $this->properties['labelCallback'] !== null )
 304          {
 305              return call_user_func_array(
 306                  $this->properties['labelCallback'],
 307                  array(
 308                      sprintf( 
 309                          $this->properties['logarithmicalFormatString'],
 310                          $this->properties['base'],
 311                          $this->properties['min'] + ( $step * $this->properties['majorStep'] )
 312                      ),
 313                      $step,
 314                  )
 315              );
 316          }
 317          else
 318          {
 319              return sprintf( 
 320                  $this->properties['logarithmicalFormatString'],
 321                  $this->properties['base'],
 322                  $this->properties['min'] + ( $step * $this->properties['majorStep'] )
 323              );
 324          }
 325      }
 326  
 327      /**
 328       * Is zero step
 329       *
 330       * Returns true if the given step is the one on the initial axis position
 331       * 
 332       * @param int $step Number of step
 333       * @return bool Status If given step is initial axis position
 334       */
 335      public function isZeroStep( $step )
 336      {
 337          return ( $step == 0 );
 338      }
 339  }
 340  
 341  ?>


Generated: Thu Jul 28 15:48:31 2011 Cross-referenced by PHPXref 0.7