| <?php |
| /** |
| * File containing the ezcGraphChartElementLogarithmicalAxis class |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| * @package Graph |
| * @version //autogentag// |
| * @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved. |
| * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 |
| */ |
| /** |
| * Class to represent a logarithmic axis. |
| * |
| * Axis elements represent the axis in a bar, line or radar chart. They are |
| * chart elements (ezcGraphChartElement) extending from |
| * ezcGraphChartElementAxis, where additional formatting options can be found. |
| * You should generally use the axis, which matches your input data best, so |
| * that the automatic chart layouting works best. Aavailable axis types are: |
| * |
| * - ezcGraphChartElementDateAxis |
| * - ezcGraphChartElementLabeledAxis |
| * - ezcGraphChartElementLogarithmicalAxis |
| * - ezcGraphChartElementNumericAxis |
| * |
| * Logarithmic axis are normally used to display very large or small values. |
| * Logarithmic axis can not be used for value spans including zero, so you |
| * should either pass only positive or only negative values to the chart. |
| * |
| * By default the axis uses a base of 10 for scaling, you may assign any other |
| * base to the $base property of the chart. With a base of 10 the steps on the |
| * axis may, for example, be at: 1, 10, 100, 1000, 10000, ... |
| * |
| * The logarithmic axis may be used like: |
| * |
| * <code> |
| * $graph = new ezcGraphLineChart(); |
| * $graph->title = 'The power of x'; |
| * $graph->legend->position = ezcGraph::BOTTOM; |
| * |
| * $graph->xAxis = new ezcGraphChartElementNumericAxis(); |
| * $graph->yAxis = new ezcGraphChartElementLogarithmicalAxis(); |
| * |
| * $graph->data['x^2'] = new ezcGraphNumericDataSet( |
| * -10, 10, |
| * create_function( '$x', 'return pow( $x, 2 ) + 1;' ) |
| * ); |
| * |
| * $graph->data['x^4'] = new ezcGraphNumericDataSet( |
| * -10, 10, |
| * create_function( '$x', 'return pow( $x, 4 ) + 1;' ) |
| * ); |
| * |
| * $graph->data['x^6'] = new ezcGraphNumericDataSet( |
| * -10, 10, |
| * create_function( '$x', 'return pow( $x, 6 ) + 1;' ) |
| * ); |
| * |
| * $graph->render( 400, 250, 'tutorial_axis_logarithmic.svg' ); |
| * </code> |
| * |
| * @property float $base |
| * Base for logarithmical scaling. |
| * @property string $logarithmicalFormatString |
| * Sprintf formatstring for the axis labels where |
| * $1 is the base and |
| * $2 is the exponent. |
| * @property-read float $minValue |
| * Minimum Value to display on this axis. |
| * @property-read float $maxValue |
| * Maximum value to display on this axis. |
| * |
| * @version //autogentag// |
| * @package Graph |
| * @mainclass |
| */ |
| class ezcGraphChartElementLogarithmicalAxis extends ezcGraphChartElementAxis |
| { |
| |
| /** |
| * Constant used for calculation of automatic definition of major scaling |
| * steps |
| */ |
| const MAX_STEPS = 9; |
| |
| /** |
| * Constructor |
| * |
| * @param array $options Default option array |
| * @return void |
| * @ignore |
| */ |
| public function __construct( array $options = array() ) |
| { |
| $this->properties['min'] = null; |
| $this->properties['max'] = null; |
| $this->properties['base'] = 10; |
| $this->properties['logarithmicalFormatString'] = '%1$d^%2$d'; |
| $this->properties['minValue'] = null; |
| $this->properties['maxValue'] = null; |
| |
| parent::__construct( $options ); |
| } |
| |
| /** |
| * __set |
| * |
| * @param mixed $propertyName |
| * @param mixed $propertyValue |
| * @throws ezcBaseValueException |
| * If a submitted parameter was out of range or type. |
| * @throws ezcBasePropertyNotFoundException |
| * If a the value for the property options is not an instance of |
| * @return void |
| * @ignore |
| */ |
| public function __set( $propertyName, $propertyValue ) |
| { |
| switch ( $propertyName ) |
| { |
| case 'min': |
| case 'max': |
| if ( !is_numeric( $propertyValue ) ) |
| { |
| throw new ezcBaseValueException( $propertyName, $propertyValue, 'float' ); |
| } |
| |
| $this->properties[$propertyName] = (float) $propertyValue; |
| $this->properties['initialized'] = true; |
| break; |
| case 'base': |
| if ( !is_numeric( $propertyValue ) || |
| ( $propertyValue <= 0 ) ) |
| { |
| throw new ezcBaseValueException( $propertyName, $propertyValue, 'float > 0' ); |
| } |
| |
| $this->properties[$propertyName] = (float) $propertyValue; |
| break; |
| case 'logarithmicalFormatString': |
| $this->properties['logarithmicalFormatString'] = (string) $propertyValue; |
| break; |
| default: |
| parent::__set( $propertyName, $propertyValue ); |
| break; |
| } |
| } |
| |
| /** |
| * Add data for this axis |
| * |
| * @param array $values Value which will be displayed on this axis |
| * @return void |
| */ |
| public function addData( array $values ) |
| { |
| foreach ( $values as $value ) |
| { |
| if ( $this->properties['minValue'] === null || |
| $value < $this->properties['minValue'] ) |
| { |
| $this->properties['minValue'] = $value; |
| } |
| |
| if ( $this->properties['maxValue'] === null || |
| $value > $this->properties['maxValue'] ) |
| { |
| $this->properties['maxValue'] = $value; |
| } |
| } |
| |
| $this->properties['initialized'] = true; |
| } |
| |
| /** |
| * Calculate axis bounding values on base of the assigned values |
| * |
| * @abstract |
| * @access public |
| * @return void |
| */ |
| public function calculateAxisBoundings() |
| { |
| // Prevent division by zero, when min == max |
| if ( $this->properties['minValue'] == $this->properties['maxValue'] ) |
| { |
| if ( $this->properties['minValue'] == 0 ) |
| { |
| $this->properties['maxValue'] = 1; |
| } |
| else |
| { |
| $this->properties['minValue'] -= ( $this->properties['minValue'] * .1 ); |
| $this->properties['maxValue'] += ( $this->properties['maxValue'] * .1 ); |
| } |
| } |
| |
| if ( $this->properties['minValue'] <= 0 ) |
| { |
| throw new ezcGraphOutOfLogithmicalBoundingsException( $this->properties['minValue'] ); |
| } |
| |
| // Use custom minimum and maximum if available |
| if ( $this->properties['min'] !== null ) |
| { |
| $this->properties['minValue'] = pow( $this->properties['base'], $this->properties['min'] ); |
| } |
| |
| if ( $this->properties['max'] !== null ) |
| { |
| $this->properties['maxValue'] = pow( $this->properties['base'], $this->properties['max'] ); |
| } |
| |
| // Calculate "nice" values for scaling parameters |
| if ( $this->properties['min'] === null ) |
| { |
| $this->properties['min'] = floor( log( $this->properties['minValue'], $this->properties['base'] ) ); |
| } |
| |
| if ( $this->properties['max'] === null ) |
| { |
| $this->properties['max'] = ceil( log( $this->properties['maxValue'], $this->properties['base'] ) ); |
| } |
| |
| $this->properties['minorStep'] = 1; |
| if ( ( $modifier = ( ( $this->properties['max'] - $this->properties['min'] ) / self::MAX_STEPS ) ) > 1 ) |
| { |
| $this->properties['majorStep'] = $modifier = ceil( $modifier ); |
| $this->properties['min'] = floor( $this->properties['min'] / $modifier ) * $modifier; |
| $this->properties['max'] = floor( $this->properties['max'] / $modifier ) * $modifier; |
| } |
| else |
| { |
| $this->properties['majorStep'] = 1; |
| } |
| } |
| |
| /** |
| * Get coordinate for a dedicated value on the chart |
| * |
| * @param float $value Value to determine position for |
| * @return float Position on chart |
| */ |
| public function getCoordinate( $value ) |
| { |
| // Force typecast, because ( false < -100 ) results in (bool) true |
| $floatValue = (float) $value; |
| |
| if ( $value === false ) |
| { |
| switch ( $this->position ) |
| { |
| case ezcGraph::LEFT: |
| case ezcGraph::TOP: |
| return 0.; |
| case ezcGraph::RIGHT: |
| case ezcGraph::BOTTOM: |
| return 1.; |
| } |
| } |
| else |
| { |
| $position = ( log( $value, $this->properties['base'] ) - $this->properties['min'] ) / ( $this->properties['max'] - $this->properties['min'] ); |
| |
| switch ( $this->position ) |
| { |
| case ezcGraph::LEFT: |
| case ezcGraph::TOP: |
| return $position; |
| case ezcGraph::RIGHT: |
| case ezcGraph::BOTTOM: |
| return 1 - $position; |
| } |
| } |
| } |
| |
| /** |
| * Return count of minor steps |
| * |
| * @return integer Count of minor steps |
| */ |
| public function getMinorStepCount() |
| { |
| return (int) ( ( $this->properties['max'] - $this->properties['min'] ) / $this->properties['minorStep'] ); |
| } |
| |
| /** |
| * Return count of major steps |
| * |
| * @return integer Count of major steps |
| */ |
| public function getMajorStepCount() |
| { |
| return (int) ( ( $this->properties['max'] - $this->properties['min'] ) / $this->properties['majorStep'] ); |
| } |
| |
| /** |
| * Get label for a dedicated step on the axis |
| * |
| * @param integer $step Number of step |
| * @return string label |
| */ |
| public function getLabel( $step ) |
| { |
| if ( $this->properties['labelCallback'] !== null ) |
| { |
| return call_user_func_array( |
| $this->properties['labelCallback'], |
| array( |
| sprintf( |
| $this->properties['logarithmicalFormatString'], |
| $this->properties['base'], |
| $this->properties['min'] + ( $step * $this->properties['majorStep'] ) |
| ), |
| $step, |
| ) |
| ); |
| } |
| else |
| { |
| return sprintf( |
| $this->properties['logarithmicalFormatString'], |
| $this->properties['base'], |
| $this->properties['min'] + ( $step * $this->properties['majorStep'] ) |
| ); |
| } |
| } |
| |
| /** |
| * Is zero step |
| * |
| * Returns true if the given step is the one on the initial axis position |
| * |
| * @param int $step Number of step |
| * @return bool Status If given step is initial axis position |
| */ |
| public function isZeroStep( $step ) |
| { |
| return ( $step == 0 ); |
| } |
| } |
| |
| ?> |