Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
/*
3
pScatter - class to draw scatter charts
4
 
5
Version     : 2.1.4
6
Made by     : Jean-Damien POGOLOTTI
7
Last Update : 19/01/2014
8
 
9
This file can be distributed under the license you can find at :
10
 
11
http://www.pchart.net/license
12
 
13
You can find the whole class documentation on the pChart web site.
14
*/
15
define("SCATTER_MISSING_X_SERIE", 190001);
16
define("SCATTER_MISSING_Y_SERIE", 190002);
17
 
18
/* pScatter class definition */
19
class pScatter
20
{
21
	var $pChartObject;
22
	var $pDataObject;
23
	/* Class creator */
24
	function __construct($pChartObject, $pDataObject)
25
	{
26
		$this->pChartObject = $pChartObject;
27
		$this->pDataObject = $pDataObject;
28
	}
29
 
30
	/* Prepare the scale */
31
	function drawScatterScale(array $Format = [])
32
	{
33
 
34
		/* Check if we have at least both one X and Y axis */
35
		$GotXAxis = FALSE;
36
		$GotYAxis = FALSE;
37
		foreach($this->pDataObject->Data["Axis"] as $AxisID => $AxisSettings) {
38
			($AxisSettings["Identity"] == AXIS_X) AND $GotXAxis = TRUE;
39
			($AxisSettings["Identity"] == AXIS_Y) AND $GotYAxis = TRUE;
40
		}
41
 
42
		if (!$GotXAxis) {
43
			return SCATTER_MISSING_X_SERIE;
44
		}
45
 
46
		if (!$GotYAxis) {
47
			return SCATTER_MISSING_Y_SERIE;
48
		}
49
 
50
		$Mode = SCALE_MODE_FLOATING;
51
		$Floating = FALSE;
52
		$XLabelsRotation = 90;
53
		$MinDivHeight = 20;
54
		$Factors = [1,2,5];
55
		$ManualScale = array("0" => ["Min" => - 100,"Max" => 100]);
56
		$XMargin = 0;
57
		$YMargin = 0;
58
		$ScaleSpacing = 15;
59
		$InnerTickWidth = 2;
60
		$OuterTickWidth = 2;
61
		$DrawXLines = ALL;
62
		$DrawYLines = ALL;
63
		$GridTicks = 4;
64
		$GridR = 255;
65
		$GridG = 255;
66
		$GridB = 255;
67
		$GridAlpha = 40;
68
		$AxisRo = isset($Format["AxisR"]) ? $Format["AxisR"] : 0;
69
		$AxisGo = isset($Format["AxisG"]) ? $Format["AxisG"] : 0;
70
		$AxisBo = isset($Format["AxisB"]) ? $Format["AxisB"] : 0;
71
		$AxisAlpha = 100;
72
		$TickRo = isset($Format["TickR"]) ? $Format["TickR"] : 0;
73
		$TickGo = isset($Format["TickG"]) ? $Format["TickG"] : 0;
74
		$TickBo = isset($Format["TickB"]) ? $Format["TickB"] : 0;
75
		$TickAlpha = 100;
76
		$DrawSubTicks = FALSE;
77
		$InnerSubTickWidth = 0;
78
		$OuterSubTickWidth = 2;
79
		$SubTickR = 255;
80
		$SubTickG = 0;
81
		$SubTickB = 0;
82
		$SubTickAlpha = 100;
83
		$XReleasePercent = 1;
84
		$DrawArrows = FALSE;
85
		$ArrowSize = 8;
86
		$CycleBackground = FALSE;
87
		$BackgroundR1 = 255;
88
		$BackgroundG1 = 255;
89
		$BackgroundB1 = 255;
90
		$BackgroundAlpha1 = 10;
91
		$BackgroundR2 = 230;
92
		$BackgroundG2 = 230;
93
		$BackgroundB2 = 230;
94
		$BackgroundAlpha2 = 10;
95
 
96
		/* Override defaults */
97
		extract($Format);
98
 
99
		$BG1 = ["R" => $BackgroundR1,"G" => $BackgroundG1,"B" => $BackgroundB1,"Alpha" => $BackgroundAlpha1];
100
		$BG2 = ["R" => $BackgroundR2,"G" => $BackgroundG2,"B" => $BackgroundB2,"Alpha" => $BackgroundAlpha2];
101
 
102
		/* Skip a NOTICE event in case of an empty array */
103
		($DrawYLines == NONE) AND $DrawYLines = ["zarma" => "31"];
104
 
105
		$Data = $this->pDataObject->getData();
106
		foreach($Data["Axis"] as $AxisID => $AxisSettings) {
107
			if ($AxisSettings["Identity"] == AXIS_X) {
108
				$Width = $this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1 - $XMargin * 2;
109
			} else {
110
				$Width = $this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1 - $YMargin * 2;
111
			}
112
 
113
			$AxisMin = ABSOLUTE_MAX;
114
			$AxisMax = OUT_OF_SIGHT;
115
			if ($Mode == SCALE_MODE_FLOATING) {
116
				foreach($Data["Series"] as $SerieID => $SerieParameter) {
117
					if ($SerieParameter["Axis"] == $AxisID && $Data["Series"][$SerieID]["isDrawable"]) {
118
						$AxisMax = max($AxisMax, $Data["Series"][$SerieID]["Max"]);
119
						$AxisMin = min($AxisMin, $Data["Series"][$SerieID]["Min"]);
120
					}
121
				}
122
 
123
				$AutoMargin = (($AxisMax - $AxisMin) / 100) * $XReleasePercent;
124
				$Data["Axis"][$AxisID]["Min"] = $AxisMin - $AutoMargin;
125
				$Data["Axis"][$AxisID]["Max"] = $AxisMax + $AutoMargin;
126
			} elseif ($Mode == SCALE_MODE_MANUAL) {
127
				if (isset($ManualScale[$AxisID]["Min"]) && isset($ManualScale[$AxisID]["Max"])) {
128
					$Data["Axis"][$AxisID]["Min"] = $ManualScale[$AxisID]["Min"];
129
					$Data["Axis"][$AxisID]["Max"] = $ManualScale[$AxisID]["Max"];
130
				} else {
131
					echo "Manual scale boundaries not set.";
132
					exit();
133
				}
134
			}
135
 
136
			/* Full manual scale */
137
			if (isset($ManualScale[$AxisID]["Rows"]) && isset($ManualScale[$AxisID]["RowHeight"])) {
138
				$Scale = ["Rows" => $ManualScale[$AxisID]["Rows"],"RowHeight" => $ManualScale[$AxisID]["RowHeight"],"XMin" => $ManualScale[$AxisID]["Min"],"XMax" => $ManualScale[$AxisID]["Max"]];
139
			} else {
140
				$MaxDivs = floor($Width / $MinDivHeight);
141
				$Scale = $this->pChartObject->computeScale($Data["Axis"][$AxisID]["Min"], $Data["Axis"][$AxisID]["Max"], $MaxDivs, $Factors, $AxisID);
142
			}
143
 
144
			$Data["Axis"][$AxisID]["Margin"] = $AxisSettings["Identity"] == AXIS_X ? $XMargin : $YMargin;
145
			$Data["Axis"][$AxisID]["ScaleMin"] = $Scale["XMin"];
146
			$Data["Axis"][$AxisID]["ScaleMax"] = $Scale["XMax"];
147
			$Data["Axis"][$AxisID]["Rows"] = $Scale["Rows"];
148
			$Data["Axis"][$AxisID]["RowHeight"] = $Scale["RowHeight"];
149
			(isset($Scale["Format"])) AND $Data["Axis"][$AxisID]["Format"] = $Scale["Format"];
150
			(!isset($Data["Axis"][$AxisID]["Display"])) AND $Data["Axis"][$AxisID]["Display"] = NULL;
151
			(!isset($Data["Axis"][$AxisID]["Format"])) AND $Data["Axis"][$AxisID]["Format"] = NULL;
152
			(!isset($Data["Axis"][$AxisID]["Unit"])) AND $Data["Axis"][$AxisID]["Unit"] = NULL;
153
		}
154
 
155
		/* Set the original boundaries */
156
		$AxisPos = [
157
			"L" => $this->pChartObject->GraphAreaX1,
158
			"R" => $this->pChartObject->GraphAreaX2,
159
			"T" => $this->pChartObject->GraphAreaY1,
160
			"B" => $this->pChartObject->GraphAreaY2
161
		];
162
 
163
		foreach($Data["Axis"] as $AxisID => $AxisSettings) {
164
			if (isset($AxisSettings["Color"])) {
165
				$AxisR = $AxisSettings["Color"]["R"];
166
				$AxisG = $AxisSettings["Color"]["G"];
167
				$AxisB = $AxisSettings["Color"]["B"];
168
				$TickR = $AxisSettings["Color"]["R"];
169
				$TickG = $AxisSettings["Color"]["G"];
170
				$TickB = $AxisSettings["Color"]["B"];
171
				$this->pChartObject->setFontProperties(["R" => $AxisR,"G" => $AxisG,"B" => $AxisB]);
172
			} else {
173
				$AxisR = $AxisRo;
174
				$AxisG = $AxisGo;
175
				$AxisB = $AxisBo;
176
				$TickR = $TickRo;
177
				$TickG = $TickGo;
178
				$TickB = $TickBo;
179
				/* Get the default font color */
180
				$this->pChartObject->setFontProperties(["R" => $this->pChartObject->FontColorR,"G" => $this->pChartObject->FontColorG,"B" => $this->pChartObject->FontColorB]);
181
			}
182
 
183
			$LastValue = "w00t";
184
			$ID = 1;
185
			if ($AxisSettings["Identity"] == AXIS_X) {
186
				if ($AxisSettings["Position"] == AXIS_POSITION_BOTTOM) {
187
					if ($XLabelsRotation == 0) {
188
						$LabelAlign = TEXT_ALIGN_TOPMIDDLE;
189
						$LabelOffset = 2;
190
					}
191
 
192
					if ($XLabelsRotation > 0 && $XLabelsRotation < 190) {
193
						$LabelAlign = TEXT_ALIGN_MIDDLERIGHT;
194
						$LabelOffset = 5;
195
					}
196
 
197
					if ($XLabelsRotation == 180) {
198
						$LabelAlign = TEXT_ALIGN_BOTTOMMIDDLE;
199
						$LabelOffset = 5;
200
					}
201
 
202
					if ($XLabelsRotation > 180 && $XLabelsRotation < 360) {
203
						$LabelAlign = TEXT_ALIGN_MIDDLELEFT;
204
						$LabelOffset = 2;
205
					}
206
 
207
					if ($Floating) {
208
						$FloatingOffset = $YMargin;
209
						$this->pChartObject->drawLine($this->pChartObject->GraphAreaX1 + $AxisSettings["Margin"], $AxisPos["B"], $this->pChartObject->GraphAreaX2 - $AxisSettings["Margin"], $AxisPos["B"], ["R" => $AxisR,"G" => $AxisG,"B" => $AxisB,"Alpha" => $AxisAlpha]);
210
					} else {
211
						$FloatingOffset = 0;
212
						$this->pChartObject->drawLine($this->pChartObject->GraphAreaX1, $AxisPos["B"], $this->pChartObject->GraphAreaX2, $AxisPos["B"], ["R" => $AxisR,"G" => $AxisG,"B" => $AxisB,"Alpha" => $AxisAlpha]);
213
					}
214
 
215
					if ($DrawArrows) {
216
						$this->pChartObject->drawArrow($this->pChartObject->GraphAreaX2 - $AxisSettings["Margin"], $AxisPos["B"], $this->pChartObject->GraphAreaX2 + ($ArrowSize * 2) , $AxisPos["B"], ["FillR" => $AxisR,"FillG" => $AxisG,"FillB" => $AxisB,"Size" => $ArrowSize]);
217
					}
218
 
219
					$Width = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) - $AxisSettings["Margin"] * 2;
220
					$Step = $Width / $AxisSettings["Rows"];
221
					$SubTicksSize = $Step / 2;
222
					$MaxBottom = $AxisPos["B"];
223
					$LastX = NULL;
224
					for ($i = 0; $i <= $AxisSettings["Rows"]; $i++) {
225
						$XPos = $this->pChartObject->GraphAreaX1 + $AxisSettings["Margin"] + $Step * $i;
226
						$YPos = $AxisPos["B"];
227
						$Value = $this->pChartObject->scaleFormat($AxisSettings["ScaleMin"] + $AxisSettings["RowHeight"] * $i, $AxisSettings["Display"], $AxisSettings["Format"], $AxisSettings["Unit"]);
228
						$BGColor = ($i % 2 == 1) ? $BG1 : $BG2;
229
 
230
						if ($LastX != NULL && $CycleBackground && ($DrawXLines == ALL || in_array($AxisID, $DrawXLines))) {
231
							$this->pChartObject->drawFilledRectangle($LastX, $this->pChartObject->GraphAreaY1 + $FloatingOffset, $XPos, $this->pChartObject->GraphAreaY2 - $FloatingOffset, $BGColor);
232
						}
233
 
234
						if ($DrawXLines == ALL || in_array($AxisID, $DrawXLines)) {
235
							$this->pChartObject->drawLine($XPos, $this->pChartObject->GraphAreaY1 + $FloatingOffset, $XPos, $this->pChartObject->GraphAreaY2 - $FloatingOffset, ["R" => $GridR,"G" => $GridG,"B" => $GridB,"Alpha" => $GridAlpha,"Ticks" => $GridTicks]);
236
						}
237
 
238
						if ($DrawSubTicks && $i != $AxisSettings["Rows"]){
239
							$this->pChartObject->drawLine($XPos + $SubTicksSize, $YPos - $InnerSubTickWidth, $XPos + $SubTicksSize, $YPos + $OuterSubTickWidth, ["R" => $SubTickR,"G" => $SubTickG,"B" => $SubTickB,"Alpha" => $SubTickAlpha]);
240
						}
241
 
242
						$this->pChartObject->drawLine($XPos, $YPos - $InnerTickWidth, $XPos, $YPos + $OuterTickWidth, ["R" => $TickR,"G" => $TickG,"B" => $TickB,"Alpha" => $TickAlpha]);
243
						$Bounds = $this->pChartObject->drawText($XPos, $YPos + $OuterTickWidth + $LabelOffset, $Value, ["Angle" => $XLabelsRotation,"Align" => $LabelAlign]);
244
						$TxtBottom = $YPos + 2 + $OuterTickWidth + 2 + ($Bounds[0]["Y"] - $Bounds[2]["Y"]);
245
						$MaxBottom = max($MaxBottom, $TxtBottom);
246
						$LastX = $XPos;
247
					}
248
 
249
					if (isset($AxisSettings["Name"])) {
250
						$YPos = $MaxBottom + 2;
251
						$XPos = $this->pChartObject->GraphAreaX1 + ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) / 2;
252
						$Bounds = $this->pChartObject->drawText($XPos, $YPos, $AxisSettings["Name"], ["Align" => TEXT_ALIGN_TOPMIDDLE]);
253
						$MaxBottom = $Bounds[0]["Y"];
254
						$this->pDataObject->Data["GraphArea"]["Y2"] = $MaxBottom + $this->pChartObject->FontSize;
255
					}
256
 
257
					$AxisPos["B"] = $MaxBottom + $ScaleSpacing;
258
 
259
				} elseif ($AxisSettings["Position"] == AXIS_POSITION_TOP) {
260
 
261
					if ($XLabelsRotation == 0) {
262
						$LabelAlign = TEXT_ALIGN_BOTTOMMIDDLE;
263
						$LabelOffset = 2;
264
					}
265
 
266
					if ($XLabelsRotation > 0 && $XLabelsRotation < 190) {
267
						$LabelAlign = TEXT_ALIGN_MIDDLELEFT;
268
						$LabelOffset = 2;
269
					}
270
 
271
					if ($XLabelsRotation == 180) {
272
						$LabelAlign = TEXT_ALIGN_TOPMIDDLE;
273
						$LabelOffset = 5;
274
					}
275
 
276
					if ($XLabelsRotation > 180 && $XLabelsRotation < 360) {
277
						$LabelAlign = TEXT_ALIGN_MIDDLERIGHT;
278
						$LabelOffset = 5;
279
					}
280
 
281
					if ($Floating) {
282
						$FloatingOffset = $YMargin;
283
						$this->pChartObject->drawLine($this->pChartObject->GraphAreaX1 + $AxisSettings["Margin"], $AxisPos["T"], $this->pChartObject->GraphAreaX2 - $AxisSettings["Margin"], $AxisPos["T"], ["R" => $AxisR,"G" => $AxisG,"B" => $AxisB,"Alpha" => $AxisAlpha]);
284
					} else {
285
						$FloatingOffset = 0;
286
						$this->pChartObject->drawLine($this->pChartObject->GraphAreaX1, $AxisPos["T"], $this->pChartObject->GraphAreaX2, $AxisPos["T"], ["R" => $AxisR,"G" => $AxisG,"B" => $AxisB,"Alpha" => $AxisAlpha]);
287
					}
288
 
289
					if ($DrawArrows) {
290
						$this->pChartObject->drawArrow($this->pChartObject->GraphAreaX2 - $AxisSettings["Margin"], $AxisPos["T"], $this->pChartObject->GraphAreaX2 + ($ArrowSize * 2) , $AxisPos["T"], ["FillR" => $AxisR,"FillG" => $AxisG,"FillB" => $AxisB,"Size" => $ArrowSize]);
291
					}
292
 
293
					$Width = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) - $AxisSettings["Margin"] * 2;
294
					$Step = $Width / $AxisSettings["Rows"];
295
					$SubTicksSize = $Step / 2;
296
					$MinTop = $AxisPos["T"];
297
					$LastX = NULL;
298
					for ($i = 0; $i <= $AxisSettings["Rows"]; $i++) {
299
						$XPos = $this->pChartObject->GraphAreaX1 + $AxisSettings["Margin"] + $Step * $i;
300
						$YPos = $AxisPos["T"];
301
						$Value = $this->pChartObject->scaleFormat($AxisSettings["ScaleMin"] + $AxisSettings["RowHeight"] * $i, $AxisSettings["Display"], $AxisSettings["Format"], $AxisSettings["Unit"]);
302
						$BGColor = ($i % 2 == 1) ? $BG1 : $BG2;
303
 
304
						if ($LastX != NULL && $CycleBackground && ($DrawXLines == ALL || in_array($AxisID, $DrawXLines))) {
305
							$this->pChartObject->drawFilledRectangle($LastX, $this->pChartObject->GraphAreaY1 + $FloatingOffset, $XPos, $this->pChartObject->GraphAreaY2 - $FloatingOffset, $BGColor);
306
						}
307
 
308
						if ($DrawXLines == ALL || in_array($AxisID, $DrawXLines)) {
309
							$this->pChartObject->drawLine($XPos, $this->pChartObject->GraphAreaY1 + $FloatingOffset, $XPos, $this->pChartObject->GraphAreaY2 - $FloatingOffset, ["R" => $GridR,"G" => $GridG,"B" => $GridB,"Alpha" => $GridAlpha,"Ticks" => $GridTicks]);
310
						}
311
 
312
						if ($DrawSubTicks && $i != $AxisSettings["Rows"]) {
313
							$this->pChartObject->drawLine($XPos + $SubTicksSize, $YPos - $OuterSubTickWidth, $XPos + $SubTicksSize, $YPos + $InnerSubTickWidth, ["R" => $SubTickR,"G" => $SubTickG,"B" => $SubTickB,"Alpha" => $SubTickAlpha]);
314
						}
315
 
316
						$this->pChartObject->drawLine($XPos, $YPos - $OuterTickWidth, $XPos, $YPos + $InnerTickWidth, ["R" => $TickR,"G" => $TickG,"B" => $TickB,"Alpha" => $TickAlpha]);
317
						$Bounds = $this->pChartObject->drawText($XPos, $YPos - $OuterTickWidth - $LabelOffset, $Value, ["Angle" => $XLabelsRotation,"Align" => $LabelAlign]);
318
						$TxtBox = $YPos - $OuterTickWidth - 4 - ($Bounds[0]["Y"] - $Bounds[2]["Y"]);
319
						$MinTop = min($MinTop, $TxtBox);
320
						$LastX = $XPos;
321
					}
322
 
323
					if (isset($AxisSettings["Name"])) {
324
						$YPos = $MinTop - 2;
325
						$XPos = $this->pChartObject->GraphAreaX1 + ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) / 2;
326
						$Bounds = $this->pChartObject->drawText($XPos, $YPos, $AxisSettings["Name"], ["Align" => TEXT_ALIGN_BOTTOMMIDDLE]);
327
						$MinTop = $Bounds[2]["Y"];
328
						$this->pDataObject->Data["GraphArea"]["Y1"] = $MinTop;
329
					}
330
 
331
					$AxisPos["T"] = $MinTop - $ScaleSpacing;
332
				}
