1 |
aurelien |
1 |
<?php
|
|
|
2 |
//=======================================================================
|
|
|
3 |
// File: JPGRAPH_PLOTBAND.PHP
|
|
|
4 |
// Description: PHP4 Graph Plotting library. Extension module.
|
|
|
5 |
// Created: 2004-02-18
|
|
|
6 |
// Ver: $Id: jpgraph_plotband.php 782 2006-10-08 08:09:02Z ljp $
|
|
|
7 |
//
|
|
|
8 |
// Copyright (c) Aditus Consulting. All rights reserved.
|
|
|
9 |
//========================================================================
|
|
|
10 |
|
|
|
11 |
// Constants for types of static bands in plot area
|
|
|
12 |
DEFINE("BAND_RDIAG",1); // Right diagonal lines
|
|
|
13 |
DEFINE("BAND_LDIAG",2); // Left diagonal lines
|
|
|
14 |
DEFINE("BAND_SOLID",3); // Solid one color
|
|
|
15 |
DEFINE("BAND_VLINE",4); // Vertical lines
|
|
|
16 |
DEFINE("BAND_HLINE",5); // Horizontal lines
|
|
|
17 |
DEFINE("BAND_3DPLANE",6); // "3D" Plane
|
|
|
18 |
DEFINE("BAND_HVCROSS",7); // Vertical/Hor crosses
|
|
|
19 |
DEFINE("BAND_DIAGCROSS",8); // Diagonal crosses
|
|
|
20 |
|
|
|
21 |
|
|
|
22 |
// Utility class to hold coordinates for a rectangle
|
|
|
23 |
class Rectangle {
|
|
|
24 |
var $x,$y,$w,$h;
|
|
|
25 |
var $xe, $ye;
|
|
|
26 |
function Rectangle($aX,$aY,$aWidth,$aHeight) {
|
|
|
27 |
$this->x=$aX;
|
|
|
28 |
$this->y=$aY;
|
|
|
29 |
$this->w=$aWidth;
|
|
|
30 |
$this->h=$aHeight;
|
|
|
31 |
$this->xe=$aX+$aWidth-1;
|
|
|
32 |
$this->ye=$aY+$aHeight-1;
|
|
|
33 |
}
|
|
|
34 |
}
|
|
|
35 |
|
|
|
36 |
//=====================================================================
|
|
|
37 |
// Class RectPattern
|
|
|
38 |
// Base class for pattern hierarchi that is used to display patterned
|
|
|
39 |
// bands on the graph. Any subclass that doesn't override Stroke()
|
|
|
40 |
// must at least implement method DoPattern(&$aImg) which is responsible
|
|
|
41 |
// for drawing the pattern onto the graph.
|
|
|
42 |
//=====================================================================
|
|
|
43 |
class RectPattern {
|
|
|
44 |
var $color;
|
|
|
45 |
var $weight;
|
|
|
46 |
var $rect=null;
|
|
|
47 |
var $doframe=true;
|
|
|
48 |
var $linespacing; // Line spacing in pixels
|
|
|
49 |
var $iBackgroundColor=-1; // Default is no background fill
|
|
|
50 |
|
|
|
51 |
function RectPattern($aColor,$aWeight=1) {
|
|
|
52 |
$this->color = $aColor;
|
|
|
53 |
$this->weight = $aWeight;
|
|
|
54 |
}
|
|
|
55 |
|
|
|
56 |
function SetBackground($aBackgroundColor) {
|
|
|
57 |
$this->iBackgroundColor=$aBackgroundColor;
|
|
|
58 |
}
|
|
|
59 |
|
|
|
60 |
function SetPos(&$aRect) {
|
|
|
61 |
$this->rect = $aRect;
|
|
|
62 |
}
|
|
|
63 |
|
|
|
64 |
function ShowFrame($aShow=true) {
|
|
|
65 |
$this->doframe=$aShow;
|
|
|
66 |
}
|
|
|
67 |
|
|
|
68 |
function SetDensity($aDens) {
|
|
|
69 |
if( $aDens < 1 || $aDens > 100 )
|
|
|
70 |
JpGraphError::RaiseL(16001,$aDens);
|
|
|
71 |
//(" Desity for pattern must be between 1 and 100. (You tried $aDens)");
|
|
|
72 |
// 1% corresponds to linespacing=50
|
|
|
73 |
// 100 % corresponds to linespacing 1
|
|
|
74 |
$this->linespacing = floor(((100-$aDens)/100.0)*50)+1;
|
|
|
75 |
|
|
|
76 |
}
|
|
|
77 |
|
|
|
78 |
function Stroke(&$aImg) {
|
|
|
79 |
if( $this->rect == null )
|
|
|
80 |
JpGraphError::RaiseL(16002);
|
|
|
81 |
//(" No positions specified for pattern.");
|
|
|
82 |
|
|
|
83 |
if( !(is_numeric($this->iBackgroundColor) && $this->iBackgroundColor==-1) ) {
|
|
|
84 |
$aImg->SetColor($this->iBackgroundColor);
|
|
|
85 |
$aImg->FilledRectangle($this->rect->x,$this->rect->y,$this->rect->xe,$this->rect->ye);
|
|
|
86 |
}
|
|
|
87 |
|
|
|
88 |
$aImg->SetColor($this->color);
|
|
|
89 |
$aImg->SetLineWeight($this->weight);
|
|
|
90 |
|
|
|
91 |
// Virtual function implemented by subclass
|
|
|
92 |
$this->DoPattern($aImg);
|
|
|
93 |
|
|
|
94 |
// Frame around the pattern area
|
|
|
95 |
if( $this->doframe )
|
|
|
96 |
$aImg->Rectangle($this->rect->x,$this->rect->y,$this->rect->xe,$this->rect->ye);
|
|
|
97 |
}
|
|
|
98 |
|
|
|
99 |
}
|
|
|
100 |
|
|
|
101 |
|
|
|
102 |
//=====================================================================
|
|
|
103 |
// Class RectPatternSolid
|
|
|
104 |
// Implements a solid band
|
|
|
105 |
//=====================================================================
|
|
|
106 |
class RectPatternSolid extends RectPattern {
|
|
|
107 |
|
|
|
108 |
function RectPatternSolid($aColor="black",$aWeight=1) {
|
|
|
109 |
parent::RectPattern($aColor,$aWeight);
|
|
|
110 |
}
|
|
|
111 |
|
|
|
112 |
function DoPattern(&$aImg) {
|
|
|
113 |
$aImg->SetColor($this->color);
|
|
|
114 |
$aImg->FilledRectangle($this->rect->x,$this->rect->y,
|
|
|
115 |
$this->rect->xe,$this->rect->ye);
|
|
|
116 |
}
|
|
|
117 |
}
|
|
|
118 |
|
|
|
119 |
//=====================================================================
|
|
|
120 |
// Class RectPatternHor
|
|
|
121 |
// Implements horizontal line pattern
|
|
|
122 |
//=====================================================================
|
|
|
123 |
class RectPatternHor extends RectPattern {
|
|
|
124 |
|
|
|
125 |
function RectPatternHor($aColor="black",$aWeight=1,$aLineSpacing=7) {
|
|
|
126 |
parent::RectPattern($aColor,$aWeight);
|
|
|
127 |
$this->linespacing = $aLineSpacing;
|
|
|
128 |
}
|
|
|
129 |
|
|
|
130 |
function DoPattern(&$aImg) {
|
|
|
131 |
$x0 = $this->rect->x;
|
|
|
132 |
$x1 = $this->rect->xe;
|
|
|
133 |
$y = $this->rect->y;
|
|
|
134 |
while( $y < $this->rect->ye ) {
|
|
|
135 |
$aImg->Line($x0,$y,$x1,$y);
|
|
|
136 |
$y += $this->linespacing;
|
|
|
137 |
}
|
|
|
138 |
}
|
|
|
139 |
}
|
|
|
140 |
|
|
|
141 |
//=====================================================================
|
|
|
142 |
// Class RectPatternVert
|
|
|
143 |
// Implements vertical line pattern
|
|
|
144 |
//=====================================================================
|
|
|
145 |
class RectPatternVert extends RectPattern {
|
|
|
146 |
var $linespacing=10; // Line spacing in pixels
|
|
|
147 |
|
|
|
148 |
function RectPatternVert($aColor="black",$aWeight=1,$aLineSpacing=7) {
|
|
|
149 |
parent::RectPattern($aColor,$aWeight);
|
|
|
150 |
$this->linespacing = $aLineSpacing;
|
|
|
151 |
}
|
|
|
152 |
|
|
|
153 |
//--------------------
|
|
|
154 |
// Private methods
|
|
|
155 |
//
|
|
|
156 |
function DoPattern(&$aImg) {
|
|
|
157 |
$x = $this->rect->x;
|
|
|
158 |
$y0 = $this->rect->y;
|
|
|
159 |
$y1 = $this->rect->ye;
|
|
|
160 |
while( $x < $this->rect->xe ) {
|
|
|
161 |
$aImg->Line($x,$y0,$x,$y1);
|
|
|
162 |
$x += $this->linespacing;
|
|
|
163 |
}
|
|
|
164 |
}
|
|
|
165 |
}
|
|
|
166 |
|
|
|
167 |
|
|
|
168 |
//=====================================================================
|
|
|
169 |
// Class RectPatternRDiag
|
|
|
170 |
// Implements right diagonal pattern
|
|
|
171 |
//=====================================================================
|
|
|
172 |
class RectPatternRDiag extends RectPattern {
|
|
|
173 |
var $linespacing; // Line spacing in pixels
|
|
|
174 |
|
|
|
175 |
function RectPatternRDiag($aColor="black",$aWeight=1,$aLineSpacing=12) {
|
|
|
176 |
parent::RectPattern($aColor,$aWeight);
|
|
|
177 |
$this->linespacing = $aLineSpacing;
|
|
|
178 |
}
|
|
|
179 |
|
|
|
180 |
function DoPattern(&$aImg) {
|
|
|
181 |
// --------------------
|
|
|
182 |
// | / / / / /|
|
|
|
183 |
// |/ / / / / |
|
|
|
184 |
// | / / / / |
|
|
|
185 |
// --------------------
|
|
|
186 |
$xe = $this->rect->xe;
|
|
|
187 |
$ye = $this->rect->ye;
|
|
|
188 |
$x0 = $this->rect->x + round($this->linespacing/2);
|
|
|
189 |
$y0 = $this->rect->y;
|
|
|
190 |
$x1 = $this->rect->x;
|
|
|
191 |
$y1 = $this->rect->y + round($this->linespacing/2);
|
|
|
192 |
|
|
|
193 |
while($x0<=$xe && $y1<=$ye) {
|
|
|
194 |
$aImg->Line($x0,$y0,$x1,$y1);
|
|
|
195 |
$x0 += $this->linespacing;
|
|
|
196 |
$y1 += $this->linespacing;
|
|
|
197 |
}
|
|
|
198 |
|
|
|
199 |
if( $xe-$x1 > $ye-$y0 ) {
|
|
|
200 |
// Width larger than height
|
|
|
201 |
$x1 = $this->rect->x + ($y1-$ye);
|
|
|
202 |
$y1 = $ye;
|
|
|
203 |
$y0 = $this->rect->y;
|
|
|
204 |
while( $x0 <= $xe ) {
|
|
|
205 |
$aImg->Line($x0,$y0,$x1,$y1);
|
|
|
206 |
$x0 += $this->linespacing;
|
|
|
207 |
$x1 += $this->linespacing;
|
|
|
208 |
}
|
|
|
209 |
|
|
|
210 |
$y0=$this->rect->y + ($x0-$xe);
|
|
|
211 |
$x0=$xe;
|
|
|
212 |
}
|
|
|
213 |
else {
|
|
|
214 |
// Height larger than width
|
|
|
215 |
$diff = $x0-$xe;
|
|
|
216 |
$y0 = $diff+$this->rect->y;
|
|
|
217 |
$x0 = $xe;
|
|
|
218 |
$x1 = $this->rect->x;
|
|
|
219 |
while( $y1 <= $ye ) {
|
|
|
220 |
$aImg->Line($x0,$y0,$x1,$y1);
|
|
|
221 |
$y1 += $this->linespacing;
|
|
|
222 |
$y0 += $this->linespacing;
|
|
|
223 |
}
|
|
|
224 |
|
|
|
225 |
$diff = $y1-$ye;
|
|
|
226 |
$y1 = $ye;
|
|
|
227 |
$x1 = $diff + $this->rect->x;
|
|
|
228 |
}
|
|
|
229 |
|
|
|
230 |
while( $y0 <= $ye ) {
|
|
|
231 |
$aImg->Line($x0,$y0,$x1,$y1);
|
|
|
232 |
$y0 += $this->linespacing;
|
|
|
233 |
$x1 += $this->linespacing;
|
|
|
234 |
}
|
|
|
235 |
}
|
|
|
236 |
}
|
|
|
237 |
|
|
|
238 |
//=====================================================================
|
|
|
239 |
// Class RectPatternLDiag
|
|
|
240 |
// Implements left diagonal pattern
|
|
|
241 |
//=====================================================================
|
|
|
242 |
class RectPatternLDiag extends RectPattern {
|
|
|
243 |
var $linespacing; // Line spacing in pixels
|
|
|
244 |
|
|
|
245 |
function RectPatternLDiag($aColor="black",$aWeight=1,$aLineSpacing=12) {
|
|
|
246 |
$this->linespacing = $aLineSpacing;
|
|
|
247 |
parent::RectPattern($aColor,$aWeight);
|
|
|
248 |
}
|
|
|
249 |
|
|
|
250 |
function DoPattern(&$aImg) {
|
|
|
251 |
// --------------------
|
|
|
252 |
// |\ \ \ \ \ |
|
|
|
253 |
// | \ \ \ \ \|
|
|
|
254 |
// | \ \ \ \ |
|
|
|
255 |
// |------------------|
|
|
|
256 |
$xe = $this->rect->xe;
|
|
|
257 |
$ye = $this->rect->ye;
|
|
|
258 |
$x0 = $this->rect->x + round($this->linespacing/2);
|
|
|
259 |
$y0 = $this->rect->ye;
|
|
|
260 |
$x1 = $this->rect->x;
|
|
|
261 |
$y1 = $this->rect->ye - round($this->linespacing/2);
|
|
|
262 |
|
|
|
263 |
while($x0<=$xe && $y1>=$this->rect->y) {
|
|
|
264 |
$aImg->Line($x0,$y0,$x1,$y1);
|
|
|
265 |
$x0 += $this->linespacing;
|
|
|
266 |
$y1 -= $this->linespacing;
|
|
|
267 |
}
|
|
|
268 |
if( $xe-$x1 > $ye-$this->rect->y ) {
|
|
|
269 |
// Width larger than height
|
|
|
270 |
$x1 = $this->rect->x + ($this->rect->y-$y1);
|
|
|
271 |
$y0=$ye; $y1=$this->rect->y;
|
|
|
272 |
while( $x0 <= $xe ) {
|
|
|
273 |
$aImg->Line($x0,$y0,$x1,$y1);
|
|
|
274 |
$x0 += $this->linespacing;
|
|
|
275 |
$x1 += $this->linespacing;
|
|
|
276 |
}
|
|
|
277 |
|
|
|
278 |
$y0=$this->rect->ye - ($x0-$xe);
|
|
|
279 |
$x0=$xe;
|
|
|
280 |
}
|
|
|
281 |
else {
|
|
|
282 |
// Height larger than width
|
|
|
283 |
$diff = $x0-$xe;
|
|
|
284 |
$y0 = $ye-$diff;
|
|
|
285 |
$x0 = $xe;
|
|
|
286 |
while( $y1 >= $this->rect->y ) {
|
|
|
287 |
$aImg->Line($x0,$y0,$x1,$y1);
|
|
|
288 |
$y0 -= $this->linespacing;
|
|
|
289 |
$y1 -= $this->linespacing;
|
|
|
290 |
}
|
|
|
291 |
$diff = $this->rect->y - $y1;
|
|
|
292 |
$x1 = $this->rect->x + $diff;
|
|
|
293 |
$y1 = $this->rect->y;
|
|
|
294 |
}
|
|
|
295 |
while( $y0 >= $this->rect->y ) {
|
|
|
296 |
$aImg->Line($x0,$y0,$x1,$y1);
|
|
|
297 |
$y0 -= $this->linespacing;
|
|
|
298 |
$x1 += $this->linespacing;
|
|
|
299 |
}
|
|
|
300 |
}
|
|
|
301 |
}
|
|
|
302 |
|
|
|
303 |
//=====================================================================
|
|
|
304 |
// Class RectPattern3DPlane
|
|
|
305 |
// Implements "3D" plane pattern
|
|
|
306 |
//=====================================================================
|
|
|
307 |
class RectPattern3DPlane extends RectPattern {
|
|
|
308 |
var $alpha=50; // Parameter that specifies the distance
|
|
|
309 |
// to "simulated" horizon in pixel from the
|
|
|
310 |
// top of the band. Specifies how fast the lines
|
|
|
311 |
// converge.
|
|
|
312 |
|
|
|
313 |
function RectPattern3DPlane($aColor="black",$aWeight=1) {
|
|
|
314 |
parent::RectPattern($aColor,$aWeight);
|
|
|
315 |
$this->SetDensity(10); // Slightly larger default
|
|
|
316 |
}
|
|
|
317 |
|
|
|
318 |
function SetHorizon($aHorizon) {
|
|
|
319 |
$this->alpha=$aHorizon;
|
|
|
320 |
}
|
|
|
321 |
|
|
|
322 |
function DoPattern(&$aImg) {
|
|
|
323 |
// "Fake" a nice 3D grid-effect.
|
|
|
324 |
$x0 = $this->rect->x + $this->rect->w/2;
|
|
|
325 |
$y0 = $this->rect->y;
|
|
|
326 |
$x1 = $x0;
|
|
|
327 |
$y1 = $this->rect->ye;
|
|
|
328 |
$x0_right = $x0;
|
|
|
329 |
$x1_right = $x1;
|
|
|
330 |
|
|
|
331 |
// BTW "apa" means monkey in Swedish but is really a shortform for
|
|
|
332 |
// "alpha+a" which was the labels I used on paper when I derived the
|
|
|
333 |
// geometric to get the 3D perspective right.
|
|
|
334 |
// $apa is the height of the bounding rectangle plus the distance to the
|
|
|
335 |
// artifical horizon (alpha)
|
|
|
336 |
$apa = $this->rect->h + $this->alpha;
|
|
|
337 |
|
|
|
338 |
// Three cases and three loops
|
|
|
339 |
// 1) The endpoint of the line ends on the bottom line
|
|
|
340 |
// 2) The endpoint ends on the side
|
|
|
341 |
// 3) Horizontal lines
|
|
|
342 |
|
|
|
343 |
// Endpoint falls on bottom line
|
|
|
344 |
$middle=$this->rect->x + $this->rect->w/2;
|
|
|
345 |
$dist=$this->linespacing;
|
|
|
346 |
$factor=$this->alpha /($apa);
|
|
|
347 |
while($x1>$this->rect->x) {
|
|
|
348 |
$aImg->Line($x0,$y0,$x1,$y1);
|
|
|
349 |
$aImg->Line($x0_right,$y0,$x1_right,$y1);
|
|
|
350 |
$x1 = $middle - $dist;
|
|
|
351 |
$x0 = $middle - $dist * $factor;
|
|
|
352 |
$x1_right = $middle + $dist;
|
|
|
353 |
$x0_right = $middle + $dist * $factor;
|
|
|
354 |
$dist += $this->linespacing;
|
|
|
355 |
}
|
|
|
356 |
|
|
|
357 |
// Endpoint falls on sides
|
|
|
358 |
$dist -= $this->linespacing;
|
|
|
359 |
$d=$this->rect->w/2;
|
|
|
360 |
$c = $apa - $d*$apa/$dist;
|
|
|
361 |
while( $x0>$this->rect->x ) {
|
|
|
362 |
$aImg->Line($x0,$y0,$this->rect->x,$this->rect->ye-$c);
|
|
|
363 |
$aImg->Line($x0_right,$y0,$this->rect->xe,$this->rect->ye-$c);
|
|
|
364 |
$dist += $this->linespacing;
|
|
|
365 |
$x0 = $middle - $dist * $factor;
|
|
|
366 |
$x1 = $middle - $dist;
|
|
|
367 |
$x0_right = $middle + $dist * $factor;
|
|
|
368 |
$c = $apa - $d*$apa/$dist;
|
|
|
369 |
}
|
|
|
370 |
|
|
|
371 |
// Horizontal lines
|
|
|
372 |
// They need some serious consideration since they are a function
|
|
|
373 |
// of perspective depth (alpha) and density (linespacing)
|
|
|
374 |
$x0=$this->rect->x;
|
|
|
375 |
$x1=$this->rect->xe;
|
|
|
376 |
$y=$this->rect->ye;
|
|
|
377 |
|
|
|
378 |
// The first line is drawn directly. Makes the loop below slightly
|
|
|
379 |
// more readable.
|
|
|
380 |
$aImg->Line($x0,$y,$x1,$y);
|
|
|
381 |
$hls = $this->linespacing;
|
|
|
382 |
|
|
|
383 |
// A correction factor for vertical "brick" line spacing to account for
|
|
|
384 |
// a) the difference in number of pixels hor vs vert
|
|
|
385 |
// b) visual apperance to make the first layer of "bricks" look more
|
|
|
386 |
// square.
|
|
|
387 |
$vls = $this->linespacing*0.6;
|
|
|
388 |
|
|
|
389 |
$ds = $hls*($apa-$vls)/$apa;
|
|
|
390 |
// Get the slope for the "perspective line" going from bottom right
|
|
|
391 |
// corner to top left corner of the "first" brick.
|
|
|
392 |
|
|
|
393 |
// Uncomment the following lines if you want to get a visual understanding
|
|
|
394 |
// of what this helpline does. BTW this mimics the way you would get the
|
|
|
395 |
// perspective right when drawing on paper.
|
|
|
396 |
/*
|
|
|
397 |
$x0 = $middle;
|
|
|
398 |
$y0 = $this->rect->ye;
|
|
|
399 |
$len=floor(($this->rect->ye-$this->rect->y)/$vls);
|
|
|
400 |
$x1 = $middle+round($len*$ds);
|
|
|
401 |
$y1 = $this->rect->ye-$len*$vls;
|
|
|
402 |
$aImg->PushColor("red");
|
|
|
403 |
$aImg->Line($x0,$y0,$x1,$y1);
|
|
|
404 |
$aImg->PopColor();
|
|
|
405 |
*/
|
|
|
406 |
|
|
|
407 |
$y -= $vls;
|
|
|
408 |
$k=($this->rect->ye-($this->rect->ye-$vls))/($middle-($middle-$ds));
|
|
|
409 |
$dist = $hls;
|
|
|
410 |
while( $y>$this->rect->y ) {
|
|
|
411 |
$aImg->Line($this->rect->x,$y,$this->rect->xe,$y);
|
|
|
412 |
$adj = $k*$dist/(1+$dist*$k/$apa);
|
|
|
413 |
if( $adj < 2 ) $adj=1;
|
|
|
414 |
$y = $this->rect->ye - round($adj);
|
|
|
415 |
$dist += $hls;
|
|
|
416 |
}
|
|
|
417 |
}
|
|
|
418 |
}
|
|
|
419 |
|
|
|
420 |
//=====================================================================
|
|
|
421 |
// Class RectPatternCross
|
|
|
422 |
// Vert/Hor crosses
|
|
|
423 |
//=====================================================================
|
|
|
424 |
class RectPatternCross extends RectPattern {
|
|
|
425 |
var $vert=null;
|
|
|
426 |
var $hor=null;
|
|
|
427 |
function RectPatternCross($aColor="black",$aWeight=1) {
|
|
|
428 |
parent::RectPattern($aColor,$aWeight);
|
|
|
429 |
$this->vert = new RectPatternVert($aColor,$aWeight);
|
|
|
430 |
$this->hor = new RectPatternHor($aColor,$aWeight);
|
|
|
431 |
}
|
|
|
432 |
|
|
|
433 |
function SetOrder($aDepth) {
|
|
|
434 |
$this->vert->SetOrder($aDepth);
|
|
|
435 |
$this->hor->SetOrder($aDepth);
|
|
|
436 |
}
|
|
|
437 |
|
|
|
438 |
function SetPos(&$aRect) {
|
|
|
439 |
parent::SetPos($aRect);
|
|
|
440 |
$this->vert->SetPos($aRect);
|
|
|
441 |
$this->hor->SetPos($aRect);
|
|
|
442 |
}
|
|
|
443 |
|
|
|
444 |
function SetDensity($aDens) {
|
|
|
445 |
$this->vert->SetDensity($aDens);
|
|
|
446 |
$this->hor->SetDensity($aDens);
|
|
|
447 |
}
|
|
|
448 |
|
|
|
449 |
function DoPattern(&$aImg) {
|
|
|
450 |
$this->vert->DoPattern($aImg);
|
|
|
451 |
$this->hor->DoPattern($aImg);
|
|
|
452 |
}
|
|
|
453 |
}
|
|
|
454 |
|
|
|
455 |
//=====================================================================
|
|
|
456 |
// Class RectPatternDiagCross
|
|
|
457 |
// Vert/Hor crosses
|
|
|
458 |
//=====================================================================
|
|
|
459 |
|
|
|
460 |
class RectPatternDiagCross extends RectPattern {
|
|
|
461 |
var $left=null;
|
|
|
462 |
var $right=null;
|
|
|
463 |
function RectPatternDiagCross($aColor="black",$aWeight=1) {
|
|
|
464 |
parent::RectPattern($aColor,$aWeight);
|
|
|
465 |
$this->right = new RectPatternRDiag($aColor,$aWeight);
|
|
|
466 |
$this->left = new RectPatternLDiag($aColor,$aWeight);
|
|
|
467 |
}
|
|
|
468 |
|
|
|
469 |
function SetOrder($aDepth) {
|
|
|
470 |
$this->left->SetOrder($aDepth);
|
|
|
471 |
$this->right->SetOrder($aDepth);
|
|
|
472 |
}
|
|
|
473 |
|
|
|
474 |
function SetPos(&$aRect) {
|
|
|
475 |
parent::SetPos($aRect);
|
|
|
476 |
$this->left->SetPos($aRect);
|
|
|
477 |
$this->right->SetPos($aRect);
|
|
|
478 |
}
|
|
|
479 |
|
|
|
480 |
function SetDensity($aDens) {
|
|
|
481 |
$this->left->SetDensity($aDens);
|
|
|
482 |
$this->right->SetDensity($aDens);
|
|
|
483 |
}
|
|
|
484 |
|
|
|
485 |
function DoPattern(&$aImg) {
|
|
|
486 |
$this->left->DoPattern($aImg);
|
|
|
487 |
$this->right->DoPattern($aImg);
|
|
|
488 |
}
|
|
|
489 |
|
|
|
490 |
}
|
|
|
491 |
|
|
|
492 |
//=====================================================================
|
|
|
493 |
// Class RectPatternFactory
|
|
|
494 |
// Factory class for rectangular pattern
|
|
|
495 |
//=====================================================================
|
|
|
496 |
class RectPatternFactory {
|
|
|
497 |
function RectPatternFactory() {
|
|
|
498 |
// Empty
|
|
|
499 |
}
|
|
|
500 |
function Create($aPattern,$aColor,$aWeight=1) {
|
|
|
501 |
switch($aPattern) {
|
|
|
502 |
case BAND_RDIAG:
|
|
|
503 |
$obj = new RectPatternRDiag($aColor,$aWeight);
|
|
|
504 |
break;
|
|
|
505 |
case BAND_LDIAG:
|
|
|
506 |
$obj = new RectPatternLDiag($aColor,$aWeight);
|
|
|
507 |
break;
|
|
|
508 |
case BAND_SOLID:
|
|
|
509 |
$obj = new RectPatternSolid($aColor,$aWeight);
|
|
|
510 |
break;
|
|
|
511 |
case BAND_VLINE:
|
|
|
512 |
$obj = new RectPatternVert($aColor,$aWeight);
|
|
|
513 |
break;
|
|
|
514 |
case BAND_HLINE:
|
|
|
515 |
$obj = new RectPatternHor($aColor,$aWeight);
|
|
|
516 |
break;
|
|
|
517 |
case BAND_3DPLANE:
|
|
|
518 |
$obj = new RectPattern3DPlane($aColor,$aWeight);
|
|
|
519 |
break;
|
|
|
520 |
case BAND_HVCROSS:
|
|
|
521 |
$obj = new RectPatternCross($aColor,$aWeight);
|
|
|
522 |
break;
|
|
|
523 |
case BAND_DIAGCROSS:
|
|
|
524 |
$obj = new RectPatternDiagCross($aColor,$aWeight);
|
|
|
525 |
break;
|
|
|
526 |
default:
|
|
|
527 |
JpGraphError::RaiseL(16003,$aPattern);
|
|
|
528 |
//(" Unknown pattern specification ($aPattern)");
|
|
|
529 |
}
|
|
|
530 |
return $obj;
|
|
|
531 |
}
|
|
|
532 |
}
|
|
|
533 |
|
|
|
534 |
|
|
|
535 |
//=====================================================================
|
|
|
536 |
// Class PlotBand
|
|
|
537 |
// Factory class which is used by the client.
|
|
|
538 |
// It is responsible for factoring the corresponding pattern
|
|
|
539 |
// concrete class.
|
|
|
540 |
//=====================================================================
|
|
|
541 |
class PlotBand {
|
|
|
542 |
var $prect=null;
|
|
|
543 |
var $depth;
|
|
|
544 |
var $dir, $min, $max;
|
|
|
545 |
|
|
|
546 |
function PlotBand($aDir,$aPattern,$aMin,$aMax,$aColor="black",$aWeight=1,$aDepth=DEPTH_BACK) {
|
|
|
547 |
$f = new RectPatternFactory();
|
|
|
548 |
$this->prect = $f->Create($aPattern,$aColor,$aWeight);
|
|
|
549 |
if( is_numeric($aMin) && is_numeric($aMax) && ($aMin > $aMax) )
|
|
|
550 |
JpGraphError::RaiseL(16004);
|
|
|
551 |
//('Min value for plotband is larger than specified max value. Please correct.');
|
|
|
552 |
$this->dir = $aDir;
|
|
|
553 |
$this->min = $aMin;
|
|
|
554 |
$this->max = $aMax;
|
|
|
555 |
$this->depth=$aDepth;
|
|
|
556 |
}
|
|
|
557 |
|
|
|
558 |
// Set position. aRect contains absolute image coordinates
|
|
|
559 |
function SetPos(&$aRect) {
|
|
|
560 |
assert( $this->prect != null ) ;
|
|
|
561 |
$this->prect->SetPos($aRect);
|
|
|
562 |
}
|
|
|
563 |
|
|
|
564 |
function ShowFrame($aFlag=true) {
|
|
|
565 |
$this->prect->ShowFrame($aFlag);
|
|
|
566 |
}
|
|
|
567 |
|
|
|
568 |
// Set z-order. In front of pplot or in the back
|
|
|
569 |
function SetOrder($aDepth) {
|
|
|
570 |
$this->depth=$aDepth;
|
|
|
571 |
}
|
|
|
572 |
|
|
|
573 |
function SetDensity($aDens) {
|
|
|
574 |
$this->prect->SetDensity($aDens);
|
|
|
575 |
}
|
|
|
576 |
|
|
|
577 |
function GetDir() {
|
|
|
578 |
return $this->dir;
|
|
|
579 |
}
|
|
|
580 |
|
|
|
581 |
function GetMin() {
|
|
|
582 |
return $this->min;
|
|
|
583 |
}
|
|
|
584 |
|
|
|
585 |
function GetMax() {
|
|
|
586 |
return $this->max;
|
|
|
587 |
}
|
|
|
588 |
|
|
|
589 |
// Display band
|
|
|
590 |
function Stroke(&$aImg,&$aXScale,&$aYScale) {
|
|
|
591 |
assert( $this->prect != null ) ;
|
|
|
592 |
if( $this->dir == HORIZONTAL ) {
|
|
|
593 |
if( $this->min === 'min' ) $this->min = $aYScale->GetMinVal();
|
|
|
594 |
if( $this->max === 'max' ) $this->max = $aYScale->GetMaxVal();
|
|
|
595 |
|
|
|
596 |
// Only draw the bar if it actually appears in the range
|
|
|
597 |
if ($this->min < $aYScale->GetMaxVal() && $this->max > $aYScale->GetMinVal()) {
|
|
|
598 |
|
|
|
599 |
// Trucate to limit of axis
|
|
|
600 |
$this->min = max($this->min, $aYScale->GetMinVal());
|
|
|
601 |
$this->max = min($this->max, $aYScale->GetMaxVal());
|
|
|
602 |
|
|
|
603 |
$x=$aXScale->scale_abs[0];
|
|
|
604 |
$y=$aYScale->Translate($this->max);
|
|
|
605 |
$width=$aXScale->scale_abs[1]-$aXScale->scale_abs[0]+1;
|
|
|
606 |
$height=abs($y-$aYScale->Translate($this->min))+1;
|
|
|
607 |
$this->prect->SetPos(new Rectangle($x,$y,$width,$height));
|
|
|
608 |
$this->prect->Stroke($aImg);
|
|
|
609 |
}
|
|
|
610 |
}
|
|
|
611 |
else { // VERTICAL
|
|
|
612 |
if( $this->min === 'min' ) $this->min = $aXScale->GetMinVal();
|
|
|
613 |
if( $this->max === 'max' ) $this->max = $aXScale->GetMaxVal();
|
|
|
614 |
|
|
|
615 |
// Only draw the bar if it actually appears in the range
|
|
|
616 |
if ($this->min < $aXScale->GetMaxVal() && $this->max > $aXScale->GetMinVal()) {
|
|
|
617 |
|
|
|
618 |
// Trucate to limit of axis
|
|
|
619 |
$this->min = max($this->min, $aXScale->GetMinVal());
|
|
|
620 |
$this->max = min($this->max, $aXScale->GetMaxVal());
|
|
|
621 |
|
|
|
622 |
$y=$aYScale->scale_abs[1];
|
|
|
623 |
$x=$aXScale->Translate($this->min);
|
|
|
624 |
$height=abs($aYScale->scale_abs[1]-$aYScale->scale_abs[0]);
|
|
|
625 |
$width=abs($x-$aXScale->Translate($this->max));
|
|
|
626 |
$this->prect->SetPos(new Rectangle($x,$y,$width,$height));
|
|
|
627 |
$this->prect->Stroke($aImg);
|
|
|
628 |
}
|
|
|
629 |
}
|
|
|
630 |
}
|
|
|
631 |
}
|
|
|
632 |
|
|
|
633 |
|
|
|
634 |
?>
|