source: trunk/client/modules/Elezioni/grafici-old/jpgraph_line.php@ 2

Last change on this file since 2 was 2, checked in by root, 15 years ago

importo il progetto

File size: 11.9 KB
Line 
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,v 1.48 2003/05/28 18:39:45 aditus Exp $
8//
9// License: This code is released under QPL
10// Copyright (C) 2001,2002 Johan Persson
11//========================================================================
12*/
13
14// constants for the (filled) area
15DEFINE("LP_AREA_FILLED", true);
16DEFINE("LP_AREA_NOT_FILLED", false);
17DEFINE("LP_AREA_BORDER",false);
18DEFINE("LP_AREA_NO_BORDER",true);
19
20//===================================================
21// CLASS LinePlot
22// Description:
23//===================================================
24class LinePlot extends Plot{
25 var $filled=false;
26 var $fill_color='blue';
27 var $mark=null;
28 var $step_style=false, $center=false;
29 var $line_style=1; // Default to solid
30 var $filledAreas = array(); // array of arrays(with min,max,col,filled in them)
31 var $barcenter=false; // When we mix line and bar. Should we center the line in the bar.
32 var $fillFromMin = false ;
33
34//---------------
35// CONSTRUCTOR
36 function LinePlot(&$datay,$datax=false) {
37 $this->Plot($datay,$datax);
38 $this->mark = new PlotMark();
39 }
40//---------------
41// PUBLIC METHODS
42
43 // Set style, filled or open
44 function SetFilled($aFlag=true) {
45 JpGraphError::Raise('LinePlot::SetFilled() is deprecated. Use SetFillColor()');
46 }
47
48 function SetBarCenter($aFlag=true) {
49 $this->barcenter=$aFlag;
50 }
51
52 function SetStyle($aStyle) {
53 $this->line_style=$aStyle;
54 }
55
56 function SetStepStyle($aFlag=true) {
57 $this->step_style = $aFlag;
58 }
59
60 function SetColor($aColor) {
61 parent::SetColor($aColor);
62 }
63
64 function SetFillFromYMin($f = true ) {
65 $this->fillFromMin = $f ;
66 }
67
68 function SetFillColor($aColor,$aFilled=true) {
69 $this->fill_color=$aColor;
70 $this->filled=$aFilled;
71 }
72
73 function Legend(&$graph) {
74 if( $this->legend!="" ) {
75 if( $this->filled ) {
76 $graph->legend->Add($this->legend,
77 $this->fill_color,$this->mark,0,
78 $this->legendcsimtarget,$this->legendcsimalt);
79 } else {
80 $graph->legend->Add($this->legend,
81 $this->color,$this->mark,$this->line_style,
82 $this->legendcsimtarget,$this->legendcsimalt);
83 }
84 }
85 }
86
87 function AddArea($aMin=0,$aMax=0,$aFilled=LP_AREA_NOT_FILLED,$aColor="gray9",$aBorder=LP_AREA_BORDER) {
88 if($aMin > $aMax) {
89 // swap
90 $tmp = $aMin;
91 $aMin = $aMax;
92 $aMax = $tmp;
93 }
94 $this->filledAreas[] = array($aMin,$aMax,$aColor,$aFilled,$aBorder);
95 }
96
97 // Gets called before any axis are stroked
98 function PreStrokeAdjust(&$graph) {
99
100 // If another plot type have already adjusted the
101 // offset we don't touch it.
102 // (We check for empty in case the scale is a log scale
103 // and hence doesn't contain any xlabel_offset)
104 if( empty($graph->xaxis->scale->ticks->xlabel_offset) ||
105 $graph->xaxis->scale->ticks->xlabel_offset == 0 ) {
106 if( $this->center ) {
107 ++$this->numpoints;
108 $a=0.5; $b=0.5;
109 } else {
110 $a=0; $b=0;
111 }
112 $graph->xaxis->scale->ticks->SetXLabelOffset($a);
113 $graph->SetTextScaleOff($b);
114 //$graph->xaxis->scale->ticks->SupressMinorTickMarks();
115 }
116 }
117
118 function Stroke(&$img,&$xscale,&$yscale) {
119 $numpoints=count($this->coords[0]);
120 if( isset($this->coords[1]) ) {
121 if( count($this->coords[1])!=$numpoints )
122 JpGraphError::Raise("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints");
123 else
124 $exist_x = true;
125 }
126 else
127 $exist_x = false;
128
129 if( $this->barcenter )
130 $textadj = 0.5-$xscale->text_scale_off;
131 else
132 $textadj = 0;
133
134 // Find the first numeric data point
135 $startpoint=0;
136 while( $startpoint < $numpoints && !is_numeric($this->coords[0][$startpoint]) )
137 ++$startpoint;
138
139 // Bail out if no data points
140 if( $startpoint == $numpoints )
141 return;
142
143 if( $exist_x )
144 $xs=$this->coords[1][$startpoint];
145 else
146 $xs= $textadj+$startpoint;
147
148 $img->SetStartPoint($xscale->Translate($xs),
149 $yscale->Translate($this->coords[0][$startpoint]));
150
151
152 if( $this->filled ) {
153 $cord[] = $xscale->Translate($xs);
154 $min = $yscale->GetMinVal();
155 if( $min > 0 || $this->fillFromMin )
156 $cord[] = $yscale->Translate($min);
157 else
158 $cord[] = $yscale->Translate(0);
159 }
160 $xt = $xscale->Translate($xs);
161 $yt = $yscale->Translate($this->coords[0][$startpoint]);
162 $cord[] = $xt;
163 $cord[] = $yt;
164 $yt_old = $yt;
165
166 $this->value->Stroke($img,$this->coords[0][$startpoint],$xt,$yt);
167
168 $img->SetColor($this->color);
169 $img->SetLineWeight($this->weight);
170 $img->SetLineStyle($this->line_style);
171 for( $pnts=$startpoint+1; $pnts<$numpoints; ++$pnts) {
172
173 if( $exist_x ) $x=$this->coords[1][$pnts];
174 else $x=$pnts+$textadj;
175 $xt = $xscale->Translate($x);
176 $yt = $yscale->Translate($this->coords[0][$pnts]);
177
178 $y=$this->coords[0][$pnts];
179 if( $this->step_style && is_numeric($y) ) {
180 $img->StyleLineTo($xt,$yt_old);
181 $img->StyleLineTo($xt,$yt);
182
183 $cord[] = $xt;
184 $cord[] = $yt_old;
185
186 $cord[] = $xt;
187 $cord[] = $yt;
188
189 }
190 else {
191 if( is_numeric($y) || (is_string($y) && $y != "-") ) {
192 $tmp1=$this->coords[0][$pnts];
193 $tmp2=$this->coords[0][$pnts-1];
194 if( is_numeric($tmp1) && (is_numeric($tmp2) || $tmp2=="-" ) ) {
195 $img->StyleLineTo($xt,$yt);
196 }
197 else {
198 $img->SetStartPoint($xt,$yt);
199 }
200
201 if( is_numeric($tmp1) &&
202 (is_numeric($tmp2) || $tmp2=="-" || ($this->filled && $tmp2=='') ) ) {
203 $cord[] = $xt;
204 $cord[] = $yt;
205 }
206 }
207 }
208 $yt_old = $yt;
209
210 $this->StrokeDataValue($img,$this->coords[0][$pnts],$xt,$yt);
211
212 }
213
214 if( $this->filled ) {
215 $cord[] = $xt;
216 if( $min > 0 || $this->fillFromMin )
217 $cord[] = $yscale->Translate($min);
218 else
219 $cord[] = $yscale->Translate(0);
220 $img->SetColor($this->fill_color);
221 $img->FilledPolygon($cord);
222 $img->SetColor($this->color);
223 $img->Polygon($cord);
224 }
225
226 if(!empty($this->filledAreas)) {
227
228 $minY = $yscale->Translate($yscale->GetMinVal());
229 $factor = ($this->step_style ? 4 : 2);
230
231 for($i = 0; $i < sizeof($this->filledAreas); ++$i) {
232 // go through all filled area elements ordered by insertion
233 // fill polygon array
234 $areaCoords[] = $cord[$this->filledAreas[$i][0] * $factor];
235 $areaCoords[] = $minY;
236
237 $areaCoords =
238 array_merge($areaCoords,
239 array_slice($cord,
240 $this->filledAreas[$i][0] * $factor,
241 ($this->filledAreas[$i][1] - $this->filledAreas[$i][0] + ($this->step_style ? 0 : 1)) * $factor));
242 $areaCoords[] = $areaCoords[sizeof($areaCoords)-2]; // last x
243 $areaCoords[] = $minY; // last y
244
245 if($this->filledAreas[$i][3]) {
246 $img->SetColor($this->filledAreas[$i][2]);
247 $img->FilledPolygon($areaCoords);
248 $img->SetColor($this->color);
249 }
250 // Check if we should draw the frame.
251 // If not we still re-draw the line since it might have been
252 // partially overwritten by the filled area and it doesn't look
253 // very good.
254 // TODO: The behaviour is undefined if the line does not have
255 // any line at the position of the area.
256 if( $this->filledAreas[$i][4] )
257 $img->Polygon($areaCoords);
258 else
259 $img->Polygon($cord);
260
261 $areaCoords = array();
262 }
263 }
264
265 if( $this->mark->type == -1 || $this->mark->show == false )
266 return;
267
268 for( $pnts=0; $pnts<$numpoints; ++$pnts) {
269
270 if( $exist_x ) $x=$this->coords[1][$pnts];
271 else $x=$pnts+$textadj;
272 $xt = $xscale->Translate($x);
273 $yt = $yscale->Translate($this->coords[0][$pnts]);
274
275 if( is_numeric($this->coords[0][$pnts]) ) {
276 if( !empty($this->csimtargets[$pnts]) ) {
277 $this->mark->SetCSIMTarget($this->csimtargets[$pnts]);
278 $this->mark->SetCSIMAlt($this->csimalts[$pnts]);
279 }
280 if( $exist_x )
281 $x=$this->coords[1][$pnts];
282 else
283 $x=$pnts;
284 $this->mark->SetCSIMAltVal($this->coords[0][$pnts],$x);
285 $this->mark->Stroke($img,$xt,$yt);
286 $this->csimareas .= $this->mark->GetCSIMAreas();
287 $this->StrokeDataValue($img,$this->coords[0][$pnts],$xt,$yt);
288 }
289 }
290
291
292 }
293} // Class
294
295
296//===================================================
297// CLASS AccLinePlot
298// Description:
299//===================================================
300class AccLinePlot extends Plot {
301 var $plots=null,$nbrplots=0,$numpoints=0;
302//---------------
303// CONSTRUCTOR
304 function AccLinePlot($plots) {
305 $this->plots = $plots;
306 $this->nbrplots = count($plots);
307 $this->numpoints = $plots[0]->numpoints;
308 }
309
310//---------------
311// PUBLIC METHODS
312 function Legend(&$graph) {
313 foreach( $this->plots as $p )
314 $p->DoLegend($graph);
315 }
316
317 function Max() {
318 list($xmax) = $this->plots[0]->Max();
319 $nmax=0;
320 for($i=0; $i<count($this->plots); ++$i) {
321 $n = count($this->plots[$i]->coords[0]);
322 $nmax = max($nmax,$n);
323 list($x) = $this->plots[$i]->Max();
324 $xmax = Max($xmax,$x);
325 }
326 for( $i = 0; $i < $nmax; $i++ ) {
327 // Get y-value for line $i by adding the
328 // individual bars from all the plots added.
329 // It would be wrong to just add the
330 // individual plots max y-value since that
331 // would in most cases give to large y-value.
332 $y=$this->plots[0]->coords[0][$i];
333 for( $j = 1; $j < $this->nbrplots; $j++ ) {
334 $y += $this->plots[ $j ]->coords[0][$i];
335 }
336 $ymax[$i] = $y;
337 }
338 $ymax = max($ymax);
339 return array($xmax,$ymax);
340 }
341
342 function Min() {
343 $nmax=0;
344 list($xmin,$ysetmin) = $this->plots[0]->Min();
345 for($i=0; $i<count($this->plots); ++$i) {
346 $n = count($this->plots[$i]->coords[0]);
347 $nmax = max($nmax,$n);
348 list($x,$y) = $this->plots[$i]->Min();
349 $xmin = Min($xmin,$x);
350 $ysetmin = Min($y,$ysetmin);
351 }
352 for( $i = 0; $i < $nmax; $i++ ) {
353 // Get y-value for line $i by adding the
354 // individual bars from all the plots added.
355 // It would be wrong to just add the
356 // individual plots min y-value since that
357 // would in most cases give to small y-value.
358 $y=$this->plots[0]->coords[0][$i];
359 for( $j = 1; $j < $this->nbrplots; $j++ ) {
360 $y += $this->plots[ $j ]->coords[0][$i];
361 }
362 $ymin[$i] = $y;
363 }
364 $ymin = Min($ysetmin,Min($ymin));
365 return array($xmin,$ymin);
366 }
367
368 // Gets called before any axis are stroked
369 function PreStrokeAdjust(&$graph) {
370
371 // If another plot type have already adjusted the
372 // offset we don't touch it.
373 // (We check for empty in case the scale is a log scale
374 // and hence doesn't contain any xlabel_offset)
375
376 if( empty($graph->xaxis->scale->ticks->xlabel_offset) ||
377 $graph->xaxis->scale->ticks->xlabel_offset == 0 ) {
378 if( $this->center ) {
379 ++$this->numpoints;
380 $a=0.5; $b=0.5;
381 } else {
382 $a=0; $b=0;
383 }
384 $graph->xaxis->scale->ticks->SetXLabelOffset($a);
385 $graph->SetTextScaleOff($b);
386 $graph->xaxis->scale->ticks->SupressMinorTickMarks();
387 }
388
389 }
390
391 // To avoid duplicate of line drawing code here we just
392 // change the y-values for each plot and then restore it
393 // after we have made the stroke. We must do this copy since
394 // it wouldn't be possible to create an acc line plot
395 // with the same graphs, i.e AccLinePlot(array($pl,$pl,$pl));
396 // since this method would have a side effect.
397 function Stroke(&$img,&$xscale,&$yscale) {
398 $img->SetLineWeight($this->weight);
399 $this->numpoints = count($this->plots[0]->coords[0]);
400 // Allocate array
401 $coords[$this->nbrplots][$this->numpoints]=0;
402 for($i=0; $i<$this->numpoints; $i++) {
403 $coords[0][$i]=$this->plots[0]->coords[0][$i];
404 $accy=$coords[0][$i];
405 for($j=1; $j<$this->nbrplots; ++$j ) {
406 $coords[$j][$i] = $this->plots[$j]->coords[0][$i]+$accy;
407 $accy = $coords[$j][$i];
408 }
409 }
410 for($j=$this->nbrplots-1; $j>=0; --$j) {
411 $p=$this->plots[$j];
412 for( $i=0; $i<$this->numpoints; ++$i) {
413 $tmp[$i]=$p->coords[0][$i];
414 $p->coords[0][$i]=$coords[$j][$i];
415 }
416 $p->Stroke($img,$xscale,$yscale);
417 for( $i=0; $i<$this->numpoints; ++$i)
418 $p->coords[0][$i]=$tmp[$i];
419 $p->coords[0][]=$tmp;
420 }
421 }
422} // Class
423
424
425/* EOF */
426?>
Note: See TracBrowser for help on using the repository browser.