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 / Bubble.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
Bubble.php
325 lines
1 <?php
2
3 namespace CpChart\Chart;
4
5 use CpChart\Data;
6 use CpChart\Image;
7 /**
8 * Bubble - class to draw bubble charts
9 *
10 * Version : 2.1.4
11 * Made by : Jean-Damien POGOLOTTI
12 * Last Update : 19/01/2014
13 *
14 * This file can be distributed under the license you can find at :
15 *
16 * http://www.pchart.net/license
17 *
18 * You can find the whole class documentation on the pChart web site.
19 */
20 class Bubble
21 {
22 /**
23 * @var Image
24 */
25 public $pChartObject;
26 /**
27 * @var Data
28 */
29 public $pDataObject;
30 /**
31 * @param Image $pChartObject
32 * @param Data $pDataObject
33 */
34 public function __construct(Image $pChartObject, Data $pDataObject)
35 {
36 $this->pChartObject = $pChartObject;
37 $this->pDataObject = $pDataObject;
38 }
39 /**
40 * Prepare the scale
41 *
42 * @param mixed $DataSeries
43 * @param mixed $WeightSeries
44 */
45 public function bubbleScale($DataSeries, $WeightSeries)
46 {
47 if (!is_array($DataSeries)) {
48 $DataSeries = [$DataSeries];
49 }
50 if (!is_array($WeightSeries)) {
51 $WeightSeries = [$WeightSeries];
52 }
53 /* Parse each data series to find the new min & max boundaries to scale */
54 $NewPositiveSerie = [];
55 $NewNegativeSerie = [];
56 $MaxValues = 0;
57 $LastPositive = 0;
58 $LastNegative = 0;
59 foreach ($DataSeries as $Key => $SerieName) {
60 $SerieWeightName = $WeightSeries[$Key];
61 $this->pDataObject->setSerieDrawable($SerieWeightName, \false);
62 $serieData = $this->pDataObject->Data["Series"][$SerieName]["Data"];
63 if (count($serieData) > $MaxValues) {
64 $MaxValues = count($serieData);
65 }
66 foreach ($serieData as $Key => $Value) {
67 if ($Value >= 0) {
68 $BubbleBounds = $Value + $this->pDataObject->Data["Series"][$SerieWeightName]["Data"][$Key];
69 if (!isset($NewPositiveSerie[$Key])) {
70 $NewPositiveSerie[$Key] = $BubbleBounds;
71 } elseif ($NewPositiveSerie[$Key] < $BubbleBounds) {
72 $NewPositiveSerie[$Key] = $BubbleBounds;
73 }
74 $LastPositive = $BubbleBounds;
75 } else {
76 $BubbleBounds = $Value - $this->pDataObject->Data["Series"][$SerieWeightName]["Data"][$Key];
77 if (!isset($NewNegativeSerie[$Key])) {
78 $NewNegativeSerie[$Key] = $BubbleBounds;
79 } elseif ($NewNegativeSerie[$Key] > $BubbleBounds) {
80 $NewNegativeSerie[$Key] = $BubbleBounds;
81 }
82 $LastNegative = $BubbleBounds;
83 }
84 }
85 }
86 /* Check for missing values and all the fake positive serie */
87 if (count($NewPositiveSerie)) {
88 for ($i = 0; $i < $MaxValues; $i++) {
89 if (!isset($NewPositiveSerie[$i])) {
90 $NewPositiveSerie[$i] = $LastPositive;
91 }
92 }
93 $this->pDataObject->addPoints($NewPositiveSerie, "BubbleFakePositiveSerie");
94 }
95 /* Check for missing values and all the fake negative serie */
96 if (count($NewNegativeSerie)) {
97 for ($i = 0; $i < $MaxValues; $i++) {
98 if (!isset($NewNegativeSerie[$i])) {
99 $NewNegativeSerie[$i] = $LastNegative;
100 }
101 }
102 $this->pDataObject->addPoints($NewNegativeSerie, "BubbleFakeNegativeSerie");
103 }
104 }
105 public function resetSeriesColors()
106 {
107 $Data = $this->pDataObject->getData();
108 $Palette = $this->pDataObject->getPalette();
109 $ID = 0;
110 foreach ($Data["Series"] as $SerieName => $SeriesParameters) {
111 if ($SeriesParameters["isDrawable"]) {
112 $this->pDataObject->Data["Series"][$SerieName]["Color"]["R"] = $Palette[$ID]["R"];
113 $this->pDataObject->Data["Series"][$SerieName]["Color"]["G"] = $Palette[$ID]["G"];
114 $this->pDataObject->Data["Series"][$SerieName]["Color"]["B"] = $Palette[$ID]["B"];
115 $this->pDataObject->Data["Series"][$SerieName]["Color"]["Alpha"] = $Palette[$ID]["Alpha"];
116 $ID++;
117 }
118 }
119 }
120 /* Prepare the scale */
121 public function drawBubbleChart($DataSeries, $WeightSeries, $Format = "")
122 {
123 $ForceAlpha = isset($Format["ForceAlpha"]) ? $Format["ForceAlpha"] : VOID;
124 $DrawBorder = isset($Format["DrawBorder"]) ? $Format["DrawBorder"] : \true;
125 $BorderWidth = isset($Format["BorderWidth"]) ? $Format["BorderWidth"] : 1;
126 $Shape = isset($Format["Shape"]) ? $Format["Shape"] : BUBBLE_SHAPE_ROUND;
127 $Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : null;
128 $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : 0;
129 $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : 0;
130 $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : 0;
131 $BorderAlpha = isset($Format["BorderAlpha"]) ? $Format["BorderAlpha"] : 30;
132 $RecordImageMap = isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : \false;
133 if (!is_array($DataSeries)) {
134 $DataSeries = [$DataSeries];
135 }
136 if (!is_array($WeightSeries)) {
137 $WeightSeries = [$WeightSeries];
138 }
139 $Data = $this->pDataObject->getData();
140 $Palette = $this->pDataObject->getPalette();
141 if (isset($Data["Series"]["BubbleFakePositiveSerie"])) {
142 $this->pDataObject->setSerieDrawable("BubbleFakePositiveSerie", \false);
143 }
144 if (isset($Data["Series"]["BubbleFakeNegativeSerie"])) {
145 $this->pDataObject->setSerieDrawable("BubbleFakeNegativeSerie", \false);
146 }
147 $this->resetSeriesColors();
148 list($XMargin, $XDivs) = $this->pChartObject->scaleGetXSettings();
149 foreach ($DataSeries as $Key => $SerieName) {
150 $AxisID = $Data["Series"][$SerieName]["Axis"];
151 $Mode = $Data["Axis"][$AxisID]["Display"];
152 $Format = $Data["Axis"][$AxisID]["Format"];
153 $Unit = $Data["Axis"][$AxisID]["Unit"];
154 if (isset($Data["Series"][$SerieName]["Description"])) {
155 $SerieDescription = $Data["Series"][$SerieName]["Description"];
156 } else {
157 $SerieDescription = $SerieName;
158 }
159 $XStep = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1 - $XMargin * 2) / $XDivs;
160 $X = $this->pChartObject->GraphAreaX1 + $XMargin;
161 $Y = $this->pChartObject->GraphAreaY1 + $XMargin;
162 $Color = ["R" => $Palette[$Key]["R"], "G" => $Palette[$Key]["G"], "B" => $Palette[$Key]["B"], "Alpha" => $Palette[$Key]["Alpha"]];
163 if ($ForceAlpha != VOID) {
164 $Color["Alpha"] = $ForceAlpha;
165 }
166 if ($DrawBorder) {
167 if ($BorderWidth != 1) {
168 if ($Surrounding != null) {
169 $BorderR = $Palette[$Key]["R"] + $Surrounding;
170 $BorderG = $Palette[$Key]["G"] + $Surrounding;
171 $BorderB = $Palette[$Key]["B"] + $Surrounding;
172 }
173 if ($ForceAlpha != VOID) {
174 $BorderAlpha = $ForceAlpha / 2;
175 }
176 $BorderColor = ["R" => $BorderR, "G" => $BorderG, "B" => $BorderB, "Alpha" => $BorderAlpha];
177 } else {
178 $Color["BorderAlpha"] = $BorderAlpha;
179 if ($Surrounding != null) {
180 $Color["BorderR"] = $Palette[$Key]["R"] + $Surrounding;
181 $Color["BorderG"] = $Palette[$Key]["G"] + $Surrounding;
182 $Color["BorderB"] = $Palette[$Key]["B"] + $Surrounding;
183 } else {
184 $Color["BorderR"] = $BorderR;
185 $Color["BorderG"] = $BorderG;
186 $Color["BorderB"] = $BorderB;
187 }
188 if ($ForceAlpha != VOID) {
189 $Color["BorderAlpha"] = $ForceAlpha / 2;
190 }
191 }
192 }
193 foreach ($Data["Series"][$SerieName]["Data"] as $iKey => $Point) {
194 $Weight = $Point + $Data["Series"][$WeightSeries[$Key]]["Data"][$iKey];
195 $PosArray = $this->pChartObject->scaleComputeY($Point, ["AxisID" => $AxisID]);
196 $WeightArray = $this->pChartObject->scaleComputeY($Weight, ["AxisID" => $AxisID]);
197 if ($Data["Orientation"] == SCALE_POS_LEFTRIGHT) {
198 if ($XDivs == 0) {
199 $XStep = 0;
200 } else {
201 $XStep = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1 - $XMargin * 2) / $XDivs;
202 }
203 $Y = floor($PosArray);
204 $CircleRadius = floor(abs($PosArray - $WeightArray) / 2);
205 if ($Shape == BUBBLE_SHAPE_SQUARE) {
206 if ($RecordImageMap) {
207 $this->pChartObject->addToImageMap("RECT", floor($X - $CircleRadius) . "," . floor($Y - $CircleRadius) . "," . floor($X + $CircleRadius) . "," . floor($Y + $CircleRadius), $this->pChartObject->toHTMLColor($Palette[$Key]["R"], $Palette[$Key]["G"], $Palette[$Key]["B"]), $SerieDescription, $Data["Series"][$WeightSeries[$Key]]["Data"][$iKey]);
208 }
209 if ($BorderWidth != 1) {
210 $this->pChartObject->drawFilledRectangle($X - $CircleRadius - $BorderWidth, $Y - $CircleRadius - $BorderWidth, $X + $CircleRadius + $BorderWidth, $Y + $CircleRadius + $BorderWidth, $BorderColor);
211 $this->pChartObject->drawFilledRectangle($X - $CircleRadius, $Y - $CircleRadius, $X + $CircleRadius, $Y + $CircleRadius, $Color);
212 } else {
213 $this->pChartObject->drawFilledRectangle($X - $CircleRadius, $Y - $CircleRadius, $X + $CircleRadius, $Y + $CircleRadius, $Color);
214 }
215 } elseif ($Shape == BUBBLE_SHAPE_ROUND) {
216 if ($RecordImageMap) {
217 $this->pChartObject->addToImageMap("CIRCLE", floor($X) . "," . floor($Y) . "," . floor($CircleRadius), $this->pChartObject->toHTMLColor($Palette[$Key]["R"], $Palette[$Key]["G"], $Palette[$Key]["B"]), $SerieDescription, $Data["Series"][$WeightSeries[$Key]]["Data"][$iKey]);
218 }
219 if ($BorderWidth != 1) {
220 $this->pChartObject->drawFilledCircle($X, $Y, $CircleRadius + $BorderWidth, $BorderColor);
221 $this->pChartObject->drawFilledCircle($X, $Y, $CircleRadius, $Color);
222 } else {
223 $this->pChartObject->drawFilledCircle($X, $Y, $CircleRadius, $Color);
224 }
225 }
226 $X = $X + $XStep;
227 } elseif ($Data["Orientation"] == SCALE_POS_TOPBOTTOM) {
228 if ($XDivs == 0) {
229 $XStep = 0;
230 } else {
231 $XStep = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1 - $XMargin * 2) / $XDivs;
232 }
233 $X = floor($PosArray);
234 $CircleRadius = floor(abs($PosArray - $WeightArray) / 2);
235 if ($Shape == BUBBLE_SHAPE_SQUARE) {
236 if ($RecordImageMap) {
237 $this->pChartObject->addToImageMap("RECT", floor($X - $CircleRadius) . "," . floor($Y - $CircleRadius) . "," . floor($X + $CircleRadius) . "," . floor($Y + $CircleRadius), $this->pChartObject->toHTMLColor($Palette[$Key]["R"], $Palette[$Key]["G"], $Palette[$Key]["B"]), $SerieDescription, $Data["Series"][$WeightSeries[$Key]]["Data"][$iKey]);
238 }
239 if ($BorderWidth != 1) {
240 $this->pChartObject->drawFilledRectangle($X - $CircleRadius - $BorderWidth, $Y - $CircleRadius - $BorderWidth, $X + $CircleRadius + $BorderWidth, $Y + $CircleRadius + $BorderWidth, $BorderColor);
241 $this->pChartObject->drawFilledRectangle($X - $CircleRadius, $Y - $CircleRadius, $X + $CircleRadius, $Y + $CircleRadius, $Color);
242 } else {
243 $this->pChartObject->drawFilledRectangle($X - $CircleRadius, $Y - $CircleRadius, $X + $CircleRadius, $Y + $CircleRadius, $Color);
244 }
245 } elseif ($Shape == BUBBLE_SHAPE_ROUND) {
246 if ($RecordImageMap) {
247 $this->pChartObject->addToImageMap("CIRCLE", floor($X) . "," . floor($Y) . "," . floor($CircleRadius), $this->pChartObject->toHTMLColor($Palette[$Key]["R"], $Palette[$Key]["G"], $Palette[$Key]["B"]), $SerieDescription, $Data["Series"][$WeightSeries[$Key]]["Data"][$iKey]);
248 }
249 if ($BorderWidth != 1) {
250 $this->pChartObject->drawFilledCircle($X, $Y, $CircleRadius + $BorderWidth, $BorderColor);
251 $this->pChartObject->drawFilledCircle($X, $Y, $CircleRadius, $Color);
252 } else {
253 $this->pChartObject->drawFilledCircle($X, $Y, $CircleRadius, $Color);
254 }
255 }
256 $Y = $Y + $XStep;
257 }
258 }
259 }
260 }
261 public function writeBubbleLabel($SerieName, $SerieWeightName, $Points, $Format = "")
262 {
263 $DrawPoint = isset($Format["DrawPoint"]) ? $Format["DrawPoint"] : LABEL_POINT_BOX;
264 if (!is_array($Points)) {
265 $Point = $Points;
266 $Points = [];
267 $Points[] = $Point;
268 }
269 $Data = $this->pDataObject->getData();
270 if (!isset($Data["Series"][$SerieName]) || !isset($Data["Series"][$SerieWeightName])) {
271 return 0;
272 }
273 list($XMargin, $XDivs) = $this->pChartObject->scaleGetXSettings();
274 $AxisID = $Data["Series"][$SerieName]["Axis"];
275 $AxisMode = $Data["Axis"][$AxisID]["Display"];
276 $AxisFormat = $Data["Axis"][$AxisID]["Format"];
277 $AxisUnit = $Data["Axis"][$AxisID]["Unit"];
278 $XStep = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1 - $XMargin * 2) / $XDivs;
279 $X = $InitialX = $this->pChartObject->GraphAreaX1 + $XMargin;
280 $Y = $InitialY = $this->pChartObject->GraphAreaY1 + $XMargin;
281 $Color = ["R" => $Data["Series"][$SerieName]["Color"]["R"], "G" => $Data["Series"][$SerieName]["Color"]["G"], "B" => $Data["Series"][$SerieName]["Color"]["B"], "Alpha" => $Data["Series"][$SerieName]["Color"]["Alpha"]];
282 foreach ($Points as $Key => $Point) {
283 $Value = $Data["Series"][$SerieName]["Data"][$Point];
284 $PosArray = $this->pChartObject->scaleComputeY($Value, ["AxisID" => $AxisID]);
285 if (isset($Data["Abscissa"]) && isset($Data["Series"][$Data["Abscissa"]]["Data"][$Point])) {
286 $Abscissa = $Data["Series"][$Data["Abscissa"]]["Data"][$Point] . " : ";
287 } else {
288 $Abscissa = "";
289 }
290 $Value = $this->pChartObject->scaleFormat($Value, $AxisMode, $AxisFormat, $AxisUnit);
291 $Weight = $Data["Series"][$SerieWeightName]["Data"][$Point];
292 $Caption = $Abscissa . $Value . " / " . $Weight;
293 if (isset($Data["Series"][$SerieName]["Description"])) {
294 $Description = $Data["Series"][$SerieName]["Description"];
295 } else {
296 $Description = "No description";
297 }
298 $Series = [["Format" => $Color, "Caption" => $Caption]];
299 if ($Data["Orientation"] == SCALE_POS_LEFTRIGHT) {
300 if ($XDivs == 0) {
301 $XStep = 0;
302 } else {
303 $XStep = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1 - $XMargin * 2) / $XDivs;
304 }
305 $X = floor($InitialX + $Point * $XStep);
306 $Y = floor($PosArray);
307 } else {
308 if ($XDivs == 0) {
309 $YStep = 0;
310 } else {
311 $YStep = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1 - $XMargin * 2) / $XDivs;
312 }
313 $X = floor($PosArray);
314 $Y = floor($InitialY + $Point * $YStep);
315 }
316 if ($DrawPoint == LABEL_POINT_CIRCLE) {
317 $this->pChartObject->drawFilledCircle($X, $Y, 3, ["R" => 255, "G" => 255, "B" => 255, "BorderR" => 0, "BorderG" => 0, "BorderB" => 0]);
318 } elseif ($DrawPoint == LABEL_POINT_BOX) {
319 $this->pChartObject->drawFilledRectangle($X - 2, $Y - 2, $X + 2, $Y + 2, ["R" => 255, "G" => 255, "B" => 255, "BorderR" => 0, "BorderG" => 0, "BorderB" => 0]);
320 }
321 $this->pChartObject->drawLabelBox($X, $Y - 3, $Description, $Series, $Format);
322 }
323 }
324 }
325