Subversion Repositories Applications.gtt

Rev

Rev 61 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
60 jpm 1
<?php
2
/*
3
 * This work is hereby released into the Public Domain.
4
 * To view a copy of the public domain dedication,
5
 * visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
6
 * Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
7
 *
8
 */
9
 
10
require_once dirname(__FILE__)."/Component.class.php";
11
 
12
/**
13
 * A mathematic function
14
 *
15
 * @package Artichow
16
 */
17
class awMathFunction implements awLegendable {
18
 
19
	/**
20
	 * Function line
21
	 *
22
	 * @var Line
23
	 */
24
	public $line;
25
 
26
	/**
27
	 * Marks for your plot
28
	 *
29
	 * @var Mark
30
	 */
31
	public $mark;
32
 
33
	/**
34
	 * Callback function
35
	 *
36
	 * @var string
37
	 */
38
	public $f;
39
 
40
	/**
41
	 * Start the drawing from this value
42
	 *
43
	 * @var float
44
	 */
45
	public $fromX;
46
 
47
	/**
48
	 * Stop the drawing at this value
49
	 *
50
	 * @var float
51
	 */
52
	public $toX;
53
 
54
	/**
55
	 * Line color
56
	 *
57
	 * @var Color
58
	 */
59
	protected $color;
60
 
61
	/**
62
	 * Construct the function
63
	 *
64
	 * @param string $f Callback function
65
	 * @param float $fromX
66
	 * @param float $toX
67
	 */
68
	public function __construct($f, $fromX = NULL, $toX = NULL) {
69
 
70
		$this->f = (string)$f;
71
		$this->fromX = is_null($fromX) ? NULL : (float)$fromX;
72
		$this->toX = is_null($toX) ? NULL : (float)$toX;
73
 
74
		$this->line = new awLine;
75
		$this->mark = new awMark;
76
		$this->color = new awBlack;
77
 
78
	}
79
 
80
	/**
81
	 * Change line color
82
	 *
83
	 * @param awColor $color A new awcolor
84
	 */
85
	public function setColor(awColor $color) {
86
		$this->color = $color;
87
	}
88
 
89
	/**
90
	 * Get line color
91
	 *
92
	 * @return Color
93
	 */
94
	public function getColor() {
95
		return $this->color;
96
	}
97
 
98
	/**
99
	 * Get the background color or gradient of an element of the component
100
	 *
101
	 * @return Color, Gradient
102
	 */
103
	public function getLegendBackground() {
104
	}
105
 
106
	/**
107
	 * Get the line thickness
108
	 *
109
	 * @return NULL
110
	 */
111
	public function getLegendLineThickness() {
112
		return $this->line->getThickness();
113
	}
114
 
115
	/**
116
	 * Get the line type
117
	 *
118
	 * @return NULL
119
	 */
120
	public function getLegendLineStyle() {
121
		return $this->line->getStyle();
122
	}
123
 
124
	/**
125
	 * Get the color of line
126
	 *
127
	 * @return NULL
128
	 */
129
	public function getLegendLineColor() {
130
		return $this->color;
131
	}
132
 
133
	/**
134
	 * Get a mark object
135
	 *
136
	 * @return NULL
137
	 */
138
	public function getLegendMark() {
139
		return $this->mark;
140
	}
141
 
142
}
143
 
144
registerClass('MathFunction');
145
 
146
/**
147
 * For mathematics functions
148
 *
149
 * @package Artichow
150
 */