333
 
334
			} elseif ($AxisSettings["Identity"] == AXIS_Y) {
335
				if ($AxisSettings["Position"] == AXIS_POSITION_LEFT) {
336
					if ($Floating) {
337
						$FloatingOffset = $XMargin;
338
						$this->pChartObject->drawLine($AxisPos["L"], $this->pChartObject->GraphAreaY1 + $AxisSettings["Margin"], $AxisPos["L"], $this->pChartObject->GraphAreaY2 - $AxisSettings["Margin"], ["R" => $AxisR,"G" => $AxisG,"B" => $AxisB,"Alpha" => $AxisAlpha]);
339
					} else {
340
						$FloatingOffset = 0;
341
						$this->pChartObject->drawLine($AxisPos["L"], $this->pChartObject->GraphAreaY1, $AxisPos["L"], $this->pChartObject->GraphAreaY2, ["R" => $AxisR,"G" => $AxisG,"B" => $AxisB,"Alpha" => $AxisAlpha]);
342
					}
343
 
344
					if ($DrawArrows) {
345
						$this->pChartObject->drawArrow($AxisPos["L"], $this->pChartObject->GraphAreaY1 + $AxisSettings["Margin"], $AxisPos["L"], $this->pChartObject->GraphAreaY1 - ($ArrowSize * 2) , ["FillR" => $AxisR,"FillG" => $AxisG,"FillB" => $AxisB,"Size" => $ArrowSize]);
346
					}
347
 
348
					$Height = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) - $AxisSettings["Margin"] * 2;
349
					$Step = $Height / $AxisSettings["Rows"];
350
					$SubTicksSize = $Step / 2;
351
					$MinLeft = $AxisPos["L"];
352
					$LastY = NULL;
353
					for ($i = 0; $i <= $AxisSettings["Rows"]; $i++) {
354
						$YPos = $this->pChartObject->GraphAreaY2 - $AxisSettings["Margin"] - $Step * $i;
355
						$XPos = $AxisPos["L"];
356
						$Value = $this->pChartObject->scaleFormat($AxisSettings["ScaleMin"] + $AxisSettings["RowHeight"] * $i, $AxisSettings["Display"], $AxisSettings["Format"], $AxisSettings["Unit"]);
357
						$BGColor = ($i % 2 == 1) ? $BG1 : $BG2;
358
 
359
						if ($LastY != NULL && $CycleBackground && ($DrawYLines == ALL || in_array($AxisID, $DrawYLines))) {
360
							$this->pChartObject->drawFilledRectangle($this->pChartObject->GraphAreaX1 + $FloatingOffset, $LastY, $this->pChartObject->GraphAreaX2 - $FloatingOffset, $YPos, $BGColor);
361
						}
362
 
363
						if (($YPos != $this->pChartObject->GraphAreaY1 && $YPos != $this->pChartObject->GraphAreaY2) && ($DrawYLines == ALL || in_array($AxisID, $DrawYLines))) {
364
							$this->pChartObject->drawLine($this->pChartObject->GraphAreaX1 + $FloatingOffset, $YPos, $this->pChartObject->GraphAreaX2 - $FloatingOffset, $YPos, ["R" => $GridR,"G" => $GridG,"B" => $GridB,"Alpha" => $GridAlpha,"Ticks" => $GridTicks]);
365
						}
366
 
367
						if ($DrawSubTicks && $i != $AxisSettings["Rows"]) {
368
							 $this->pChartObject->drawLine($XPos - $OuterSubTickWidth, $YPos - $SubTicksSize, $XPos + $InnerSubTickWidth, $YPos - $SubTicksSize, ["R" => $SubTickR,"G" => $SubTickG,"B" => $SubTickB,"Alpha" => $SubTickAlpha]);
369
						}
370
 
371
						$this->pChartObject->drawLine($XPos - $OuterTickWidth, $YPos, $XPos + $InnerTickWidth, $YPos, ["R" => $TickR,"G" => $TickG,"B" => $TickB,"Alpha" => $TickAlpha]);
372
						$Bounds = $this->pChartObject->drawText($XPos - $OuterTickWidth - 2, $YPos, $Value, ["Align" => TEXT_ALIGN_MIDDLERIGHT]);
373
						$TxtLeft = $XPos - $OuterTickWidth - 2 - ($Bounds[1]["X"] - $Bounds[0]["X"]);
374
						$MinLeft = min($MinLeft, $TxtLeft);
375
						$LastY = $YPos;
376
					}
377
 
378
					if (isset($AxisSettings["Name"])) {
379
						$XPos = $MinLeft - 2;
380
						$YPos = $this->pChartObject->GraphAreaY1 + ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) / 2;
381
						$Bounds = $this->pChartObject->drawText($XPos, $YPos, $AxisSettings["Name"],["Align" => TEXT_ALIGN_BOTTOMMIDDLE,"Angle" => 90]);
382
						$MinLeft = $Bounds[2]["X"];
383
						$this->pDataObject->Data["GraphArea"]["X1"] = $MinLeft;
384
					}
