| [ Index ] |
PHP Cross Reference of MantisBT |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * File containing the abstract ezcGraphChartElementAxis 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 an axis as a chart element 12 * 13 * Chart elements can be understood as widgets or layout container inside the 14 * chart. The actual transformation to images happens inside the renderers. 15 * They represent all elements inside the chart and contain mostly general 16 * formatting options, while the renderer itself might define additional 17 * formatting options for some chart elments. You can find more about the 18 * general formatting options for chart elements in the base class 19 * ezcGraphChartElement. 20 * 21 * The axis elements are special elements, as the border and background 22 * settings do not apply directly as axis axis are not put inside any boxes. 23 * The border value is reused for the color of the axis itself. 24 * 25 * Generally you should select the axis which matches your data best. By 26 * default a labeled x axis and a numeric y axis are used. If you are using 27 * date or time values on either axis, you should for example use a 28 * ezcGraphChartElementDateAxis. The currently available axis types are: 29 * 30 * - ezcGraphChartElementDateAxis 31 * - ezcGraphChartElementLabeledAxis 32 * - ezcGraphChartElementLogarithmicalAxis 33 * - ezcGraphChartElementNumericAxis 34 * 35 * Beside this there are several option to define the general layout of the 36 * axis labels. The $formatString option may be used to add additional text to 37 * each label on the axis, like a percent sign on the y axis: 38 * 39 * <code> 40 * $chart->xAxis->formatString = '%s %%'; 41 * </code> 42 * 43 * For more complex formatting operations for the label you may assign a custom 44 * formatter function to the property $labelCallback. 45 * 46 * The orientation of labels and their position relatively to the axis ticks is 47 * calcualted and rendered by the ezcGraphAxisLabelRenderer classes. You can 48 * choose between different axis label renderer, or create you own, and assign 49 * an instance of one to the property $axisLabelRenderer. Currently the 50 * available axis label renderers are: 51 * 52 * - ezcGraphAxisBoxedLabelRenderer 53 * 54 * Renders grid and labels like commonly used in bar charts, with the label 55 * between two grid lines. 56 * 57 * - ezcGraphAxisCenteredLabelRenderer 58 * 59 * Centers the label right next to a tick. Commonly used for labeled axis. 60 * 61 * - ezcGraphAxisExactLabelRenderer 62 * 63 * Put the label next to each tick. Commonly used for numeric axis. 64 * 65 * - ezcGraphAxisNoLabelRenderer 66 * 67 * Renders no labels. 68 * 69 * - ezcGraphAxisRadarLabelRenderer 70 * 71 * Special label renderer for radar charts. 72 * 73 * - ezcGraphAxisRotatedLabelRenderer 74 * 75 * Accepts a rotation angle for the texts put at some axis, which might be 76 * useful for longer textual labels on the axis. 77 * 78 * The label renderer used by default is different depending on the axis type. 79 * 80 * @property float $nullPosition 81 * The position of the null value. 82 * @property float $axisSpace 83 * Percent of the chart space used to display axis labels and 84 * arrowheads instead of data values. 85 * @property float $outerAxisSpace 86 * Percent of the chart space used to display axis arrow at the outer 87 * side of the axis. If set to null, the axisSpace will be used here. 88 * @property ezcGraphColor $majorGrid 89 * Color of major majorGrid. 90 * @property ezcGraphColor $minorGrid 91 * Color of minor majorGrid. 92 * @property mixed $majorStep 93 * Labeled major steps displayed on the axis. @TODO: Should be moved 94 * to numeric axis. 95 * @property mixed $minorStep 96 * Non labeled minor steps on the axis. @TODO: Should be moved to 97 * numeric axis. 98 * @property string $formatString 99 * Formatstring to use for labeling of the axis. 100 * @property string $label 101 * Axis label 102 * @property int $labelSize 103 * Size of axis label 104 * @property int $labelMargin 105 * Distance between label an axis 106 * @property int $minArrowHeadSize 107 * Minimum Size used to draw arrow heads. 108 * @property int $maxArrowHeadSize 109 * Maximum Size used to draw arrow heads. 110 * @property ezcGraphAxisLabelRenderer $axisLabelRenderer 111 * AxisLabelRenderer used to render labels and grid on this axis. 112 * @property callback $labelCallback 113 * Callback function to format chart labels. 114 * Function will receive two parameters and should return a 115 * reformatted label. 116 * string function( label, step ) 117 * @property float $chartPosition 118 * Position of the axis in the chart. Only useful for additional 119 * axis. The basic chart axis will be automatically positioned. 120 * @property-read bool $initialized 121 * Property indicating if some values were associated with axis, or a 122 * scaling has been set manually. 123 * @property float $labelRotation 124 * Rotation of the axis label in degree 125 * 126 * @version 1.5 127 * @package Graph 128 */ 129 abstract class ezcGraphChartElementAxis extends ezcGraphChartElement 130 { 131 /** 132 * Axis label renderer class 133 * 134 * @var ezcGraphAxisLabelRenderer 135 */ 136 protected $axisLabelRenderer; 137 138 /** 139 * Optionally set inner boundings. May be null depending on the used chart 140 * implementation. 141 * 142 * @var ezcGraphBoundings 143 */ 144 protected $innerBoundings; 145 146 /** 147 * Constructor 148 * 149 * @param array $options Default option array 150 * @return void 151 * @ignore 152 */ 153 public function __construct( array $options = array() ) 154 { 155 $this->properties['nullPosition'] = false; 156 $this->properties['axisSpace'] = .1; 157 $this->properties['outerAxisSpace'] = null; 158 $this->properties['majorGrid'] = false; 159 $this->properties['minorGrid'] = false; 160 $this->properties['majorStep'] = null; 161 $this->properties['minorStep'] = null; 162 $this->properties['formatString'] = '%s'; 163 $this->properties['label'] = false; 164 $this->properties['labelSize'] = 14; 165 $this->properties['labelMargin'] = 2; 166 $this->properties['minArrowHeadSize'] = 4; 167 $this->properties['maxArrowHeadSize'] = 8; 168 $this->properties['labelCallback'] = null; 169 $this->properties['chartPosition'] = null; 170 $this->properties['initialized'] = false; 171 $this->properties['labelRotation'] = 0.; 172 173 parent::__construct( $options ); 174 175 if ( !isset( $this->axisLabelRenderer ) ) 176 { 177 $this->axisLabelRenderer = new ezcGraphAxisExactLabelRenderer(); 178 } 179 } 180 181 /** 182 * Set colors and border fro this element 183 * 184 * @param ezcGraphPalette $palette Palette 185 * @return void 186 */ 187 public function setFromPalette( ezcGraphPalette $palette ) 188 { 189 $this->border = $palette->axisColor; 190 $this->padding = $palette->padding; 191 $this->margin = $palette->margin; 192 $this->majorGrid = $palette->majorGridColor; 193 $this->minorGrid = $palette->minorGridColor; 194 } 195 196 /** 197 * __set 198 * 199 * @param mixed $propertyName 200 * @param mixed $propertyValue 201 * @throws ezcBaseValueException 202 * If a submitted parameter was out of range or type. 203 * @throws ezcBasePropertyNotFoundException 204 * If a the value for the property options is not an instance of 205 * @return void 206 */ 207 public function __set( $propertyName, $propertyValue ) 208 { 209 switch ( $propertyName ) 210 { 211 case 'nullPosition': 212 $this->properties['nullPosition'] = (float) $propertyValue; 213 break; 214 case 'axisSpace': 215 if ( !is_numeric( $propertyValue ) || 216 ( $propertyValue < 0 ) || 217 ( $propertyValue >= 1 ) ) 218 { 219 throw new ezcBaseValueException( $propertyName, $propertyValue, '0 <= float < 1' ); 220 } 221 222 $this->properties['axisSpace'] = (float) $propertyValue; 223 break; 224 case 'outerAxisSpace': 225 if ( !is_null( $propertyValue ) && 226 ( !is_numeric( $propertyValue ) || 227 ( $propertyValue < 0 ) || 228 ( $propertyValue >= 1 ) ) ) 229 { 230 throw new ezcBaseValueException( $propertyName, $propertyValue, 'null, or 0 <= float < 1' ); 231 } 232 233 $this->properties['outerAxisSpace'] = $propertyValue; 234 break; 235 case 'majorGrid': 236 $this->properties['majorGrid'] = ezcGraphColor::create( $propertyValue ); 237 break; 238 case 'minorGrid': 239 $this->properties['minorGrid'] = ezcGraphColor::create( $propertyValue ); 240 break; 241 case 'majorStep': 242 if ( !is_numeric( $propertyValue ) || 243 ( $propertyValue <= 0 ) ) 244 { 245 throw new ezcBaseValueException( $propertyName, $propertyValue, 'float > 0' ); 246 } 247 248 $this->properties['majorStep'] = (float) $propertyValue; 249 break; 250 case 'minorStep': 251 if ( !is_numeric( $propertyValue ) || 252 ( $propertyValue <= 0 ) ) 253 { 254 throw new ezcBaseValueException( $propertyName, $propertyValue, 'float > 0' ); 255 } 256 257 $this->properties['minorStep'] = (float) $propertyValue; 258 break; 259 case 'formatString': 260 $this->properties['formatString'] = (string) $propertyValue; 261 break; 262 case 'label': 263 $this->properties['label'] = (string) $propertyValue; 264 break; 265 case 'labelSize': 266 if ( !is_numeric( $propertyValue ) || 267 ( $propertyValue <= 6 ) ) 268 { 269 throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 6' ); 270 } 271 272 $this->properties['labelSize'] = (int) $propertyValue; 273 break; 274 case 'labelMargin': 275 if ( !is_numeric( $propertyValue ) || 276 ( $propertyValue <= 0 ) ) 277 { 278 throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' ); 279 } 280 281 $this->properties['labelMargin'] = (int) $propertyValue; 282 break; 283 case 'maxArrowHeadSize': 284 if ( !is_numeric( $propertyValue ) || 285 ( $propertyValue <= 0 ) ) 286 { 287 throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' ); 288 } 289 290 $this->properties['maxArrowHeadSize'] = (int) $propertyValue; 291 break; 292 case 'minArrowHeadSize': 293 if ( !is_numeric( $propertyValue ) || 294 ( $propertyValue <= 0 ) ) 295 { 296 throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' ); 297 } 298 299 $this->properties['minArrowHeadSize'] = (int) $propertyValue; 300 break; 301 case 'axisLabelRenderer': 302 if ( $propertyValue instanceof ezcGraphAxisLabelRenderer ) 303 { 304 $this->axisLabelRenderer = $propertyValue; 305 } 306 else 307 { 308 throw new ezcBaseValueException( $propertyName, $propertyValue, 'ezcGraphAxisLabelRenderer' ); 309 } 310 break; 311 case 'labelCallback': 312 if ( is_callable( $propertyValue ) ) 313 { 314 $this->properties['labelCallback'] = $propertyValue; 315 } 316 else 317 { 318 throw new ezcBaseValueException( $propertyName, $propertyValue, 'callback function' ); 319 } 320 break; 321 case 'chartPosition': 322 if ( !is_numeric( $propertyValue ) || 323 ( $propertyValue < 0 ) || 324 ( $propertyValue > 1 ) ) 325 { 326 throw new ezcBaseValueException( $propertyName, $propertyValue, '0 <= float <= 1' ); 327 } 328 329 $this->properties['chartPosition'] = (float) $propertyValue; 330 break; 331 case 'labelRotation': 332 if ( !is_numeric( $propertyValue ) ) 333 { 334 throw new ezcBaseValueException( $propertyName, $propertyValue, 'float' ); 335 } 336 337 $this->properties['labelRotation'] = fmod( (float) $propertyValue, 360. ); 338 break; 339 default: 340 parent::__set( $propertyName, $propertyValue ); 341 break; 342 } 343 } 344 345 /** 346 * __get 347 * 348 * @param mixed $propertyName 349 * @throws ezcBasePropertyNotFoundException 350 * If a the value for the property options is not an instance of 351 * @return mixed 352 * @ignore 353 */ 354 public function __get( $propertyName ) 355 { 356 switch ( $propertyName ) 357 { 358 case 'axisLabelRenderer': 359 return $this->axisLabelRenderer; 360 default: 361 return parent::__get( $propertyName ); 362 } 363 } 364 365 /** 366 * Get coordinate for a dedicated value on the chart 367 * 368 * @param float $value Value to determine position for 369 * @return float Position on chart 370 */ 371 abstract public function getCoordinate( $value ); 372 373 /** 374 * Return count of minor steps 375 * 376 * @return integer Count of minor steps 377 */ 378 abstract public function getMinorStepCount(); 379 380 /** 381 * Return count of major steps 382 * 383 * @return integer Count of major steps 384 */ 385 abstract public function getMajorStepCount(); 386 387 /** 388 * Get label for a dedicated step on the axis 389 * 390 * @param integer $step Number of step 391 * @return string label 392 */ 393 abstract public function getLabel( $step ); 394 395 /** 396 * Return array of steps on this axis 397 * 398 * @return array( ezcGraphAxisStep ) 399 */ 400 public function getSteps() 401 { 402 $majorSteps = $this->getMajorStepCount(); 403 $minorStepsPerMajorStepCount = ( $this->getMinorStepCount() / $majorSteps ); 404 405 $majorStepSize = 1 / $majorSteps; 406 $minorStepSize = ( $minorStepsPerMajorStepCount > 0 ? $majorStepSize / $minorStepsPerMajorStepCount : 0 ); 407 408 $steps = array(); 409 for ( $major = 0; $major <= $majorSteps; ++$major ) 410 { 411 $majorStep = new ezcGraphAxisStep( 412 $majorStepSize * $major, 413 $majorStepSize, 414 $this->getLabel( $major ), 415 array(), 416 $this->isZeroStep( $major ), 417 ( $major === $majorSteps ) 418 ); 419 420 if ( ( $minorStepsPerMajorStepCount > 0 ) && 421 ( $major < $majorSteps ) ) 422 { 423 // Do not add minor steps at major steps positions 424 for( $minor = 1; $minor < $minorStepsPerMajorStepCount; ++$minor ) 425 { 426 $majorStep->childs[] = new ezcGraphAxisStep( 427 ( $majorStepSize * $major ) + ( $minorStepSize * $minor ), 428 $minorStepSize 429 ); 430 } 431 } 432 433 $steps[] = $majorStep; 434 } 435 436 return $steps; 437 } 438 439 /** 440 * Is zero step 441 * 442 * Returns true if the given step is the one on the initial axis position 443 * 444 * @param int $step Number of step 445 * @return bool Status If given step is initial axis position 446 */ 447 abstract public function isZeroStep( $step ); 448 449 /** 450 * Add data for this axis 451 * 452 * @param array $values 453 * @return void 454 */ 455 abstract public function addData( array $values ); 456 457 /** 458 * Calculate axis bounding values on base of the assigned values 459 * 460 * @abstract 461 * @access public 462 * @return void 463 */ 464 abstract public function calculateAxisBoundings(); 465 466 /** 467 * Render the axis 468 * 469 * @param ezcGraphRenderer $renderer Renderer 470 * @param ezcGraphBoundings $boundings Boundings for the axis 471 * @return ezcGraphBoundings Remaining boundings 472 */ 473 public function render( ezcGraphRenderer $renderer, ezcGraphBoundings $boundings, ezcGraphBoundings $innerBoundings = null ) 474 { 475 $this->innerBoundings = $innerBoundings; 476 $startSpace = $this->axisSpace; 477 $endSpace = $this->outerAxisSpace === null ? $this->axisSpace : $this->outerAxisSpace; 478 479 switch ( $this->position ) 480 { 481 case ezcGraph::TOP: 482 $start = new ezcGraphCoordinate( 483 $boundings->width * $startSpace + 484 $this->nullPosition * $boundings->width * ( 1 - ( $startSpace + $endSpace ) ), 485 0 486 ); 487 $end = new ezcGraphCoordinate( 488 $boundings->width * $startSpace + 489 $this->nullPosition * $boundings->width * ( 1 - ( $startSpace + $endSpace ) ), 490 $boundings->height 491 ); 492 break; 493 case ezcGraph::BOTTOM: 494 $start = new ezcGraphCoordinate( 495 $boundings->width * $startSpace + 496 $this->nullPosition * $boundings->width * ( 1 - ( $startSpace + $endSpace ) ), 497 $boundings->height 498 ); 499 $end = new ezcGraphCoordinate( 500 $boundings->width * $startSpace + 501 $this->nullPosition * $boundings->width * ( 1 - ( $startSpace + $endSpace ) ), 502 0 503 ); 504 break; 505 case ezcGraph::LEFT: 506 $start = new ezcGraphCoordinate( 507 0, 508 $boundings->height * $endSpace + 509 $this->nullPosition * $boundings->height * ( 1 - ( $startSpace + $endSpace ) ) 510 ); 511 $end = new ezcGraphCoordinate( 512 $boundings->width, 513 $boundings->height * $endSpace + 514 $this->nullPosition * $boundings->height * ( 1 - ( $startSpace + $endSpace ) ) 515 ); 516 break; 517 case ezcGraph::RIGHT: 518 $start = new ezcGraphCoordinate( 519 $boundings->width, 520 $boundings->height * $endSpace + 521 $this->nullPosition * $boundings->height * ( 1 - ( $startSpace + $endSpace ) ) 522 ); 523 $end = new ezcGraphCoordinate( 524 0, 525 $boundings->height * $endSpace + 526 $this->nullPosition * $boundings->height * ( 1 - ( $startSpace + $endSpace ) ) 527 ); 528 break; 529 } 530 531 $renderer->drawAxis( 532 $boundings, 533 $start, 534 $end, 535 $this, 536 $this->axisLabelRenderer, 537 $innerBoundings 538 ); 539 540 return $boundings; 541 } 542 } 543 544 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Jul 28 15:48:31 2011 | Cross-referenced by PHPXref 0.7 |