Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
/*
3
pSurface - class to draw surface 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("UNKNOWN", 0.123456789);
16
define("IGNORED", -1);
17
define("LABEL_POSITION_LEFT", 880001);
18
define("LABEL_POSITION_RIGHT", 880002);
19
define("LABEL_POSITION_TOP", 880003);
20
define("LABEL_POSITION_BOTTOM", 880004);
21
 
22
/* pStock class definition */
23
class pSurface
24
{
25
	var $pChartObject;
26
	var $GridSizeX;
27
	var $GridSizeY;
28
	var $Points = [];
29
	/* Class creator */
30
	function __construct($pChartObject)
31
	{
32
		$this->pChartObject = $pChartObject;
33
		#$this->GridSize = 10; # UNUSED
34
	}
35
 
36
	/* Define the grid size and initialise the 2D matrix */
37
	function setGrid($XSize = 10, $YSize = 10)
38
	{
39
		for ($X = 0; $X <= $XSize; $X++) {
40
			for ($Y = 0; $Y <= $YSize; $Y++) {
41
				$this->Points[$X][$Y] = UNKNOWN;
42
			}
43
		}
44
 
45
		$this->GridSizeX = $XSize;
46
		$this->GridSizeY = $YSize;
47
	}
48
 
49
	/* Add a point on the grid */
50
	function addPoint($X, $Y, $Value, $Force = TRUE)
51
	{
52
		if ($X < 0 || $X > $this->GridSizeX) {
53
			return 0;
54
		}
55
 
56
		if ($Y < 0 || $Y > $this->GridSizeY) {
57
			return 0;
58
		}
59
 
60
		if ($this->Points[$X][$Y] == UNKNOWN || $Force) {
61
			$this->Points[$X][$Y] = $Value;
62
		} elseif ($this->Points[$X][$Y] == UNKNOWN) {
63
			$this->Points[$X][$Y] = $Value;
64
		} else {
65
			$this->Points[$X][$Y] = ($this->Points[$X][$Y] + $Value) / 2;
66
		}
67
	}
68
 
69
	/* Write the X labels */
70
	function writeXLabels(array $Format = [])
71
	{
72
		$R = $this->pChartObject->FontColorR;
73
		$G = $this->pChartObject->FontColorG;
74
		$B = $this->pChartObject->FontColorB;
75
		$Alpha = $this->pChartObject->FontColorA;
76
		$Angle = 0;
77
		$Padding = 5;
78
		$Position = LABEL_POSITION_TOP;
79
		$Labels = NULL;
80
		$CountOffset = 0;
81
 
82
		/* Override defaults */
83
		extract($Format);
84
 
85
		if ($Labels != NULL && !is_array($Labels)) {
86
			$Labels = [$Labels];
87
		}
88
 
89
		$X0 = $this->pChartObject->GraphAreaX1;
90
		$XSize = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) / ($this->GridSizeX + 1);
91
		$Settings = ["Angle" => $Angle,"R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha];
92
		if ($Position == LABEL_POSITION_TOP) {
93
			$YPos = $this->pChartObject->GraphAreaY1 - $Padding;
94
			$Settings["Align"] = ($Angle == 0) ? TEXT_ALIGN_BOTTOMMIDDLE : TEXT_ALIGN_MIDDLELEFT;
95
 
96
		} elseif ($Position == LABEL_POSITION_BOTTOM) {
97
			$YPos = $this->pChartObject->GraphAreaY2 + $Padding;
98
			$Settings["Align"] = ($Angle == 0) ? TEXT_ALIGN_TOPMIDDLE : TEXT_ALIGN_MIDDLERIGHT;
99
 
100
		} else {
101
			return -1;
102
		}
103
 
104
		for ($X = 0; $X <= $this->GridSizeX; $X++) {
105
			$XPos = floor($X0 + $X * $XSize + $XSize / 2);
106
			$Value = ($Labels == NULL || !isset($Labels[$X])) ? $X + $CountOffset : $Labels[$X];
107
			$this->pChartObject->drawText($XPos, $YPos, $Value, $Settings);
108
		}
109
	}
110
 
111
	/* Write the Y labels */
112
	function writeYLabels(array $Format = [])
113
	{
114
		$R = $this->pChartObject->FontColorR;
115
		$G = $this->pChartObject->FontColorG;
116
		$B = $this->pChartObject->FontColorB;
117
		$Alpha = $this->pChartObject->FontColorA;
118
		$Angle = 0;
119
		$Padding = 5;
120
		$Position = LABEL_POSITION_LEFT;
121
		$Labels = NULL;
122
		$CountOffset = 0;
123
 
124
		/* Override defaults */
125
		extract($Format);
126
 
127
		if ($Labels != NULL && !is_array($Labels)) {
128
			$Labels = [$Labels];
129
		}
130
 
131
		$Y0 = $this->pChartObject->GraphAreaY1;
132
		$YSize = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) / ($this->GridSizeY + 1);
133
		$Settings = ["Angle" => $Angle,"R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha];
134
 
135
		if ($Position == LABEL_POSITION_LEFT) {
136
			$XPos = $this->pChartObject->GraphAreaX1 - $Padding;
137
			$Settings["Align"] = TEXT_ALIGN_MIDDLERIGHT;
138
		} elseif ($Position == LABEL_POSITION_RIGHT) {
139
			$XPos = $this->pChartObject->GraphAreaX2 + $Padding;
140
			$Settings["Align"] = TEXT_ALIGN_MIDDLELEFT;
141
		} else {
142
			return -1;
143
		}
144
 
145
		for ($Y = 0; $Y <= $this->GridSizeY; $Y++) {
146
			$YPos = floor($Y0 + $Y * $YSize + $YSize / 2);
147
			$Value = ($Labels == NULL || !isset($Labels[$Y])) ? $Y + $CountOffset : $Labels[$Y];
148
			$this->pChartObject->drawText($XPos, $YPos, $Value, $Settings);
149
		}
150
	}
151
 
152
	/* Draw the area arround the specified Threshold */
153
	function drawContour($Threshold, array $Format = [])
154
	{
155
		$R = 0;
156
		$G = 0;
157
		$B = 0;
158
		$Alpha = 100;
159
		$Ticks = 3;
160
		$Padding = 0;
161
 
162
		/* Override defaults */
163
		extract($Format);
164
 
165
		$X0 = $this->pChartObject->GraphAreaX1;
166
		$Y0 = $this->pChartObject->GraphAreaY1;
167
		$XSize = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) / ($this->GridSizeX + 1);
168
		$YSize = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) / ($this->GridSizeY + 1);