385
 
386
					$AxisPos["L"] = $MinLeft - $ScaleSpacing;
387
				} elseif ($AxisSettings["Position"] == AXIS_POSITION_RIGHT) {
388
					if ($Floating) {
389
						$FloatingOffset = $XMargin;
390
						$this->pChartObject->drawLine($AxisPos["R"], $this->pChartObject->GraphAreaY1 + $AxisSettings["Margin"], $AxisPos["R"], $this->pChartObject->GraphAreaY2 - $AxisSettings["Margin"], ["R" => $AxisR,"G" => $AxisG,"B" => $AxisB,"Alpha" => $AxisAlpha]);
391
					} else {
392
						$FloatingOffset = 0;
393
						$this->pChartObject->drawLine($AxisPos["R"], $this->pChartObject->GraphAreaY1, $AxisPos["R"], $this->pChartObject->GraphAreaY2, ["R" => $AxisR,"G" => $AxisG,"B" => $AxisB,"Alpha" => $AxisAlpha]);
394
					}
395
 
396
					if ($DrawArrows) {
397
						$this->pChartObject->drawArrow($AxisPos["R"], $this->pChartObject->GraphAreaY1 + $AxisSettings["Margin"], $AxisPos["R"], $this->pChartObject->GraphAreaY1 - ($ArrowSize * 2), ["FillR" => $AxisR,"FillG" => $AxisG,"FillB" => $AxisB,"Size" => $ArrowSize]);
398
					}
399
 
400
					$Height = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) - $AxisSettings["Margin"] * 2;
401
					$Step = $Height / $AxisSettings["Rows"];
402
					$SubTicksSize = $Step / 2;
403
					$MaxLeft = $AxisPos["R"];
404
					$LastY = NULL;
405
					for ($i = 0; $i <= $AxisSettings["Rows"]; $i++) {
406
						$YPos = $this->pChartObject->GraphAreaY2 - $AxisSettings["Margin"] - $Step * $i;
407
						$XPos = $AxisPos["R"];
408
						$Value = $this->pChartObject->scaleFormat($AxisSettings["ScaleMin"] + $AxisSettings["RowHeight"] * $i, $AxisSettings["Display"], $AxisSettings["Format"], $AxisSettings["Unit"]);
409
						$BGColor = ($i % 2 == 1) ? $BG1 : $BG2;
410
 
411
						if ($LastY != NULL && $CycleBackground && ($DrawYLines == ALL || in_array($AxisID, $DrawYLines))) {
412
							$this->pChartObject->drawFilledRectangle($this->pChartObject->GraphAreaX1 + $FloatingOffset, $LastY, $this->pChartObject->GraphAreaX2 - $FloatingOffset, $YPos, $BGColor);
413
						}
414
 
415
						if (($YPos != $this->pChartObject->GraphAreaY1 && $YPos != $this->pChartObject->GraphAreaY2) && ($DrawYLines == ALL || in_array($AxisID, $DrawYLines))) {
416
							$this->pChartObject->drawLine($this->pChartObject->GraphAreaX1 + $FloatingOffset, $YPos, $this->pChartObject->GraphAreaX2 - $FloatingOffset, $YPos, ["R" => $GridR,"G" => $GridG,"B" => $GridB,"Alpha" => $GridAlpha,"Ticks" => $GridTicks]);
417
						}
418
 
419
						if ($DrawSubTicks && $i != $AxisSettings["Rows"]) {
420
							$this->pChartObject->drawLine($XPos - $InnerSubTickWidth, $YPos - $SubTicksSize, $XPos + $OuterSubTickWidth, $YPos - $SubTicksSize, ["R" => $SubTickR,"G" => $SubTickG,"B" => $SubTickB,"Alpha" => $SubTickAlpha]);
421
						}
422
 
423
						$this->pChartObject->drawLine($XPos - $InnerTickWidth, $YPos, $XPos + $OuterTickWidth, $YPos, ["R" => $TickR,"G" => $TickG,"B" => $TickB,"Alpha" => $TickAlpha]);
424
						$Bounds = $this->pChartObject->drawText($XPos + $OuterTickWidth + 2, $YPos, $Value, ["Align" => TEXT_ALIGN_MIDDLELEFT]);
425
						$TxtLeft = $XPos + $OuterTickWidth + 2 + ($Bounds[1]["X"] - $Bounds[0]["X"]);
426
						$MaxLeft = max($MaxLeft, $TxtLeft);
427
						$LastY = $YPos;
428
					}
429
 
430
					if (isset($AxisSettings["Name"])) {
431
						$XPos = $MaxLeft + 6;
432
						$YPos = $this->pChartObject->GraphAreaY1 + ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) / 2;
