Subversion Repositories Applications.annuaire

Rev

Rev 66 | Details | Compare with Previous | Last modification | View Log | RSS feed

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