[ Index ] |
|
Code source de eGroupWare 1.2.106-2 |
1 <?php 2 /*======================================================================= 3 // File: JPGRAPH_PIE3D.PHP 4 // Description: 3D Pie plot extension for JpGraph 5 // Created: 2001-03-24 6 // Author: Johan Persson (johanp@aditus.nu) 7 // Ver: $Id: jpgraph_pie3d.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 PiePlot3D 16 // Description: Plots a 3D pie with a specified projection 17 // angle between 20 and 70 degrees. 18 //=================================================== 19 class PiePlot3D extends PiePlot { 20 var $labelhintcolor="red",$showlabelhint=true,$labelmargin=0.30; 21 var $angle=30; 22 23 //--------------- 24 // CONSTRUCTOR 25 function PiePlot3d(&$data) { 26 $this->data = $data; 27 $this->title = new Text(""); 28 $this->title->SetFont(FF_FONT1,FS_BOLD); 29 } 30 31 //--------------- 32 // PUBLIC METHODS 33 34 // Specify projection angle for 3D in degrees 35 // Must be between 20 and 70 degrees 36 function SetAngle($a) { 37 if( $a<30 || $a>70 ) 38 JpGraphError::Raise("JpGraph: 3D Pie projection angle must be between 30 and 70 degrees."); 39 else 40 $this->angle = $a; 41 } 42 43 function AddSliceToCSIM($i,$xc,$yc,$height,$width,$thick,$sa,$ea) { //Slice number, ellipse centre (x,y), height, width, start angle, end angle 44 45 //add coordinates of the centre to the map 46 $coords = "$xc, $yc"; 47 48 //add coordinates of the first point on the arc to the map 49 $xp = floor($width*cos($sa)/2+$xc); 50 $yp = floor($yc-$height*sin($sa)/2); 51 $coords.= ", $xp, $yp"; 52 53 //If on the front half, add the thickness offset 54 if ($sa >= M_PI && $sa <= 2*M_PI*1.01) { 55 $yp = floor($yp+($thick*$width)); 56 $coords.= ", $xp, $yp"; 57 } 58 59 //add coordinates every 0.2 radians 60 $a=$sa+0.2; 61 while ($a<$ea) { 62 $xp = floor($width*cos($a)/2+$xc); 63 if ($a >= M_PI && $a <= 2*M_PI*1.01) { 64 $yp = floor($yc-($height*sin($a)/2)+$thick*$width); 65 } else { 66 $yp = floor($yc-$height*sin($a)/2); 67 } 68 $coords.= ", $xp, $yp"; 69 $a += 0.2; 70 } 71 72 //Add the last point on the arc 73 $xp = floor($width*cos($ea)/2+$xc); 74 $yp = floor($yc-$height*sin($ea)/2); 75 76 //If on the front half, add the thickness offset 77 if ($ea >= M_PI && $ea <= 2*M_PI*1.01) { 78 $coords.= ", $xp, ".floor($yp+($thick*$width)); 79 } 80 $coords.= ", $xp, $yp"; 81 if( !empty($this->csimalts[$i]) ) { 82 $tmp=sprintf($this->csimalts[$i],$this->data[$i]); 83 $alt="alt=\"$tmp\""; 84 } 85 if( !empty($this->csimtargets[$i]) ) 86 $this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->csimtargets[$i]."\" $alt>\r\n"; 87 } 88 89 90 function ExplodeSlice($e) { 91 JpGraphError::Raise("JpGraph Error: Exploding slices are not (yet) implemented for 3d pies graphs."); 92 //$this->explode_slice=$e; 93 } 94 95 // Distance from the pie to the labels 96 function SetLabelMargin($m) { 97 assert($m>0 && $m<1); 98 $this->labelmargin=$m; 99 } 100 101 // Show a thin line from the pie to the label for a specific slice 102 function ShowLabelHint($f=true) { 103 $this->showlabelhint=$f; 104 } 105 106 // Set color of hint line to label for each slice 107 function SetLabelHintColor($c) { 108 $this->labelhintcolor=$c; 109 } 110 111 function Stroke(&$img) { 112 113 $colors = array_keys($img->rgb->rgb_table); 114 sort($colors); 115 $ta=$this->themearr[$this->theme]; 116 117 if( $this->setslicecolors==null ) 118 $numcolors=count($ta); 119 else 120 $numcolors=count($this->setslicecolors); 121 122 // Draw the slices 123 $sum=0; 124 foreach($this->data as $d) 125 $sum += $d; 126 127 // Format the titles for each slice 128 for( $i=0; $i<count($this->data); ++$i) { 129 if( $this->labeltype==0 ) 130 if( $sum != 0 ) 131 $l = round(100*$this->data[$i]/$sum,$this->precision); 132 else 133 $l=0; 134 else 135 $l = $this->data[$i]; 136 $l = sprintf($this->labelformat,$l); 137 if( $this->show_psign ) $l .= "%"; 138 $this->labels[$i]=$l; 139 } 140 141 // Set up the pie-circle with some heuristic constants 142 $thick=0.16-($this->angle-20)/60*0.07; 143 144 $width = floor(2.0*$this->radius*min($img->width,$img->height)); 145 $height = ($this->angle/90.0)*$width; 146 $xc = $this->posx*$img->width; 147 $yc = $this->posy*$img->height; 148 149 $img->SetColor($this->color); 150 $img->Ellipse($xc,$yc,$width,$height); 151 $img->Arc($xc,$yc+$width*$thick,$width,$height,0,180); 152 $img->Line($xc+$width/2,$yc,$xc+$width/2,$yc+$width*$thick); 153 $img->Line($xc-$width/2,$yc,$xc-$width/2,$yc+$width*$thick); 154 $fillPerimeter[0] = array('x' => round((($xc - ($width / 2)) + 1)), 155 'y' => round(($yc + ($width * $thick) / 2))); 156 157 // Draw the first slice first line 158 $img->SetColor($this->color); 159 $img->SetLineWeight($this->weight); 160 $a = $this->startangle; 161 162 $xp = $width*cos($a)/2+$xc; 163 $yp = $yc-$height*sin($a)/2; 164 $img->Line($xc,$yc,$xp,$yp); 165 166 for($i=0; $sum>0 && $i<count($this->data); $i++) { 167 $img->SetColor($this->color); 168 $d = $this->data[$i]; 169 $la = $a + M_PI*$d/$sum; 170 $old_a = $a; 171 $a += 2*M_PI*$d/$sum; 172 173 if ($this->csimtargets[$i]) { 174 $this->AddSliceToCSIM($i,$xc,$yc,$height,$width,$thick,$old_a,$a); 175 } 176 177 $xp = $width*cos($a)/2+$xc; 178 $yp = $yc-$height*sin($a)/2; 179 180 if( $i<count($this->data)-1) 181 $img->Line($xc,$yc,$xp,$yp); 182 183 if( $a > M_PI && $a < 0.999*2*M_PI ) 184 $img->Line($xp,$yp,$xp,$yp+$width*$thick-1); 185 186 if($a < M_PI) { 187 $fillPerimeter[$i + 1] = $fillPerimeter[$i]; 188 } else { 189 $fillPerimeter[$i + 1] = array('x' => round(($xp + 1)), 190 'y' => round(($yp + ($width * $thick) / 2))); 191 } 192 193 if( $this->setslicecolors==null ) 194 $slicecolor=$colors[$ta[$i%$numcolors]]; 195 else 196 $slicecolor=$this->setslicecolors[$i%$numcolors]; 197 198 if( $this->show_labels ) { 199 $margin = 1 + $this->labelmargin; 200 $xp = $width*cos($la)/2*$margin; 201 $yp = $height*sin($la)/2*$margin; 202 203 if( ($la >= 0 && $la <= M_PI) || $la>2*M_PI*0.98 ) { 204 $this->StrokeLabels($this->labels[$i],$img,$la,$xc+$xp,$yc-$yp); 205 if( $this->showlabelhint ) { 206 $img->SetColor($this->labelhintcolor); 207 $img->Line($xc+$xp/$margin,$yc-$yp/$margin,$xc+$xp,$yc-$yp); 208 } 209 } 210 else { 211 $this->StrokeLabels($this->labels[$i],$img,$la,$xc+$xp,$yc-$yp+$width*$thick); 212 if( $this->showlabelhint ) { 213 $img->SetColor($this->labelhintcolor); 214 $img->Line($xc+$xp/$margin,$yc-$yp/$margin+$width*$thick,$xc+$xp,$yc-$yp+$width*$thick); 215 } 216 } 217 218 219 $img->SetColor($slicecolor); 220 $xp = $width*cos($la)/3+$xc; 221 $yp = $yc-$height*sin($la)/3; 222 $img->Fill(round($xp), round($yp)); 223 224 // Make the edge color 35% darker 225 $img->SetColor($slicecolor.":0.65"); 226 227 if($fillPerimeter[$i]['x'] <= $xc + ($width / 2)) { 228 $img->Fill($fillPerimeter[$i]['x'],$fillPerimeter[$i]['y']); 229 } 230 } 231 } 232 233 // Adjust title position 234 $this->title->Pos($xc,$yc-$img->GetFontHeight()-$this->radius,"center","bottom"); 235 $this->title->Stroke($img); 236 237 // Draw the pie ellipse one more time since the filling might have 238 // written partly on the lines due to the filling in the edges. 239 $img->SetColor($this->color); 240 $img->Ellipse($xc,$yc,$width,$height); 241 $img->Arc($xc,$yc+$width*$thick,$width,$height,0,180); 242 243 // Draw the first slice first line 244 $a = $this->startangle; 245 $xp = $width*cos($a)/2+$xc; 246 $yp = $yc-$height*sin($a)/2; 247 $img->Line($xc,$yc,$xp,$yp); 248 249 // Draw the rest of the slice lines 250 for($i=0, $a=0; $sum>0 && $i<count($this->data); $i++) { 251 $d = $this->data[$i]; 252 $la = $a + M_PI*$d/$sum; 253 $old_a = $a; 254 $a += 2*M_PI*$d/$sum; 255 256 $xp = $width*cos($a)/2+$xc; 257 $yp = $yc-$height*sin($a)/2; 258 259 if( $a > M_PI && $a < 0.999*2*M_PI ) 260 $img->Line($xp,$yp,$xp,$yp+$width*$thick-1); 261 262 if( $i<count($this->data)-1) 263 $img->Line($xc,$yc,$xp,$yp); 264 } 265 266 $img->Line($xc+$width/2,$yc,$xc+$width/2,$yc+$width*$thick); 267 $img->Line($xc-$width/2,$yc,$xc-$width/2,$yc+$width*$thick); 268 269 } 270 271 //--------------- 272 // PRIVATE METHODS 273 274 // Position the labels of each slice 275 function StrokeLabels($label,$img,$a,$xp,$yp) { 276 277 $img->SetFont($this->font_family,$this->font_style,$this->font_size); 278 $img->SetColor($this->font_color); 279 $img->SetTextAlign("left","top"); 280 $marg=6; 281 282 // Position the axis title. 283 // dx, dy is the offset from the top left corner of the bounding box that sorrounds the text 284 // that intersects with the extension of the corresponding axis. The code looks a little 285 // bit messy but this is really the only way of having a reasonable position of the 286 // axis titles. 287 $h=$img->GetTextHeight($label); 288 $w=$img->GetTextWidth($label); 289 while( $a > 2*M_PI ) $a -= 2*M_PI; 290 if( $a>=7*M_PI/4 || $a <= M_PI/4 ) $dx=0; 291 if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dx=($a-M_PI/4)*2/M_PI; 292 if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dx=1; 293 if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dx=(1-($a-M_PI*5/4)*2/M_PI); 294 295 if( $a>=7*M_PI/4 ) $dy=(($a-M_PI)-3*M_PI/4)*2/M_PI; 296 if( $a<=M_PI/4 ) $dy=(1-$a*2/M_PI); 297 if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dy=1; 298 if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dy=(1-($a-3*M_PI/4)*2/M_PI); 299 if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dy=0; 300 301 $img->StrokeText($xp-$dx*$w,$yp-$dy*$h,$label); 302 } 303 } // Class 304 305 /* EOF */ 306 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 17:20:01 2007 | par Balluche grâce à PHPXref 0.7 |