433
						$Bounds = $this->pChartObject->drawText($XPos, $YPos, $AxisSettings["Name"], ["Align" => TEXT_ALIGN_BOTTOMMIDDLE,"Angle" => 270]);
434
						$MaxLeft = $Bounds[2]["X"];
435
						$this->pDataObject->Data["GraphArea"]["X2"] = $MaxLeft + $this->pChartObject->FontSize;
436
					}
437
 
438
					$AxisPos["R"] = $MaxLeft + $ScaleSpacing;
439
				}
440
			}
441
		}
442
 
443
		$this->pDataObject->saveAxisConfig($Data["Axis"]);
444
	}
445
 
446
	/* Draw a scatter plot chart */
447
	function drawScatterPlotChart(array $Format = [])
448
	{
449
		$PlotSize = 3;
450
		$PlotBorder = FALSE;
451
		$BorderR = 250;
452
		$BorderG = 250;
453
		$BorderB = 250;
454
		$BorderAlpha = 30;
455
		$BorderSize = 1;
456
		$Surrounding = NULL;
457
		$RecordImageMap = FALSE;
458
		$ImageMapTitle = NULL;
459
		$ImageMapPrecision = 2;
460
 
461
		/* Override defaults */
462
		extract($Format);
463
 
464
		$Data = $this->pDataObject->getData();
465
		$Palette = $this->pDataObject->getPalette();
466
		$BorderColor =["R" => $BorderR,"G" => $BorderG,"B" => $BorderB,"Alpha" => $BorderAlpha];
467
		foreach($Data["ScatterSeries"] as $Key => $Series) {
468
			if ($Series["isDrawable"] == TRUE) {
469
				$SerieX = $Series["X"];
470
				$SerieValuesX = $Data["Series"][$SerieX]["Data"];
471
				$SerieXAxis = $Data["Series"][$SerieX]["Axis"];
472
				$SerieY = $Series["Y"];
473
				$SerieValuesY = $Data["Series"][$SerieY]["Data"];
474
				$SerieYAxis = $Data["Series"][$SerieY]["Axis"];
475
				$Description = ($ImageMapTitle == NULL) ? $Data["Series"][$Series["X"]]["Description"] . " / " . $Data["Series"][$Series["Y"]]["Description"] : $ImageMapTitle;
476
 
477
				if (isset($Series["Picture"]) && $Series["Picture"] != "") {
478
					$Picture = $Series["Picture"];
479
					list($PicWidth, $PicHeight, $PicType) = $this->pChartObject->getPicInfo($Picture);
480
				} else {
481
					$Picture = NULL;
482
				}
483
 
484
				$PosArrayX = $this->getPosArray($SerieValuesX, $SerieXAxis);
485
				(!is_array($PosArrayX)) AND $PosArrayX = [0 => $PosArrayX];
486
 
487
				$PosArrayY = $this->getPosArray($SerieValuesY, $SerieYAxis);
488
				(!is_array($PosArrayY)) AND $PosArrayY = [0 => $PosArrayY];
489
 
490
				$Color = array("R" => $Series["Color"]["R"],"G" => $Series["Color"]["G"],"B" => $Series["Color"]["B"],"Alpha" => $Series["Color"]["Alpha"]);
491
 
492
				foreach($PosArrayX as $Key => $Value) {
493
					$X = $Value;
494
					$Y = $PosArrayY[$Key];
495
					if ($X != VOID && $Y != VOID) {
496
						$RealValue = round($Data["Series"][$Series["X"]]["Data"][$Key], 2) . " / " . round($Data["Series"][$Series["Y"]]["Data"][$Key], 2);
497
						if ($RecordImageMap) {
498
							$this->pChartObject->addToImageMap("CIRCLE", floor($X) . "," . floor($Y) . "," . floor($PlotSize + $BorderSize) , $this->pChartObject->toHTMLColor($Series["Color"]["R"], $Series["Color"]["G"], $Series["Color"]["B"]) , $Description, $RealValue);
499
						}
500
 
501
						if (isset($Series["Shape"])) {
502
							$this->pChartObject->drawShape($X, $Y, $Series["Shape"], $PlotSize, $PlotBorder, $BorderSize, $Series["Color"]["R"], $Series["Color"]["G"], $Series["Color"]["B"], $Series["Color"]["Alpha"], $BorderR, $BorderG, $BorderB, $BorderAlpha);
503
						} elseif ($Picture == NULL) {
504
							if ($PlotBorder) {
505
								$this->pChartObject->drawFilledCircle($X, $Y, $PlotSize + $BorderSize, $BorderColor);
506
							}
507
 
508
							$this->pChartObject->drawFilledCircle($X, $Y, $PlotSize, $Color);
509
						} else {
510
							$this->pChartObject->drawFromPicture($PicType, $Picture, $X - $PicWidth / 2, $Y - $PicHeight / 2);
511
						}
512
					}
513
				}
514
			}
515
		}
516
	}
517
 
518
	/* Draw a scatter line chart */
519
	function drawScatterLineChart(array $Format = [])
520
	{
521
		$Data = $this->pDataObject->getData();
522
		$Palette = $this->pDataObject->getPalette();
523
		$RecordImageMap = isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : FALSE;
524
		$ImageMapTitle = isset($Format["ImageMapTitle"]) ? $Format["ImageMapTitle"] : NULL;
525
		$ImageMapPlotSize = isset($Format["ImageMapPlotSize"]) ? $Format["ImageMapPlotSize"] : 10;
526
		$ImageMapPrecision = isset($Format["ImageMapPrecision"]) ? $Format["ImageMapPrecision"] : 2;
527
		/* Parse all the series to draw */
528
		foreach($Data["ScatterSeries"] as $Key => $Series) {
529
			if ($Series["isDrawable"] == TRUE) {
530
				$SerieX = $Series["X"];
531
				$SerieValuesX = $Data["Series"][$SerieX]["Data"];
532
				$SerieXAxis = $Data["Series"][$SerieX]["Axis"];
533
				$SerieY = $Series["Y"];
534
				$SerieValuesY = $Data["Series"][$SerieY]["Data"];
535
				$SerieYAxis = $Data["Series"][$SerieY]["Axis"];
536
				$Ticks = $Series["Ticks"];
537
				$Weight = $Series["Weight"];
538
				$Description = ($ImageMapTitle == NULL) ? $Data["Series"][$Series["X"]]["Description"] . " / " . $Data["Series"][$Series["Y"]]["Description"] : $ImageMapTitle;
539
 
540
				$PosArrayX = $this->getPosArray($SerieValuesX, $SerieXAxis);
541
				(!is_array($PosArrayX)) AND $PosArrayX = [0 => $PosArrayX];
542
 
543
				$PosArrayY = $this->getPosArray($SerieValuesY, $SerieYAxis);
544
				(!is_array($PosArrayY)) AND $PosArrayY = [0 => $PosArrayY];
545
 
546
				$Color = ["R" => $Series["Color"]["R"],"G" => $Series["Color"]["G"],"B" => $Series["Color"]["B"],"Alpha" => $Series["Color"]["Alpha"]];
547
				($Ticks != 0) AND $Color["Ticks"] = $Ticks;
548
				($Weight != 0) AND $Color["Weight"] = $Weight;
549
 
550
				$LastX = VOID;
551
				$LastY = VOID;
552
				foreach($PosArrayX as $Key => $Value) {
553
					$X = $Value;
554
					$Y = $PosArrayY[$Key];
555
					if ($X != VOID && $Y != VOID) {
556
						$RealValue = round($Data["Series"][$Series["X"]]["Data"][$Key], 2) . " / " . round($Data["Series"][$Series["Y"]]["Data"][$Key], 2);
557
						if ($RecordImageMap) {
558
							$this->pChartObject->addToImageMap("CIRCLE", floor($X) . "," . floor($Y) . "," . $ImageMapPlotSize, $this->pChartObject->toHTMLColor($Series["Color"]["R"], $Series["Color"]["G"], $Series["Color"]["B"]) , $Description, $RealValue);
559
						}
560
 
561
						if ($LastX != VOID && $LastY != VOID){
562
							$this->pChartObject->drawLine($LastX, $LastY, $X, $Y, $Color);
563
						}
564
					}
565
 
566
					$LastX = $X;
567
					$LastY = $Y;
568
				}
569
			}
570
		}
571
	}
572
 
573
	/* Draw a scatter spline chart */
574
	function drawScatterSplineChart(array $Format = [])
