1<?php 2/*======================================================================= 3// File: JPGRAPH_BAR.PHP 4// Description: Bar plot extension for JpGraph 5// Created: 2001-01-08 6// Author: Johan Persson (johanp@aditus.nu) 7// Ver: $Id: jpgraph_bar.php 8819 2005-02-08 11:35:07Z tokul $ 8// 9// License: This code is released under QPL 10// Copyright (C) 2001,2002 Johan Persson 11//======================================================================== 12*/ 13 14//=================================================== 15// CLASS Gradient 16// Description: Handles gradient fills. This is to be 17// considered a "friend" class of Class Image. 18//=================================================== 19class Gradient { 20 var $img=null; 21//--------------- 22// CONSTRUCTOR 23 function Gradient(&$img) { 24 $this->img = $img; 25 } 26 27//--------------- 28// PUBLIC METHODS 29 // Produce a gradient filled rectangle with a smooth transition between 30 // two colors. 31 // ($xl,$yt) Top left corner 32 // ($xr,$yb) Bottom right 33 // $from_color Starting color in gradient 34 // $to_color End color in the gradient 35 // $style Which way is the gradient oriented? 36 function FilledRectangle($xl,$yt,$xr,$yb,$from_color,$to_color,$style=1) { 37 switch( $style ) { 38 case 1: // HORIZONTAL 39 $steps = abs($xr-$xl); 40 $delta = $xr>=$xl ? 1 : -1; 41 $this->GetColArray($from_color,$to_color,$steps,$colors); 42 for( $i=0, $x=$xl; $i<$steps; ++$i ) { 43 $this->img->current_color = $colors[$i]; 44 $this->img->Line($x,$yt,$x,$yb); 45 $x += $delta; 46 } 47 break; 48 49 case 2: // VERTICAL 50 $steps = abs($yb-$yt); 51 $delta = $yb>=$yt ? 1 : -1; 52 $this->GetColArray($from_color,$to_color,$steps,$colors); 53 for($i=0,$y=$yt; $i<$steps; ++$i) { 54 $this->img->current_color = $colors[$i]; 55 $this->img->Line($xl,$y,$xr,$y); 56 $y += $delta; 57 } 58 break; 59 60 case 3: // VERTICAL FROM MIDDLE 61 $steps = abs($yb-$yt)/2; 62 $delta = $yb>=$yt ? 1 : -1; 63 $this->GetColArray($from_color,$to_color,$steps,$colors); 64 for($y=$yt, $i=0; $i<$steps; ++$i) { 65 $this->img->current_color = $colors[$i]; 66 $this->img->Line($xl,$y,$xr,$y); 67 $y += $delta; 68 } 69 --$i; 70 for($j=0; $j<$steps; ++$j, --$i) { 71 $this->img->current_color = $colors[$i]; 72 $this->img->Line($xl,$y,$xr,$y); 73 $y += $delta; 74 } 75 $this->img->Line($xl,$y,$xr,$y); 76 break; 77 78 case 4: // HORIZONTAL FROM MIDDLE 79 $steps = abs($xr-$xl)/2; 80 $delta = $xr>=$xl ? 1 : -1; 81 $this->GetColArray($from_color,$to_color,$steps,$colors); 82 for($x=$xl, $i=0; $i<$steps; ++$i) { 83 $this->img->current_color = $colors[$i]; 84 $this->img->Line($x,$yb,$x,$yt); 85 $x += $delta; 86 } 87 --$i; 88 for($j=0; $j<$steps; ++$j, --$i) { 89 $this->img->current_color = $colors[$i]; 90 $this->img->Line($x,$yb,$x,$yt); 91 $x += $delta; 92 } 93 $this->img->Line($x,$yb,$x,$yt); 94 break; 95 96 case 6: // HORIZONTAL WIDER MIDDLE 97 $steps = abs($xr-$xl)/3; 98 $delta = $xr>=$xl ? 1 : -1; 99 $this->GetColArray($from_color,$to_color,$steps,$colors); 100 for($x=$xl, $i=0; $i<$steps; ++$i) { 101 $this->img->current_color = $colors[$i]; 102 $this->img->Line($x,$yb,$x,$yt); 103 $x += $delta; 104 } 105 --$i; 106 $this->img->current_color = $colors[$i]; 107 for($j=0; $j< $steps; ++$j) { 108 $this->img->Line($x,$yb,$x,$yt); 109 $x += $delta; 110 } 111 112 for($j=0; $j<$steps; ++$j, --$i) { 113 $this->img->current_color = $colors[$i]; 114 $this->img->Line($x,$yb,$x,$yt); 115 $x += $delta; 116 } 117 break; 118 119 case 7: // VERTICAL WIDER MIDDLE 120 $steps = abs($yb-$yt)/3; 121 $delta = $yb>=$yt? 1 : -1; 122 $this->GetColArray($from_color,$to_color,$steps,$colors); 123 for($y=$yt, $i=0; $i<$steps; ++$i) { 124 $this->img->current_color = $colors[$i]; 125 $this->img->Line($xl,$y,$xr,$y); 126 $y += $delta; 127 } 128 --$i; 129 $this->img->current_color = $colors[$i]; 130 for($j=0; $j< $steps; ++$j) { 131 $this->img->Line($xl,$y,$xr,$y); 132 $y += $delta; 133 } 134 for($j=0; $j<$steps; ++$j, --$i) { 135 $this->img->current_color = $colors[$i]; 136 $this->img->Line($xl,$y,$xr,$y); 137 $y += $delta; 138 } 139 break; 140 141 case 5: // Rectangle 142 $steps = floor(min(($yb-$yt)+1,($xr-$xl)+1)/2); 143 $this->GetColArray($from_color,$to_color,$steps,$colors); 144 $dx = ($xr-$xl)/2; 145 $dy = ($yb-$yt)/2; 146 $x=$xl;$y=$yt;$x2=$xr;$y2=$yb; 147 for($x=$xl, $i=0; $x<$xl+$dx && $y<$yt+$dy ; ++$x, ++$y, --$x2, --$y2, ++$i) { 148 assert($i<count($colors)); 149 $this->img->current_color = $colors[$i]; 150 $this->img->Rectangle($x,$y,$x2,$y2); 151 } 152 $this->img->Line($x,$y,$x2,$y2); 153 break; 154 155 default: 156 die("JpGraph Error: Unknown gradient style (=$style)."); 157 break; 158 } 159 } 160 161//--------------- 162// PRIVATE METHODS 163 // Add to the image color map the necessary colors to do the transition 164 // between the two colors using $numcolors intermediate colors 165 function GetColArray($from_color,$to_color,$arr_size,&$colors,$numcols=100) { 166 if( $arr_size==0 ) return; 167 // If color is give as text get it's corresponding r,g,b values 168 $from_color = $this->img->rgb->Color($from_color); 169 $to_color = $this->img->rgb->Color($to_color); 170 171 $rdelta=($to_color[0]-$from_color[0])/$numcols; 172 $gdelta=($to_color[1]-$from_color[1])/$numcols; 173 $bdelta=($to_color[2]-$from_color[2])/$numcols; 174 $stepspercolor = $numcols/$arr_size; 175 $prevcolnum = -1; 176 for ($i=0; $i<$arr_size; ++$i) { 177 $colnum = floor($stepspercolor*$i); 178 if ( $colnum == $prevcolnum ) 179 $colors[$i] = $colidx; 180 else { 181 $r = floor($from_color[0] + $colnum*$rdelta); 182 $g = floor($from_color[1] + $colnum*$gdelta); 183 $b = floor($from_color[2] + $colnum*$bdelta); 184 $colidx = $this->img->rgb->Allocate(sprintf("#%02x%02x%02x",$r,$g,$b)); 185 $colors[$i] = $colidx; 186 } 187 $prevcolnum = $colnum; 188 } 189 } 190} // Class 191 192 193//=================================================== 194// CLASS BarPlot 195// Description: Main code to produce a bar plot 196//=================================================== 197class BarPlot extends Plot { 198 var $width=0.4; // in percent of major ticks 199 var $abswidth=-1; // Width in absolute pixels 200 var $fill_color="lightblue"; // Default is to fill with light blue 201 var $ybase=0; // Bars start at 0 202 var $align="center"; 203 var $grad=false,$grad_style=1; 204 var $grad_fromcolor=array(50,50,200),$grad_tocolor=array(255,255,255); 205 var $bar_shadow=false; 206 var $bar_shadow_color="black"; 207 var $bar_shadow_hsize=3,$bar_shadow_vsize=3; 208 var $valuepos='top'; 209 210//--------------- 211// CONSTRUCTOR 212 function BarPlot(&$datay,$datax=false) { 213 $this->Plot($datay,$datax); 214 ++$this->numpoints; 215 } 216 217//--------------- 218// PUBLIC METHODS 219 220 // Set a drop shadow for the bar (or rather an "up-right" shadow) 221 function SetShadow($color="black",$hsize=3,$vsize=3) { 222 $this->bar_shadow=true; 223 $this->bar_shadow_color=$color; 224 $this->bar_shadow_vsize=$vsize; 225 $this->bar_shadow_hsize=$hsize; 226 227 // Adjust the value margin to compensate for shadow 228 $this->value->margin += $vsize; 229 } 230 231 // DEPRECATED use SetYBase instead 232 function SetYMin($aYStartValue) { 233 //die("JpGraph Error: Deprecated function SetYMin. Use SetYBase() instead."); 234 $this->ybase=$aYStartValue; 235 } 236 237 // Specify the base value for the bars 238 function SetYBase($aYStartValue) { 239 $this->ybase=$aYStartValue; 240 } 241 242 function Legend(&$graph) { 243 if( $this->fill_color && $this->legend!="" ) { 244 if( is_array($this->fill_color) ) 245 $graph->legend->Add($this->legend,$this->fill_color[0],"",0,$this->legendcsimtarget,$this->legendcsimalt); 246 else 247 $graph->legend->Add($this->legend,$this->fill_color,"",0,$this->legendcsimtarget,$this->legendcsimalt); 248 } 249 } 250 251 // Gets called before any axis are stroked 252 function PreStrokeAdjust(&$graph) { 253 parent::PreStrokeAdjust($graph); 254 255 // If we are using a log Y-scale we want the base to be at the 256 // minimum Y-value unless the user have specifically set some other 257 // value than the default. 258 if( substr($graph->axtype,-3,3)=="log" && $this->ybase==0 ) 259 $this->ybase = $graph->yaxis->scale->GetMinVal(); 260 261 // For a "text" X-axis scale we will adjust the 262 // display of the bars a little bit. 263 if( substr($graph->axtype,0,3)=="tex" ) { 264 // Position the ticks between the bars 265 $graph->xaxis->scale->ticks->SetXLabelOffset(0.5,0); 266 267 // Center the bars 268 if( $this->align == "center" ) 269 $graph->SetTextScaleOff(0.5-$this->width/2); 270 elseif( $this->align == "right" ) 271 $graph->SetTextScaleOff(1-$this->width); 272 } 273 else { 274 // We only set an absolute width for linear and int scale 275 // for text scale the width will be set to a fraction of 276 // the majstep width. 277 if( $this->abswidth == -1 ) // Not set 278 // set width to a visuable sensible default 279 $this->abswidth = $graph->img->plotwidth/(2*count($this->coords[0])); 280 } 281 } 282 283 function Min() { 284 $m = parent::Min(); 285 if( $m[1] >= $this->ybase ) 286 $m[1] = $this->ybase; 287 return $m; 288 } 289 290 function Max() { 291 $m = parent::Max(); 292 if( $m[1] <= $this->ybase ) 293 $m[1] = $this->ybase; 294 return $m; 295 } 296 297 // Specify width as fractions of the major stepo size 298 function SetWidth($aFractionWidth) { 299 $this->width=$aFractionWidth; 300 } 301 302 // Specify width in absolute pixels. If specified this 303 // overrides SetWidth() 304 function SetAbsWidth($aWidth) { 305 $this->abswidth=$aWidth; 306 } 307 308 function SetAlign($aAlign) { 309 $this->align=$aAlign; 310 } 311 312 function SetNoFill() { 313 $this->grad = false; 314 $this->fill_color=false; 315 } 316 317 function SetFillColor($aColor) { 318 $this->fill_color=$aColor; 319 } 320 321 function SetFillGradient($from_color,$to_color,$style) { 322 $this->grad=true; 323 $this->grad_fromcolor=$from_color; 324 $this->grad_tocolor=$to_color; 325 $this->grad_style=$style; 326 } 327 328 function SetValuePos($aPos) { 329 $this->valuepos = $aPos; 330 } 331 332 function Stroke(&$img,&$xscale,&$yscale) { 333 334 $numpoints = count($this->coords[0]); 335 if( isset($this->coords[1]) ) { 336 if( count($this->coords[1])!=$numpoints ) 337 die("JpGraph Error: Number of X and Y points are not equal.<br> 338 Number of X-points:".count($this->coords[1])."<br> 339 Number of Y-points:$numpoints"); 340 else 341 $exist_x = true; 342 } 343 else 344 $exist_x = false; 345 346 347 $numbars=count($this->coords[0]); 348 349 // Use GetMinVal() instead of scale[0] directly since in the case 350 // of log scale we get a correct value. Log scales will have negative 351 // values for values < 1 while still not representing negative numbers. 352 if( $yscale->GetMinVal() >= 0 ) 353 $zp=$yscale->scale_abs[0]; 354 else { 355 $zp=$yscale->Translate(0); 356 } 357 358 if( $this->abswidth > -1 ) 359 $abswidth=$this->abswidth; 360 else 361 $abswidth=round($this->width*$xscale->scale_factor,0); 362 363 for($i=0; $i<$numbars; $i++) { 364 if( $exist_x ) $x=$this->coords[1][$i]; 365 else $x=$i; 366 367 $x=$xscale->Translate($x); 368 369 //if($this->align=="center") 370 //$x -= $abswidth/2; 371 //elseif($this->align=="right") 372 //$x -= $abswidth; 373 374 if( !$xscale->textscale ) { 375 if($this->align=="center") 376 $x -= $abswidth/2; 377 elseif($this->align=="right") 378 $x -= $abswidth; 379 } 380 381 $pts=array( 382 $x,$zp, 383 $x,$yscale->Translate($this->coords[0][$i]), 384 $x+$abswidth,$yscale->Translate($this->coords[0][$i]), 385 $x+$abswidth,$zp); 386 if( $this->grad ) { 387 $grad = new Gradient($img); 388 $grad->FilledRectangle($pts[2],$pts[3], 389 $pts[6],$pts[7], 390 $this->grad_fromcolor,$this->grad_tocolor,$this->grad_style); 391 } 392 elseif( !empty($this->fill_color) ) { 393 if(is_array($this->fill_color)) { 394 $img->PushColor($this->fill_color[$i % count($this->fill_color)]); 395 } else { 396 $img->PushColor($this->fill_color); 397 } 398 $img->FilledPolygon($pts); 399 $img->PopColor(); 400 } 401 402 // Remember value of this bar 403 $val=$this->coords[0][$i]; 404 405 if( $this->bar_shadow && $val != 0 ) { 406 $ssh = $this->bar_shadow_hsize; 407 $ssv = $this->bar_shadow_vsize; 408 // Create points to create a "upper-right" shadow 409 if( $val > 0 ) { 410 $sp[0]=$pts[6]; $sp[1]=$pts[7]; 411 $sp[2]=$pts[4]; $sp[3]=$pts[5]; 412 $sp[4]=$pts[2]; $sp[5]=$pts[3]; 413 $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv; 414 $sp[8]=$pts[4]+$ssh; $sp[9]=$pts[5]-$ssv; 415 $sp[10]=$pts[6]+$ssh; $sp[11]=$pts[7]-$ssv; 416 } 417 elseif( $val < 0 ) { 418 $sp[0]=$pts[4]; $sp[1]=$pts[5]; 419 $sp[2]=$pts[6]; $sp[3]=$pts[7]; 420 $sp[4]=$pts[0]; $sp[5]=$pts[1]; 421 $sp[6]=$pts[0]+$ssh; $sp[7]=$pts[1]-$ssv; 422 $sp[8]=$pts[6]+$ssh; $sp[9]=$pts[7]-$ssv; 423 $sp[10]=$pts[4]+$ssh; $sp[11]=$pts[5]-$ssv; 424 } 425 426 $img->PushColor($this->bar_shadow_color); 427 $img->FilledPolygon($sp); 428 $img->PopColor(); 429 } 430 431 // Stroke the outline of the bar 432 if( is_array($this->color) ) 433 $img->SetColor($this->color[$i % count($this->color)]); 434 else 435 $img->SetColor($this->color); 436 $img->SetLineWeight($this->weight); 437 $pts[] = $pts[0]; 438 $pts[] = $pts[1]; 439 $img->Polygon($pts); 440 441 $x=$pts[2]+($pts[4]-$pts[2])/2; 442 if( $this->valuepos=='top' ) { 443 $y=$pts[3]; 444 $this->value->Stroke($img,$val,$x,$y); 445 } 446 elseif( $this->valuepos=='center' ) { 447 $y = ($pts[3] + $pts[1])/2; 448 $this->value->SetAlign('center','center'); 449 $this->value->SetMargin(0); 450 $this->value->Stroke($img,$val,$x,$y); 451 } 452 elseif( $this->valuepos=='bottom' ) { 453 $y=$pts[1]; 454 $this->value->SetMargin(0); 455 $this->value->Stroke($img,$val,$x,$y); 456 } 457 else { 458 JpGraphError::Raise('Unknown position for values on bars :'.$this->valuepos); 459 die(); 460 } 461 // Create the client side image map 462 $rpts = $img->ArrRotate($pts); 463 $csimcoord=round($rpts[0]).", ".round($rpts[1]); 464 for( $j=1; $j < 4; ++$j){ 465 $csimcoord .= ", ".round($rpts[2*$j]).", ".round($rpts[2*$j+1]); 466 } 467 $this->csimareas.= '<area shape="poly" coords="'.$csimcoord.'" '; 468 if( !empty($this->csimtargets[$i]) ) 469 $this->csimareas .= " href=\"".$this->csimtargets[$i]."\""; 470 if( !empty($this->csimalts[$i]) ) { 471 $sval=sprintf($this->csimalts[$i],$this->coords[0][$i]); 472 $this->csimareas .= " alt=\"$sval\" title=\"$sval\" "; 473 } 474 $this->csimareas .= ">\n"; 475 } 476 return true; 477 } 478} // Class 479 480//=================================================== 481// CLASS GroupBarPlot 482// Description: Produce grouped bar plots 483//=================================================== 484class GroupBarPlot extends BarPlot { 485 var $plots; 486 var $width=0.7; 487 var $nbrplots=0; 488 var $numpoints; 489//--------------- 490// CONSTRUCTOR 491 function GroupBarPlot($plots) { 492 $this->plots = $plots; 493 $this->nbrplots = count($plots); 494 $this->numpoints = $plots[0]->numpoints; 495 } 496 497//--------------- 498// PUBLIC METHODS 499 function Legend(&$graph) { 500 $n = count($this->plots); 501 for($i=0; $i<$n; ++$i) 502 $this->plots[$i]->Legend($graph); 503 } 504 505 function Min() { 506 list($xmin,$ymin) = $this->plots[0]->Min(); 507 $n = count($this->plots); 508 for($i=0; $i<$n; ++$i) { 509 list($xm,$ym) = $this->plots[$i]->Min(); 510 $xmin = max($xmin,$xm); 511 $ymin = min($ymin,$ym); 512 } 513 return array($xmin,$ymin); 514 } 515 516 function Max() { 517 list($xmax,$ymax) = $this->plots[0]->Max(); 518 $n = count($this->plots); 519 for($i=0; $i<$n; ++$i) { 520 list($xm,$ym) = $this->plots[$i]->Max(); 521 $xmax = max($xmax,$xm); 522 $ymax = max($ymax,$ym); 523 } 524 return array($xmax,$ymax); 525 } 526 527 function GetCSIMareas() { 528 $n = count($this->plots); 529 $csimareas=''; 530 for($i=0; $i < $n; ++$i) { 531 $csimareas .= $this->plots[$i]->csimareas; 532 } 533 return $csimareas; 534 } 535 536 // Stroke all the bars next to each other 537 function Stroke(&$img,&$xscale,&$yscale) { 538 $tmp=$xscale->off; 539 $n = count($this->plots); 540 for( $i=0; $i<$n; ++$i ) { 541 $this->plots[$i]->ymin=$this->ybase; 542 $this->plots[$i]->SetWidth($this->width/$this->nbrplots); 543 $xscale->off = $tmp+$i*round($xscale->ticks->major_step*$xscale->scale_factor*$this->width/$this->nbrplots); 544 $this->plots[$i]->Stroke($img,$xscale,$yscale); 545 } 546 $xscale->off=$tmp; 547 } 548} // Class 549 550//=================================================== 551// CLASS AccBarPlot 552// Description: Produce accumulated bar plots 553//=================================================== 554class AccBarPlot extends BarPlot { 555 var $plots=null,$nbrplots=0,$numpoints=0; 556//--------------- 557// CONSTRUCTOR 558 function AccBarPlot($plots) { 559 $this->plots = $plots; 560 $this->nbrplots = count($plots); 561 $this->numpoints = $plots[0]->numpoints; 562 $this->value = new DisplayValue(); 563 } 564 565//--------------- 566// PUBLIC METHODS 567 function Legend(&$graph) { 568 $n = count($this->plots); 569 for( $i=0; $i<$n; ++$i ) 570 $this->plots[$i]->Legend($graph); 571 } 572 573 function Max() { 574 list($xmax) = $this->plots[0]->Max(); 575 $nmax=0; 576 for($i=0; $i<count($this->plots); ++$i) { 577 $n = count($this->plots[$i]->coords[0]); 578 $nmax = max($nmax,$n); 579 list($x) = $this->plots[$i]->Max(); 580 $xmax = Max($xmax,$x); 581 } 582 for( $i = 0; $i < $nmax; $i++ ) { 583 // Get y-value for bar $i by adding the 584 // individual bars from all the plots added. 585 // It would be wrong to just add the 586 // individual plots max y-value since that 587 // would in most cases give to large y-value. 588 $y=$this->plots[0]->coords[0][$i]; 589 for( $j = 1; $j < $this->nbrplots; $j++ ) { 590 $y += $this->plots[ $j ]->coords[0][$i]; 591 } 592 $ymax[$i] = $y; 593 } 594 $ymax = max($ymax); 595 596 // Bar always start at baseline 597 if( $ymax <= $this->ybase ) 598 $ymax = $this->ybase; 599 return array($xmax,$ymax); 600 } 601 602 function Min() { 603 $nmax=0; 604 list($xmin,$ysetmin) = $this->plots[0]->Min(); 605 for($i=0; $i<count($this->plots); ++$i) { 606 $n = count($this->plots[$i]->coords[0]); 607 $nmax = max($nmax,$n); 608 list($x,$y) = $this->plots[$i]->Min(); 609 $xmin = Min($xmin,$x); 610 $ysetmin = Min($y,$ysetmin); 611 } 612 for( $i = 0; $i < $nmax; $i++ ) { 613 // Get y-value for bar $i by adding the 614 // individual bars from all the plots added. 615 // It would be wrong to just add the 616 // individual plots max y-value since that 617 // would in most cases give to large y-value. 618 $y=$this->plots[0]->coords[0][$i]; 619 for( $j = 1; $j < $this->nbrplots; $j++ ) { 620 $y += $this->plots[ $j ]->coords[0][$i]; 621 } 622 $ymin[$i] = $y; 623 } 624 $ymin = Min($ysetmin,Min($ymin)); 625 // Bar always start at baseline 626 if( $ymin >= $this->ybase ) 627 $ymin = $this->ybase; 628 return array($xmin,$ymin); 629 } 630 631 // Stroke acc bar plot 632 function Stroke(&$img,&$xscale,&$yscale) { 633 $img->SetLineWeight($this->weight); 634 for($i=0; $i<$this->numpoints-1; $i++) { 635 $accy = 0; 636 $accy_neg = 0; 637 for($j=0; $j<$this->nbrplots; ++$j ) { 638 $img->SetColor($this->plots[$j]->color); 639 640 if ($this->plots[$j]->coords[0][$i] > 0) { 641 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy); 642 $accyt=$yscale->Translate($accy); 643 $accy+=$this->plots[$j]->coords[0][$i]; 644 } else { 645 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg); 646 $accyt=$yscale->Translate($accy_neg); 647 $accy_neg+=$this->plots[$j]->coords[0][$i]; 648 } 649 650 $xt=$xscale->Translate($i); 651 652 //echo "$i => $xt<br>"; 653 654 if( $this->abswidth > -1 ) 655 $abswidth=$this->abswidth; 656 else 657 $abswidth=round($this->width*$xscale->scale_factor,0); 658 659 $pts=array($xt,$accyt,$xt,$yt,$xt+$abswidth,$yt,$xt+$abswidth,$accyt); 660 661 if( $this->plots[$j]->grad ) { 662 $grad = new Gradient($img); 663 $grad->FilledRectangle( 664 $pts[2],$pts[3], 665 $pts[6],$pts[7], 666 $this->plots[$j]->grad_fromcolor, 667 $this->plots[$j]->grad_tocolor, 668 $this->plots[$j]->grad_style); 669 } elseif ($this->plots[$j]->fill_color ) { 670 $img->SetColor($this->plots[$j]->fill_color); 671 $img->FilledPolygon($pts); 672 $img->SetColor($this->plots[$j]->color); 673 } 674 675 if( $this->bar_shadow ) { 676 $ssh = $this->bar_shadow_hsize; 677 $ssv = $this->bar_shadow_vsize; 678 // Create points to create a "upper-right" shadow 679 $sp[0]=$pts[6]; $sp[1]=$pts[7]; 680 $sp[2]=$pts[4]; $sp[3]=$pts[5]; 681 $sp[4]=$pts[2]; $sp[5]=$pts[3]; 682 $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv; 683 $sp[8]=$pts[4]+$ssh; $sp[9]=$pts[5]-$ssv; 684 $sp[10]=$pts[6]+$ssh; $sp[11]=$pts[7]-$ssv; 685 $img->SetColor($this->bar_shadow_color); 686 $img->FilledPolygon($sp,4); 687 } 688 689 if( $i < count($this->plots[$j]->csimtargets) ) { 690 // Create the client side image map 691 $rpts = $img->ArrRotate($pts); 692 $csimcoord=round($rpts[0]).", ".round($rpts[1]); 693 for( $k=1; $k < 4; ++$k){ 694 $csimcoord .= ", ".round($rpts[2*$k]).", ".round($rpts[2*$k+1]); 695 } 696 $this->csimareas.= '<area shape="poly" coords="'.$csimcoord.'" '; 697 $this->csimareas.= " href=\"".$this->plots[$j]->csimtargets[$i]."\""; 698 if( !empty($this->plots[$j]->csimalts[$i]) ) { 699 $sval=sprintf($this->plots[$j]->csimalts[$i],$this->plots[$j]->coords[0][$i]); 700 $this->csimareas .= " alt=\"$sval\" title=\"$sval\" "; 701 } 702 $this->csimareas .= ">\n"; 703 } 704 $pts[] = $pts[0]; 705 $pts[] = $pts[1]; 706 $img->Polygon($pts); 707 } 708 709 710 $x=$pts[2]+($pts[4]-$pts[2])/2; 711 $y=$yscale->Translate($accy); 712 if($this->bar_shadow) $x += $ssh; 713 $this->value->Stroke($img,$accy,$x,$y); 714 715 $accy = 0; 716 $accy_neg = 0; 717 for($j=0; $j<$this->nbrplots; ++$j ) { 718 if ($this->plots[$j]->coords[0][$i] > 0) { 719 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy); 720 $accyt=$yscale->Translate($accy); 721 $y = $accyt-($accyt-$yt)/2; 722 $accy+=$this->plots[$j]->coords[0][$i]; 723 } else { 724 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg); 725 $accyt=$yscale->Translate($accy_neg); 726 $y=0; 727 $accy_neg+=$this->plots[$j]->coords[0][$i]; 728 } 729 $this->plots[$j]->value->SetAlign("center","center"); 730 $this->plots[$j]->value->SetMargin(0); 731 $this->plots[$j]->value->Stroke($img,$this->plots[$j]->coords[0][$i],$x,$y); 732 } 733 734 } 735 return true; 736 } 737} // Class 738 739/* EOF */ 740?> 741