169
		$Color = ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha,"Ticks" => $Ticks];
170
		for ($X = 0; $X <= $this->GridSizeX; $X++) {
171
			for ($Y = 0; $Y <= $this->GridSizeY; $Y++) {
172
				$Value = $this->Points[$X][$Y];
173
				if ($Value != UNKNOWN && $Value != IGNORED && $Value >= $Threshold) {
174
					$X1 = floor($X0 + $X * $XSize) + $Padding;
175
					$Y1 = floor($Y0 + $Y * $YSize) + $Padding;
176
					$X2 = floor($X0 + $X * $XSize + $XSize);
177
					$Y2 = floor($Y0 + $Y * $YSize + $YSize);
178
					if ($X > 0 && $this->Points[$X - 1][$Y] != UNKNOWN && $this->Points[$X - 1][$Y] != IGNORED && $this->Points[$X - 1][$Y] < $Threshold){
179
						$this->pChartObject->drawLine($X1, $Y1, $X1, $Y2, $Color);
180
					}
181
					if ($Y > 0 && $this->Points[$X][$Y - 1] != UNKNOWN && $this->Points[$X][$Y - 1] != IGNORED && $this->Points[$X][$Y - 1] < $Threshold){
182
						$this->pChartObject->drawLine($X1, $Y1, $X2, $Y1, $Color);
183
					}
184
					if ($X < $this->GridSizeX && $this->Points[$X + 1][$Y] != UNKNOWN && $this->Points[$X + 1][$Y] != IGNORED && $this->Points[$X + 1][$Y] < $Threshold){
185
						$this->pChartObject->drawLine($X2, $Y1, $X2, $Y2, $Color);
186
					}
187
					if ($Y < $this->GridSizeY && $this->Points[$X][$Y + 1] != UNKNOWN && $this->Points[$X][$Y + 1] != IGNORED && $this->Points[$X][$Y + 1] < $Threshold){
188
						$this->pChartObject->drawLine($X1, $Y2, $X2, $Y2, $Color);
189
					}
190
				}
191
			}
192
		}
193
	}
194
 
195
	/* Draw the surface chart */
196
	function drawSurface(array $Format = [])
197
	{
198
		$Palette = NULL;
199
		$ShadeR1 = 77;
200
		$ShadeG1 = 205;
201
		$ShadeB1 = 21;
202
		$ShadeA1 = 40;
203
		$ShadeR2 = 227;
204
		$ShadeG2 = 135;
205
		$ShadeB2 = 61;
206
		$ShadeA2 = 100;
207
		$Border = FALSE;
208
		$BorderR = 0;
209
		$BorderG = 0;
210
		$BorderB = 0;
211
		$Surrounding = -1;
212
		$Padding = 1;
213
 
214
		/* Override defaults */
215
		extract($Format);
216
 
217
		$X0 = $this->pChartObject->GraphAreaX1;
218
		$Y0 = $this->pChartObject->GraphAreaY1;
219
		$XSize = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) / ($this->GridSizeX + 1);
220
		$YSize = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) / ($this->GridSizeY + 1);