575
	{
576
		$Data = $this->pDataObject->getData();
577
		$Palette = $this->pDataObject->getPalette();
578
		$RecordImageMap = isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : FALSE;
579
		$ImageMapTitle = isset($Format["ImageMapTitle"]) ? $Format["ImageMapTitle"] : NULL;
580
		$ImageMapPlotSize = isset($Format["ImageMapPlotSize"]) ? $Format["ImageMapPlotSize"] : 10;
581
		$ImageMapPrecision = isset($Format["ImageMapPrecision"]) ? $Format["ImageMapPrecision"] : 2;
582
		foreach($Data["ScatterSeries"] as $Key => $Series) {
583
			if ($Series["isDrawable"] == TRUE) {
584
				$SerieX = $Series["X"];
585
				$SerieValuesX = $Data["Series"][$SerieX]["Data"];
586
				$SerieXAxis = $Data["Series"][$SerieX]["Axis"];
587
				$SerieY = $Series["Y"];
588
				$SerieValuesY = $Data["Series"][$SerieY]["Data"];
589
				$SerieYAxis = $Data["Series"][$SerieY]["Axis"];
590
				$Ticks = $Series["Ticks"];
591
				$Weight = $Series["Weight"];
592
				$Description = ($ImageMapTitle == NULL) ? $Data["Series"][$Series["X"]]["Description"] . " / " . $Data["Series"][$Series["Y"]]["Description"] : $ImageMapTitle;
593
 
594
				$PosArrayX = $this->getPosArray($SerieValuesX, $SerieXAxis);
595
				if (!is_array($PosArrayX)) {
596
					$Value = $PosArrayX;
597
					$PosArrayX = [];
598
					$PosArrayX[0] = $Value;
599
				}
600
 
601
				$PosArrayY = $this->getPosArray($SerieValuesY, $SerieYAxis);
602
				if (!is_array($PosArrayY)) {
603
					$Value = $PosArrayY;
604
					$PosArrayY = [0 => $Value];
605
				}
606
 
607
				$SplineSettings = ["R" => $Series["Color"]["R"],"G" => $Series["Color"]["G"],"B" => $Series["Color"]["B"],"Alpha" => $Series["Color"]["Alpha"]];
608
				($Ticks != 0) AND $SplineSettings["Ticks"] = $Ticks;
609
				($Weight != 0) AND $SplineSettings["Weight"] = $Weight;
610
 
611
				$LastX = VOID;
612
				$LastY = VOID;
613
				$WayPoints = [];
614
				$Forces = [];
615
				foreach($PosArrayX as $Key => $Value) {
616
					$X = $Value;
617
					$Y = $PosArrayY[$Key];
618
					$Force = $this->pChartObject->getLength($LastX, $LastY, $X, $Y) / 5;
619
					if ($X != VOID && $Y != VOID) {
620
						$RealValue = round($Data["Series"][$Series["X"]]["Data"][$Key], 2) . " / " . round($Data["Series"][$Series["Y"]]["Data"][$Key], 2);
621
						if ($RecordImageMap) {
622
							$this->pChartObject->addToImageMap("CIRCLE", floor($X) . "," . floor($Y) . "," . $ImageMapPlotSize, $this->pChartObject->toHTMLColor($Series["Color"]["R"], $Series["Color"]["G"], $Series["Color"]["B"]) , $Description, $RealValue);
623
						}
624
					}
625
 
626
					if ($X != VOID && $Y != VOID) {
627
						$WayPoints[] = [$X,$Y];
628
						$Forces[] = $Force;
629
					}
630
 
631
					if ($Y == VOID || $X == VOID) {
632
						$SplineSettings["Forces"] = $Forces;
633
						$this->pChartObject->drawSpline($WayPoints, $SplineSettings);
634
						$WayPoints = [];
635
						$Forces = [];
636
					}
637
 
638
					$LastX = $X;
639
					$LastY = $Y;
640
				}
641
 
642
				$SplineSettings["Forces"] = $Forces;
643
				$this->pChartObject->drawSpline($WayPoints, $SplineSettings);
644
			}
645
		}
646
	}
647
 
648
	/* Return the scaled plot position */
649
	function getPosArray($Values, $AxisID)
650
	{
651
		$Data = $this->pDataObject->getData();
652
		$ScaleHeight = $Data["Axis"][$AxisID]["ScaleMax"] - $Data["Axis"][$AxisID]["ScaleMin"];
653
 
654
		(!is_array($Values)) AND $Values = [$Values];
655
		$Result = [];
656
 
657
		if ($Data["Axis"][$AxisID]["Identity"] == AXIS_X) {
658
			$Height = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) - $Data["Axis"][$AxisID]["Margin"] * 2;
659
			$Step = $Height / $ScaleHeight;
660
 
661
			foreach($Values as $Key => $Value) {
662
				$Result[] = ($Value == VOID) ? VOID : $this->pChartObject->GraphAreaX1 + $Data["Axis"][$AxisID]["Margin"] + ($Step * ($Value - $Data["Axis"][$AxisID]["ScaleMin"]));
663
			}
664
 
665
		} else {
666
			$Height = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) - $Data["Axis"][$AxisID]["Margin"] * 2;
667
			$Step = $Height / $ScaleHeight;
668
 
669
			foreach($Values as $Key => $Value) {
670
				$Result[] = ($Value == VOID) ? VOID : $this->pChartObject->GraphAreaY2 - $Data["Axis"][$AxisID]["Margin"] - ($Step * ($Value - $Data["Axis"][$AxisID]["ScaleMin"]));
671
			}
672
		}
673
 
674
		return (count($Result) == 1) ? $Result[0] : $Result;
675
 
676
	}
677
 
678
	/* Draw the legend of the active series */
679
	function drawScatterLegend($X, $Y, array $Format = [])
680
	{
681
		$Family = LEGEND_FAMILY_BOX;
682
		$FontName = $this->pChartObject->FontName;
683
		$FontSize = $this->pChartObject->FontSize;
684
		$FontR = $this->pChartObject->FontColorR;
685
		$FontG = $this->pChartObject->FontColorG;
686
		$FontB = $this->pChartObject->FontColorB;
687
		$BoxWidth = isset($Format["BoxWidth"]) ? $Format["BoxWidth"] : 5;
688
		$BoxHeight = isset($Format["BoxHeight"]) ? $Format["BoxHeight"] : 5;
689
		$IconAreaWidth = $BoxWidth;
690
		$IconAreaHeight = $BoxHeight;
691
		$XSpacing = 5;
692
		$Margin = 5;
693
		$R = 200;
694
		$G = 200;
695
		$B = 200;
696
		$Alpha = 100;
697
		$BorderR = 255;
698
		$BorderG = 255;
699
		$BorderB = 255;
700
		$Surrounding = NULL;
701
		$Style = LEGEND_ROUND;
702
		$Mode = LEGEND_VERTICAL;
703
 
704
		/* Override defaults */
705
		extract($Format);
706
 
707
		if ($Surrounding != NULL) {
708
			$BorderR = $R + $Surrounding;
709
			$BorderG = $G + $Surrounding;
710
			$BorderB = $B + $Surrounding;
711
		}
712
 
713
		$Data = $this->pDataObject->getData();
714
		foreach($Data["ScatterSeries"] as $Key => $Series) {
715
			if ($Series["isDrawable"] == TRUE && isset($Series["Picture"])) {
716
				list($PicWidth, $PicHeight) = $this->pChartObject->getPicInfo($Series["Picture"]);
717
				($IconAreaWidth < $PicWidth) AND $IconAreaWidth = $PicWidth;
718
				($IconAreaHeight < $PicHeight) AND $IconAreaHeight = $PicHeight;
719
			}
720
		}
721
 
722
		$YStep = max($this->pChartObject->FontSize, $IconAreaHeight) + 5;
723
		$XStep = $IconAreaWidth + 5;
724
		$XStep = $XSpacing;
725
		$Boundaries = ["L" => $X, "T" => $Y, "R" => 0, "B" => 0];
726
		$vY = $Y;
727
		$vX = $X;
728
		foreach($Data["ScatterSeries"] as $Key => $Series) {
729
			if ($Series["isDrawable"] == TRUE) {
730
				if ($Mode == LEGEND_VERTICAL) {
731
					$BoxArray = $this->pChartObject->getTextBox($vX + $IconAreaWidth + 4, $vY + $IconAreaHeight / 2, $FontName, $FontSize, 0, $Series["Description"]);
732
					($Boundaries["T"] > $BoxArray[2]["Y"] + $IconAreaHeight / 2) AND $Boundaries["T"] = $BoxArray[2]["Y"] + $IconAreaHeight / 2;
733
					($Boundaries["R"] < $BoxArray[1]["X"] + 2) AND $Boundaries["R"] = $BoxArray[1]["X"] + 2;
734
					($Boundaries["B"] < $BoxArray[1]["Y"] + 2 + $IconAreaHeight / 2) AND $Boundaries["B"] = $BoxArray[1]["Y"] + 2 + $IconAreaHeight / 2;
735
					$Lines = preg_split("/\n/", $Series["Description"]);
736
					$vY = $vY + max($this->pChartObject->FontSize * count($Lines) , $IconAreaHeight) + 5;
737
 
738
				} elseif ($Mode == LEGEND_HORIZONTAL) {
739
					$Lines = preg_split("/\n/", $Series["Description"]);
740
					$Width = [];
741
					foreach($Lines as $Key => $Value) {
742
						$BoxArray = $this->pChartObject->getTextBox($vX + $IconAreaWidth + 6, $Y + $IconAreaHeight / 2 + (($this->pChartObject->FontSize + 3) * $Key) , $FontName, $FontSize, 0, $Value);
743
						($Boundaries["T"] > $BoxArray[2]["Y"] + $IconAreaHeight / 2) AND $Boundaries["T"] = $BoxArray[2]["Y"] + $IconAreaHeight / 2;
744
						($Boundaries["R"] < $BoxArray[1]["X"] + 2) AND $Boundaries["R"] = $BoxArray[1]["X"] + 2;
745
						($Boundaries["B"] < $BoxArray[1]["Y"] + 2 + $IconAreaHeight / 2) AND $Boundaries["B"] = $BoxArray[1]["Y"] + 2 + $IconAreaHeight / 2;
746
 
747
						$Width[] = $BoxArray[1]["X"];
748
					}
749
 
750
					$vX = max($Width) + $XStep;
751
				}
752
			}
753
		}
754
 
755
		$vY = $vY - $YStep;
756
		$vX = $vX - $XStep;
757
		$TopOffset = $Y - $Boundaries["T"];
758
		if ($Boundaries["B"] - ($vY + $IconAreaHeight) < $TopOffset) {
759
			$Boundaries["B"] = $vY + $IconAreaHeight + $TopOffset;
760
		}
761
 
762
		if ($Style == LEGEND_ROUND) {
763
			$this->pChartObject->drawRoundedFilledRectangle($Boundaries["L"] - $Margin, $Boundaries["T"] - $Margin, $Boundaries["R"] + $Margin, $Boundaries["B"] + $Margin, $Margin, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha,"BorderR" => $BorderR,"BorderG" => $BorderG,"BorderB" => $BorderB]);
764
		} elseif ($Style == LEGEND_BOX) {
765
			$this->pChartObject->drawFilledRectangle($Boundaries["L"] - $Margin, $Boundaries["T"] - $Margin, $Boundaries["R"] + $Margin, $Boundaries["B"] + $Margin, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha,"BorderR" => $BorderR,"BorderG" => $BorderG,"BorderB" => $BorderB]);
766
		}
767
 
768
		$RestoreShadow = $this->pChartObject->Shadow;
769
		$this->Shadow = FALSE;
