[ Index ] |
|
Code source de vtiger CRM 5.0.2 |
1 <?php 2 3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 4 5 /** 6 * Image_Graph - PEAR PHP OO Graph Rendering Utility. 7 * 8 * PHP versions 4 and 5 9 * 10 * LICENSE: This library is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License as published by 12 * the Free Software Foundation; either version 2.1 of the License, or (at your 13 * option) any later version. This library is distributed in the hope that it 14 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 16 * General Public License for more details. You should have received a copy of 17 * the GNU Lesser General Public License along with this library; if not, write 18 * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19 * 02111-1307 USA 20 * 21 * @category Images 22 * @package Image_Graph 23 * @subpackage Plot 24 * @author Jesper Veggerby <pear.nosey@veggerby.dk> 25 * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen 26 * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 27 * @version CVS: $Id: Odo.php,v 1.3 2005/11/27 22:21:16 nosey Exp $ 28 * @link http://pear.php.net/package/Image_Graph 29 */ 30 31 /** 32 * Include file Image/Graph/Plot.php 33 */ 34 require_once 'Image/Graph/Plot.php'; 35 36 /** 37 * Include file Image/Graph/Tool.php 38 */ 39 require_once 'Image/Graph/Tool.php'; 40 41 /** 42 * 2D Odochart. 43 * 44 * @category Images 45 * @package Image_Graph 46 * @subpackage Plot 47 * @author Maxime Delorme <mdelorme@tennaxia.com> 48 * @copyright Copyright (C) 2005 Maxime Delorme 49 * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 50 * @version Release: 0.7.2 51 * @link http://pear.php.net/package/Image_Graph 52 */ 53 class Image_Graph_Plot_Odo extends Image_Graph_Plot 54 { 55 /** 56 * the percent of the radius of the chart that will be use as the width of the range 57 * @access private 58 * @var int 59 */ 60 var $_radiusPercent = 50; 61 62 /** 63 * the minimun value of the chart or the start value 64 * @access private 65 * @var int 66 */ 67 var $_value_min = 0; 68 69 /** 70 * the maximum value of the chart or the end value 71 * @access private 72 * @var int 73 */ 74 var $_value_max = 100; 75 76 /** 77 * the start angle 78 * @access private 79 * @var int 80 */ 81 var $_deg_offset = 135; 82 83 /** 84 * the angle of the chart , the length of the chart 85 * 180 min a half circle 86 * @access private 87 * @var int 88 */ 89 var $_deg_width = 270; 90 91 /** 92 * the length of the big ticks 93 * the small ones will be half ot it, the values 160% of it 94 * 180 min a half circle 95 * @access private 96 * @var int 97 */ 98 var $_tickLength = 14; 99 100 /** 101 * how many small ticks a big tick appears 102 * the small ticks appear every 6° 103 * so with the default value of 5, every 30° there is a value and a big tick 104 * 180 min a half circle 105 * @access private 106 * @var int 107 */ 108 var $_axisTicks = 5; 109 110 /** 111 * Arrow marker 112 * @access private 113 * @var Image_Graph_Marker 114 */ 115 var $_arrowMarker; 116 117 /** 118 * Range marker fill style 119 * @access private 120 * @var Image_Graph_Fill 121 */ 122 var $_rangeFillStyle = null; 123 124 /** 125 * The width of the arrow 126 * @access private 127 * @var int 128 */ 129 var $_arrowWidth = 5; 130 131 /** 132 * The length of the arrow 133 * @access private 134 * @var int 135 */ 136 var $_arrowLength = 80; 137 138 /** 139 * The radius of the plot 140 * @access private 141 * @var int 142 */ 143 var $_radius = false; 144 145 /** 146 * The total Y 147 * @access private 148 * @var int 149 */ 150 var $_totalY = false; 151 152 /** 153 * Center X of odometer "circle" 154 * @access private 155 * @var int 156 */ 157 var $_centerX = false; 158 159 /** 160 * Center y of odometer "circle" 161 * @access private 162 * @var int 163 */ 164 var $_centerY = false; 165 166 /** 167 * Plot_Odo [Constructor] 168 * 169 * dataset with one data per arrow 170 * @param Image_Graph_Dataset $dataset The data set (value containter) to 171 * plot or an array of datasets 172 * {@link Image_Graph_Legend} 173 */ 174 function Image_Graph_Plot_Odo(&$dataset) 175 { 176 parent::Image_Graph_Plot($dataset); 177 178 $keys = array_keys($this->_dataset); 179 foreach ($keys as $key) { 180 $dataset =& $this->_dataset[$key]; 181 if (isset($min)) { 182 $min = min($dataset->minimumY(), $min); 183 } 184 else { 185 $min = $dataset->minimumY(); 186 } 187 if (isset($max)) { 188 $max = max($dataset->maximumY(), $max); 189 } 190 else { 191 $max = $dataset->maximumY(); 192 } 193 } 194 $this->_value_min = $min; 195 $this->_value_max = $max; 196 } 197 198 /** 199 * Set the center of the odometer 200 * 201 * @param int $centerX The center x point 202 * @param int $centerY The center y point 203 */ 204 function setCenter($centerX, $centerY) 205 { 206 $this->_centerX = $centerX; 207 $this->_centerY = $centerY; 208 } 209 210 /** 211 * Convert a value to the angle position onto the odometer 212 * 213 * @access private 214 * @param int $value the value to convert 215 * @return int the angle'position onto the odometer 216 */ 217 function _value2angle($value) 218 { 219 return $this->_deg_width * (($value - $this->_value_min) / $this->_totalY) + $this->_deg_offset; 220 } 221 222 /** 223 * set some internal var 224 * 225 * @access private 226 */ 227 function _initialize() 228 { 229 $v1 = $this->_deg_offset; 230 $v2 = $this->_deg_offset + $this->_deg_width; 231 232 $dimensions = Image_Graph_Tool::calculateArcDimensionAndCenter($v1, $v2); 233 234 $radiusX = ($this->width() / 2) / $dimensions['rx']; 235 $radiusY = ($this->height() / 2) / $dimensions['ry']; 236 237 $this->_radius = min($radiusX, $radiusY); 238 239 if ($this->_marker) { 240 $this->_radius = $this->_radius * 0.85; 241 } 242 243 //the center of the plot 244 if ($this->_centerX === false) { 245 $this->_centerX = (int) (($this->_left + $this->_right) / 2) + 246 $this->_radius * ($dimensions['cx'] - 0.5); 247 } 248 249 if ($this->_centerY === false) { 250 $this->_centerY = (int) (($this->_top + $this->_bottom) / 2) + 251 $this->_radius * ($dimensions['cy'] - 0.5); 252 } 253 254 //the max range 255 $this->_totalY = abs($this->_value_max - $this->_value_min); 256 } 257 258 /** 259 * set min and max value of the range 260 * 261 * @access public 262 * @param integer $value_min the minimun value of the chart or the start value 263 * @param integer $value_max the maximum value of the chart or the end value 264 */ 265 function setRange($value_min, $value_max) 266 { 267 $this->_value_min = $value_min; 268 $this->_value_max = $value_max; 269 } 270 271 /** 272 * Set start's angle and amplitude of the chart 273 * 274 * @access public 275 * @param integer $deg_offset the start angle 276 * @param integer $deg_width the angle of the chart (the length) 277 */ 278 function setAngles($deg_offset, $deg_width) 279 { 280 $this->_deg_offset = min(360, abs($deg_offset)); 281 $this->_deg_width = min(360, abs($deg_width)); 282 } 283 284 /** 285 * set the width of the chart 286 * 287 * @access public 288 * @param string $radius_percent a value between 0 and 100 289 */ 290 function setRadiusWidth($radius_percent) 291 { 292 $this->_radiusPercent = $radius_percent; 293 } 294 295 /** 296 * set the width and length of the arrow (in percent of the total plot "radius") 297 * 298 * @param int length The length in percent 299 * @param int width The width in percent 300 */ 301 function setArrowSize($length, $width) 302 { 303 $this->_arrowWidth = max(0, min(100, $width)); 304 $this->_arrowLength = max(0, min(100, $length)); 305 } 306 307 /** 308 * Set the arrow marker 309 * @param Image_Graph_Marker $marker The marker to set for arrow marker 310 */ 311 function setArrowMarker(&$marker) 312 { 313 $this->_arrowMarker =& $marker; 314 } 315 316 317 /** 318 * Output the plot 319 * 320 * @return bool Was the output 'good' (true) or 'bad' (false). 321 * @access private 322 */ 323 function _done() 324 { 325 if (parent::_done() === false) { 326 return false; 327 } 328 $this->_initialize(); 329 $this->_drawRange(); 330 $this->_drawAxis(); 331 $this->_drawArrow(); 332 $this->_drawMarker(); 333 return true; 334 } 335 336 /** 337 * set the length of the ticks 338 * 339 * @access public 340 * @param string $radius_percent a value between 0 and 100 341 */ 342 function setTickLength($radius) 343 { 344 $this->_tickLength = $radius; 345 } 346 347 /** 348 * set the length of the ticks 349 * 350 * @access public 351 * @param string $radius_percent a value between 0 and 100 352 */ 353 function setAxisTicks($int) 354 { 355 $this->_axisTicks = $int; 356 } 357 358 /** 359 * Draw the outline and the axis 360 * 361 * @access private 362 */ 363 function _drawAxis() 364 { 365 //draw outline 366 $this->_getLineStyle(); 367 $this->_canvas->pieslice( 368 array( 369 'x' => $this->_centerX, 370 'y' => $this->_centerY, 371 'rx' => $this->_radius, 372 'ry' => $this->_radius, 373 'v1' => $this->_deg_offset, 374 'v2' => $this->_deg_offset+$this->_deg_width, 375 'srx' => $this->_radius * (1 - $this->_radiusPercent / 100), 376 'sry' => $this->_radius * (1 - $this->_radiusPercent / 100) 377 ) 378 ); 379 380 //step for every 6° 381 $step = (int) ($this->_totalY / $this->_deg_width * 6); 382 $value = $this->_value_min; 383 $i = 0; 384 while ($value <= $this->_value_max) { 385 $angle = $this->_value2angle($value); 386 387 $cos = cos(deg2rad($angle)); 388 $sin = sin(deg2rad($angle)); 389 $point = array('Y' => $value); 390 $point['AX'] = $cos; 391 $point['AY'] = $sin; 392 $point['LENGTH'] = 1; 393 $x = $this->_centerX + $this->_radius * $cos; 394 $y = $this->_centerY + $this->_radius * $sin; 395 $deltaX = - $cos * $this->_tickLength ; 396 $deltaY = - $sin * $this->_tickLength ; 397 $this->_getLineStyle(); 398 if(($i % $this->_axisTicks) == 0){ 399 $this->_canvas->line(array('x0' => $x, 'y0' => $y, 'x1' => $x + $deltaX, 'y1' => $y + $deltaY)); 400 if ($this->_arrowMarker) { 401 $this->_arrowMarker->_drawMarker($x + $deltaX * 1.6, $y + $deltaY *1.6, $point); 402 } 403 } else { 404 $this->_canvas->line(array('x0' => $x, 'y0' => $y, 'x1' => $x + $deltaX * 0.5, 'y1' => $y + $deltaY * 0.5)); 405 } 406 $i++; 407 $value += $step; 408 } 409 410 } 411 412 /** 413 * Set the line style of the arrows 414 * 415 * @param Image_Graph_Line $lineStyle The line style of the Arrow 416 * @see Image_Graph_Line 417 * @access public 418 */ 419 function setArrowLineStyle($lineStyle) 420 { 421 $this->_arrowLineStyle = &$lineStyle; 422 } 423 424 /** 425 * Set the fillstyle of the arrows 426 * 427 * @param Image_Graph_Fill $fillStyle The fill style of the arrows 428 * @see Image_Graph_Fill 429 * @access public 430 */ 431 function setArrowFillStyle($fillStyle) 432 { 433 $this->_arrowFillStyle = &$fillStyle; 434 } 435 436 /** 437 * Draw the arrows 438 * 439 * @access private 440 */ 441 function _drawArrow() 442 { 443 $keys = array_keys($this->_dataset); 444 foreach ($keys as $key) { 445 $dataset =& $this->_dataset[$key]; 446 $dataset->_reset(); 447 $this->setLineStyle($this->_arrowLineStyle); 448 $this->setFillStyle($this->_arrowFillStyle); 449 while ($point = $dataset->_next()) { 450 $ID = $point['ID']; 451 $this->_getFillStyle($ID); 452 $this->_getLineStyle($ID); 453 $deg = $this->_value2angle($point['Y']); 454 list($xr,$yr) = Image_Graph_Tool::rotate($this->_centerX + $this->_arrowLength * $this->_radius / 100, $this->_centerY, $this->_centerX, $this->_centerY, $deg); 455 $this->_canvas->addVertex(array('x' => $xr, 'y' => $yr)); 456 list($xr,$yr) = Image_Graph_Tool::rotate($this->_centerX, $this->_centerY - $this->_arrowWidth * $this->_radius/100, $this->_centerX, $this->_centerY, $deg); 457 $this->_canvas->addVertex(array('x' => $xr, 'y' => $yr)); 458 list($xr,$yr) = Image_Graph_Tool::rotate($this->_centerX - $this->_arrowWidth * $this->_radius / 100, $this->_centerY, $this->_centerX, $this->_centerY, $deg); 459 $this->_canvas->addVertex(array('x' => $xr, 'y' => $yr)); 460 list($xr,$yr) = Image_Graph_Tool::rotate($this->_centerX,$this->_centerY + $this->_arrowWidth * $this->_radius / 100, $this->_centerX, $this->_centerY, $deg); 461 $this->_canvas->addVertex(array('x' => $xr, 'y' => $yr)); 462 $this->_canvas->polygon(array('connect' => true)); 463 } 464 } 465 } 466 467 /** 468 * Calculate marker point data 469 * 470 * @param array $point The point to calculate data for 471 * @param array $nextPoint The next point 472 * @param array $prevPoint The previous point 473 * @param array $totals The pre-calculated totals, if needed 474 * @return array An array containing marker point data 475 * @access private 476 */ 477 function _getMarkerData($point, $nextPoint, $prevPoint, &$totals) 478 { 479 $point = parent::_getMarkerData($point, $nextPoint, $prevPoint, $totals); 480 481 $point['ANGLE'] = $this->_value2angle($point['Y']); 482 483 $point['ANG_X'] = cos(deg2rad($point['ANGLE'])); 484 $point['ANG_Y'] = sin(deg2rad($point['ANGLE'])); 485 486 $point['AX'] = -$point['ANG_X']; 487 $point['AY'] = -$point['ANG_Y']; 488 489 $point['LENGTH'] = 2.5; //$radius; 490 491 $point['MARKER_X'] = $totals['CENTER_X'] + 492 $totals['ODO_RADIUS'] * $point['ANG_X']; 493 $point['MARKER_Y'] = $totals['CENTER_Y'] + 494 $totals['ODO_RADIUS'] * $point['ANG_Y']; 495 496 return $point; 497 } 498 499 /** 500 * Draws markers of the arrows on the canvas 501 * 502 * @access private 503 */ 504 function _drawMarker() 505 { 506 507 if ($this->_marker) { 508 $this->_marker->_radius += $this->_radius / 2; 509 $totals = $this->_getTotals(); 510 511 $totals['CENTER_X'] = $this->_centerX; 512 $totals['CENTER_Y'] = $this->_centerY; 513 514 515 /* $keys = array_keys($this->_dataset); 516 foreach ($keys as $key) { */ 517 $dataset =& $this->_dataset[0]; 518 519 $totals['RADIUS0'] = false; 520 $totals['ODO_RADIUS'] = 1.1 * $this->_radius * $this->_arrowLength / 100; 521 $totals['ALL_SUM_Y'] = $this->_totalY; 522 523 $dataset->_reset(); 524 while ($point = $dataset->_next()) { 525 if ((!is_object($this->_dataSelector)) || 526 ($this->_dataSelector->select($point)) 527 ) { 528 $point = $this->_getMarkerData( 529 $point, 530 false, 531 false, 532 $totals 533 ); 534 if (is_array($point)) { 535 $this->_marker->_drawMarker( 536 $point['MARKER_X'], 537 $point['MARKER_Y'], 538 $point 539 ); 540 } 541 } 542 } 543 /* } 544 unset($keys); */ 545 } 546 } 547 548 /** 549 * Set range 550 * 551 * dataset with two data start and end value of the range 552 * @param Image_Graph_Dataset $dataset The data set (value containter) to 553 * plot or an array of datasets 554 * 555 */ 556 function addRangeMarker($min, $max, $id = false) 557 { 558 $this->_range[] = 559 array( 560 'min' => max($this->_value_min, min($min, $max)), 561 'max' => min($this->_value_max, max($min, $max)), 562 'id' => $id 563 ); 564 } 565 566 /** 567 * Set the fillstyle of the ranges 568 * 569 * @param Image_Graph_Fill $fillStyle The fill style of the range 570 * @see Image_Graph_Fill 571 * @access public 572 */ 573 function &setRangeMarkerFillStyle(&$rangeMarkerFillStyle) 574 { 575 $this->_rangeFillStyle = $rangeMarkerFillStyle; 576 } 577 578 /** 579 * Draw the ranges 580 * 581 * @access private 582 */ 583 function _drawRange() 584 { 585 if($this->_range){ 586 $radius0 = $this->_radius * (1 - $this->_radiusPercent/100); 587 foreach ($this->_range as $range) { 588 $angle1 = $this->_value2angle($range['min']); 589 $angle2 = $this->_value2angle($range['max']); 590 591 if (is_object($this->_rangeFillStyle)) { 592 $this->_canvas->setFill($this->_rangeFillStyle->_getFillStyle($range['id'])); 593 } elseif ($this->_rangeFillStyle != null) { 594 $this->_canvas->setFill($this->_rangeFillStyle); 595 } 596 $this->_getLineStyle(); 597 $this->_canvas->Pieslice( 598 array( 599 'x' => $this->_centerX, 600 'y' => $this->_centerY, 601 'rx' => $this->_radius, 602 'ry' => $this->_radius, 603 'v1' => $angle1, 604 'v2' => $angle2, 605 'srx' => $radius0, 606 'sry' => $radius0 607 ) 608 ); 609 } 610 } 611 } 612 613 /** 614 * Perform the actual drawing on the legend. 615 * 616 * @param int $x0 The top-left x-coordinate 617 * @param int $y0 The top-left y-coordinate 618 * @param int $x1 The bottom-right x-coordinate 619 * @param int $y1 The bottom-right y-coordinate 620 * @access private 621 */ 622 function _drawLegendSample($x0, $y0, $x1, $y1) 623 { 624 $dx = abs($x1 - $x0) / 4; 625 $this->_canvas->addVertex(array('x' => $x0 + $dx , 'y' => $y1)); 626 $this->_canvas->addVertex(array('x' => ($x0 + $x1) / 2, 'y' => $y0 )); 627 $this->_canvas->addVertex(array('x' => $x1 - $dx , 'y' => $y1)); 628 $this->_canvas->polygon(array('connect' => true)); 629 } 630 631 /** 632 * Draw a sample for use with legend 633 * 634 * @param array $param The parameters for the legend 635 * @access private 636 */ 637 function _legendSample(&$param) 638 { 639 if (is_array($this->_dataset)) { 640 641 $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); 642 $this->_clip(true); 643 644 $totals = $this->_getTotals(); 645 $totals['CENTER_X'] = (int) (($this->_left + $this->_right) / 2); 646 $totals['CENTER_Y'] = (int) (($this->_top + $this->_bottom) / 2); 647 $totals['RADIUS'] = min($this->height(), $this->width()) * 0.75 * 0.5; 648 $totals['CURRENT_Y'] = 0; 649 650 if (is_a($this->_fillStyle, "Image_Graph_Fill")) { 651 $this->_fillStyle->_reset(); 652 } 653 654 $count = 0; 655 $keys = array_keys($this->_dataset); 656 foreach ($keys as $key) { 657 $dataset =& $this->_dataset[$key]; 658 $count++; 659 660 $dataset->_reset(); 661 while ($point = $dataset->_next()) { 662 $caption = $point['X']; 663 664 $this->_canvas->setFont($param['font']); 665 $width = 20 + $param['width'] + $this->_canvas->textWidth($caption); 666 $param['maxwidth'] = max($param['maxwidth'], $width); 667 $x2 = $param['x'] + $width; 668 $y2 = $param['y'] + $param['height'] + 5; 669 670 if ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) && ($y2 > $param['bottom'])) { 671 $param['y'] = $param['top']; 672 $param['x'] = $x2; 673 $y2 = $param['y'] + $param['height']; 674 } elseif ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) == 0) && ($x2 > $param['right'])) { 675 $param['x'] = $param['left']; 676 $param['y'] = $y2; 677 $x2 = $param['x'] + 20 + $param['width'] + $this->_canvas->textWidth($caption); 678 } 679 680 $x = $x0 = $param['x']; 681 $y = $param['y']; 682 $y0 = $param['y'] - $param['height'] / 2; 683 $x1 = $param['x'] + $param['width']; 684 $y1 = $param['y'] + $param['height'] / 2; 685 686 if (!isset($param['simulate'])) { 687 $this->_getFillStyle($point['ID']); 688 $this->_getLineStyle($point['ID']); 689 $this->_drawLegendSample($x0, $y0, $x1, $y1); 690 691 if (($this->_marker) && ($dataset) && ($param['show_marker'])) { 692 $prevPoint = $dataset->_nearby(-2); 693 $nextPoint = $dataset->_nearby(); 694 695 $p = $this->_getMarkerData($point, $nextPoint, $prevPoint, $totals); 696 if (is_array($point)) { 697 $p['MARKER_X'] = $x+$param['width'] / 2; 698 $p['MARKER_Y'] = $y; 699 unset ($p['AVERAGE_Y']); 700 $this->_marker->_drawMarker($p['MARKER_X'], $p['MARKER_Y'], $p); 701 } 702 } 703 $this->write($x + $param['width'] + 10, $y, $caption, IMAGE_GRAPH_ALIGN_CENTER_Y | IMAGE_GRAPH_ALIGN_LEFT, $param['font']); 704 } 705 706 if (($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) { 707 $param['y'] = $y2; 708 } else { 709 $param['x'] = $x2; 710 } 711 } 712 } 713 unset($keys); 714 $this->_clip(false); 715 $this->_canvas->endGroup(); 716 } 717 } 718 } 719 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 10:22:19 2007 | par Balluche grâce à PHPXref 0.7 |