151
class awMathPlot extends awComponent {
152
 
153
	/**
154
	 * Functions
155
	 *
156
	 * @var array
157
	 */
158
	protected $functions = array();
159
 
160
	/**
161
	 * Grid properties
162
	 *
163
	 * @var Grid
164
	 */
165
	public $grid;
166
 
167
	/**
168
	 * X axis
169
	 *
170
	 * @var Axis
171
	 */
172
	public $xAxis;
173
 
174
	/**
175
	 * Y axis
176
	 *
177
	 * @var Axis
178
	 */
179
	public $yAxis;
180
 
181
	/**
182
	 * Extremum
183
	 *
184
	 * @var Side
185
	 */
186
	private $extremum = NULL;
187
 
188
	/**
189
	 * Interval
190
	 *
191
	 * @var float
192
	 */
193
	private $interval = 1;
194
 
195
	/**
196
	 * Build the plot
197
	 *
198
	 * @param int $xMin Minimum X value
199
	 * @param int $xMax Maximum X value
200
	 * @param int $yMax Maximum Y value
201
	 * @param int $yMin Minimum Y value
202
	 */
203
	public function __construct($xMin, $xMax, $yMax, $yMin) {
204
 
205
		parent::__construct();
206
 
207
		$this->setPadding(8, 8, 8, 8);
208
 
209
		$this->grid = new awGrid;
210
 
211
		// Hide grid by default
212
		$this->grid->hide(TRUE);
213
 
214
		// Set extremum
215
		$this->extremum = new awSide($xMin, $xMax, $yMax, $yMin);
216
 
217
		// Create axis
218
		$this->xAxis = new awAxis;
219
		$this->xAxis->setTickStyle(awTick::IN);
220
		$this->xAxis->label->hideValue(0);
221
		$this->initAxis($this->xAxis);
222
 
223
		$this->yAxis = new awAxis;
224
		$this->yAxis->setTickStyle(awTick::IN);
225
		$this->yAxis->label->hideValue(0);
226
		$this->initAxis($this->yAxis);
227
 
228
	}
229
 
230
	protected function initAxis(awAxis $axis) {
231
 
232
		$axis->setLabelPrecision(1);
233
		$axis->addTick('major', new awTick(0, 5));
234
		$axis->addTick('minor', new awTick(0, 3));
235
		$axis->addTick('micro', new awTick(0, 1));
236
		$axis->setNumberByTick('minor', 'major', 1);
237
		$axis->setNumberByTick('micro', 'minor', 4);
238
		$axis->label->setFont(new awTuffy(7));
239
 
240
	}
241
 
242
	/**
243
	 * Interval to calculate values
244
	 *
245
	 * @param float $interval
246
	 */
247
	public function setInterval($interval) {
248
		$this->interval = (float)$interval;
249
	}
250
 
251
	/**
252
	 * Add a formula f(x)
253
	 *
254
	 * @param awMathFunction $function
255
	 * @param string $name Name for the legend (can be NULL if you don't want to set a legend)
256
	 * @param int $type Type for the legend
257
	 */
258
	public function add(awMathFunction $function, $name = NULL, $type = awLegend::LINE) {
259
 
260
		$this->functions[] = $function;
261
 
262
		if($name !== NULL) {
263
			$this->legend->add($function, $name, $type);
264
		}
265
 
266
	}
267
 
268
	public function init(awDriver $driver) {
269
 
270
		list($x1, $y1, $x2, $y2) = $this->getPosition();
271
 
272
		$this->xAxis->line->setX($x1, $x2);
273
		$this->xAxis->label->setAlign(NULL, awLabel::BOTTOM);
274
		$this->xAxis->label->move(0, 3);
275
		$this->xAxis->setRange($this->extremum->left, $this->extremum->right);
276
 
277
		$this->yAxis->line->setY($y2, $y1);
278
		$this->yAxis->label->setAlign(awLabel::RIGHT);
279
		$this->yAxis->label->move(-6, 0);
280
		$this->yAxis->reverseTickStyle();
281
		$this->yAxis->setRange($this->extremum->bottom, $this->extremum->top);
282
 
283
 
284
		$this->xAxis->setYCenter($this->yAxis, 0);
285
		$this->yAxis->setXCenter($this->xAxis, 0);
286
 
287
		if($this->yAxis->getLabelNumber() === NULL) {
288
			$number = $this->extremum->top - $this->extremum->bottom + 1;
289
			$this->yAxis->setLabelNumber($number);
290
		}
291
 
292
		if($this->xAxis->getLabelNumber() === NULL) {
293
			$number = $this->extremum->right - $this->extremum->left + 1;
294
			$this->xAxis->setLabelNumber($number);
295
		}
296
 
297
		// Set ticks
298
 
299
		$this->xAxis->tick('major')->setNumber($this->xAxis->getLabelNumber());
300
		$this->yAxis->tick('major')->setNumber($this->yAxis->getLabelNumber());
301
 
302
 
303
		// Set axis labels
304
		$labels = array();
305
		for($i = 0, $count = $this->xAxis->getLabelNumber(); $i < $count; $i++) {
306
			$labels[] = $i;
307
		}
308
		$this->xAxis->label->set($labels);
309
 
310
		$labels = array();
311
		for($i = 0, $count = $this->yAxis->getLabelNumber(); $i < $count; $i++) {
312
			$labels[] = $i;
313
		}
314
		$this->yAxis->label->set($labels);
315
 
316
		parent::init($driver);
317
 
318
		// Create the grid
319
		$this->createGrid();
320
 
321
		// Draw the grid
322
		$this->grid->draw($driver, $x1, $y1, $x2, $y2);
323
 
324
	}
325
 
326
	public function drawEnvelope(awDriver $driver) {
327
 
328
		// Draw axis
329
		$this->xAxis->draw($driver);
330
		$this->yAxis->draw($driver);
331
 
332
	}
333
 
334
	public function drawComponent(awDriver $driver, $x1, $y1, $x2, $y2, $aliasing) {
335
 
336
		foreach($this->functions as $function) {
337
 
338
			$f = $function->f;
339
			$fromX = is_null($function->fromX) ? $this->extremum->left : $function->fromX;
340
			$toX = is_null($function->toX) ? $this->extremum->right : $function->toX;
341
 
342
			$old = NULL;
343
 
344
			for($i = $fromX; $i <= $toX; $i += $this->interval) {
345
 
346
				$p = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($i, $f($i)));
347
 
348
				if($p->y >= $y1 and $p->y <= $y2) {
349
					$function->mark->draw($driver, $p);
350
				}
351
 
352
				if($old !== NULL) {
353
 
354
					$line = $function->line;
355
					$line->setLocation($old, $p);
356
 
357
					if(
358
						($line->p1->y >= $y1 and $line->p1->y <= $y2) or
359
						($line->p2->y >= $y1 and $line->p2->y <= $y2)
360
					) {
361
						$driver->line(
362
							$function->getColor(),
363
							$line
364
						);
365
					}
366
 
367
				}
368
 
369
				$old = $p;
370
 
371
			}
372
 
373
			// Draw last point if needed
374
			if($old !== NULL and $i - $this->interval != $toX) {
375
 
376
				$p = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($toX, $f($toX)));
377
 
378
				if($p->y >= $y1 and $p->y <= $y2) {
379
					$function->mark->draw($driver, $p);
380
				}
381
 
382
 
383
				$line = $function->line;
384
				$line->setLocation($old, $p);
385
 
386
				if(
387
					($line->p1->y >= $y1 and $line->p1->y <= $y2) or
388
					($line->p2->y >= $y1 and $line->p2->y <= $y2)
389
				) {
390
					$driver->line(
391
						$function->getColor(),
392
						$line
393
					);
394
				}
395
 
396
			}
397
 
398
		}
399
 
400
	}
401
 
402
	protected function createGrid() {
403
 
404
		// Horizontal lines of the grid
405
 
406
		$major = $this->yAxis->tick('major');
407
		$interval = $major->getInterval();
408
		$number = $this->yAxis->getLabelNumber() - 1;
409
 
410
		$h = array();
411
		if($number > 0) {
412
			for($i = 0; $i <= $number; $i++) {
413
				$h[] = $i / $number;
414
			}
415
		}
416
 
417
		// Vertical lines
418
 
419
		$major = $this->xAxis->tick('major');
420
		$interval = $major->getInterval();
421
		$number = $this->xAxis->getLabelNumber() - 1;
422
 
423
		$w = array();
424
		if($number > 0) {
425
			for($i = 0; $i <= $number; $i++) {
426
				if($i%$interval === 0) {
427
					$w[] = $i / $number;
428
				}
429
			}
430
		}
431
 
432
		$this->grid->setGrid($w, $h);
433
 
434
	}
435
 
436
}
437
 
438
registerClass('MathPlot');
439
?>