| [ Index ] |
|
Code source de phpMyVisites 2.3 |
1 <?php 2 /* 3 * This work is hereby released into the Public Domain. 4 * To view a copy of the public domain dedication, 5 * visit http://creativecommons.org/licenses/publicdomain/ or send a letter to 6 * Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. 7 * 8 */ 9 10 /** 11 * Handle axis 12 * 13 * @package Artichow 14 */ 15 class awAxis { 16 17 /** 18 * Axis line 19 * 20 * @var Line 21 */ 22 public $line; 23 24 /** 25 * Axis labels 26 * 27 * @var Label 28 */ 29 public $label; 30 31 /** 32 * Axis title 33 * 34 * @var Label 35 */ 36 public $title; 37 38 /** 39 * Title position 40 * 41 * @var float 42 */ 43 protected $titlePosition = 0.5; 44 45 /** 46 * Labels number 47 * 48 * @var int 49 */ 50 protected $labelNumber; 51 52 /** 53 * Axis ticks 54 * 55 * @var array 56 */ 57 protected $ticks = array(); 58 59 /** 60 * Axis and ticks color 61 * 62 * @var Color 63 */ 64 protected $color; 65 66 /** 67 * Axis left and right padding 68 * 69 * @var Side 70 */ 71 protected $padding; 72 73 /** 74 * Axis range 75 * 76 * @var array 77 */ 78 protected $range; 79 80 /** 81 * Hide axis 82 * 83 * @var bool 84 */ 85 protected $hide = FALSE; 86 87 /** 88 * Auto-scaling mode 89 * 90 * @var bool 91 */ 92 protected $auto = TRUE; 93 94 /** 95 * Axis range callback function 96 * 97 * @var array 98 */ 99 protected $rangeCallback = array( 100 'toValue' => 'toProportionalValue', 101 'toPosition' => 'toProportionalPosition' 102 ); 103 104 /** 105 * Build the axis 106 * 107 * @param float $min Begin of the range of the axis 108 * @param float $max End of the range of the axis 109 */ 110 public function __construct($min = NULL, $max = NULL) { 111 112 $this->line = new awVector( 113 new awPoint(0, 0), 114 new awPoint(0, 0) 115 ); 116 117 $this->label = new awLabel; 118 $this->padding = new awSide; 119 120 $this->title = new awLabel( 121 NULL, 122 NULL, 123 NULL, 124 0 125 ); 126 127 $this->setColor(new awBlack); 128 129 if($min !== NULL and $max !== NULL) { 130 $this->setRange($min, $max); 131 } 132 133 } 134 135 /** 136 * Enable/disable auto-scaling mode 137 * 138 * @param bool $auto 139 */ 140 public function auto($auto) { 141 $this->auto = (bool)$auto; 142 } 143 144 /** 145 * Get auto-scaling mode status 146 * 147 * @return bool 148 */ 149 public function isAuto() { 150 return $this->auto; 151 } 152 153 /** 154 * Hide axis 155 * 156 * @param bool $hide 157 */ 158 public function hide($hide = TRUE) { 159 $this->hide = (bool)$hide; 160 } 161 162 /** 163 * Show axis 164 * 165 * @param bool $show 166 */ 167 public function show($show = TRUE) { 168 $this->hide = !(bool)$show; 169 } 170 171 /** 172 * Return a tick object from its name 173 * 174 * @param string $name Tick object name 175 * @return Tick 176 */ 177 public function tick($name) { 178 /* <php5> */ 179 return array_key_exists($name, $this->ticks) ? $this->ticks[$name] : NULL; 180 /* </php5> */ 181 /* <php4> -- 182 if(array_key_exists($name, $this->ticks)) { 183 return $tick = &$this->ticks[$name]; 184 } else { 185 return NULL; 186 } 187 -- </php4> */ 188 } 189 190 /** 191 * Add a tick object 192 * 193 * @param string $name Tick object name 194 * @param awTick $tick Tick object 195 */ 196 public function addTick($name, awTick $tick) { 197 /* <php5> */ 198 $this->ticks[$name] = $tick; 199 /* </php5> */ 200 /* <php4> -- 201 $this->ticks[$name] = &$tick; 202 -- </php4> */ 203 } 204 205 /** 206 * Delete a tick object 207 * 208 * @param string $name Tick object name 209 */ 210 public function deleteTick($name) { 211 if(array_key_exists($name, $this->ticks)) { 212 unset($this->ticks[$name]); 213 } 214 } 215 216 /** 217 * Hide all ticks 218 * 219 * @param bool $hide Hide or not ? 220 */ 221 public function hideTicks($hide = TRUE) { 222 /* <php5> */ 223 foreach($this->ticks as $tick) { 224 $tick->hide($hide); 225 } 226 /* </php5> */ 227 /* <php4> -- 228 foreach($this->ticks as $key => $tick) { 229 $this->ticks[$key]->hide($hide); 230 } 231 -- </php4> */ 232 } 233 234 /** 235 * Change ticks style 236 * 237 * @param int $style Ticks style 238 */ 239 public function setTickStyle($style) { 240 /* <php5> */ 241 foreach($this->ticks as $tick) { 242 $tick->setStyle($style); 243 } 244 /* </php5> */ 245 /* <php4> -- 246 foreach($this->ticks as $key => $tick) { 247 $this->ticks[$key]->setStyle($style); 248 } 249 -- </php4> */ 250 } 251 252 /** 253 * Change ticks interval 254 * 255 * @param int $interval Ticks interval 256 */ 257 public function setTickInterval($interval) { 258 /* <php5> */ 259 foreach($this->ticks as $tick) { 260 $tick->setInterval($interval); 261 } 262 /* </php5> */ 263 /* <php4> -- 264 foreach($this->ticks as $key => $tick) { 265 $this->ticks[$key]->setInterval($interval); 266 } 267 -- </php4> */ 268 } 269 270 /** 271 * Change number of ticks relative to others ticks 272 * 273 * @param awTick $to Change number of theses ticks 274 * @param awTick $from Ticks reference 275 * @param float $number Number of ticks by the reference 276 */ 277 public function setNumberByTick($to, $from, $number) { 278 $this->ticks[$to]->setNumberByTick($this->ticks[$from], $number); 279 } 280 281 /** 282 * Reverse ticks style 283 */ 284 public function reverseTickStyle() { 285 /* <php5> */ 286 foreach($this->ticks as $tick) { 287 if($tick->getStyle() === awTick::IN) { 288 $tick->setStyle(awTick::OUT); 289 } else if($tick->getStyle() === awTick::OUT) { 290 $tick->setStyle(awTick::IN); 291 } 292 } 293 /* </php5> */ 294 /* <php4> -- 295 foreach($this->ticks as $key => $tick) { 296 if($this->ticks[$key]->getStyle() === awTick::IN) { 297 $this->ticks[$key]->setStyle(awTick::OUT); 298 } else if($this->ticks[$key]->getStyle() === awTick::OUT) { 299 $this->ticks[$key]->setStyle(awTick::IN); 300 } 301 } 302 -- </php4> */ 303 } 304 305 /** 306 * Change interval of labels 307 * 308 * @param int $interval Interval 309 */ 310 public function setLabelInterval($interval) { 311 $this->auto(FALSE); 312 $this->setTickInterval($interval); 313 $this->label->setInterval($interval); 314 } 315 316 /** 317 * Change number of labels 318 * 319 * @param int $number Number of labels to display (can be NULL) 320 */ 321 public function setLabelNumber($number) { 322 $this->auto(FALSE); 323 $this->labelNumber = is_null($number) ? NULL : (int)$number; 324 } 325 326 /** 327 * Get number of labels 328 * 329 * @return int 330 */ 331 public function getLabelNumber() { 332 return $this->labelNumber; 333 } 334 335 /** 336 * Change precision of labels 337 * 338 * @param int $precision Precision 339 */ 340 public function setLabelPrecision($precision) { 341 $this->auto(FALSE); 342 $function = 'axis'.time().'_'.(microtime() * 1000000); 343 eval('function '.$function.'($value) { 344 return sprintf("%.'.(int)$precision.'f", $value); 345 }'); 346 $this->label->setCallbackFunction($function); 347 } 348 349 /** 350 * Change text of labels 351 * 352 * @param array $texts Some texts 353 */ 354 public function setLabelText($texts) { 355 if(is_array($texts)) { 356 $this->auto(FALSE); 357 $function = 'axis'.time().'_'.(microtime() * 1000000); 358 eval('function '.$function.'($value) { 359 $texts = '.var_export($texts, TRUE).'; 360 return $texts[$value]; 361 }'); 362 $this->label->setCallbackFunction($function); 363 } 364 } 365 366 /** 367 * Get the position of a point 368 * 369 * @param awAxis $xAxis X axis 370 * @param awAxis $yAxis Y axis 371 * @param awPoint $p Position of the point 372 * @return Point Position on the axis 373 */ 374 public static function toPosition(awAxis $xAxis, awAxis $yAxis, awPoint $p) { 375 376 $p1 = $xAxis->getPointFromValue($p->x); 377 $p2 = $yAxis->getPointFromValue($p->y); 378 379 return new awPoint( 380 round($p1->x), 381 round($p2->y) 382 ); 383 384 } 385 386 /** 387 * Change title alignment 388 * 389 * @param int $alignment New Alignment 390 */ 391 public function setTitleAlignment($alignment) { 392 393 switch($alignment) { 394 395 case awLabel::TOP : 396 $this->setTitlePosition(1); 397 $this->title->setAlign(NULL, awLabel::BOTTOM); 398 break; 399 400 case awLabel::BOTTOM : 401 $this->setTitlePosition(0); 402 $this->title->setAlign(NULL, awLabel::TOP); 403 break; 404 405 case awLabel::LEFT : 406 $this->setTitlePosition(0); 407 $this->title->setAlign(awLabel::LEFT); 408 break; 409 410 case awLabel::RIGHT : 411 $this->setTitlePosition(1); 412 $this->title->setAlign(awLabel::RIGHT); 413 break; 414 415 } 416 417 } 418 419 /** 420 * Change title position on the axis 421 * 422 * @param float $position A new awposition between 0 and 1 423 */ 424 public function setTitlePosition($position) { 425 $this->titlePosition = (float)$position; 426 } 427 428 /** 429 * Change axis and axis title color 430 * 431 * @param awColor $color 432 */ 433 public function setColor(awColor $color) { 434 $this->color = $color; 435 $this->title->setColor($color); 436 } 437 438 /** 439 * Change axis padding 440 * 441 * @param int $left Left padding in pixels 442 * @param int $right Right padding in pixels 443 */ 444 public function setPadding($left, $right) { 445 $this->padding->set($left, $right); 446 } 447 448 /** 449 * Get axis padding 450 * 451 * @return Side 452 */ 453 public function getPadding() { 454 return $this->padding; 455 } 456 457 /** 458 * Change axis range 459 * 460 * @param float $min 461 * @param float $max 462 */ 463 public function setRange($min, $max) { 464 if($min !== NULL) { 465 $this->range[0] = (float)$min; 466 } 467 if($max !== NULL) { 468 $this->range[1] = (float)$max; 469 } 470 } 471 472 /** 473 * Get axis range 474 * 475 * @return array 476 */ 477 public function getRange() { 478 return $this->range; 479 } 480 481 /** 482 * Change axis range callback function 483 * 484 * @param string $toValue Transform a position between 0 and 1 to a value 485 * @param string $toPosition Transform a value to a position between 0 and 1 on the axis 486 */ 487 public function setRangeCallback($toValue, $toPosition) { 488 $this->rangeCallback = array( 489 'toValue' => (string)$toValue, 490 'toPosition' => (string)$toPosition 491 ); 492 } 493 494 /** 495 * Center X values of the axis 496 * 497 * @param awAxis $axis An axis 498 * @param float $value The reference value on the axis 499 */ 500 public function setXCenter(awAxis $axis, $value) { 501 502 // Check vector angle 503 if($this->line->isVertical() === FALSE) { 504 trigger_error("setXCenter() can only be used on vertical axes", E_USER_ERROR); 505 } 506 507 $p = $axis->getPointFromValue($value); 508 509 $this->line->setX( 510 $p->x, 511 $p->x 512 ); 513 514 } 515 516 /** 517 * Center Y values of the axis 518 * 519 * @param awAxis $axis An axis 520 * @param float $value The reference value on the axis 521 */ 522 public function setYCenter(awAxis $axis, $value) { 523 524 // Check vector angle 525 if($this->line->isHorizontal() === FALSE) { 526 trigger_error("setYCenter() can only be used on horizontal axes", E_USER_ERROR); 527 } 528 529 $p = $axis->getPointFromValue($value); 530 531 $this->line->setY( 532 $p->y, 533 $p->y 534 ); 535 536 } 537 538 /** 539 * Get the distance between to values on the axis 540 * 541 * @param float $from The first value 542 * @param float $to The last value 543 * @return Point 544 */ 545 public function getDistance($from, $to) { 546 547 $p1 = $this->getPointFromValue($from); 548 $p2 = $this->getPointFromValue($to); 549 550 return $p1->getDistance($p2); 551 552 } 553 554 /** 555 * Get a point on the axis from a value 556 * 557 * @param float $value 558 * @return Point 559 */ 560 protected function getPointFromValue($value) { 561 562 $callback = $this->rangeCallback['toPosition']; 563 564 list($min, $max) = $this->range; 565 $position = $callback($value, $min, $max); 566 567 return $this->getPointFromPosition($position); 568 569 } 570 571 /** 572 * Get a point on the axis from a position 573 * 574 * @param float $position A position between 0 and 1 575 * @return Point 576 */ 577 protected function getPointFromPosition($position) { 578 579 $vector = $this->getVector(); 580 581 $angle = $vector->getAngle(); 582 $size = $vector->getSize(); 583 584 return $vector->p1->move( 585 cos($angle) * $size * $position, 586 -1 * sin($angle) * $size * $position 587 ); 588 589 } 590 591 /** 592 * Draw axis 593 * 594 * @param awDrawer $drawer A drawer 595 */ 596 public function draw(awDrawer $drawer) { 597 598 if($this->hide) { 599 return; 600 } 601 602 $vector = $this->getVector(); 603 604 // Draw axis ticks 605 $this->drawTicks($drawer, $vector); 606 607 // Draw axis line 608 $this->line($drawer); 609 610 // Draw labels 611 $this->drawLabels($drawer); 612 613 // Draw axis title 614 $p = $this->getPointFromPosition($this->titlePosition); 615 $this->title->draw($drawer, $p); 616 617 } 618 619 public function autoScale() { 620 621 if($this->isAuto() === FALSE) { 622 return; 623 } 624 625 list($min, $max) = $this->getRange(); 626 $interval = $max - $min; 627 628 $partMax = $max / $interval; 629 $partMin = $min / $interval; 630 631 $difference = log($interval) / log(10); 632 $difference = floor($difference); 633 634 $pow = pow(10, $difference); 635 636 $intervalNormalize = $interval / $pow; 637 638 if($difference <= 0) { 639 640 $precision = $difference * -1 + 1; 641 642 if($intervalNormalize > 2) { 643 $precision--; 644 } 645 646 } else { 647 $precision = 0; 648 } 649 650 if($min != 0 and $max != 0) { 651 $precision++; 652 } 653 654 $this->setLabelPrecision($precision); 655 656 if($intervalNormalize <= 1.5) { 657 $intervalReal = 1.5; 658 $labelNumber = 4; 659 } else if($intervalNormalize <= 2) { 660 $intervalReal = 2; 661 $labelNumber = 5; 662 } else if($intervalNormalize <= 3) { 663 $intervalReal = 3; 664 $labelNumber = 4; 665 } else if($intervalNormalize <= 4) { 666 $intervalReal = 4; 667 $labelNumber = 5; 668 } else if($intervalNormalize <= 5) { 669 $intervalReal = 5; 670 $labelNumber = 6; 671 } else if($intervalNormalize <= 8) { 672 $intervalReal = 8; 673 $labelNumber = 5; 674 } else if($intervalNormalize <= 10) { 675 $intervalReal = 10; 676 $labelNumber = 6; 677 } 678 679 if($min == 0) { 680 681 $this->setRange( 682 $min, 683 $intervalReal * $pow 684 ); 685 686 } else if($max == 0) { 687 688 $this->setRange( 689 $intervalReal * $pow * -1, 690 0 691 ); 692 693 } 694 695 $this->setLabelNumber($labelNumber); 696 697 } 698 699 protected function line(awDrawer $drawer) { 700 701 $drawer->line( 702 $this->color, 703 $this->line 704 ); 705 706 } 707 708 protected function drawTicks(awDrawer $drawer, awVector $vector) { 709 710 foreach($this->ticks as $tick) { 711 $tick->setColor($this->color); 712 $tick->draw($drawer, $vector); 713 } 714 715 } 716 717 protected function drawLabels($drawer) { 718 719 if($this->labelNumber !== NULL) { 720 list($min, $max) = $this->range; 721 $number = $this->labelNumber - 1; 722 if($number < 1) { 723 return; 724 } 725 $function = $this->rangeCallback['toValue']; 726 $labels = array(); 727 for($i = 0; $i <= $number; $i++) { 728 $labels[] = $function($i / $number, $min, $max); 729 } 730 $this->label->set($labels); 731 } 732 733 $labels = $this->label->count(); 734 735 for($i = 0; $i < $labels; $i++) { 736 737 $p = $this->getPointFromValue($this->label->get($i)); 738 $this->label->draw($drawer, $p, $i); 739 740 } 741 742 } 743 744 protected function getVector() { 745 746 $angle = $this->line->getAngle(); 747 748 // Compute paddings 749 $vector = new awVector( 750 $this->line->p1->move( 751 cos($angle) * $this->padding->left, 752 -1 * sin($angle) * $this->padding->left 753 ), 754 $this->line->p2->move( 755 -1 * cos($angle) * $this->padding->right, 756 -1 * -1 * sin($angle) * $this->padding->right 757 ) 758 ); 759 760 return $vector; 761 762 } 763 764 public function __clone() { 765 766 $this->label = clone $this->label; 767 $this->line = clone $this->line; 768 $this->title = clone $this->title; 769 770 foreach($this->ticks as $name => $tick) { 771 $this->ticks[$name] = clone $tick; 772 } 773 774 } 775 776 } 777 778 registerClass('Axis'); 779 780 function toProportionalValue($position, $min, $max) { 781 return $min + ($max - $min) * $position; 782 } 783 784 function toProportionalPosition($value, $min, $max) { 785 if($max - $min == 0) { 786 return 0; 787 } 788 return ($value - $min) / ($max - $min); 789 } 790 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Mon Nov 26 14:10:01 2007 | par Balluche grâce à PHPXref 0.7 |
|