PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.12.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.12.1
5.12.1 5.12.0 5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / vendor / szymach / c-pchart / src / Chart / Surface.php
matomo / app / vendor / szymach / c-pchart / src / Chart Last commit date
Bubble.php 1 year ago Indicator.php 1 year ago Pie.php 1 year ago Radar.php 1 year ago Scatter.php 1 year ago Split.php 1 year ago Spring.php 1 year ago Stock.php 1 year ago Surface.php 1 year ago
Surface.php
355 lines
1 <?php
2
3 namespace CpChart\Chart;
4
5 use CpChart\Image;
6 /**
7 * Surface - class to draw surface charts
8 *
9 * Version : 2.1.4
10 * Made by : Jean-Damien POGOLOTTI
11 * Last Update : 19/01/2014
12 *
13 * This file can be distributed under the license you can find at :
14 *
15 * http://www.pchart.net/license
16 *
17 * You can find the whole class documentation on the pChart web site.
18 */
19 class Surface
20 {
21 /**
22 * @var Image
23 */
24 public $pChartObject;
25 /**
26 * @var int
27 */
28 public $GridSizeX;
29 /**
30 * @var int
31 */
32 public $GridSizeY;
33 /**
34 * @var array
35 */
36 public $Points = [];
37 /**
38 * @param Image $pChartObject
39 */
40 public function __construct(Image $pChartObject)
41 {
42 $this->pChartObject = $pChartObject;
43 }
44 /**
45 * Define the grid size and initialise the 2D matrix
46 * @param int $XSize
47 * @param int $YSize
48 */
49 public function setGrid($XSize = 10, $YSize = 10)
50 {
51 for ($X = 0; $X <= $XSize; $X++) {
52 for ($Y = 0; $Y <= $YSize; $Y++) {
53 $this->Points[$X][$Y] = UNKNOWN;
54 }
55 }
56 $this->GridSizeX = $XSize;
57 $this->GridSizeY = $YSize;
58 }
59 /**
60 * Add a point on the grid
61 * @param int $X
62 * @param int $Y
63 * @param int|float $Value
64 * @param boolean $Force
65 * @return null
66 */
67 public function addPoint($X, $Y, $Value, $Force = \true)
68 {
69 if ($X < 0 || $X > $this->GridSizeX) {
70 return 0;
71 }
72 if ($Y < 0 || $Y > $this->GridSizeY) {
73 return 0;
74 }
75 if ($this->Points[$X][$Y] == UNKNOWN || $Force) {
76 $this->Points[$X][$Y] = $Value;
77 } elseif ($this->Points[$X][$Y] == UNKNOWN) {
78 $this->Points[$X][$Y] = $Value;
79 } else {
80 $this->Points[$X][$Y] = ($this->Points[$X][$Y] + $Value) / 2;
81 }
82 }
83 /**
84 * Write the X labels
85 * @param array $Format
86 * @return null|int
87 */
88 public function writeXLabels(array $Format = [])
89 {
90 $R = isset($Format["R"]) ? $Format["R"] : $this->pChartObject->FontColorR;
91 $G = isset($Format["G"]) ? $Format["G"] : $this->pChartObject->FontColorG;
92 $B = isset($Format["B"]) ? $Format["B"] : $this->pChartObject->FontColorB;
93 $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : $this->pChartObject->FontColorA;
94 $Angle = isset($Format["Angle"]) ? $Format["Angle"] : 0;
95 $Padding = isset($Format["Padding"]) ? $Format["Padding"] : 5;
96 $Position = isset($Format["Position"]) ? $Format["Position"] : LABEL_POSITION_TOP;
97 $Labels = isset($Format["Labels"]) ? $Format["Labels"] : null;
98 $CountOffset = isset($Format["CountOffset"]) ? $Format["CountOffset"] : 0;
99 if ($Labels != null && !is_array($Labels)) {
100 $Label = $Labels;
101 $Labels = [$Label];
102 }
103 $X0 = $this->pChartObject->GraphAreaX1;
104 $XSize = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) / ($this->GridSizeX + 1);
105 $Settings = ["Angle" => $Angle, "R" => $R, "G" => $G, "B" => $B, "Alpha" => $Alpha];
106 if ($Position == LABEL_POSITION_TOP) {
107 $YPos = $this->pChartObject->GraphAreaY1 - $Padding;
108 if ($Angle == 0) {
109 $Settings["Align"] = TEXT_ALIGN_BOTTOMMIDDLE;
110 }
111 if ($Angle != 0) {
112 $Settings["Align"] = TEXT_ALIGN_MIDDLELEFT;
113 }
114 } elseif ($Position == LABEL_POSITION_BOTTOM) {
115 $YPos = $this->pChartObject->GraphAreaY2 + $Padding;
116 if ($Angle == 0) {
117 $Settings["Align"] = TEXT_ALIGN_TOPMIDDLE;
118 }
119 if ($Angle != 0) {
120 $Settings["Align"] = TEXT_ALIGN_MIDDLERIGHT;
121 }
122 } else {
123 return -1;
124 }
125 for ($X = 0; $X <= $this->GridSizeX; $X++) {
126 $XPos = floor($X0 + $X * $XSize + $XSize / 2);
127 if ($Labels == null || !isset($Labels[$X])) {
128 $Value = $X + $CountOffset;
129 } else {
130 $Value = $Labels[$X];
131 }
132 $this->pChartObject->drawText($XPos, $YPos, $Value, $Settings);
133 }
134 }
135 /**
136 * Write the Y labels
137 * @param array $Format
138 * @return type
139 */
140 public function writeYLabels(array $Format = [])
141 {
142 $R = isset($Format["R"]) ? $Format["R"] : $this->pChartObject->FontColorR;
143 $G = isset($Format["G"]) ? $Format["G"] : $this->pChartObject->FontColorG;
144 $B = isset($Format["B"]) ? $Format["B"] : $this->pChartObject->FontColorB;
145 $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : $this->pChartObject->FontColorA;
146 $Angle = isset($Format["Angle"]) ? $Format["Angle"] : 0;
147 $Padding = isset($Format["Padding"]) ? $Format["Padding"] : 5;
148 $Position = isset($Format["Position"]) ? $Format["Position"] : LABEL_POSITION_LEFT;
149 $Labels = isset($Format["Labels"]) ? $Format["Labels"] : null;
150 $CountOffset = isset($Format["CountOffset"]) ? $Format["CountOffset"] : 0;
151 if ($Labels != null && !is_array($Labels)) {
152 $Label = $Labels;
153 $Labels = [$Label];
154 }
155 $Y0 = $this->pChartObject->GraphAreaY1;
156 $YSize = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) / ($this->GridSizeY + 1);
157 $Settings = ["Angle" => $Angle, "R" => $R, "G" => $G, "B" => $B, "Alpha" => $Alpha];
158 if ($Position == LABEL_POSITION_LEFT) {
159 $XPos = $this->pChartObject->GraphAreaX1 - $Padding;
160 $Settings["Align"] = TEXT_ALIGN_MIDDLERIGHT;
161 } elseif ($Position == LABEL_POSITION_RIGHT) {
162 $XPos = $this->pChartObject->GraphAreaX2 + $Padding;
163 $Settings["Align"] = TEXT_ALIGN_MIDDLELEFT;
164 } else {
165 return -1;
166 }
167 for ($Y = 0; $Y <= $this->GridSizeY; $Y++) {
168 $YPos = floor($Y0 + $Y * $YSize + $YSize / 2);
169 if ($Labels == null || !isset($Labels[$Y])) {
170 $Value = $Y + $CountOffset;
171 } else {
172 $Value = $Labels[$Y];
173 }
174 $this->pChartObject->drawText($XPos, $YPos, $Value, $Settings);
175 }
176 }
177 /**
178 * Draw the area arround the specified Threshold
179 * @param int|float $Threshold
180 * @param array $Format
181 */
182 public function drawContour($Threshold, array $Format = [])
183 {
184 $R = isset($Format["R"]) ? $Format["R"] : 0;
185 $G = isset($Format["G"]) ? $Format["G"] : 0;
186 $B = isset($Format["B"]) ? $Format["B"] : 0;
187 $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
188 $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : 3;
189 $Padding = isset($Format["Padding"]) ? $Format["Padding"] : 0;
190 $X0 = $this->pChartObject->GraphAreaX1;
191 $Y0 = $this->pChartObject->GraphAreaY1;
192 $XSize = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) / ($this->GridSizeX + 1);
193 $YSize = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) / ($this->GridSizeY + 1);
194 $Color = ["R" => $R, "G" => $G, "B" => $B, "Alpha" => $Alpha, "Ticks" => $Ticks];
195 for ($X = 0; $X <= $this->GridSizeX; $X++) {
196 for ($Y = 0; $Y <= $this->GridSizeY; $Y++) {
197 $Value = $this->Points[$X][$Y];
198 if ($Value != UNKNOWN && $Value != IGNORED && $Value >= $Threshold) {
199 $X1 = floor($X0 + $X * $XSize) + $Padding;
200 $Y1 = floor($Y0 + $Y * $YSize) + $Padding;
201 $X2 = floor($X0 + $X * $XSize + $XSize);
202 $Y2 = floor($Y0 + $Y * $YSize + $YSize);
203 if ($X > 0 && $this->Points[$X - 1][$Y] != UNKNOWN && $this->Points[$X - 1][$Y] != IGNORED && $this->Points[$X - 1][$Y] < $Threshold) {
204 $this->pChartObject->drawLine($X1, $Y1, $X1, $Y2, $Color);
205 }
206 if ($Y > 0 && $this->Points[$X][$Y - 1] != UNKNOWN && $this->Points[$X][$Y - 1] != IGNORED && $this->Points[$X][$Y - 1] < $Threshold) {
207 $this->pChartObject->drawLine($X1, $Y1, $X2, $Y1, $Color);
208 }
209 if ($X < $this->GridSizeX && $this->Points[$X + 1][$Y] != UNKNOWN && $this->Points[$X + 1][$Y] != IGNORED && $this->Points[$X + 1][$Y] < $Threshold) {
210 $this->pChartObject->drawLine($X2, $Y1, $X2, $Y2, $Color);
211 }
212 if ($Y < $this->GridSizeY && $this->Points[$X][$Y + 1] != UNKNOWN && $this->Points[$X][$Y + 1] != IGNORED && $this->Points[$X][$Y + 1] < $Threshold) {
213 $this->pChartObject->drawLine($X1, $Y2, $X2, $Y2, $Color);
214 }
215 }
216 }
217 }
218 }
219 /**
220 * Draw the surface chart
221 * @param array $Format
222 */
223 public function drawSurface(array $Format = [])
224 {
225 $Palette = isset($Format["Palette"]) ? $Format["Palette"] : null;
226 $ShadeR1 = isset($Format["ShadeR1"]) ? $Format["ShadeR1"] : 77;
227 $ShadeG1 = isset($Format["ShadeG1"]) ? $Format["ShadeG1"] : 205;
228 $ShadeB1 = isset($Format["ShadeB1"]) ? $Format["ShadeB1"] : 21;
229 $ShadeA1 = isset($Format["ShadeA1"]) ? $Format["ShadeA1"] : 40;
230 $ShadeR2 = isset($Format["ShadeR2"]) ? $Format["ShadeR2"] : 227;
231 $ShadeG2 = isset($Format["ShadeG2"]) ? $Format["ShadeG2"] : 135;
232 $ShadeB2 = isset($Format["ShadeB2"]) ? $Format["ShadeB2"] : 61;
233 $ShadeA2 = isset($Format["ShadeA2"]) ? $Format["ShadeA2"] : 100;
234 $Border = isset($Format["Border"]) ? $Format["Border"] : \false;
235 $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : 0;
236 $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : 0;
237 $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : 0;
238 $Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : -1;
239 $Padding = isset($Format["Padding"]) ? $Format["Padding"] : 1;
240 $X0 = $this->pChartObject->GraphAreaX1;
241 $Y0 = $this->pChartObject->GraphAreaY1;
242 $XSize = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) / ($this->GridSizeX + 1);
243 $YSize = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) / ($this->GridSizeY + 1);
244 for ($X = 0; $X <= $this->GridSizeX; $X++) {
245 for ($Y = 0; $Y <= $this->GridSizeY; $Y++) {
246 $Value = $this->Points[$X][$Y];
247 if ($Value != UNKNOWN && $Value != IGNORED) {
248 $X1 = floor($X0 + $X * $XSize) + $Padding;
249 $Y1 = floor($Y0 + $Y * $YSize) + $Padding;
250 $X2 = floor($X0 + $X * $XSize + $XSize);
251 $Y2 = floor($Y0 + $Y * $YSize + $YSize);
252 if ($Palette != null) {
253 if (isset($Palette[$Value]) && isset($Palette[$Value]["R"])) {
254 $R = $Palette[$Value]["R"];
255 } else {
256 $R = 0;
257 }
258 if (isset($Palette[$Value]) && isset($Palette[$Value]["G"])) {
259 $G = $Palette[$Value]["G"];
260 } else {
261 $G = 0;
262 }
263 if (isset($Palette[$Value]) && isset($Palette[$Value]["B"])) {
264 $B = $Palette[$Value]["B"];
265 } else {
266 $B = 0;
267 }
268 if (isset($Palette[$Value]) && isset($Palette[$Value]["Alpha"])) {
269 $Alpha = $Palette[$Value]["Alpha"];
270 } else {
271 $Alpha = 1000;
272 }
273 } else {
274 $R = ($ShadeR2 - $ShadeR1) / 100 * $Value + $ShadeR1;
275 $G = ($ShadeG2 - $ShadeG1) / 100 * $Value + $ShadeG1;
276 $B = ($ShadeB2 - $ShadeB1) / 100 * $Value + $ShadeB1;
277 $Alpha = ($ShadeA2 - $ShadeA1) / 100 * $Value + $ShadeA1;
278 }
279 $Settings = ["R" => $R, "G" => $G, "B" => $B, "Alpha" => $Alpha];
280 if ($Border) {
281 $Settings["BorderR"] = $BorderR;
282 $Settings["BorderG"] = $BorderG;
283 $Settings["BorderB"] = $BorderB;
284 }
285 if ($Surrounding != -1) {
286 $Settings["BorderR"] = $R + $Surrounding;
287 $Settings["BorderG"] = $G + $Surrounding;
288 $Settings["BorderB"] = $B + $Surrounding;
289 }
290 $this->pChartObject->drawFilledRectangle($X1, $Y1, $X2 - 1, $Y2 - 1, $Settings);
291 }
292 }
293 }
294 }
295 /**
296 * Compute the missing points
297 */
298 public function computeMissing()
299 {
300 $Missing = [];
301 for ($X = 0; $X <= $this->GridSizeX; $X++) {
302 for ($Y = 0; $Y <= $this->GridSizeY; $Y++) {
303 if ($this->Points[$X][$Y] == UNKNOWN) {
304 $Missing[] = $X . "," . $Y;
305 }
306 }
307 }
308 shuffle($Missing);
309 foreach ($Missing as $Pos) {
310 $Pos = preg_split("/,/", $Pos);
311 $X = $Pos[0];
312 $Y = $Pos[1];
313 if ($this->Points[$X][$Y] == UNKNOWN) {
314 $NearestNeighbor = $this->getNearestNeighbor($X, $Y);
315 $Value = 0;
316 $Points = 0;
317 for ($Xi = $X - $NearestNeighbor; $Xi <= $X + $NearestNeighbor; $Xi++) {
318 for ($Yi = $Y - $NearestNeighbor; $Yi <= $Y + $NearestNeighbor; $Yi++) {
319 if ($Xi >= 0 && $Yi >= 0 && $Xi <= $this->GridSizeX && $Yi <= $this->GridSizeY && $this->Points[$Xi][$Yi] != UNKNOWN && $this->Points[$Xi][$Yi] != IGNORED) {
320 $Value = $Value + $this->Points[$Xi][$Yi];
321 $Points++;
322 }
323 }
324 }
325 if ($Points != 0) {
326 $this->Points[$X][$Y] = $Value / $Points;
327 }
328 }
329 }
330 }
331 /**
332 * Return the nearest Neighbor distance of a point
333 * @param int $Xp
334 * @param int $Yp
335 * @return int
336 */
337 public function getNearestNeighbor($Xp, $Yp)
338 {
339 $Nearest = UNKNOWN;
340 for ($X = 0; $X <= $this->GridSizeX; $X++) {
341 for ($Y = 0; $Y <= $this->GridSizeY; $Y++) {
342 if ($this->Points[$X][$Y] != UNKNOWN && $this->Points[$X][$Y] != IGNORED) {
343 $DistanceX = max($Xp, $X) - min($Xp, $X);
344 $DistanceY = max($Yp, $Y) - min($Yp, $Y);
345 $Distance = max($DistanceX, $DistanceY);
346 if ($Distance < $Nearest || $Nearest == UNKNOWN) {
347 $Nearest = $Distance;
348 }
349 }
350 }
351 }
352 return $Nearest;
353 }
354 }
355