770
		foreach($Data["ScatterSeries"] as $Key => $Series) {
771
			if ($Series["isDrawable"] == TRUE) {
772
				$R = $Series["Color"]["R"];
773
				$G = $Series["Color"]["G"];
774
				$B = $Series["Color"]["B"];
775
				$Ticks = $Series["Ticks"];
776
				$Weight = $Series["Weight"];
777
				if (isset($Series["Picture"])) {
778
					$Picture = $Series["Picture"];
779
					list($PicWidth, $PicHeight) = $this->pChartObject->getPicInfo($Picture);
780
					$PicX = $X + $IconAreaWidth / 2;
781
					$PicY = $Y + $IconAreaHeight / 2;
782
					$this->pChartObject->drawFromPNG($PicX - $PicWidth / 2, $PicY - $PicHeight / 2, $Picture);
783
 
784
				} else {
785
					if ($Family == LEGEND_FAMILY_BOX) {
786
						$XOffset = ($BoxWidth != $IconAreaWidth) ? floor(($IconAreaWidth - $BoxWidth) / 2) : 0;
787
						$YOffset = ($BoxHeight != $IconAreaHeight) ? floor(($IconAreaHeight - $BoxHeight) / 2) : 0;
788
 
789
						$this->pChartObject->drawFilledRectangle($X + 1 + $XOffset, $Y + 1 + $YOffset, $X + $BoxWidth + $XOffset + 1, $Y + $BoxHeight + 1 + $YOffset, ["R" => 0,"G" => 0,"B" => 0,"Alpha" => 20]);
790
						$this->pChartObject->drawFilledRectangle($X + $XOffset, $Y + $YOffset, $X + $BoxWidth + $XOffset, $Y + $BoxHeight + $YOffset, ["R" => $R,"G" => $G,"B" => $B,"Surrounding" => 20]);
791
					} elseif ($Family == LEGEND_FAMILY_CIRCLE) {
792
						$this->pChartObject->drawFilledCircle($X + 1 + $IconAreaWidth / 2, $Y + 1 + $IconAreaHeight / 2, min($IconAreaHeight / 2, $IconAreaWidth / 2), ["R" => 0,"G" => 0,"B" => 0,"Alpha" => 20]);
793
						$this->pChartObject->drawFilledCircle($X + $IconAreaWidth / 2, $Y + $IconAreaHeight / 2, min($IconAreaHeight / 2, $IconAreaWidth / 2), ["R" => $R,"G" => $G,"B" => $B,"Surrounding" => 20]);
794
					} elseif ($Family == LEGEND_FAMILY_LINE) {
795
						$this->pChartObject->drawLine($X + 1, $Y + 1 + $IconAreaHeight / 2, $X + 1 + $IconAreaWidth, $Y + 1 + $IconAreaHeight / 2, ["R" => 0,"G" => 0,"B" => 0,"Alpha" => 20,"Ticks" => $Ticks,	"Weight" => $Weight]);
796
						$this->pChartObject->drawLine($X, $Y + $IconAreaHeight / 2, $X + $IconAreaWidth, $Y + $IconAreaHeight / 2, ["R" => $R,"G" => $G,"B" => $B,"Ticks" => $Ticks,"Weight" => $Weight]);
797
					}
798
				}
799
 
800
				if ($Mode == LEGEND_VERTICAL) {
801
					$Lines = preg_split("/\n/", $Series["Description"]);
802
					foreach($Lines as $Key => $Value) $this->pChartObject->drawText($X + $IconAreaWidth + 4, $Y + $IconAreaHeight / 2 + (($this->pChartObject->FontSize + 3) * $Key), $Value, ["R" => $FontR,"G" => $FontG,"B" => $FontB,"Align" => TEXT_ALIGN_MIDDLELEFT]);
803
					$Y = $Y + max($this->pChartObject->FontSize * count($Lines) , $IconAreaHeight) + 5;
804
				} elseif ($Mode == LEGEND_HORIZONTAL) {
805
					$Lines = preg_split("/\n/", $Series["Description"]);
806
					$Width = [];
807
					foreach($Lines as $Key => $Value) {
808
						$BoxArray = $this->pChartObject->drawText($X + $IconAreaWidth + 4, $Y + $IconAreaHeight / 2 + (($this->pChartObject->FontSize + 3) * $Key) , $Value, ["R" => $FontR,"G" => $FontG,"B" => $FontB,"Align" => TEXT_ALIGN_MIDDLELEFT]);
809
						$Width[] = $BoxArray[1]["X"];
810
					}
811
					$X = max($Width) + 2 + $XStep;
812
				}
813
			}
814
		}
815
 
816
		$this->Shadow = $RestoreShadow;
817
	}
818
 
819
	/* Get the legend box size */
820
	function getScatterLegendSize(array $Format = [])
821
	{
822
		$FontName = isset($Format["FontName"]) ? $Format["FontName"] : $this->pChartObject->FontName;
823
		$FontSize = isset($Format["FontSize"]) ? $Format["FontSize"] : $this->pChartObject->FontSize;
824
		$BoxSize = isset($Format["BoxSize"]) ? $Format["BoxSize"] : 5;
825
		$Margin = isset($Format["Margin"]) ? $Format["Margin"] : 5;
826
		$Style = isset($Format["Style"]) ? $Format["Style"] : LEGEND_ROUND;
827
		$Mode = isset($Format["Mode"]) ? $Format["Mode"] : LEGEND_VERTICAL;
828
		$YStep = max($this->pChartObject->FontSize, $BoxSize) + 5;
829
		$XStep = $BoxSize + 5;
830
		$X = 100;
831
		$Y = 100;
832
		$Data = $this->pDataObject->getData();
833
		foreach($Data["ScatterSeries"] as $Key => $Series) {
834
			if ($Series["isDrawable"] == TRUE && isset($Series["Picture"])) {
835
				list($PicWidth, $PicHeight) = $this->pChartObject->getPicInfo($Series["Picture"]);
836
				($IconAreaWidth < $PicWidth) AND $IconAreaWidth = $PicWidth;
837
				($IconAreaHeight < $PicHeight) AND $IconAreaHeight = $PicHeight;
838
			}
839
		}
840
 
841
		$YStep = max($this->pChartObject->FontSize, $IconAreaHeight) + 5;
842
		$XStep = $IconAreaWidth + 5;
843
		$XStep = $XSpacing;
844
		$Boundaries = ["L" => $X, "T" => $Y, "R" => 0, "B" => 0];
845
		$vY = $Y;
846
		$vX = $X;
847
		foreach($Data["ScatterSeries"] as $Key => $Series) {
848
			if ($Series["isDrawable"] == TRUE) {
849
				if ($Mode == LEGEND_VERTICAL) {
850
					$BoxArray = $this->pChartObject->getTextBox($vX + $IconAreaWidth + 4, $vY + $IconAreaHeight / 2, $FontName, $FontSize, 0, $Series["Description"]);
851
					($Boundaries["T"] > $BoxArray[2]["Y"] + $IconAreaHeight / 2) AND $Boundaries["T"] = $BoxArray[2]["Y"] + $IconAreaHeight / 2;
852
					($Boundaries["R"] < $BoxArray[1]["X"] + 2) AND $Boundaries["R"] = $BoxArray[1]["X"] + 2;
853
					($Boundaries["B"] < $BoxArray[1]["Y"] + 2 + $IconAreaHeight / 2) AND $Boundaries["B"] = $BoxArray[1]["Y"] + 2 + $IconAreaHeight / 2;
854
 
855
					$Lines = preg_split("/\n/", $Series["Description"]);
856
					$vY = $vY + max($this->pChartObject->FontSize * count($Lines) , $IconAreaHeight) + 5;
857
 
858
				} elseif ($Mode == LEGEND_HORIZONTAL) {
859
					$Lines = preg_split("/\n/", $Series["Description"]);
860
					$Width = [];
861
					foreach($Lines as $Key => $Value) {
862
						$BoxArray = $this->pChartObject->getTextBox($vX + $IconAreaWidth + 6, $Y + $IconAreaHeight / 2 + (($this->pChartObject->FontSize + 3) * $Key) , $FontName, $FontSize, 0, $Value);
863
						($Boundaries["T"] > $BoxArray[2]["Y"] + $IconAreaHeight / 2) AND $Boundaries["T"] = $BoxArray[2]["Y"] + $IconAreaHeight / 2;
864
						($Boundaries["R"] < $BoxArray[1]["X"] + 2) AND $Boundaries["R"] = $BoxArray[1]["X"] + 2;
865
						($Boundaries["B"] < $BoxArray[1]["Y"] + 2 + $IconAreaHeight / 2) AND $Boundaries["B"] = $BoxArray[1]["Y"] + 2 + $IconAreaHeight / 2;
866
 
867
						$Width[] = $BoxArray[1]["X"];
868
					}
869
 
870
					$vX = max($Width) + $XStep;
871
				}
872
			}
873
		}
874
 
875
		$vY = $vY - $YStep;
876
		$vX = $vX - $XStep;
877
		$TopOffset = $Y - $Boundaries["T"];
878
		($Boundaries["B"] - ($vY + $BoxSize) < $TopOffset) AND $Boundaries["B"] = $vY + $BoxSize + $TopOffset;
879
		$Width = ($Boundaries["R"] + $Margin) - ($Boundaries["L"] - $Margin);
880
		$Height = ($Boundaries["B"] + $Margin) - ($Boundaries["T"] - $Margin);
881
 
882
		return ["Width" => $Width,"Height" => $Height];
883
	}
884
 
885
	/* Draw the line of best fit */
886
	function drawScatterBestFit(array $Format = [])
