Changeset 284 for trunk/client/modules/Elezioni/grafici/jpgraph_line.php
- Timestamp:
- Apr 21, 2019, 11:49:56 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/client/modules/Elezioni/grafici/jpgraph_line.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_LINE.PHP4 // Description:Line plot extension for JpGraph5 // Created:2001-01-086 // Ver: $Id: jpgraph_line.php 981 2008-03-24 11:51:12Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */3 // File: JPGRAPH_LINE.PHP 4 // Description: Line plot extension for JpGraph 5 // Created: 2001-01-08 6 // Ver: $Id: jpgraph_line.php 1921 2009-12-11 11:46:39Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 require_once ('jpgraph_plotmark.inc.php'); … … 20 20 //=================================================== 21 21 // CLASS LinePlot 22 // Description: 22 // Description: 23 23 //=================================================== 24 24 class LinePlot extends Plot{ … … 27 27 protected $fill_color='blue'; 28 28 protected $step_style=false, $center=false; 29 protected $line_style=1; 29 protected $line_style=1; // Default to solid 30 30 protected $filledAreas = array(); // array of arrays(with min,max,col,filled in them) 31 31 public $barcenter=false; // When we mix line and bar. Should we center the line in the bar. 32 protected $fillFromMin = false 32 protected $fillFromMin = false, $fillFromMax = false; 33 33 protected $fillgrad=false,$fillgrad_fromcolor='navy',$fillgrad_tocolor='silver',$fillgrad_numcolors=100; 34 34 protected $iFastStroke=false; 35 35 36 //--------------- 37 // CONSTRUCTOR 38 function LinePlot($datay,$datax=false) { 39 $this->Plot($datay,$datax); 40 $this->mark = new PlotMark() ; 41 } 42 //--------------- 43 // PUBLIC METHODS 44 45 // Set style, filled or open 46 function SetFilled($aFlag=true) { 47 JpGraphError::RaiseL(10001);//('LinePlot::SetFilled() is deprecated. Use SetFillColor()'); 48 } 49 36 //--------------- 37 // CONSTRUCTOR 38 function __construct($datay,$datax=false) { 39 parent::__construct($datay,$datax); 40 $this->mark = new PlotMark() ; 41 $this->color = ColorFactory::getColor(); 42 $this->fill_color = $this->color; 43 } 44 //--------------- 45 // PUBLIC METHODS 46 47 function SetFilled($aFlg=true) { 48 $this->filled = $aFlg; 49 } 50 50 51 function SetBarCenter($aFlag=true) { 51 52 $this->barcenter=$aFlag; 52 53 } 53 54 54 55 function SetStyle($aStyle) { 55 56 } 57 56 $this->line_style=$aStyle; 57 } 58 58 59 function SetStepStyle($aFlag=true) { 59 60 } 61 60 $this->step_style = $aFlag; 61 } 62 62 63 function SetColor($aColor) { 63 64 } 65 64 parent::SetColor($aColor); 65 } 66 66 67 function SetFillFromYMin($f=true) { 67 $this->fillFromMin = $f ; 68 } 69 68 $this->fillFromMin = $f ; 69 } 70 71 function SetFillFromYMax($f=true) { 72 $this->fillFromMax = $f ; 73 } 74 70 75 function SetFillColor($aColor,$aFilled=true) { 71 $this->fill_color=$aColor; 72 $this->filled=$aFilled; 76 //$this->color = $aColor; 77 $this->fill_color=$aColor; 78 $this->filled=$aFilled; 73 79 } 74 80 75 81 function SetFillGradient($aFromColor,$aToColor,$aNumColors=100,$aFilled=true) { 76 77 78 79 80 81 } 82 82 $this->fillgrad_fromcolor = $aFromColor; 83 $this->fillgrad_tocolor = $aToColor; 84 $this->fillgrad_numcolors = $aNumColors; 85 $this->filled = $aFilled; 86 $this->fillgrad = true; 87 } 88 83 89 function Legend($graph) { 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 } 90 if( $this->legend!="" ) { 91 if( $this->filled && !$this->fillgrad ) { 92 $graph->legend->Add($this->legend, 93 $this->fill_color,$this->mark,0, 94 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 95 } 96 elseif( $this->fillgrad ) { 97 $color=array($this->fillgrad_fromcolor,$this->fillgrad_tocolor); 98 // In order to differentiate between gradients and cooors specified as an RGB triple 99 $graph->legend->Add($this->legend,$color,"",-2 /* -GRAD_HOR */, 100 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 101 } else { 102 $graph->legend->Add($this->legend, 103 $this->color,$this->mark,$this->line_style, 104 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 105 } 106 } 101 107 } 102 108 103 109 function AddArea($aMin=0,$aMax=0,$aFilled=LP_AREA_NOT_FILLED,$aColor="gray9",$aBorder=LP_AREA_BORDER) { 104 105 106 107 108 109 } 110 111 } 112 110 if($aMin > $aMax) { 111 // swap 112 $tmp = $aMin; 113 $aMin = $aMax; 114 $aMax = $tmp; 115 } 116 $this->filledAreas[] = array($aMin,$aMax,$aColor,$aFilled,$aBorder); 117 } 118 113 119 // Gets called before any axis are stroked 114 120 function PreStrokeAdjust($graph) { 115 121 116 // If another plot type have already adjusted the 117 // offset we don't touch it. 118 // (We check for empty in case the scale is a log scale 119 // and hence doesn't contain any xlabel_offset) 120 if( empty($graph->xaxis->scale->ticks->xlabel_offset) || 121 $graph->xaxis->scale->ticks->xlabel_offset == 0 ) { 122 if( $this->center ) { 123 ++$this->numpoints; 124 $a=0.5; $b=0.5; 125 } else { 126 $a=0; $b=0; 127 } 128 $graph->xaxis->scale->ticks->SetXLabelOffset($a); 129 $graph->SetTextScaleOff($b); 130 //$graph->xaxis->scale->ticks->SupressMinorTickMarks(); 131 } 132 } 133 122 // If another plot type have already adjusted the 123 // offset we don't touch it. 124 // (We check for empty in case the scale is a log scale 125 // and hence doesn't contain any xlabel_offset) 126 if( empty($graph->xaxis->scale->ticks->xlabel_offset) || $graph->xaxis->scale->ticks->xlabel_offset == 0 ) { 127 if( $this->center ) { 128 ++$this->numpoints; 129 $a=0.5; $b=0.5; 130 } else { 131 $a=0; $b=0; 132 } 133 $graph->xaxis->scale->ticks->SetXLabelOffset($a); 134 $graph->SetTextScaleOff($b); 135 //$graph->xaxis->scale->ticks->SupressMinorTickMarks(); 136 } 137 } 138 134 139 function SetFastStroke($aFlg=true) { 135 140 $this->iFastStroke = $aFlg; 136 141 } 137 142 138 143 function FastStroke($img,$xscale,$yscale,$aStartPoint=0,$exist_x=true) { 139 // An optimized stroke for many data points with no extra 140 // features but 60% faster. You can't have values or line styles, or null 141 // values in plots. 142 $numpoints=count($this->coords[0]); 143 if( $this->barcenter ) 144 $textadj = 0.5-$xscale->text_scale_off; 145 else 146 $textadj = 0; 147 148 $img->SetColor($this->color); 149 $img->SetLineWeight($this->weight); 150 $pnts=$aStartPoint; 151 while( $pnts < $numpoints ) { 152 if( $exist_x ) $x=$this->coords[1][$pnts]; 153 else $x=$pnts+$textadj; 154 $xt = $xscale->Translate($x); 155 $y=$this->coords[0][$pnts]; 156 $yt = $yscale->Translate($y); 157 if( is_numeric($y) ) { 158 $cord[] = $xt; 159 $cord[] = $yt; 160 } 161 elseif( $y == '-' && $pnts > 0 ) { 162 // Just ignore 163 } 164 else { 165 JpGraphError::RaiseL(10002);//('Plot too complicated for fast line Stroke. Use standard Stroke()'); 166 } 167 ++$pnts; 168 } // WHILE 169 170 $img->Polygon($cord,false,true); 171 } 172 144 // An optimized stroke for many data points with no extra 145 // features but 60% faster. You can't have values or line styles, or null 146 // values in plots. 147 $numpoints=count($this->coords[0]); 148 if( $this->barcenter ) { 149 $textadj = 0.5-$xscale->text_scale_off; 150 } 151 else { 152 $textadj = 0; 153 } 154 155 $img->SetColor($this->color); 156 $img->SetLineWeight($this->weight); 157 $pnts=$aStartPoint; 158 while( $pnts < $numpoints ) { 159 if( $exist_x ) { 160 $x=$this->coords[1][$pnts]; 161 } 162 else { 163 $x=$pnts+$textadj; 164 } 165 $xt = $xscale->Translate($x); 166 $y=$this->coords[0][$pnts]; 167 $yt = $yscale->Translate($y); 168 if( is_numeric($y) ) { 169 $cord[] = $xt; 170 $cord[] = $yt; 171 } 172 elseif( $y == '-' && $pnts > 0 ) { 173 // Just ignore 174 } 175 else { 176 JpGraphError::RaiseL(10002);//('Plot too complicated for fast line Stroke. Use standard Stroke()'); 177 } 178 ++$pnts; 179 } // WHILE 180 181 $img->Polygon($cord,false,true); 182 } 183 173 184 function Stroke($img,$xscale,$yscale) { 174 $idx=0; 175 $numpoints=count($this->coords[0]); 176 if( isset($this->coords[1]) ) { 177 if( count($this->coords[1])!=$numpoints ) 178 JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints); 179 //("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints"); 180 else 181 $exist_x = true; 182 } 183 else 184 $exist_x = false; 185 186 if( $this->barcenter ) 187 $textadj = 0.5-$xscale->text_scale_off; 188 else 189 $textadj = 0; 190 191 // Find the first numeric data point 192 $startpoint=0; 193 while( $startpoint < $numpoints && !is_numeric($this->coords[0][$startpoint]) ) 194 ++$startpoint; 195 196 // Bail out if no data points 197 if( $startpoint == $numpoints ) 198 return; 199 200 if( $this->iFastStroke ) { 201 $this->FastStroke($img,$xscale,$yscale,$startpoint,$exist_x); 202 return; 203 } 204 205 if( $exist_x ) 206 $xs=$this->coords[1][$startpoint]; 207 else 208 $xs= $textadj+$startpoint; 209 210 $img->SetStartPoint($xscale->Translate($xs), 211 $yscale->Translate($this->coords[0][$startpoint])); 212 213 214 if( $this->filled ) { 215 $min = $yscale->GetMinVal(); 216 if( $min > 0 || $this->fillFromMin ) 217 $fillmin = $yscale->scale_abs[0];//Translate($min); 218 else 219 $fillmin = $yscale->Translate(0); 220 221 $cord[$idx++] = $xscale->Translate($xs); 222 $cord[$idx++] = $fillmin; 223 } 224 $xt = $xscale->Translate($xs); 225 $yt = $yscale->Translate($this->coords[0][$startpoint]); 226 $cord[$idx++] = $xt; 227 $cord[$idx++] = $yt; 228 $yt_old = $yt; 229 $xt_old = $xt; 230 $y_old = $this->coords[0][$startpoint]; 231 232 $this->value->Stroke($img,$this->coords[0][$startpoint],$xt,$yt); 233 234 $img->SetColor($this->color); 235 $img->SetLineWeight($this->weight); 236 $img->SetLineStyle($this->line_style); 237 $pnts=$startpoint+1; 238 $firstnonumeric = false; 239 240 241 while( $pnts < $numpoints ) { 242 243 if( $exist_x ) $x=$this->coords[1][$pnts]; 244 else $x=$pnts+$textadj; 245 $xt = $xscale->Translate($x); 246 $yt = $yscale->Translate($this->coords[0][$pnts]); 247 248 $y=$this->coords[0][$pnts]; 249 if( $this->step_style ) { 250 // To handle null values within step style we need to record the 251 // first non numeric value so we know from where to start if the 252 // non value is '-'. 253 if( is_numeric($y) ) { 254 $firstnonumeric = false; 255 if( is_numeric($y_old) ) { 256 $img->StyleLine($xt_old,$yt_old,$xt,$yt_old); 257 $img->StyleLine($xt,$yt_old,$xt,$yt); 258 } 259 elseif( $y_old == '-' ) { 260 $img->StyleLine($xt_first,$yt_first,$xt,$yt_first); 261 $img->StyleLine($xt,$yt_first,$xt,$yt); 262 } 263 else { 264 $yt_old = $yt; 265 $xt_old = $xt; 266 } 267 $cord[$idx++] = $xt; 268 $cord[$idx++] = $yt_old; 269 $cord[$idx++] = $xt; 270 $cord[$idx++] = $yt; 271 } 272 elseif( $firstnonumeric==false ) { 273 $firstnonumeric = true; 274 $yt_first = $yt_old; 275 $xt_first = $xt_old; 276 } 277 } 278 else { 279 $tmp1=$y; 280 $prev=$this->coords[0][$pnts-1]; 281 if( $tmp1==='' || $tmp1===NULL || $tmp1==='X' ) $tmp1 = 'x'; 282 if( $prev==='' || $prev===null || $prev==='X' ) $prev = 'x'; 283 284 if( is_numeric($y) || (is_string($y) && $y != '-') ) { 285 if( is_numeric($y) && (is_numeric($prev) || $prev === '-' ) ) { 286 $img->StyleLineTo($xt,$yt); 287 } 288 else { 289 $img->SetStartPoint($xt,$yt); 290 } 291 } 292 if( $this->filled && $tmp1 !== '-' ) { 293 if( $tmp1 === 'x' ) { 294 $cord[$idx++] = $cord[$idx-3]; 295 $cord[$idx++] = $fillmin; 296 } 297 elseif( $prev === 'x' ) { 298 $cord[$idx++] = $xt; 299 $cord[$idx++] = $fillmin; 300 $cord[$idx++] = $xt; 301 $cord[$idx++] = $yt; 302 } 303 else { 304 $cord[$idx++] = $xt; 305 $cord[$idx++] = $yt; 306 } 307 } 308 else { 309 if( is_numeric($tmp1) && (is_numeric($prev) || $prev === '-' ) ) { 310 $cord[$idx++] = $xt; 311 $cord[$idx++] = $yt; 312 } 313 } 314 } 315 $yt_old = $yt; 316 $xt_old = $xt; 317 $y_old = $y; 318 319 $this->StrokeDataValue($img,$this->coords[0][$pnts],$xt,$yt); 320 321 ++$pnts; 322 } 323 324 if( $this->filled ) { 325 $cord[$idx++] = $xt; 326 if( $min > 0 || $this->fillFromMin ) 327 $cord[$idx++] = $yscale->Translate($min); 328 else 329 $cord[$idx++] = $yscale->Translate(0); 330 if( $this->fillgrad ) { 331 $img->SetLineWeight(1); 332 $grad = new Gradient($img); 333 $grad->SetNumColors($this->fillgrad_numcolors); 334 $grad->FilledFlatPolygon($cord,$this->fillgrad_fromcolor,$this->fillgrad_tocolor); 335 $img->SetLineWeight($this->weight); 336 } 337 else { 338 $img->SetColor($this->fill_color); 339 $img->FilledPolygon($cord); 340 } 341 if( $this->line_weight > 0 ) { 342 $img->SetColor($this->color); 343 $img->Polygon($cord); 344 } 345 } 346 347 if(!empty($this->filledAreas)) { 348 349 $minY = $yscale->Translate($yscale->GetMinVal()); 350 $factor = ($this->step_style ? 4 : 2); 351 352 for($i = 0; $i < sizeof($this->filledAreas); ++$i) { 353 // go through all filled area elements ordered by insertion 354 // fill polygon array 355 $areaCoords[] = $cord[$this->filledAreas[$i][0] * $factor]; 356 $areaCoords[] = $minY; 357 358 $areaCoords = 359 array_merge($areaCoords, 360 array_slice($cord, 361 $this->filledAreas[$i][0] * $factor, 362 ($this->filledAreas[$i][1] - $this->filledAreas[$i][0] + ($this->step_style ? 0 : 1)) * $factor)); 363 $areaCoords[] = $areaCoords[sizeof($areaCoords)-2]; // last x 364 $areaCoords[] = $minY; // last y 365 366 if($this->filledAreas[$i][3]) { 367 $img->SetColor($this->filledAreas[$i][2]); 368 $img->FilledPolygon($areaCoords); 369 $img->SetColor($this->color); 370 } 371 // Check if we should draw the frame. 372 // If not we still re-draw the line since it might have been 373 // partially overwritten by the filled area and it doesn't look 374 // very good. 375 // TODO: The behaviour is undefined if the line does not have 376 // any line at the position of the area. 377 if( $this->filledAreas[$i][4] ) 378 $img->Polygon($areaCoords); 379 else 380 $img->Polygon($cord); 381 382 $areaCoords = array(); 383 } 384 } 385 386 if( $this->mark->type == -1 || $this->mark->show == false ) 387 return; 388 389 for( $pnts=0; $pnts<$numpoints; ++$pnts) { 390 391 if( $exist_x ) $x=$this->coords[1][$pnts]; 392 else $x=$pnts+$textadj; 393 $xt = $xscale->Translate($x); 394 $yt = $yscale->Translate($this->coords[0][$pnts]); 395 396 if( is_numeric($this->coords[0][$pnts]) ) { 397 if( !empty($this->csimtargets[$pnts]) ) { 398 if( !empty($this->csimwintargets[$pnts]) ) { 399 $this->mark->SetCSIMTarget($this->csimtargets[$pnts],$this->csimwintargets[$pnts]); 400 } 401 else { 402 $this->mark->SetCSIMTarget($this->csimtargets[$pnts]); 403 } 404 $this->mark->SetCSIMAlt($this->csimalts[$pnts]); 405 } 406 if( $exist_x ) 407 $x=$this->coords[1][$pnts]; 408 else 409 $x=$pnts; 410 $this->mark->SetCSIMAltVal($this->coords[0][$pnts],$x); 411 $this->mark->Stroke($img,$xt,$yt); 412 $this->csimareas .= $this->mark->GetCSIMAreas(); 413 } 414 } 185 $idx=0; 186 $numpoints=count($this->coords[0]); 187 if( isset($this->coords[1]) ) { 188 if( count($this->coords[1])!=$numpoints ) { 189 JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints); 190 //("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints"); 191 } 192 else { 193 $exist_x = true; 194 } 195 } 196 else { 197 $exist_x = false; 198 } 199 200 if( $this->barcenter ) { 201 $textadj = 0.5-$xscale->text_scale_off; 202 } 203 else { 204 $textadj = 0; 205 } 206 207 // Find the first numeric data point 208 $startpoint=0; 209 while( $startpoint < $numpoints && !is_numeric($this->coords[0][$startpoint]) ) { 210 ++$startpoint; 211 } 212 213 // Bail out if no data points 214 if( $startpoint == $numpoints ) return; 215 216 if( $this->iFastStroke ) { 217 $this->FastStroke($img,$xscale,$yscale,$startpoint,$exist_x); 218 return; 219 } 220 221 if( $exist_x ) { 222 $xs=$this->coords[1][$startpoint]; 223 } 224 else { 225 $xs= $textadj+$startpoint; 226 } 227 228 $img->SetStartPoint($xscale->Translate($xs), 229 $yscale->Translate($this->coords[0][$startpoint])); 230 231 if( $this->filled ) { 232 if( $this->fillFromMax ) { 233 //$max = $yscale->GetMaxVal(); 234 $cord[$idx++] = $xscale->Translate($xs); 235 $cord[$idx++] = $yscale->scale_abs[1]; 236 } 237 else { 238 $min = $yscale->GetMinVal(); 239 if( $min > 0 || $this->fillFromMin ) { 240 $fillmin = $yscale->scale_abs[0];//Translate($min); 241 } 242 else { 243 $fillmin = $yscale->Translate(0); 244 } 245 246 $cord[$idx++] = $xscale->Translate($xs); 247 $cord[$idx++] = $fillmin; 248 } 249 } 250 $xt = $xscale->Translate($xs); 251 $yt = $yscale->Translate($this->coords[0][$startpoint]); 252 $cord[$idx++] = $xt; 253 $cord[$idx++] = $yt; 254 $yt_old = $yt; 255 $xt_old = $xt; 256 $y_old = $this->coords[0][$startpoint]; 257 258 $this->value->Stroke($img,$this->coords[0][$startpoint],$xt,$yt); 259 260 $img->SetColor($this->color); 261 $img->SetLineWeight($this->weight); 262 $img->SetLineStyle($this->line_style); 263 $pnts=$startpoint+1; 264 $firstnonumeric = false; 265 266 267 while( $pnts < $numpoints ) { 268 269 if( $exist_x ) { 270 $x=$this->coords[1][$pnts]; 271 } 272 else { 273 $x=$pnts+$textadj; 274 } 275 $xt = $xscale->Translate($x); 276 $yt = $yscale->Translate($this->coords[0][$pnts]); 277 278 $y=$this->coords[0][$pnts]; 279 if( $this->step_style ) { 280 // To handle null values within step style we need to record the 281 // first non numeric value so we know from where to start if the 282 // non value is '-'. 283 if( is_numeric($y) ) { 284 $firstnonumeric = false; 285 if( is_numeric($y_old) ) { 286 $img->StyleLine($xt_old,$yt_old,$xt,$yt_old); 287 $img->StyleLine($xt,$yt_old,$xt,$yt); 288 } 289 elseif( $y_old == '-' ) { 290 $img->StyleLine($xt_first,$yt_first,$xt,$yt_first); 291 $img->StyleLine($xt,$yt_first,$xt,$yt); 292 } 293 else { 294 $yt_old = $yt; 295 $xt_old = $xt; 296 } 297 $cord[$idx++] = $xt; 298 $cord[$idx++] = $yt_old; 299 $cord[$idx++] = $xt; 300 $cord[$idx++] = $yt; 301 } 302 elseif( $firstnonumeric==false ) { 303 $firstnonumeric = true; 304 $yt_first = $yt_old; 305 $xt_first = $xt_old; 306 } 307 } 308 else { 309 $tmp1=$y; 310 $prev=$this->coords[0][$pnts-1]; 311 if( $tmp1==='' || $tmp1===NULL || $tmp1==='X' ) $tmp1 = 'x'; 312 if( $prev==='' || $prev===null || $prev==='X' ) $prev = 'x'; 313 314 if( is_numeric($y) || (is_string($y) && $y != '-') ) { 315 if( is_numeric($y) && (is_numeric($prev) || $prev === '-' ) ) { 316 $img->StyleLineTo($xt,$yt); 317 } 318 else { 319 $img->SetStartPoint($xt,$yt); 320 } 321 } 322 if( $this->filled && $tmp1 !== '-' ) { 323 if( $tmp1 === 'x' ) { 324 $cord[$idx++] = $cord[$idx-3]; 325 $cord[$idx++] = $fillmin; 326 } 327 elseif( $prev === 'x' ) { 328 $cord[$idx++] = $xt; 329 $cord[$idx++] = $fillmin; 330 $cord[$idx++] = $xt; 331 $cord[$idx++] = $yt; 332 } 333 else { 334 $cord[$idx++] = $xt; 335 $cord[$idx++] = $yt; 336 } 337 } 338 else { 339 if( is_numeric($tmp1) && (is_numeric($prev) || $prev === '-' ) ) { 340 $cord[$idx++] = $xt; 341 $cord[$idx++] = $yt; 342 } 343 } 344 } 345 $yt_old = $yt; 346 $xt_old = $xt; 347 $y_old = $y; 348 349 $this->StrokeDataValue($img,$this->coords[0][$pnts],$xt,$yt); 350 351 ++$pnts; 352 } 353 354 if( $this->filled ) { 355 $cord[$idx++] = $xt; 356 if( $this->fillFromMax ) { 357 $cord[$idx++] = $yscale->scale_abs[1]; 358 } 359 else { 360 if( $min > 0 || $this->fillFromMin ) { 361 $cord[$idx++] = $yscale->Translate($min); 362 } 363 else { 364 $cord[$idx++] = $yscale->Translate(0); 365 } 366 } 367 if( $this->fillgrad ) { 368 $img->SetLineWeight(1); 369 $grad = new Gradient($img); 370 $grad->SetNumColors($this->fillgrad_numcolors); 371 $grad->FilledFlatPolygon($cord,$this->fillgrad_fromcolor,$this->fillgrad_tocolor); 372 $img->SetLineWeight($this->weight); 373 } 374 else { 375 $img->SetColor($this->fill_color); 376 $img->FilledPolygon($cord); 377 } 378 if( $this->weight > 0 ) { 379 $img->SetLineWeight($this->weight); 380 $img->SetColor($this->color); 381 // Remove first and last coordinate before drawing the line 382 // sine we otherwise get the vertical start and end lines which 383 // doesn't look appropriate 384 $img->Polygon(array_slice($cord,2,count($cord)-4)); 385 } 386 } 387 388 if(!empty($this->filledAreas)) { 389 390 $minY = $yscale->Translate($yscale->GetMinVal()); 391 $factor = ($this->step_style ? 4 : 2); 392 393 for($i = 0; $i < sizeof($this->filledAreas); ++$i) { 394 // go through all filled area elements ordered by insertion 395 // fill polygon array 396 $areaCoords[] = $cord[$this->filledAreas[$i][0] * $factor]; 397 $areaCoords[] = $minY; 398 399 $areaCoords = 400 array_merge($areaCoords, 401 array_slice($cord, 402 $this->filledAreas[$i][0] * $factor, 403 ($this->filledAreas[$i][1] - $this->filledAreas[$i][0] + ($this->step_style ? 0 : 1)) * $factor)); 404 $areaCoords[] = $areaCoords[sizeof($areaCoords)-2]; // last x 405 $areaCoords[] = $minY; // last y 406 407 if($this->filledAreas[$i][3]) { 408 $img->SetColor($this->filledAreas[$i][2]); 409 $img->FilledPolygon($areaCoords); 410 $img->SetColor($this->color); 411 } 412 // Check if we should draw the frame. 413 // If not we still re-draw the line since it might have been 414 // partially overwritten by the filled area and it doesn't look 415 // very good. 416 if( $this->filledAreas[$i][4] ) { 417 $img->Polygon($areaCoords); 418 } 419 else { 420 $img->Polygon($cord); 421 } 422 423 $areaCoords = array(); 424 } 425 } 426 427 if( $this->mark->type == -1 || $this->mark->show == false ) 428 return; 429 430 for( $pnts=0; $pnts<$numpoints; ++$pnts) { 431 432 if( $exist_x ) { 433 $x=$this->coords[1][$pnts]; 434 } 435 else { 436 $x=$pnts+$textadj; 437 } 438 $xt = $xscale->Translate($x); 439 $yt = $yscale->Translate($this->coords[0][$pnts]); 440 441 if( is_numeric($this->coords[0][$pnts]) ) { 442 if( !empty($this->csimtargets[$pnts]) ) { 443 if( !empty($this->csimwintargets[$pnts]) ) { 444 $this->mark->SetCSIMTarget($this->csimtargets[$pnts],$this->csimwintargets[$pnts]); 445 } 446 else { 447 $this->mark->SetCSIMTarget($this->csimtargets[$pnts]); 448 } 449 $this->mark->SetCSIMAlt($this->csimalts[$pnts]); 450 } 451 if( $exist_x ) { 452 $x=$this->coords[1][$pnts]; 453 } 454 else { 455 $x=$pnts; 456 } 457 $this->mark->SetCSIMAltVal($this->coords[0][$pnts],$x); 458 $this->mark->Stroke($img,$xt,$yt); 459 $this->csimareas .= $this->mark->GetCSIMAreas(); 460 } 461 } 415 462 } 416 463 } // Class … … 419 466 //=================================================== 420 467 // CLASS AccLinePlot 421 // Description: 468 // Description: 422 469 //=================================================== 423 470 class AccLinePlot extends Plot { 424 471 protected $plots=null,$nbrplots=0; 425 472 private $iStartEndZero=true; 426 //---------------427 // CONSTRUCTOR428 function AccLinePlot($plots) {473 //--------------- 474 // CONSTRUCTOR 475 function __construct($plots) { 429 476 $this->plots = $plots; 430 431 432 433 434 435 436 437 438 } 439 440 441 442 } 443 } 444 445 //---------------446 // PUBLIC METHODS 477 $this->nbrplots = count($plots); 478 $this->numpoints = $plots[0]->numpoints; 479 480 // Verify that all plots have the same number of data points 481 for( $i=1; $i < $this->nbrplots; ++$i ) { 482 if( $plots[$i]->numpoints != $this->numpoints ) { 483 JpGraphError::RaiseL(10003);//('Each plot in an accumulated lineplot must have the same number of data points',0) 484 } 485 } 486 487 for($i=0; $i < $this->nbrplots; ++$i ) { 488 $this->LineInterpolate($this->plots[$i]->coords[0]); 489 } 490 } 491 492 //--------------- 493 // PUBLIC METHODS 447 494 function Legend($graph) { 448 foreach( $this->plots as $p ) 449 $p->DoLegend($graph); 450 } 451 495 foreach( $this->plots as $p ) { 496 $p->DoLegend($graph); 497 } 498 } 499 452 500 function Max() { 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 } 501 list($xmax) = $this->plots[0]->Max(); 502 $nmax=0; 503 $n = count($this->plots); 504 for($i=0; $i < $n; ++$i) { 505 $nc = count($this->plots[$i]->coords[0]); 506 $nmax = max($nmax,$nc); 507 list($x) = $this->plots[$i]->Max(); 508 $xmax = Max($xmax,$x); 509 } 510 for( $i = 0; $i < $nmax; $i++ ) { 511 // Get y-value for line $i by adding the 512 // individual bars from all the plots added. 513 // It would be wrong to just add the 514 // individual plots max y-value since that 515 // would in most cases give to large y-value. 516 $y=$this->plots[0]->coords[0][$i]; 517 for( $j = 1; $j < $this->nbrplots; $j++ ) { 518 $y += $this->plots[ $j ]->coords[0][$i]; 519 } 520 $ymax[$i] = $y; 521 } 522 $ymax = max($ymax); 523 return array($xmax,$ymax); 524 } 477 525 478 526 function Min() { 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 527 $nmax=0; 528 list($xmin,$ysetmin) = $this->plots[0]->Min(); 529 $n = count($this->plots); 530 for($i=0; $i < $n; ++$i) { 531 $nc = count($this->plots[$i]->coords[0]); 532 $nmax = max($nmax,$nc); 533 list($x,$y) = $this->plots[$i]->Min(); 534 $xmin = Min($xmin,$x); 535 $ysetmin = Min($y,$ysetmin); 536 } 537 for( $i = 0; $i < $nmax; $i++ ) { 538 // Get y-value for line $i by adding the 539 // individual bars from all the plots added. 540 // It would be wrong to just add the 541 // individual plots min y-value since that 542 // would in most cases give to small y-value. 543 $y=$this->plots[0]->coords[0][$i]; 544 for( $j = 1; $j < $this->nbrplots; $j++ ) { 545 $y += $this->plots[ $j ]->coords[0][$i]; 546 } 547 $ymin[$i] = $y; 548 } 549 $ymin = Min($ysetmin,Min($ymin)); 550 return array($xmin,$ymin); 503 551 } 504 552 … … 506 554 function PreStrokeAdjust($graph) { 507 555 508 509 510 // (We check for empty in case the scale is a log scale 511 512 513 514 515 516 517 518 519 520 521 522 $graph->SetTextScaleOff($b); 523 524 525 556 // If another plot type have already adjusted the 557 // offset we don't touch it. 558 // (We check for empty in case the scale is a log scale 559 // and hence doesn't contain any xlabel_offset) 560 561 if( empty($graph->xaxis->scale->ticks->xlabel_offset) || 562 $graph->xaxis->scale->ticks->xlabel_offset == 0 ) { 563 if( $this->center ) { 564 ++$this->numpoints; 565 $a=0.5; $b=0.5; 566 } else { 567 $a=0; $b=0; 568 } 569 $graph->xaxis->scale->ticks->SetXLabelOffset($a); 570 $graph->SetTextScaleOff($b); 571 $graph->xaxis->scale->ticks->SupressMinorTickMarks(); 572 } 573 526 574 } 527 575 528 576 function SetInterpolateMode($aIntMode) { 529 577 $this->iStartEndZero=$aIntMode; 530 578 } 531 579 … … 535 583 function LineInterpolate(&$aData) { 536 584 537 $n=count($aData); 538 $i=0; 539 540 // If first point is undefined we will set it to the same as the first 541 // valid data 542 if( $aData[$i]==='-' ) { 543 // Find the first valid data 544 while( $i < $n && $aData[$i]==='-' ) { 545 ++$i; 546 } 547 if( $i < $n ) { 548 for($j=0; $j < $i; ++$j ) { 549 if( $this->iStartEndZero ) 550 $aData[$i] = 0; 551 else 552 $aData[$j] = $aData[$i]; 553 } 554 } 555 else { 556 // All '-' => Error 557 return false; 558 } 559 } 560 561 while($i < $n) { 562 while( $i < $n && $aData[$i] !== '-' ) { 563 ++$i; 564 } 565 if( $i < $n ) { 566 $pstart=$i-1; 567 568 // Now see how long this segment of '-' are 569 while( $i < $n && $aData[$i] === '-' ) 570 ++$i; 571 if( $i < $n ) { 572 $pend=$i; 573 $size=$pend-$pstart; 574 $k=($aData[$pend]-$aData[$pstart])/$size; 575 // Replace the segment of '-' with a linear interpolated value. 576 for($j=1; $j < $size; ++$j ) { 577 $aData[$pstart+$j] = $aData[$pstart] + $j*$k ; 578 } 579 } 580 else { 581 // There are no valid end point. The '-' goes all the way to the end 582 // In that case we just set all the remaining values the the same as the 583 // last valid data point. 584 for( $j=$pstart+1; $j < $n; ++$j ) 585 if( $this->iStartEndZero ) 586 $aData[$j] = 0; 587 else 588 $aData[$j] = $aData[$pstart] ; 589 } 590 } 591 } 592 return true; 593 } 594 595 585 $n=count($aData); 586 $i=0; 587 588 // If first point is undefined we will set it to the same as the first 589 // valid data 590 if( $aData[$i]==='-' ) { 591 // Find the first valid data 592 while( $i < $n && $aData[$i]==='-' ) { 593 ++$i; 594 } 595 if( $i < $n ) { 596 for($j=0; $j < $i; ++$j ) { 597 if( $this->iStartEndZero ) 598 $aData[$i] = 0; 599 else 600 $aData[$j] = $aData[$i]; 601 } 602 } 603 else { 604 // All '-' => Error 605 return false; 606 } 607 } 608 609 while($i < $n) { 610 while( $i < $n && $aData[$i] !== '-' ) { 611 ++$i; 612 } 613 if( $i < $n ) { 614 $pstart=$i-1; 615 616 // Now see how long this segment of '-' are 617 while( $i < $n && $aData[$i] === '-' ) { 618 ++$i; 619 } 620 if( $i < $n ) { 621 $pend=$i; 622 $size=$pend-$pstart; 623 $k=($aData[$pend]-$aData[$pstart])/$size; 624 // Replace the segment of '-' with a linear interpolated value. 625 for($j=1; $j < $size; ++$j ) { 626 $aData[$pstart+$j] = $aData[$pstart] + $j*$k ; 627 } 628 } 629 else { 630 // There are no valid end point. The '-' goes all the way to the end 631 // In that case we just set all the remaining values the the same as the 632 // last valid data point. 633 for( $j=$pstart+1; $j < $n; ++$j ) 634 if( $this->iStartEndZero ) { 635 $aData[$j] = 0; 636 } 637 else { 638 $aData[$j] = $aData[$pstart] ; 639 } 640 } 641 } 642 } 643 return true; 644 } 596 645 597 646 // To avoid duplicate of line drawing code here we just … … 602 651 // since this method would have a side effect. 603 652 function Stroke($img,$xscale,$yscale) { 604 $img->SetLineWeight($this->weight); 605 $this->numpoints = count($this->plots[0]->coords[0]); 606 // Allocate array 607 $coords[$this->nbrplots][$this->numpoints]=0; 608 for($i=0; $i<$this->numpoints; $i++) { 609 $coords[0][$i]=$this->plots[0]->coords[0][$i]; 610 $accy=$coords[0][$i]; 611 for($j=1; $j<$this->nbrplots; ++$j ) { 612 $coords[$j][$i] = $this->plots[$j]->coords[0][$i]+$accy; 613 $accy = $coords[$j][$i]; 614 } 615 } 616 for($j=$this->nbrplots-1; $j>=0; --$j) { 617 $p=$this->plots[$j]; 618 for( $i=0; $i<$this->numpoints; ++$i) { 619 $tmp[$i]=$p->coords[0][$i]; 620 $p->coords[0][$i]=$coords[$j][$i]; 621 } 622 $p->Stroke($img,$xscale,$yscale); 623 for( $i=0; $i<$this->numpoints; ++$i) 624 $p->coords[0][$i]=$tmp[$i]; 625 $p->coords[0][]=$tmp; 626 } 653 $img->SetLineWeight($this->weight); 654 $this->numpoints = count($this->plots[0]->coords[0]); 655 // Allocate array 656 $coords[$this->nbrplots][$this->numpoints]=0; 657 for($i=0; $i<$this->numpoints; $i++) { 658 $coords[0][$i]=$this->plots[0]->coords[0][$i]; 659 $accy=$coords[0][$i]; 660 for($j=1; $j<$this->nbrplots; ++$j ) { 661 $coords[$j][$i] = $this->plots[$j]->coords[0][$i]+$accy; 662 $accy = $coords[$j][$i]; 663 } 664 } 665 for($j=$this->nbrplots-1; $j>=0; --$j) { 666 $p=$this->plots[$j]; 667 for( $i=0; $i<$this->numpoints; ++$i) { 668 $tmp[$i]=$p->coords[0][$i]; 669 $p->coords[0][$i]=$coords[$j][$i]; 670 } 671 $p->Stroke($img,$xscale,$yscale); 672 for( $i=0; $i<$this->numpoints; ++$i) { 673 $p->coords[0][$i]=$tmp[$i]; 674 } 675 $p->coords[0][]=$tmp; 676 } 627 677 } 628 678 } // Class
Note:
See TracChangeset
for help on using the changeset viewer.