1 | <?php |
---|
2 | /*======================================================================= |
---|
3 | // File: JPGRAPH_LINE.PHP |
---|
4 | // Description: Line plot extension for JpGraph |
---|
5 | // Created: 2001-01-08 |
---|
6 | // Author: Johan Persson (johanp@aditus.nu) |
---|
7 | // Ver: $Id: jpgraph_line.php 18250 2005-05-07 14:13:43Z ralfbecker $ |
---|
8 | // |
---|
9 | // License: This code is released under GPL 2.0 |
---|
10 | // Copyright (C) 2001 Johan Persson |
---|
11 | //======================================================================== |
---|
12 | */ |
---|
13 | |
---|
14 | //=================================================== |
---|
15 | // CLASS Value |
---|
16 | // Description: |
---|
17 | //=================================================== |
---|
18 | class DisplayValue { |
---|
19 | var $show=false,$format="%d",$angle=0; |
---|
20 | var $ff=FF_FONT1,$fs=FS_NORMAL,$fsize=10; |
---|
21 | var $color="navy",$margin=3; |
---|
22 | |
---|
23 | function Show($f=true) { |
---|
24 | $this->show=$f; |
---|
25 | } |
---|
26 | |
---|
27 | function SetColor($color) { |
---|
28 | $this->color = $color; |
---|
29 | } |
---|
30 | |
---|
31 | function SetFont($ff,$fs=FS_NORMAL,$fsize=10) { |
---|
32 | $this->ff=$ff; |
---|
33 | $this->fs=$fs; |
---|
34 | $this->fsize=$fsize; |
---|
35 | } |
---|
36 | |
---|
37 | function SetMargin($m) { |
---|
38 | $this->margin = $m; |
---|
39 | } |
---|
40 | |
---|
41 | function SetFormat($format,$angle=0) { |
---|
42 | $this->format= $format; |
---|
43 | $this->angle = $angle; |
---|
44 | } |
---|
45 | } |
---|
46 | |
---|
47 | |
---|
48 | //=================================================== |
---|
49 | // CLASS LinePlot |
---|
50 | // Description: |
---|
51 | //=================================================== |
---|
52 | class LinePlot extends Plot{ |
---|
53 | var $filled=false; |
---|
54 | var $fill_color; |
---|
55 | var $mark=null; |
---|
56 | var $step_style=false, $center=false; |
---|
57 | var $line_style=1; // Default to solid |
---|
58 | var $value; |
---|
59 | |
---|
60 | //--------------- |
---|
61 | // CONSTRUCTOR |
---|
62 | function LinePlot(&$datay,$datax=false) { |
---|
63 | $this->Plot($datay,$datax); |
---|
64 | $this->mark = new PlotMark(); |
---|
65 | $this->mark->SetColor($this->color); |
---|
66 | $this->value = new DisplayValue(); |
---|
67 | } |
---|
68 | //--------------- |
---|
69 | // PUBLIC METHODS |
---|
70 | |
---|
71 | // Set style, filled or open |
---|
72 | function SetFilled($f=true) { |
---|
73 | $this->filled=$f; |
---|
74 | } |
---|
75 | |
---|
76 | function SetStyle($s) { |
---|
77 | $this->line_style=$s; |
---|
78 | } |
---|
79 | |
---|
80 | function SetStepStyle($f=true) { |
---|
81 | $this->step_style = $f; |
---|
82 | } |
---|
83 | |
---|
84 | function SetColor($c) { |
---|
85 | parent::SetColor($c); |
---|
86 | $this->mark->SetColor($this->color); |
---|
87 | } |
---|
88 | |
---|
89 | function SetFillColor($c,$f=true) { |
---|
90 | $this->fill_color=$c; |
---|
91 | $this->filled=$f; |
---|
92 | } |
---|
93 | |
---|
94 | function Legend(&$graph) { |
---|
95 | if( $this->legend!="" ) { |
---|
96 | if( $this->filled ) { |
---|
97 | $graph->legend->Add($this->legend, |
---|
98 | $this->fill_color,$this->mark); |
---|
99 | } else { |
---|
100 | $graph->legend->Add($this->legend, |
---|
101 | $this->color,$this->mark,$this->line_style); |
---|
102 | } |
---|
103 | } |
---|
104 | } |
---|
105 | |
---|
106 | function SetCenter($c=true) { |
---|
107 | $this->center=$c; |
---|
108 | } |
---|
109 | |
---|
110 | // Gets called before any axis are stroked |
---|
111 | function PreStrokeAdjust(&$graph) { |
---|
112 | if( $this->center ) { |
---|
113 | ++$this->numpoints; |
---|
114 | $a=0.5; $b=0.5; |
---|
115 | } else { |
---|
116 | $a=0; $b=0; |
---|
117 | } |
---|
118 | $graph->xaxis->scale->ticks->SetXLabelOffset($a); |
---|
119 | $graph->SetTextScaleOff($b); |
---|
120 | $graph->xaxis->scale->ticks->SupressMinorTickMarks(); |
---|
121 | } |
---|
122 | |
---|
123 | function Stroke(&$img,&$xscale,&$yscale) { |
---|
124 | $numpoints=count($this->coords[0]); |
---|
125 | if( isset($this->coords[1]) ) { |
---|
126 | if( count($this->coords[1])!=$numpoints ) |
---|
127 | JpGraphError::Raise("JpGraph Error: Number of X and Y points are not equal.<br> |
---|
128 | Number of X-points:".count($this->coords[1])."<br> |
---|
129 | Number of Y-points:$numpoints"); |
---|
130 | else |
---|
131 | $exist_x = true; |
---|
132 | } |
---|
133 | else |
---|
134 | $exist_x = false; |
---|
135 | |
---|
136 | if( $exist_x ) |
---|
137 | $xs=$this->coords[1][0]; |
---|
138 | else |
---|
139 | $xs=0; |
---|
140 | |
---|
141 | $img->SetStartPoint($xscale->Translate($xs), |
---|
142 | $yscale->Translate($this->coords[0][0])); |
---|
143 | |
---|
144 | if( $this->filled ) { |
---|
145 | $cord[] = $xscale->Translate($xs); |
---|
146 | $cord[] = $yscale->Translate($yscale->GetMinVal()); |
---|
147 | } |
---|
148 | $cord[] = $xscale->Translate($xs); |
---|
149 | $cord[] = $yscale->Translate($this->coords[0][0]); |
---|
150 | $yt_old = $yscale->Translate($this->coords[0][0]); |
---|
151 | $img->SetColor($this->color); |
---|
152 | $img->SetLineWeight($this->weight); |
---|
153 | $img->SetLineStyle($this->line_style); |
---|
154 | for( $pnts=1; $pnts<$numpoints; ++$pnts) { |
---|
155 | if( $exist_x ) $x=$this->coords[1][$pnts]; |
---|
156 | else $x=$pnts; |
---|
157 | $xt = $xscale->Translate($x); |
---|
158 | $yt = $yscale->Translate($this->coords[0][$pnts]); |
---|
159 | $cord[] = $xt; |
---|
160 | $cord[] = $yt; |
---|
161 | if( $this->step_style ) { |
---|
162 | $img->StyleLineTo($xt,$yt_old); |
---|
163 | $img->StyleLineTo($xt,$yt); |
---|
164 | } |
---|
165 | else { |
---|
166 | $y=$this->coords[0][$pnts]; |
---|
167 | if( is_numeric($y) || (is_string($y) && $y != "-") ) { |
---|
168 | $tmp1=$this->coords[0][$pnts]; |
---|
169 | $tmp2=$this->coords[0][$pnts-1]; |
---|
170 | if( is_numeric($tmp1) && (is_numeric($tmp2) || $tmp2=="-" ) ) { |
---|
171 | $img->StyleLineTo($xt,$yt); |
---|
172 | } |
---|
173 | else { |
---|
174 | $img->SetStartPoint($xt,$yt); |
---|
175 | } |
---|
176 | } |
---|
177 | } |
---|
178 | $yt_old = $yt; |
---|
179 | if( $this->value->show) |
---|
180 | { |
---|
181 | $sval=sprintf($this->value->format,$this->coords[0][$pnts]); |
---|
182 | $txt = new Text($sval,$xt,$yt-$this->value->margin); |
---|
183 | $txt->SetFont($this->value->ff,$this->value->fs,$this->value->fsize); |
---|
184 | $txt->Align("center","bottom"); |
---|
185 | $txt->SetOrientation($this->value->angle); |
---|
186 | $txt->SetColor($this->value->color); |
---|
187 | $txt->Stroke($img); |
---|
188 | } |
---|
189 | } |
---|
190 | if( $this->filled ) { |
---|
191 | $cord[] = $xt; |
---|
192 | $cord[] = $yscale->Translate($yscale->GetMinVal()); |
---|
193 | $img->SetColor($this->fill_color); |
---|
194 | $img->FilledPolygon($cord); |
---|
195 | $img->SetColor($this->color); |
---|
196 | $img->Polygon($cord); |
---|
197 | } |
---|
198 | $adjust=0; |
---|
199 | if( $this->filled ) $adjust=2; |
---|
200 | for($i=$adjust; $i<count($cord)-$adjust; $i+=2) { |
---|
201 | if( is_numeric($this->coords[0][($i-$adjust)/2]) ) |
---|
202 | $this->mark->Stroke($img,$cord[$i],$cord[$i+1]); |
---|
203 | } |
---|
204 | } |
---|
205 | //--------------- |
---|
206 | // PRIVATE METHODS |
---|
207 | } // Class |
---|
208 | |
---|
209 | |
---|
210 | //=================================================== |
---|
211 | // CLASS AccLinePlot |
---|
212 | // Description: |
---|
213 | //=================================================== |
---|
214 | class AccLinePlot extends Plot { |
---|
215 | var $plots=null,$nbrplots=0,$numpoints=0; |
---|
216 | //--------------- |
---|
217 | // CONSTRUCTOR |
---|
218 | function AccLinePlot($plots) { |
---|
219 | $this->plots = $plots; |
---|
220 | $this->nbrplots = count($plots); |
---|
221 | $this->numpoints = $plots[0]->numpoints; |
---|
222 | } |
---|
223 | |
---|
224 | //--------------- |
---|
225 | // PUBLIC METHODS |
---|
226 | function Legend(&$graph) { |
---|
227 | foreach( $this->plots as $p ) |
---|
228 | $p->Legend($graph); |
---|
229 | } |
---|
230 | |
---|
231 | function Max() { |
---|
232 | $accymax=0; |
---|
233 | list($xmax,$dummy) = $this->plots[0]->Max(); |
---|
234 | foreach($this->plots as $p) { |
---|
235 | list($xm,$ym) = $p->Max(); |
---|
236 | $xmax = max($xmax,$xm); |
---|
237 | $accymax += $ym; |
---|
238 | } |
---|
239 | return array($xmax,$accymax); |
---|
240 | } |
---|
241 | |
---|
242 | function Min() { |
---|
243 | list($xmin,$ymin)=$this->plots[0]->Min(); |
---|
244 | foreach( $this->plots as $p ) { |
---|
245 | list($xm,$ym)=$p->Min(); |
---|
246 | $xmin=Min($xmin,$xm); |
---|
247 | $ymin=Min($ymin,$ym); |
---|
248 | } |
---|
249 | return array($xmin,$ymin); |
---|
250 | } |
---|
251 | |
---|
252 | // To avoid duplicate of line drawing code here we just |
---|
253 | // change the y-values for each plot and then restore it |
---|
254 | // after we have made the stroke. We must do this copy since |
---|
255 | // it wouldn't be possible to create an acc line plot |
---|
256 | // with the same graphs, i.e AccLinePlot(array($pl,$pl,$pl)); |
---|
257 | // since this method would have a side effect. |
---|
258 | function Stroke(&$img,&$xscale,&$yscale) { |
---|
259 | $img->SetLineWeight($this->weight); |
---|
260 | // Allocate array |
---|
261 | $coords[$this->nbrplots][$this->numpoints]=0; |
---|
262 | for($i=0; $i<$this->numpoints; $i++) { |
---|
263 | $coords[0][$i]=$this->plots[0]->coords[0][$i]; |
---|
264 | $accy=$coords[0][$i]; |
---|
265 | for($j=1; $j<$this->nbrplots; ++$j ) { |
---|
266 | $coords[$j][$i] = $this->plots[$j]->coords[0][$i]+$accy; |
---|
267 | $accy = $coords[$j][$i]; |
---|
268 | } |
---|
269 | } |
---|
270 | for($j=$this->nbrplots-1; $j>=0; --$j) { |
---|
271 | $p=$this->plots[$j]; |
---|
272 | for( $i=0; $i<$this->numpoints; ++$i) { |
---|
273 | $tmp[$i]=$p->coords[0][$i]; |
---|
274 | $p->coords[0][$i]=$coords[$j][$i]; |
---|
275 | } |
---|
276 | $p->Stroke($img,$xscale,$yscale); |
---|
277 | for( $i=0; $i<$this->numpoints; ++$i) |
---|
278 | $p->coords[0][$i]=$tmp[$i]; |
---|
279 | $p->coords[0][]=$tmp; |
---|
280 | } |
---|
281 | } |
---|
282 | } // Class |
---|
283 | |
---|
284 | /* EOF */ |
---|
285 | ?> |
---|