1 | <?php |
||||
2 | |||||
3 | /** |
||||
4 | * JPGraph v4.0.3 |
||||
5 | */ |
||||
6 | |||||
7 | namespace Amenadiel\JpGraph\Plot; |
||||
8 | |||||
9 | use Amenadiel\JpGraph\Text; |
||||
10 | use Amenadiel\JpGraph\Util; |
||||
11 | |||||
12 | /** |
||||
13 | * File: JPGRAPH_PIE3D.PHP |
||||
14 | * // Description: 3D Pie plot extension for JpGraph |
||||
15 | * // Created: 2001-03-24 |
||||
16 | * // Ver: $Id: jpgraph_pie3d.php 1329 2009-06-20 19:23:30Z ljp $ |
||||
17 | * // |
||||
18 | * // Copyright (c) Asial Corporation. All rights reserved. |
||||
19 | */ |
||||
20 | |||||
21 | /** |
||||
22 | * @class PiePlot3D |
||||
23 | * // Description: Plots a 3D pie with a specified projection |
||||
24 | * // angle between 20 and 70 degrees. |
||||
25 | */ |
||||
26 | class PiePlot3D extends PiePlot |
||||
27 | { |
||||
28 | private $labelhintcolor = 'red'; |
||||
29 | private $showlabelhint = true; |
||||
30 | private $angle = 50; |
||||
31 | private $edgecolor = ''; |
||||
32 | private $edgeweight = 1; |
||||
33 | private $iThickness = false; |
||||
34 | |||||
35 | /** |
||||
36 | * CONSTRUCTOR. |
||||
37 | * |
||||
38 | * @param mixed $data |
||||
39 | */ |
||||
40 | 2 | public function __construct($data) |
|||
41 | { |
||||
42 | 2 | $this->radius = 0.5; |
|||
43 | 2 | $this->data = $data; |
|||
44 | 2 | $this->title = new Text\Text(''); |
|||
45 | 2 | $this->title->SetFont(FF_FONT1, FS_BOLD); |
|||
46 | 2 | $this->value = new DisplayValue(); |
|||
47 | 2 | $this->value->Show(); |
|||
48 | 2 | $this->value->SetFormat('%.0f%%'); |
|||
49 | 2 | } |
|||
50 | |||||
51 | /** |
||||
52 | * PUBLIC METHODS. |
||||
53 | * |
||||
54 | * @param mixed $aLegend |
||||
55 | */ |
||||
56 | // Set label arrays |
||||
57 | 2 | public function SetLegends($aLegend) |
|||
58 | { |
||||
59 | 2 | $this->legends = array_reverse(array_slice($aLegend, 0, safe_count($this->data))); |
|||
60 | 2 | } |
|||
61 | |||||
62 | public function SetSliceColors($aColors) |
||||
63 | { |
||||
64 | $this->setslicecolors = $aColors; |
||||
65 | } |
||||
66 | |||||
67 | 2 | public function Legend($aGraph) |
|||
68 | { |
||||
69 | 2 | parent::Legend($aGraph); |
|||
70 | 2 | $aGraph->legend->txtcol = array_reverse($aGraph->legend->txtcol); |
|||
71 | 2 | } |
|||
72 | |||||
73 | public function SetCSIMTargets($aTargets, $aAlts = '', $aWinTargets = '') |
||||
74 | { |
||||
75 | $this->csimtargets = $aTargets; |
||||
76 | $this->csimwintargets = $aWinTargets; |
||||
77 | $this->csimalts = $aAlts; |
||||
78 | } |
||||
79 | |||||
80 | // Should the slices be separated by a line? If color is specified as "" no line |
||||
81 | // will be used to separate pie slices. |
||||
82 | 1 | public function SetEdge($aColor = 'black', $aWeight = 1) |
|||
83 | { |
||||
84 | 1 | $this->edgecolor = $aColor; |
|||
85 | 1 | $this->edgeweight = $aWeight; |
|||
86 | 1 | } |
|||
87 | |||||
88 | // Specify projection angle for 3D in degrees |
||||
89 | // Must be between 20 and 70 degrees |
||||
90 | 2 | public function SetAngle($a) |
|||
91 | { |
||||
92 | 2 | if ($a < 5 || $a > 90) { |
|||
93 | Util\JpGraphError::RaiseL(14002); |
||||
94 | //("PiePlot3D::SetAngle() 3D Pie projection angle must be between 5 and 85 degrees."); |
||||
95 | } else { |
||||
96 | 2 | $this->angle = $a; |
|||
97 | } |
||||
98 | 2 | } |
|||
99 | |||||
100 | 2 | public function Add3DSliceToCSIM($i, $xc, $yc, $height, $width, $thick, $sa, $ea) |
|||
101 | { |
||||
102 | //Slice number, ellipse centre (x,y), height, width, start angle, end angle |
||||
103 | |||||
104 | 2 | $sa *= M_PI / 180; |
|||
105 | 2 | $ea *= M_PI / 180; |
|||
106 | |||||
107 | //add coordinates of the centre to the map |
||||
108 | 2 | $coords = "${xc}, ${yc}"; |
|||
109 | |||||
110 | //add coordinates of the first point on the arc to the map |
||||
111 | 2 | $xp = floor($width * cos($sa) / 2 + $xc); |
|||
112 | 2 | $yp = floor($yc - $height * sin($sa) / 2); |
|||
113 | 2 | $coords .= ", ${xp}, ${yp}"; |
|||
114 | |||||
115 | //If on the front half, add the thickness offset |
||||
116 | 2 | if ($sa >= M_PI && $sa <= 2 * M_PI * 1.01) { |
|||
117 | 2 | $yp = floor($yp + $thick); |
|||
118 | 2 | $coords .= ", ${xp}, ${yp}"; |
|||
119 | } |
||||
120 | |||||
121 | //add coordinates every 0.2 radians |
||||
122 | 2 | $a = $sa + 0.2; |
|||
123 | 2 | while ($a < $ea) { |
|||
124 | 2 | $xp = floor($width * cos($a) / 2 + $xc); |
|||
125 | 2 | if ($a >= M_PI && $a <= 2 * M_PI * 1.01) { |
|||
126 | 2 | $yp = floor($yc - ($height * sin($a) / 2) + $thick); |
|||
127 | } else { |
||||
128 | 2 | $yp = floor($yc - $height * sin($a) / 2); |
|||
129 | } |
||||
130 | 2 | $coords .= ", ${xp}, ${yp}"; |
|||
131 | 2 | $a += 0.2; |
|||
132 | } |
||||
133 | |||||
134 | //Add the last point on the arc |
||||
135 | 2 | $xp = floor($width * cos($ea) / 2 + $xc); |
|||
136 | 2 | $yp = floor($yc - $height * sin($ea) / 2); |
|||
137 | |||||
138 | 2 | if ($ea >= M_PI && $ea <= 2 * M_PI * 1.01) { |
|||
139 | 2 | $coords .= ", ${xp}, " . floor($yp + $thick); |
|||
140 | } |
||||
141 | 2 | $coords .= ", ${xp}, ${yp}"; |
|||
142 | 2 | $alt = ''; |
|||
0 ignored issues
–
show
Unused Code
introduced
by
![]() |
|||||
143 | |||||
144 | 2 | if (!empty($this->csimtargets[$i])) { |
|||
145 | $this->csimareas .= "<area shape=\"poly\" coords=\"${coords}\" href=\"" . $this->csimtargets[$i] . '"'; |
||||
146 | |||||
147 | if (!empty($this->csimwintargets[$i])) { |
||||
148 | $this->csimareas .= ' target="' . $this->csimwintargets[$i] . '" '; |
||||
149 | } |
||||
150 | |||||
151 | if (!empty($this->csimalts[$i])) { |
||||
152 | $tmp = sprintf($this->csimalts[$i], $this->data[$i]); |
||||
153 | $this->csimareas .= "alt=\"${tmp}\" title=\"${tmp}\" "; |
||||
154 | } |
||||
155 | $this->csimareas .= " />\n"; |
||||
156 | } |
||||
157 | 2 | } |
|||
158 | |||||
159 | public function SetLabels($aLabels, $aLblPosAdj = 'auto') |
||||
160 | { |
||||
161 | $this->labels = $aLabels; |
||||
162 | $this->ilabelposadj = $aLblPosAdj; |
||||
163 | } |
||||
164 | |||||
165 | // Distance from the pie to the labels |
||||
166 | public function SetLabelMargin($m) |
||||
167 | { |
||||
168 | $this->value->SetMargin($m); |
||||
169 | } |
||||
170 | |||||
171 | // Show a thin line from the pie to the label for a specific slice |
||||
172 | public function ShowLabelHint($f = true) |
||||
173 | { |
||||
174 | $this->showlabelhint = $f; |
||||
175 | } |
||||
176 | |||||
177 | // Set color of hint line to label for each slice |
||||
178 | public function SetLabelHintColor($c) |
||||
179 | { |
||||
180 | $this->labelhintcolor = $c; |
||||
181 | } |
||||
182 | |||||
183 | 1 | public function SetHeight($aHeight) |
|||
184 | { |
||||
185 | 1 | $this->iThickness = $aHeight; |
|||
186 | 1 | } |
|||
187 | |||||
188 | // Normalize Angle between 0-360 |
||||
189 | 2 | public function NormAngle($a) |
|||
190 | { |
||||
191 | // Normalize anle to 0 to 2M_PI |
||||
192 | // |
||||
193 | 2 | if ($a > 0) { |
|||
194 | 2 | while ($a > 360) { |
|||
195 | 1 | $a -= 360; |
|||
196 | } |
||||
197 | } else { |
||||
198 | 2 | while ($a < 0) { |
|||
199 | $a += 360; |
||||
200 | } |
||||
201 | } |
||||
202 | 2 | if ($a < 0) { |
|||
203 | $a = 360 + $a; |
||||
204 | } |
||||
205 | |||||
206 | 2 | if ($a == 360) { |
|||
207 | 2 | $a = 0; |
|||
208 | } |
||||
209 | |||||
210 | 2 | return $a; |
|||
211 | } |
||||
212 | |||||
213 | // Draw one 3D pie slice at position ($xc,$yc) with height $z |
||||
214 | 2 | public function Pie3DSlice($img, $xc, $yc, $w, $h, $sa, $ea, $z, $fillcolor, $shadow = 0.65) |
|||
215 | { |
||||
216 | // Due to the way the 3D Pie algorithm works we are |
||||
217 | // guaranteed that any slice we get into this method |
||||
218 | // belongs to either the left or right side of the |
||||
219 | // pie ellipse. Hence, no slice will cross 90 or 270 |
||||
220 | // point. |
||||
221 | 2 | if (($sa < 90 && $ea > 90) || (($sa > 90 && $sa < 270) && $ea > 270)) { |
|||
222 | Util\JpGraphError::RaiseL(14003); //('Internal assertion failed. Pie3D::Pie3DSlice'); |
||||
223 | exit(1); |
||||
0 ignored issues
–
show
|
|||||
224 | } |
||||
225 | |||||
226 | 2 | $p[] = []; |
|||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
227 | |||||
228 | // Setup pre-calculated values |
||||
229 | 2 | $rsa = $sa / 180 * M_PI; // to Rad |
|||
230 | 2 | $rea = $ea / 180 * M_PI; // to Rad |
|||
231 | 2 | $sinsa = sin($rsa); |
|||
232 | 2 | $cossa = cos($rsa); |
|||
233 | 2 | $sinea = sin($rea); |
|||
234 | 2 | $cosea = cos($rea); |
|||
235 | |||||
236 | // p[] is the points for the overall slice and |
||||
237 | // pt[] is the points for the top pie |
||||
238 | |||||
239 | // Angular step when approximating the arc with a polygon train. |
||||
240 | 2 | $step = 0.05; |
|||
241 | |||||
242 | 2 | if ($sa >= 270) { |
|||
243 | 2 | if ($ea > 360 || ($ea > 0 && $ea <= 90)) { |
|||
244 | 1 | if ($ea > 0 && $ea <= 90) { |
|||
245 | // Adjust angle to simplify conditions in loops |
||||
246 | 1 | $rea += 2 * M_PI; |
|||
247 | } |
||||
248 | |||||
249 | 1 | $p = [$xc, $yc, $xc, $yc + $z, |
|||
250 | 1 | $xc + $w * $cossa, $z + $yc - $h * $sinsa, ]; |
|||
251 | 1 | $pt = [$xc, $yc, $xc + $w * $cossa, $yc - $h * $sinsa]; |
|||
252 | |||||
253 | 1 | for ($a = $rsa; $a < 2 * M_PI; $a += $step) { |
|||
254 | 1 | $tca = cos($a); |
|||
255 | 1 | $tsa = sin($a); |
|||
256 | 1 | $p[] = $xc + $w * $tca; |
|||
257 | 1 | $p[] = $z + $yc - $h * $tsa; |
|||
258 | 1 | $pt[] = $xc + $w * $tca; |
|||
259 | 1 | $pt[] = $yc - $h * $tsa; |
|||
260 | } |
||||
261 | |||||
262 | 1 | $pt[] = $xc + $w; |
|||
263 | 1 | $pt[] = $yc; |
|||
264 | |||||
265 | 1 | $p[] = $xc + $w; |
|||
266 | 1 | $p[] = $z + $yc; |
|||
267 | 1 | $p[] = $xc + $w; |
|||
268 | 1 | $p[] = $yc; |
|||
269 | 1 | $p[] = $xc; |
|||
270 | 1 | $p[] = $yc; |
|||
271 | |||||
272 | 1 | for ($a = 2 * M_PI + $step; $a < $rea; $a += $step) { |
|||
273 | 1 | $pt[] = $xc + $w * cos($a); |
|||
274 | 1 | $pt[] = $yc - $h * sin($a); |
|||
275 | } |
||||
276 | |||||
277 | 1 | $pt[] = $xc + $w * $cosea; |
|||
278 | 1 | $pt[] = $yc - $h * $sinea; |
|||
279 | 1 | $pt[] = $xc; |
|||
280 | 1 | $pt[] = $yc; |
|||
281 | } else { |
||||
282 | 2 | $p = [$xc, $yc, $xc, $yc + $z, |
|||
283 | 2 | $xc + $w * $cossa, $z + $yc - $h * $sinsa, ]; |
|||
284 | 2 | $pt = [$xc, $yc, $xc + $w * $cossa, $yc - $h * $sinsa]; |
|||
285 | |||||
286 | 2 | $rea = $rea == 0.0 ? 2 * M_PI : $rea; |
|||
287 | 2 | for ($a = $rsa; $a < $rea; $a += $step) { |
|||
288 | 2 | $tca = cos($a); |
|||
289 | 2 | $tsa = sin($a); |
|||
290 | 2 | $p[] = $xc + $w * $tca; |
|||
291 | 2 | $p[] = $z + $yc - $h * $tsa; |
|||
292 | 2 | $pt[] = $xc + $w * $tca; |
|||
293 | 2 | $pt[] = $yc - $h * $tsa; |
|||
294 | } |
||||
295 | |||||
296 | 2 | $pt[] = $xc + $w * $cosea; |
|||
297 | 2 | $pt[] = $yc - $h * $sinea; |
|||
298 | 2 | $pt[] = $xc; |
|||
299 | 2 | $pt[] = $yc; |
|||
300 | |||||
301 | 2 | $p[] = $xc + $w * $cosea; |
|||
302 | 2 | $p[] = $z + $yc - $h * $sinea; |
|||
303 | 2 | $p[] = $xc + $w * $cosea; |
|||
304 | 2 | $p[] = $yc - $h * $sinea; |
|||
305 | 2 | $p[] = $xc; |
|||
306 | 2 | $p[] = $yc; |
|||
307 | } |
||||
308 | 2 | } elseif ($sa >= 180) { |
|||
309 | 2 | $p = [$xc, $yc, $xc, $yc + $z, $xc + $w * $cosea, $z + $yc - $h * $sinea]; |
|||
310 | 2 | $pt = [$xc, $yc, $xc + $w * $cosea, $yc - $h * $sinea]; |
|||
311 | |||||
312 | 2 | for ($a = $rea; $a > $rsa; $a -= $step) { |
|||
313 | 2 | $tca = cos($a); |
|||
314 | 2 | $tsa = sin($a); |
|||
315 | 2 | $p[] = $xc + $w * $tca; |
|||
316 | 2 | $p[] = $z + $yc - $h * $tsa; |
|||
317 | 2 | $pt[] = $xc + $w * $tca; |
|||
318 | 2 | $pt[] = $yc - $h * $tsa; |
|||
319 | } |
||||
320 | |||||
321 | 2 | $pt[] = $xc + $w * $cossa; |
|||
322 | 2 | $pt[] = $yc - $h * $sinsa; |
|||
323 | 2 | $pt[] = $xc; |
|||
324 | 2 | $pt[] = $yc; |
|||
325 | |||||
326 | 2 | $p[] = $xc + $w * $cossa; |
|||
327 | 2 | $p[] = $z + $yc - $h * $sinsa; |
|||
328 | 2 | $p[] = $xc + $w * $cossa; |
|||
329 | 2 | $p[] = $yc - $h * $sinsa; |
|||
330 | 2 | $p[] = $xc; |
|||
331 | 2 | $p[] = $yc; |
|||
332 | 2 | } elseif ($sa >= 90) { |
|||
333 | 2 | if ($ea > 180) { |
|||
334 | 2 | $p = [$xc, $yc, $xc, $yc + $z, $xc + $w * $cosea, $z + $yc - $h * $sinea]; |
|||
335 | 2 | $pt = [$xc, $yc, $xc + $w * $cosea, $yc - $h * $sinea]; |
|||
336 | |||||
337 | 2 | for ($a = $rea; $a > M_PI; $a -= $step) { |
|||
338 | 2 | $tca = cos($a); |
|||
339 | 2 | $tsa = sin($a); |
|||
340 | 2 | $p[] = $xc + $w * $tca; |
|||
341 | 2 | $p[] = $z + $yc - $h * $tsa; |
|||
342 | 2 | $pt[] = $xc + $w * $tca; |
|||
343 | 2 | $pt[] = $yc - $h * $tsa; |
|||
344 | } |
||||
345 | |||||
346 | 2 | $p[] = $xc - $w; |
|||
347 | 2 | $p[] = $z + $yc; |
|||
348 | 2 | $p[] = $xc - $w; |
|||
349 | 2 | $p[] = $yc; |
|||
350 | 2 | $p[] = $xc; |
|||
351 | 2 | $p[] = $yc; |
|||
352 | |||||
353 | 2 | $pt[] = $xc - $w; |
|||
354 | 2 | $pt[] = $z + $yc; |
|||
355 | 2 | $pt[] = $xc - $w; |
|||
356 | 2 | $pt[] = $yc; |
|||
357 | |||||
358 | 2 | for ($a = M_PI - $step; $a > $rsa; $a -= $step) { |
|||
359 | 2 | $pt[] = $xc + $w * cos($a); |
|||
360 | 2 | $pt[] = $yc - $h * sin($a); |
|||
361 | } |
||||
362 | |||||
363 | 2 | $pt[] = $xc + $w * $cossa; |
|||
364 | 2 | $pt[] = $yc - $h * $sinsa; |
|||
365 | 2 | $pt[] = $xc; |
|||
366 | 2 | $pt[] = $yc; |
|||
367 | } else { |
||||
368 | // $sa >= 90 && $ea <= 180 |
||||
369 | 2 | $p = [$xc, $yc, $xc, $yc + $z, |
|||
370 | 2 | $xc + $w * $cosea, $z + $yc - $h * $sinea, |
|||
371 | 2 | $xc + $w * $cosea, $yc - $h * $sinea, |
|||
372 | 2 | $xc, $yc, ]; |
|||
373 | |||||
374 | 2 | $pt = [$xc, $yc, $xc + $w * $cosea, $yc - $h * $sinea]; |
|||
375 | |||||
376 | 2 | for ($a = $rea; $a > $rsa; $a -= $step) { |
|||
377 | 2 | $pt[] = $xc + $w * cos($a); |
|||
378 | 2 | $pt[] = $yc - $h * sin($a); |
|||
379 | } |
||||
380 | |||||
381 | 2 | $pt[] = $xc + $w * $cossa; |
|||
382 | 2 | $pt[] = $yc - $h * $sinsa; |
|||
383 | 2 | $pt[] = $xc; |
|||
384 | 2 | $pt[] = $yc; |
|||
385 | } |
||||
386 | } else { |
||||
387 | // sa > 0 && ea < 90 |
||||
388 | |||||
389 | 2 | $p = [$xc, $yc, $xc, $yc + $z, |
|||
390 | 2 | $xc + $w * $cossa, $z + $yc - $h * $sinsa, |
|||
391 | 2 | $xc + $w * $cossa, $yc - $h * $sinsa, |
|||
392 | 2 | $xc, $yc, ]; |
|||
393 | |||||
394 | 2 | $pt = [$xc, $yc, $xc + $w * $cossa, $yc - $h * $sinsa]; |
|||
395 | |||||
396 | 2 | for ($a = $rsa; $a < $rea; $a += $step) { |
|||
397 | 2 | $pt[] = $xc + $w * cos($a); |
|||
398 | 2 | $pt[] = $yc - $h * sin($a); |
|||
399 | } |
||||
400 | |||||
401 | 2 | $pt[] = $xc + $w * $cosea; |
|||
402 | 2 | $pt[] = $yc - $h * $sinea; |
|||
403 | 2 | $pt[] = $xc; |
|||
404 | 2 | $pt[] = $yc; |
|||
405 | } |
||||
406 | |||||
407 | 2 | $img->PushColor($fillcolor . ':' . $shadow); |
|||
408 | 2 | $img->FilledPolygon($p); |
|||
409 | 2 | $img->PopColor(); |
|||
410 | |||||
411 | 2 | $img->PushColor($fillcolor); |
|||
412 | 2 | $img->FilledPolygon($pt); |
|||
413 | 2 | $img->PopColor(); |
|||
414 | 2 | } |
|||
415 | |||||
416 | 1 | public function SetStartAngle($aStart) |
|||
417 | { |
||||
418 | 1 | if ($aStart < 0 || $aStart > 360) { |
|||
419 | Util\JpGraphError::RaiseL(14004); //('Slice start angle must be between 0 and 360 degrees.'); |
||||
420 | } |
||||
421 | 1 | $this->startangle = $aStart; |
|||
422 | 1 | } |
|||
423 | |||||
424 | // Draw a 3D Pie |
||||
425 | 2 | public function Pie3D( |
|||
426 | $aaoption, |
||||
427 | $img, |
||||
428 | $data, |
||||
429 | $colors, |
||||
430 | $xc, |
||||
431 | $yc, |
||||
432 | $d, |
||||
433 | $angle, |
||||
434 | $z, |
||||
435 | $shadow = 0.65, |
||||
436 | $startangle = 0, |
||||
437 | $edgecolor = '', |
||||
438 | $edgeweight = 1 |
||||
439 | ) { |
||||
440 | /** |
||||
441 | * As usual the algorithm get more complicated than I originally |
||||
442 | * // envisioned. I believe that this is as simple as it is possible |
||||
443 | * // to do it with the features I want. It's a good exercise to start |
||||
444 | * // thinking on how to do this to convince your self that all this |
||||
445 | * // is really needed for the general case. |
||||
446 | * // |
||||
447 | * // The algorithm two draw 3D pies without "real 3D" is done in |
||||
448 | * // two steps. |
||||
449 | * // First imagine the pie cut in half through a thought line between |
||||
450 | * // 12'a clock and 6'a clock. It now easy to imagine that we can plot |
||||
451 | * // the individual slices for each half by starting with the topmost |
||||
452 | * // pie slice and continue down to 6'a clock. |
||||
453 | * // |
||||
454 | * // In the algortithm this is done in three principal steps |
||||
455 | * // Step 1. Do the knife cut to ensure by splitting slices that extends |
||||
456 | * // over the cut line. This is done by splitting the original slices into |
||||
457 | * // upto 3 subslices. |
||||
458 | * // Step 2. Find the top slice for each half |
||||
459 | * // Step 3. Draw the slices from top to bottom |
||||
460 | * // |
||||
461 | * // The thing that slightly complicates this scheme with all the |
||||
462 | * // angle comparisons below is that we can have an arbitrary start |
||||
463 | * // angle so we must take into account the different equivalence classes. |
||||
464 | * // For the same reason we must walk through the angle array in a |
||||
465 | * // modulo fashion. |
||||
466 | * // |
||||
467 | * // Limitations of algorithm: |
||||
468 | * // * A small exploded slice which crosses the 270 degree point |
||||
469 | * // will get slightly nagged close to the center due to the fact that |
||||
470 | * // we print the slices in Z-order and that the slice left part |
||||
471 | * // get printed first and might get slightly nagged by a larger |
||||
472 | * // slice on the right side just before the right part of the small |
||||
473 | * // slice. Not a major problem though. |
||||
474 | */ |
||||
475 | // Determine the height of the ellippse which gives an |
||||
476 | // indication of the inclination angle |
||||
477 | 2 | $h = ($angle / 90.0) * $d; |
|||
478 | 2 | $sum = 0; |
|||
479 | 2 | for ($i = 0; $i < safe_count($data); ++$i) { |
|||
480 | 2 | $sum += $data[$i]; |
|||
481 | } |
||||
482 | |||||
483 | // Special optimization |
||||
484 | 2 | if ($sum == 0) { |
|||
0 ignored issues
–
show
|
|||||
485 | return; |
||||
486 | } |
||||
487 | |||||
488 | 2 | if ($this->labeltype == 2) { |
|||
489 | $this->adjusted_data = $this->AdjPercentage($data); |
||||
490 | } |
||||
491 | |||||
492 | // Setup the start |
||||
493 | 2 | $accsum = 0; |
|||
0 ignored issues
–
show
|
|||||
494 | 2 | $a = $startangle; |
|||
495 | 2 | $a = $this->NormAngle($a); |
|||
496 | |||||
497 | // |
||||
498 | // Step 1 . Split all slices that crosses 90 or 270 |
||||
499 | // |
||||
500 | 2 | $idx = 0; |
|||
501 | 2 | $adjexplode = []; |
|||
502 | 2 | $numcolors = safe_count($colors); |
|||
503 | 2 | for ($i = 0; $i < safe_count($data); ++$i, ++$idx) { |
|||
504 | 2 | $da = $data[$i] / $sum * 360; |
|||
505 | |||||
506 | 2 | if (empty($this->explode_radius[$i])) { |
|||
507 | 2 | $this->explode_radius[$i] = 0; |
|||
508 | } |
||||
509 | |||||
510 | 2 | $expscale = 1; |
|||
511 | 2 | if ($aaoption == 1) { |
|||
512 | 2 | $expscale = 2; |
|||
513 | } |
||||
514 | |||||
515 | 2 | $la = $a + $da / 2; |
|||
516 | 2 | $explode = [$xc + $this->explode_radius[$i] * cos($la * M_PI / 180) * $expscale, |
|||
517 | 2 | $yc - $this->explode_radius[$i] * sin($la * M_PI / 180) * ($h / $d) * $expscale, ]; |
|||
518 | 2 | $adjexplode[$idx] = $explode; |
|||
519 | 2 | $labeldata[$i] = [$la, $explode[0], $explode[1]]; |
|||
520 | 2 | $originalangles[$i] = [$a, $a + $da]; |
|||
521 | |||||
522 | 2 | $ne = $this->NormAngle($a + $da); |
|||
523 | 2 | if ($da <= 180) { |
|||
524 | // If the slice size is <= 90 it can at maximum cut across |
||||
525 | // one boundary (either 90 or 270) where it needs to be split |
||||
526 | 2 | $split = -1; // no split |
|||
527 | 2 | if (($da <= 90 && ($a <= 90 && $ne > 90)) || |
|||
528 | 2 | (($da <= 180 && $da > 90) && (($a < 90 || $a >= 270) && $ne > 90))) { |
|||
529 | 2 | $split = 90; |
|||
530 | 2 | } elseif (($da <= 90 && ($a <= 270 && $ne > 270)) || |
|||
531 | 2 | (($da <= 180 && $da > 90) && ($a >= 90 && $a < 270 && ($a + $da) > 270))) { |
|||
532 | 2 | $split = 270; |
|||
533 | } |
||||
534 | 2 | if ($split > 0) { |
|||
535 | // split in two |
||||
536 | 2 | $angles[$idx] = [$a, $split]; |
|||
537 | 2 | $adjcolors[$idx] = $colors[$i % $numcolors]; |
|||
538 | 2 | $adjexplode[$idx] = $explode; |
|||
539 | 2 | $angles[++$idx] = [$split, $ne]; |
|||
540 | 2 | $adjcolors[$idx] = $colors[$i % $numcolors]; |
|||
541 | 2 | $adjexplode[$idx] = $explode; |
|||
542 | } else { |
||||
543 | // no split |
||||
544 | 2 | $angles[$idx] = [$a, $ne]; |
|||
545 | 2 | $adjcolors[$idx] = $colors[$i % $numcolors]; |
|||
546 | 2 | $adjexplode[$idx] = $explode; |
|||
547 | } |
||||
548 | } else { |
||||
549 | // da>180 |
||||
550 | // Slice may, depending on position, cross one or two |
||||
551 | // bonudaries |
||||
552 | |||||
553 | if ($a < 90) { |
||||
554 | $split = 90; |
||||
555 | } elseif ($a <= 270) { |
||||
556 | $split = 270; |
||||
557 | } else { |
||||
558 | $split = 90; |
||||
559 | } |
||||
560 | |||||
561 | $angles[$idx] = [$a, $split]; |
||||
562 | $adjcolors[$idx] = $colors[$i % $numcolors]; |
||||
563 | $adjexplode[$idx] = $explode; |
||||
564 | //if( $a+$da > 360-$split ) { |
||||
565 | // For slices larger than 270 degrees we might cross |
||||
566 | // another boundary as well. This means that we must |
||||
567 | // split the slice further. The comparison gets a little |
||||
568 | // bit complicated since we must take into accound that |
||||
569 | // a pie might have a startangle >0 and hence a slice might |
||||
570 | // wrap around the 0 angle. |
||||
571 | // Three cases: |
||||
572 | // a) Slice starts before 90 and hence gets a split=90, but |
||||
573 | // we must also check if we need to split at 270 |
||||
574 | // b) Slice starts after 90 but before 270 and slices |
||||
575 | // crosses 90 (after a wrap around of 0) |
||||
576 | // c) If start is > 270 (hence the firstr split is at 90) |
||||
577 | // and the slice is so large that it goes all the way |
||||
578 | // around 270. |
||||
579 | if (($a < 90 && ($a + $da > 270)) || ($a > 90 && $a <= 270 && ($a + $da > 360 + 90)) || ($a > 270 && $this->NormAngle($a + $da) > 270)) { |
||||
580 | $angles[++$idx] = [$split, 360 - $split]; |
||||
581 | $adjcolors[$idx] = $colors[$i % $numcolors]; |
||||
582 | $adjexplode[$idx] = $explode; |
||||
583 | $angles[++$idx] = [360 - $split, $ne]; |
||||
584 | $adjcolors[$idx] = $colors[$i % $numcolors]; |
||||
585 | $adjexplode[$idx] = $explode; |
||||
586 | } else { |
||||
587 | // Just a simple split to the previous decided |
||||
588 | // angle. |
||||
589 | $angles[++$idx] = [$split, $ne]; |
||||
590 | $adjcolors[$idx] = $colors[$i % $numcolors]; |
||||
591 | $adjexplode[$idx] = $explode; |
||||
592 | } |
||||
593 | } |
||||
594 | 2 | $a += $da; |
|||
595 | 2 | $a = $this->NormAngle($a); |
|||
596 | } |
||||
597 | |||||
598 | // Total number of slices |
||||
599 | 2 | $n = safe_count($angles); |
|||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
600 | |||||
601 | 2 | for ($i = 0; $i < $n; ++$i) { |
|||
602 | 2 | list($dbgs, $dbge) = $angles[$i]; |
|||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
603 | } |
||||
604 | |||||
605 | // |
||||
606 | // Step 2. Find start index (first pie that starts in upper left quadrant) |
||||
607 | // |
||||
608 | 2 | $minval = $angles[0][0]; |
|||
609 | 2 | $min = 0; |
|||
610 | 2 | for ($i = 0; $i < $n; ++$i) { |
|||
611 | 2 | if ($angles[$i][0] < $minval) { |
|||
612 | $minval = $angles[$i][0]; |
||||
613 | $min = $i; |
||||
614 | } |
||||
615 | } |
||||
616 | 2 | $j = $min; |
|||
617 | 2 | $cnt = 0; |
|||
618 | 2 | while ($angles[$j][1] <= 90) { |
|||
619 | 2 | ++$j; |
|||
620 | 2 | if ($j >= $n) { |
|||
621 | $j = 0; |
||||
622 | } |
||||
623 | 2 | if ($cnt > $n) { |
|||
624 | Util\JpGraphError::RaiseL(14005); |
||||
625 | //("Pie3D Internal error (#1). Trying to wrap twice when looking for start index"); |
||||
626 | } |
||||
627 | 2 | ++$cnt; |
|||
628 | } |
||||
629 | 2 | $start = $j; |
|||
630 | |||||
631 | // |
||||
632 | // Step 3. Print slices in z-order |
||||
633 | // |
||||
634 | 2 | $cnt = 0; |
|||
635 | |||||
636 | // First stroke all the slices between 90 and 270 (left half circle) |
||||
637 | // counterclockwise |
||||
638 | |||||
639 | 2 | while ($angles[$j][0] < 270 && $aaoption !== 2) { |
|||
640 | 2 | list($x, $y) = $adjexplode[$j]; |
|||
641 | |||||
642 | 2 | $this->Pie3DSlice( |
|||
643 | 2 | $img, |
|||
644 | 2 | $x, |
|||
645 | 2 | $y, |
|||
646 | 2 | $d, |
|||
647 | 2 | $h, |
|||
648 | 2 | $angles[$j][0], |
|||
649 | 2 | $angles[$j][1], |
|||
650 | 2 | $z, |
|||
651 | 2 | $adjcolors[$j], |
|||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
652 | 2 | $shadow |
|||
653 | ); |
||||
654 | |||||
655 | 2 | $last = [$x, $y, $j]; |
|||
656 | |||||
657 | 2 | ++$j; |
|||
658 | 2 | if ($j >= $n) { |
|||
659 | $j = 0; |
||||
660 | } |
||||
661 | |||||
662 | 2 | if ($cnt > $n) { |
|||
663 | Util\JpGraphError::RaiseL(14006); |
||||
664 | //("Pie3D Internal Error: Z-Sorting algorithm for 3D Pies is not working properly (2). Trying to wrap twice while stroking."); |
||||
665 | } |
||||
666 | 2 | ++$cnt; |
|||
667 | } |
||||
668 | |||||
669 | 2 | $slice_left = $n - $cnt; |
|||
670 | 2 | $j = $start - 1; |
|||
671 | 2 | if ($j < 0) { |
|||
672 | $j = $n - 1; |
||||
673 | } |
||||
674 | |||||
675 | 2 | $cnt = 0; |
|||
676 | |||||
677 | // The stroke all slices from 90 to -90 (right half circle) |
||||
678 | // clockwise |
||||
679 | 2 | while ($cnt < $slice_left && $aaoption !== 2) { |
|||
680 | 2 | list($x, $y) = $adjexplode[$j]; |
|||
681 | |||||
682 | 2 | $this->Pie3DSlice( |
|||
683 | 2 | $img, |
|||
684 | 2 | $x, |
|||
685 | 2 | $y, |
|||
686 | 2 | $d, |
|||
687 | 2 | $h, |
|||
688 | 2 | $angles[$j][0], |
|||
689 | 2 | $angles[$j][1], |
|||
690 | 2 | $z, |
|||
691 | 2 | $adjcolors[$j], |
|||
692 | 2 | $shadow |
|||
693 | ); |
||||
694 | 2 | --$j; |
|||
695 | 2 | if ($cnt > $n) { |
|||
696 | Util\JpGraphError::RaiseL(14006); |
||||
697 | //("Pie3D Internal Error: Z-Sorting algorithm for 3D Pies is not working properly (2). Trying to wrap twice while stroking."); |
||||
698 | } |
||||
699 | 2 | if ($j < 0) { |
|||
700 | 2 | $j = $n - 1; |
|||
701 | } |
||||
702 | |||||
703 | 2 | ++$cnt; |
|||
704 | } |
||||
705 | |||||
706 | // Now do a special thing. Stroke the last slice on the left |
||||
707 | // halfcircle one more time. This is needed in the case where |
||||
708 | // the slice close to 270 have been exploded. In that case the |
||||
709 | // part of the slice close to the center of the pie might be |
||||
710 | // slightly nagged. |
||||
711 | 2 | if ($aaoption !== 2) { |
|||
712 | 2 | $this->Pie3DSlice( |
|||
713 | 2 | $img, |
|||
714 | 2 | $last[0], |
|||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
715 | 2 | $last[1], |
|||
716 | 2 | $d, |
|||
717 | 2 | $h, |
|||
718 | 2 | $angles[$last[2]][0], |
|||
719 | 2 | $angles[$last[2]][1], |
|||
720 | 2 | $z, |
|||
721 | 2 | $adjcolors[$last[2]], |
|||
722 | 2 | $shadow |
|||
723 | ); |
||||
724 | } |
||||
725 | |||||
726 | 2 | if ($aaoption !== 1) { |
|||
727 | // Now print possible labels and add csim |
||||
728 | 2 | $this->value->ApplyFont($img); |
|||
729 | 2 | $margin = $img->GetFontHeight() / 2 + $this->value->margin; |
|||
730 | 2 | for ($i = 0; $i < safe_count($data); ++$i) { |
|||
731 | 2 | $la = $labeldata[$i][0]; |
|||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
732 | 2 | $x = $labeldata[$i][1] + cos($la * M_PI / 180) * ($d + $margin) * $this->ilabelposadj; |
|||
733 | 2 | $y = $labeldata[$i][2] - sin($la * M_PI / 180) * ($h + $margin) * $this->ilabelposadj; |
|||
734 | 2 | if ($this->ilabelposadj >= 1.0) { |
|||
735 | 2 | if ($la > 180 && $la < 360) { |
|||
736 | 2 | $y += $z; |
|||
737 | } |
||||
738 | } |
||||
739 | 2 | if ($this->labeltype == 0) { |
|||
740 | 2 | if ($sum > 0) { |
|||
741 | 2 | $l = 100 * $data[$i] / $sum; |
|||
742 | } else { |
||||
743 | 2 | $l = 0; |
|||
744 | } |
||||
745 | } elseif ($this->labeltype == 1) { |
||||
746 | $l = $data[$i]; |
||||
747 | } else { |
||||
748 | $l = $this->adjusted_data[$i]; |
||||
749 | } |
||||
750 | 2 | if (isset($this->labels[$i]) && is_string($this->labels[$i])) { |
|||
751 | $l = sprintf($this->labels[$i], $l); |
||||
752 | } |
||||
753 | |||||
754 | 2 | $this->StrokeLabels($l, $img, $labeldata[$i][0] * M_PI / 180, $x, $y, $z); |
|||
755 | |||||
756 | 2 | $this->Add3DSliceToCSIM( |
|||
757 | 2 | $i, |
|||
758 | 2 | $labeldata[$i][1], |
|||
759 | 2 | $labeldata[$i][2], |
|||
760 | 2 | $h * 2, |
|||
761 | 2 | $d * 2, |
|||
762 | 2 | $z, |
|||
763 | 2 | $originalangles[$i][0], |
|||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
764 | 2 | $originalangles[$i][1] |
|||
765 | ); |
||||
766 | } |
||||
767 | } |
||||
768 | |||||
769 | // |
||||
770 | // Finally add potential lines in pie |
||||
771 | // |
||||
772 | |||||
773 | 2 | if ($edgecolor == '' || $aaoption !== 0) { |
|||
774 | 2 | return; |
|||
775 | } |
||||
776 | |||||
777 | $accsum = 0; |
||||
778 | $a = $startangle; |
||||
779 | $a = $this->NormAngle($a); |
||||
780 | |||||
781 | $a *= M_PI / 180.0; |
||||
782 | |||||
783 | $idx = 0; |
||||
784 | $img->PushColor($edgecolor); |
||||
785 | $img->SetLineWeight($edgeweight); |
||||
786 | |||||
787 | $fulledge = true; |
||||
788 | for ($i = 0; $i < safe_count($data) && $fulledge; ++$i) { |
||||
789 | if (empty($this->explode_radius[$i])) { |
||||
790 | $this->explode_radius[$i] = 0; |
||||
791 | } |
||||
792 | if ($this->explode_radius[$i] > 0) { |
||||
793 | $fulledge = false; |
||||
794 | } |
||||
795 | } |
||||
796 | |||||
797 | for ($i = 0; $i < safe_count($data); ++$i, ++$idx) { |
||||
798 | $da = $data[$i] / $sum * 2 * M_PI; |
||||
799 | $this->StrokeFullSliceFrame( |
||||
800 | $img, |
||||
801 | $xc, |
||||
802 | $yc, |
||||
803 | $a, |
||||
804 | $a + $da, |
||||
805 | $d, |
||||
806 | $h, |
||||
807 | $z, |
||||
808 | $edgecolor, |
||||
809 | $this->explode_radius[$i], |
||||
810 | $fulledge |
||||
811 | ); |
||||
812 | $a += $da; |
||||
813 | } |
||||
814 | $img->PopColor(); |
||||
815 | } |
||||
816 | |||||
817 | public function StrokeFullSliceFrame($img, $xc, $yc, $sa, $ea, $w, $h, $z, $edgecolor, $exploderadius, $fulledge) |
||||
818 | { |
||||
819 | $step = 0.02; |
||||
820 | |||||
821 | if ($exploderadius > 0) { |
||||
822 | $la = ($sa + $ea) / 2; |
||||
823 | $xc += $exploderadius * cos($la); |
||||
824 | $yc -= $exploderadius * sin($la) * ($h / $w); |
||||
825 | } |
||||
826 | |||||
827 | $p = [$xc, $yc, $xc + $w * cos($sa), $yc - $h * sin($sa)]; |
||||
828 | |||||
829 | for ($a = $sa; $a < $ea; $a += $step) { |
||||
830 | $p[] = $xc + $w * cos($a); |
||||
831 | $p[] = $yc - $h * sin($a); |
||||
832 | } |
||||
833 | |||||
834 | $p[] = $xc + $w * cos($ea); |
||||
835 | $p[] = $yc - $h * sin($ea); |
||||
836 | $p[] = $xc; |
||||
837 | $p[] = $yc; |
||||
838 | |||||
839 | $img->SetColor($edgecolor); |
||||
840 | $img->Polygon($p); |
||||
841 | |||||
842 | // Unfortunately we can't really draw the full edge around the whole of |
||||
843 | // of the slice if any of the slices are exploded. The reason is that |
||||
844 | // this algorithm is to simply. There are cases where the edges will |
||||
845 | // "overwrite" other slices when they have been exploded. |
||||
846 | // Doing the full, proper 3D hidden lines stiff is actually quite |
||||
847 | // tricky. So for exploded pies we only draw the top edge. Not perfect |
||||
848 | // but the "real" solution is much more complicated. |
||||
849 | if ($fulledge && !($sa > 0 && $sa < M_PI && $ea < M_PI)) { |
||||
850 | if ($sa < M_PI && $ea > M_PI) { |
||||
851 | $sa = M_PI; |
||||
852 | } |
||||
853 | |||||
854 | if ($sa < 2 * M_PI && (($ea >= 2 * M_PI) || ($ea > 0 && $ea < $sa))) { |
||||
855 | $ea = 2 * M_PI; |
||||
856 | } |
||||
857 | |||||
858 | if ($sa >= M_PI && $ea <= 2 * M_PI) { |
||||
859 | $p = [$xc + $w * cos($sa), $yc - $h * sin($sa), |
||||
860 | $xc + $w * cos($sa), $z + $yc - $h * sin($sa), ]; |
||||
861 | |||||
862 | for ($a = $sa + $step; $a < $ea; $a += $step) { |
||||
863 | $p[] = $xc + $w * cos($a); |
||||
864 | $p[] = $z + $yc - $h * sin($a); |
||||
865 | } |
||||
866 | $p[] = $xc + $w * cos($ea); |
||||
867 | $p[] = $z + $yc - $h * sin($ea); |
||||
868 | $p[] = $xc + $w * cos($ea); |
||||
869 | $p[] = $yc - $h * sin($ea); |
||||
870 | $img->SetColor($edgecolor); |
||||
871 | $img->Polygon($p); |
||||
872 | } |
||||
873 | } |
||||
874 | } |
||||
875 | |||||
876 | 2 | public function Stroke($img, $aaoption = 0) |
|||
877 | { |
||||
878 | 2 | $n = safe_count($this->data); |
|||
879 | |||||
880 | // If user hasn't set the colors use the theme array |
||||
881 | 2 | if ($this->setslicecolors == null) { |
|||
882 | 2 | $colors = array_keys($img->rgb->rgb_table); |
|||
883 | 2 | sort($colors); |
|||
884 | 2 | $idx_a = $this->themearr[$this->theme]; |
|||
885 | 2 | $ca = []; |
|||
886 | 2 | $m = safe_count($idx_a); |
|||
887 | 2 | for ($i = 0; $i < $m; ++$i) { |
|||
888 | 2 | $ca[$i] = $colors[$idx_a[$i]]; |
|||
889 | } |
||||
890 | 2 | $ca = array_reverse(array_slice($ca, 0, $n)); |
|||
891 | } else { |
||||
892 | $ca = $this->setslicecolors; |
||||
893 | } |
||||
894 | |||||
895 | 2 | if ($this->posx <= 1 && $this->posx > 0) { |
|||
896 | 2 | $xc = round($this->posx * $img->width); |
|||
897 | } else { |
||||
898 | $xc = $this->posx; |
||||
899 | } |
||||
900 | |||||
901 | 2 | if ($this->posy <= 1 && $this->posy > 0) { |
|||
902 | 2 | $yc = round($this->posy * $img->height); |
|||
903 | } else { |
||||
904 | $yc = $this->posy; |
||||
905 | } |
||||
906 | |||||
907 | 2 | if ($this->radius <= 1) { |
|||
908 | 2 | $width = floor($this->radius * min($img->width, $img->height)); |
|||
909 | // Make sure that the pie doesn't overflow the image border |
||||
910 | // The 0.9 factor is simply an extra margin to leave some space |
||||
911 | // between the pie an the border of the image. |
||||
912 | 2 | $width = min($width, min($xc * 0.9, ($yc * 90 / $this->angle - $width / 4) * 0.9)); |
|||
913 | } else { |
||||
914 | 1 | $width = $this->radius * ($aaoption === 1 ? 2 : 1); |
|||
915 | } |
||||
916 | |||||
917 | // Add a sanity check for width |
||||
918 | 2 | if ($width < 1) { |
|||
919 | Util\JpGraphError::RaiseL(14007); //("Width for 3D Pie is 0. Specify a size > 0"); |
||||
920 | } |
||||
921 | |||||
922 | // Establish a thickness. By default the thickness is a fifth of the |
||||
923 | // pie slice width (=pie radius) but since the perspective depends |
||||
924 | // on the inclination angle we use some heuristics to make the edge |
||||
925 | // slightly thicker the less the angle. |
||||
926 | |||||
927 | // Has user specified an absolute thickness? In that case use |
||||
928 | // that instead |
||||
929 | |||||
930 | 2 | if ($this->iThickness) { |
|||
931 | 1 | $thick = $this->iThickness; |
|||
932 | 1 | $thick *= ($aaoption === 1 ? 2 : 1); |
|||
933 | } else { |
||||
934 | 2 | $thick = $width / 12; |
|||
935 | } |
||||
936 | 2 | $a = $this->angle; |
|||
937 | |||||
938 | 2 | if ($a <= 30) { |
|||
939 | 2 | $thick *= 1.6; |
|||
940 | 2 | } elseif ($a <= 40) { |
|||
941 | $thick *= 1.4; |
||||
942 | 2 | } elseif ($a <= 50) { |
|||
943 | 2 | $thick *= 1.2; |
|||
944 | } elseif ($a <= 60) { |
||||
945 | $thick *= 1.0; |
||||
946 | } elseif ($a <= 70) { |
||||
947 | $thick *= 0.8; |
||||
948 | } elseif ($a <= 80) { |
||||
949 | $thick *= 0.7; |
||||
950 | } else { |
||||
951 | $thick *= 0.6; |
||||
952 | } |
||||
953 | |||||
954 | 2 | $thick = floor($thick); |
|||
0 ignored issues
–
show
It seems like
$thick can also be of type true ; however, parameter $num of floor() does only seem to accept double|integer , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
955 | |||||
956 | 2 | if ($this->explode_all) { |
|||
957 | for ($i = 0; $i < $n; ++$i) { |
||||
958 | $this->explode_radius[$i] = $this->explode_r; |
||||
959 | } |
||||
960 | } |
||||
961 | |||||
962 | 2 | $this->Pie3D( |
|||
963 | 2 | $aaoption, |
|||
964 | 2 | $img, |
|||
965 | 2 | $this->data, |
|||
966 | 2 | $ca, |
|||
967 | 2 | $xc, |
|||
968 | 2 | $yc, |
|||
969 | 2 | $width, |
|||
970 | 2 | $this->angle, |
|||
971 | 2 | $thick, |
|||
972 | 2 | 0.65, |
|||
973 | 2 | $this->startangle, |
|||
974 | 2 | $this->edgecolor, |
|||
975 | 2 | $this->edgeweight |
|||
976 | ); |
||||
977 | |||||
978 | // Adjust title position |
||||
979 | 2 | if ($aaoption != 1) { |
|||
980 | 2 | $this->title->SetPos($xc, $yc - $this->title->GetFontHeight($img) - $width / 2 - $this->title->margin, 'center', 'bottom'); |
|||
981 | 2 | $this->title->Stroke($img); |
|||
982 | } |
||||
983 | 2 | } |
|||
984 | |||||
985 | /** |
||||
986 | * PRIVATE METHODS. |
||||
987 | * |
||||
988 | * @param mixed $label |
||||
989 | * @param mixed $img |
||||
990 | * @param mixed $a |
||||
991 | * @param mixed $xp |
||||
992 | * @param mixed $yp |
||||
993 | * @param mixed $z |
||||
994 | */ |
||||
995 | |||||
996 | // Position the labels of each slice |
||||
997 | 2 | public function StrokeLabels($label, $img, $a, $xp, $yp, $z) |
|||
0 ignored issues
–
show
The parameter
$z is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
998 | { |
||||
999 | 2 | $this->value->halign = 'left'; |
|||
1000 | 2 | $this->value->valign = 'top'; |
|||
1001 | |||||
1002 | // Position the axis title. |
||||
1003 | // dx, dy is the offset from the top left corner of the bounding box that sorrounds the text |
||||
1004 | // that intersects with the extension of the corresponding axis. The code looks a little |
||||
1005 | // bit messy but this is really the only way of having a reasonable position of the |
||||
1006 | // axis titles. |
||||
1007 | 2 | $this->value->ApplyFont($img); |
|||
1008 | 2 | $h = $img->GetTextHeight($label); |
|||
1009 | // For numeric values the format of the display value |
||||
1010 | // must be taken into account |
||||
1011 | 2 | if (is_numeric($label)) { |
|||
1012 | 2 | if ($label >= 0) { |
|||
1013 | 2 | $w = $img->GetTextWidth(sprintf($this->value->format, $label)); |
|||
1014 | } else { |
||||
1015 | 2 | $w = $img->GetTextWidth(sprintf($this->value->negformat, $label)); |
|||
1016 | } |
||||
1017 | } else { |
||||
1018 | $w = $img->GetTextWidth($label); |
||||
1019 | } |
||||
1020 | |||||
1021 | 2 | while ($a > 2 * M_PI) { |
|||
1022 | $a -= 2 * M_PI; |
||||
1023 | } |
||||
1024 | |||||
1025 | 2 | if ($a >= 7 * M_PI / 4 || $a <= M_PI / 4) { |
|||
1026 | 2 | $dx = 0; |
|||
1027 | } |
||||
1028 | |||||
1029 | 2 | if ($a >= M_PI / 4 && $a <= 3 * M_PI / 4) { |
|||
1030 | 2 | $dx = ($a - M_PI / 4) * 2 / M_PI; |
|||
1031 | } |
||||
1032 | |||||
1033 | 2 | if ($a >= 3 * M_PI / 4 && $a <= 5 * M_PI / 4) { |
|||
1034 | 2 | $dx = 1; |
|||
1035 | } |
||||
1036 | |||||
1037 | 2 | if ($a >= 5 * M_PI / 4 && $a <= 7 * M_PI / 4) { |
|||
1038 | 2 | $dx = (1 - ($a - M_PI * 5 / 4) * 2 / M_PI); |
|||
1039 | } |
||||
1040 | |||||
1041 | 2 | if ($a >= 7 * M_PI / 4) { |
|||
1042 | 2 | $dy = (($a - M_PI) - 3 * M_PI / 4) * 2 / M_PI; |
|||
1043 | } |
||||
1044 | |||||
1045 | 2 | if ($a <= M_PI / 4) { |
|||
1046 | 1 | $dy = (1 - $a * 2 / M_PI); |
|||
1047 | } |
||||
1048 | |||||
1049 | 2 | if ($a >= M_PI / 4 && $a <= 3 * M_PI / 4) { |
|||
1050 | 2 | $dy = 1; |
|||
1051 | } |
||||
1052 | |||||
1053 | 2 | if ($a >= 3 * M_PI / 4 && $a <= 5 * M_PI / 4) { |
|||
1054 | 2 | $dy = (1 - ($a - 3 * M_PI / 4) * 2 / M_PI); |
|||
1055 | } |
||||
1056 | |||||
1057 | 2 | if ($a >= 5 * M_PI / 4 && $a <= 7 * M_PI / 4) { |
|||
1058 | 2 | $dy = 0; |
|||
1059 | } |
||||
1060 | |||||
1061 | 2 | $x = round($xp - $dx * $w); |
|||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
1062 | 2 | $y = round($yp - $dy * $h); |
|||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
1063 | |||||
1064 | // Mark anchor point for debugging |
||||
1065 | /* |
||||
1066 | $img->SetColor('red'); |
||||
1067 | $img->Line($xp-10,$yp,$xp+10,$yp); |
||||
1068 | $img->Line($xp,$yp-10,$xp,$yp+10); |
||||
1069 | */ |
||||
1070 | |||||
1071 | 2 | $oldmargin = $this->value->margin; |
|||
1072 | 2 | $this->value->margin = 0; |
|||
1073 | 2 | $this->value->Stroke($img, $label, $x, $y); |
|||
1074 | 2 | $this->value->margin = $oldmargin; |
|||
1075 | 2 | } |
|||
1076 | } // @class |
||||
1077 | |||||
1078 | /* EOF */ |
||||
1079 |