887
	{
888
		$Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : 0;
889
		$Data = $this->pDataObject->getData();
890
		foreach($Data["ScatterSeries"] as $Key => $Series) {
891
			if ($Series["isDrawable"] == TRUE) {
892
				$SerieX = $Series["X"];
893
				$SerieValuesX = $Data["Series"][$SerieX]["Data"];
894
				$SerieXAxis = $Data["Series"][$SerieX]["Axis"];
895
				$SerieY = $Series["Y"];
896
				$SerieValuesY = $Data["Series"][$SerieY]["Data"];
897
				$SerieYAxis = $Data["Series"][$SerieY]["Axis"];
898
				$Color = ["R" => $Series["Color"]["R"],"G" => $Series["Color"]["G"],"B" => $Series["Color"]["B"],"Alpha" => $Series["Color"]["Alpha"]];
899
				$Color["Ticks"] = $Ticks;
900
				$PosArrayX = $Data["Series"][$Series["X"]]["Data"];
901
				$PosArrayY = $Data["Series"][$Series["Y"]]["Data"];
902
				$Sxy = 0;
903
				$Sx = 0;
904
				$Sy = 0;
905
				$Sxx = 0;
906
				foreach($PosArrayX as $Key => $Value) {
907
					$X = $Value;
908
					$Y = $PosArrayY[$Key];
909
					$Sxy = $Sxy + $X * $Y;
910
					$Sx = $Sx + $X;
911
					$Sy = $Sy + $Y;
912
					$Sxx = $Sxx + $X * $X;
913
				}
914
 
915
				$n = count($PosArrayX);
916
				if ((($n * $Sxx) == ($Sx * $Sx))) {
917
					$X1 = $this->getPosArray($Data["Axis"][$SerieXAxis]["ScaleMin"], $SerieXAxis);
918
					$X2 = $X1;
919
					$Y1 = $this->pChartObject->GraphAreaY1;
920
					$Y2 = $this->pChartObject->GraphAreaY2;
921
				} else {
922
					$M = (($n * $Sxy) - ($Sx * $Sy)) / (($n * $Sxx) - ($Sx * $Sx));
923
					$B = (($Sy) - ($M * $Sx)) / ($n);
924
					$X1 = $this->getPosArray($Data["Axis"][$SerieXAxis]["ScaleMin"], $SerieXAxis);
925
					$Y1 = $this->getPosArray($M * $Data["Axis"][$SerieXAxis]["ScaleMin"] + $B, $SerieYAxis);
926
					$X2 = $this->getPosArray($Data["Axis"][$SerieXAxis]["ScaleMax"], $SerieXAxis);
927
					$Y2 = $this->getPosArray($M * $Data["Axis"][$SerieXAxis]["ScaleMax"] + $B, $SerieYAxis);
928
					$RealM = - ($Y2 - $Y1) / ($X2 - $X1);
929
					if ($Y1 < $this->pChartObject->GraphAreaY1) {
930
						$X1 = $X1 + ($this->pChartObject->GraphAreaY1 - $Y1 / $RealM);
931
						$Y1 = $this->pChartObject->GraphAreaY1;
932
					}
933
 
934
					if ($Y1 > $this->pChartObject->GraphAreaY2) {
935
						$X1 = $X1 + ($Y1 - $this->pChartObject->GraphAreaY2) / $RealM;
936
						$Y1 = $this->pChartObject->GraphAreaY2;
937
					}
938
 
939
					if ($Y2 < $this->pChartObject->GraphAreaY1) {
940
						$X2 = $X2 - ($this->pChartObject->GraphAreaY1 - $Y2) / $RealM;
941
						$Y2 = $this->pChartObject->GraphAreaY1;
942
					}
943
 
944
					if ($Y2 > $this->pChartObject->GraphAreaY2) {
945
						$X2 = $X2 - ($Y2 - $this->pChartObject->GraphAreaY2) / $RealM;
946
						$Y2 = $this->pChartObject->GraphAreaY2;
947
					}
948
				}
949
 
950
				$this->pChartObject->drawLine($X1, $Y1, $X2, $Y2, $Color);
951
			}
952
		}
953
	}
954
 
955
	function writeScatterLabel($ScatterSerieID, $Points, array $Format = [])
956
	{
957
		$Data = $this->pDataObject->getData();
958
		$Palette = $this->pDataObject->getPalette();
959
 
960
		if (!isset($Data["ScatterSeries"][$ScatterSerieID])) {
961
			return 0;
962
		}
963
 
964
		(!is_array($Points)) AND $Points = [$Points];
965
		$OverrideTitle = isset($Format["OverrideTitle"]) ? $Format["OverrideTitle"] : NULL;
966
		$DrawPoint = isset($Format["DrawPoint"]) ? $Format["DrawPoint"] : LABEL_POINT_BOX;
967
		$Decimals = isset($Format["Decimals"]) ? $Format["Decimals"] : NULL;
968
 
969
		$Series = $Data["ScatterSeries"][$ScatterSerieID];
970
		$SerieX = $Series["X"];
971
		$SerieValuesX = $Data["Series"][$SerieX]["Data"];
972
		$SerieXAxis = $Data["Series"][$SerieX]["Axis"];
973
		$SerieY = $Series["Y"];
974
		$SerieValuesY = $Data["Series"][$SerieY]["Data"];
975
		$SerieYAxis = $Data["Series"][$SerieY]["Axis"];
976
 
977
		$PosArrayX = $this->getPosArray($SerieValuesX, $SerieXAxis);
978
		(!is_array($PosArrayX)) AND $PosArrayX = [0 => $PosArrayX];
979
 
980
		$PosArrayY = $this->getPosArray($SerieValuesY, $SerieYAxis);
981
		(!is_array($PosArrayY)) AND $PosArrayY = [0 => $PosArrayY];
982
 
983
		foreach($Points as $Key => $Point) {
984
			if (isset($PosArrayX[$Point]) && isset($PosArrayY[$Point])) {
985
				$X = floor($PosArrayX[$Point]);
986
				$Y = floor($PosArrayY[$Point]);
987
				if ($DrawPoint == LABEL_POINT_CIRCLE) {
988
					$this->pChartObject->drawFilledCircle($X, $Y, 3, ["R" => 255,"G" => 255,"B" => 255,"BorderR" => 0,"BorderG" => 0,"BorderB" => 0]);
989
				} elseif ($DrawPoint == LABEL_POINT_BOX) {
990
					$this->pChartObject->drawFilledRectangle($X - 2, $Y - 2, $X + 2, $Y + 2, ["R" => 255,"G" => 255,"B" => 255,"BorderR" => 0,"BorderG" => 0,"BorderB" => 0]);
991
				}
992
 
993
				$XValue = ($Decimals == NULL) ? $SerieValuesX[$Point] : round($SerieValuesX[$Point], $Decimals);
994
				$XValue = $this->pChartObject->scaleFormat($XValue, $Data["Axis"][$SerieXAxis]["Display"], $Data["Axis"][$SerieXAxis]["Format"], $Data["Axis"][$SerieXAxis]["Unit"]);
995
 
996
				$YValue = ($Decimals == NULL) ? $SerieValuesY[$Point] : round($SerieValuesY[$Point], $Decimals);
997
				$YValue = $this->pChartObject->scaleFormat($YValue, $Data["Axis"][$SerieYAxis]["Display"], $Data["Axis"][$SerieYAxis]["Format"], $Data["Axis"][$SerieYAxis]["Unit"]);
998
 
999
				$Description = (isset($Series["Description"])) ? $Series["Description"] : "No description";
1000
				$Series = ["Format" => ["R" => $Series["Color"]["R"],"G" => $Series["Color"]["G"],"B" => $Series["Color"]["B"],"Alpha" => $Series["Color"]["Alpha"]],"Caption" => $XValue . " / " . $YValue];
1001
				$this->pChartObject->drawLabelBox($X, $Y - 3, $Description, $Series, $Format);
1002
			}
1003
		}
1004
	}
1005
 
1006
	/* Draw a Scatter threshold */
1007
	function drawScatterThreshold($Value, array $Format = [])
1008
	{
1009
 
1010
		$AxisID = 0;
1011
		$R = 255;
1012
		$G = 0;
1013
		$B = 0;
1014
		$Alpha = 50;
1015
		$Weight = NULL;
1016
		$Ticks = 3;
1017
		$Wide = FALSE;
1018
		$WideFactor = 5;
1019
		$WriteCaption = FALSE;
1020
		$Caption = NULL;
1021
		$CaptionAlign = CAPTION_LEFT_TOP;
1022
		$CaptionOffset = 10;
1023
		$CaptionR = 255;
1024
		$CaptionG = 255;
1025
		$CaptionB = 255;
1026
		$CaptionAlpha = 100;
1027
		$DrawBox = TRUE;
1028
		$DrawBoxBorder = FALSE;
1029
		$BorderOffset = 5;
1030
		$BoxRounded = TRUE;
1031
		$RoundedRadius = 3;
1032
		$BoxR = 0;
1033
		$BoxG = 0;
1034
		$BoxB = 0;
1035
		$BoxAlpha = 20;
1036
		$BoxSurrounding = "";
1037
		$BoxBorderR = 255;
1038
		$BoxBorderG = 255;
1039
		$BoxBorderB = 255;
1040
		$BoxBorderAlpha = 100;
1041
 
1042
		/* Override defaults */
1043
		extract($Format);
1044
 
1045
		$Data = $this->pDataObject->getData();
1046
		if (!isset($Data["Axis"][$AxisID])) {
1047
			return -1;
1048
		}
1049
 
1050
		($Caption == NULL) AND $Caption = $Value;
1051
		$CaptionSettings = [
1052
			"DrawBox" => $DrawBox,
1053
			"DrawBoxBorder" => $DrawBoxBorder,
1054
			"BorderOffset" => $BorderOffset,
1055
			"BoxRounded" => $BoxRounded,
1056
			"RoundedRadius" => $RoundedRadius,
1057
			"BoxR" => $BoxR,
1058
			"BoxG" => $BoxG,
1059
			"BoxB" => $BoxB,
1060
			"BoxAlpha" => $BoxAlpha,
1061
			"BoxSurrounding" => $BoxSurrounding,
1062
			"BoxBorderR" => $BoxBorderR,
1063
			"BoxBorderG" => $BoxBorderG,
1064
			"BoxBorderB" => $BoxBorderB,
1065
			"BoxBorderAlpha" => $BoxBorderAlpha,
1066
			"R" => $CaptionR,
1067
			"G" => $CaptionG,
1068
			"B" => $CaptionB,
1069
			"Alpha" => $CaptionAlpha
1070
		];
1071
 
1072
		if ($Data["Axis"][$AxisID]["Identity"] == AXIS_Y) {
1073
			$X1 = $this->pChartObject->GraphAreaX1 + $Data["Axis"][$AxisID]["Margin"];
1074
			$X2 = $this->pChartObject->GraphAreaX2 - $Data["Axis"][$AxisID]["Margin"];
1075
			$Y = $this->getPosArray($Value, $AxisID);
1076
			$this->pChartObject->drawLine($X1, $Y, $X2, $Y, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha,"Ticks" => $Ticks,"Weight" => $Weight]);
1077
			if ($Wide) {
1078
				$this->pChartObject->drawLine($X1, $Y - 1, $X2, $Y - 1, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha / $WideFactor,"Ticks" => $Ticks]);
1079
				$this->pChartObject->drawLine($X1, $Y + 1, $X2, $Y + 1, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha / $WideFactor,"Ticks" => $Ticks]);
