PageRenderTime 50ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/ezc/Graph/src/axis/logarithmic.php

http://github.com/phpundercontrol/phpUnderControl
PHP | 341 lines | 174 code | 24 blank | 143 comment | 20 complexity | a18f5201cf21f3c333b9628b9e3281d3 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * File containing the ezcGraphChartElementLogarithmicalAxis class
  4. *
  5. * @package Graph
  6. * @version 1.4.3
  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.4.3
  72. * @package Graph
  73. * @mainclass
  74. */
  75. class ezcGraphChartElementLogarithmicalAxis extends ezcGraphChartElementAxis
  76. {
  77. /**
  78. * Constant used for calculation of automatic definition of major scaling
  79. * steps
  80. */
  81. const MAX_STEPS = 9;
  82. /**
  83. * Constructor
  84. *
  85. * @param array $options Default option array
  86. * @return void
  87. * @ignore
  88. */
  89. public function __construct( array $options = array() )
  90. {
  91. $this->properties['min'] = null;
  92. $this->properties['max'] = null;
  93. $this->properties['base'] = 10;
  94. $this->properties['logarithmicalFormatString'] = '%1$d^%2$d';
  95. $this->properties['minValue'] = null;
  96. $this->properties['maxValue'] = null;
  97. parent::__construct( $options );
  98. }
  99. /**
  100. * __set
  101. *
  102. * @param mixed $propertyName
  103. * @param mixed $propertyValue
  104. * @throws ezcBaseValueException
  105. * If a submitted parameter was out of range or type.
  106. * @throws ezcBasePropertyNotFoundException
  107. * If a the value for the property options is not an instance of
  108. * @return void
  109. * @ignore
  110. */
  111. public function __set( $propertyName, $propertyValue )
  112. {
  113. switch ( $propertyName )
  114. {
  115. case 'min':
  116. case 'max':
  117. if ( !is_numeric( $propertyValue ) )
  118. {
  119. throw new ezcBaseValueException( $propertyName, $propertyValue, 'float' );
  120. }
  121. $this->properties[$propertyName] = (float) $propertyValue;
  122. $this->properties['initialized'] = true;
  123. break;
  124. case 'base':
  125. if ( !is_numeric( $propertyValue ) ||
  126. ( $propertyValue <= 0 ) )
  127. {
  128. throw new ezcBaseValueException( $propertyName, $propertyValue, 'float > 0' );
  129. }
  130. $this->properties[$propertyName] = (float) $propertyValue;
  131. break;
  132. case 'logarithmicalFormatString':
  133. $this->properties['logarithmicalFormatString'] = (string) $propertyValue;
  134. break;
  135. default:
  136. parent::__set( $propertyName, $propertyValue );
  137. break;
  138. }
  139. }
  140. /**
  141. * Add data for this axis
  142. *
  143. * @param array $values Value which will be displayed on this axis
  144. * @return void
  145. */
  146. public function addData( array $values )
  147. {
  148. foreach ( $values as $value )
  149. {
  150. if ( $this->properties['minValue'] === null ||
  151. $value < $this->properties['minValue'] )
  152. {
  153. $this->properties['minValue'] = $value;
  154. }
  155. if ( $this->properties['maxValue'] === null ||
  156. $value > $this->properties['maxValue'] )
  157. {
  158. $this->properties['maxValue'] = $value;
  159. }
  160. }
  161. $this->properties['initialized'] = true;
  162. }
  163. /**
  164. * Calculate axis bounding values on base of the assigned values
  165. *
  166. * @abstract
  167. * @access public
  168. * @return void
  169. */
  170. public function calculateAxisBoundings()
  171. {
  172. // Prevent division by zero, when min == max
  173. if ( $this->properties['minValue'] == $this->properties['maxValue'] )
  174. {
  175. if ( $this->properties['minValue'] == 0 )
  176. {
  177. $this->properties['maxValue'] = 1;
  178. }
  179. else
  180. {
  181. $this->properties['minValue'] -= ( $this->properties['minValue'] * .1 );
  182. $this->properties['maxValue'] += ( $this->properties['maxValue'] * .1 );
  183. }
  184. }
  185. if ( $this->properties['minValue'] <= 0 )
  186. {
  187. throw new ezcGraphOutOfLogithmicalBoundingsException( $this->properties['minValue'] );
  188. }
  189. // Use custom minimum and maximum if available
  190. if ( $this->properties['min'] !== null )
  191. {
  192. $this->properties['minValue'] = pow( $this->properties['base'], $this->properties['min'] );
  193. }
  194. if ( $this->properties['max'] !== null )
  195. {
  196. $this->properties['maxValue'] = pow( $this->properties['base'], $this->properties['max'] );
  197. }
  198. // Calculate "nice" values for scaling parameters
  199. if ( $this->properties['min'] === null )
  200. {
  201. $this->properties['min'] = floor( log( $this->properties['minValue'], $this->properties['base'] ) );
  202. }
  203. if ( $this->properties['max'] === null )
  204. {
  205. $this->properties['max'] = ceil( log( $this->properties['maxValue'], $this->properties['base'] ) );
  206. }
  207. $this->properties['minorStep'] = 1;
  208. if ( ( $modifier = ( ( $this->properties['max'] - $this->properties['min'] ) / self::MAX_STEPS ) ) > 1 )
  209. {
  210. $this->properties['majorStep'] = $modifier = ceil( $modifier );
  211. $this->properties['min'] = floor( $this->properties['min'] / $modifier ) * $modifier;
  212. $this->properties['max'] = floor( $this->properties['max'] / $modifier ) * $modifier;
  213. }
  214. else
  215. {
  216. $this->properties['majorStep'] = 1;
  217. }
  218. }
  219. /**
  220. * Get coordinate for a dedicated value on the chart
  221. *
  222. * @param float $value Value to determine position for
  223. * @return float Position on chart
  224. */
  225. public function getCoordinate( $value )
  226. {
  227. // Force typecast, because ( false < -100 ) results in (bool) true
  228. $floatValue = (float) $value;
  229. if ( $value === false )
  230. {
  231. switch ( $this->position )
  232. {
  233. case ezcGraph::LEFT:
  234. case ezcGraph::TOP:
  235. return 0.;
  236. case ezcGraph::RIGHT:
  237. case ezcGraph::BOTTOM:
  238. return 1.;
  239. }
  240. }
  241. else
  242. {
  243. $position = ( log( $value, $this->properties['base'] ) - $this->properties['min'] ) / ( $this->properties['max'] - $this->properties['min'] );
  244. switch ( $this->position )
  245. {
  246. case ezcGraph::LEFT:
  247. case ezcGraph::TOP:
  248. return $position;
  249. case ezcGraph::RIGHT:
  250. case ezcGraph::BOTTOM:
  251. return 1 - $position;
  252. }
  253. }
  254. }
  255. /**
  256. * Return count of minor steps
  257. *
  258. * @return integer Count of minor steps
  259. */
  260. public function getMinorStepCount()
  261. {
  262. return (int) ( ( $this->properties['max'] - $this->properties['min'] ) / $this->properties['minorStep'] );
  263. }
  264. /**
  265. * Return count of major steps
  266. *
  267. * @return integer Count of major steps
  268. */
  269. public function getMajorStepCount()
  270. {
  271. return (int) ( ( $this->properties['max'] - $this->properties['min'] ) / $this->properties['majorStep'] );
  272. }
  273. /**
  274. * Get label for a dedicated step on the axis
  275. *
  276. * @param integer $step Number of step
  277. * @return string label
  278. */
  279. public function getLabel( $step )
  280. {
  281. if ( $this->properties['labelCallback'] !== null )
  282. {
  283. return call_user_func_array(
  284. $this->properties['labelCallback'],
  285. array(
  286. sprintf(
  287. $this->properties['logarithmicalFormatString'],
  288. $this->properties['base'],
  289. $this->properties['min'] + ( $step * $this->properties['majorStep'] )
  290. ),
  291. $step,
  292. )
  293. );
  294. }
  295. else
  296. {
  297. return sprintf(
  298. $this->properties['logarithmicalFormatString'],
  299. $this->properties['base'],
  300. $this->properties['min'] + ( $step * $this->properties['majorStep'] )
  301. );
  302. }
  303. }
  304. /**
  305. * Is zero step
  306. *
  307. * Returns true if the given step is the one on the initial axis position
  308. *
  309. * @param int $step Number of step
  310. * @return bool Status If given step is initial axis position
  311. */
  312. public function isZeroStep( $step )
  313. {
  314. return ( $step == 0 );
  315. }
  316. }
  317. ?>