Fix checkRpItemsPosition
[ryzomcore.git] / web / public_php / admin / jpgraph / jpgraph_plotband.php
bloba969e57208c464c1fd0cda7af4f4b2c4cefa3e85
1 <?php
2 //=======================================================================
3 // File: JPGRAPH_PLOTBAND.PHP
4 // Description: PHP4 Graph Plotting library. Extension module.
5 // Created: 2004-02-18
6 // Author: Johan Persson (johanp@aditus.nu)
7 // Ver: $Id: jpgraph_plotband.php,v 1.1 2006/07/07 13:37:14 powles Exp $
8 //
9 // Copyright (c) Aditus Consulting. All rights reserved.
10 //========================================================================
12 // Constants for types of static bands in plot area
13 DEFINE("BAND_RDIAG",1); // Right diagonal lines
14 DEFINE("BAND_LDIAG",2); // Left diagonal lines
15 DEFINE("BAND_SOLID",3); // Solid one color
16 DEFINE("BAND_VLINE",4); // Vertical lines
17 DEFINE("BAND_HLINE",5); // Horizontal lines
18 DEFINE("BAND_3DPLANE",6); // "3D" Plane
19 DEFINE("BAND_HVCROSS",7); // Vertical/Hor crosses
20 DEFINE("BAND_DIAGCROSS",8); // Diagonal crosses
23 // Utility class to hold coordinates for a rectangle
24 class Rectangle {
25 var $x,$y,$w,$h;
26 var $xe, $ye;
27 function Rectangle($aX,$aY,$aWidth,$aHeight) {
28 $this->x=$aX;
29 $this->y=$aY;
30 $this->w=$aWidth;
31 $this->h=$aHeight;
32 $this->xe=$aX+$aWidth-1;
33 $this->ye=$aY+$aHeight-1;
37 //=====================================================================
38 // Class RectPattern
39 // Base class for pattern hierarchi that is used to display patterned
40 // bands on the graph. Any subclass that doesn't override Stroke()
41 // must at least implement method DoPattern(&$aImg) which is responsible
42 // for drawing the pattern onto the graph.
43 //=====================================================================
44 class RectPattern {
45 var $color;
46 var $weight;
47 var $rect=null;
48 var $doframe=true;
49 var $linespacing; // Line spacing in pixels
50 var $iBackgroundColor=-1; // Default is no background fill
52 function RectPattern($aColor,$aWeight=1) {
53 $this->color = $aColor;
54 $this->weight = $aWeight;
57 function SetBackground($aBackgroundColor) {
58 $this->iBackgroundColor=$aBackgroundColor;
61 function SetPos(&$aRect) {
62 $this->rect = $aRect;
65 function ShowFrame($aShow=true) {
66 $this->doframe=$aShow;
69 function SetDensity($aDens) {
70 if( $aDens < 1 || $aDens > 100 )
71 JpGraphError::RaiseL(16001,$aDens);
72 //(" Desity for pattern must be between 1 and 100. (You tried $aDens)");
73 // 1% corresponds to linespacing=50
74 // 100 % corresponds to linespacing 1
75 $this->linespacing = floor(((100-$aDens)/100.0)*50)+1;
79 function Stroke(&$aImg) {
80 if( $this->rect == null )
81 JpGraphError::RaiseL(16002);
82 //(" No positions specified for pattern.");
84 if( !(is_numeric($this->iBackgroundColor) && $this->iBackgroundColor==-1) ) {
85 $aImg->SetColor($this->iBackgroundColor);
86 $aImg->FilledRectangle($this->rect->x,$this->rect->y,$this->rect->xe,$this->rect->ye);
89 $aImg->SetColor($this->color);
90 $aImg->SetLineWeight($this->weight);
92 // Virtual function implemented by subclass
93 $this->DoPattern($aImg);
95 // Frame around the pattern area
96 if( $this->doframe )
97 $aImg->Rectangle($this->rect->x,$this->rect->y,$this->rect->xe,$this->rect->ye);
103 //=====================================================================
104 // Class RectPatternSolid
105 // Implements a solid band
106 //=====================================================================
107 class RectPatternSolid extends RectPattern {
109 function RectPatternSolid($aColor="black",$aWeight=1) {
110 parent::RectPattern($aColor,$aWeight);
113 function DoPattern(&$aImg) {
114 $aImg->SetColor($this->color);
115 $aImg->FilledRectangle($this->rect->x,$this->rect->y,
116 $this->rect->xe,$this->rect->ye);
120 //=====================================================================
121 // Class RectPatternHor
122 // Implements horizontal line pattern
123 //=====================================================================
124 class RectPatternHor extends RectPattern {
126 function RectPatternHor($aColor="black",$aWeight=1,$aLineSpacing=7) {
127 parent::RectPattern($aColor,$aWeight);
128 $this->linespacing = $aLineSpacing;
131 function DoPattern(&$aImg) {
132 $x0 = $this->rect->x;
133 $x1 = $this->rect->xe;
134 $y = $this->rect->y;
135 while( $y < $this->rect->ye ) {
136 $aImg->Line($x0,$y,$x1,$y);
137 $y += $this->linespacing;
142 //=====================================================================
143 // Class RectPatternVert
144 // Implements vertical line pattern
145 //=====================================================================
146 class RectPatternVert extends RectPattern {
147 var $linespacing=10; // Line spacing in pixels
149 function RectPatternVert($aColor="black",$aWeight=1,$aLineSpacing=7) {
150 parent::RectPattern($aColor,$aWeight);
151 $this->linespacing = $aLineSpacing;
154 //--------------------
155 // Private methods
157 function DoPattern(&$aImg) {
158 $x = $this->rect->x;
159 $y0 = $this->rect->y;
160 $y1 = $this->rect->ye;
161 while( $x < $this->rect->xe ) {
162 $aImg->Line($x,$y0,$x,$y1);
163 $x += $this->linespacing;
169 //=====================================================================
170 // Class RectPatternRDiag
171 // Implements right diagonal pattern
172 //=====================================================================
173 class RectPatternRDiag extends RectPattern {
174 var $linespacing; // Line spacing in pixels
176 function RectPatternRDiag($aColor="black",$aWeight=1,$aLineSpacing=12) {
177 parent::RectPattern($aColor,$aWeight);
178 $this->linespacing = $aLineSpacing;
181 function DoPattern(&$aImg) {
182 // --------------------
183 // | / / / / /|
184 // |/ / / / / |
185 // | / / / / |
186 // --------------------
187 $xe = $this->rect->xe;
188 $ye = $this->rect->ye;
189 $x0 = $this->rect->x + round($this->linespacing/2);
190 $y0 = $this->rect->y;
191 $x1 = $this->rect->x;
192 $y1 = $this->rect->y + round($this->linespacing/2);
194 while($x0<=$xe && $y1<=$ye) {
195 $aImg->Line($x0,$y0,$x1,$y1);
196 $x0 += $this->linespacing;
197 $y1 += $this->linespacing;
200 if( $xe-$x1 > $ye-$y0 ) {
201 // Width larger than height
202 $x1 = $this->rect->x + ($y1-$ye);
203 $y1 = $ye;
204 $y0 = $this->rect->y;
205 while( $x0 <= $xe ) {
206 $aImg->Line($x0,$y0,$x1,$y1);
207 $x0 += $this->linespacing;
208 $x1 += $this->linespacing;
211 $y0=$this->rect->y + ($x0-$xe);
212 $x0=$xe;
214 else {
215 // Height larger than width
216 $diff = $x0-$xe;
217 $y0 = $diff+$this->rect->y;
218 $x0 = $xe;
219 $x1 = $this->rect->x;
220 while( $y1 <= $ye ) {
221 $aImg->Line($x0,$y0,$x1,$y1);
222 $y1 += $this->linespacing;
223 $y0 += $this->linespacing;
226 $diff = $y1-$ye;
227 $y1 = $ye;
228 $x1 = $diff + $this->rect->x;
231 while( $y0 <= $ye ) {
232 $aImg->Line($x0,$y0,$x1,$y1);
233 $y0 += $this->linespacing;
234 $x1 += $this->linespacing;
239 //=====================================================================
240 // Class RectPatternLDiag
241 // Implements left diagonal pattern
242 //=====================================================================
243 class RectPatternLDiag extends RectPattern {
244 var $linespacing; // Line spacing in pixels
246 function RectPatternLDiag($aColor="black",$aWeight=1,$aLineSpacing=12) {
247 $this->linespacing = $aLineSpacing;
248 parent::RectPattern($aColor,$aWeight);
251 function DoPattern(&$aImg) {
252 // --------------------
253 // |\ \ \ \ \ |
254 // | \ \ \ \ \|
255 // | \ \ \ \ |
256 // |------------------|
257 $xe = $this->rect->xe;
258 $ye = $this->rect->ye;
259 $x0 = $this->rect->x + round($this->linespacing/2);
260 $y0 = $this->rect->ye;
261 $x1 = $this->rect->x;
262 $y1 = $this->rect->ye - round($this->linespacing/2);
264 while($x0<=$xe && $y1>=$this->rect->y) {
265 $aImg->Line($x0,$y0,$x1,$y1);
266 $x0 += $this->linespacing;
267 $y1 -= $this->linespacing;
269 if( $xe-$x1 > $ye-$this->rect->y ) {
270 // Width larger than height
271 $x1 = $this->rect->x + ($this->rect->y-$y1);
272 $y0=$ye; $y1=$this->rect->y;
273 while( $x0 <= $xe ) {
274 $aImg->Line($x0,$y0,$x1,$y1);
275 $x0 += $this->linespacing;
276 $x1 += $this->linespacing;
279 $y0=$this->rect->ye - ($x0-$xe);
280 $x0=$xe;
282 else {
283 // Height larger than width
284 $diff = $x0-$xe;
285 $y0 = $ye-$diff;
286 $x0 = $xe;
287 while( $y1 >= $this->rect->y ) {
288 $aImg->Line($x0,$y0,$x1,$y1);
289 $y0 -= $this->linespacing;
290 $y1 -= $this->linespacing;
292 $diff = $this->rect->y - $y1;
293 $x1 = $this->rect->x + $diff;
294 $y1 = $this->rect->y;
296 while( $y0 >= $this->rect->y ) {
297 $aImg->Line($x0,$y0,$x1,$y1);
298 $y0 -= $this->linespacing;
299 $x1 += $this->linespacing;
304 //=====================================================================
305 // Class RectPattern3DPlane
306 // Implements "3D" plane pattern
307 //=====================================================================
308 class RectPattern3DPlane extends RectPattern {
309 var $alpha=50; // Parameter that specifies the distance
310 // to "simulated" horizon in pixel from the
311 // top of the band. Specifies how fast the lines
312 // converge.
314 function RectPattern3DPlane($aColor="black",$aWeight=1) {
315 parent::RectPattern($aColor,$aWeight);
316 $this->SetDensity(10); // Slightly larger default
319 function SetHorizon($aHorizon) {
320 $this->alpha=$aHorizon;
323 function DoPattern(&$aImg) {
324 // "Fake" a nice 3D grid-effect.
325 $x0 = $this->rect->x + $this->rect->w/2;
326 $y0 = $this->rect->y;
327 $x1 = $x0;
328 $y1 = $this->rect->ye;
329 $x0_right = $x0;
330 $x1_right = $x1;
332 // BTW "apa" means monkey in Swedish but is really a shortform for
333 // "alpha+a" which was the labels I used on paper when I derived the
334 // geometric to get the 3D perspective right.
335 // $apa is the height of the bounding rectangle plus the distance to the
336 // artifical horizon (alpha)
337 $apa = $this->rect->h + $this->alpha;
339 // Three cases and three loops
340 // 1) The endpoint of the line ends on the bottom line
341 // 2) The endpoint ends on the side
342 // 3) Horizontal lines
344 // Endpoint falls on bottom line
345 $middle=$this->rect->x + $this->rect->w/2;
346 $dist=$this->linespacing;
347 $factor=$this->alpha /($apa);
348 while($x1>$this->rect->x) {
349 $aImg->Line($x0,$y0,$x1,$y1);
350 $aImg->Line($x0_right,$y0,$x1_right,$y1);
351 $x1 = $middle - $dist;
352 $x0 = $middle - $dist * $factor;
353 $x1_right = $middle + $dist;
354 $x0_right = $middle + $dist * $factor;
355 $dist += $this->linespacing;
358 // Endpoint falls on sides
359 $dist -= $this->linespacing;
360 $d=$this->rect->w/2;
361 $c = $apa - $d*$apa/$dist;
362 while( $x0>$this->rect->x ) {
363 $aImg->Line($x0,$y0,$this->rect->x,$this->rect->ye-$c);
364 $aImg->Line($x0_right,$y0,$this->rect->xe,$this->rect->ye-$c);
365 $dist += $this->linespacing;
366 $x0 = $middle - $dist * $factor;
367 $x1 = $middle - $dist;
368 $x0_right = $middle + $dist * $factor;
369 $c = $apa - $d*$apa/$dist;
372 // Horizontal lines
373 // They need some serious consideration since they are a function
374 // of perspective depth (alpha) and density (linespacing)
375 $x0=$this->rect->x;
376 $x1=$this->rect->xe;
377 $y=$this->rect->ye;
379 // The first line is drawn directly. Makes the loop below slightly
380 // more readable.
381 $aImg->Line($x0,$y,$x1,$y);
382 $hls = $this->linespacing;
384 // A correction factor for vertical "brick" line spacing to account for
385 // a) the difference in number of pixels hor vs vert
386 // b) visual apperance to make the first layer of "bricks" look more
387 // square.
388 $vls = $this->linespacing*0.6;
390 $ds = $hls*($apa-$vls)/$apa;
391 // Get the slope for the "perspective line" going from bottom right
392 // corner to top left corner of the "first" brick.
394 // Uncomment the following lines if you want to get a visual understanding
395 // of what this helpline does. BTW this mimics the way you would get the
396 // perspective right when drawing on paper.
398 $x0 = $middle;
399 $y0 = $this->rect->ye;
400 $len=floor(($this->rect->ye-$this->rect->y)/$vls);
401 $x1 = $middle+round($len*$ds);
402 $y1 = $this->rect->ye-$len*$vls;
403 $aImg->PushColor("red");
404 $aImg->Line($x0,$y0,$x1,$y1);
405 $aImg->PopColor();
408 $y -= $vls;
409 $k=($this->rect->ye-($this->rect->ye-$vls))/($middle-($middle-$ds));
410 $dist = $hls;
411 while( $y>$this->rect->y ) {
412 $aImg->Line($this->rect->x,$y,$this->rect->xe,$y);
413 $adj = $k*$dist/(1+$dist*$k/$apa);
414 if( $adj < 2 ) $adj=1;
415 $y = $this->rect->ye - round($adj);
416 $dist += $hls;
421 //=====================================================================
422 // Class RectPatternCross
423 // Vert/Hor crosses
424 //=====================================================================
425 class RectPatternCross extends RectPattern {
426 var $vert=null;
427 var $hor=null;
428 function RectPatternCross($aColor="black",$aWeight=1) {
429 parent::RectPattern($aColor,$aWeight);
430 $this->vert = new RectPatternVert($aColor,$aWeight);
431 $this->hor = new RectPatternHor($aColor,$aWeight);
434 function SetOrder($aDepth) {
435 $this->vert->SetOrder($aDepth);
436 $this->hor->SetOrder($aDepth);
439 function SetPos(&$aRect) {
440 parent::SetPos($aRect);
441 $this->vert->SetPos($aRect);
442 $this->hor->SetPos($aRect);
445 function SetDensity($aDens) {
446 $this->vert->SetDensity($aDens);
447 $this->hor->SetDensity($aDens);
450 function DoPattern(&$aImg) {
451 $this->vert->DoPattern($aImg);
452 $this->hor->DoPattern($aImg);
456 //=====================================================================
457 // Class RectPatternDiagCross
458 // Vert/Hor crosses
459 //=====================================================================
461 class RectPatternDiagCross extends RectPattern {
462 var $left=null;
463 var $right=null;
464 function RectPatternDiagCross($aColor="black",$aWeight=1) {
465 parent::RectPattern($aColor,$aWeight);
466 $this->right = new RectPatternRDiag($aColor,$aWeight);
467 $this->left = new RectPatternLDiag($aColor,$aWeight);
470 function SetOrder($aDepth) {
471 $this->left->SetOrder($aDepth);
472 $this->right->SetOrder($aDepth);
475 function SetPos(&$aRect) {
476 parent::SetPos($aRect);
477 $this->left->SetPos($aRect);
478 $this->right->SetPos($aRect);
481 function SetDensity($aDens) {
482 $this->left->SetDensity($aDens);
483 $this->right->SetDensity($aDens);
486 function DoPattern(&$aImg) {
487 $this->left->DoPattern($aImg);
488 $this->right->DoPattern($aImg);
493 //=====================================================================
494 // Class RectPatternFactory
495 // Factory class for rectangular pattern
496 //=====================================================================
497 class RectPatternFactory {
498 function RectPatternFactory() {
499 // Empty
501 function Create($aPattern,$aColor,$aWeight=1) {
502 switch($aPattern) {
503 case BAND_RDIAG:
504 $obj = new RectPatternRDiag($aColor,$aWeight);
505 break;
506 case BAND_LDIAG:
507 $obj = new RectPatternLDiag($aColor,$aWeight);
508 break;
509 case BAND_SOLID:
510 $obj = new RectPatternSolid($aColor,$aWeight);
511 break;
512 case BAND_VLINE:
513 $obj = new RectPatternVert($aColor,$aWeight);
514 break;
515 case BAND_HLINE:
516 $obj = new RectPatternHor($aColor,$aWeight);
517 break;
518 case BAND_3DPLANE:
519 $obj = new RectPattern3DPlane($aColor,$aWeight);
520 break;
521 case BAND_HVCROSS:
522 $obj = new RectPatternCross($aColor,$aWeight);
523 break;
524 case BAND_DIAGCROSS:
525 $obj = new RectPatternDiagCross($aColor,$aWeight);
526 break;
527 default:
528 JpGraphError::RaiseL(16003,$aPattern);
529 //(" Unknown pattern specification ($aPattern)");
531 return $obj;
536 //=====================================================================
537 // Class PlotBand
538 // Factory class which is used by the client.
539 // It is responsible for factoring the corresponding pattern
540 // concrete class.
541 //=====================================================================
542 class PlotBand {
543 var $prect=null;
544 var $depth;
545 var $dir, $min, $max;
547 function PlotBand($aDir,$aPattern,$aMin,$aMax,$aColor="black",$aWeight=1,$aDepth=DEPTH_BACK) {
548 $f = new RectPatternFactory();
549 $this->prect = $f->Create($aPattern,$aColor,$aWeight);
550 if( is_numeric($aMin) && is_numeric($aMax) && ($aMin > $aMax) )
551 JpGraphError::RaiseL(16004);
552 //('Min value for plotband is larger than specified max value. Please correct.');
553 $this->dir = $aDir;
554 $this->min = $aMin;
555 $this->max = $aMax;
556 $this->depth=$aDepth;
559 // Set position. aRect contains absolute image coordinates
560 function SetPos(&$aRect) {
561 assert( $this->prect != null ) ;
562 $this->prect->SetPos($aRect);
565 function ShowFrame($aFlag=true) {
566 $this->prect->ShowFrame($aFlag);
569 // Set z-order. In front of pplot or in the back
570 function SetOrder($aDepth) {
571 $this->depth=$aDepth;
574 function SetDensity($aDens) {
575 $this->prect->SetDensity($aDens);
578 function GetDir() {
579 return $this->dir;
582 function GetMin() {
583 return $this->min;
586 function GetMax() {
587 return $this->max;
590 // Display band
591 function Stroke(&$aImg,&$aXScale,&$aYScale) {
592 assert( $this->prect != null ) ;
593 if( $this->dir == HORIZONTAL ) {
594 if( $this->min === 'min' ) $this->min = $aYScale->GetMinVal();
595 if( $this->max === 'max' ) $this->max = $aYScale->GetMaxVal();
597 // Only draw the bar if it actually appears in the range
598 if ($this->min < $aYScale->GetMaxVal() && $this->max > $aYScale->GetMinVal()) {
600 // Trucate to limit of axis
601 $this->min = max($this->min, $aYScale->GetMinVal());
602 $this->max = min($this->max, $aYScale->GetMaxVal());
604 $x=$aXScale->scale_abs[0];
605 $y=$aYScale->Translate($this->max);
606 $width=$aXScale->scale_abs[1]-$aXScale->scale_abs[0]+1;
607 $height=abs($y-$aYScale->Translate($this->min))+1;
608 $this->prect->SetPos(new Rectangle($x,$y,$width,$height));
609 $this->prect->Stroke($aImg);
612 else { // VERTICAL
613 if( $this->min === 'min' ) $this->min = $aXScale->GetMinVal();
614 if( $this->max === 'max' ) $this->max = $aXScale->GetMaxVal();
616 // Only draw the bar if it actually appears in the range
617 if ($this->min < $aXScale->GetMaxVal() && $this->max > $aXScale->GetMinVal()) {
619 // Trucate to limit of axis
620 $this->min = max($this->min, $aXScale->GetMinVal());
621 $this->max = min($this->max, $aXScale->GetMaxVal());
623 $y=$aYScale->scale_abs[1];
624 $x=$aXScale->Translate($this->min);
625 $height=abs($aYScale->scale_abs[1]-$aYScale->scale_abs[0]);
626 $width=abs($x-$aXScale->Translate($this->max));
627 $this->prect->SetPos(new Rectangle($x,$y,$width,$height));
628 $this->prect->Stroke($aImg);