1080
			}
1081
 
1082
			if ($WriteCaption) {
1083
				if ($CaptionAlign == CAPTION_LEFT_TOP) {
1084
					$X = $this->pChartObject->GraphAreaX1 + $Data["Axis"][$AxisID]["Margin"] + $CaptionOffset;
1085
					$CaptionSettings["Align"] = TEXT_ALIGN_MIDDLELEFT;
1086
				} else {
1087
					$X = $this->pChartObject->GraphAreaX2 - $Data["Axis"][$AxisID]["Margin"] - $CaptionOffset;
1088
					$CaptionSettings["Align"] = TEXT_ALIGN_MIDDLERIGHT;
1089
				}
1090
 
1091
				$this->pChartObject->drawText($X, $Y, $Caption, $CaptionSettings);
1092
			}
1093
 
1094
			return ["Y" => $Y];
1095
 
1096
		} elseif ($Data["Axis"][$AxisID]["Identity"] == AXIS_X) {
1097
			$X = $this->getPosArray($Value, $AxisID);
1098
			$Y1 = $this->pChartObject->GraphAreaY1 + $Data["Axis"][$AxisID]["Margin"];
1099
			$Y2 = $this->pChartObject->GraphAreaY2 - $Data["Axis"][$AxisID]["Margin"];
1100
			$this->pChartObject->drawLine($X, $Y1, $X, $Y2, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha,"Ticks" => $Ticks,"Weight" => $Weight]);
1101
			if ($Wide) {
1102
				$this->pChartObject->drawLine($X - 1, $Y1, $X - 1, $Y2, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha / $WideFactor,"Ticks" => $Ticks]);
1103
				$this->pChartObject->drawLine($X + 1, $Y1, $X + 1, $Y2, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha / $WideFactor,"Ticks" => $Ticks]);
1104
			}
1105
 
1106
			if ($WriteCaption) {
1107
				if ($CaptionAlign == CAPTION_LEFT_TOP) {
1108
					$Y = $this->pChartObject->GraphAreaY1 + $Data["Axis"][$AxisID]["Margin"] + $CaptionOffset;
1109
					#$CaptionSettings["Align"] = TEXT_ALIGN_TOPMIDDLE; # POINTLESS
1110
				} else {
1111
					$Y = $this->pChartObject->GraphAreaY2 - $Data["Axis"][$AxisID]["Margin"] - $CaptionOffset;
1112
					#$CaptionSettings["Align"] = TEXT_ALIGN_BOTTOMMIDDLE; # POINTLESS
1113
				}
1114
 
1115
				$CaptionSettings["Align"] = TEXT_ALIGN_TOPMIDDLE;
1116
				$this->pChartObject->drawText($X, $Y, $Caption, $CaptionSettings);
1117
			}
1118
 
1119
			return ["X" => $X];
1120
		}
1121
	}
1122
 
1123
	/* Draw a Scatter threshold area */
1124
	function drawScatterThresholdArea($Value1, $Value2, array $Format = [])
1125
	{
1126
		$AxisID = 0;
1127
		$R = isset($Format["R"]) ? $Format["R"] : 255;
1128
		$G = isset($Format["G"]) ? $Format["G"] : 0;
1129
		$B = isset($Format["B"]) ? $Format["B"] : 0;
1130
		$Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 20;
1131
		$Border = TRUE;
1132
		$BorderR = $R;
1133
		$BorderG = $G;
1134
		$BorderB = $B;
1135
		$BorderAlpha = $Alpha + 20;
1136
		$BorderTicks = 2;
1137
		$AreaName = "La ouate de phoque"; //NULL;
1138
		$NameAngle = ZONE_NAME_ANGLE_AUTO;
1139
		$NameR = 255;
1140
		$NameG = 255;
1141
		$NameB = 255;
1142
		$NameAlpha = 100;
1143
		$DisableShadowOnArea = TRUE;
1144
 
1145
		/* Override defaults */
1146
		extract($Format);
1147
 
1148
		$Data = $this->pDataObject->getData();
1149
		if (!isset($Data["Axis"][$AxisID])) {
1150
			return -1;
1151
		}
1152
 
1153
		($BorderAlpha > 100) AND $BorderAlpha = 100;
1154
 
1155
		if ($Value1 > $Value2) {
1156
			list($Value1, $Value2) = [$Value2,$Value1];
1157
		}
1158
 
1159
		$RestoreShadow = $this->pChartObject->Shadow;
1160
		if ($DisableShadowOnArea && $this->pChartObject->Shadow) {
1161
			$this->pChartObject->Shadow = FALSE;
1162
		}
1163
 
1164
		if ($Data["Axis"][$AxisID]["Identity"] == AXIS_X) {
1165
			$Y1 = $this->pChartObject->GraphAreaY1 + $Data["Axis"][$AxisID]["Margin"];
1166
			$Y2 = $this->pChartObject->GraphAreaY2 - $Data["Axis"][$AxisID]["Margin"];
1167
			$X1 = $this->getPosArray($Value1, $AxisID);
1168
			$X2 = $this->getPosArray($Value2, $AxisID);
1169
			if ($X1 <= $this->pChartObject->GraphAreaX1) {
1170
				$X1 = $this->pChartObject->GraphAreaX1 + $Data["Axis"][$AxisID]["Margin"];
1171
			}
1172
 
1173
			if ($X2 >= $this->pChartObject->GraphAreaX2) {
1174
				$X2 = $this->pChartObject->GraphAreaX2 - $Data["Axis"][$AxisID]["Margin"];
1175
			}
1176
 
1177
			$this->pChartObject->drawFilledRectangle($X1, $Y1, $X2, $Y2, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha]);
1178
 
1179
			if ($Border) {
1180
				$this->pChartObject->drawLine($X1, $Y1, $X1, $Y2, ["R" => $BorderR,"G" => $BorderG,"B" => $BorderB,"Alpha" => $BorderAlpha,"Ticks" => $BorderTicks]);
1181
				$this->pChartObject->drawLine($X2, $Y1, $X2, $Y2, ["R" => $BorderR,"G" => $BorderG,"B" => $BorderB,"Alpha" => $BorderAlpha,"Ticks" => $BorderTicks]);
1182
			}
1183
 
1184
			if ($AreaName != NULL) {
1185
				$XPos = ($X2 - $X1) / 2 + $X1;
1186
				$YPos = ($Y2 - $Y1) / 2 + $Y1;
1187
				if ($NameAngle == ZONE_NAME_ANGLE_AUTO) {
1188
					$TxtPos = $this->pChartObject->getTextBox($XPos, $YPos, $this->pChartObject->FontName, $this->pChartObject->FontSize, 0, $AreaName);
1189
					$TxtWidth = $TxtPos[1]["X"] - $TxtPos[0]["X"];
1190
					$NameAngle = (abs($X2 - $X1) > $TxtWidth) ? 0 : 90;
1191
				}
1192
 
1193
				$this->pChartObject->Shadow = $RestoreShadow;
1194
				$this->pChartObject->drawText($XPos, $YPos, $AreaName, ["R" => $NameR,"G" => $NameG,"B" => $NameB,"Alpha" => $NameAlpha,"Angle" => $NameAngle,"Align" => TEXT_ALIGN_MIDDLEMIDDLE]);
1195
				($DisableShadowOnArea) AND $this->pChartObject->Shadow = FALSE;
1196
			}
1197
 
1198
			$this->pChartObject->Shadow = $RestoreShadow;
1199
 
1200
			return ["X1" => $X1,"X2" => $X2];
1201
 
1202
		} elseif ($Data["Axis"][$AxisID]["Identity"] == AXIS_Y) {
1203
 
1204
			$X1 = $this->pChartObject->GraphAreaX1 + $Data["Axis"][$AxisID]["Margin"];
1205
			$X2 = $this->pChartObject->GraphAreaX2 - $Data["Axis"][$AxisID]["Margin"];
1206
			$Y1 = $this->getPosArray($Value1, $AxisID);
1207
			$Y2 = $this->getPosArray($Value2, $AxisID);
1208
			if ($Y1 >= $this->pChartObject->GraphAreaY2) {
1209
				$Y1 = $this->pChartObject->GraphAreaY2 - $Data["Axis"][$AxisID]["Margin"];
1210
			}
1211
 
1212
			if ($Y2 <= $this->pChartObject->GraphAreaY1) {
1213
				$Y2 = $this->pChartObject->GraphAreaY1 + $Data["Axis"][$AxisID]["Margin"];
1214
			}
1215
 
1216
			$this->pChartObject->drawFilledRectangle($X1, $Y1, $X2, $Y2, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha]);
1217
			if ($Border) {
1218
				$this->pChartObject->drawLine($X1, $Y1, $X2, $Y1, ["R" => $BorderR,"G" => $BorderG,"B" => $BorderB,"Alpha" => $BorderAlpha,"Ticks" => $BorderTicks]);
1219
				$this->pChartObject->drawLine($X1, $Y2, $X2, $Y2, ["R" => $BorderR,"G" => $BorderG,"B" => $BorderB,"Alpha" => $BorderAlpha,"Ticks" => $BorderTicks]);
1220
			}
1221
 
1222
			if ($AreaName != NULL) {
1223
				$XPos = ($X2 - $X1) / 2 + $X1;
1224
				$YPos = ($Y2 - $Y1) / 2 + $Y1;
1225
				$this->pChartObject->Shadow = $RestoreShadow;
1226
				$this->pChartObject->drawText($YPos, $XPos, $AreaName, ["R" => $NameR,"G" => $NameG,"B" => $NameB,"Alpha" => $NameAlpha,"Angle" => 0,"Align" => TEXT_ALIGN_MIDDLEMIDDLE]);
1227
				($DisableShadowOnArea) AND $this->Shadow = FALSE;
1228
			}
1229
 
1230
			$this->pChartObject->Shadow = $RestoreShadow;
1231
 
1232
			return ["Y1" => $Y1,"Y2" => $Y2];
1233
		}
1234
	}
1235
}
1236
 
1237
?>