Changeset 267 for trunk/client/modules/Elezioni/grafici/jpgraph_bar.php
- Timestamp:
- Apr 14, 2019, 2:31:40 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/client/modules/Elezioni/grafici/jpgraph_bar.php
r265 r267 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_BAR.PHP4 // Description:Bar plot extension for JpGraph5 // Created:2001-01-086 // Ver: $Id: jpgraph_bar.php 1905 2009-10-06 18:00:21Z ljp $7 8 // Copyright (c) Asial Corporation. All rights reserved.9 10 3 // File: JPGRAPH_BAR.PHP 4 // Description: Bar plot extension for JpGraph 5 // Created: 2001-01-08 6 // Ver: $Id: jpgraph_bar.php 1017 2008-07-08 06:09:28Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 require_once('jpgraph_plotband.php'); … … 26 26 //=================================================== 27 27 // CLASS BarPlot 28 // Description: Main code to produce a bar plot 28 // Description: Main code to produce a bar plot 29 29 //=================================================== 30 30 class BarPlot extends Plot { … … 37 37 protected $width=0.4; // in percent of major ticks 38 38 protected $abswidth=-1; // Width in absolute pixels 39 protected $ybase=0; // Bars start at 0 39 protected $ybase=0; // Bars start at 0 40 40 protected $align="center"; 41 41 protected $bar_shadow=false; 42 42 protected $bar_shadow_color="black"; 43 protected $bar_shadow_hsize=3,$bar_shadow_vsize=3; 44 protected $bar_3d=false; 45 protected $bar_3d_hsize=3,$bar_3d_vsize=3; 46 47 //--------------- 48 // CONSTRUCTOR 49 function __construct($datay,$datax=false) { 50 parent::__construct($datay,$datax); 51 ++$this->numpoints; 52 } 53 54 //--------------- 55 // PUBLIC METHODS 56 43 protected $bar_shadow_hsize=3,$bar_shadow_vsize=3; 44 45 //--------------- 46 // CONSTRUCTOR 47 function BarPlot($datay,$datax=false) { 48 $this->Plot($datay,$datax); 49 ++$this->numpoints; 50 } 51 52 //--------------- 53 // PUBLIC METHODS 54 57 55 // Set a drop shadow for the bar (or rather an "up-right" shadow) 58 function SetShadow($aColor="black",$aHSize=3,$aVSize=3,$aShow=true) { 59 $this->bar_shadow=$aShow; 60 $this->bar_shadow_color=$aColor; 61 $this->bar_shadow_vsize=$aVSize; 62 $this->bar_shadow_hsize=$aHSize; 63 64 // Adjust the value margin to compensate for shadow 65 $this->value->margin += $aVSize; 66 } 67 68 function Set3D($aHSize=3,$aVSize=3,$aShow=true) { 69 $this->bar_3d=$aShow; 70 $this->bar_3d_vsize=$aVSize; 71 $this->bar_3d_hsize=$aHSize; 72 73 $this->value->margin += $aVSize; 74 } 75 56 function SetShadow($color="black",$hsize=3,$vsize=3,$show=true) { 57 $this->bar_shadow=$show; 58 $this->bar_shadow_color=$color; 59 $this->bar_shadow_vsize=$vsize; 60 $this->bar_shadow_hsize=$hsize; 61 62 // Adjust the value margin to compensate for shadow 63 $this->value->margin += $vsize; 64 } 65 76 66 // DEPRECATED use SetYBase instead 77 67 function SetYMin($aYStartValue) { 78 //die("JpGraph Error: Deprecated function SetYMin. Use SetYBase() instead."); 79 68 //die("JpGraph Error: Deprecated function SetYMin. Use SetYBase() instead."); 69 $this->ybase=$aYStartValue; 80 70 } 81 71 82 72 // Specify the base value for the bars 83 73 function SetYBase($aYStartValue) { 84 $this->ybase=$aYStartValue; 85 } 86 87 // The method will take the specified pattern anre 88 // return a pattern index that corresponds to the original 89 // patterm being rotated 90 degreees. This is needed when plottin 90 // Horizontal bars 91 function RotatePattern($aPat,$aRotate=true) { 92 $rotate = array(1 => 2, 2 => 1, 3 => 3, 4 => 5, 5 => 4, 6 => 6, 7 => 7, 8 => 8); 93 if( $aRotate ) { 94 return $rotate[$aPat]; 95 } 96 else { 97 return $aPat; 98 } 99 } 100 74 $this->ybase=$aYStartValue; 75 } 76 101 77 function Legend($graph) { 102 if( $this->grad && $this->legend!="" && !$this->fill ) { 103 $color=array($this->grad_fromcolor,$this->grad_tocolor); 104 // In order to differentiate between gradients and cooors specified as an RGB triple 105 $graph->legend->Add($this->legend,$color,"",-$this->grad_style, 106 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 107 } 108 elseif( $this->legend!="" && ($this->iPattern > -1 || is_array($this->iPattern)) ) { 109 if( is_array($this->iPattern) ) { 110 $p1 = $this->RotatePattern( $this->iPattern[0], $graph->img->a == 90 ); 111 $p2 = $this->iPatternColor[0]; 112 $p3 = $this->iPatternDensity[0]; 113 } 114 else { 115 $p1 = $this->RotatePattern( $this->iPattern, $graph->img->a == 90 ); 116 $p2 = $this->iPatternColor; 117 $p3 = $this->iPatternDensity; 118 } 119 if( $p3 < 90 ) $p3 += 5; 120 $color = array($p1,$p2,$p3,$this->fill_color); 121 // A kludge: Too mark that we add a pattern we use a type value of < 100 122 $graph->legend->Add($this->legend,$color,"",-101, 123 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 124 } 125 elseif( $this->fill_color && $this->legend!="" ) { 126 if( is_array($this->fill_color) ) { 127 $graph->legend->Add($this->legend,$this->fill_color[0],"",0, 128 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 129 } 130 else { 131 $graph->legend->Add($this->legend,$this->fill_color,"",0, 132 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 133 } 134 } 78 if( $this->grad && $this->legend!="" && !$this->fill ) { 79 $color=array($this->grad_fromcolor,$this->grad_tocolor); 80 // In order to differentiate between gradients and cooors specified as an RGB triple 81 $graph->legend->Add($this->legend,$color,"",-$this->grad_style, 82 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 83 } 84 elseif( $this->legend!="" && ($this->iPattern > -1 || is_array($this->iPattern)) ) { 85 if( is_array($this->iPattern) ) { 86 $p1 = $this->iPattern[0]; 87 $p2 = $this->iPatternColor[0]; 88 $p3 = $this->iPatternDensity[0]; 89 } 90 else { 91 $p1 = $this->iPattern; 92 $p2 = $this->iPatternColor; 93 $p3 = $this->iPatternDensity; 94 } 95 $color = array($p1,$p2,$p3,$this->fill_color); 96 // A kludge: Too mark that we add a pattern we use a type value of < 100 97 $graph->legend->Add($this->legend,$color,"",-101, 98 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 99 } 100 elseif( $this->fill_color && $this->legend!="" ) { 101 if( is_array($this->fill_color) ) { 102 $graph->legend->Add($this->legend,$this->fill_color[0],"",0, 103 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 104 } 105 else { 106 $graph->legend->Add($this->legend,$this->fill_color,"",0, 107 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 108 } 109 } 135 110 } 136 111 137 112 // Gets called before any axis are stroked 138 113 function PreStrokeAdjust($graph) { 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 // Center the bars 154 155 156 157 158 159 160 161 $graph->SetTextScaleOff(1-$this->width); 162 163 164 elseif( ($this instanceof AccBarPlot) || ($this instanceof GroupBarPlot) ) { 165 166 167 168 114 parent::PreStrokeAdjust($graph); 115 116 // If we are using a log Y-scale we want the base to be at the 117 // minimum Y-value unless the user have specifically set some other 118 // value than the default. 119 if( substr($graph->axtype,-3,3)=="log" && $this->ybase==0 ) 120 $this->ybase = $graph->yaxis->scale->GetMinVal(); 121 122 // For a "text" X-axis scale we will adjust the 123 // display of the bars a little bit. 124 if( substr($graph->axtype,0,3)=="tex" ) { 125 // Position the ticks between the bars 126 $graph->xaxis->scale->ticks->SetXLabelOffset(0.5,0); 127 128 // Center the bars 129 if( $this->abswidth > -1 ) { 130 $graph->SetTextScaleAbsCenterOff($this->abswidth); 131 } 132 else { 133 if( $this->align == "center" ) 134 $graph->SetTextScaleOff(0.5-$this->width/2); 135 elseif( $this->align == "right" ) 136 $graph->SetTextScaleOff(1-$this->width); 137 } 138 } 139 elseif( ($this instanceof AccBarPlot) || ($this instanceof GroupBarPlot) ) { 140 // We only set an absolute width for linear and int scale 141 // for text scale the width will be set to a fraction of 142 // the majstep width. 143 if( $this->abswidth == -1 ) { 169 144 // Not set 170 171 172 173 145 // set width to a visuable sensible default 146 $this->abswidth = $graph->img->plotwidth/(2*$this->numpoints); 147 } 148 } 174 149 } 175 150 176 151 function Min() { 177 $m = parent::Min(); 178 if( $m[1] >= $this->ybase ) $m[1] = $this->ybase; 179 return $m; 152 $m = parent::Min(); 153 if( $m[1] >= $this->ybase ) 154 $m[1] = $this->ybase; 155 return $m; 180 156 } 181 157 182 158 function Max() { 183 $m = parent::Max(); 184 if( $m[1] <= $this->ybase ) $m[1] = $this->ybase; 185 return $m; 186 } 187 159 $m = parent::Max(); 160 if( $m[1] <= $this->ybase ) 161 $m[1] = $this->ybase; 162 return $m; 163 } 164 188 165 // Specify width as fractions of the major stepo size 189 166 function SetWidth($aWidth) { 190 if( $aWidth > 1 ) { 191 // Interpret this as absolute width 192 $this->abswidth=$aWidth; 193 } 194 else { 195 $this->width=$aWidth; 196 } 197 } 198 167 if( $aWidth > 1 ) { 168 // Interpret this as absolute width 169 $this->abswidth=$aWidth; 170 } 171 else 172 $this->width=$aWidth; 173 } 174 199 175 // Specify width in absolute pixels. If specified this 200 176 // overrides SetWidth() 201 177 function SetAbsWidth($aWidth) { 202 203 } 204 178 $this->abswidth=$aWidth; 179 } 180 205 181 function SetAlign($aAlign) { 206 207 } 208 182 $this->align=$aAlign; 183 } 184 209 185 function SetNoFill() { 210 211 212 213 } 214 186 $this->grad = false; 187 $this->fill_color=false; 188 $this->fill=false; 189 } 190 215 191 function SetFillColor($aColor) { 216 // Do an extra error check if the color is specified as an RGB array triple 217 // In that case convert it to a hex string since it will otherwise be 218 // interpretated as an array of colors for each individual bar. 219 220 $aColor = RGB::tryHexConversion($aColor); 221 $this->fill = true ; 222 $this->fill_color=$aColor; 223 224 } 225 192 $this->fill = true ; 193 $this->fill_color=$aColor; 194 } 195 226 196 function SetFillGradient($aFromColor,$aToColor=null,$aStyle=null) { 227 228 229 230 231 } 232 197 $this->grad = true; 198 $this->grad_fromcolor = $aFromColor; 199 $this->grad_tocolor = $aToColor; 200 $this->grad_style = $aStyle; 201 } 202 233 203 function SetValuePos($aPos) { 234 204 $this->valuepos = $aPos; 235 205 } 236 206 237 207 function SetPattern($aPattern, $aColor='black'){ 238 if( is_array($aPattern) ) { 239 $n = count($aPattern); 240 $this->iPattern = array(); 241 $this->iPatternDensity = array(); 242 if( is_array($aColor) ) { 243 $this->iPatternColor = array(); 244 if( count($aColor) != $n ) { 245 JpGraphError::RaiseL(2001);//('NUmber of colors is not the same as the number of patterns in BarPlot::SetPattern()'); 246 } 247 } 248 else { 249 $this->iPatternColor = $aColor; 250 } 251 for( $i=0; $i < $n; ++$i ) { 252 $this->_SetPatternHelper($aPattern[$i], $this->iPattern[$i], $this->iPatternDensity[$i]); 253 if( is_array($aColor) ) { 254 $this->iPatternColor[$i] = $aColor[$i]; 255 } 256 } 257 } 258 else { 259 $this->_SetPatternHelper($aPattern, $this->iPattern, $this->iPatternDensity); 260 $this->iPatternColor = $aColor; 261 } 208 if( is_array($aPattern) ) { 209 $n = count($aPattern); 210 $this->iPattern = array(); 211 $this->iPatternDensity = array(); 212 if( is_array($aColor) ) { 213 $this->iPatternColor = array(); 214 if( count($aColor) != $n ) { 215 JpGraphError::RaiseL(2001);//('NUmber of colors is not the same as the number of patterns in BarPlot::SetPattern()'); 216 } 217 } 218 else 219 $this->iPatternColor = $aColor; 220 for( $i=0; $i < $n; ++$i ) { 221 $this->_SetPatternHelper($aPattern[$i], $this->iPattern[$i], $this->iPatternDensity[$i]); 222 if( is_array($aColor) ) { 223 $this->iPatternColor[$i] = $aColor[$i]; 224 } 225 } 226 } 227 else { 228 $this->_SetPatternHelper($aPattern, $this->iPattern, $this->iPatternDensity); 229 $this->iPatternColor = $aColor; 230 } 262 231 } 263 232 264 233 function _SetPatternHelper($aPattern, &$aPatternValue, &$aDensity){ 265 switch( $aPattern ) { 266 case PATTERN_DIAG1: 267 $aPatternValue= 1; 268 $aDensity = 92; 269 break; 270 case PATTERN_DIAG2: 271 $aPatternValue= 1; 272 $aDensity = 78; 273 break; 274 case PATTERN_DIAG3: 275 $aPatternValue= 2; 276 $aDensity = 92; 277 break; 278 case PATTERN_DIAG4: 279 $aPatternValue= 2; 280 $aDensity = 78; 281 break; 282 case PATTERN_CROSS1: 283 $aPatternValue= 8; 284 $aDensity = 90; 285 break; 286 case PATTERN_CROSS2: 287 $aPatternValue= 8; 288 $aDensity = 78; 289 break; 290 case PATTERN_CROSS3: 291 $aPatternValue= 8; 292 $aDensity = 65; 293 break; 294 case PATTERN_CROSS4: 295 $aPatternValue= 7; 296 $aDensity = 90; 297 break; 298 case PATTERN_STRIPE1: 299 $aPatternValue= 5; 300 $aDensity = 94; 301 break; 302 case PATTERN_STRIPE2: 303 $aPatternValue= 5; 304 $aDensity = 85; 305 break; 306 default: 307 JpGraphError::RaiseL(2002); 308 //('Unknown pattern specified in call to BarPlot::SetPattern()'); 309 } 310 } 311 312 function Stroke($img,$xscale,$yscale) { 313 314 $numpoints = count($this->coords[0]); 315 if( isset($this->coords[1]) ) { 316 if( count($this->coords[1])!=$numpoints ) { 317 JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints); 318 //"Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])."Number of Y-points:$numpoints"); 319 } 320 else { 321 $exist_x = true; 322 } 323 } 324 else { 325 $exist_x = false; 326 } 327 328 329 $numbars=count($this->coords[0]); 330 331 // Use GetMinVal() instead of scale[0] directly since in the case 332 // of log scale we get a correct value. Log scales will have negative 333 // values for values < 1 while still not representing negative numbers. 334 if( $yscale->GetMinVal() >= 0 ) 335 $zp=$yscale->scale_abs[0]; 336 else { 337 $zp=$yscale->Translate(0); 338 } 339 340 if( $this->abswidth > -1 ) { 341 $abswidth=$this->abswidth; 342 } 343 else { 344 $abswidth=round($this->width*$xscale->scale_factor,0); 345 } 346 347 // Count pontetial pattern array to avoid doing the count for each iteration 348 if( is_array($this->iPattern) ) { 349 $np = count($this->iPattern); 350 } 351 352 $grad = null; 353 for($i=0; $i < $numbars; ++$i) { 354 355 // If value is NULL, or 0 then don't draw a bar at all 356 if ($this->coords[0][$i] === null || $this->coords[0][$i] === '' ) 357 continue; 358 359 if( $exist_x ) { 360 $x=$this->coords[1][$i]; 361 } 362 else { 363 $x=$i; 364 } 365 366 $x=$xscale->Translate($x); 367 368 // Comment Note: This confuses the positioning when using acc together with 369 // grouped bars. Workaround for fixing #191 370 /* 371 if( !$xscale->textscale ) { 372 if($this->align=="center") 373 $x -= $abswidth/2; 374 elseif($this->align=="right") 375 $x -= $abswidth; 376 } 377 */ 378 // Stroke fill color and fill gradient 379 $pts=array( 380 $x,$zp, 381 $x,$yscale->Translate($this->coords[0][$i]), 382 $x+$abswidth,$yscale->Translate($this->coords[0][$i]), 383 $x+$abswidth,$zp); 384 if( $this->grad ) { 385 if( $grad === null ) { 386 $grad = new Gradient($img); 387 } 388 if( is_array($this->grad_fromcolor) ) { 389 // The first argument (grad_fromcolor) can be either an array or a single color. If it is an array 390 // then we have two choices. It can either a) be a single color specified as an RGB triple or it can be 391 // an array to specify both (from, to style) for each individual bar. The way to know the difference is 392 // to investgate the first element. If this element is an integer [0,255] then we assume it is an RGB 393 // triple. 394 $ng = count($this->grad_fromcolor); 395 if( $ng === 3 ) { 396 if( is_numeric($this->grad_fromcolor[0]) && $this->grad_fromcolor[0] > 0 && $this->grad_fromcolor[0] < 256 ) { 397 // RGB Triple 398 $fromcolor = $this->grad_fromcolor; 399 $tocolor = $this->grad_tocolor; 400 $style = $this->grad_style; 401 } 402 else { 403 $fromcolor = $this->grad_fromcolor[$i % $ng][0]; 404 $tocolor = $this->grad_fromcolor[$i % $ng][1]; 405 $style = $this->grad_fromcolor[$i % $ng][2]; 406 } 407 } 408 else { 409 $fromcolor = $this->grad_fromcolor[$i % $ng][0]; 410 $tocolor = $this->grad_fromcolor[$i % $ng][1]; 411 $style = $this->grad_fromcolor[$i % $ng][2]; 412 } 413 $grad->FilledRectangle($pts[2],$pts[3], 414 $pts[6],$pts[7], 415 $fromcolor,$tocolor,$style); 416 } 417 else { 418 $grad->FilledRectangle($pts[2],$pts[3], 419 $pts[6],$pts[7], 420 $this->grad_fromcolor,$this->grad_tocolor,$this->grad_style); 421 } 422 } 423 elseif( !empty($this->fill_color) ) { 424 if(is_array($this->fill_color)) { 425 $img->PushColor($this->fill_color[$i % count($this->fill_color)]); 426 } else { 427 $img->PushColor($this->fill_color); 428 } 429 $img->FilledPolygon($pts); 430 $img->PopColor(); 431 } 432 433 /////////////////////////kokorahen rectangle polygon////////////////////// 434 435 // Remember value of this bar 436 $val=$this->coords[0][$i]; 437 438 if( !empty($val) && !is_numeric($val) ) { 439 JpGraphError::RaiseL(2004,$i,$val); 440 //'All values for a barplot must be numeric. You have specified value['.$i.'] == \''.$val.'\''); 441 } 442 443 // Determine the shadow 444 if( $this->bar_shadow && $val != 0) { 445 446 $ssh = $this->bar_shadow_hsize; 447 $ssv = $this->bar_shadow_vsize; 448 // Create points to create a "upper-right" shadow 449 if( $val > 0 ) { 450 $sp[0]=$pts[6]; $sp[1]=$pts[7]; 451 $sp[2]=$pts[4]; $sp[3]=$pts[5]; 452 $sp[4]=$pts[2]; $sp[5]=$pts[3]; 453 $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv; 454 $sp[8]=$pts[4]+$ssh; $sp[9]=$pts[5]-$ssv; 455 $sp[10]=$pts[6]+$ssh; $sp[11]=$pts[7]-$ssv; 456 } 457 elseif( $val < 0 ) { 458 $sp[0]=$pts[4]; $sp[1]=$pts[5]; 459 $sp[2]=$pts[6]; $sp[3]=$pts[7]; 460 $sp[4]=$pts[0]; $sp[5]=$pts[1]; 461 $sp[6]=$pts[0]+$ssh; $sp[7]=$pts[1]-$ssv; 462 $sp[8]=$pts[6]+$ssh; $sp[9]=$pts[7]-$ssv; 463 $sp[10]=$pts[4]+$ssh; $sp[11]=$pts[5]-$ssv; 464 } 465 if( is_array($this->bar_shadow_color) ) { 466 $numcolors = count($this->bar_shadow_color); 467 if( $numcolors == 0 ) { 468 JpGraphError::RaiseL(2005);//('You have specified an empty array for shadow colors in the bar plot.'); 469 } 470 $img->PushColor($this->bar_shadow_color[$i % $numcolors]); 471 } 472 else { 473 $img->PushColor($this->bar_shadow_color); 474 } 475 $img->FilledPolygon($sp); 476 $img->PopColor(); 477 478 } elseif( $this->bar_3d && $val != 0) { 479 // Determine the 3D 480 481 $ssh = $this->bar_3d_hsize; 482 $ssv = $this->bar_3d_vsize; 483 484 // Create points to create a "upper-right" shadow 485 if( $val > 0 ) { 486 $sp1[0]=$pts[6]; $sp1[1]=$pts[7]; 487 $sp1[2]=$pts[4]; $sp1[3]=$pts[5]; 488 $sp1[4]=$pts[4]+$ssh; $sp1[5]=$pts[5]-$ssv; 489 $sp1[6]=$pts[6]+$ssh; $sp1[7]=$pts[7]-$ssv; 490 491 $sp2[0]=$pts[4]; $sp2[1]=$pts[5]; 492 $sp2[2]=$pts[2]; $sp2[3]=$pts[3]; 493 $sp2[4]=$pts[2]+$ssh; $sp2[5]=$pts[3]-$ssv; 494 $sp2[6]=$pts[4]+$ssh; $sp2[7]=$pts[5]-$ssv; 495 496 } 497 elseif( $val < 0 ) { 498 $sp1[0]=$pts[4]; $sp1[1]=$pts[5]; 499 $sp1[2]=$pts[6]; $sp1[3]=$pts[7]; 500 $sp1[4]=$pts[6]+$ssh; $sp1[5]=$pts[7]-$ssv; 501 $sp1[6]=$pts[4]+$ssh; $sp1[7]=$pts[5]-$ssv; 502 503 $sp2[0]=$pts[6]; $sp2[1]=$pts[7]; 504 $sp2[2]=$pts[0]; $sp2[3]=$pts[1]; 505 $sp2[4]=$pts[0]+$ssh; $sp2[5]=$pts[1]-$ssv; 506 $sp2[6]=$pts[6]+$ssh; $sp2[7]=$pts[7]-$ssv; 507 } 508 509 $base_color = $this->fill_color; 510 511 $img->PushColor($base_color . ':0.7'); 512 $img->FilledPolygon($sp1); 513 $img->PopColor(); 514 515 $img->PushColor($base_color . ':1.1'); 516 $img->FilledPolygon($sp2); 517 $img->PopColor(); 518 } 519 520 // Stroke the pattern 521 if( is_array($this->iPattern) ) { 522 $f = new RectPatternFactory(); 523 if( is_array($this->iPatternColor) ) { 524 $pcolor = $this->iPatternColor[$i % $np]; 525 } 526 else { 527 $pcolor = $this->iPatternColor; 528 } 529 $prect = $f->Create($this->iPattern[$i % $np],$pcolor,1); 530 $prect->SetDensity($this->iPatternDensity[$i % $np]); 531 532 if( $val < 0 ) { 533 $rx = $pts[0]; 534 $ry = $pts[1]; 535 } 536 else { 537 $rx = $pts[2]; 538 $ry = $pts[3]; 539 } 540 $width = abs($pts[4]-$pts[0])+1; 541 $height = abs($pts[1]-$pts[3])+1; 542 $prect->SetPos(new Rectangle($rx,$ry,$width,$height)); 543 $prect->Stroke($img); 544 } 545 else { 546 if( $this->iPattern > -1 ) { 547 $f = new RectPatternFactory(); 548 $prect = $f->Create($this->iPattern,$this->iPatternColor,1); 549 $prect->SetDensity($this->iPatternDensity); 550 if( $val < 0 ) { 551 $rx = $pts[0]; 552 $ry = $pts[1]; 553 } 554 else { 555 $rx = $pts[2]; 556 $ry = $pts[3]; 557 } 558 $width = abs($pts[4]-$pts[0])+1; 559 $height = abs($pts[1]-$pts[3])+1; 560 $prect->SetPos(new Rectangle($rx,$ry,$width,$height)); 561 $prect->Stroke($img); 562 } 563 } 564 565 // Stroke the outline of the bar 566 if( is_array($this->color) ) { 567 $img->SetColor($this->color[$i % count($this->color)]); 568 } 569 else { 570 $img->SetColor($this->color); 571 } 572 573 $pts[] = $pts[0]; 574 $pts[] = $pts[1]; 575 576 if( $this->weight > 0 ) { 577 $img->SetLineWeight($this->weight); 578 $img->Polygon($pts); 579 } 580 581 // Determine how to best position the values of the individual bars 582 $x=$pts[2]+($pts[4]-$pts[2])/2; 583 $this->value->SetMargin(5); 584 585 if( $this->valuepos=='top' ) { 586 $y=$pts[3]; 587 if( $img->a === 90 ) { 588 if( $val < 0 ) { 589 $this->value->SetAlign('right','center'); 590 } 591 else { 592 $this->value->SetAlign('left','center'); 593 } 594 595 } 596 else { 597 if( $val < 0 ) { 598 $this->value->SetMargin(-5); 599 $y=$pts[1]; 600 $this->value->SetAlign('center','bottom'); 601 } 602 else { 603 $this->value->SetAlign('center','bottom'); 604 } 605 606 } 607 $this->value->Stroke($img,$val,$x,$y); 608 } 609 elseif( $this->valuepos=='max' ) { 610 $y=$pts[3]; 611 if( $img->a === 90 ) { 612 if( $val < 0 ) 613 $this->value->SetAlign('left','center'); 614 else 615 $this->value->SetAlign('right','center'); 616 } 617 else { 618 if( $val < 0 ) { 619 $this->value->SetAlign('center','bottom'); 620 } 621 else { 622 $this->value->SetAlign('center','top'); 623 } 624 } 625 $this->value->SetMargin(-5); 626 $this->value->Stroke($img,$val,$x,$y); 627 } 628 elseif( $this->valuepos=='center' ) { 629 $y = ($pts[3] + $pts[1])/2; 630 $this->value->SetAlign('center','center'); 631 $this->value->SetMargin(0); 632 $this->value->Stroke($img,$val,$x,$y); 633 } 634 elseif( $this->valuepos=='bottom' || $this->valuepos=='min' ) { 635 $y=$pts[1]; 636 if( $img->a === 90 ) { 637 if( $val < 0 ) 638 $this->value->SetAlign('right','center'); 639 else 640 $this->value->SetAlign('left','center'); 641 } 642 $this->value->SetMargin(3); 643 $this->value->Stroke($img,$val,$x,$y); 644 } 645 else { 646 JpGraphError::RaiseL(2006,$this->valuepos); 647 //'Unknown position for values on bars :'.$this->valuepos); 648 } 649 // Create the client side image map 650 $rpts = $img->ArrRotate($pts); 651 $csimcoord=round($rpts[0]).", ".round($rpts[1]); 652 for( $j=1; $j < 4; ++$j){ 653 $csimcoord .= ", ".round($rpts[2*$j]).", ".round($rpts[2*$j+1]); 654 } 655 if( !empty($this->csimtargets[$i]) ) { 656 $this->csimareas .= '<area shape="poly" coords="'.$csimcoord.'" '; 657 $this->csimareas .= " href=\"".htmlentities($this->csimtargets[$i])."\""; 658 659 if( !empty($this->csimwintargets[$i]) ) { 660 $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; 661 } 662 663 $sval=''; 664 if( !empty($this->csimalts[$i]) ) { 665 $sval=sprintf($this->csimalts[$i],$this->coords[0][$i]); 666 $this->csimareas .= " title=\"$sval\" alt=\"$sval\" "; 667 } 668 $this->csimareas .= " />\n"; 669 } 670 } 671 return true; 234 switch( $aPattern ) { 235 case PATTERN_DIAG1: 236 $aPatternValue= 1; 237 $aDensity = 90; 238 break; 239 case PATTERN_DIAG2: 240 $aPatternValue= 1; 241 $aDensity = 75; 242 break; 243 case PATTERN_DIAG3: 244 $aPatternValue= 2; 245 $aDensity = 90; 246 break; 247 case PATTERN_DIAG4: 248 $aPatternValue= 2; 249 $aDensity = 75; 250 break; 251 case PATTERN_CROSS1: 252 $aPatternValue= 8; 253 $aDensity = 90; 254 break; 255 case PATTERN_CROSS2: 256 $aPatternValue= 8; 257 $aDensity = 78; 258 break; 259 case PATTERN_CROSS3: 260 $aPatternValue= 8; 261 $aDensity = 65; 262 break; 263 case PATTERN_CROSS4: 264 $aPatternValue= 7; 265 $aDensity = 90; 266 break; 267 case PATTERN_STRIPE1: 268 $aPatternValue= 5; 269 $aDensity = 90; 270 break; 271 case PATTERN_STRIPE2: 272 $aPatternValue= 5; 273 $aDensity = 75; 274 break; 275 default: 276 JpGraphError::RaiseL(2002); 277 //('Unknown pattern specified in call to BarPlot::SetPattern()'); 278 } 279 } 280 281 function Stroke($img,$xscale,$yscale) { 282 283 $numpoints = count($this->coords[0]); 284 if( isset($this->coords[1]) ) { 285 if( count($this->coords[1])!=$numpoints ) 286 JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints); 287 //"Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])."Number of Y-points:$numpoints"); 288 else 289 $exist_x = true; 290 } 291 else 292 $exist_x = false; 293 294 295 $numbars=count($this->coords[0]); 296 297 // Use GetMinVal() instead of scale[0] directly since in the case 298 // of log scale we get a correct value. Log scales will have negative 299 // values for values < 1 while still not representing negative numbers. 300 if( $yscale->GetMinVal() >= 0 ) 301 $zp=$yscale->scale_abs[0]; 302 else { 303 $zp=$yscale->Translate(0); 304 } 305 306 if( $this->abswidth > -1 ) { 307 $abswidth=$this->abswidth; 308 } 309 else 310 $abswidth=round($this->width*$xscale->scale_factor,0); 311 312 // Count pontetial pattern array to avoid doing the count for each iteration 313 if( is_array($this->iPattern) ) { 314 $np = count($this->iPattern); 315 } 316 317 $grad = null; 318 for($i=0; $i < $numbars; ++$i) { 319 320 // If value is NULL, or 0 then don't draw a bar at all 321 if ($this->coords[0][$i] === null || $this->coords[0][$i] === '' ) 322 continue; 323 324 if( $exist_x ) $x=$this->coords[1][$i]; 325 else $x=$i; 326 327 $x=$xscale->Translate($x); 328 329 // Comment Note: This confuses the positioning when using acc together with 330 // grouped bars. Workaround for fixing #191 331 /* 332 if( !$xscale->textscale ) { 333 if($this->align=="center") 334 $x -= $abswidth/2; 335 elseif($this->align=="right") 336 $x -= $abswidth; 337 } 338 */ 339 // Stroke fill color and fill gradient 340 $pts=array( 341 $x,$zp, 342 $x,$yscale->Translate($this->coords[0][$i]), 343 $x+$abswidth,$yscale->Translate($this->coords[0][$i]), 344 $x+$abswidth,$zp); 345 if( $this->grad ) { 346 if( $grad === null ) 347 $grad = new Gradient($img); 348 if( is_array($this->grad_fromcolor) ) { 349 // The first argument (grad_fromcolor) can be either an array or a single color. If it is an array 350 // then we have two choices. It can either a) be a single color specified as an RGB triple or it can be 351 // an array to specify both (from, to style) for each individual bar. The way to know the difference is 352 // to investgate the first element. If this element is an integer [0,255] then we assume it is an RGB 353 // triple. 354 $ng = count($this->grad_fromcolor); 355 if( $ng === 3 ) { 356 if( is_numeric($this->grad_fromcolor[0]) && $this->grad_fromcolor[0] > 0 && $this->grad_fromcolor[0] < 256 ) { 357 // RGB Triple 358 $fromcolor = $this->grad_fromcolor; 359 $tocolor = $this->grad_tocolor; 360 $style = $this->grad_style; 361 } 362 } 363 else { 364 $fromcolor = $this->grad_fromcolor[$i % $ng][0]; 365 $tocolor = $this->grad_fromcolor[$i % $ng][1]; 366 $style = $this->grad_fromcolor[$i % $ng][2]; 367 } 368 $grad->FilledRectangle($pts[2],$pts[3], 369 $pts[6],$pts[7], 370 $fromcolor,$tocolor,$style); 371 } 372 else { 373 $grad->FilledRectangle($pts[2],$pts[3], 374 $pts[6],$pts[7], 375 $this->grad_fromcolor,$this->grad_tocolor,$this->grad_style); 376 } 377 } 378 elseif( !empty($this->fill_color) ) { 379 if(is_array($this->fill_color)) { 380 $img->PushColor($this->fill_color[$i % count($this->fill_color)]); 381 } else { 382 $img->PushColor($this->fill_color); 383 } 384 $img->FilledPolygon($pts); 385 $img->PopColor(); 386 } 387 388 389 // Remember value of this bar 390 $val=$this->coords[0][$i]; 391 392 if( !empty($val) && !is_numeric($val) ) { 393 JpGraphError::RaiseL(2004,$i,$val); 394 //'All values for a barplot must be numeric. You have specified value['.$i.'] == \''.$val.'\''); 395 } 396 397 // Determine the shadow 398 if( $this->bar_shadow && $val != 0) { 399 400 $ssh = $this->bar_shadow_hsize; 401 $ssv = $this->bar_shadow_vsize; 402 // Create points to create a "upper-right" shadow 403 if( $val > 0 ) { 404 $sp[0]=$pts[6]; $sp[1]=$pts[7]; 405 $sp[2]=$pts[4]; $sp[3]=$pts[5]; 406 $sp[4]=$pts[2]; $sp[5]=$pts[3]; 407 $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv; 408 $sp[8]=$pts[4]+$ssh; $sp[9]=$pts[5]-$ssv; 409 $sp[10]=$pts[6]+$ssh; $sp[11]=$pts[7]-$ssv; 410 } 411 elseif( $val < 0 ) { 412 $sp[0]=$pts[4]; $sp[1]=$pts[5]; 413 $sp[2]=$pts[6]; $sp[3]=$pts[7]; 414 $sp[4]=$pts[0]; $sp[5]=$pts[1]; 415 $sp[6]=$pts[0]+$ssh; $sp[7]=$pts[1]-$ssv; 416 $sp[8]=$pts[6]+$ssh; $sp[9]=$pts[7]-$ssv; 417 $sp[10]=$pts[4]+$ssh; $sp[11]=$pts[5]-$ssv; 418 } 419 if( is_array($this->bar_shadow_color) ) { 420 $numcolors = count($this->bar_shadow_color); 421 if( $numcolors == 0 ) { 422 JpGraphError::RaiseL(2005);//('You have specified an empty array for shadow colors in the bar plot.'); 423 } 424 $img->PushColor($this->bar_shadow_color[$i % $numcolors]); 425 } 426 else { 427 $img->PushColor($this->bar_shadow_color); 428 } 429 $img->FilledPolygon($sp); 430 $img->PopColor(); 431 } 432 433 // Stroke the pattern 434 if( is_array($this->iPattern) ) { 435 $f = new RectPatternFactory(); 436 if( is_array($this->iPatternColor) ) { 437 $pcolor = $this->iPatternColor[$i % $np]; 438 } 439 else 440 $pcolor = $this->iPatternColor; 441 $prect = $f->Create($this->iPattern[$i % $np],$pcolor,1); 442 $prect->SetDensity($this->iPatternDensity[$i % $np]); 443 444 if( $val < 0 ) { 445 $rx = $pts[0]; 446 $ry = $pts[1]; 447 } 448 else { 449 $rx = $pts[2]; 450 $ry = $pts[3]; 451 } 452 $width = abs($pts[4]-$pts[0])+1; 453 $height = abs($pts[1]-$pts[3])+1; 454 $prect->SetPos(new Rectangle($rx,$ry,$width,$height)); 455 $prect->Stroke($img); 456 } 457 else { 458 if( $this->iPattern > -1 ) { 459 $f = new RectPatternFactory(); 460 $prect = $f->Create($this->iPattern,$this->iPatternColor,1); 461 $prect->SetDensity($this->iPatternDensity); 462 if( $val < 0 ) { 463 $rx = $pts[0]; 464 $ry = $pts[1]; 465 } 466 else { 467 $rx = $pts[2]; 468 $ry = $pts[3]; 469 } 470 $width = abs($pts[4]-$pts[0])+1; 471 $height = abs($pts[1]-$pts[3])+1; 472 $prect->SetPos(new Rectangle($rx,$ry,$width,$height)); 473 $prect->Stroke($img); 474 } 475 } 476 // Stroke the outline of the bar 477 if( is_array($this->color) ) 478 $img->SetColor($this->color[$i % count($this->color)]); 479 else 480 $img->SetColor($this->color); 481 482 $pts[] = $pts[0]; 483 $pts[] = $pts[1]; 484 485 if( $this->weight > 0 ) { 486 $img->SetLineWeight($this->weight); 487 $img->Polygon($pts); 488 } 489 490 // Determine how to best position the values of the individual bars 491 $x=$pts[2]+($pts[4]-$pts[2])/2; 492 $this->value->SetMargin(5); 493 494 if( $this->valuepos=='top' ) { 495 $y=$pts[3]; 496 if( $img->a === 90 ) { 497 if( $val < 0 ) 498 $this->value->SetAlign('right','center'); 499 else 500 $this->value->SetAlign('left','center'); 501 502 } 503 else { 504 if( $val < 0 ) { 505 $this->value->SetMargin(-5); 506 $y=$pts[1]; 507 $this->value->SetAlign('center','bottom'); 508 } 509 else { 510 $this->value->SetAlign('center','bottom'); 511 } 512 513 } 514 $this->value->Stroke($img,$val,$x,$y); 515 } 516 elseif( $this->valuepos=='max' ) { 517 $y=$pts[3]; 518 if( $img->a === 90 ) { 519 if( $val < 0 ) 520 $this->value->SetAlign('left','center'); 521 else 522 $this->value->SetAlign('right','center'); 523 } 524 else { 525 if( $val < 0 ) { 526 $this->value->SetAlign('center','bottom'); 527 } 528 else { 529 $this->value->SetAlign('center','top'); 530 } 531 } 532 $this->value->SetMargin(-5); 533 $this->value->Stroke($img,$val,$x,$y); 534 } 535 elseif( $this->valuepos=='center' ) { 536 $y = ($pts[3] + $pts[1])/2; 537 $this->value->SetAlign('center','center'); 538 $this->value->SetMargin(0); 539 $this->value->Stroke($img,$val,$x,$y); 540 } 541 elseif( $this->valuepos=='bottom' || $this->valuepos=='min' ) { 542 $y=$pts[1]; 543 if( $img->a === 90 ) { 544 if( $val < 0 ) 545 $this->value->SetAlign('right','center'); 546 else 547 $this->value->SetAlign('left','center'); 548 } 549 $this->value->SetMargin(3); 550 $this->value->Stroke($img,$val,$x,$y); 551 } 552 else { 553 JpGraphError::RaiseL(2006,$this->valuepos); 554 //'Unknown position for values on bars :'.$this->valuepos); 555 } 556 // Create the client side image map 557 $rpts = $img->ArrRotate($pts); 558 $csimcoord=round($rpts[0]).", ".round($rpts[1]); 559 for( $j=1; $j < 4; ++$j){ 560 $csimcoord .= ", ".round($rpts[2*$j]).", ".round($rpts[2*$j+1]); 561 } 562 if( !empty($this->csimtargets[$i]) ) { 563 $this->csimareas .= '<area shape="poly" coords="'.$csimcoord.'" '; 564 $this->csimareas .= " href=\"".htmlentities($this->csimtargets[$i])."\""; 565 566 if( !empty($this->csimwintargets[$i]) ) { 567 $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; 568 } 569 570 $sval=''; 571 if( !empty($this->csimalts[$i]) ) { 572 $sval=sprintf($this->csimalts[$i],$this->coords[0][$i]); 573 $this->csimareas .= " title=\"$sval\" alt=\"$sval\" "; 574 } 575 $this->csimareas .= " />\n"; 576 } 577 } 578 return true; 672 579 } 673 580 } // Class … … 678 585 //=================================================== 679 586 class GroupBarPlot extends BarPlot { 680 public $plots; 681 private $nbrplots=0; 682 //--------------- 683 // CONSTRUCTOR 684 function __construct($plots) { 685 $this->width=0.7; 686 $this->plots = $plots; 687 $this->nbrplots = count($plots); 688 if( $this->nbrplots < 1 ) { 689 JpGraphError::RaiseL(2007);//('Cannot create GroupBarPlot from empty plot array.'); 690 } 691 for($i=0; $i < $this->nbrplots; ++$i ) { 692 if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) { 693 JpGraphError::RaiseL(2008,$i);//("Group bar plot element nbr $i is undefined or empty."); 694 } 695 } 696 $this->numpoints = $plots[0]->numpoints; 697 $this->width=0.7; 698 } 699 700 //--------------- 701 // PUBLIC METHODS 587 private $plots, $nbrplots=0; 588 //--------------- 589 // CONSTRUCTOR 590 function GroupBarPlot($plots) { 591 $this->width=0.7; 592 $this->plots = $plots; 593 $this->nbrplots = count($plots); 594 if( $this->nbrplots < 1 ) { 595 JpGraphError::RaiseL(2007);//('Cannot create GroupBarPlot from empty plot array.'); 596 } 597 for($i=0; $i < $this->nbrplots; ++$i ) { 598 if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) { 599 JpGraphError::RaiseL(2008,$i);//("Group bar plot element nbr $i is undefined or empty."); 600 } 601 } 602 $this->numpoints = $plots[0]->numpoints; 603 $this->width=0.7; 604 } 605 606 //--------------- 607 // PUBLIC METHODS 702 608 function Legend($graph) { 703 704 705 706 707 708 709 710 711 712 } 713 609 $n = count($this->plots); 610 for($i=0; $i < $n; ++$i) { 611 $c = get_class($this->plots[$i]); 612 if( !($this->plots[$i] instanceof BarPlot) ) { 613 JpGraphError::RaiseL(2009,$c); 614 //('One of the objects submitted to GroupBar is not a BarPlot. Make sure that you create the Group Bar plot from an array of BarPlot or AccBarPlot objects. (Class = '.$c.')'); 615 } 616 $this->plots[$i]->DoLegend($graph); 617 } 618 } 619 714 620 function Min() { 715 716 717 718 719 720 721 722 return array($xmin,$ymin); 723 } 724 621 list($xmin,$ymin) = $this->plots[0]->Min(); 622 $n = count($this->plots); 623 for($i=0; $i < $n; ++$i) { 624 list($xm,$ym) = $this->plots[$i]->Min(); 625 $xmin = max($xmin,$xm); 626 $ymin = min($ymin,$ym); 627 } 628 return array($xmin,$ymin); 629 } 630 725 631 function Max() { 726 727 728 729 730 731 732 733 734 } 735 632 list($xmax,$ymax) = $this->plots[0]->Max(); 633 $n = count($this->plots); 634 for($i=0; $i < $n; ++$i) { 635 list($xm,$ym) = $this->plots[$i]->Max(); 636 $xmax = max($xmax,$xm); 637 $ymax = max($ymax,$ym); 638 } 639 return array($xmax,$ymax); 640 } 641 736 642 function GetCSIMareas() { 737 738 739 740 741 742 743 } 744 643 $n = count($this->plots); 644 $csimareas=''; 645 for($i=0; $i < $n; ++$i) { 646 $csimareas .= $this->plots[$i]->csimareas; 647 } 648 return $csimareas; 649 } 650 745 651 // Stroke all the bars next to each other 746 function Stroke($img,$xscale,$yscale) { 747 748 749 $subwidth = $this->width/$this->nbrplots ; 750 751 752 753 754 755 756 757 758 759 760 761 762 763 652 function Stroke($img,$xscale,$yscale) { 653 $tmp=$xscale->off; 654 $n = count($this->plots); 655 $subwidth = $this->width/$this->nbrplots ; 656 657 for( $i=0; $i < $n; ++$i ) { 658 $this->plots[$i]->ymin=$this->ybase; 659 $this->plots[$i]->SetWidth($subwidth); 660 661 // If the client have used SetTextTickInterval() then 662 // major_step will be > 1 and the positioning will fail. 663 // If we assume it is always one the positioning will work 664 // fine with a text scale but this will not work with 665 // arbitrary linear scale 666 $xscale->off = $tmp+$i*round($xscale->scale_factor* $subwidth); 667 $this->plots[$i]->Stroke($img,$xscale,$yscale); 668 } 669 $xscale->off=$tmp; 764 670 } 765 671 } // Class … … 770 676 //=================================================== 771 677 class AccBarPlot extends BarPlot { 772 public $plots=null; 773 private $nbrplots=0; 774 //--------------- 775 // CONSTRUCTOR 776 function __construct($plots) { 777 $this->plots = $plots; 778 $this->nbrplots = count($plots); 779 if( $this->nbrplots < 1 ) { 780 JpGraphError::RaiseL(2010);//('Cannot create AccBarPlot from empty plot array.'); 781 } 782 for($i=0; $i < $this->nbrplots; ++$i ) { 783 if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) { 784 JpGraphError::RaiseL(2011,$i);//("Acc bar plot element nbr $i is undefined or empty."); 785 } 786 } 787 788 // We can only allow individual plost which do not have specified X-positions 789 for($i=0; $i < $this->nbrplots; ++$i ) { 790 if( !empty($this->plots[$i]->coords[1]) ) { 791 JpGraphError::RaiseL(2015); 792 //'Individual bar plots in an AccBarPlot or GroupBarPlot can not have specified X-positions.'); 793 } 794 } 795 796 // Use 0 weight by default which means that the individual bar 797 // weights will be used per part n the accumulated bar 798 $this->SetWeight(0); 799 800 $this->numpoints = $plots[0]->numpoints; 801 $this->value = new DisplayValue(); 802 } 803 804 //--------------- 805 // PUBLIC METHODS 678 private $plots=null,$nbrplots=0; 679 //--------------- 680 // CONSTRUCTOR 681 function AccBarPlot($plots) { 682 $this->plots = $plots; 683 $this->nbrplots = count($plots); 684 if( $this->nbrplots < 1 ) { 685 JpGraphError::RaiseL(2010);//('Cannot create AccBarPlot from empty plot array.'); 686 } 687 for($i=0; $i < $this->nbrplots; ++$i ) { 688 if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) { 689 JpGraphError::RaiseL(2011,$i);//("Acc bar plot element nbr $i is undefined or empty."); 690 } 691 } 692 693 // We can only allow individual plost which do not have specified X-positions 694 for($i=0; $i < $this->nbrplots; ++$i ) { 695 if( !empty($this->plots[$i]->coords[1]) ) { 696 JpGraphError::RaiseL(2015); 697 //'Individual bar plots in an AccBarPlot or GroupBarPlot can not have specified X-positions.'); 698 } 699 } 700 701 $this->numpoints = $plots[0]->numpoints; 702 $this->value = new DisplayValue(); 703 } 704 705 //--------------- 706 // PUBLIC METHODS 806 707 function Legend($graph) { 807 808 809 810 811 812 813 } 814 815 708 $n = count($this->plots); 709 for( $i=$n-1; $i >= 0; --$i ) { 710 $c = get_class($this->plots[$i]); 711 if( !($this->plots[$i] instanceof BarPlot) ) { 712 JpGraphError::RaiseL(2012,$c); 713 //('One of the objects submitted to AccBar is not a BarPlot. Make sure that you create the AccBar plot from an array of BarPlot objects.(Class='.$c.')'); 714 } 715 $this->plots[$i]->DoLegend($graph); 716 } 816 717 } 817 718 818 719 function Max() { 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 if( $ymax <= $this->ybase ) 852 853 720 list($xmax) = $this->plots[0]->Max(); 721 $nmax=0; 722 for($i=0; $i < count($this->plots); ++$i) { 723 $n = count($this->plots[$i]->coords[0]); 724 $nmax = max($nmax,$n); 725 list($x) = $this->plots[$i]->Max(); 726 $xmax = max($xmax,$x); 727 } 728 for( $i = 0; $i < $nmax; $i++ ) { 729 // Get y-value for bar $i by adding the 730 // individual bars from all the plots added. 731 // It would be wrong to just add the 732 // individual plots max y-value since that 733 // would in most cases give to large y-value. 734 $y=0; 735 if( !isset($this->plots[0]->coords[0][$i]) ) { 736 JpGraphError::RaiseL(2014); 737 } 738 if( $this->plots[0]->coords[0][$i] > 0 ) 739 $y=$this->plots[0]->coords[0][$i]; 740 for( $j = 1; $j < $this->nbrplots; $j++ ) { 741 if( !isset($this->plots[$j]->coords[0][$i]) ) { 742 JpGraphError::RaiseL(2014); 743 } 744 if( $this->plots[$j]->coords[0][$i] > 0 ) 745 $y += $this->plots[$j]->coords[0][$i]; 746 } 747 $ymax[$i] = $y; 748 } 749 $ymax = max($ymax); 750 751 // Bar always start at baseline 752 if( $ymax <= $this->ybase ) 753 $ymax = $this->ybase; 754 return array($xmax,$ymax); 854 755 } 855 756 856 757 function Min() { 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 758 $nmax=0; 759 list($xmin,$ysetmin) = $this->plots[0]->Min(); 760 for($i=0; $i < count($this->plots); ++$i) { 761 $n = count($this->plots[$i]->coords[0]); 762 $nmax = max($nmax,$n); 763 list($x,$y) = $this->plots[$i]->Min(); 764 $xmin = Min($xmin,$x); 765 $ysetmin = Min($y,$ysetmin); 766 } 767 for( $i = 0; $i < $nmax; $i++ ) { 768 // Get y-value for bar $i by adding the 769 // individual bars from all the plots added. 770 // It would be wrong to just add the 771 // individual plots max y-value since that 772 // would in most cases give to large y-value. 773 $y=0; 774 if( $this->plots[0]->coords[0][$i] < 0 ) 775 $y=$this->plots[0]->coords[0][$i]; 776 for( $j = 1; $j < $this->nbrplots; $j++ ) { 777 if( $this->plots[$j]->coords[0][$i] < 0 ) 778 $y += $this->plots[ $j ]->coords[0][$i]; 779 } 780 $ymin[$i] = $y; 781 } 782 $ymin = Min($ysetmin,Min($ymin)); 783 // Bar always start at baseline 784 if( $ymin >= $this->ybase ) 785 $ymin = $this->ybase; 786 return array($xmin,$ymin); 886 787 } 887 788 888 789 // Stroke acc bar plot 889 790 function Stroke($img,$xscale,$yscale) { 890 $pattern=NULL; 891 $img->SetLineWeight($this->weight); 892 $grad=null; 893 for($i=0; $i < $this->numpoints-1; $i++) { 894 $accy = 0; 895 $accy_neg = 0; 896 for($j=0; $j < $this->nbrplots; ++$j ) { 897 $img->SetColor($this->plots[$j]->color); 898 899 if ( $this->plots[$j]->coords[0][$i] >= 0) { 900 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy); 901 $accyt=$yscale->Translate($accy); 902 $accy+=$this->plots[$j]->coords[0][$i]; 903 } 904 else { 905 //if ( $this->plots[$j]->coords[0][$i] < 0 || $accy_neg < 0 ) { 906 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg); 907 $accyt=$yscale->Translate($accy_neg); 908 $accy_neg+=$this->plots[$j]->coords[0][$i]; 909 } 910 911 $xt=$xscale->Translate($i); 912 913 if( $this->abswidth > -1 ) { 914 $abswidth=$this->abswidth; 915 } 916 else { 917 $abswidth=round($this->width*$xscale->scale_factor,0); 918 } 919 920 $pts=array($xt,$accyt,$xt,$yt,$xt+$abswidth,$yt,$xt+$abswidth,$accyt); 921 922 if( $this->bar_shadow ) { 923 $ssh = $this->bar_shadow_hsize; 924 $ssv = $this->bar_shadow_vsize; 925 926 // We must also differ if we are a positive or negative bar. 927 if( $j === 0 ) { 928 // This gets extra complicated since we have to 929 // see all plots to see if we are negative. It could 930 // for example be that all plots are 0 until the very 931 // last one. We therefore need to save the initial setup 932 // for both the negative and positive case 933 934 // In case the final bar is positive 935 $sp[0]=$pts[6]+1; $sp[1]=$pts[7]; 936 $sp[2]=$pts[6]+$ssh; $sp[3]=$pts[7]-$ssv; 937 938 // In case the final bar is negative 939 $nsp[0]=$pts[0]; $nsp[1]=$pts[1]; 940 $nsp[2]=$pts[0]+$ssh; $nsp[3]=$pts[1]-$ssv; 941 $nsp[4]=$pts[6]+$ssh; $nsp[5]=$pts[7]-$ssv; 942 $nsp[10]=$pts[6]+1; $nsp[11]=$pts[7]; 943 } 944 945 if( $j === $this->nbrplots-1 ) { 946 // If this is the last plot of the bar and 947 // the total value is larger than 0 then we 948 // add the shadow. 949 if( is_array($this->bar_shadow_color) ) { 950 $numcolors = count($this->bar_shadow_color); 951 if( $numcolors == 0 ) { 952 JpGraphError::RaiseL(2013);//('You have specified an empty array for shadow colors in the bar plot.'); 953 } 954 $img->PushColor($this->bar_shadow_color[$i % $numcolors]); 955 } 956 else { 957 $img->PushColor($this->bar_shadow_color); 958 } 959 960 if( $accy > 0 ) { 961 $sp[4]=$pts[4]+$ssh; $sp[5]=$pts[5]-$ssv; 962 $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv; 963 $sp[8]=$pts[2]; $sp[9]=$pts[3]-1; 964 $sp[10]=$pts[4]+1; $sp[11]=$pts[5]; 965 $img->FilledPolygon($sp,4); 966 } 967 elseif( $accy_neg < 0 ) { 968 $nsp[6]=$pts[4]+$ssh; $nsp[7]=$pts[5]-$ssv; 969 $nsp[8]=$pts[4]+1; $nsp[9]=$pts[5]; 970 $img->FilledPolygon($nsp,4); 971 } 972 $img->PopColor(); 973 } 974 } 975 976 977 // If value is NULL or 0, then don't draw a bar at all 978 if ($this->plots[$j]->coords[0][$i] == 0 ) continue; 979 980 if( $this->plots[$j]->grad ) { 981 if( $grad === null ) { 982 $grad = new Gradient($img); 983 } 984 if( is_array($this->plots[$j]->grad_fromcolor) ) { 985 // The first argument (grad_fromcolor) can be either an array or a single color. If it is an array 986 // then we have two choices. It can either a) be a single color specified as an RGB triple or it can be 987 // an array to specify both (from, to style) for each individual bar. The way to know the difference is 988 // to investgate the first element. If this element is an integer [0,255] then we assume it is an RGB 989 // triple. 990 $ng = count($this->plots[$j]->grad_fromcolor); 991 if( $ng === 3 ) { 992 if( is_numeric($this->plots[$j]->grad_fromcolor[0]) && $this->plots[$j]->grad_fromcolor[0] > 0 && 993 $this->plots[$j]->grad_fromcolor[0] < 256 ) { 994 // RGB Triple 995 $fromcolor = $this->plots[$j]->grad_fromcolor; 996 $tocolor = $this->plots[$j]->grad_tocolor; 997 $style = $this->plots[$j]->grad_style; 998 } 999 else { 1000 $fromcolor = $this->plots[$j]->grad_fromcolor[$i % $ng][0]; 1001 $tocolor = $this->plots[$j]->grad_fromcolor[$i % $ng][1]; 1002 $style = $this->plots[$j]->grad_fromcolor[$i % $ng][2]; 1003 } 1004 } 1005 else { 1006 $fromcolor = $this->plots[$j]->grad_fromcolor[$i % $ng][0]; 1007 $tocolor = $this->plots[$j]->grad_fromcolor[$i % $ng][1]; 1008 $style = $this->plots[$j]->grad_fromcolor[$i % $ng][2]; 1009 } 1010 $grad->FilledRectangle($pts[2],$pts[3], 1011 $pts[6],$pts[7], 1012 $fromcolor,$tocolor,$style); 1013 } 1014 else { 1015 $grad->FilledRectangle($pts[2],$pts[3], 1016 $pts[6],$pts[7], 1017 $this->plots[$j]->grad_fromcolor, 1018 $this->plots[$j]->grad_tocolor, 1019 $this->plots[$j]->grad_style); 1020 } 1021 } else { 1022 if (is_array($this->plots[$j]->fill_color) ) { 1023 $numcolors = count($this->plots[$j]->fill_color); 1024 $fillcolor = $this->plots[$j]->fill_color[$i % $numcolors]; 1025 // If the bar is specified to be non filled then the fill color is false 1026 if( $fillcolor !== false ) { 1027 $img->SetColor($this->plots[$j]->fill_color[$i % $numcolors]); 1028 } 1029 } 1030 else { 1031 $fillcolor = $this->plots[$j]->fill_color; 1032 if( $fillcolor !== false ) { 1033 $img->SetColor($this->plots[$j]->fill_color); 1034 } 1035 } 1036 if( $fillcolor !== false ) { 1037 $img->FilledPolygon($pts); 1038 } 1039 } 1040 1041 $img->SetColor($this->plots[$j]->color); 1042 1043 // Stroke the pattern 1044 if( $this->plots[$j]->iPattern > -1 ) { 1045 if( $pattern===NULL ) { 1046 $pattern = new RectPatternFactory(); 1047 } 1048 1049 $prect = $pattern->Create($this->plots[$j]->iPattern,$this->plots[$j]->iPatternColor,1); 1050 $prect->SetDensity($this->plots[$j]->iPatternDensity); 1051 if( $this->plots[$j]->coords[0][$i] < 0 ) { 1052 $rx = $pts[0]; 1053 $ry = $pts[1]; 1054 } 1055 else { 1056 $rx = $pts[2]; 1057 $ry = $pts[3]; 1058 } 1059 $width = abs($pts[4]-$pts[0])+1; 1060 $height = abs($pts[1]-$pts[3])+1; 1061 $prect->SetPos(new Rectangle($rx,$ry,$width,$height)); 1062 $prect->Stroke($img); 1063 } 1064 1065 1066 // CSIM array 1067 1068 if( $i < count($this->plots[$j]->csimtargets) ) { 1069 // Create the client side image map 1070 $rpts = $img->ArrRotate($pts); 1071 $csimcoord=round($rpts[0]).", ".round($rpts[1]); 1072 for( $k=1; $k < 4; ++$k){ 1073 $csimcoord .= ", ".round($rpts[2*$k]).", ".round($rpts[2*$k+1]); 1074 } 1075 if( ! empty($this->plots[$j]->csimtargets[$i]) ) { 1076 $this->csimareas.= '<area shape="poly" coords="'.$csimcoord.'" '; 1077 $this->csimareas.= " href=\"".$this->plots[$j]->csimtargets[$i]."\" "; 1078 1079 if( ! empty($this->plots[$j]->csimwintargets[$i]) ) { 1080 $this->csimareas.= " target=\"".$this->plots[$j]->csimwintargets[$i]."\" "; 1081 } 1082 1083 $sval=''; 1084 if( !empty($this->plots[$j]->csimalts[$i]) ) { 1085 $sval=sprintf($this->plots[$j]->csimalts[$i],$this->plots[$j]->coords[0][$i]); 1086 $this->csimareas .= " title=\"$sval\" "; 1087 } 1088 $this->csimareas .= " alt=\"$sval\" />\n"; 1089 } 1090 } 1091 1092 $pts[] = $pts[0]; 1093 $pts[] = $pts[1]; 1094 $img->SetLineWeight($this->plots[$j]->weight); 1095 $img->Polygon($pts); 1096 $img->SetLineWeight(1); 1097 } 1098 1099 // Daw potential bar around the entire accbar bar 1100 if( $this->weight > 0 ) { 1101 $y=$yscale->Translate(0); 1102 $img->SetColor($this->color); 1103 $img->SetLineWeight($this->weight); 1104 $img->Rectangle($pts[0],$y,$pts[6],$pts[5]); 1105 } 1106 1107 // Draw labels for each acc.bar 1108 1109 $x=$pts[2]+($pts[4]-$pts[2])/2; 1110 if($this->bar_shadow) $x += $ssh; 1111 1112 // First stroke the accumulated value for the entire bar 1113 // This value is always placed at the top/bottom of the bars 1114 if( $accy + $accy_neg < 0 ) { 1115 $y=$yscale->Translate($accy_neg); 1116 } 1117 else { 1118 $y=$yscale->Translate($accy); 1119 } 1120 $this->value->Stroke($img,$accy + $accy_neg,$x,$y); 1121 1122 $accy = 0; 1123 $accy_neg = 0; 1124 for($j=0; $j < $this->nbrplots; ++$j ) { 1125 1126 // We don't print 0 values in an accumulated bar plot 1127 if( $this->plots[$j]->coords[0][$i] == 0 ) continue; 1128 1129 if ($this->plots[$j]->coords[0][$i] > 0) { 1130 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy); 1131 $accyt=$yscale->Translate($accy); 1132 if( $this->plots[$j]->valuepos=='center' ) { 1133 $y = $accyt-($accyt-$yt)/2; 1134 } 1135 elseif( $this->plots[$j]->valuepos=='bottom' ) { 1136 $y = $accyt; 1137 } 1138 else { // top or max 1139 $y = $accyt-($accyt-$yt); 1140 } 1141 $accy+=$this->plots[$j]->coords[0][$i]; 1142 if( $this->plots[$j]->valuepos=='center' ) { 1143 $this->plots[$j]->value->SetAlign("center","center"); 1144 $this->plots[$j]->value->SetMargin(0); 1145 } 1146 elseif( $this->plots[$j]->valuepos=='bottom' ) { 1147 $this->plots[$j]->value->SetAlign('center','bottom'); 1148 $this->plots[$j]->value->SetMargin(2); 1149 } 1150 else { 1151 $this->plots[$j]->value->SetAlign('center','top'); 1152 $this->plots[$j]->value->SetMargin(1); 1153 } 1154 } else { 1155 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg); 1156 $accyt=$yscale->Translate($accy_neg); 1157 $accy_neg+=$this->plots[$j]->coords[0][$i]; 1158 if( $this->plots[$j]->valuepos=='center' ) { 1159 $y = $accyt-($accyt-$yt)/2; 1160 } 1161 elseif( $this->plots[$j]->valuepos=='bottom' ) { 1162 $y = $accyt; 1163 } 1164 else { 1165 $y = $accyt-($accyt-$yt); 1166 } 1167 if( $this->plots[$j]->valuepos=='center' ) { 1168 $this->plots[$j]->value->SetAlign("center","center"); 1169 $this->plots[$j]->value->SetMargin(0); 1170 } 1171 elseif( $this->plots[$j]->valuepos=='bottom' ) { 1172 $this->plots[$j]->value->SetAlign('center',$j==0 ? 'bottom':'top'); 1173 $this->plots[$j]->value->SetMargin(-2); 1174 } 1175 else { 1176 $this->plots[$j]->value->SetAlign('center','bottom'); 1177 $this->plots[$j]->value->SetMargin(-1); 1178 } 1179 } 1180 $this->plots[$j]->value->Stroke($img,$this->plots[$j]->coords[0][$i],round($x),round($y)); 1181 } 1182 1183 } 1184 return true; 791 $pattern=NULL; 792 $img->SetLineWeight($this->weight); 793 for($i=0; $i < $this->numpoints-1; $i++) { 794 $accy = 0; 795 $accy_neg = 0; 796 for($j=0; $j < $this->nbrplots; ++$j ) { 797 $img->SetColor($this->plots[$j]->color); 798 799 if ( $this->plots[$j]->coords[0][$i] >= 0) { 800 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy); 801 $accyt=$yscale->Translate($accy); 802 $accy+=$this->plots[$j]->coords[0][$i]; 803 } 804 else { 805 //if ( $this->plots[$j]->coords[0][$i] < 0 || $accy_neg < 0 ) { 806 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg); 807 $accyt=$yscale->Translate($accy_neg); 808 $accy_neg+=$this->plots[$j]->coords[0][$i]; 809 } 810 811 $xt=$xscale->Translate($i); 812 813 if( $this->abswidth > -1 ) 814 $abswidth=$this->abswidth; 815 else 816 $abswidth=round($this->width*$xscale->scale_factor,0); 817 818 $pts=array($xt,$accyt,$xt,$yt,$xt+$abswidth,$yt,$xt+$abswidth,$accyt); 819 820 if( $this->bar_shadow ) { 821 $ssh = $this->bar_shadow_hsize; 822 $ssv = $this->bar_shadow_vsize; 823 824 // We must also differ if we are a positive or negative bar. 825 if( $j === 0 ) { 826 // This gets extra complicated since we have to 827 // see all plots to see if we are negative. It could 828 // for example be that all plots are 0 until the very 829 // last one. We therefore need to save the initial setup 830 // for both the negative and positive case 831 832 // In case the final bar is positive 833 $sp[0]=$pts[6]+1; $sp[1]=$pts[7]; 834 $sp[2]=$pts[6]+$ssh; $sp[3]=$pts[7]-$ssv; 835 836 // In case the final bar is negative 837 $nsp[0]=$pts[0]; $nsp[1]=$pts[1]; 838 $nsp[2]=$pts[0]+$ssh; $nsp[3]=$pts[1]-$ssv; 839 $nsp[4]=$pts[6]+$ssh; $nsp[5]=$pts[7]-$ssv; 840 $nsp[10]=$pts[6]+1; $nsp[11]=$pts[7]; 841 } 842 843 if( $j === $this->nbrplots-1 ) { 844 // If this is the last plot of the bar and 845 // the total value is larger than 0 then we 846 // add the shadow. 847 if( is_array($this->bar_shadow_color) ) { 848 $numcolors = count($this->bar_shadow_color); 849 if( $numcolors == 0 ) { 850 JpGraphError::RaiseL(2013);//('You have specified an empty array for shadow colors in the bar plot.'); 851 } 852 $img->PushColor($this->bar_shadow_color[$i % $numcolors]); 853 } 854 else { 855 $img->PushColor($this->bar_shadow_color); 856 } 857 858 if( $accy > 0 ) { 859 $sp[4]=$pts[4]+$ssh; $sp[5]=$pts[5]-$ssv; 860 $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv; 861 $sp[8]=$pts[2]; $sp[9]=$pts[3]-1; 862 $sp[10]=$pts[4]+1; $sp[11]=$pts[5]; 863 $img->FilledPolygon($sp,4); 864 } 865 elseif( $accy_neg < 0 ) { 866 $nsp[6]=$pts[4]+$ssh; $nsp[7]=$pts[5]-$ssv; 867 $nsp[8]=$pts[4]+1; $nsp[9]=$pts[5]; 868 $img->FilledPolygon($nsp,4); 869 } 870 $img->PopColor(); 871 } 872 } 873 874 875 // If value is NULL or 0, then don't draw a bar at all 876 if ($this->plots[$j]->coords[0][$i] == 0 ) continue; 877 878 if( $this->plots[$j]->grad ) { 879 $grad = new Gradient($img); 880 $grad->FilledRectangle( 881 $pts[2],$pts[3], 882 $pts[6],$pts[7], 883 $this->plots[$j]->grad_fromcolor, 884 $this->plots[$j]->grad_tocolor, 885 $this->plots[$j]->grad_style); 886 } else { 887 if (is_array($this->plots[$j]->fill_color) ) { 888 $numcolors = count($this->plots[$j]->fill_color); 889 $fillcolor = $this->plots[$j]->fill_color[$i % $numcolors]; 890 // If the bar is specified to be non filled then the fill color is false 891 if( $fillcolor !== false ) 892 $img->SetColor($this->plots[$j]->fill_color[$i % $numcolors]); 893 } 894 else { 895 $fillcolor = $this->plots[$j]->fill_color; 896 if( $fillcolor !== false ) 897 $img->SetColor($this->plots[$j]->fill_color); 898 } 899 if( $fillcolor !== false ) 900 $img->FilledPolygon($pts); 901 $img->SetColor($this->plots[$j]->color); 902 } 903 904 // Stroke the pattern 905 if( $this->plots[$j]->iPattern > -1 ) { 906 if( $pattern===NULL ) 907 $pattern = new RectPatternFactory(); 908 909 $prect = $pattern->Create($this->plots[$j]->iPattern,$this->plots[$j]->iPatternColor,1); 910 $prect->SetDensity($this->plots[$j]->iPatternDensity); 911 if( $this->plots[$j]->coords[0][$i] < 0 ) { 912 $rx = $pts[0]; 913 $ry = $pts[1]; 914 } 915 else { 916 $rx = $pts[2]; 917 $ry = $pts[3]; 918 } 919 $width = abs($pts[4]-$pts[0])+1; 920 $height = abs($pts[1]-$pts[3])+1; 921 $prect->SetPos(new Rectangle($rx,$ry,$width,$height)); 922 $prect->Stroke($img); 923 } 924 925 926 // CSIM array 927 928 if( $i < count($this->plots[$j]->csimtargets) ) { 929 // Create the client side image map 930 $rpts = $img->ArrRotate($pts); 931 $csimcoord=round($rpts[0]).", ".round($rpts[1]); 932 for( $k=1; $k < 4; ++$k){ 933 $csimcoord .= ", ".round($rpts[2*$k]).", ".round($rpts[2*$k+1]); 934 } 935 if( ! empty($this->plots[$j]->csimtargets[$i]) ) { 936 $this->csimareas.= '<area shape="poly" coords="'.$csimcoord.'" '; 937 $this->csimareas.= " href=\"".$this->plots[$j]->csimtargets[$i]."\" "; 938 939 if( ! empty($this->plots[$j]->csimwintargets[$i]) ) { 940 $this->csimareas.= " target=\"".$this->plots[$j]->csimwintargets[$i]."\" "; 941 } 942 943 $sval=''; 944 if( !empty($this->plots[$j]->csimalts[$i]) ) { 945 $sval=sprintf($this->plots[$j]->csimalts[$i],$this->plots[$j]->coords[0][$i]); 946 $this->csimareas .= " title=\"$sval\" "; 947 } 948 $this->csimareas .= " alt=\"$sval\" />\n"; 949 } 950 } 951 952 $pts[] = $pts[0]; 953 $pts[] = $pts[1]; 954 $img->SetLineWeight($this->plots[$j]->line_weight); 955 $img->Polygon($pts); 956 $img->SetLineWeight(1); 957 } 958 959 // Draw labels for each acc.bar 960 961 $x=$pts[2]+($pts[4]-$pts[2])/2; 962 if($this->bar_shadow) $x += $ssh; 963 964 // First stroke the accumulated value for the entire bar 965 // This value is always placed at the top/bottom of the bars 966 if( $accy_neg < 0 ) { 967 $y=$yscale->Translate($accy_neg); 968 $this->value->Stroke($img,$accy_neg,$x,$y); 969 } 970 else { 971 $y=$yscale->Translate($accy); 972 $this->value->Stroke($img,$accy,$x,$y); 973 } 974 975 $accy = 0; 976 $accy_neg = 0; 977 for($j=0; $j < $this->nbrplots; ++$j ) { 978 979 // We don't print 0 values in an accumulated bar plot 980 if( $this->plots[$j]->coords[0][$i] == 0 ) continue; 981 982 if ($this->plots[$j]->coords[0][$i] > 0) { 983 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy); 984 $accyt=$yscale->Translate($accy); 985 if( $this->plots[$j]->valuepos=='center' ) { 986 $y = $accyt-($accyt-$yt)/2; 987 } 988 elseif( $this->plots[$j]->valuepos=='bottom' ) { 989 $y = $accyt; 990 } 991 else { // top or max 992 $y = $accyt-($accyt-$yt); 993 } 994 $accy+=$this->plots[$j]->coords[0][$i]; 995 if( $this->plots[$j]->valuepos=='center' ) { 996 $this->plots[$j]->value->SetAlign("center","center"); 997 $this->plots[$j]->value->SetMargin(0); 998 } 999 elseif( $this->plots[$j]->valuepos=='bottom' ) { 1000 $this->plots[$j]->value->SetAlign('center','bottom'); 1001 $this->plots[$j]->value->SetMargin(2); 1002 } 1003 else { 1004 $this->plots[$j]->value->SetAlign('center','top'); 1005 $this->plots[$j]->value->SetMargin(1); 1006 } 1007 } else { 1008 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg); 1009 $accyt=$yscale->Translate($accy_neg); 1010 $accy_neg+=$this->plots[$j]->coords[0][$i]; 1011 if( $this->plots[$j]->valuepos=='center' ) { 1012 $y = $accyt-($accyt-$yt)/2; 1013 } 1014 elseif( $this->plots[$j]->valuepos=='bottom' ) { 1015 $y = $accyt; 1016 } 1017 else { 1018 $y = $accyt-($accyt-$yt); 1019 } 1020 if( $this->plots[$j]->valuepos=='center' ) { 1021 $this->plots[$j]->value->SetAlign("center","center"); 1022 $this->plots[$j]->value->SetMargin(0); 1023 } 1024 elseif( $this->plots[$j]->valuepos=='bottom' ) { 1025 $this->plots[$j]->value->SetAlign('center',$j==0 ? 'bottom':'top'); 1026 $this->plots[$j]->value->SetMargin(-2); 1027 } 1028 else { 1029 $this->plots[$j]->value->SetAlign('center','bottom'); 1030 $this->plots[$j]->value->SetMargin(-1); 1031 } 1032 } 1033 $this->plots[$j]->value->Stroke($img,$this->plots[$j]->coords[0][$i],$x,$y); 1034 } 1035 1036 } 1037 return true; 1185 1038 } 1186 1039 } // Class
Note:
See TracChangeset
for help on using the changeset viewer.