1
|
|
|
<?php |
|
|
|
|
2
|
|
|
namespace Amenadiel\JpGraph\Graph; |
3
|
|
|
|
4
|
|
|
use Amenadiel\JpGraph\Plot; |
5
|
|
|
|
6
|
|
|
//======================================================================= |
7
|
|
|
// File: JPGRAPH_LEGEND.INC.PHP |
8
|
|
|
// Description: Class to handle the legend box in the graph that gives |
9
|
|
|
// names on the data series. The number of rows and columns |
10
|
|
|
// in the legend are user specifyable. |
11
|
|
|
// Created: 2001-01-08 (Refactored to separate file 2008-08-01) |
12
|
|
|
// Ver: $Id: jpgraph_legend.inc.php 1926 2010-01-11 16:33:07Z ljp $ |
13
|
|
|
// |
14
|
|
|
// Copyright (c) Asial Corporation. All rights reserved. |
15
|
|
|
//======================================================================== |
16
|
|
|
|
17
|
|
|
DEFINED('_DEFAULT_LPM_SIZE') || DEFINE('_DEFAULT_LPM_SIZE', 8); // Default Legend Plot Mark size |
18
|
|
|
|
19
|
|
|
//=================================================== |
20
|
|
|
// CLASS Legend |
21
|
|
|
// Description: Responsible for drawing the box containing |
22
|
|
|
// all the legend text for the graph |
23
|
|
|
//=================================================== |
24
|
|
|
|
25
|
|
|
class Legend |
26
|
|
|
{ |
27
|
|
|
public $txtcol = []; |
28
|
|
|
public $font_family = FF_DEFAULT; |
29
|
|
|
public $font_style = FS_NORMAL; |
30
|
|
|
public $font_size = 8; // old. 12 |
31
|
|
|
private $color = [120, 120, 120]; // Default frame color |
32
|
|
|
private $fill_color = [245, 245, 245]; // Default fill color |
33
|
|
|
private $shadow = false; // Shadow around legend "box" |
34
|
|
|
private $shadow_color = 'darkgray'; |
35
|
|
|
private $mark_abs_hsize = _DEFAULT_LPM_SIZE; |
36
|
|
|
private $mark_abs_vsize = _DEFAULT_LPM_SIZE; |
37
|
|
|
private $xmargin = 10; |
38
|
|
|
private $ymargin = 0; |
|
|
|
|
39
|
|
|
private $shadow_width = 2; |
40
|
|
|
private $xlmargin = 4; |
41
|
|
|
private $ylinespacing = 5; |
42
|
|
|
|
43
|
|
|
// We need a separate margin since the baseline of the last text would coincide with the bottom otherwise |
44
|
|
|
private $ybottom_margin = 8; |
45
|
|
|
|
46
|
|
|
private $xpos = 0.05; |
47
|
|
|
private $ypos = 0.15; |
48
|
|
|
private $xabspos = -1; |
49
|
|
|
private $yabspos = -1; |
50
|
|
|
private $halign = "right"; |
51
|
|
|
private $valign = "top"; |
52
|
|
|
private $font_color = 'black'; |
53
|
|
|
private $hide = false; |
54
|
|
|
private $layout_n = 1; |
55
|
|
|
private $weight = 1; |
56
|
|
|
private $frameweight = 1; |
57
|
|
|
private $csimareas = ''; |
58
|
|
|
private $reverse = false; |
59
|
|
|
private $bkg_gradtype = -1; |
60
|
|
|
private $bkg_gradfrom = 'lightgray'; |
61
|
|
|
private $bkg_gradto = 'gray'; |
62
|
|
|
|
63
|
|
|
//--------------- |
64
|
|
|
// CONSTRUCTOR |
65
|
|
|
public function __construct() |
66
|
|
|
{ |
67
|
|
|
// Empty |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
//--------------- |
71
|
|
|
// PUBLIC METHODS |
72
|
|
|
public function Hide($aHide = true) |
73
|
|
|
{ |
74
|
|
|
$this->hide = $aHide; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
public function SetHColMargin($aXMarg) |
78
|
|
|
{ |
79
|
|
|
$this->xmargin = $aXMarg; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
public function SetVColMargin($aSpacing) |
83
|
|
|
{ |
84
|
|
|
$this->ylinespacing = $aSpacing; |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
public function SetLeftMargin($aXMarg) |
88
|
|
|
{ |
89
|
|
|
$this->xlmargin = $aXMarg; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
// Synonym |
93
|
|
|
public function SetLineSpacing($aSpacing) |
94
|
|
|
{ |
95
|
|
|
$this->ylinespacing = $aSpacing; |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
public function SetShadow($aShow = 'gray', $aWidth = 4) |
99
|
|
|
{ |
100
|
|
|
if (is_string($aShow)) { |
101
|
|
|
$this->shadow_color = $aShow; |
102
|
|
|
$this->shadow = true; |
103
|
|
|
} else { |
104
|
|
|
$this->shadow = $aShow; |
105
|
|
|
} |
106
|
|
|
$this->shadow_width = $aWidth; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
public function SetMarkAbsSize($aSize) |
110
|
|
|
{ |
111
|
|
|
$this->mark_abs_vsize = $aSize; |
112
|
|
|
$this->mark_abs_hsize = $aSize; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
public function SetMarkAbsVSize($aSize) |
116
|
|
|
{ |
117
|
|
|
$this->mark_abs_vsize = $aSize; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
public function SetMarkAbsHSize($aSize) |
121
|
|
|
{ |
122
|
|
|
$this->mark_abs_hsize = $aSize; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
public function SetLineWeight($aWeight) |
126
|
|
|
{ |
127
|
|
|
$this->weight = $aWeight; |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
public function SetFrameWeight($aWeight) |
131
|
|
|
{ |
132
|
|
|
$this->frameweight = $aWeight; |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
public function SetLayout($aDirection = LEGEND_VERT) |
136
|
|
|
{ |
137
|
|
|
$this->layout_n = $aDirection == LEGEND_VERT ? 1 : 99; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
public function SetColumns($aCols) |
141
|
|
|
{ |
142
|
|
|
$this->layout_n = $aCols; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
public function SetReverse($f = true) |
146
|
|
|
{ |
147
|
|
|
$this->reverse = $f; |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
// Set color on frame around box |
151
|
|
|
public function SetColor($aFontColor, $aColor = 'black') |
152
|
|
|
{ |
153
|
|
|
$this->font_color = $aFontColor; |
154
|
|
|
$this->color = $aColor; |
|
|
|
|
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
public function SetFont($aFamily, $aStyle = FS_NORMAL, $aSize = 10) |
158
|
|
|
{ |
159
|
|
|
$this->font_family = $aFamily; |
160
|
|
|
$this->font_style = $aStyle; |
161
|
|
|
$this->font_size = $aSize; |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
public function SetPos($aX, $aY, $aHAlign = 'right', $aVAlign = 'top') |
165
|
|
|
{ |
166
|
|
|
$this->Pos($aX, $aY, $aHAlign, $aVAlign); |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
public function SetAbsPos($aX, $aY, $aHAlign = 'right', $aVAlign = 'top') |
170
|
|
|
{ |
171
|
|
|
$this->xabspos = $aX; |
172
|
|
|
$this->yabspos = $aY; |
173
|
|
|
$this->halign = $aHAlign; |
174
|
|
|
$this->valign = $aVAlign; |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
public function Pos($aX, $aY, $aHAlign = 'right', $aVAlign = 'top') |
178
|
|
|
{ |
179
|
|
|
if (!($aX < 1 && $aY < 1)) { |
180
|
|
|
JpGraphError::RaiseL(25120); //(" Position for legend must be given as percentage in range 0-1"); |
181
|
|
|
} |
182
|
|
|
$this->xpos = $aX; |
183
|
|
|
$this->ypos = $aY; |
184
|
|
|
$this->halign = $aHAlign; |
185
|
|
|
$this->valign = $aVAlign; |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
public function SetFillColor($aColor) |
189
|
|
|
{ |
190
|
|
|
$this->fill_color = $aColor; |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
public function Clear() |
194
|
|
|
{ |
195
|
|
|
$this->txtcol = []; |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
public function Add($aTxt, $aColor, $aPlotmark = '', $aLinestyle = 0, $csimtarget = '', $csimalt = '', $csimwintarget = '') |
199
|
|
|
{ |
200
|
|
|
$this->txtcol[] = [$aTxt, $aColor, $aPlotmark, $aLinestyle, $csimtarget, $csimalt, $csimwintarget]; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
public function GetCSIMAreas() |
204
|
|
|
{ |
205
|
|
|
return $this->csimareas; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
public function SetBackgroundGradient($aFrom = 'navy', $aTo = 'silver', $aGradType = 2) |
209
|
|
|
{ |
210
|
|
|
$this->bkg_gradtype = $aGradType; |
211
|
|
|
$this->bkg_gradfrom = $aFrom; |
212
|
|
|
$this->bkg_gradto = $aTo; |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
public function HasItems() |
216
|
|
|
{ |
217
|
|
|
return (boolean) (count($this->txtcol)); |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
public function Stroke($aImg) |
221
|
|
|
{ |
222
|
|
|
// Constant |
223
|
|
|
$fillBoxFrameWeight = 1; |
224
|
|
|
|
225
|
|
|
if ($this->hide) { |
226
|
|
|
return; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
$aImg->SetFont($this->font_family, $this->font_style, $this->font_size); |
230
|
|
|
|
231
|
|
|
if ($this->reverse) { |
232
|
|
|
$this->txtcol = array_reverse($this->txtcol); |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
$n = count($this->txtcol); |
236
|
|
|
if ($n == 0) { |
237
|
|
|
return; |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
// Find out the max width and height of each column to be able |
241
|
|
|
// to size the legend box. |
242
|
|
|
$numcolumns = ($n > $this->layout_n ? $this->layout_n : $n); |
243
|
|
|
for ($i = 0; $i < $numcolumns; ++$i) { |
244
|
|
|
$colwidth[$i] = $aImg->GetTextWidth($this->txtcol[$i][0]) + |
|
|
|
|
245
|
|
|
2 * $this->xmargin + 2 * $this->mark_abs_hsize; |
246
|
|
|
$colheight[$i] = 0; |
|
|
|
|
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
// Find our maximum height in each row |
250
|
|
|
$rows = 0; |
251
|
|
|
$rowheight[0] = 0; |
|
|
|
|
252
|
|
|
for ($i = 0; $i < $n; ++$i) { |
253
|
|
|
$h = max($this->mark_abs_vsize, $aImg->GetTextHeight($this->txtcol[$i][0])) + $this->ylinespacing; |
254
|
|
|
|
255
|
|
|
// Makes sure we always have a minimum of 1/4 (1/2 on each side) of the mark as space |
256
|
|
|
// between two vertical legend entries |
257
|
|
|
//$h = round(max($h,$this->mark_abs_vsize+$this->ymargin)); |
|
|
|
|
258
|
|
|
//echo "Textheight #$i: tetxheight=".$aImg->GetTextHeight($this->txtcol[$i][0]).', '; |
|
|
|
|
259
|
|
|
//echo "h=$h ({$this->mark_abs_vsize},{$this->ymargin})<br>"; |
260
|
|
|
if ($i % $numcolumns == 0) { |
261
|
|
|
$rows++; |
262
|
|
|
$rowheight[$rows - 1] = 0; |
263
|
|
|
} |
264
|
|
|
$rowheight[$rows - 1] = max($rowheight[$rows - 1], $h) + 1; |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
$abs_height = 0; |
268
|
|
|
for ($i = 0; $i < $rows; ++$i) { |
269
|
|
|
$abs_height += $rowheight[$i]; |
270
|
|
|
} |
271
|
|
|
|
272
|
|
|
// Make sure that the height is at least as high as mark size + ymargin |
273
|
|
|
$abs_height = max($abs_height, $this->mark_abs_vsize); |
274
|
|
|
$abs_height += $this->ybottom_margin; |
275
|
|
|
|
276
|
|
|
// Find out the maximum width in each column |
277
|
|
|
for ($i = $numcolumns; $i < $n; ++$i) { |
278
|
|
|
$colwidth[$i % $numcolumns] = max( |
|
|
|
|
279
|
|
|
$aImg->GetTextWidth($this->txtcol[$i][0]) + 2 * $this->xmargin + 2 * $this->mark_abs_hsize, |
280
|
|
|
$colwidth[$i % $numcolumns]); |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
// Get the total width |
284
|
|
|
$mtw = 0; |
285
|
|
|
for ($i = 0; $i < $numcolumns; ++$i) { |
286
|
|
|
$mtw += $colwidth[$i]; |
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
// remove the last rows interpace margin (since there is no next row) |
290
|
|
|
$abs_height -= $this->ylinespacing; |
291
|
|
|
|
292
|
|
|
// Find out maximum width we need for legend box |
293
|
|
|
$abs_width = $mtw + $this->xlmargin + ($numcolumns - 1) * $this->mark_abs_hsize; |
294
|
|
|
|
295
|
|
|
if ($this->xabspos === -1 && $this->yabspos === -1) { |
296
|
|
|
$this->xabspos = $this->xpos * $aImg->width; |
|
|
|
|
297
|
|
|
$this->yabspos = $this->ypos * $aImg->height; |
|
|
|
|
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
// Positioning of the legend box |
301
|
|
|
if ($this->halign == 'left') { |
302
|
|
|
$xp = $this->xabspos; |
303
|
|
|
} elseif ($this->halign == 'center') { |
304
|
|
|
$xp = $this->xabspos - $abs_width / 2; |
305
|
|
|
} else { |
306
|
|
|
$xp = $aImg->width - $this->xabspos - $abs_width; |
307
|
|
|
} |
308
|
|
|
|
309
|
|
|
$yp = $this->yabspos; |
310
|
|
|
if ($this->valign == 'center') { |
311
|
|
|
$yp -= $abs_height / 2; |
312
|
|
|
} elseif ($this->valign == 'bottom') { |
313
|
|
|
$yp -= $abs_height; |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
// Stroke legend box |
317
|
|
|
$aImg->SetColor($this->color); |
318
|
|
|
$aImg->SetLineWeight($this->frameweight); |
319
|
|
|
$aImg->SetLineStyle('solid'); |
320
|
|
|
|
321
|
|
|
if ($this->shadow) { |
322
|
|
|
$aImg->ShadowRectangle($xp, $yp, |
323
|
|
|
$xp + $abs_width + $this->shadow_width + 2, |
324
|
|
|
$yp + $abs_height + $this->shadow_width + 2, |
325
|
|
|
$this->fill_color, $this->shadow_width + 2, $this->shadow_color); |
326
|
|
|
} else { |
327
|
|
|
$aImg->SetColor($this->fill_color); |
328
|
|
|
$aImg->FilledRectangle($xp, $yp, $xp + $abs_width, $yp + $abs_height); |
329
|
|
|
$aImg->SetColor($this->color); |
330
|
|
|
$aImg->Rectangle($xp, $yp, $xp + $abs_width, $yp + $abs_height); |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
if ($this->bkg_gradtype >= 0) { |
334
|
|
|
$grad = new Plot\Gradient($aImg); |
335
|
|
|
$grad->FilledRectangle($xp + 1, $yp + 1, |
336
|
|
|
$xp + $abs_width - 3, $yp + $abs_height - 3, |
337
|
|
|
$this->bkg_gradfrom, $this->bkg_gradto, |
338
|
|
|
$this->bkg_gradtype); |
339
|
|
|
} |
340
|
|
|
|
341
|
|
|
// x1,y1 is the position for the legend marker + text |
342
|
|
|
// The vertical position is the baseline position for the text |
343
|
|
|
// and every marker is adjusted acording to that. |
344
|
|
|
|
345
|
|
|
// For multiline texts this get more complicated. |
346
|
|
|
|
347
|
|
|
$x1 = $xp + $this->xlmargin; |
348
|
|
|
$y1 = $yp + $rowheight[0] - $this->ylinespacing + 2; // The ymargin is included in rowheight |
349
|
|
|
|
350
|
|
|
// Now, y1 is the bottom vertical position of the first legend, i.e if |
351
|
|
|
// the legend has multiple lines it is the bottom line. |
352
|
|
|
|
353
|
|
|
$grad = new Plot\Gradient($aImg); |
354
|
|
|
$patternFactory = null; |
355
|
|
|
|
356
|
|
|
// Now stroke each legend in turn |
357
|
|
|
// Each plot has added the following information to the legend |
358
|
|
|
// p[0] = Legend text |
359
|
|
|
// p[1] = Color, |
|
|
|
|
360
|
|
|
// p[2] = For markers a reference to the PlotMark object |
361
|
|
|
// p[3] = For lines the line style, for gradient the negative gradient style |
362
|
|
|
// p[4] = CSIM target |
363
|
|
|
// p[5] = CSIM Alt text |
364
|
|
|
$i = 1; |
365
|
|
|
$row = 0; |
366
|
|
|
foreach ($this->txtcol as $p) { |
367
|
|
|
|
368
|
|
|
// STROKE DEBUG BOX |
369
|
|
|
if (_JPG_DEBUG) { |
370
|
|
|
$aImg->SetLineWeight(1); |
371
|
|
|
$aImg->SetColor('red'); |
372
|
|
|
$aImg->SetLineStyle('solid'); |
373
|
|
|
$aImg->Rectangle($x1, $y1, $xp + $abs_width - 1, $y1 - $rowheight[$row]); |
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
$aImg->SetLineWeight($this->weight); |
377
|
|
|
$x1 = round($x1) + 1; // We add one to not collide with the border |
378
|
|
|
$y1 = round($y1); |
379
|
|
|
|
380
|
|
|
// This is the center offset up from the baseline which is |
381
|
|
|
// considered the "center" of the marks. This gets slightly complicated since |
382
|
|
|
// we need to consider if the text is a multiline paragraph or if it is only |
383
|
|
|
// a single line. The reason is that for single line the y1 corresponds to the baseline |
384
|
|
|
// and that is fine. However for a multiline paragraph there is no single baseline |
385
|
|
|
// and in that case the y1 corresponds to the lowest y for the bounding box. In that |
386
|
|
|
// case we center the mark in the middle of the paragraph |
387
|
|
|
if (!preg_match('/\n/', $p[0])) { |
388
|
|
|
// Single line |
389
|
|
|
$marky = ceil($y1 - $this->mark_abs_vsize / 2) - 1; |
390
|
|
|
} else { |
391
|
|
|
// Paragraph |
392
|
|
|
$marky = $y1 - $aImg->GetTextHeight($p[0]) / 2; |
393
|
|
|
|
394
|
|
|
// echo "y1=$y1, p[o]={$p[0]}, marky=$marky<br>"; |
395
|
|
|
} |
396
|
|
|
|
397
|
|
|
//echo "<br>Mark #$i: marky=$marky<br>"; |
398
|
|
|
|
399
|
|
|
$x1 += $this->mark_abs_hsize; |
400
|
|
|
|
401
|
|
|
if (!empty($p[2]) && $p[2]->GetType() > -1) { |
402
|
|
|
|
403
|
|
|
// Make a plot mark legend. This is constructed with a mark which |
404
|
|
|
// is run through with a line |
405
|
|
|
|
406
|
|
|
// First construct a bit of the line that looks exactly like the |
407
|
|
|
// line in the plot |
408
|
|
|
$aImg->SetColor($p[1]); |
409
|
|
|
if (is_string($p[3]) || $p[3] > 0) { |
410
|
|
|
$aImg->SetLineStyle($p[3]); |
411
|
|
|
$aImg->StyleLine($x1 - $this->mark_abs_hsize, $marky, $x1 + $this->mark_abs_hsize, $marky); |
412
|
|
|
} |
413
|
|
|
|
414
|
|
|
// Stroke a mark using image |
415
|
|
|
if ($p[2]->GetType() == MARK_IMG) { |
416
|
|
|
$p[2]->Stroke($aImg, $x1, $marky); |
417
|
|
|
} |
418
|
|
|
|
419
|
|
|
// Stroke a mark with the standard size |
420
|
|
|
// (As long as it is not an image mark ) |
421
|
|
|
if ($p[2]->GetType() != MARK_IMG) { |
422
|
|
|
|
423
|
|
|
// Clear any user callbacks since we ont want them called for |
424
|
|
|
// the legend marks |
425
|
|
|
$p[2]->iFormatCallback = ''; |
426
|
|
|
$p[2]->iFormatCallback2 = ''; |
427
|
|
|
|
428
|
|
|
// Since size for circles is specified as the radius |
429
|
|
|
// this means that we must half the size to make the total |
430
|
|
|
// width behave as the other marks |
431
|
|
|
if ($p[2]->GetType() == MARK_FILLEDCIRCLE || $p[2]->GetType() == MARK_CIRCLE) { |
432
|
|
|
$p[2]->SetSize(min($this->mark_abs_vsize, $this->mark_abs_hsize) / 2); |
433
|
|
|
$p[2]->Stroke($aImg, $x1, $marky); |
434
|
|
|
} else { |
435
|
|
|
$p[2]->SetSize(min($this->mark_abs_vsize, $this->mark_abs_hsize)); |
436
|
|
|
$p[2]->Stroke($aImg, $x1, $marky); |
437
|
|
|
} |
438
|
|
|
} |
439
|
|
|
} elseif (!empty($p[2]) && (is_string($p[3]) || $p[3] > 0)) { |
440
|
|
|
// Draw a styled line |
441
|
|
|
$aImg->SetColor($p[1]); |
442
|
|
|
$aImg->SetLineStyle($p[3]); |
443
|
|
|
$aImg->StyleLine($x1 - $this->mark_abs_hsize, $marky, $x1 + $this->mark_abs_hsize, $marky); |
444
|
|
|
$aImg->StyleLine($x1 - $this->mark_abs_hsize, $marky + 1, $x1 + $this->mark_abs_hsize, $marky + 1); |
445
|
|
|
} else { |
446
|
|
|
// Draw a colored box |
447
|
|
|
$color = $p[1]; |
448
|
|
|
|
449
|
|
|
// We make boxes slightly larger to better show |
450
|
|
|
$boxsize = max($this->mark_abs_vsize, $this->mark_abs_hsize) + 2; |
451
|
|
|
|
452
|
|
|
$ym = $marky - ceil($boxsize / 2); // Marker y-coordinate |
453
|
|
|
|
454
|
|
|
// We either need to plot a gradient or a |
455
|
|
|
// pattern. To differentiate we use a kludge. |
456
|
|
|
// Patterns have a p[3] value of < -100 |
457
|
|
|
if ($p[3] < -100) { |
458
|
|
|
// p[1][0] == iPattern, p[1][1] == iPatternColor, p[1][2] == iPatternDensity |
|
|
|
|
459
|
|
|
if ($patternFactory == null) { |
460
|
|
|
$patternFactory = new RectPatternFactory(); |
461
|
|
|
} |
462
|
|
|
$prect = $patternFactory->Create($p[1][0], $p[1][1], 1); |
463
|
|
|
$prect->SetBackground($p[1][3]); |
464
|
|
|
$prect->SetDensity($p[1][2] + 1); |
465
|
|
|
$prect->SetPos(new Util\Rectangle($x1, $ym, $boxsize, $boxsize)); |
466
|
|
|
$prect->Stroke($aImg); |
467
|
|
|
$prect = null; |
|
|
|
|
468
|
|
|
} else { |
469
|
|
|
if (is_array($color) && count($color) == 2) { |
470
|
|
|
// The client want a gradient color |
471
|
|
|
$grad->FilledRectangle($x1 - $boxsize / 2, $ym, |
472
|
|
|
$x1 + $boxsize / 2, $ym + $boxsize, |
473
|
|
|
$color[0], $color[1], -$p[3]); |
474
|
|
|
} else { |
475
|
|
|
$aImg->SetColor($p[1]); |
476
|
|
|
$aImg->FilledRectangle($x1 - $boxsize / 2, $ym, $x1 + $boxsize / 2, $ym + $boxsize); |
477
|
|
|
} |
478
|
|
|
|
479
|
|
|
// Draw a plot frame line |
480
|
|
|
$aImg->SetColor($this->color); |
481
|
|
|
$aImg->SetLineWeight($fillBoxFrameWeight); |
482
|
|
|
$aImg->Rectangle($x1 - $boxsize / 2, $ym, |
483
|
|
|
$x1 + $boxsize / 2, $ym + $boxsize); |
484
|
|
|
} |
485
|
|
|
} |
486
|
|
|
$aImg->SetColor($this->font_color); |
487
|
|
|
$aImg->SetFont($this->font_family, $this->font_style, $this->font_size); |
488
|
|
|
$aImg->SetTextAlign('left', 'baseline'); |
489
|
|
|
|
490
|
|
|
$debug = false; |
491
|
|
|
$aImg->StrokeText($x1 + $this->mark_abs_hsize + $this->xmargin, $y1, $p[0], |
492
|
|
|
0, 'left', $debug); |
493
|
|
|
|
494
|
|
|
// Add CSIM for Legend if defined |
495
|
|
|
if (!empty($p[4])) { |
496
|
|
|
$xs = $x1 - $this->mark_abs_hsize; |
497
|
|
|
$ys = $y1 + 1; |
498
|
|
|
$xe = $x1 + $aImg->GetTextWidth($p[0]) + $this->mark_abs_hsize + $this->xmargin; |
499
|
|
|
$ye = $y1 - $rowheight[$row] + 1; |
500
|
|
|
$coords = "$xs,$ys,$xe,$y1,$xe,$ye,$xs,$ye"; |
501
|
|
|
if (!empty($p[4])) { |
502
|
|
|
$this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"" . htmlentities($p[4]) . "\""; |
503
|
|
|
|
504
|
|
|
if (!empty($p[6])) { |
505
|
|
|
$this->csimareas .= " target=\"" . $p[6] . "\""; |
506
|
|
|
} |
507
|
|
|
|
508
|
|
|
if (!empty($p[5])) { |
509
|
|
|
$tmp = sprintf($p[5], $p[0]); |
510
|
|
|
$this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" "; |
511
|
|
|
} |
512
|
|
|
$this->csimareas .= " />\n"; |
513
|
|
|
} |
514
|
|
|
} |
515
|
|
|
|
516
|
|
|
if ($i >= $this->layout_n) { |
517
|
|
|
$x1 = $xp + $this->xlmargin; |
518
|
|
|
$row++; |
519
|
|
|
if (!empty($rowheight[$row])) { |
520
|
|
|
$y1 += $rowheight[$row]; |
521
|
|
|
} |
522
|
|
|
|
523
|
|
|
$i = 1; |
524
|
|
|
} else { |
525
|
|
|
$x1 += $colwidth[($i - 1) % $numcolumns]; |
526
|
|
|
++$i; |
527
|
|
|
} |
528
|
|
|
} |
529
|
|
|
} |
530
|
|
|
} // Class |
531
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.