source: trunk/client/modules/Elezioni/grafici/jpgraph_canvtools.php@ 430

Last change on this file since 430 was 284, checked in by roby, 6 years ago
File size: 16.5 KB
RevLine 
[2]1<?php
2/*=======================================================================
[284]3 // File: JPGRAPH_CANVTOOLS.PHP
4 // Description: Some utilities for text and shape drawing on a canvas
5 // Created: 2002-08-23
6 // Ver: $Id: jpgraph_canvtools.php 1857 2009-09-28 14:38:14Z ljp $
7 //
8 // Copyright (c) Asial Corporation. All rights reserved.
9 //========================================================================
10 */
[2]11
12define('CORNER_TOPLEFT',0);
13define('CORNER_TOPRIGHT',1);
14define('CORNER_BOTTOMRIGHT',2);
15define('CORNER_BOTTOMLEFT',3);
16
17
18//===================================================
19// CLASS CanvasScale
20// Description: Define a scale for canvas so we
21// can abstract away with absolute pixels
22//===================================================
[284]23
[2]24class CanvasScale {
25 private $g;
26 private $w,$h;
27 private $ixmin=0,$ixmax=10,$iymin=0,$iymax=10;
28
[284]29 function __construct($graph,$xmin=0,$xmax=10,$ymin=0,$ymax=10) {
30 $this->g = $graph;
31 $this->w = $graph->img->width;
32 $this->h = $graph->img->height;
33 $this->ixmin = $xmin;
34 $this->ixmax = $xmax;
35 $this->iymin = $ymin;
36 $this->iymax = $ymax;
[2]37 }
[284]38
[2]39 function Set($xmin=0,$xmax=10,$ymin=0,$ymax=10) {
[284]40 $this->ixmin = $xmin;
41 $this->ixmax = $xmax;
42 $this->iymin = $ymin;
43 $this->iymax = $ymax;
[2]44 }
45
[284]46 function Get() {
47 return array($this->ixmin,$this->ixmax,$this->iymin,$this->iymax);
48 }
49
[2]50 function Translate($x,$y) {
[284]51 $xp = round(($x-$this->ixmin)/($this->ixmax - $this->ixmin) * $this->w);
52 $yp = round(($y-$this->iymin)/($this->iymax - $this->iymin) * $this->h);
53 return array($xp,$yp);
[2]54 }
55
56 function TranslateX($x) {
[284]57 $xp = round(($x-$this->ixmin)/($this->ixmax - $this->ixmin) * $this->w);
58 return $xp;
[2]59 }
60
61 function TranslateY($y) {
[284]62 $yp = round(($y-$this->iymin)/($this->iymax - $this->iymin) * $this->h);
63 return $yp;
[2]64 }
65
66}
67
68
69//===================================================
70// CLASS Shape
71// Description: Methods to draw shapes on canvas
72//===================================================
73class Shape {
74 private $img,$scale;
75
[284]76 function __construct($aGraph,$scale) {
77 $this->img = $aGraph->img;
78 $this->img->SetColor('black');
79 $this->scale = $scale;
[2]80 }
81
82 function SetColor($aColor) {
[284]83 $this->img->SetColor($aColor);
[2]84 }
85
86 function Line($x1,$y1,$x2,$y2) {
[284]87 list($x1,$y1) = $this->scale->Translate($x1,$y1);
88 list($x2,$y2) = $this->scale->Translate($x2,$y2);
89 $this->img->Line($x1,$y1,$x2,$y2);
[2]90 }
91
[284]92 function SetLineWeight($aWeight) {
93 $this->img->SetLineWeight($aWeight);
94 }
95
[2]96 function Polygon($p,$aClosed=false) {
[284]97 $n=count($p);
98 for($i=0; $i < $n; $i+=2 ) {
99 $p[$i] = $this->scale->TranslateX($p[$i]);
100 $p[$i+1] = $this->scale->TranslateY($p[$i+1]);
101 }
102 $this->img->Polygon($p,$aClosed);
[2]103 }
104
105 function FilledPolygon($p) {
[284]106 $n=count($p);
107 for($i=0; $i < $n; $i+=2 ) {
108 $p[$i] = $this->scale->TranslateX($p[$i]);
109 $p[$i+1] = $this->scale->TranslateY($p[$i+1]);
110 }
111 $this->img->FilledPolygon($p);
[2]112 }
113
[284]114
[2]115 // Draw a bezier curve with defining points in the $aPnts array
116 // using $aSteps steps.
117 // 0=x0, 1=y0
118 // 2=x1, 3=y1
119 // 4=x2, 5=y2
120 // 6=x3, 7=y3
121 function Bezier($p,$aSteps=40) {
[284]122 $x0 = $p[0];
123 $y0 = $p[1];
124 // Calculate coefficients
125 $cx = 3*($p[2]-$p[0]);
126 $bx = 3*($p[4]-$p[2])-$cx;
127 $ax = $p[6]-$p[0]-$cx-$bx;
128 $cy = 3*($p[3]-$p[1]);
129 $by = 3*($p[5]-$p[3])-$cy;
130 $ay = $p[7]-$p[1]-$cy-$by;
[2]131
[284]132 // Step size
133 $delta = 1.0/$aSteps;
[2]134
[284]135 $x_old = $x0;
136 $y_old = $y0;
137 for($t=$delta; $t<=1.0; $t+=$delta) {
138 $tt = $t*$t; $ttt=$tt*$t;
139 $x = $ax*$ttt + $bx*$tt + $cx*$t + $x0;
140 $y = $ay*$ttt + $by*$tt + $cy*$t + $y0;
141 $this->Line($x_old,$y_old,$x,$y);
142 $x_old = $x;
143 $y_old = $y;
144 }
145 $this->Line($x_old,$y_old,$p[6],$p[7]);
[2]146 }
147
148 function Rectangle($x1,$y1,$x2,$y2) {
[284]149 list($x1,$y1) = $this->scale->Translate($x1,$y1);
150 list($x2,$y2) = $this->scale->Translate($x2,$y2);
151 $this->img->Rectangle($x1,$y1,$x2,$y2);
[2]152 }
153
154 function FilledRectangle($x1,$y1,$x2,$y2) {
[284]155 list($x1,$y1) = $this->scale->Translate($x1,$y1);
156 list($x2,$y2) = $this->scale->Translate($x2,$y2);
157 $this->img->FilledRectangle($x1,$y1,$x2,$y2);
[2]158 }
[284]159
[2]160 function Circle($x1,$y1,$r) {
[284]161 list($x1,$y1) = $this->scale->Translate($x1,$y1);
162 if( $r >= 0 )
163 $r = $this->scale->TranslateX($r);
164 else
165 $r = -$r;
166 $this->img->Circle($x1,$y1,$r);
[2]167 }
168
169 function FilledCircle($x1,$y1,$r) {
[284]170 list($x1,$y1) = $this->scale->Translate($x1,$y1);
171 if( $r >= 0 )
172 $r = $this->scale->TranslateX($r);
173 else
174 $r = -$r;
175 $this->img->FilledCircle($x1,$y1,$r);
[2]176 }
177
[284]178 function RoundedRectangle($x1,$y1,$x2,$y2,$r=null) {
179 list($x1,$y1) = $this->scale->Translate($x1,$y1);
180 list($x2,$y2) = $this->scale->Translate($x2,$y2);
[2]181
[284]182 if( $r == null )
183 $r = 5;
184 elseif( $r >= 0 )
185 $r = $this->scale->TranslateX($r);
186 else
187 $r = -$r;
188 $this->img->RoundedRectangle($x1,$y1,$x2,$y2,$r);
[2]189 }
190
[284]191 function FilledRoundedRectangle($x1,$y1,$x2,$y2,$r=null) {
192 list($x1,$y1) = $this->scale->Translate($x1,$y1);
193 list($x2,$y2) = $this->scale->Translate($x2,$y2);
[2]194
[284]195 if( $r == null )
196 $r = 5;
197 elseif( $r > 0 )
198 $r = $this->scale->TranslateX($r);
199 else
200 $r = -$r;
201 $this->img->FilledRoundedRectangle($x1,$y1,$x2,$y2,$r);
[2]202 }
203
204 function ShadowRectangle($x1,$y1,$x2,$y2,$fcolor=false,$shadow_width=null,$shadow_color=array(102,102,102)) {
[284]205 list($x1,$y1) = $this->scale->Translate($x1,$y1);
206 list($x2,$y2) = $this->scale->Translate($x2,$y2);
207 if( $shadow_width == null )
208 $shadow_width=4;
209 else
210 $shadow_width=$this->scale->TranslateX($shadow_width);
211 $this->img->ShadowRectangle($x1,$y1,$x2,$y2,$fcolor,$shadow_width,$shadow_color);
[2]212 }
213
214 function SetTextAlign($halign,$valign="bottom") {
[284]215 $this->img->SetTextAlign($halign,$valign="bottom");
[2]216 }
217
218 function StrokeText($x1,$y1,$txt,$dir=0,$paragraph_align="left") {
[284]219 list($x1,$y1) = $this->scale->Translate($x1,$y1);
220 $this->img->StrokeText($x1,$y1,$txt,$dir,$paragraph_align);
[2]221 }
222
223 // A rounded rectangle where one of the corner has been moved "into" the
224 // rectangle 'iw' width and 'ih' height. Corners:
225 // 0=Top left, 1=top right, 2=bottom right, 3=bottom left
226 function IndentedRectangle($xt,$yt,$w,$h,$iw=0,$ih=0,$aCorner=3,$aFillColor="",$r=4) {
227
[284]228 list($xt,$yt) = $this->scale->Translate($xt,$yt);
229 list($w,$h) = $this->scale->Translate($w,$h);
230 list($iw,$ih) = $this->scale->Translate($iw,$ih);
[2]231
[284]232 $xr = $xt + $w - 0;
233 $yl = $yt + $h - 0;
[2]234
[284]235 switch( $aCorner ) {
236 case 0: // Upper left
237
238 // Bottom line, left & right arc
239 $this->img->Line($xt+$r,$yl,$xr-$r,$yl);
240 $this->img->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180);
241 $this->img->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90);
[2]242
[284]243 // Right line, Top right arc
244 $this->img->Line($xr,$yt+$r,$xr,$yl-$r);
245 $this->img->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360);
[2]246
[284]247 // Top line, Top left arc
248 $this->img->Line($xt+$iw+$r,$yt,$xr-$r,$yt);
249 $this->img->Arc($xt+$iw+$r,$yt+$r,$r*2,$r*2,180,270);
[2]250
[284]251 // Left line
252 $this->img->Line($xt,$yt+$ih+$r,$xt,$yl-$r);
[2]253
[284]254 // Indent horizontal, Lower left arc
255 $this->img->Line($xt+$r,$yt+$ih,$xt+$iw-$r,$yt+$ih);
256 $this->img->Arc($xt+$r,$yt+$ih+$r,$r*2,$r*2,180,270);
[2]257
[284]258 // Indent vertical, Indent arc
259 $this->img->Line($xt+$iw,$yt+$r,$xt+$iw,$yt+$ih-$r);
260 $this->img->Arc($xt+$iw-$r,$yt+$ih-$r,$r*2,$r*2,0,90);
[2]261
[284]262 if( $aFillColor != '' ) {
263 $bc = $this->img->current_color_name;
264 $this->img->PushColor($aFillColor);
265 $this->img->FillToBorder($xr-$r,$yl-$r,$bc);
266 $this->img->PopColor();
267 }
[2]268
[284]269 break;
[2]270
[284]271 case 1: // Upper right
[2]272
[284]273 // Bottom line, left & right arc
274 $this->img->Line($xt+$r,$yl,$xr-$r,$yl);
275 $this->img->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180);
276 $this->img->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90);
[2]277
[284]278 // Left line, Top left arc
279 $this->img->Line($xt,$yt+$r,$xt,$yl-$r);
280 $this->img->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270);
[2]281
[284]282 // Top line, Top right arc
283 $this->img->Line($xt+$r,$yt,$xr-$iw-$r,$yt);
284 $this->img->Arc($xr-$iw-$r,$yt+$r,$r*2,$r*2,270,360);
[2]285
[284]286 // Right line
287 $this->img->Line($xr,$yt+$ih+$r,$xr,$yl-$r);
[2]288
[284]289 // Indent horizontal, Lower right arc
290 $this->img->Line($xr-$iw+$r,$yt+$ih,$xr-$r,$yt+$ih);
291 $this->img->Arc($xr-$r,$yt+$ih+$r,$r*2,$r*2,270,360);
[2]292
[284]293 // Indent vertical, Indent arc
294 $this->img->Line($xr-$iw,$yt+$r,$xr-$iw,$yt+$ih-$r);
295 $this->img->Arc($xr-$iw+$r,$yt+$ih-$r,$r*2,$r*2,90,180);
[2]296
[284]297 if( $aFillColor != '' ) {
298 $bc = $this->img->current_color_name;
299 $this->img->PushColor($aFillColor);
300 $this->img->FillToBorder($xt+$r,$yl-$r,$bc);
301 $this->img->PopColor();
302 }
[2]303
[284]304 break;
[2]305
[284]306 case 2: // Lower right
307 // Top line, Top left & Top right arc
308 $this->img->Line($xt+$r,$yt,$xr-$r,$yt);
309 $this->img->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270);
310 $this->img->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360);
[2]311
[284]312 // Left line, Bottom left arc
313 $this->img->Line($xt,$yt+$r,$xt,$yl-$r);
314 $this->img->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180);
[2]315
[284]316 // Bottom line, Bottom right arc
317 $this->img->Line($xt+$r,$yl,$xr-$iw-$r,$yl);
318 $this->img->Arc($xr-$iw-$r,$yl-$r,$r*2,$r*2,0,90);
[2]319
[284]320 // Right line
321 $this->img->Line($xr,$yt+$r,$xr,$yl-$ih-$r);
322
323 // Indent horizontal, Lower right arc
324 $this->img->Line($xr-$r,$yl-$ih,$xr-$iw+$r,$yl-$ih);
325 $this->img->Arc($xr-$r,$yl-$ih-$r,$r*2,$r*2,0,90);
[2]326
[284]327 // Indent vertical, Indent arc
328 $this->img->Line($xr-$iw,$yl-$r,$xr-$iw,$yl-$ih+$r);
329 $this->img->Arc($xr-$iw+$r,$yl-$ih+$r,$r*2,$r*2,180,270);
[2]330
[284]331 if( $aFillColor != '' ) {
332 $bc = $this->img->current_color_name;
333 $this->img->PushColor($aFillColor);
334 $this->img->FillToBorder($xt+$r,$yt+$r,$bc);
335 $this->img->PopColor();
336 }
[2]337
[284]338 break;
[2]339
[284]340 case 3: // Lower left
341 // Top line, Top left & Top right arc
342 $this->img->Line($xt+$r,$yt,$xr-$r,$yt);
343 $this->img->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270);
344 $this->img->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360);
[2]345
[284]346 // Right line, Bottom right arc
347 $this->img->Line($xr,$yt+$r,$xr,$yl-$r);
348 $this->img->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90);
[2]349
[284]350 // Bottom line, Bottom left arc
351 $this->img->Line($xt+$iw+$r,$yl,$xr-$r,$yl);
352 $this->img->Arc($xt+$iw+$r,$yl-$r,$r*2,$r*2,90,180);
[2]353
[284]354 // Left line
355 $this->img->Line($xt,$yt+$r,$xt,$yl-$ih-$r);
356
357 // Indent horizontal, Lower left arc
358 $this->img->Line($xt+$r,$yl-$ih,$xt+$iw-$r,$yl-$ih);
359 $this->img->Arc($xt+$r,$yl-$ih-$r,$r*2,$r*2,90,180);
[2]360
[284]361 // Indent vertical, Indent arc
362 $this->img->Line($xt+$iw,$yl-$ih+$r,$xt+$iw,$yl-$r);
363 $this->img->Arc($xt+$iw-$r,$yl-$ih+$r,$r*2,$r*2,270,360);
364
365 if( $aFillColor != '' ) {
366 $bc = $this->img->current_color_name;
367 $this->img->PushColor($aFillColor);
368 $this->img->FillToBorder($xr-$r,$yt+$r,$bc);
369 $this->img->PopColor();
370 }
371
372 break;
373 }
[2]374 }
375}
376
377
378//===================================================
379// CLASS RectangleText
[284]380// Description: Draws a text paragraph inside a
[2]381// rounded, possible filled, rectangle.
382//===================================================
383class CanvasRectangleText {
384 private $ix,$iy,$iw,$ih,$ir=4;
385 private $iTxt,$iColor='black',$iFillColor='',$iFontColor='black';
386 private $iParaAlign='center';
387 private $iAutoBoxMargin=5;
388 private $iShadowWidth=3,$iShadowColor='';
389
[284]390 function __construct($aTxt='',$xl=0,$yt=0,$w=0,$h=0) {
391 $this->iTxt = new Text($aTxt);
392 $this->ix = $xl;
393 $this->iy = $yt;
394 $this->iw = $w;
395 $this->ih = $h;
[2]396 }
[284]397
[2]398 function SetShadow($aColor='gray',$aWidth=3) {
[284]399 $this->iShadowColor = $aColor;
400 $this->iShadowWidth = $aWidth;
[2]401 }
402
403 function SetFont($FontFam,$aFontStyle,$aFontSize=12) {
[284]404 $this->iTxt->SetFont($FontFam,$aFontStyle,$aFontSize);
[2]405 }
406
407 function SetTxt($aTxt) {
[284]408 $this->iTxt->Set($aTxt);
[2]409 }
410
411 function ParagraphAlign($aParaAlign) {
[284]412 $this->iParaAlign = $aParaAlign;
[2]413 }
414
415 function SetFillColor($aFillColor) {
[284]416 $this->iFillColor = $aFillColor;
[2]417 }
418
419 function SetAutoMargin($aMargin) {
[284]420 $this->iAutoBoxMargin=$aMargin;
[2]421 }
422
423 function SetColor($aColor) {
[284]424 $this->iColor = $aColor;
[2]425 }
426
427 function SetFontColor($aColor) {
[284]428 $this->iFontColor = $aColor;
[2]429 }
430
431 function SetPos($xl=0,$yt=0,$w=0,$h=0) {
[284]432 $this->ix = $xl;
433 $this->iy = $yt;
434 $this->iw = $w;
435 $this->ih = $h;
[2]436 }
437
438 function Pos($xl=0,$yt=0,$w=0,$h=0) {
[284]439 $this->ix = $xl;
440 $this->iy = $yt;
441 $this->iw = $w;
442 $this->ih = $h;
[2]443 }
444
445 function Set($aTxt,$xl,$yt,$w=0,$h=0) {
[284]446 $this->iTxt->Set($aTxt);
447 $this->ix = $xl;
448 $this->iy = $yt;
449 $this->iw = $w;
450 $this->ih = $h;
[2]451 }
452
453 function SetCornerRadius($aRad=5) {
[284]454 $this->ir = $aRad;
[2]455 }
456
457 function Stroke($aImg,$scale) {
458
[284]459 // If coordinates are specifed as negative this means we should
460 // treat them as abolsute (pixels) coordinates
461 if( $this->ix > 0 ) {
462 $this->ix = $scale->TranslateX($this->ix) ;
463 }
464 else {
465 $this->ix = -$this->ix;
466 }
[2]467
[284]468 if( $this->iy > 0 ) {
469 $this->iy = $scale->TranslateY($this->iy) ;
470 }
471 else {
472 $this->iy = -$this->iy;
473 }
474
475 list($this->iw,$this->ih) = $scale->Translate($this->iw,$this->ih) ;
[2]476
[284]477 if( $this->iw == 0 )
478 $this->iw = round($this->iTxt->GetWidth($aImg) + $this->iAutoBoxMargin);
479 if( $this->ih == 0 ) {
480 $this->ih = round($this->iTxt->GetTextHeight($aImg) + $this->iAutoBoxMargin);
481 }
[2]482
[284]483 if( $this->iShadowColor != '' ) {
484 $aImg->PushColor($this->iShadowColor);
485 $aImg->FilledRoundedRectangle($this->ix+$this->iShadowWidth,
486 $this->iy+$this->iShadowWidth,
487 $this->ix+$this->iw-1+$this->iShadowWidth,
488 $this->iy+$this->ih-1+$this->iShadowWidth,
489 $this->ir);
490 $aImg->PopColor();
491 }
[2]492
[284]493 if( $this->iFillColor != '' ) {
494 $aImg->PushColor($this->iFillColor);
495 $aImg->FilledRoundedRectangle($this->ix,$this->iy,
496 $this->ix+$this->iw-1,
497 $this->iy+$this->ih-1,
498 $this->ir);
499 $aImg->PopColor();
500 }
[2]501
[284]502 if( $this->iColor != '' ) {
503 $aImg->PushColor($this->iColor);
504 $aImg->RoundedRectangle($this->ix,$this->iy,
505 $this->ix+$this->iw-1,
506 $this->iy+$this->ih-1,
507 $this->ir);
508 $aImg->PopColor();
509 }
[2]510
[284]511 $this->iTxt->Align('center','center');
512 $this->iTxt->ParagraphAlign($this->iParaAlign);
513 $this->iTxt->SetColor($this->iFontColor);
514 $this->iTxt->Stroke($aImg, $this->ix+$this->iw/2, $this->iy+$this->ih/2);
515
516 return array($this->iw, $this->ih);
517
[2]518 }
519
520}
521
522
[284]523?>
Note: See TracBrowser for help on using the repository browser.