221
		for ($X = 0; $X <= $this->GridSizeX; $X++) {
222
			for ($Y = 0; $Y <= $this->GridSizeY; $Y++) {
223
				$Value = $this->Points[$X][$Y];
224
				if ($Value != UNKNOWN && $Value != IGNORED) {
225
 
226
					$X1 = floor($X0 + $X * $XSize) + $Padding;
227
					$Y1 = floor($Y0 + $Y * $YSize) + $Padding;
228
					$X2 = floor($X0 + $X * $XSize + $XSize);
229
					$Y2 = floor($Y0 + $Y * $YSize + $YSize);
230
 
231
					if ($Palette != NULL) {
232
						$R = (isset($Palette[$Value]) && isset($Palette[$Value]["R"])) ? $Palette[$Value]["R"] : 0;
233
						$G = (isset($Palette[$Value]) && isset($Palette[$Value]["G"])) ? $Palette[$Value]["G"] : 0;
234
						$B = (isset($Palette[$Value]) && isset($Palette[$Value]["B"])) ? $Palette[$Value]["B"] : 0;
235
						$Alpha = (isset($Palette[$Value]) && isset($Palette[$Value]["Alpha"])) ? $Palette[$Value]["Alpha"] : 1000;
236
 
237
					} else {
238
						$R = (($ShadeR2 - $ShadeR1) / 100) * $Value + $ShadeR1;
239
						$G = (($ShadeG2 - $ShadeG1) / 100) * $Value + $ShadeG1;
240
						$B = (($ShadeB2 - $ShadeB1) / 100) * $Value + $ShadeB1;
241
						$Alpha = (($ShadeA2 - $ShadeA1) / 100) * $Value + $ShadeA1;
242
					}
243
 
244
					$Settings = ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha];
245
 
246
					if ($Border) {
247
						$Settings["BorderR"] = $BorderR;
248
						$Settings["BorderG"] = $BorderG;
249
						$Settings["BorderB"] = $BorderB;
250
					}
251
 
252
					if ($Surrounding != - 1) {
253
						$Settings["BorderR"] = $R + $Surrounding;
254
						$Settings["BorderG"] = $G + $Surrounding;
255
						$Settings["BorderB"] = $B + $Surrounding;
256
					}
257
 
258
					$this->pChartObject->drawFilledRectangle($X1, $Y1, $X2 - 1, $Y2 - 1, $Settings);
259
				}
260
			}
261
		}
262
	}
263
 
264
	/* Compute the missing points */
265
	function computeMissing()
266
	{
267
		$Missing = [];
268
		for ($X = 0; $X <= $this->GridSizeX; $X++) {
269
			for ($Y = 0; $Y <= $this->GridSizeY; $Y++) {
270
				if ($this->Points[$X][$Y] == UNKNOWN) {
271
					$Missing[] = [$X, $Y];
272
				}
273
			}
274
		}
275
 
276
		shuffle($Missing);
277
		foreach($Missing as $Pos) {
278
			$X = $Pos[0];
279
			$Y = $Pos[1];
280
			if ($this->Points[$X][$Y] == UNKNOWN) {
281
				$NearestNeighbor = $this->getNearestNeighbor($X, $Y);
282
				$Value = 0;
283
				$Points = 0;
284
				for ($Xi = $X - $NearestNeighbor; $Xi <= $X + $NearestNeighbor; $Xi++) {
285
					for ($Yi = $Y - $NearestNeighbor; $Yi <= $Y + $NearestNeighbor; $Yi++) {
286
						if ($Xi >= 0 && $Yi >= 0 && $Xi <= $this->GridSizeX && $Yi <= $this->GridSizeY && $this->Points[$Xi][$Yi] != UNKNOWN && $this->Points[$Xi][$Yi] != IGNORED) {
287
							$Value = $Value + $this->Points[$Xi][$Yi];
288
							$Points++;
289
						}
290
					}
291
				}
292
 
293
				if ($Points != 0) {
294
					$this->Points[$X][$Y] = $Value / $Points;
295
				}
296
			}
297
		}
298
	}
299
 
300
	/* Return the nearest Neighbor distance of a point */
301
	function getNearestNeighbor($Xp, $Yp)
302
	{
303
		$Nearest = UNKNOWN;
304
		for ($X = 0; $X <= $this->GridSizeX; $X++) {
305
			for ($Y = 0; $Y <= $this->GridSizeY; $Y++) {
306
				if ($this->Points[$X][$Y] != UNKNOWN && $this->Points[$X][$Y] != IGNORED) {
307
					$DistanceX = max($Xp, $X) - min($Xp, $X);
308
					$DistanceY = max($Yp, $Y) - min($Yp, $Y);
309
					$Distance = max($DistanceX, $DistanceY);
310
					if ($Distance < $Nearest || $Nearest == UNKNOWN) {
311
						$Nearest = $Distance;
312
					}
313
				}
314
			}
315
		}
316
 
317
		return $Nearest;
318
	}
319
}
320
 
321
?>