[3594] | 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 | ?> |
---|