/apps/principal/lib/Graph/src/element/axis.php

https://github.com/proyectoalba/alba · PHP · 438 lines · 258 code · 31 blank · 149 comment · 17 complexity · 657965bce96afdcf2ced57de26cf4e91 MD5 · raw file

  1. <?php
  2. /**
  3. * File containing the abstract ezcGraphChartElementAxis class
  4. *
  5. * @package Graph
  6. * @version 1.2
  7. * @copyright Copyright (C) 2005-2007 eZ systems as. All rights reserved.
  8. * @license http://ez.no/licenses/new_bsd New BSD License
  9. */
  10. /**
  11. * Basic axis class
  12. *
  13. * @property float $nullPosition
  14. * The position of the null value.
  15. * @property float $axisSpace
  16. * Percent of the chart space used to display axis labels and
  17. * arrowheads instead of data values.
  18. * @property ezcGraphColor $majorGrid
  19. * Color of major majorGrid.
  20. * @property ezcGraphColor $minorGrid
  21. * Color of minor majorGrid.
  22. * @property mixed $majorStep
  23. * Labeled major steps displayed on the axis. @TODO: Should be moved
  24. * to numeric axis.
  25. * @property mixed $minorStep
  26. * Non labeled minor steps on the axis. @TODO: Should be moved to
  27. * numeric axis.
  28. * @property string $formatString
  29. * Formatstring to use for labeling of the axis.
  30. * @property string $label
  31. * Axis label
  32. * @property int $labelSize
  33. * Size of axis label
  34. * @property int $labelMargin
  35. * Distance between label an axis
  36. * @property int $minArrowHeadSize
  37. * Minimum Size used to draw arrow heads.
  38. * @property int $maxArrowHeadSize
  39. * Maximum Size used to draw arrow heads.
  40. * @property ezcGraphAxisLabelRenderer $axisLabelRenderer
  41. * AxisLabelRenderer used to render labels and grid on this axis.
  42. * @property callback $labelCallback
  43. * Callback function to format chart labels.
  44. * Function will receive two parameters and should return a
  45. * reformatted label.
  46. * string function( label, step )
  47. * @property float $chartPosition
  48. * Position of the axis in the chart. Only useful for additional
  49. * axis. The basic chart axis will be automatically positioned.
  50. * @property-read bool $initialized
  51. * Property indicating if some values were associated with axis, or a
  52. * scaling has been set manually.
  53. *
  54. * @version 1.2
  55. * @package Graph
  56. */
  57. abstract class ezcGraphChartElementAxis extends ezcGraphChartElement
  58. {
  59. /**
  60. * Axis label renderer class
  61. *
  62. * @var ezcGraphAxisLabelRenderer
  63. */
  64. protected $axisLabelRenderer;
  65. /**
  66. * Constructor
  67. *
  68. * @param array $options Default option array
  69. * @return void
  70. * @ignore
  71. */
  72. public function __construct( array $options = array() )
  73. {
  74. $this->properties['nullPosition'] = false;
  75. $this->properties['axisSpace'] = .1;
  76. $this->properties['majorGrid'] = false;
  77. $this->properties['minorGrid'] = false;
  78. $this->properties['majorStep'] = null;
  79. $this->properties['minorStep'] = null;
  80. $this->properties['formatString'] = '%s';
  81. $this->properties['label'] = false;
  82. $this->properties['labelSize'] = 14;
  83. $this->properties['labelMargin'] = 2;
  84. $this->properties['minArrowHeadSize'] = 4;
  85. $this->properties['maxArrowHeadSize'] = 8;
  86. $this->properties['labelCallback'] = null;
  87. $this->properties['chartPosition'] = null;
  88. $this->properties['initialized'] = false;
  89. parent::__construct( $options );
  90. if ( !isset( $this->axisLabelRenderer ) )
  91. {
  92. $this->axisLabelRenderer = new ezcGraphAxisExactLabelRenderer();
  93. }
  94. }
  95. /**
  96. * Set colors and border fro this element
  97. *
  98. * @param ezcGraphPalette $palette Palette
  99. * @return void
  100. */
  101. public function setFromPalette( ezcGraphPalette $palette )
  102. {
  103. $this->border = $palette->axisColor;
  104. $this->padding = $palette->padding;
  105. $this->margin = $palette->margin;
  106. $this->majorGrid = $palette->majorGridColor;
  107. $this->minorGrid = $palette->minorGridColor;
  108. }
  109. /**
  110. * __set
  111. *
  112. * @param mixed $propertyName
  113. * @param mixed $propertyValue
  114. * @throws ezcBaseValueException
  115. * If a submitted parameter was out of range or type.
  116. * @throws ezcBasePropertyNotFoundException
  117. * If a the value for the property options is not an instance of
  118. * @return void
  119. */
  120. public function __set( $propertyName, $propertyValue )
  121. {
  122. switch ( $propertyName )
  123. {
  124. case 'nullPosition':
  125. $this->properties['nullPosition'] = (float) $propertyValue;
  126. break;
  127. case 'axisSpace':
  128. if ( !is_numeric( $propertyValue ) ||
  129. ( $propertyValue < 0 ) ||
  130. ( $propertyValue > 1 ) )
  131. {
  132. throw new ezcBaseValueException( $propertyName, $propertyValue, '0 <= float <= 1' );
  133. }
  134. $this->properties['axisSpace'] = (float) $propertyValue;
  135. break;
  136. case 'majorGrid':
  137. $this->properties['majorGrid'] = ezcGraphColor::create( $propertyValue );
  138. break;
  139. case 'minorGrid':
  140. $this->properties['minorGrid'] = ezcGraphColor::create( $propertyValue );
  141. break;
  142. case 'majorStep':
  143. if ( !is_numeric( $propertyValue ) ||
  144. ( $propertyValue <= 0 ) )
  145. {
  146. throw new ezcBaseValueException( $propertyName, $propertyValue, 'float > 0' );
  147. }
  148. $this->properties['majorStep'] = (float) $propertyValue;
  149. break;
  150. case 'minorStep':
  151. if ( !is_numeric( $propertyValue ) ||
  152. ( $propertyValue <= 0 ) )
  153. {
  154. throw new ezcBaseValueException( $propertyName, $propertyValue, 'float > 0' );
  155. }
  156. $this->properties['minorStep'] = (float) $propertyValue;
  157. break;
  158. case 'formatString':
  159. $this->properties['formatString'] = (string) $propertyValue;
  160. break;
  161. case 'label':
  162. $this->properties['label'] = (string) $propertyValue;
  163. break;
  164. case 'labelSize':
  165. if ( !is_numeric( $propertyValue ) ||
  166. ( $propertyValue <= 6 ) )
  167. {
  168. throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 6' );
  169. }
  170. $this->properties['labelSize'] = (int) $propertyValue;
  171. break;
  172. case 'labelMargin':
  173. if ( !is_numeric( $propertyValue ) ||
  174. ( $propertyValue <= 0 ) )
  175. {
  176. throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' );
  177. }
  178. $this->properties['labelMargin'] = (int) $propertyValue;
  179. break;
  180. case 'maxArrowHeadSize':
  181. if ( !is_numeric( $propertyValue ) ||
  182. ( $propertyValue <= 0 ) )
  183. {
  184. throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' );
  185. }
  186. $this->properties['maxArrowHeadSize'] = (int) $propertyValue;
  187. break;
  188. case 'minArrowHeadSize':
  189. if ( !is_numeric( $propertyValue ) ||
  190. ( $propertyValue <= 0 ) )
  191. {
  192. throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' );
  193. }
  194. $this->properties['minArrowHeadSize'] = (int) $propertyValue;
  195. break;
  196. case 'axisLabelRenderer':
  197. if ( $propertyValue instanceof ezcGraphAxisLabelRenderer )
  198. {
  199. $this->axisLabelRenderer = $propertyValue;
  200. }
  201. else
  202. {
  203. throw new ezcBaseValueException( $propertyName, $propertyValue, 'ezcGraphAxisLabelRenderer' );
  204. }
  205. break;
  206. case 'labelCallback':
  207. if ( is_callable( $propertyValue ) )
  208. {
  209. $this->properties['labelCallback'] = $propertyValue;
  210. }
  211. else
  212. {
  213. throw new ezcBaseValueException( $propertyName, $propertyValue, 'callback function' );
  214. }
  215. break;
  216. case 'chartPosition':
  217. if ( !is_numeric( $propertyValue ) ||
  218. ( $propertyValue < 0 ) ||
  219. ( $propertyValue > 1 ) )
  220. {
  221. throw new ezcBaseValueException( $propertyName, $propertyValue, '0 <= float <= 1' );
  222. }
  223. $this->properties['chartPosition'] = (float) $propertyValue;
  224. break;
  225. default:
  226. parent::__set( $propertyName, $propertyValue );
  227. break;
  228. }
  229. }
  230. /**
  231. * __get
  232. *
  233. * @param mixed $propertyName
  234. * @throws ezcBasePropertyNotFoundException
  235. * If a the value for the property options is not an instance of
  236. * @return mixed
  237. * @ignore
  238. */
  239. public function __get( $propertyName )
  240. {
  241. switch ( $propertyName )
  242. {
  243. case 'axisLabelRenderer':
  244. return $this->axisLabelRenderer;
  245. default:
  246. return parent::__get( $propertyName );
  247. }
  248. }
  249. /**
  250. * Get coordinate for a dedicated value on the chart
  251. *
  252. * @param float $value Value to determine position for
  253. * @return float Position on chart
  254. */
  255. abstract public function getCoordinate( $value );
  256. /**
  257. * Return count of minor steps
  258. *
  259. * @return integer Count of minor steps
  260. */
  261. abstract public function getMinorStepCount();
  262. /**
  263. * Return count of major steps
  264. *
  265. * @return integer Count of major steps
  266. */
  267. abstract public function getMajorStepCount();
  268. /**
  269. * Get label for a dedicated step on the axis
  270. *
  271. * @param integer $step Number of step
  272. * @return string label
  273. */
  274. abstract public function getLabel( $step );
  275. /**
  276. * Return array of steps on this axis
  277. *
  278. * @return array( ezcGraphAxisStep )
  279. */
  280. public function getSteps()
  281. {
  282. $majorSteps = $this->getMajorStepCount();
  283. $minorStepsPerMajorStepCount = ( $this->getMinorStepCount() / $majorSteps );
  284. $majorStepSize = 1 / $majorSteps;
  285. $minorStepSize = ( $minorStepsPerMajorStepCount > 0 ? $majorStepSize / $minorStepsPerMajorStepCount : 0 );
  286. $steps = array();
  287. for ( $major = 0; $major <= $majorSteps; ++$major )
  288. {
  289. $majorStep = new ezcGraphAxisStep(
  290. $majorStepSize * $major,
  291. $majorStepSize,
  292. $this->getLabel( $major ),
  293. array(),
  294. $this->isZeroStep( $major ),
  295. ( $major === $majorSteps )
  296. );
  297. if ( ( $minorStepsPerMajorStepCount > 0 ) &&
  298. ( $major < $majorSteps ) )
  299. {
  300. // Do not add minor steps at major steps positions
  301. for( $minor = 1; $minor < $minorStepsPerMajorStepCount; ++$minor )
  302. {
  303. $majorStep->childs[] = new ezcGraphAxisStep(
  304. ( $majorStepSize * $major ) + ( $minorStepSize * $minor ),
  305. $minorStepSize
  306. );
  307. }
  308. }
  309. $steps[] = $majorStep;
  310. }
  311. return $steps;
  312. }
  313. /**
  314. * Is zero step
  315. *
  316. * Returns true if the given step is the one on the initial axis position
  317. *
  318. * @param int $step Number of step
  319. * @return bool Status If given step is initial axis position
  320. */
  321. abstract public function isZeroStep( $step );
  322. /**
  323. * Add data for this axis
  324. *
  325. * @param array $values
  326. * @return void
  327. */
  328. abstract public function addData( array $values );
  329. /**
  330. * Calculate axis bounding values on base of the assigned values
  331. *
  332. * @abstract
  333. * @access public
  334. * @return void
  335. */
  336. abstract public function calculateAxisBoundings();
  337. /**
  338. * Render the axis
  339. *
  340. * @param ezcGraphRenderer $renderer Renderer
  341. * @param ezcGraphBoundings $boundings Boundings for the axis
  342. * @return ezcGraphBoundings Remaining boundings
  343. */
  344. public function render( ezcGraphRenderer $renderer, ezcGraphBoundings $boundings )
  345. {
  346. switch ( $this->position )
  347. {
  348. case ezcGraph::TOP:
  349. $start = new ezcGraphCoordinate(
  350. ( $boundings->x1 - $boundings->x0 ) * $this->axisSpace +
  351. $this->nullPosition * ( $boundings->x1 - $boundings->x0 ) * ( 1 - 2 * $this->axisSpace ),
  352. 0
  353. );
  354. $end = new ezcGraphCoordinate(
  355. ( $boundings->x1 - $boundings->x0 ) * $this->axisSpace +
  356. $this->nullPosition * ( $boundings->x1 - $boundings->x0 ) * ( 1 - 2 * $this->axisSpace ),
  357. $boundings->y1 - $boundings->y0
  358. );
  359. break;
  360. case ezcGraph::BOTTOM:
  361. $start = new ezcGraphCoordinate(
  362. ( $boundings->x1 - $boundings->x0 ) * $this->axisSpace +
  363. $this->nullPosition * ( $boundings->x1 - $boundings->x0 ) * ( 1 - 2 * $this->axisSpace ),
  364. $boundings->y1 - $boundings->y0
  365. );
  366. $end = new ezcGraphCoordinate(
  367. ( $boundings->x1 - $boundings->x0 ) * $this->axisSpace +
  368. $this->nullPosition * ( $boundings->x1 - $boundings->x0 ) * ( 1 - 2 * $this->axisSpace ),
  369. 0
  370. );
  371. break;
  372. case ezcGraph::LEFT:
  373. $start = new ezcGraphCoordinate(
  374. 0,
  375. ( $boundings->y1 - $boundings->y0 ) * $this->axisSpace +
  376. $this->nullPosition * ( $boundings->y1 - $boundings->y0 ) * ( 1 - 2 * $this->axisSpace )
  377. );
  378. $end = new ezcGraphCoordinate(
  379. $boundings->x1 - $boundings->x0,
  380. ( $boundings->y1 - $boundings->y0 ) * $this->axisSpace +
  381. $this->nullPosition * ( $boundings->y1 - $boundings->y0 ) * ( 1 - 2 * $this->axisSpace )
  382. );
  383. break;
  384. case ezcGraph::RIGHT:
  385. $start = new ezcGraphCoordinate(
  386. $boundings->x1 - $boundings->x0,
  387. ( $boundings->y1 - $boundings->y0 ) * $this->axisSpace +
  388. $this->nullPosition * ( $boundings->y1 - $boundings->y0 ) * ( 1 - 2 * $this->axisSpace )
  389. );
  390. $end = new ezcGraphCoordinate(
  391. 0,
  392. ( $boundings->y1 - $boundings->y0 ) * $this->axisSpace +
  393. $this->nullPosition * ( $boundings->y1 - $boundings->y0 ) * ( 1 - 2 * $this->axisSpace )
  394. );
  395. break;
  396. }
  397. $renderer->drawAxis(
  398. $boundings,
  399. $start,
  400. $end,
  401. $this,
  402. $this->axisLabelRenderer
  403. );
  404. return $boundings;
  405. }
  406. }
  407. ?>