Merge branch '138-toggle-free-look-with-hotkey' into 'main/atys-live'
[ryzomcore.git] / web / public_php / admin / jpgraph / jpgraph_plotmark.inc
blobc555aab6e979f910d757be3b879926c6b6d0e535
1 <?php\r
2 //=======================================================================\r
3 // File:        JPGRAPH_PLOTMARK.PHP\r
4 // Description: Class file. Handles plotmarks\r
5 // Created:     2003-03-21\r
6 // Author:      Johan Persson (johanp@aditus.nu)\r
7 // Ver:         $Id: jpgraph_plotmark.inc,v 1.1 2006/07/07 13:37:14 powles Exp $\r
8 //\r
9 // Copyright (c) Aditus Consulting. All rights reserved.\r
10 //========================================================================\r
13 //========================================================================\r
14 // CLASS ImgData\r
15 // Description: Base class for all image data classes that contains the \r
16 // real image data.\r
17 //========================================================================\r
18 class ImgData {\r
19     var $name = '';             // Each subclass gives a name\r
20     var $an = array();          // Data array names\r
21     var $colors = array();      // Available colors\r
22     var $index  = array();      // Index for colors\r
23     var $maxidx = 0 ;           // Max color index\r
24     var $anchor_x=0.5, $anchor_y=0.5 ;    // Where is the center of the image\r
25     // Create a GD image from the data and return a GD handle\r
26     function GetImg($aMark,$aIdx) {\r
27         $n = $this->an[$aMark];\r
28         if( is_string($aIdx) ) {\r
29             if( !in_array($aIdx,$this->colors) ) {\r
30                 JpGraphError::RaiseL(23001,$this->name,$aIdx); //('This marker "'.($this->name).'" does not exist in color: '.$aIdx);\r
31             }\r
32             $idx = $this->index[$aIdx];\r
33         }\r
34         elseif( !is_integer($aIdx) || \r
35                 (is_integer($aIdx) && $aIdx > $this->maxidx ) ) {\r
36             JpGraphError::RaiseL(23002,$this->name);\r
37 //('Mark color index too large for marker "'.($this->name).'"');\r
38         }\r
39         else\r
40             $idx = $aIdx ;\r
41         return Image::CreateFromString(base64_decode($this->{$n}[$idx][1]));   \r
42     }\r
43     function GetAnchor() {\r
44         return array($this->anchor_x,$this->anchor_y);\r
45     }\r
46 }\r
49 // Keep a global flag cache to reduce memory usage\r
50 $_gFlagCache=array(\r
51     1 => null,\r
52     2 => null,\r
53     3 => null,\r
54     4 => null,\r
55 );\r
56 // Only supposed to b called as statics\r
57 class FlagCache {\r
58     function GetFlagImgByName($aSize,$aName) {\r
59         global $_gFlagCache;\r
60         require_once('jpgraph_flags.php');\r
61         if( $_gFlagCache[$aSize] === null ) {\r
62             $_gFlagCache[$aSize] = new FlagImages($aSize);\r
63         }\r
64         $f =& $_gFlagCache[$aSize];\r
65         $idx = $f->GetIdxByName($aName,$aFullName);\r
66         return $f->GetImgByIdx($idx);\r
67     }\r
68 }\r
70 //===================================================\r
71 // CLASS PlotMark\r
72 // Description: Handles the plot marks in graphs\r
73 //===================================================\r
74 class PlotMark {\r
75     var $title, $show=true;\r
76     var $type,$weight=1;\r
77     var $color="black", $width=4, $fill_color="blue";\r
78     var $yvalue,$xvalue='',$csimtarget,$csimalt,$csimareas;\r
79     var $iFormatCallback="";\r
80     var $iFormatCallback2="";\r
81     var $markimg='',$iScale=1.0;\r
82     var $oldfilename='',$iFileName='';\r
83     var $imgdata_balls = null;\r
84     var $imgdata_diamonds = null;\r
85     var $imgdata_squares = null;\r
86     var $imgdata_bevels = null;\r
87     var $imgdata_stars = null;\r
88     var $imgdata_pushpins = null;\r
90 //--------------\r
91 // CONSTRUCTOR\r
92     function __construct() {\r
93         $this->title = new Text();\r
94         $this->title->Hide();\r
95         $this->csimareas = '';\r
96         $this->csimalt = '';\r
97         $this->type=-1;\r
98     }\r
99 //---------------\r
100 // PUBLIC METHODS       \r
101     function SetType($aType,$aFileName='',$aScale=1.0) {\r
102         $this->type = $aType;\r
103         if( $aType == MARK_IMG && $aFileName=='' ) {\r
104             JpGraphError::RaiseL(23003);//('A filename must be specified if you set the mark type to MARK_IMG.');\r
105         }\r
106         $this->iFileName = $aFileName;\r
107         $this->iScale = $aScale;\r
108     }\r
109         \r
110     function SetCallback($aFunc) {\r
111         $this->iFormatCallback = $aFunc;\r
112     }\r
114     function SetCallbackYX($aFunc) {\r
115         $this->iFormatCallback2 = $aFunc;\r
116     }\r
117     \r
118     function GetType() {\r
119         return $this->type;\r
120     }\r
121         \r
122     function SetColor($aColor) {\r
123         $this->color=$aColor;\r
124     }\r
125         \r
126     function SetFillColor($aFillColor) {\r
127         $this->fill_color = $aFillColor;\r
128     }\r
130     function SetWeight($aWeight) {\r
131         $this->weight = $aWeight;\r
132     }\r
134     // Synonym for SetWidth()\r
135     function SetSize($aWidth) {\r
136         $this->width=$aWidth;\r
137     }\r
138         \r
139     function SetWidth($aWidth) {\r
140         $this->width=$aWidth;\r
141     }\r
143     function SetDefaultWidth() {\r
144         switch( $this->type ) {\r
145             case MARK_CIRCLE: \r
146             case MARK_FILLEDCIRCLE: \r
147                 $this->width=4;\r
148                 break;\r
149             default:\r
150                 $this->width=7;\r
151         }\r
152     }\r
153         \r
154     function GetWidth() {\r
155         return $this->width;\r
156     }\r
157         \r
158     function Hide($aHide=true) {\r
159         $this->show = !$aHide;\r
160     }\r
161         \r
162     function Show($aShow=true) {\r
163         $this->show = $aShow;\r
164     }\r
166     function SetCSIMAltVal($aY,$aX='') {\r
167         $this->yvalue=$aY; \r
168         $this->xvalue=$aX; \r
169     }\r
170     \r
171     function SetCSIMTarget($aTarget) {\r
172         $this->csimtarget=$aTarget;\r
173     }\r
174     \r
175     function SetCSIMAlt($aAlt) {\r
176         $this->csimalt=$aAlt;\r
177     }\r
178     \r
179     function GetCSIMAreas(){\r
180         return $this->csimareas;\r
181     }\r
182         \r
183     function AddCSIMPoly($aPts) {\r
184         $coords = round($aPts[0]).", ".round($aPts[1]);\r
185         $n = count($aPts)/2;\r
186         for( $i=1; $i < $n; ++$i){\r
187             $coords .= ", ".round($aPts[2*$i]).", ".round($aPts[2*$i+1]);\r
188         }\r
189         $this->csimareas="";    \r
190         if( !empty($this->csimtarget) ) {\r
191             $this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->csimtarget."\"";\r
192             if( !empty($this->csimalt) ) {                                                                              \r
193                 $tmp=sprintf($this->csimalt,$this->yvalue,$this->xvalue);\r
194                 $this->csimareas .= " title=\"$tmp\"";\r
195             }\r
196             $this->csimareas .= " alt=\"$tmp\" />\n";\r
197         }\r
198     }\r
199     \r
200     function AddCSIMCircle($x,$y,$r) {\r
201         $x = round($x); $y=round($y); $r=round($r);\r
202         $this->csimareas="";    \r
203         if( !empty($this->csimtarget) ) {\r
204             $this->csimareas .= "<area shape=\"circle\" coords=\"$x,$y,$r\" href=\"".$this->csimtarget."\"";\r
205             if( !empty($this->csimalt) ) {                                                                              \r
206                 $tmp=sprintf($this->csimalt,$this->yvalue,$this->xvalue);\r
207                 $this->csimareas .= " title=\"$tmp\"";\r
208             }\r
209             $this->csimareas .= " alt=\"$tmp\" />\n";        \r
210         }\r
211     }\r
212         \r
213     function Stroke(&$img,$x,$y) {\r
214         if( !$this->show ) return;\r
216         if( $this->iFormatCallback != '' || $this->iFormatCallback2 != '' ) {\r
218             if( $this->iFormatCallback != '' ) {\r
219                 $f = $this->iFormatCallback;\r
220                 list($width,$color,$fcolor) = call_user_func($f,$this->yvalue);\r
221                 $filename = $this->iFileName;\r
222                 $imgscale = $this->iScale;\r
223             }\r
224             else {\r
225                 $f = $this->iFormatCallback2;\r
226                 list($width,$color,$fcolor,$filename,$imgscale) = call_user_func($f,$this->yvalue,$this->xvalue);\r
227                 if( $filename=="" ) $filename = $this->iFileName;\r
228                 if( $imgscale=="" ) $imgscale = $this->iScale;\r
229             }\r
231             if( $width=="" ) $width = $this->width;\r
232             if( $color=="" ) $color = $this->color;\r
233             if( $fcolor=="" ) $fcolor = $this->fill_color;\r
235         }\r
236         else {\r
237             $fcolor = $this->fill_color;\r
238             $color = $this->color;\r
239             $width = $this->width;\r
240             $filename = $this->iFileName;\r
241             $imgscale = $this->iScale;\r
242         }\r
244         if( $this->type == MARK_IMG ||\r
245             ($this->type >= MARK_FLAG1 && $this->type <= MARK_FLAG4 ) ||\r
246             $this->type >= MARK_IMG_PUSHPIN ) {\r
248             // Note: For the builtin images we use the "filename" parameter\r
249             // to denote the color\r
250             $anchor_x = 0.5;\r
251             $anchor_y = 0.5; \r
252             switch( $this->type ) {\r
253                 case MARK_FLAG1:\r
254                 case MARK_FLAG2:\r
255                 case MARK_FLAG3:\r
256                 case MARK_FLAG4:\r
257                     $this->markimg = FlagCache::GetFlagImgByName($this->type-MARK_FLAG1+1,$filename);\r
258                     break;\r
260                 case MARK_IMG :\r
261                     // Load an image and use that as a marker\r
262                     // Small optimization, if we have already read an image don't\r
263                     // waste time reading it again.\r
264                     if( $this->markimg == '' || !($this->oldfilename === $filename) ) {\r
265                         $this->markimg = Graph::LoadBkgImage('',$filename);\r
266                         $this->oldfilename = $filename ;\r
267                     }\r
268                     break;\r
270                 case MARK_IMG_PUSHPIN:\r
271                 case MARK_IMG_SPUSHPIN:\r
272                 case MARK_IMG_LPUSHPIN:\r
273                     if( $this->imgdata_pushpins == null ) {\r
274                         require_once 'imgdata_pushpins.inc';\r
275                         $this->imgdata_pushpins = new ImgData_PushPins();\r
276                     }\r
277                     $this->markimg = $this->imgdata_pushpins->GetImg($this->type,$filename);\r
278                     list($anchor_x,$anchor_y) = $this->imgdata_pushpins->GetAnchor();\r
279                     break;\r
281                 case MARK_IMG_SQUARE:\r
282                     if( $this->imgdata_squares == null ) {\r
283                         require_once 'imgdata_squares.inc';\r
284                         $this->imgdata_squares = new ImgData_Squares();\r
285                     }\r
286                     $this->markimg = $this->imgdata_squares->GetImg($this->type,$filename);\r
287                     list($anchor_x,$anchor_y) = $this->imgdata_squares->GetAnchor();\r
288                     break;\r
290                 case MARK_IMG_STAR:\r
291                     if( $this->imgdata_stars == null ) {\r
292                         require_once 'imgdata_stars.inc';\r
293                         $this->imgdata_stars = new ImgData_Stars();\r
294                     }\r
295                     $this->markimg = $this->imgdata_stars->GetImg($this->type,$filename);\r
296                     list($anchor_x,$anchor_y) = $this->imgdata_stars->GetAnchor();\r
297                     break;\r
299                 case MARK_IMG_BEVEL:\r
300                     if( $this->imgdata_bevels == null ) {\r
301                         require_once 'imgdata_bevels.inc';\r
302                         $this->imgdata_bevels = new ImgData_Bevels();\r
303                     }\r
304                     $this->markimg = $this->imgdata_bevels->GetImg($this->type,$filename);\r
305                     list($anchor_x,$anchor_y) = $this->imgdata_bevels->GetAnchor();\r
306                     break;\r
308                 case MARK_IMG_DIAMOND:\r
309                     if( $this->imgdata_diamonds == null ) {\r
310                         require_once 'imgdata_diamonds.inc';\r
311                         $this->imgdata_diamonds = new ImgData_Diamonds();\r
312                     }\r
313                     $this->markimg = $this->imgdata_diamonds->GetImg($this->type,$filename);\r
314                     list($anchor_x,$anchor_y) = $this->imgdata_diamonds->GetAnchor();\r
315                     break;\r
317                 case MARK_IMG_BALL:                 \r
318                 case MARK_IMG_SBALL:                \r
319                 case MARK_IMG_MBALL:                \r
320                 case MARK_IMG_LBALL:                \r
321                     if( $this->imgdata_balls == null ) {\r
322                         require_once 'imgdata_balls.inc';\r
323                         $this->imgdata_balls = new ImgData_Balls();\r
324                     }\r
325                     $this->markimg = $this->imgdata_balls->GetImg($this->type,$filename);\r
326                     list($anchor_x,$anchor_y) = $this->imgdata_balls->GetAnchor();\r
327                     break;\r
328             }\r
330             $w = $img->GetWidth($this->markimg);\r
331             $h = $img->GetHeight($this->markimg);\r
332             \r
333             $dw = round($imgscale * $w );\r
334             $dh = round($imgscale * $h );\r
336             // Do potential rotation\r
337             list($x,$y) = $img->Rotate($x,$y);\r
339             $dx = round($x-$dw*$anchor_x);\r
340             $dy = round($y-$dh*$anchor_y);\r
341             \r
342             $this->width = max($dx,$dy);\r
343             \r
344             $img->Copy($this->markimg,$dx,$dy,0,0,$dw,$dh,$w,$h);\r
345             if( !empty($this->csimtarget) ) {\r
346                 $this->csimareas = "<area shape=\"rect\" coords=\"".\r
347                     $dx.','.$dy.','.round($dx+$dw).','.round($dy+$dh).'" '.\r
348                     "href=\"".$this->csimtarget."\"";\r
349                 if( !empty($this->csimalt) ) {\r
350                     $tmp=sprintf($this->csimalt,$this->yvalue,$this->xvalue);\r
351                     $this->csimareas .= " title=\"$tmp\"";\r
352                 }\r
353                 $this->csimareas .= " alt=\"$tmp\" />\n";\r
354             }\r
355             \r
356             // Stroke title\r
357             $this->title->Align("center","top");\r
358             $this->title->Stroke($img,$x,$y+round($dh/2));                      \r
359             return;\r
360         }\r
362         $weight = $this->weight;\r
363         $dx=round($width/2,0);\r
364         $dy=round($width/2,0);\r
365         $pts=0;         \r
367         switch( $this->type ) {\r
368             case MARK_SQUARE:\r
369                 $c[]=$x-$dx;$c[]=$y-$dy;\r
370                 $c[]=$x+$dx;$c[]=$y-$dy;\r
371                 $c[]=$x+$dx;$c[]=$y+$dy;\r
372                 $c[]=$x-$dx;$c[]=$y+$dy;\r
373                 $c[]=$x-$dx;$c[]=$y-$dy;\r
374                 $pts=5;\r
375                 break;\r
376             case MARK_UTRIANGLE:\r
377                 ++$dx;++$dy;\r
378                 $c[]=$x-$dx;$c[]=$y+0.87*$dy;   // tan(60)/2*$dx\r
379                 $c[]=$x;$c[]=$y-0.87*$dy;\r
380                 $c[]=$x+$dx;$c[]=$y+0.87*$dy;\r
381                 $c[]=$x-$dx;$c[]=$y+0.87*$dy;   // tan(60)/2*$dx\r
382                 $pts=4;\r
383                 break;\r
384             case MARK_DTRIANGLE:\r
385                 ++$dx;++$dy;                    \r
386                 $c[]=$x;$c[]=$y+0.87*$dy;       // tan(60)/2*$dx\r
387                 $c[]=$x-$dx;$c[]=$y-0.87*$dy;\r
388                 $c[]=$x+$dx;$c[]=$y-0.87*$dy;\r
389                 $c[]=$x;$c[]=$y+0.87*$dy;       // tan(60)/2*$dx\r
390                 $pts=4;\r
391                 break;                          \r
392             case MARK_DIAMOND:\r
393                 $c[]=$x;$c[]=$y+$dy;\r
394                 $c[]=$x-$dx;$c[]=$y;\r
395                 $c[]=$x;$c[]=$y-$dy;\r
396                 $c[]=$x+$dx;$c[]=$y;\r
397                 $c[]=$x;$c[]=$y+$dy;\r
398                 $pts=5;\r
399                 break;  \r
400             case MARK_LEFTTRIANGLE:\r
401                 $c[]=$x;$c[]=$y;\r
402                 $c[]=$x;$c[]=$y+2*$dy;\r
403                 $c[]=$x+$dx*2;$c[]=$y;\r
404                 $c[]=$x;$c[]=$y;\r
405                 $pts=4;\r
406                 break;\r
407             case MARK_RIGHTTRIANGLE:\r
408                 $c[]=$x-$dx*2;$c[]=$y;\r
409                 $c[]=$x;$c[]=$y+2*$dy;\r
410                 $c[]=$x;$c[]=$y;\r
411                 $c[]=$x-$dx*2;$c[]=$y;\r
412                 $pts=4;\r
413                 break;\r
414             case MARK_FLASH:\r
415                 $dy *= 2;\r
416                 $c[]=$x+$dx/2; $c[]=$y-$dy;\r
417                 $c[]=$x-$dx+$dx/2; $c[]=$y+$dy*0.7-$dy;\r
418                 $c[]=$x+$dx/2; $c[]=$y+$dy*1.3-$dy;\r
419                 $c[]=$x-$dx+$dx/2; $c[]=$y+2*$dy-$dy;\r
420                 $img->SetLineWeight($weight);\r
421                 $img->SetColor($color);                                 \r
422                 $img->Polygon($c);\r
423                 $img->SetLineWeight(1);\r
424                 $this->AddCSIMPoly($c);\r
425                 break;\r
426         }\r
428         if( $pts>0 ) {\r
429             $this->AddCSIMPoly($c);\r
430             $img->SetLineWeight($weight);\r
431             $img->SetColor($fcolor);                                                            \r
432             $img->FilledPolygon($c);\r
433             $img->SetColor($color);                                     \r
434             $img->Polygon($c);\r
435             $img->SetLineWeight(1);\r
436         }\r
437         elseif( $this->type==MARK_CIRCLE ) {\r
438             $img->SetColor($color);                                     \r
439             $img->Circle($x,$y,$width);\r
440             $this->AddCSIMCircle($x,$y,$width);\r
441         }\r
442         elseif( $this->type==MARK_FILLEDCIRCLE ) {\r
443             $img->SetColor($fcolor);            \r
444             $img->FilledCircle($x,$y,$width);\r
445             $img->SetColor($color);     \r
446             $img->Circle($x,$y,$width);\r
447             $this->AddCSIMCircle($x,$y,$width);\r
448         }\r
449         elseif( $this->type==MARK_CROSS ) {\r
450             // Oversize by a pixel to match the X\r
451             $img->SetColor($color);\r
452             $img->SetLineWeight($weight);\r
453             $img->Line($x,$y+$dy+1,$x,$y-$dy-1);\r
454             $img->Line($x-$dx-1,$y,$x+$dx+1,$y);\r
455             $this->AddCSIMCircle($x,$y,$dx);        \r
456         }\r
457         elseif( $this->type==MARK_X ) {\r
458             $img->SetColor($color);\r
459             $img->SetLineWeight($weight);\r
460             $img->Line($x+$dx,$y+$dy,$x-$dx,$y-$dy);\r
461             $img->Line($x-$dx,$y+$dy,$x+$dx,$y-$dy);            \r
462             $this->AddCSIMCircle($x,$y,$dx+$dy);                    \r
463         }                       \r
464         elseif( $this->type==MARK_STAR ) {\r
465             $img->SetColor($color);\r
466             $img->SetLineWeight($weight);\r
467             $img->Line($x+$dx,$y+$dy,$x-$dx,$y-$dy);\r
468             $img->Line($x-$dx,$y+$dy,$x+$dx,$y-$dy);\r
469             // Oversize by a pixel to match the X                               \r
470             $img->Line($x,$y+$dy+1,$x,$y-$dy-1);\r
471             $img->Line($x-$dx-1,$y,$x+$dx+1,$y);\r
472             $this->AddCSIMCircle($x,$y,$dx+$dy);            \r
473         }\r
474                 \r
475         // Stroke title\r
476         $this->title->Align("center","center");\r
477         $this->title->Stroke($img,$x,$y);                       \r
478     }\r
479 } // Class\r
482 ?>\r