Changeset 284 for trunk/client/modules/Elezioni/grafici/jpgraph_radar.php
- Timestamp:
- Apr 21, 2019, 11:49:56 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/client/modules/Elezioni/grafici/jpgraph_radar.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_RADAR.PHP4 // Description: Radar plot extension for JpGraph5 // Created:2001-02-046 // Ver: $Id: jpgraph_radar.php 1044 2008-07-31 18:34:55Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */3 // File: JPGRAPH_RADAR.PHP 4 // Description: Radar plot extension for JpGraph 5 // Created: 2001-02-04 6 // Ver: $Id: jpgraph_radar.php 1783 2009-08-25 11:41:01Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 require_once('jpgraph_plotmark.inc.php'); 13 13 14 //=================================================== 15 // CLASS RadarLogTicks 16 // Description: Logarithmic ticks 17 //=================================================== 14 18 class RadarLogTicks extends Ticks { 15 //--------------- 16 // CONSTRUCTOR 17 function RadarLogTicks() { 18 } 19 //--------------- 20 // PUBLIC METHODS 21 22 // TODO: Add Argument grid 19 20 function __construct() { 21 // Empty 22 } 23 23 24 function Stroke($aImg,&$grid,$aPos,$aAxisAngle,$aScale,&$aMajPos,&$aMajLabel) { 24 $start = $aScale->GetMinVal(); 25 $limit = $aScale->GetMaxVal(); 26 $nextMajor = 10*$start; 27 $step = $nextMajor / 10.0; 28 $count=1; 29 30 $ticklen_maj=5; 31 $dx_maj=round(sin($aAxisAngle)*$ticklen_maj); 32 $dy_maj=round(cos($aAxisAngle)*$ticklen_maj); 33 $ticklen_min=3; 34 $dx_min=round(sin($aAxisAngle)*$ticklen_min); 35 $dy_min=round(cos($aAxisAngle)*$ticklen_min); 36 37 $aMajPos=array(); 38 $aMajLabel=array(); 39 40 if( $this->supress_first ) 41 $aMajLabel[]=""; 42 else 43 $aMajLabel[]=$start; 44 $yr=$aScale->RelTranslate($start); 45 $xt=round($yr*cos($aAxisAngle))+$aScale->scale_abs[0]; 46 $yt=$aPos-round($yr*sin($aAxisAngle)); 47 $aMajPos[]=$xt+2*$dx_maj; 48 $aMajPos[]=$yt-$aImg->GetFontheight()/2; 49 $grid[]=$xt; 50 $grid[]=$yt; 51 52 $aImg->SetLineWeight($this->weight); 53 54 for($y=$start; $y<=$limit; $y+=$step,++$count ) { 55 $yr=$aScale->RelTranslate($y); 56 $xt=round($yr*cos($aAxisAngle))+$aScale->scale_abs[0]; 57 $yt=$aPos-round($yr*sin($aAxisAngle)); 58 if( $count % 10 == 0 ) { 59 $grid[]=$xt; 60 $grid[]=$yt; 61 $aMajPos[]=$xt+2*$dx_maj; 62 $aMajPos[]=$yt-$aImg->GetFontheight()/2; 63 if( !$this->supress_tickmarks ) { 64 if( $this->majcolor!="" ) $aImg->PushColor($this->majcolor); 65 $aImg->Line($xt+$dx_maj,$yt+$dy_maj,$xt-$dx_maj,$yt-$dy_maj); 66 if( $this->majcolor!="" ) $aImg->PopColor(); 67 } 68 if( $this->label_formfunc != "" ) { 69 $f=$this->label_formfunc; 70 $l = call_user_func($f,$nextMajor); 71 } 72 else 73 $l = $nextMajor; 74 75 $aMajLabel[]=$l; 76 $nextMajor *= 10; 77 $step *= 10; 78 $count=1; 79 } 80 else 81 if( !$this->supress_minor_tickmarks ) { 82 if( $this->mincolor!="" ) $aImg->PushColor($this->mincolor); 83 $aImg->Line($xt+$dx_min,$yt+$dy_min,$xt-$dx_min,$yt-$dy_min); 84 if( $this->mincolor!="" ) $aImg->PopColor(); 85 } 86 } 87 } 25 $start = $aScale->GetMinVal(); 26 $limit = $aScale->GetMaxVal(); 27 $nextMajor = 10*$start; 28 $step = $nextMajor / 10.0; 29 $count=1; 30 31 $ticklen_maj=5; 32 $dx_maj=round(sin($aAxisAngle)*$ticklen_maj); 33 $dy_maj=round(cos($aAxisAngle)*$ticklen_maj); 34 $ticklen_min=3; 35 $dx_min=round(sin($aAxisAngle)*$ticklen_min); 36 $dy_min=round(cos($aAxisAngle)*$ticklen_min); 37 38 $aMajPos=array(); 39 $aMajLabel=array(); 40 41 if( $this->supress_first ) { 42 $aMajLabel[] = ''; 43 } 44 else { 45 $aMajLabel[]=$start; 46 } 47 48 $yr=$aScale->RelTranslate($start); 49 $xt=round($yr*cos($aAxisAngle))+$aScale->scale_abs[0]; 50 $yt=$aPos-round($yr*sin($aAxisAngle)); 51 $aMajPos[]=$xt+2*$dx_maj; 52 $aMajPos[]=$yt-$aImg->GetFontheight()/2; 53 $grid[]=$xt; 54 $grid[]=$yt; 55 56 $aImg->SetLineWeight($this->weight); 57 58 for($y=$start; $y<=$limit; $y+=$step,++$count ) { 59 $yr=$aScale->RelTranslate($y); 60 $xt=round($yr*cos($aAxisAngle))+$aScale->scale_abs[0]; 61 $yt=$aPos-round($yr*sin($aAxisAngle)); 62 if( $count % 10 == 0 ) { 63 $grid[]=$xt; 64 $grid[]=$yt; 65 $aMajPos[]=$xt+2*$dx_maj; 66 $aMajPos[]=$yt-$aImg->GetFontheight()/2; 67 if( !$this->supress_tickmarks ) { 68 if( $this->majcolor != '' ) { 69 $aImg->PushColor($this->majcolor); 70 } 71 $aImg->Line($xt+$dx_maj,$yt+$dy_maj,$xt-$dx_maj,$yt-$dy_maj); 72 if( $this->majcolor != '' ) { 73 $aImg->PopColor(); 74 } 75 } 76 if( $this->label_formfunc != '' ) { 77 $f=$this->label_formfunc; 78 $l = call_user_func($f,$nextMajor); 79 } 80 else { 81 $l = $nextMajor; 82 } 83 84 $aMajLabel[]=$l; 85 $nextMajor *= 10; 86 $step *= 10; 87 $count=1; 88 } 89 else { 90 if( !$this->supress_minor_tickmarks ) { 91 if( $this->mincolor != '' ) { 92 $aImg->PushColor($this->mincolor); 93 } 94 $aImg->Line($xt+$dx_min,$yt+$dy_min,$xt-$dx_min,$yt-$dy_min); 95 if( $this->mincolor != '' ) { 96 $aImg->PopColor(); 97 } 98 } 99 } 100 } 101 } 88 102 } 89 90 class RadarLinearTicks extends Ticks { 103 104 //=================================================== 105 // CLASS RadarLinear 106 // Description: Linear ticks 107 //=================================================== 108 class RadarLinearTicks extends Ticks { 91 109 92 110 private $minor_step=1, $major_step=2; 93 111 private $xlabel_offset=0,$xtick_offset=0; 94 112 95 //--------------- 96 // CONSTRUCTOR 97 function RadarLinearTicks() { 98 // Empty 99 } 100 101 //--------------- 102 // PUBLIC METHODS 103 104 113 function __construct() { 114 // Empty 115 } 116 105 117 // Return major step size in world coordinates 106 118 function GetMajor() { 107 108 } 109 119 return $this->major_step; 120 } 121 110 122 // Return minor step size in world coordinates 111 123 function GetMinor() { 112 113 } 114 124 return $this->minor_step; 125 } 126 115 127 // Set Minor and Major ticks (in world coordinates) 116 128 function Set($aMajStep,$aMinStep=false) { 117 if( $aMinStep==false ) 118 $aMinStep=$aMajStep; 119 120 if( $aMajStep <= 0 || $aMinStep <= 0 ) { 121 JpGraphError::Raise(" Minor or major step size is 0. Check that you haven't 122 got an accidental SetTextTicks(0) in your code.<p> 123 If this is not the case you might have stumbled upon a bug in JpGraph. 124 Please report this and if possible include the data that caused the 125 problem."); 126 } 127 128 $this->major_step=$aMajStep; 129 $this->minor_step=$aMinStep; 130 $this->is_set = true; 129 if( $aMinStep==false ) { 130 $aMinStep=$aMajStep; 131 } 132 133 if( $aMajStep <= 0 || $aMinStep <= 0 ) { 134 JpGraphError::RaiseL(25064); 135 //JpGraphError::Raise(" Minor or major step size is 0. Check that you haven't got an accidental SetTextTicks(0) in your code. If this is not the case you might have stumbled upon a bug in JpGraph. Please report this and if possible include the data that caused the problem."); 136 } 137 138 $this->major_step=$aMajStep; 139 $this->minor_step=$aMinStep; 140 $this->is_set = true; 131 141 } 132 142 133 143 function Stroke($aImg,&$grid,$aPos,$aAxisAngle,$aScale,&$aMajPos,&$aMajLabel) { 134 // Prepare to draw linear ticks 135 $maj_step_abs = abs($aScale->scale_factor*$this->major_step); 136 $min_step_abs = abs($aScale->scale_factor*$this->minor_step); 137 $nbrmaj = floor(($aScale->world_abs_size)/$maj_step_abs); 138 $nbrmin = floor(($aScale->world_abs_size)/$min_step_abs); 139 $skip = round($nbrmin/$nbrmaj); // Don't draw minor ontop of major 140 141 // Draw major ticks 142 $ticklen2=$this->major_abs_size; 143 $dx=round(sin($aAxisAngle)*$ticklen2); 144 $dy=round(cos($aAxisAngle)*$ticklen2); 145 $label=$aScale->scale[0]+$this->major_step; 146 147 $aImg->SetLineWeight($this->weight); 148 // NEW 149 $aMajPos = array(); 150 $aMajLabel = array(); 151 for($i=1; $i<=$nbrmaj; ++$i) { 152 $xt=round($i*$maj_step_abs*cos($aAxisAngle))+$aScale->scale_abs[0]; 153 $yt=$aPos-round($i*$maj_step_abs*sin($aAxisAngle)); 154 155 if( $this->label_formfunc != "" ) { 156 $f=$this->label_formfunc; 157 $l = call_user_func($f,$label); 158 } 159 else 160 $l = $label; 161 162 $aMajLabel[]=$l; 163 $label += $this->major_step; 164 $grid[]=$xt; 165 $grid[]=$yt; 166 $aMajPos[($i-1)*2]=$xt+2*$dx; 167 $aMajPos[($i-1)*2+1]=$yt-$aImg->GetFontheight()/2; 168 if( !$this->supress_tickmarks ) { 169 if( $this->majcolor!="" ) $aImg->PushColor($this->majcolor); 170 $aImg->Line($xt+$dx,$yt+$dy,$xt-$dx,$yt-$dy); 171 if( $this->majcolor!="" ) $aImg->PopColor(); 172 } 173 } 174 175 // Draw minor ticks 176 $ticklen2=$this->minor_abs_size; 177 $dx=round(sin($aAxisAngle)*$ticklen2); 178 $dy=round(cos($aAxisAngle)*$ticklen2); 179 if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) { 180 if( $this->mincolor!="" ) $aImg->PushColor($this->mincolor); 181 for($i=1; $i<=$nbrmin; ++$i) { 182 if( ($i % $skip) == 0 ) continue; 183 $xt=round($i*$min_step_abs*cos($aAxisAngle))+$aScale->scale_abs[0]; 184 $yt=$aPos-round($i*$min_step_abs*sin($aAxisAngle)); 185 $aImg->Line($xt+$dx,$yt+$dy,$xt-$dx,$yt-$dy); 186 } 187 if( $this->mincolor!="" ) $aImg->PopColor(); 188 } 144 // Prepare to draw linear ticks 145 $maj_step_abs = abs($aScale->scale_factor*$this->major_step); 146 $min_step_abs = abs($aScale->scale_factor*$this->minor_step); 147 $nbrmaj = round($aScale->world_abs_size/$maj_step_abs); 148 $nbrmin = round($aScale->world_abs_size/$min_step_abs); 149 $skip = round($nbrmin/$nbrmaj); // Don't draw minor on top of major 150 151 // Draw major ticks 152 $ticklen2=$this->major_abs_size; 153 $dx=round(sin($aAxisAngle)*$ticklen2); 154 $dy=round(cos($aAxisAngle)*$ticklen2); 155 $label=$aScale->scale[0]+$this->major_step; 156 157 $aImg->SetLineWeight($this->weight); 158 159 $aMajPos = array(); 160 $aMajLabel = array(); 161 162 for($i=1; $i<=$nbrmaj; ++$i) { 163 $xt=round($i*$maj_step_abs*cos($aAxisAngle))+$aScale->scale_abs[0]; 164 $yt=$aPos-round($i*$maj_step_abs*sin($aAxisAngle)); 165 166 if( $this->label_formfunc != '' ) { 167 $f=$this->label_formfunc; 168 $l = call_user_func($f,$label); 169 } 170 else { 171 $l = $label; 172 } 173 174 $aMajLabel[]=$l; 175 $label += $this->major_step; 176 $grid[]=$xt; 177 $grid[]=$yt; 178 $aMajPos[($i-1)*2]=$xt+2*$dx; 179 $aMajPos[($i-1)*2+1]=$yt-$aImg->GetFontheight()/2; 180 if( !$this->supress_tickmarks ) { 181 if( $this->majcolor != '' ) { 182 $aImg->PushColor($this->majcolor); 183 } 184 $aImg->Line($xt+$dx,$yt+$dy,$xt-$dx,$yt-$dy); 185 if( $this->majcolor != '' ) { 186 $aImg->PopColor(); 187 } 188 } 189 } 190 191 // Draw minor ticks 192 $ticklen2=$this->minor_abs_size; 193 $dx=round(sin($aAxisAngle)*$ticklen2); 194 $dy=round(cos($aAxisAngle)*$ticklen2); 195 if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) { 196 if( $this->mincolor != '' ) { 197 $aImg->PushColor($this->mincolor); 198 } 199 for($i=1; $i<=$nbrmin; ++$i) { 200 if( ($i % $skip) == 0 ) { 201 continue; 202 } 203 $xt=round($i*$min_step_abs*cos($aAxisAngle))+$aScale->scale_abs[0]; 204 $yt=$aPos-round($i*$min_step_abs*sin($aAxisAngle)); 205 $aImg->Line($xt+$dx,$yt+$dy,$xt-$dx,$yt-$dy); 206 } 207 if( $this->mincolor != '' ) { 208 $aImg->PopColor(); 209 } 210 } 189 211 } 190 212 } 191 213 192 193 214 194 215 //=================================================== … … 198 219 class RadarAxis extends AxisPrototype { 199 220 public $title=null; 200 private $title_color= "navy";221 private $title_color='navy'; 201 222 private $len=0; 202 //--------------- 203 // CONSTRUCTOR 204 function RadarAxis($img,$aScale,$color=array(0,0,0)) { 205 parent::Axis($img,$aScale,$color); 206 $this->len=$img->plotheight; 207 $this->title = new Text(); 208 $this->title->SetFont(FF_FONT1,FS_BOLD); 209 $this->color = array(0,0,0); 210 } 211 //--------------- 212 // PUBLIC METHODS 213 function SetTickLabels($aLabelArray,$aLabelColorArray=null) { 214 $this->ticks_label = $aLabelArray; 215 $this->ticks_label_colors = $aLabelColorArray; 216 } 217 218 219 // Stroke the axis 220 // $pos = Vertical position of axis 223 224 function __construct($img,$aScale,$color=array(0,0,0)) { 225 parent::__construct($img,$aScale,$color); 226 $this->len = $img->plotheight; 227 $this->title = new Text(); 228 $this->title->SetFont(FF_FONT1,FS_BOLD); 229 $this->color = array(0,0,0); 230 } 231 232 // Stroke the axis 233 // $pos = Vertical position of axis 221 234 // $aAxisAngle = Axis angle 222 // $grid 223 // $lf= Label flag, TRUE if the axis should have labels235 // $grid = Returns an array with positions used to draw the grid 236 // $lf = Label flag, TRUE if the axis should have labels 224 237 function Stroke($pos,$aAxisAngle,&$grid,$title,$lf) { 225 $this->img->SetColor($this->color); 226 227 // Determine end points for the axis 228 $x=round($this->scale->world_abs_size*cos($aAxisAngle)+$this->scale->scale_abs[0]); 229 $y=round($pos-$this->scale->world_abs_size*sin($aAxisAngle)); 230 231 // Draw axis 232 $this->img->SetColor($this->color); 233 $this->img->SetLineWeight($this->weight); 234 if( !$this->hide ) 235 $this->img->Line($this->scale->scale_abs[0],$pos,$x,$y); 236 237 $this->scale->ticks->Stroke($this->img,$grid,$pos,$aAxisAngle,$this->scale,$majpos,$majlabel); 238 $ncolor=0; 239 if( isset($this->ticks_label_colors) ) 240 $ncolor=count($this->ticks_label_colors); 241 242 // Draw labels 243 if( $lf && !$this->hide ) { 244 $this->img->SetFont($this->font_family,$this->font_style,$this->font_size); 245 $this->img->SetTextAlign("left","top"); 246 $this->img->SetColor($this->label_color); 247 248 // majpos contains (x,y) coordinates for labels 249 if( ! $this->hide_labels ) { 250 $n = floor(count($majpos)/2); 251 for($i=0; $i < $n; ++$i) { 252 // Set specific label color if specified 253 if( $ncolor > 0 ) 254 $this->img->SetColor($this->ticks_label_colors[$i % $ncolor]); 255 256 if( $this->ticks_label != null && isset($this->ticks_label[$i]) ) 257 $this->img->StrokeText($majpos[$i*2],$majpos[$i*2+1],$this->ticks_label[$i]); 258 else 259 $this->img->StrokeText($majpos[$i*2],$majpos[$i*2+1],$majlabel[$i]); 260 } 261 } 262 } 263 $this->_StrokeAxisTitle($pos,$aAxisAngle,$title); 264 } 265 //--------------- 266 // PRIVATE METHODS 267 238 $this->img->SetColor($this->color); 239 240 // Determine end points for the axis 241 $x=round($this->scale->world_abs_size*cos($aAxisAngle)+$this->scale->scale_abs[0]); 242 $y=round($pos-$this->scale->world_abs_size*sin($aAxisAngle)); 243 244 // Draw axis 245 $this->img->SetColor($this->color); 246 $this->img->SetLineWeight($this->weight); 247 if( !$this->hide ) { 248 $this->img->Line($this->scale->scale_abs[0],$pos,$x,$y); 249 } 250 251 $this->scale->ticks->Stroke($this->img,$grid,$pos,$aAxisAngle,$this->scale,$majpos,$majlabel); 252 $ncolor=0; 253 if( isset($this->ticks_label_colors) ) { 254 $ncolor=count($this->ticks_label_colors); 255 } 256 257 // Draw labels 258 if( $lf && !$this->hide ) { 259 $this->img->SetFont($this->font_family,$this->font_style,$this->font_size); 260 $this->img->SetTextAlign('left','top'); 261 $this->img->SetColor($this->label_color); 262 263 // majpos contains (x,y) coordinates for labels 264 if( ! $this->hide_labels ) { 265 $n = floor(count($majpos)/2); 266 for($i=0; $i < $n; ++$i) { 267 // Set specific label color if specified 268 if( $ncolor > 0 ) { 269 $this->img->SetColor($this->ticks_label_colors[$i % $ncolor]); 270 } 271 272 if( $this->ticks_label != null && isset($this->ticks_label[$i]) ) { 273 $this->img->StrokeText($majpos[$i*2],$majpos[$i*2+1],$this->ticks_label[$i]); 274 } 275 else { 276 $this->img->StrokeText($majpos[$i*2],$majpos[$i*2+1],$majlabel[$i]); 277 } 278 } 279 } 280 } 281 $this->_StrokeAxisTitle($pos,$aAxisAngle,$title); 282 } 283 268 284 function _StrokeAxisTitle($pos,$aAxisAngle,$title) { 269 $this->title->Set($title); 270 $marg=6+$this->title->margin; 271 $xt=round(($this->scale->world_abs_size+$marg)*cos($aAxisAngle)+$this->scale->scale_abs[0]); 272 $yt=round($pos-($this->scale->world_abs_size+$marg)*sin($aAxisAngle)); 273 274 // Position the axis title. 275 // dx, dy is the offset from the top left corner of the bounding box that sorrounds the text 276 // that intersects with the extension of the corresponding axis. The code looks a little 277 // bit messy but this is really the only way of having a reasonable position of the 278 // axis titles. 279 if( $this->title->iWordwrap > 0 ) { 280 $title = wordwrap($title,$this->title->iWordwrap,"\n"); 281 } 282 283 $h=$this->img->GetTextHeight($title)*1.2; 284 $w=$this->img->GetTextWidth($title)*1.2; 285 286 while( $aAxisAngle > 2*M_PI ) $aAxisAngle -= 2*M_PI; 287 288 // Around 3 a'clock 289 if( $aAxisAngle>=7*M_PI/4 || $aAxisAngle <= M_PI/4 ) $dx=-0.15; // Small trimming to make the dist to the axis more even 290 // Around 12 a'clock 291 if( $aAxisAngle>=M_PI/4 && $aAxisAngle <= 3*M_PI/4 ) $dx=($aAxisAngle-M_PI/4)*2/M_PI; 292 // Around 9 a'clock 293 if( $aAxisAngle>=3*M_PI/4 && $aAxisAngle <= 5*M_PI/4 ) $dx=1; 294 // Around 6 a'clock 295 if( $aAxisAngle>=5*M_PI/4 && $aAxisAngle <= 7*M_PI/4 ) $dx=(1-($aAxisAngle-M_PI*5/4)*2/M_PI); 296 297 if( $aAxisAngle>=7*M_PI/4 ) $dy=(($aAxisAngle-M_PI)-3*M_PI/4)*2/M_PI; 298 if( $aAxisAngle<=M_PI/12 ) $dy=(0.5-$aAxisAngle*2/M_PI); 299 if( $aAxisAngle<=M_PI/4 && $aAxisAngle > M_PI/12) $dy=(1-$aAxisAngle*2/M_PI); 300 if( $aAxisAngle>=M_PI/4 && $aAxisAngle <= 3*M_PI/4 ) $dy=1; 301 if( $aAxisAngle>=3*M_PI/4 && $aAxisAngle <= 5*M_PI/4 ) $dy=(1-($aAxisAngle-3*M_PI/4)*2/M_PI); 302 if( $aAxisAngle>=5*M_PI/4 && $aAxisAngle <= 7*M_PI/4 ) $dy=0; 303 304 if( !$this->hide ) { 305 $this->title->Stroke($this->img,$xt-$dx*$w,$yt-$dy*$h,$title); 306 } 307 } 308 309 285 $this->title->Set($title); 286 $marg=6+$this->title->margin; 287 $xt=round(($this->scale->world_abs_size+$marg)*cos($aAxisAngle)+$this->scale->scale_abs[0]); 288 $yt=round($pos-($this->scale->world_abs_size+$marg)*sin($aAxisAngle)); 289 290 // Position the axis title. 291 // dx, dy is the offset from the top left corner of the bounding box that sorrounds the text 292 // that intersects with the extension of the corresponding axis. The code looks a little 293 // bit messy but this is really the only way of having a reasonable position of the 294 // axis titles. 295 if( $this->title->iWordwrap > 0 ) { 296 $title = wordwrap($title,$this->title->iWordwrap,"\n"); 297 } 298 299 $h=$this->img->GetTextHeight($title)*1.2; 300 $w=$this->img->GetTextWidth($title)*1.2; 301 302 while( $aAxisAngle > 2*M_PI ) 303 $aAxisAngle -= 2*M_PI; 304 305 // Around 3 a'clock 306 if( $aAxisAngle>=7*M_PI/4 || $aAxisAngle <= M_PI/4 ) $dx=-0.15; // Small trimming to make the dist to the axis more even 307 308 // Around 12 a'clock 309 if( $aAxisAngle>=M_PI/4 && $aAxisAngle <= 3*M_PI/4 ) $dx=($aAxisAngle-M_PI/4)*2/M_PI; 310 311 // Around 9 a'clock 312 if( $aAxisAngle>=3*M_PI/4 && $aAxisAngle <= 5*M_PI/4 ) $dx=1; 313 314 // Around 6 a'clock 315 if( $aAxisAngle>=5*M_PI/4 && $aAxisAngle <= 7*M_PI/4 ) $dx=(1-($aAxisAngle-M_PI*5/4)*2/M_PI); 316 317 if( $aAxisAngle>=7*M_PI/4 ) $dy=(($aAxisAngle-M_PI)-3*M_PI/4)*2/M_PI; 318 if( $aAxisAngle<=M_PI/12 ) $dy=(0.5-$aAxisAngle*2/M_PI); 319 if( $aAxisAngle<=M_PI/4 && $aAxisAngle > M_PI/12) $dy=(1-$aAxisAngle*2/M_PI); 320 if( $aAxisAngle>=M_PI/4 && $aAxisAngle <= 3*M_PI/4 ) $dy=1; 321 if( $aAxisAngle>=3*M_PI/4 && $aAxisAngle <= 5*M_PI/4 ) $dy=(1-($aAxisAngle-3*M_PI/4)*2/M_PI); 322 if( $aAxisAngle>=5*M_PI/4 && $aAxisAngle <= 7*M_PI/4 ) $dy=0; 323 324 if( !$this->hide ) { 325 $this->title->Stroke($this->img,$xt-$dx*$w,$yt-$dy*$h,$title); 326 } 327 } 328 310 329 } // Class 311 330 … … 320 339 private $show=false, $weight=1; 321 340 322 //------------ 323 // CONSTRUCTOR 324 function RadarGrid() { 325 } 326 327 // PUBLIC METHODS 341 function __construct() { 342 // Empty 343 } 344 328 345 function SetColor($aMajColor) { 329 330 } 331 346 $this->grid_color = $aMajColor; 347 } 348 332 349 function SetWeight($aWeight) { 333 334 } 335 350 $this->weight=$aWeight; 351 } 352 336 353 // Specify if grid should be dashed, dotted or solid 337 354 function SetLineStyle($aType) { 338 339 } 340 355 $this->type = $aType; 356 } 357 341 358 // Decide if both major and minor grid should be displayed 342 359 function Show($aShowMajor=true) { 343 $this->show=$aShowMajor; 344 } 345 346 //---------------- 347 // PRIVATE METHODS 360 $this->show=$aShowMajor; 361 } 362 348 363 function Stroke($img,$grid) { 349 if( !$this->show ) return; 350 $nbrticks = count($grid[0])/2; 351 $nbrpnts = count($grid); 352 $img->SetColor($this->grid_color); 353 $img->SetLineWeight($this->weight); 354 for($i=0; $i<$nbrticks; ++$i) { 355 for($j=0; $j<$nbrpnts; ++$j) { 356 $pnts[$j*2]=$grid[$j][$i*2]; 357 $pnts[$j*2+1]=$grid[$j][$i*2+1]; 358 } 359 for($k=0; $k<$nbrpnts; ++$k ){ 360 $l=($k+1)%$nbrpnts; 361 if( $this->type == "solid" ) 362 $img->Line($pnts[$k*2],$pnts[$k*2+1],$pnts[$l*2],$pnts[$l*2+1]); 363 elseif( $this->type == "dotted" ) 364 $img->DashedLine($pnts[$k*2],$pnts[$k*2+1],$pnts[$l*2],$pnts[$l*2+1],1,6); 365 elseif( $this->type == "dashed" ) 366 $img->DashedLine($pnts[$k*2],$pnts[$k*2+1],$pnts[$l*2],$pnts[$l*2+1],2,4); 367 elseif( $this->type == "longdashed" ) 368 $img->DashedLine($pnts[$k*2],$pnts[$k*2+1],$pnts[$l*2],$pnts[$l*2+1],8,6); 369 } 370 $pnts=array(); 371 } 364 if( !$this->show ) { 365 return; 366 } 367 368 $nbrticks = count($grid[0])/2; 369 $nbrpnts = count($grid); 370 $img->SetColor($this->grid_color); 371 $img->SetLineWeight($this->weight); 372 373 for($i=0; $i<$nbrticks; ++$i) { 374 for($j=0; $j<$nbrpnts; ++$j) { 375 $pnts[$j*2]=$grid[$j][$i*2]; 376 $pnts[$j*2+1]=$grid[$j][$i*2+1]; 377 } 378 for($k=0; $k<$nbrpnts; ++$k ){ 379 $l=($k+1)%$nbrpnts; 380 if( $this->type == 'solid' ) 381 $img->Line($pnts[$k*2],$pnts[$k*2+1],$pnts[$l*2],$pnts[$l*2+1]); 382 elseif( $this->type == 'dotted' ) 383 $img->DashedLine($pnts[$k*2],$pnts[$k*2+1],$pnts[$l*2],$pnts[$l*2+1],1,6); 384 elseif( $this->type == 'dashed' ) 385 $img->DashedLine($pnts[$k*2],$pnts[$k*2+1],$pnts[$l*2],$pnts[$l*2+1],2,4); 386 elseif( $this->type == 'longdashed' ) 387 $img->DashedLine($pnts[$k*2],$pnts[$k*2+1],$pnts[$l*2],$pnts[$l*2+1],8,6); 388 } 389 $pnts=array(); 390 } 372 391 } 373 392 } // Class … … 380 399 class RadarPlot { 381 400 public $mark=null; 382 public $legend=""; 401 public $legend=''; 402 public $legendcsimtarget=''; 403 public $legendcsimalt=''; 404 public $csimtargets=array(); // Array of targets for CSIM 405 public $csimareas=""; // Resultant CSIM area tags 406 public $csimalts=null; // ALT:s for corresponding target 383 407 private $data=array(); 384 408 private $fill=false, $fill_color=array(200,170,180); … … 386 410 private $weight=1; 387 411 private $linestyle='solid'; 388 //--------------- 389 // CONSTRUCTOR 390 function RadarPlot($data) { 391 $this->data = $data; 392 $this->mark = new PlotMark(); 393 } 394 395 //--------------- 396 // PUBLIC METHODS 412 413 //--------------- 414 // CONSTRUCTOR 415 function __construct($data) { 416 $this->data = $data; 417 $this->mark = new PlotMark(); 418 } 419 397 420 function Min() { 398 399 } 400 421 return Min($this->data); 422 } 423 401 424 function Max() { 402 403 } 404 425 return Max($this->data); 426 } 427 405 428 function SetLegend($legend) { 406 429 $this->legend=$legend; 407 430 } 408 431 409 432 function SetLineStyle($aStyle) { 410 411 } 412 433 $this->linestyle=$aStyle; 434 } 435 413 436 function SetLineWeight($w) { 414 415 } 416 437 $this->weight=$w; 438 } 439 417 440 function SetFillColor($aColor) { 418 419 $this->fill = true; 420 } 421 441 $this->fill_color = $aColor; 442 $this->fill = true; 443 } 444 422 445 function SetFill($f=true) { 423 424 } 425 446 $this->fill = $f; 447 } 448 426 449 function SetColor($aColor,$aFillColor=false) { 427 $this->color = $aColor; 428 if( $aFillColor ) { 429 $this->SetFillColor($aFillColor); 430 $this->fill = true; 431 } 432 } 433 450 $this->color = $aColor; 451 if( $aFillColor ) { 452 $this->SetFillColor($aFillColor); 453 $this->fill = true; 454 } 455 } 456 457 // Set href targets for CSIM 458 function SetCSIMTargets($aTargets,$aAlts=null) { 459 $this->csimtargets=$aTargets; 460 $this->csimalts=$aAlts; 461 } 462 463 // Get all created areas 434 464 function GetCSIMareas() { 435 JpGraphError::RaiseL(18001); 436 //("Client side image maps not supported for RadarPlots."); 437 } 438 465 return $this->csimareas; 466 } 467 439 468 function Stroke($img, $pos, $scale, $startangle) { 440 $nbrpnts = count($this->data); 441 $astep=2*M_PI/$nbrpnts; 442 $a=$startangle; 443 444 $nulls=0; 445 for($i=0; $i<$nbrpnts; ++$i) { 446 if(!is_null($this->data[$i])) { 447 // Rotate each non null point to the correct axis-angle 448 $cs=$scale->RelTranslate($this->data[$i]); 449 $x=round($cs*cos($a)+$scale->scale_abs[0]); 450 $y=round($pos-$cs*sin($a)); 451 /* 452 // TODO: Update for proper LogScale 453 $c=log10($c); 454 $x=round(($c-$scale->scale[0])*$scale->scale_factor*cos($a)+$scale->scale_abs[0]); 455 $y=round($pos-($c-$scale->scale[0])*$scale->scale_factor*sin($a)); 456 */ 457 $pnts[($i-$nulls)*2]=$x; 458 $pnts[($i-$nulls)*2+1]=$y; 459 } 460 else { 461 ++$nulls; 462 } 463 $a += $astep; 464 } 465 466 if( $this->fill ) { 467 $img->SetColor($this->fill_color); 468 $img->FilledPolygon($pnts); 469 } 470 $img->SetLineWeight($this->weight); 471 $img->SetColor($this->color); 472 $img->SetLineStyle($this->linestyle); 473 $pnts[]=$pnts[0]; 474 $pnts[]=$pnts[1]; 475 $img->Polygon($pnts); 476 $img->SetLineStyle('solid'); // Reset line style to default 477 478 // Add plotmarks on top 479 if( $this->mark->show ) { 480 for($i=0; $i < $nbrpnts; ++$i) { 481 $this->mark->Stroke($img,$pnts[$i*2],$pnts[$i*2+1]); 482 } 483 } 484 485 } 486 487 //--------------- 488 // PRIVATE METHODS 469 $nbrpnts = count($this->data); 470 $astep=2*M_PI/$nbrpnts; 471 $a=$startangle; 472 473 for($i=0; $i<$nbrpnts; ++$i) { 474 475 // Rotate each non null point to the correct axis-angle 476 $cs=$scale->RelTranslate($this->data[$i]); 477 $x=round($cs*cos($a)+$scale->scale_abs[0]); 478 $y=round($pos-$cs*sin($a)); 479 480 $pnts[$i*2]=$x; 481 $pnts[$i*2+1]=$y; 482 483 // If the next point is null then we draw this polygon segment 484 // to the center, skip the next and draw the next segment from 485 // the center up to the point on the axis with the first non-null 486 // value and continues from that point. Some additoinal logic is necessary 487 // to handle the boundary conditions 488 if( $i < $nbrpnts-1 ) { 489 if( is_null($this->data[$i+1]) ) { 490 $cs = 0; 491 $x=round($cs*cos($a)+$scale->scale_abs[0]); 492 $y=round($pos-$cs*sin($a)); 493 $pnts[$i*2]=$x; 494 $pnts[$i*2+1]=$y; 495 $a += $astep; 496 } 497 } 498 499 $a += $astep; 500 } 501 502 if( $this->fill ) { 503 $img->SetColor($this->fill_color); 504 $img->FilledPolygon($pnts); 505 } 506 507 $img->SetLineWeight($this->weight); 508 $img->SetColor($this->color); 509 $img->SetLineStyle($this->linestyle); 510 $pnts[] = $pnts[0]; 511 $pnts[] = $pnts[1]; 512 $img->Polygon($pnts); 513 $img->SetLineStyle('solid'); // Reset line style to default 514 515 // Add plotmarks on top 516 if( $this->mark->show ) { 517 for($i=0; $i < $nbrpnts; ++$i) { 518 if( isset($this->csimtargets[$i]) ) { 519 $this->mark->SetCSIMTarget($this->csimtargets[$i]); 520 $this->mark->SetCSIMAlt($this->csimalts[$i]); 521 $this->mark->SetCSIMAltVal($pnts[$i*2], $pnts[$i*2+1]); 522 $this->mark->Stroke($img, $pnts[$i*2], $pnts[$i*2+1]); 523 $this->csimareas .= $this->mark->GetCSIMAreas(); 524 } 525 else { 526 $this->mark->Stroke($img,$pnts[$i*2],$pnts[$i*2+1]); 527 } 528 } 529 } 530 531 } 532 489 533 function GetCount() { 490 491 } 492 534 return count($this->data); 535 } 536 493 537 function Legend($graph) { 494 if( $this->legend=="" ) return; 495 if( $this->fill ) 496 $graph->legend->Add($this->legend,$this->fill_color,$this->mark); 497 else 498 $graph->legend->Add($this->legend,$this->color,$this->mark); 499 } 500 538 if( $this->legend == '' ) { 539 return; 540 } 541 if( $this->fill ) { 542 $graph->legend->Add($this->legend,$this->fill_color,$this->mark); 543 } else { 544 $graph->legend->Add($this->legend,$this->color,$this->mark); 545 } 546 } 547 501 548 } // Class 502 549 … … 508 555 public $grid,$axis=null; 509 556 private $posx,$posy; 510 private $len; 557 private $len; 511 558 private $axis_title=null; 512 //--------------- 513 // CONSTRUCTOR 514 function RadarGraph($width=300,$height=200,$cachedName="",$timeout=0,$inline=1) { 515 $this->Graph($width,$height,$cachedName,$timeout,$inline); 516 $this->posx=$width/2; 517 $this->posy=$height/2; 518 $this->len=min($width,$height)*0.35; 519 $this->SetColor(array(255,255,255)); 520 $this->SetTickDensity(TICKD_NORMAL); 521 $this->SetScale("lin"); 522 $this->SetGridDepth(DEPTH_FRONT); 523 524 } 525 526 //--------------- 527 // PUBLIC METHODS 528 function SupressTickMarks($f=true) { 529 if( ERR_DEPRECATED ) 530 JpGraphError::RaiseL(18002); 531 //('RadarGraph::SupressTickMarks() is deprecated. Use HideTickMarks() instead.'); 532 $this->axis->scale->ticks->SupressTickMarks($f); 559 560 function __construct($width=300,$height=200,$cachedName="",$timeout=0,$inline=1) { 561 parent::__construct($width,$height,$cachedName,$timeout,$inline); 562 $this->posx = $width/2; 563 $this->posy = $height/2; 564 $this->len = min($width,$height)*0.35; 565 $this->SetColor(array(255,255,255)); 566 $this->SetTickDensity(TICKD_NORMAL); 567 $this->SetScale('lin'); 568 $this->SetGridDepth(DEPTH_FRONT); 533 569 } 534 570 535 571 function HideTickMarks($aFlag=true) { 536 537 } 538 572 $this->axis->scale->ticks->SupressTickMarks($aFlag); 573 } 574 539 575 function ShowMinorTickmarks($aFlag=true) { 540 541 } 542 576 $this->yscale->ticks->SupressMinorTickMarks(!$aFlag); 577 } 578 543 579 function SetScale($axtype,$ymin=1,$ymax=1,$dummy1=null,$dumy2=null) { 544 if( $axtype != "lin" && $axtype != "log") {545 546 //("Illegal scale for radarplot ($axtype). Must be \"lin\" or \"log\"");547 548 if( $axtype=="lin") {549 550 551 552 553 elseif( $axtype=="log") {554 555 556 557 558 559 $this->grid = new RadarGrid(); 580 if( $axtype != 'lin' && $axtype != 'log' ) { 581 JpGraphError::RaiseL(18003,$axtype); 582 //("Illegal scale for radarplot ($axtype). Must be \"lin\" or \"log\""); 583 } 584 if( $axtype == 'lin' ) { 585 $this->yscale = new LinearScale($ymin,$ymax); 586 $this->yscale->ticks = new RadarLinearTicks(); 587 $this->yscale->ticks->SupressMinorTickMarks(); 588 } 589 elseif( $axtype == 'log' ) { 590 $this->yscale = new LogScale($ymin,$ymax); 591 $this->yscale->ticks = new RadarLogTicks(); 592 } 593 594 $this->axis = new RadarAxis($this->img,$this->yscale); 595 $this->grid = new RadarGrid(); 560 596 } 561 597 562 598 function SetSize($aSize) { 563 if( $aSize < 0.1 || $aSize>1 ) 564 JpGraphError::RaiseL(18004,$aSize); 565 //("Radar Plot size must be between 0.1 and 1. (Your value=$s)"); 566 $this->len=min($this->img->width,$this->img->height)*$aSize/2; 599 if( $aSize < 0.1 || $aSize>1 ) { 600 JpGraphError::RaiseL(18004,$aSize); 601 //("Radar Plot size must be between 0.1 and 1. (Your value=$s)"); 602 } 603 $this->len=min($this->img->width,$this->img->height)*$aSize/2; 567 604 } 568 605 569 606 function SetPlotSize($aSize) { 570 607 $this->SetSize($aSize); 571 608 } 572 609 573 610 function SetTickDensity($densy=TICKD_NORMAL,$dummy1=null) { 574 $this->ytick_factor=25; 575 576 577 $this->ytick_factor=12; 578 579 580 $this->ytick_factor=25; 581 582 583 $this->ytick_factor=40; 584 585 586 $this->ytick_factor=70; 587 break; 588 589 590 //("RadarPlot Unsupported Tick density: $densy");591 611 $this->ytick_factor=25; 612 switch( $densy ) { 613 case TICKD_DENSE: 614 $this->ytick_factor=12; 615 break; 616 case TICKD_NORMAL: 617 $this->ytick_factor=25; 618 break; 619 case TICKD_SPARSE: 620 $this->ytick_factor=40; 621 break; 622 case TICKD_VERYSPARSE: 623 $this->ytick_factor=70; 624 break; 625 default: 626 JpGraphError::RaiseL(18005,$densy); 627 //("RadarPlot Unsupported Tick density: $densy"); 628 } 592 629 } 593 630 594 631 function SetPos($px,$py=0.5) { 595 632 $this->SetCenter($px,$py); 596 633 } 597 634 598 635 function SetCenter($px,$py=0.5) { 599 assert($px > 0 && $py > 0 ); 600 $this->posx=$this->img->width*$px; 601 $this->posy=$this->img->height*$py; 602 } 603 604 function SetColor($c) { 605 $this->SetMarginColor($c); 606 } 607 608 function SetTitles($title) { 609 $this->axis_title = $title; 610 } 611 612 function Add($splot) { 613 $this->plots[]=$splot; 614 } 615 636 if( $px >= 0 && $px <= 1 ) { 637 $this->posx = $this->img->width*$px; 638 } 639 else { 640 $this->posx = $px; 641 } 642 if( $py >= 0 && $py <= 1 ) { 643 $this->posy = $this->img->height*$py; 644 } 645 else { 646 $this->posy = $py; 647 } 648 } 649 650 function SetColor($aColor) { 651 $this->SetMarginColor($aColor); 652 } 653 654 function SetTitles($aTitleArray) { 655 $this->axis_title = $aTitleArray; 656 } 657 658 function Add($aPlot) { 659 if( $aPlot == null ) { 660 JpGraphError::RaiseL(25010);//("Graph::Add() You tried to add a null plot to the graph."); 661 } 662 if( is_array($aPlot) && count($aPlot) > 0 ) { 663 $cl = $aPlot[0]; 664 } 665 else { 666 $cl = $aPlot; 667 } 668 669 if( $cl instanceof Text ) $this->AddText($aPlot); 670 elseif( class_exists('IconPlot',false) && ($cl instanceof IconPlot) ) $this->AddIcon($aPlot); 671 else { 672 $this->plots[] = $aPlot; 673 } 674 } 675 616 676 function GetPlotsYMinMax($aPlots) { 617 $min=$aPlots[0]->Min(); 618 $max=$aPlots[0]->Max(); 619 foreach( $this->plots as $p ) { 620 $max=max($max,$p->Max()); 621 $min=min($min,$p->Min()); 622 } 623 if( $min < 0 ) 624 JpGraphError::RaiseL(18006,$min); 625 //("Minimum data $min (Radar plots should only be used when all data points > 0)"); 626 return array($min,$max); 627 } 677 $min=$aPlots[0]->Min(); 678 $max=$aPlots[0]->Max(); 679 foreach( $this->plots as $p ) { 680 $max=max($max,$p->Max()); 681 $min=min($min,$p->Min()); 682 } 683 if( $min < 0 ) { 684 JpGraphError::RaiseL(18006,$min); 685 //("Minimum data $min (Radar plots should only be used when all data points > 0)"); 686 } 687 return array($min,$max); 688 } 689 690 function StrokeIcons() { 691 if( $this->iIcons != null ) { 692 $n = count($this->iIcons); 693 for( $i=0; $i < $n; ++$i ) { 694 $this->iIcons[$i]->Stroke($this->img); 695 } 696 } 697 } 698 699 function StrokeTexts() { 700 if( $this->texts != null ) { 701 $n = count($this->texts); 702 for( $i=0; $i < $n; ++$i ) { 703 $this->texts[$i]->Stroke($this->img); 704 } 705 } 706 } 628 707 629 708 // Stroke the Radar graph 630 function Stroke($aStrokeFileName="") { 631 $n = count($this->plots); 632 // Set Y-scale 633 if( !$this->yscale->IsSpecified() && count($this->plots)>0 ) { 634 list($min,$max) = $this->GetPlotsYMinMax($this->plots); 635 $this->yscale->AutoScale($this->img,0,$max,$this->len/$this->ytick_factor); 636 } 637 elseif( $this->yscale->IsSpecified() && 638 ( $this->yscale->auto_ticks || !$this->yscale->ticks->IsSpecified()) ) { 639 // The tick calculation will use the user suplied min/max values to determine 640 // the ticks. If auto_ticks is false the exact user specifed min and max 641 // values will be used for the scale. 642 // If auto_ticks is true then the scale might be slightly adjusted 643 // so that the min and max values falls on an even major step. 644 $min = $this->yscale->scale[0]; 645 $max = $this->yscale->scale[1]; 646 $this->yscale->AutoScale($this->img,$min,$max, 647 $this->len/$this->ytick_factor, 648 $this->yscale->auto_ticks); 649 } 650 651 // Set start position end length of scale (in absolute pixels) 652 $this->yscale->SetConstants($this->posx,$this->len); 653 654 // We need as many axis as there are data points 655 $nbrpnts=$this->plots[0]->GetCount(); 656 657 // If we have no titles just number the axis 1,2,3,... 658 if( $this->axis_title==null ) { 659 for($i=0; $i < $nbrpnts; ++$i ) 660 $this->axis_title[$i] = $i+1; 661 } 662 elseif(count($this->axis_title)<$nbrpnts) 663 JpGraphError::RaiseL(18007); 664 //("Number of titles does not match number of points in plot."); 665 for($i=0; $i < $n; ++$i ) 666 if( $nbrpnts != $this->plots[$i]->GetCount() ) 667 JpGraphError::RaiseL(18008); 668 //("Each radar plot must have the same number of data points."); 669 670 if( $this->background_image != "" ) { 671 $this->StrokeFrameBackground(); 672 } 673 else { 674 $this->StrokeFrame(); 675 } 676 $astep=2*M_PI/$nbrpnts; 677 678 // Prepare legends 679 for($i=0; $i < $n; ++$i) 680 $this->plots[$i]->Legend($this); 681 $this->legend->Stroke($this->img); 682 $this->footer->Stroke($this->img); 683 684 if( $this->grid_depth == DEPTH_BACK ) { 685 // Draw axis and grid 686 for( $i=0,$a=M_PI/2; $i < $nbrpnts; ++$i, $a += $astep ) { 687 $this->axis->Stroke($this->posy,$a,$grid[$i],$this->axis_title[$i],$i==0); 688 } 689 } 690 691 // Plot points 692 $a=M_PI/2; 693 for($i=0; $i < $n; ++$i ) 694 $this->plots[$i]->Stroke($this->img, $this->posy, $this->yscale, $a); 695 696 if( $this->grid_depth != DEPTH_BACK ) { 697 // Draw axis and grid 698 for( $i=0,$a=M_PI/2; $i < $nbrpnts; ++$i, $a += $astep ) { 699 $this->axis->Stroke($this->posy,$a,$grid[$i],$this->axis_title[$i],$i==0); 700 } 701 } 702 $this->grid->Stroke($this->img,$grid); 703 $this->StrokeTitles(); 704 705 // Stroke texts 706 if( $this->texts != null ) { 707 foreach( $this->texts as $t) 708 $t->Stroke($this->img); 709 } 710 711 // Should we do any final image transformation 712 if( $this->iImgTrans ) { 713 if( !class_exists('ImgTrans',false) ) { 714 require_once('jpgraph_imgtrans.php'); 715 } 716 717 $tform = new ImgTrans($this->img->img); 718 $this->img->img = $tform->Skew3D($this->iImgTransHorizon,$this->iImgTransSkewDist, 719 $this->iImgTransDirection,$this->iImgTransHighQ, 720 $this->iImgTransMinSize,$this->iImgTransFillColor, 721 $this->iImgTransBorder); 722 } 723 724 // If the filename is given as the special "__handle" 725 // then the image handler is returned and the image is NOT 726 // streamed back 727 if( $aStrokeFileName == _IMG_HANDLER ) { 728 return $this->img->img; 729 } 730 else { 731 // Finally stream the generated picture 732 $this->cache->PutAndStream($this->img,$this->cache_name,$this->inline, 733 $aStrokeFileName); 734 } 709 function Stroke($aStrokeFileName='') { 710 711 // If the filename is the predefined value = '_csim_special_' 712 // we assume that the call to stroke only needs to do enough 713 // to correctly generate the CSIM maps. 714 // We use this variable to skip things we don't strictly need 715 // to do to generate the image map to improve performance 716 // a best we can. Therefor you will see a lot of tests !$_csim in the 717 // code below. 718 $_csim = ( $aStrokeFileName === _CSIM_SPECIALFILE ); 719 720 // We need to know if we have stroked the plot in the 721 // GetCSIMareas. Otherwise the CSIM hasn't been generated 722 // and in the case of GetCSIM called before stroke to generate 723 // CSIM without storing an image to disk GetCSIM must call Stroke. 724 $this->iHasStroked = true; 725 726 $n = count($this->plots); 727 // Set Y-scale 728 729 if( !$this->yscale->IsSpecified() && count($this->plots) > 0 ) { 730 list($min,$max) = $this->GetPlotsYMinMax($this->plots); 731 $this->yscale->AutoScale($this->img,0,$max,$this->len/$this->ytick_factor); 732 } 733 elseif( $this->yscale->IsSpecified() && 734 ( $this->yscale->auto_ticks || !$this->yscale->ticks->IsSpecified()) ) { 735 736 // The tick calculation will use the user suplied min/max values to determine 737 // the ticks. If auto_ticks is false the exact user specifed min and max 738 // values will be used for the scale. 739 // If auto_ticks is true then the scale might be slightly adjusted 740 // so that the min and max values falls on an even major step. 741 $min = $this->yscale->scale[0]; 742 $max = $this->yscale->scale[1]; 743 $this->yscale->AutoScale($this->img,$min,$max, 744 $this->len/$this->ytick_factor, 745 $this->yscale->auto_ticks); 746 } 747 748 // Set start position end length of scale (in absolute pixels) 749 $this->yscale->SetConstants($this->posx,$this->len); 750 751 // We need as many axis as there are data points 752 $nbrpnts=$this->plots[0]->GetCount(); 753 754 // If we have no titles just number the axis 1,2,3,... 755 if( $this->axis_title==null ) { 756 for($i=0; $i < $nbrpnts; ++$i ) { 757 $this->axis_title[$i] = $i+1; 758 } 759 } 760 elseif( count($this->axis_title) < $nbrpnts) { 761 JpGraphError::RaiseL(18007); 762 // ("Number of titles does not match number of points in plot."); 763 } 764 for( $i=0; $i < $n; ++$i ) { 765 if( $nbrpnts != $this->plots[$i]->GetCount() ) { 766 JpGraphError::RaiseL(18008); 767 //("Each radar plot must have the same number of data points."); 768 } 769 } 770 771 if( !$_csim ) { 772 if( $this->background_image != '' ) { 773 $this->StrokeFrameBackground(); 774 } 775 else { 776 $this->StrokeFrame(); 777 $this->StrokeBackgroundGrad(); 778 } 779 } 780 $astep=2*M_PI/$nbrpnts; 781 782 if( !$_csim ) { 783 if( $this->iIconDepth == DEPTH_BACK ) { 784 $this->StrokeIcons(); 785 } 786 787 788 // Prepare legends 789 for($i=0; $i < $n; ++$i) { 790 $this->plots[$i]->Legend($this); 791 } 792 $this->legend->Stroke($this->img); 793 $this->footer->Stroke($this->img); 794 } 795 796 if( !$_csim ) { 797 if( $this->grid_depth == DEPTH_BACK ) { 798 // Draw axis and grid 799 for( $i=0,$a=M_PI/2; $i < $nbrpnts; ++$i, $a += $astep ) { 800 $this->axis->Stroke($this->posy,$a,$grid[$i],$this->axis_title[$i],$i==0); 801 } 802 $this->grid->Stroke($this->img,$grid); 803 } 804 if( $this->iIconDepth == DEPTH_BACK ) { 805 $this->StrokeIcons(); 806 } 807 808 } 809 810 // Plot points 811 $a=M_PI/2; 812 for($i=0; $i < $n; ++$i ) { 813 $this->plots[$i]->Stroke($this->img, $this->posy, $this->yscale, $a); 814 } 815 816 if( !$_csim ) { 817 if( $this->grid_depth != DEPTH_BACK ) { 818 // Draw axis and grid 819 for( $i=0,$a=M_PI/2; $i < $nbrpnts; ++$i, $a += $astep ) { 820 $this->axis->Stroke($this->posy,$a,$grid[$i],$this->axis_title[$i],$i==0); 821 } 822 $this->grid->Stroke($this->img,$grid); 823 } 824 825 $this->StrokeTitles(); 826 $this->StrokeTexts(); 827 if( $this->iIconDepth == DEPTH_FRONT ) { 828 $this->StrokeIcons(); 829 } 830 } 831 832 // Should we do any final image transformation 833 if( $this->iImgTrans && !$_csim ) { 834 if( !class_exists('ImgTrans',false) ) { 835 require_once('jpgraph_imgtrans.php'); 836 } 837 838 $tform = new ImgTrans($this->img->img); 839 $this->img->img = $tform->Skew3D($this->iImgTransHorizon,$this->iImgTransSkewDist, 840 $this->iImgTransDirection,$this->iImgTransHighQ, 841 $this->iImgTransMinSize,$this->iImgTransFillColor, 842 $this->iImgTransBorder); 843 } 844 845 if( !$_csim ) { 846 // If the filename is given as the special "__handle" 847 // then the image handler is returned and the image is NOT 848 // streamed back 849 if( $aStrokeFileName == _IMG_HANDLER ) { 850 return $this->img->img; 851 } 852 else { 853 // Finally stream the generated picture 854 $this->cache->PutAndStream($this->img,$this->cache_name,$this->inline,$aStrokeFileName); 855 } 856 } 735 857 } 736 858 } // Class
Note:
See TracChangeset
for help on using the changeset viewer.