Changeset 284 for trunk/client
- Timestamp:
- Apr 21, 2019, 11:49:56 PM (6 years ago)
- Location:
- trunk/client
- Files:
-
- 46 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/client/modules/Elezioni/grafici.php
r268 r284 605 605 echo "</td></tr></table><table><tr><td>"; 606 606 # grafico flash 607 #if($flash=='1') flash_torta($gruppos,$pre,40,145);607 if($flash=='1') flash_torta($gruppos,$pre,40,145); 608 608 $uno=''; 609 609 foreach($gruppos as $k=>$v) $uno.="- $v"; 610 610 $due='due:'; 611 611 foreach($pre as $k=>$v) $due.="- $v"; 612 include("flash_torta($uno,$due,20,70)");613 612 echo "</td></tr></table>"; 614 613 -
trunk/client/modules/Elezioni/grafici/gd_image.inc.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id$3 // File: GD_IMAGE.INC.PHP 4 // Description: PHP Graph Plotting library. Low level image drawing routines 5 // Created: 2001-01-08, refactored 2008-03-29 6 // Ver: $Id: gd_image.inc.php 1922 2010-01-11 11:42:50Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 11 12 //=================================================== 11 require_once 'jpgraph_rgb.inc.php'; 12 require_once 'jpgraph_ttf.inc.php'; 13 require_once 'imageSmoothArc.php'; 14 require_once 'jpgraph_errhandler.inc.php'; 15 16 // Line styles 17 define('LINESTYLE_SOLID',1); 18 define('LINESTYLE_DOTTED',2); 19 define('LINESTYLE_DASHED',3); 20 define('LINESTYLE_LONGDASH',4); 21 22 // The DEFAULT_GFORMAT sets the default graphic encoding format, i.e. 23 // PNG, JPG or GIF depending on what is installed on the target system 24 // in that order. 25 if( !DEFINED("DEFAULT_GFORMAT") ) { 26 define("DEFAULT_GFORMAT","auto"); 27 } 28 29 //======================================================================== 13 30 // CLASS Image 14 // Description: Wrapper class with some goodies to form the 15 // Interface to low level image drawing routines. 16 //=================================================== 31 // Description: The very coor image drawing class that encapsulates all 32 // calls to the GD library 33 // Note: The class used by the library is the decendant 34 // class RotImage which extends the Image class with transparent 35 // rotation. 36 //========================================================================= 17 37 class Image { 18 public $left_margin=30,$right_margin=30,$top_margin=20,$bottom_margin=30;19 38 public $img=null; 20 public $plotwidth=0,$plotheight=0;21 public $width=0, $height=0;22 39 public $rgb=null; 23 public $current_color,$current_color_name;24 public $line_weight=1, $line_style=LINESTYLE_SOLID;25 40 public $img_format; 26 41 public $ttf=null; 42 public $line_style=LINESTYLE_SOLID; 43 public $current_color,$current_color_name; 44 public $original_width=0, $original_height=0; 45 public $plotwidth=0,$plotheight=0; 46 47 // for __get, __set 48 private $_left_margin=30,$_right_margin=30,$_top_margin=20,$_bottom_margin=30; 49 //private $_plotwidth=0,$_plotheight=0; 50 private $_width=0, $_height=0; 51 private $_line_weight=1; 52 27 53 protected $expired=true; 28 54 protected $lastx=0, $lasty=0; 29 55 protected $obs_list=array(); 30 protected $font_size=12,$font_family=FF_ FONT1, $font_style=FS_NORMAL;56 protected $font_size=12,$font_family=FF_DEFAULT, $font_style=FS_NORMAL; 31 57 protected $font_file=''; 32 58 protected $text_halign="left",$text_valign="bottom"; … … 37 63 protected $langconv = null ; 38 64 protected $iInterlace=false; 65 protected $bbox_cache = array(); // STore the last found tetx bounding box 66 protected $ff_font0; 67 protected $ff_font0_bold; 68 protected $ff_font1; 69 protected $ff_font1_bold; 70 protected $ff_font2; 71 protected $ff_font2_bold; 72 73 39 74 //--------------- 40 75 // CONSTRUCTOR 41 function Image($aWidth,$aHeight,$aFormat=DEFAULT_GFORMAT,$aSetAutoMargin=true) { 42 $this->CreateImgCanvas($aWidth,$aHeight); 43 if( $aSetAutoMargin ) 44 $this->SetAutoMargin(); 45 46 if( !$this->SetImgFormat($aFormat) ) { 47 JpGraphError::RaiseL(25081,$aFormat);//("JpGraph: Selected graphic format is either not supported or unknown [$aFormat]"); 48 } 49 $this->ttf = new TTF(); 50 $this->langconv = new LanguageConv(); 76 function __construct($aWidth=0,$aHeight=0,$aFormat=DEFAULT_GFORMAT,$aSetAutoMargin=true) { 77 78 $this->original_width = $aWidth; 79 $this->original_height = $aHeight; 80 $this->CreateImgCanvas($aWidth, $aHeight); 81 82 if( $aSetAutoMargin ) { 83 $this->SetAutoMargin(); 84 } 85 86 if( !$this->SetImgFormat($aFormat) ) { 87 JpGraphError::RaiseL(25081,$aFormat);//("JpGraph: Selected graphic format is either not supported or unknown [$aFormat]"); 88 } 89 $this->ttf = new TTF(); 90 $this->langconv = new LanguageConv(); 91 92 $this->ff_font0 = imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT0.gdf"); 93 $this->ff_font1 = imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT1.gdf"); 94 $this->ff_font2 = imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT2.gdf"); 95 $this->ff_font1_bold = imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT1-Bold.gdf"); 96 $this->ff_font2_bold = imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT2-Bold.gdf"); 51 97 } 52 98 53 99 // Enable interlacing in images 54 100 function SetInterlace($aFlg=true) { 55 101 $this->iInterlace=$aFlg; 56 102 } 57 103 58 104 // Should we use anti-aliasing. Note: This really slows down graphics! 59 105 function SetAntiAliasing($aFlg=true) { 60 $this->use_anti_aliasing = $aFlg; 61 if( function_exists('imageantialias') ) { 62 imageantialias($this->img,$aFlg); 63 } 64 else { 65 JpGraphError::RaiseL(25128);//('The function imageantialias() is not available in your PHP installation. Use the GD version that comes with PHP and not the standalone version.') 66 } 106 $this->use_anti_aliasing = $aFlg; 107 if( function_exists('imageantialias') ) { 108 imageantialias($this->img,$aFlg); 109 } 110 else { 111 JpGraphError::RaiseL(25128);//('The function imageantialias() is not available in your PHP installation. Use the GD version that comes with PHP and not the standalone version.') 112 } 113 } 114 115 function GetAntiAliasing() { 116 return $this->use_anti_aliasing ; 67 117 } 68 118 69 119 function CreateRawCanvas($aWidth=0,$aHeight=0) { 70 if( $aWidth <= 1 || $aHeight <= 1 ) { 71 JpGraphError::RaiseL(25082,$aWidth,$aHeight);//("Illegal sizes specified for width or height when creating an image, (width=$aWidth, height=$aHeight)"); 72 } 73 74 if( USE_TRUECOLOR ) { 75 $this->img = @imagecreatetruecolor($aWidth, $aHeight); 76 if( $this->img < 1 ) { 77 JpGraphError::RaiseL(25126); 78 //die("Can't create truecolor image. Check that you really have GD2 library installed."); 79 } 80 $this->SetAlphaBlending(); 81 } else { 82 $this->img = @imagecreate($aWidth, $aHeight); 83 if( $this->img < 1 ) { 84 JpGraphError::RaiseL(25126); 85 //die("<b>JpGraph Error:</b> Can't create image. Check that you really have the GD library installed."); 86 } 87 } 88 89 if( $this->iInterlace ) { 90 imageinterlace($this->img,1); 91 } 92 if( $this->rgb != null ) 93 $this->rgb->img = $this->img ; 94 else 95 $this->rgb = new RGB($this->img); 120 121 $aWidth *= SUPERSAMPLING_SCALE; 122 $aHeight *= SUPERSAMPLING_SCALE; 123 124 if( $aWidth <= 1 || $aHeight <= 1 ) { 125 JpGraphError::RaiseL(25082,$aWidth,$aHeight);//("Illegal sizes specified for width or height when creating an image, (width=$aWidth, height=$aHeight)"); 126 } 127 128 $this->img = @imagecreatetruecolor($aWidth, $aHeight); 129 if( $this->img < 1 ) { 130 JpGraphError::RaiseL(25126); 131 //die("Can't create truecolor image. Check that you really have GD2 library installed."); 132 } 133 $this->SetAlphaBlending(); 134 135 if( $this->iInterlace ) { 136 imageinterlace($this->img,1); 137 } 138 if( $this->rgb != null ) { 139 $this->rgb->img = $this->img ; 140 } 141 else { 142 $this->rgb = new RGB($this->img); 143 } 96 144 } 97 145 98 146 function CloneCanvasH() { 99 100 101 102 103 } 104 147 $oldimage = $this->img; 148 $this->CreateRawCanvas($this->width,$this->height); 149 imagecopy($this->img,$oldimage,0,0,0,0,$this->width,$this->height); 150 return $oldimage; 151 } 152 105 153 function CreateImgCanvas($aWidth=0,$aHeight=0) { 106 154 107 108 109 110 111 112 113 $this->height=$aHeight; 114 115 116 117 // We will set the final size later. 118 119 120 121 122 123 124 125 126 // Set canvas color (will also be the background color for a 127 128 $this->SetColor($this->canvascolor); 129 $this->FilledRectangle(0,0,$aWidth,$aHeight);130 131 155 $old = array($this->img,$this->width,$this->height); 156 157 $aWidth = round($aWidth); 158 $aHeight = round($aHeight); 159 160 $this->width=$aWidth; 161 $this->height=$aHeight; 162 163 164 if( $aWidth==0 || $aHeight==0 ) { 165 // We will set the final size later. 166 // Note: The size must be specified before any other 167 // img routines that stroke anything are called. 168 $this->img = null; 169 $this->rgb = null; 170 return $old; 171 } 172 173 $this->CreateRawCanvas($aWidth,$aHeight); 174 // Set canvas color (will also be the background color for a 175 // a pallett image 176 $this->SetColor($this->canvascolor); 177 $this->FilledRectangle(0,0,$this->width-1,$this->height-1); 178 179 return $old ; 132 180 } 133 181 134 182 function CopyCanvasH($aToHdl,$aFromHdl,$aToX,$aToY,$aFromX,$aFromY,$aWidth,$aHeight,$aw=-1,$ah=-1) { 135 136 137 138 139 140 141 142 143 183 if( $aw === -1 ) { 184 $aw = $aWidth; 185 $ah = $aHeight; 186 $f = 'imagecopyresized'; 187 } 188 else { 189 $f = 'imagecopyresampled'; 190 } 191 $f($aToHdl,$aFromHdl,$aToX,$aToY,$aFromX,$aFromY, $aWidth,$aHeight,$aw,$ah); 144 192 } 145 193 146 194 function Copy($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth=-1,$fromHeight=-1) { 147 $this->CopyCanvasH($this->img,$fromImg,$toX,$toY,$fromX,$fromY, 148 $toWidth,$toHeight,$fromWidth,$fromHeight); 195 $this->CopyCanvasH($this->img,$fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth,$fromHeight); 149 196 } 150 197 151 198 function CopyMerge($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth=-1,$fromHeight=-1,$aMix=100) { 152 if( $aMix == 100 ) { 153 $this->CopyCanvasH($this->img,$fromImg, 154 $toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth,$fromHeight); 155 } 156 else { 157 if( ($fromWidth != -1 && ($fromWidth != $toWidth)) || 158 ($fromHeight != -1 && ($fromHeight != $fromHeight)) ) { 159 // Create a new canvas that will hold the re-scaled original from image 160 if( $toWidth <= 1 || $toHeight <= 1 ) { 161 JpGraphError::RaiseL(25083);//('Illegal image size when copying image. Size for copied to image is 1 pixel or less.'); 162 } 163 if( USE_TRUECOLOR ) { 164 $tmpimg = @imagecreatetruecolor($toWidth, $toHeight); 165 } else { 166 $tmpimg = @imagecreate($toWidth, $toHeight); 167 } 168 if( $tmpimg < 1 ) { 169 JpGraphError::RaiseL(25084);//('Failed to create temporary GD canvas. Out of memory ?'); 170 } 171 $this->CopyCanvasH($tmpimg,$fromImg,0,0,0,0, 172 $toWidth,$toHeight,$fromWidth,$fromHeight); 173 $fromImg = $tmpimg; 174 } 175 imagecopymerge($this->img,$fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$aMix); 176 } 199 if( $aMix == 100 ) { 200 $this->CopyCanvasH($this->img,$fromImg, 201 $toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth,$fromHeight); 202 } 203 else { 204 if( ($fromWidth != -1 && ($fromWidth != $toWidth)) || ($fromHeight != -1 && ($fromHeight != $fromHeight)) ) { 205 // Create a new canvas that will hold the re-scaled original from image 206 if( $toWidth <= 1 || $toHeight <= 1 ) { 207 JpGraphError::RaiseL(25083);//('Illegal image size when copying image. Size for copied to image is 1 pixel or less.'); 208 } 209 210 $tmpimg = @imagecreatetruecolor($toWidth, $toHeight); 211 212 if( $tmpimg < 1 ) { 213 JpGraphError::RaiseL(25084);//('Failed to create temporary GD canvas. Out of memory ?'); 214 } 215 $this->CopyCanvasH($tmpimg,$fromImg,0,0,0,0, 216 $toWidth,$toHeight,$fromWidth,$fromHeight); 217 $fromImg = $tmpimg; 218 } 219 imagecopymerge($this->img,$fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$aMix); 220 } 177 221 } 178 222 179 223 static function GetWidth($aImg=null) { 180 if( $aImg === null ) 181 $aImg = $this->img; 182 return imagesx($aImg); 224 if( $aImg === null ) { 225 $aImg = $this->img; 226 } 227 return imagesx($aImg); 183 228 } 184 229 185 230 static function GetHeight($aImg=null) { 186 if( $aImg === null ) 187 $aImg = $this->img; 188 return imagesy($aImg); 189 } 190 231 if( $aImg === null ) { 232 $aImg = $this->img; 233 } 234 return imagesy($aImg); 235 } 236 191 237 static function CreateFromString($aStr) { 192 $img = imagecreatefromstring($aStr); 193 if( $img === false ) { 194 JpGraphError::RaiseL(25085);//('An image can not be created from the supplied string. It is either in a format not supported or the string is representing an corrupt image.'); 195 } 196 return $img; 238 $img = imagecreatefromstring($aStr); 239 if( $img === false ) { 240 JpGraphError::RaiseL(25085); 241 //('An image can not be created from the supplied string. It is either in a format not supported or the string is representing an corrupt image.'); 242 } 243 return $img; 197 244 } 198 245 199 246 function SetCanvasH($aHdl) { 200 201 247 $this->img = $aHdl; 248 $this->rgb->img = $aHdl; 202 249 } 203 250 204 251 function SetCanvasColor($aColor) { 205 252 $this->canvascolor = $aColor ; 206 253 } 207 254 208 255 function SetAlphaBlending($aFlg=true) { 209 ImageAlphaBlending($this->img,$aFlg); 210 } 211 212 213 function SetAutoMargin() { 214 GLOBAL $gJpgBrandTiming; 215 $min_bm=5; 216 /* 217 if( $gJpgBrandTiming ) 218 $min_bm=15; 219 */ 220 $lm = min(40,$this->width/7); 221 $rm = min(20,$this->width/10); 222 $tm = max(5,$this->height/7); 223 $bm = max($min_bm,$this->height/7); 224 $this->SetMargin($lm,$rm,$tm,$bm); 225 } 226 227 256 ImageAlphaBlending($this->img,$aFlg); 257 } 258 259 function SetAutoMargin() { 260 $min_bm=5; 261 $lm = min(40,$this->width/7); 262 $rm = min(20,$this->width/10); 263 $tm = max(5,$this->height/7); 264 $bm = max($min_bm,$this->height/6); 265 $this->SetMargin($lm,$rm,$tm,$bm); 266 } 267 228 268 //--------------- 229 // PUBLIC METHODS 230 269 // PUBLIC METHODS 270 231 271 function SetFont($family,$style=FS_NORMAL,$size=10) { 232 $this->font_family=$family; 233 $this->font_style=$style; 234 $this->font_size=$size; 235 $this->font_file=''; 236 if( ($this->font_family==FF_FONT1 || $this->font_family==FF_FONT2) && $this->font_style==FS_BOLD ){ 237 ++$this->font_family; 238 } 239 if( $this->font_family > FF_FONT2+1 ) { // A TTF font so get the font file 240 241 // Check that this PHP has support for TTF fonts 242 if( !function_exists('imagettfbbox') ) { 243 JpGraphError::RaiseL(25087);//('This PHP build has not been configured with TTF support. You need to recompile your PHP installation with FreeType support.'); 244 } 245 $this->font_file = $this->ttf->File($this->font_family,$this->font_style); 246 } 272 $this->font_family=$family; 273 $this->font_style=$style; 274 $this->font_size=$size*SUPERSAMPLING_SCALE; 275 $this->font_file=''; 276 if( ($this->font_family==FF_FONT1 || $this->font_family==FF_FONT2) && $this->font_style==FS_BOLD ){ 277 ++$this->font_family; 278 } 279 if( $this->font_family > FF_FONT2+1 ) { // A TTF font so get the font file 280 281 // Check that this PHP has support for TTF fonts 282 if( !function_exists('imagettfbbox') ) { 283 // use internal font when php is configured without '--with-ttf' 284 $this->font_family = FF_FONT1; 285 // JpGraphError::RaiseL(25087);//('This PHP build has not been configured with TTF support. You need to recompile your PHP installation with FreeType support.'); 286 } else { 287 $this->font_file = $this->ttf->File($this->font_family,$this->font_style); 288 } 289 } 247 290 } 248 291 249 292 // Get the specific height for a text string 250 293 function GetTextHeight($txt="",$angle=0) { 251 $tmp = split("\n",$txt); 252 $n = count($tmp); 253 $m=0; 254 for($i=0; $i< $n; ++$i) 255 $m = max($m,strlen($tmp[$i])); 256 257 if( $this->font_family <= FF_FONT2+1 ) { 258 if( $angle==0 ) { 259 $h = imagefontheight($this->font_family); 260 if( $h === false ) { 261 JpGraphError::RaiseL(25088);//('You have a misconfigured GD font support. The call to imagefontwidth() fails.'); 262 } 263 264 return $n*$h; 265 } 266 else { 267 $w = @imagefontwidth($this->font_family); 268 if( $w === false ) { 269 JpGraphError::RaiseL(25088);//('You have a misconfigured GD font support. The call to imagefontwidth() fails.'); 270 } 271 272 return $m*$w; 273 } 274 } 275 else { 276 $bbox = $this->GetTTFBBox($txt,$angle); 277 return $bbox[1]-$bbox[5]; 278 } 279 } 280 294 $tmp = preg_split('/\n/',$txt); 295 $n = count($tmp); 296 $m=0; 297 for($i=0; $i< $n; ++$i) { 298 $m = max($m,strlen($tmp[$i])); 299 } 300 301 if( $this->font_family <= FF_FONT2+1 ) { 302 if( $angle==0 ) { 303 $h = imagefontheight($this->font_family); 304 if( $h === false ) { 305 JpGraphError::RaiseL(25088);//('You have a misconfigured GD font support. The call to imagefontwidth() fails.'); 306 } 307 308 return $n*$h; 309 } 310 else { 311 $w = @imagefontwidth($this->font_family); 312 if( $w === false ) { 313 JpGraphError::RaiseL(25088);//('You have a misconfigured GD font support. The call to imagefontwidth() fails.'); 314 } 315 316 return $m*$w; 317 } 318 } 319 else { 320 $bbox = $this->GetTTFBBox($txt,$angle); 321 return $bbox[1]-$bbox[5]+1; 322 } 323 } 324 281 325 // Estimate font height 282 326 function GetFontHeight($angle=0) { 283 284 285 } 286 327 $txt = "XOMg"; 328 return $this->GetTextHeight($txt,$angle); 329 } 330 287 331 // Approximate font width with width of letter "O" 288 332 function GetFontWidth($angle=0) { 289 $txt = 'O'; 290 return $this->GetTextWidth($txt,$angle); 291 } 292 293 // Get actual width of text in absolute pixels 333 $txt = 'O'; 334 return $this->GetTextWidth($txt,$angle); 335 } 336 337 // Get actual width of text in absolute pixels. Note that the width is the 338 // texts projected with onto the x-axis. Call with angle=0 to get the true 339 // etxt width. 294 340 function GetTextWidth($txt,$angle=0) { 295 341 296 $tmp = split("\n",$txt); 297 $n = count($tmp); 298 if( $this->font_family <= FF_FONT2+1 ) { 299 300 $m=0; 301 for($i=0; $i < $n; ++$i) { 302 $l=strlen($tmp[$i]); 303 if( $l > $m ) { 304 $m = $l; 305 } 306 } 307 308 if( $angle==0 ) { 309 $w = @imagefontwidth($this->font_family); 310 if( $w === false ) { 311 JpGraphError::RaiseL(25088);//('You have a misconfigured GD font support. The call to imagefontwidth() fails.'); 312 } 313 return $m*$w; 314 } 315 else { 316 // 90 degrees internal so height becomes width 317 $h = @imagefontheight($this->font_family); 318 if( $h === false ) { 319 JpGraphError::RaiseL(25089);//('You have a misconfigured GD font support. The call to imagefontheight() fails.'); 320 } 321 return $n*$h; 322 } 323 } 324 else { 325 // For TTF fonts we must walk through a lines and find the 326 // widest one which we use as the width of the multi-line 327 // paragraph 328 $m=0; 329 for( $i=0; $i < $n; ++$i ) { 330 $bbox = $this->GetTTFBBox($tmp[$i],$angle); 331 $mm = $bbox[2] - $bbox[0]; 332 if( $mm > $m ) 333 $m = $mm; 334 } 335 return $m; 336 } 337 } 338 342 $tmp = preg_split('/\n/',$txt); 343 $n = count($tmp); 344 if( $this->font_family <= FF_FONT2+1 ) { 345 346 $m=0; 347 for($i=0; $i < $n; ++$i) { 348 $l=strlen($tmp[$i]); 349 if( $l > $m ) { 350 $m = $l; 351 } 352 } 353 354 if( $angle==0 ) { 355 $w = @imagefontwidth($this->font_family); 356 if( $w === false ) { 357 JpGraphError::RaiseL(25088);//('You have a misconfigured GD font support. The call to imagefontwidth() fails.'); 358 } 359 return $m*$w; 360 } 361 else { 362 // 90 degrees internal so height becomes width 363 $h = @imagefontheight($this->font_family); 364 if( $h === false ) { 365 JpGraphError::RaiseL(25089);//('You have a misconfigured GD font support. The call to imagefontheight() fails.'); 366 } 367 return $n*$h; 368 } 369 } 370 else { 371 // For TTF fonts we must walk through a lines and find the 372 // widest one which we use as the width of the multi-line 373 // paragraph 374 $m=0; 375 for( $i=0; $i < $n; ++$i ) { 376 $bbox = $this->GetTTFBBox($tmp[$i],$angle); 377 $mm = $bbox[2] - $bbox[0]; 378 if( $mm > $m ) 379 $m = $mm; 380 } 381 return $m; 382 } 383 } 384 385 339 386 // Draw text with a box around it 340 387 function StrokeBoxedText($x,$y,$txt,$dir=0,$fcolor="white",$bcolor="black", 341 $shadowcolor=false,$paragraph_align="left", 342 $xmarg=6,$ymarg=4,$cornerradius=0,$dropwidth=3) { 343 344 if( !is_numeric($dir) ) { 345 if( $dir=="h" ) $dir=0; 346 elseif( $dir=="v" ) $dir=90; 347 else JpGraphError::RaiseL(25090,$dir);//(" Unknown direction specified in call to StrokeBoxedText() [$dir]"); 348 } 349 350 if( $this->font_family >= FF_FONT0 && $this->font_family <= FF_FONT2+1) { 351 $width=$this->GetTextWidth($txt,$dir) ; 352 $height=$this->GetTextHeight($txt,$dir) ; 353 } 354 else { 355 $width=$this->GetBBoxWidth($txt,$dir) ; 356 $height=$this->GetBBoxHeight($txt,$dir) ; 357 } 358 359 $height += 2*$ymarg; 360 $width += 2*$xmarg; 361 362 if( $this->text_halign=="right" ) $x -= $width; 363 elseif( $this->text_halign=="center" ) $x -= $width/2; 364 if( $this->text_valign=="bottom" ) $y -= $height; 365 elseif( $this->text_valign=="center" ) $y -= $height/2; 366 367 $olda = $this->SetAngle(0); 368 369 if( $shadowcolor ) { 370 $this->PushColor($shadowcolor); 371 $this->FilledRoundedRectangle($x-$xmarg+$dropwidth,$y-$ymarg+$dropwidth, 372 $x+$width+$dropwidth,$y+$height-$ymarg+$dropwidth, 373 $cornerradius); 374 $this->PopColor(); 375 $this->PushColor($fcolor); 376 $this->FilledRoundedRectangle($x-$xmarg,$y-$ymarg, 377 $x+$width,$y+$height-$ymarg, 378 $cornerradius); 379 $this->PopColor(); 380 $this->PushColor($bcolor); 381 $this->RoundedRectangle($x-$xmarg,$y-$ymarg, 382 $x+$width,$y+$height-$ymarg,$cornerradius); 383 $this->PopColor(); 384 } 385 else { 386 if( $fcolor ) { 387 $oc=$this->current_color; 388 $this->SetColor($fcolor); 389 $this->FilledRoundedRectangle($x-$xmarg,$y-$ymarg,$x+$width,$y+$height-$ymarg,$cornerradius); 390 $this->current_color=$oc; 391 } 392 if( $bcolor ) { 393 $oc=$this->current_color; 394 $this->SetColor($bcolor); 395 $this->RoundedRectangle($x-$xmarg,$y-$ymarg,$x+$width,$y+$height-$ymarg,$cornerradius); 396 $this->current_color=$oc; 397 } 398 } 399 400 $h=$this->text_halign; 401 $v=$this->text_valign; 402 $this->SetTextAlign("left","top"); 403 $this->StrokeText($x, $y, $txt, $dir, $paragraph_align); 404 $bb = array($x-$xmarg,$y+$height-$ymarg,$x+$width,$y+$height-$ymarg, 405 $x+$width,$y-$ymarg,$x-$xmarg,$y-$ymarg); 406 $this->SetTextAlign($h,$v); 407 408 $this->SetAngle($olda); 409 410 return $bb; 411 } 412 413 // Set text alignment 388 $shadowcolor=false,$paragraph_align="left", 389 $xmarg=6,$ymarg=4,$cornerradius=0,$dropwidth=3) { 390 391 $oldx = $this->lastx; 392 $oldy = $this->lasty; 393 394 if( !is_numeric($dir) ) { 395 if( $dir=="h" ) $dir=0; 396 elseif( $dir=="v" ) $dir=90; 397 else JpGraphError::RaiseL(25090,$dir);//(" Unknown direction specified in call to StrokeBoxedText() [$dir]"); 398 } 399 400 if( $this->font_family >= FF_FONT0 && $this->font_family <= FF_FONT2+1) { 401 $width=$this->GetTextWidth($txt,$dir) ; 402 $height=$this->GetTextHeight($txt,$dir) ; 403 } 404 else { 405 $width=$this->GetBBoxWidth($txt,$dir) ; 406 $height=$this->GetBBoxHeight($txt,$dir) ; 407 } 408 409 $height += 2*$ymarg; 410 $width += 2*$xmarg; 411 412 if( $this->text_halign=="right" ) $x -= $width; 413 elseif( $this->text_halign=="center" ) $x -= $width/2; 414 415 if( $this->text_valign=="bottom" ) $y -= $height; 416 elseif( $this->text_valign=="center" ) $y -= $height/2; 417 418 $olda = $this->SetAngle(0); 419 420 if( $shadowcolor ) { 421 $this->PushColor($shadowcolor); 422 $this->FilledRoundedRectangle($x-$xmarg+$dropwidth,$y-$ymarg+$dropwidth, 423 $x+$width+$dropwidth,$y+$height-$ymarg+$dropwidth, 424 $cornerradius); 425 $this->PopColor(); 426 $this->PushColor($fcolor); 427 $this->FilledRoundedRectangle($x-$xmarg,$y-$ymarg, 428 $x+$width,$y+$height-$ymarg, 429 $cornerradius); 430 $this->PopColor(); 431 $this->PushColor($bcolor); 432 $this->RoundedRectangle($x-$xmarg,$y-$ymarg, 433 $x+$width,$y+$height-$ymarg,$cornerradius); 434 $this->PopColor(); 435 } 436 else { 437 if( $fcolor ) { 438 $oc=$this->current_color; 439 $this->SetColor($fcolor); 440 $this->FilledRoundedRectangle($x-$xmarg,$y-$ymarg,$x+$width,$y+$height-$ymarg,$cornerradius); 441 $this->current_color=$oc; 442 } 443 if( $bcolor ) { 444 $oc=$this->current_color; 445 $this->SetColor($bcolor); 446 $this->RoundedRectangle($x-$xmarg,$y-$ymarg,$x+$width,$y+$height-$ymarg,$cornerradius); 447 $this->current_color=$oc; 448 } 449 } 450 451 $h=$this->text_halign; 452 $v=$this->text_valign; 453 $this->SetTextAlign("left","top"); 454 455 $debug=false; 456 $this->StrokeText($x, $y, $txt, $dir, $paragraph_align,$debug); 457 458 $bb = array($x-$xmarg,$y+$height-$ymarg,$x+$width,$y+$height-$ymarg, 459 $x+$width,$y-$ymarg,$x-$xmarg,$y-$ymarg); 460 $this->SetTextAlign($h,$v); 461 462 $this->SetAngle($olda); 463 $this->lastx = $oldx; 464 $this->lasty = $oldy; 465 466 return $bb; 467 } 468 469 // Draw text with a box around it. This time the box will be rotated 470 // with the text. The previous method will just make a larger enough non-rotated 471 // box to hold the text inside. 472 function StrokeBoxedText2($x,$y,$txt,$dir=0,$fcolor="white",$bcolor="black", 473 $shadowcolor=false,$paragraph_align="left", 474 $xmarg=6,$ymarg=4,$cornerradius=0,$dropwidth=3) { 475 476 // This version of boxed text will stroke a rotated box round the text 477 // thta will follow the angle of the text. 478 // This has two implications: 479 // 1) This methos will only support TTF fonts 480 // 2) The only two alignment that makes sense are centered or baselined 481 482 if( $this->font_family <= FF_FONT2+1 ) { 483 JpGraphError::RaiseL(25131);//StrokeBoxedText2() Only support TTF fonts and not built in bitmap fonts 484 } 485 486 $oldx = $this->lastx; 487 $oldy = $this->lasty; 488 $dir = $this->NormAngle($dir); 489 490 if( !is_numeric($dir) ) { 491 if( $dir=="h" ) $dir=0; 492 elseif( $dir=="v" ) $dir=90; 493 else JpGraphError::RaiseL(25090,$dir);//(" Unknown direction specified in call to StrokeBoxedText() [$dir]"); 494 } 495 496 $width=$this->GetTextWidth($txt,0) + 2*$xmarg; 497 $height=$this->GetTextHeight($txt,0) + 2*$ymarg ; 498 $rect_width=$this->GetBBoxWidth($txt,$dir) ; 499 $rect_height=$this->GetBBoxHeight($txt,$dir) ; 500 501 $baseline_offset = $this->bbox_cache[1]-1; 502 503 if( $this->text_halign=="center" ) { 504 if( $dir >= 0 && $dir <= 90 ) { 505 506 $x -= $rect_width/2; 507 $x += sin($dir*M_PI/180)*$height; 508 $y += $rect_height/2; 509 510 } elseif( $dir >= 270 && $dir <= 360 ) { 511 512 $x -= $rect_width/2; 513 $y -= $rect_height/2; 514 $y += cos($dir*M_PI/180)*$height; 515 516 } elseif( $dir >= 90 && $dir <= 180 ) { 517 518 $x += $rect_width/2; 519 $y += $rect_height/2; 520 $y += cos($dir*M_PI/180)*$height; 521 522 } 523 else { 524 // $dir > 180 && $dir < 270 525 $x += $rect_width/2; 526 $x += sin($dir*M_PI/180)*$height; 527 $y -= $rect_height/2; 528 } 529 } 530 531 // Rotate the box around this point 532 $this->SetCenter($x,$y); 533 $olda = $this->SetAngle(-$dir); 534 535 // We need to use adjusted coordinats for the box to be able 536 // to draw the box below the baseline. This cannot be done before since 537 // the rotating point must be the original x,y since that is arounbf the 538 // point where the text will rotate and we cannot change this since 539 // that is where the GD/GreeType will rotate the text 540 541 542 // For smaller <14pt font we need to do some additional 543 // adjustments to make it look good 544 if( $this->font_size < 14 ) { 545 $x -= 2; 546 $y += 2; 547 } 548 else { 549 // $y += $baseline_offset; 550 } 551 552 if( $shadowcolor ) { 553 $this->PushColor($shadowcolor); 554 $this->FilledRectangle($x-$xmarg+$dropwidth,$y+$ymarg+$dropwidth-$height, 555 $x+$width+$dropwidth,$y+$ymarg+$dropwidth); 556 //$cornerradius); 557 $this->PopColor(); 558 $this->PushColor($fcolor); 559 $this->FilledRectangle($x-$xmarg, $y+$ymarg-$height, 560 $x+$width, $y+$ymarg); 561 //$cornerradius); 562 $this->PopColor(); 563 $this->PushColor($bcolor); 564 $this->Rectangle($x-$xmarg,$y+$ymarg-$height, 565 $x+$width,$y+$ymarg); 566 //$cornerradius); 567 $this->PopColor(); 568 } 569 else { 570 if( $fcolor ) { 571 $oc=$this->current_color; 572 $this->SetColor($fcolor); 573 $this->FilledRectangle($x-$xmarg,$y+$ymarg-$height,$x+$width,$y+$ymarg);//,$cornerradius); 574 $this->current_color=$oc; 575 } 576 if( $bcolor ) { 577 $oc=$this->current_color; 578 $this->SetColor($bcolor); 579 $this->Rectangle($x-$xmarg,$y+$ymarg-$height,$x+$width,$y+$ymarg);//,$cornerradius); 580 $this->current_color=$oc; 581 } 582 } 583 584 if( $this->font_size < 14 ) { 585 $x += 2; 586 $y -= 2; 587 } 588 else { 589 590 // Restore the original y before we stroke the text 591 // $y -= $baseline_offset; 592 593 } 594 595 $this->SetCenter(0,0); 596 $this->SetAngle($olda); 597 598 $h=$this->text_halign; 599 $v=$this->text_valign; 600 if( $this->text_halign == 'center') { 601 $this->SetTextAlign('center','basepoint'); 602 } 603 else { 604 $this->SetTextAlign('basepoint','basepoint'); 605 } 606 607 $debug=false; 608 $this->StrokeText($x, $y, $txt, $dir, $paragraph_align,$debug); 609 610 $bb = array($x-$xmarg, $y+$height-$ymarg, 611 $x+$width, $y+$height-$ymarg, 612 $x+$width, $y-$ymarg, 613 $x-$xmarg, $y-$ymarg); 614 615 $this->SetTextAlign($h,$v); 616 $this->SetAngle($olda); 617 618 $this->lastx = $oldx; 619 $this->lasty = $oldy; 620 621 return $bb; 622 } 623 624 // Set text alignment 414 625 function SetTextAlign($halign,$valign="bottom") { 415 $this->text_halign=$halign; 416 $this->text_valign=$valign; 417 } 418 419 420 function _StrokeBuiltinFont($x,$y,$txt,$dir=0,$paragraph_align="left",&$aBoundingBox,$aDebug=false) { 421 422 if( is_numeric($dir) && $dir!=90 && $dir!=0) 423 JpGraphError::RaiseL(25091);//(" Internal font does not support drawing text at arbitrary angle. Use TTF fonts instead."); 424 425 $h=$this->GetTextHeight($txt); 426 $fh=$this->GetFontHeight(); 427 $w=$this->GetTextWidth($txt); 428 429 if( $this->text_halign=="right") 430 $x -= $dir==0 ? $w : $h; 431 elseif( $this->text_halign=="center" ) { 432 // For center we subtract 1 pixel since this makes the middle 433 // be prefectly in the middle 434 $x -= $dir==0 ? $w/2-1 : $h/2; 435 } 436 if( $this->text_valign=="top" ) 437 $y += $dir==0 ? $h : $w; 438 elseif( $this->text_valign=="center" ) 439 $y += $dir==0 ? $h/2 : $w/2; 440 441 if( $dir==90 ) { 442 imagestringup($this->img,$this->font_family,$x,$y,$txt,$this->current_color); 443 $aBoundingBox = array(round($x),round($y),round($x),round($y-$w),round($x+$h),round($y-$w),round($x+$h),round($y)); 626 $this->text_halign=$halign; 627 $this->text_valign=$valign; 628 } 629 630 function _StrokeBuiltinFont($x,$y,$txt,$dir,$paragraph_align,&$aBoundingBox,$aDebug=false) { 631 632 if( is_numeric($dir) && $dir!=90 && $dir!=0) 633 JpGraphError::RaiseL(25091);//(" Internal font does not support drawing text at arbitrary angle. Use TTF fonts instead."); 634 635 $h=$this->GetTextHeight($txt); 636 $fh=$this->GetFontHeight(); 637 $w=$this->GetTextWidth($txt); 638 639 if( $this->text_halign=="right") { 640 $x -= $dir==0 ? $w : $h; 641 } 642 elseif( $this->text_halign=="center" ) { 643 // For center we subtract 1 pixel since this makes the middle 644 // be prefectly in the middle 645 $x -= $dir==0 ? $w/2-1 : $h/2; 646 } 647 if( $this->text_valign=="top" ) { 648 $y += $dir==0 ? $h : $w; 649 } 650 elseif( $this->text_valign=="center" ) { 651 $y += $dir==0 ? $h/2 : $w/2; 652 } 653 654 $use_font = $this->font_family; 655 656 if( $dir==90 ) { 657 imagestringup($this->img,$use_font,$x,$y,$txt,$this->current_color); 658 $aBoundingBox = array(round($x),round($y),round($x),round($y-$w),round($x+$h),round($y-$w),round($x+$h),round($y)); 444 659 if( $aDebug ) { 445 // Draw bounding box 446 $this->PushColor('green'); 447 $this->Polygon($aBoundingBox,true); 448 $this->PopColor(); 449 } 450 } 451 else { 452 if( preg_match('/\n/',$txt) ) { 453 $tmp = split("\n",$txt); 454 for($i=0; $i < count($tmp); ++$i) { 455 $w1 = $this->GetTextWidth($tmp[$i]); 456 if( $paragraph_align=="left" ) { 457 imagestring($this->img,$this->font_family,$x,$y-$h+1+$i*$fh,$tmp[$i],$this->current_color); 458 } 459 elseif( $paragraph_align=="right" ) { 460 imagestring($this->img,$this->font_family,$x+($w-$w1), 461 $y-$h+1+$i*$fh,$tmp[$i],$this->current_color); 462 } 463 else { 464 imagestring($this->img,$this->font_family,$x+$w/2-$w1/2, 465 $y-$h+1+$i*$fh,$tmp[$i],$this->current_color); 466 } 467 } 468 } 469 else { 470 //Put the text 471 imagestring($this->img,$this->font_family,$x,$y-$h+1,$txt,$this->current_color); 472 } 660 // Draw bounding box 661 $this->PushColor('green'); 662 $this->Polygon($aBoundingBox,true); 663 $this->PopColor(); 664 } 665 } 666 else { 667 if( preg_match('/\n/',$txt) ) { 668 $tmp = preg_split('/\n/',$txt); 669 for($i=0; $i < count($tmp); ++$i) { 670 $w1 = $this->GetTextWidth($tmp[$i]); 671 if( $paragraph_align=="left" ) { 672 imagestring($this->img,$use_font,$x,$y-$h+1+$i*$fh,$tmp[$i],$this->current_color); 673 } 674 elseif( $paragraph_align=="right" ) { 675 imagestring($this->img,$use_font,$x+($w-$w1),$y-$h+1+$i*$fh,$tmp[$i],$this->current_color); 676 } 677 else { 678 imagestring($this->img,$use_font,$x+$w/2-$w1/2,$y-$h+1+$i*$fh,$tmp[$i],$this->current_color); 679 } 680 } 681 } 682 else { 683 //Put the text 684 imagestring($this->img,$use_font,$x,$y-$h+1,$txt,$this->current_color); 685 } 473 686 if( $aDebug ) { 474 475 476 477 478 479 480 481 482 } 483 484 687 // Draw the bounding rectangle and the bounding box 688 $p1 = array(round($x),round($y),round($x),round($y-$h),round($x+$w),round($y-$h),round($x+$w),round($y)); 689 690 // Draw bounding box 691 $this->PushColor('green'); 692 $this->Polygon($p1,true); 693 $this->PopColor(); 694 695 } 696 $aBoundingBox=array(round($x),round($y),round($x),round($y-$h),round($x+$w),round($y-$h),round($x+$w),round($y)); 697 } 485 698 } 486 699 487 700 function AddTxtCR($aTxt) { 488 // If the user has just specified a '\n' 489 // instead of '\n\t' we have to add '\r' since 490 // the width will be too muchy otherwise since when 491 // we print we stroke the individually lines by hand. 492 $e = explode("\n",$aTxt); 493 $n = count($e); 494 for($i=0; $i<$n; ++$i) { 495 $e[$i]=str_replace("\r","",$e[$i]); 496 } 497 return implode("\n\r",$e); 498 } 499 701 // If the user has just specified a '\n' 702 // instead of '\n\t' we have to add '\r' since 703 // the width will be too muchy otherwise since when 704 // we print we stroke the individually lines by hand. 705 $e = explode("\n",$aTxt); 706 $n = count($e); 707 for($i=0; $i<$n; ++$i) { 708 $e[$i]=str_replace("\r","",$e[$i]); 709 } 710 return implode("\n\r",$e); 711 } 712 713 function NormAngle($a) { 714 // Normalize angle in degrees 715 // Normalize angle to be between 0-360 716 while( $a > 360 ) 717 $a -= 360; 718 while( $a < -360 ) 719 $a += 360; 720 if( $a < 0 ) 721 $a = 360 + $a; 722 return $a; 723 } 724 725 function imagettfbbox_fixed($size, $angle, $fontfile, $text) { 726 727 728 if( ! USE_LIBRARY_IMAGETTFBBOX ) { 729 730 $bbox = @imagettfbbox($size, $angle, $fontfile, $text); 731 if( $bbox === false ) { 732 JpGraphError::RaiseL(25092,$this->font_file); 733 //("There is either a configuration problem with TrueType or a problem reading font file (".$this->font_file."). Make sure file exists and is in a readable place for the HTTP process. (If 'basedir' restriction is enabled in PHP then the font file must be located in the document root.). It might also be a wrongly installed FreeType library. Try uppgrading to at least FreeType 2.1.13 and recompile GD with the correct setup so it can find the new FT library."); 734 } 735 $this->bbox_cache = $bbox; 736 return $bbox; 737 } 738 739 // The built in imagettfbbox is buggy for angles != 0 so 740 // we calculate this manually by getting the bounding box at 741 // angle = 0 and then rotate the bounding box manually 742 $bbox = @imagettfbbox($size, 0, $fontfile, $text); 743 if( $bbox === false ) { 744 JpGraphError::RaiseL(25092,$this->font_file); 745 //("There is either a configuration problem with TrueType or a problem reading font file (".$this->font_file."). Make sure file exists and is in a readable place for the HTTP process. (If 'basedir' restriction is enabled in PHP then the font file must be located in the document root.). It might also be a wrongly installed FreeType library. Try uppgrading to at least FreeType 2.1.13 and recompile GD with the correct setup so it can find the new FT library."); 746 } 747 748 $angle = $this->NormAngle($angle); 749 750 $a = $angle*M_PI/180; 751 $ca = cos($a); 752 $sa = sin($a); 753 $ret = array(); 754 755 // We always add 1 pixel to the left since the left edge of the bounding 756 // box is sometimes coinciding with the first pixel of the text 757 //$bbox[0] -= 1; 758 //$bbox[6] -= 1; 759 760 // For roatated text we need to add extra width for rotated 761 // text since the kerning and stroking of the TTF is not the same as for 762 // text at a 0 degree angle 763 764 if( $angle > 0.001 && abs($angle-360) > 0.001 ) { 765 $h = abs($bbox[7]-$bbox[1]); 766 $w = abs($bbox[2]-$bbox[0]); 767 768 $bbox[0] -= 2; 769 $bbox[6] -= 2; 770 // The width is underestimated so compensate for that 771 $bbox[2] += round($w*0.06); 772 $bbox[4] += round($w*0.06); 773 774 // and we also need to compensate with increased height 775 $bbox[5] -= round($h*0.1); 776 $bbox[7] -= round($h*0.1); 777 778 if( $angle > 90 ) { 779 // For angles > 90 we also need to extend the height further down 780 // by the baseline since that is also one more problem 781 $bbox[1] += round($h*0.15); 782 $bbox[3] += round($h*0.15); 783 784 // and also make it slighty less height 785 $bbox[7] += round($h*0.05); 786 $bbox[5] += round($h*0.05); 787 788 // And we need to move the box slightly top the rright (from a tetx perspective) 789 $bbox[0] += round($w*0.02); 790 $bbox[6] += round($w*0.02); 791 792 if( $angle > 180 ) { 793 // And we need to move the box slightly to the left (from a text perspective) 794 $bbox[0] -= round($w*0.02); 795 $bbox[6] -= round($w*0.02); 796 $bbox[2] -= round($w*0.02); 797 $bbox[4] -= round($w*0.02); 798 799 } 800 801 } 802 for($i = 0; $i < 7; $i += 2) { 803 $ret[$i] = round($bbox[$i] * $ca + $bbox[$i+1] * $sa); 804 $ret[$i+1] = round($bbox[$i+1] * $ca - $bbox[$i] * $sa); 805 } 806 $this->bbox_cache = $ret; 807 return $ret; 808 } 809 else { 810 $this->bbox_cache = $bbox; 811 return $bbox; 812 } 813 } 814 815 // Deprecated 500 816 function GetTTFBBox($aTxt,$aAngle=0) { 501 $bbox = @ImageTTFBBox($this->font_size,$aAngle,$this->font_file,$aTxt); 502 if( $bbox === false ) { 503 JpGraphError::RaiseL(25092,$this->font_file); 504 //("There is either a configuration problem with TrueType or a problem reading font file (".$this->font_file."). Make sure file exists and is in a readable place for the HTTP process. (If 'basedir' restriction is enabled in PHP then the font file must be located in the document root.). It might also be a wrongly installed FreeType library. Try uppgrading to at least FreeType 2.1.13 and recompile GD with the correct setup so it can find the new FT library."); 505 } 506 return $bbox; 817 $bbox = $this->imagettfbbox_fixed($this->font_size,$aAngle,$this->font_file,$aTxt); 818 return $bbox; 507 819 } 508 820 509 821 function GetBBoxTTF($aTxt,$aAngle=0) { 510 511 512 513 514 515 516 517 //('Can not read font file ('.$this->font_file.') in call to Image::GetBBoxTTF. Please make sure that you have set a font before calling this method and that the font is installed in the TTF directory.');518 519 $bbox = $this->GetTTFBBox($aTxt,$aAngle);520 521 if( $aAngle==0 ) 522 return $bbox; 523 524 if( $aAngle <= 90 ) { //<=0 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 } 559 822 // Normalize the bounding box to become a minimum 823 // enscribing rectangle 824 825 $aTxt = $this->AddTxtCR($aTxt); 826 827 if( !is_readable($this->font_file) ) { 828 JpGraphError::RaiseL(25093,$this->font_file); 829 //('Can not read font file ('.$this->font_file.') in call to Image::GetBBoxTTF. Please make sure that you have set a font before calling this method and that the font is installed in the TTF directory.'); 830 } 831 $bbox = $this->imagettfbbox_fixed($this->font_size,$aAngle,$this->font_file,$aTxt); 832 833 if( $aAngle==0 ) return $bbox; 834 835 if( $aAngle >= 0 ) { 836 if( $aAngle <= 90 ) { //<=0 837 $bbox = array($bbox[6],$bbox[1],$bbox[2],$bbox[1], 838 $bbox[2],$bbox[5],$bbox[6],$bbox[5]); 839 } 840 elseif( $aAngle <= 180 ) { //<= 2 841 $bbox = array($bbox[4],$bbox[7],$bbox[0],$bbox[7], 842 $bbox[0],$bbox[3],$bbox[4],$bbox[3]); 843 } 844 elseif( $aAngle <= 270 ) { //<= 3 845 $bbox = array($bbox[2],$bbox[5],$bbox[6],$bbox[5], 846 $bbox[6],$bbox[1],$bbox[2],$bbox[1]); 847 } 848 else { 849 $bbox = array($bbox[0],$bbox[3],$bbox[4],$bbox[3], 850 $bbox[4],$bbox[7],$bbox[0],$bbox[7]); 851 } 852 } 853 elseif( $aAngle < 0 ) { 854 if( $aAngle <= -270 ) { // <= -3 855 $bbox = array($bbox[6],$bbox[1],$bbox[2],$bbox[1], 856 $bbox[2],$bbox[5],$bbox[6],$bbox[5]); 857 } 858 elseif( $aAngle <= -180 ) { // <= -2 859 $bbox = array($bbox[0],$bbox[3],$bbox[4],$bbox[3], 860 $bbox[4],$bbox[7],$bbox[0],$bbox[7]); 861 } 862 elseif( $aAngle <= -90 ) { // <= -1 863 $bbox = array($bbox[2],$bbox[5],$bbox[6],$bbox[5], 864 $bbox[6],$bbox[1],$bbox[2],$bbox[1]); 865 } 866 else { 867 $bbox = array($bbox[0],$bbox[3],$bbox[4],$bbox[3], 868 $bbox[4],$bbox[7],$bbox[0],$bbox[7]); 869 } 870 } 871 return $bbox; 560 872 } 561 873 562 874 function GetBBoxHeight($aTxt,$aAngle=0) { 563 564 return $box[1]-$box[7]+1;875 $box = $this->GetBBoxTTF($aTxt,$aAngle); 876 return abs($box[7]-$box[1]); 565 877 } 566 878 567 879 function GetBBoxWidth($aTxt,$aAngle=0) { 568 $box = $this->GetBBoxTTF($aTxt,$aAngle); 569 return $box[2]-$box[0]+1; 570 } 571 572 function _StrokeTTF($x,$y,$txt,$dir=0,$paragraph_align="left",&$aBoundingBox,$debug=false) { 573 574 // Setupo default inter line margin for paragraphs to 575 // 25% of the font height. 576 $ConstLineSpacing = 0.25 ; 577 578 // Remember the anchor point before adjustment 579 if( $debug ) { 580 $ox=$x; 581 $oy=$y; 582 } 583 584 if( !preg_match('/\n/',$txt) || ($dir>0 && preg_match('/\n/',$txt)) ) { 585 // Format a single line 586 587 $txt = $this->AddTxtCR($txt); 588 589 $bbox=$this->GetBBoxTTF($txt,$dir); 590 591 // Align x,y ot lower left corner of bbox 592 $x -= $bbox[0]; 593 $y -= $bbox[1]; 594 595 // Note to self: "topanchor" is deprecated after we changed the 596 // bopunding box stuff. 597 if( $this->text_halign=="right" || $this->text_halign=="topanchor" ) 598 $x -= $bbox[2]-$bbox[0]; 599 elseif( $this->text_halign=="center" ) $x -= ($bbox[2]-$bbox[0])/2; 600 601 if( $this->text_valign=="top" ) $y += abs($bbox[5])+$bbox[1]; 602 elseif( $this->text_valign=="center" ) $y -= ($bbox[5]-$bbox[1])/2; 603 604 ImageTTFText ($this->img, $this->font_size, $dir, $x, $y, 605 $this->current_color,$this->font_file,$txt); 606 607 // Calculate and return the co-ordinates for the bounding box 608 $box=@ImageTTFBBox($this->font_size,$dir,$this->font_file,$txt); 609 $p1 = array(); 610 611 612 for($i=0; $i < 4; ++$i) { 613 $p1[] = round($box[$i*2]+$x); 614 $p1[] = round($box[$i*2+1]+$y); 615 } 616 $aBoundingBox = $p1; 617 618 // Debugging code to highlight the bonding box and bounding rectangle 619 // For text at 0 degrees the bounding box and bounding rectangle are the 620 // same 880 $box = $this->GetBBoxTTF($aTxt,$aAngle); 881 return $box[2]-$box[0]+1; 882 } 883 884 885 function _StrokeTTF($x,$y,$txt,$dir,$paragraph_align,&$aBoundingBox,$debug=false) { 886 887 // Setup default inter line margin for paragraphs to be 888 // 3% of the font height. 889 $ConstLineSpacing = 0.03 ; 890 891 // Remember the anchor point before adjustment 892 if( $debug ) { 893 $ox=$x; 894 $oy=$y; 895 } 896 897 if( !preg_match('/\n/',$txt) || ($dir>0 && preg_match('/\n/',$txt)) ) { 898 // Format a single line 899 900 $txt = $this->AddTxtCR($txt); 901 $bbox=$this->GetBBoxTTF($txt,$dir); 902 $width = $this->GetBBoxWidth($txt,$dir); 903 $height = $this->GetBBoxHeight($txt,$dir); 904 905 // The special alignment "basepoint" is mostly used internally 906 // in the library. This will put the anchor position at the left 907 // basepoint of the tetx. This is the default anchor point for 908 // TTF text. 909 910 if( $this->text_valign != 'basepoint' ) { 911 // Align x,y ot lower left corner of bbox 912 913 914 if( $this->text_halign=='right' ) { 915 $x -= $width; 916 $x -= $bbox[0]; 917 } 918 elseif( $this->text_halign=='center' ) { 919 $x -= $width/2; 920 $x -= $bbox[0]; 921 } 922 elseif( $this->text_halign=='baseline' ) { 923 // This is only support for text at 90 degree !! 924 // Do nothing the text is drawn at baseline by default 925 } 926 927 if( $this->text_valign=='top' ) { 928 $y -= $bbox[1]; // Adjust to bottom of text 929 $y += $height; 930 } 931 elseif( $this->text_valign=='center' ) { 932 $y -= $bbox[1]; // Adjust to bottom of text 933 $y += $height/2; 934 } 935 elseif( $this->text_valign=='baseline' ) { 936 // This is only support for text at 0 degree !! 937 // Do nothing the text is drawn at baseline by default 938 } 939 } 940 ImageTTFText ($this->img, $this->font_size, $dir, $x, $y, 941 $this->current_color,$this->font_file,$txt); 942 943 // Calculate and return the co-ordinates for the bounding box 944 $box = $this->imagettfbbox_fixed($this->font_size,$dir,$this->font_file,$txt); 945 $p1 = array(); 946 947 for($i=0; $i < 4; ++$i) { 948 $p1[] = round($box[$i*2]+$x); 949 $p1[] = round($box[$i*2+1]+$y); 950 } 951 $aBoundingBox = $p1; 952 953 // Debugging code to highlight the bonding box and bounding rectangle 954 // For text at 0 degrees the bounding box and bounding rectangle are the 955 // same 621 956 if( $debug ) { 622 // Draw the bounding rectangle and the bounding box 623 $box=@ImageTTFBBox($this->font_size,$dir,$this->font_file,$txt); 624 $p = array(); 625 $p1 = array(); 626 for($i=0; $i < 4; ++$i) { 627 $p[] = $bbox[$i*2]+$x; 628 $p[] = $bbox[$i*2+1]+$y; 629 $p1[] = $box[$i*2]+$x; 630 $p1[] = $box[$i*2+1]+$y; 631 } 632 633 // Draw bounding box 634 $this->PushColor('green'); 635 $this->Polygon($p1,true); 636 $this->PopColor(); 637 638 // Draw bounding rectangle 639 $this->PushColor('darkgreen'); 640 $this->Polygon($p,true); 641 $this->PopColor(); 642 643 // Draw a cross at the anchor point 644 $this->PushColor('red'); 645 $this->Line($ox-15,$oy,$ox+15,$oy); 646 $this->Line($ox,$oy-15,$ox,$oy+15); 647 $this->PopColor(); 648 } 649 } 650 else { 651 // Format a text paragraph 652 $fh=$this->GetFontHeight(); 653 654 // Line margin is 25% of font height 655 $linemargin=round($fh*$ConstLineSpacing); 656 $fh += $linemargin; 657 $w=$this->GetTextWidth($txt); 658 659 $y -= $linemargin/2; 660 $tmp = split("\n",$txt); 661 $nl = count($tmp); 662 $h = $nl * $fh; 663 664 if( $this->text_halign=="right") 665 $x -= $dir==0 ? $w : $h; 666 elseif( $this->text_halign=="center" ) { 667 $x -= $dir==0 ? $w/2 : $h/2; 668 } 669 670 if( $this->text_valign=="top" ) 671 $y += $dir==0 ? $h : $w; 672 elseif( $this->text_valign=="center" ) 673 $y += $dir==0 ? $h/2 : $w/2; 674 675 // Here comes a tricky bit. 676 // Since we have to give the position for the string at the 677 // baseline this means thaht text will move slightly up 678 // and down depending on any of it's character descend below 679 // the baseline, for example a 'g'. To adjust the Y-position 680 // we therefore adjust the text with the baseline Y-offset 681 // as used for the current font and size. This will keep the 682 // baseline at a fixed positoned disregarding the actual 683 // characters in the string. 684 $standardbox = $this->GetTTFBBox('Gg',$dir); 685 $yadj = $standardbox[1]; 686 $xadj = $standardbox[0]; 687 $aBoundingBox = array(); 688 for($i=0; $i < $nl; ++$i) { 689 $wl = $this->GetTextWidth($tmp[$i]); 690 $bbox = $this->GetTTFBBox($tmp[$i],$dir); 691 if( $paragraph_align=="left" ) { 692 $xl = $x; 693 } 694 elseif( $paragraph_align=="right" ) { 695 $xl = $x + ($w-$wl); 696 } 697 else { 698 // Center 699 $xl = $x + $w/2 - $wl/2 ; 700 } 701 702 $xl -= $bbox[0]; 703 $yl = $y - $yadj; 704 $xl = $xl - $xadj; 705 ImageTTFText ($this->img, $this->font_size, $dir, 706 $xl, $yl-($h-$fh)+$fh*$i, 707 $this->current_color,$this->font_file,$tmp[$i]); 708 709 if( $debug ) { 710 // Draw the bounding rectangle around each line 711 $box=@ImageTTFBBox($this->font_size,$dir,$this->font_file,$tmp[$i]); 712 $p = array(); 713 for($j=0; $j < 4; ++$j) { 714 $p[] = $bbox[$j*2]+$xl; 715 $p[] = $bbox[$j*2+1]+$yl-($h-$fh)+$fh*$i; 716 } 717 718 // Draw bounding rectangle 719 $this->PushColor('darkgreen'); 720 $this->Polygon($p,true); 721 $this->PopColor(); 722 } 723 } 724 725 // Get the bounding box 726 $bbox = $this->GetBBoxTTF($txt,$dir); 727 for($j=0; $j < 4; ++$j) { 728 $bbox[$j*2]+= round($x); 729 $bbox[$j*2+1]+= round($y - ($h-$fh) - $yadj); 730 } 731 $aBoundingBox = $bbox; 732 733 if( $debug ) { 734 // Draw a cross at the anchor point 735 $this->PushColor('red'); 736 $this->Line($ox-25,$oy,$ox+25,$oy); 737 $this->Line($ox,$oy-25,$ox,$oy+25); 738 $this->PopColor(); 739 } 740 741 } 742 } 743 957 // Draw the bounding rectangle and the bounding box 958 959 $p = array(); 960 $p1 = array(); 961 962 for($i=0; $i < 4; ++$i) { 963 $p[] = $bbox[$i*2]+$x ; 964 $p[] = $bbox[$i*2+1]+$y; 965 $p1[] = $box[$i*2]+$x ; 966 $p1[] = $box[$i*2+1]+$y ; 967 } 968 969 // Draw bounding box 970 $this->PushColor('green'); 971 $this->Polygon($p1,true); 972 $this->PopColor(); 973 974 // Draw bounding rectangle 975 $this->PushColor('darkgreen'); 976 $this->Polygon($p,true); 977 $this->PopColor(); 978 979 // Draw a cross at the anchor point 980 $this->PushColor('red'); 981 $this->Line($ox-15,$oy,$ox+15,$oy); 982 $this->Line($ox,$oy-15,$ox,$oy+15); 983 $this->PopColor(); 984 } 985 } 986 else { 987 // Format a text paragraph 988 $fh=$this->GetFontHeight(); 989 990 // Line margin is 25% of font height 991 $linemargin=round($fh*$ConstLineSpacing); 992 $fh += $linemargin; 993 $w=$this->GetTextWidth($txt); 994 995 $y -= $linemargin/2; 996 $tmp = preg_split('/\n/',$txt); 997 $nl = count($tmp); 998 $h = $nl * $fh; 999 1000 if( $this->text_halign=='right') { 1001 $x -= $dir==0 ? $w : $h; 1002 } 1003 elseif( $this->text_halign=='center' ) { 1004 $x -= $dir==0 ? $w/2 : $h/2; 1005 } 1006 1007 if( $this->text_valign=='top' ) { 1008 $y += $dir==0 ? $h : $w; 1009 } 1010 elseif( $this->text_valign=='center' ) { 1011 $y += $dir==0 ? $h/2 : $w/2; 1012 } 1013 1014 // Here comes a tricky bit. 1015 // Since we have to give the position for the string at the 1016 // baseline this means thaht text will move slightly up 1017 // and down depending on any of it's character descend below 1018 // the baseline, for example a 'g'. To adjust the Y-position 1019 // we therefore adjust the text with the baseline Y-offset 1020 // as used for the current font and size. This will keep the 1021 // baseline at a fixed positoned disregarding the actual 1022 // characters in the string. 1023 $standardbox = $this->GetTTFBBox('Gg',$dir); 1024 $yadj = $standardbox[1]; 1025 $xadj = $standardbox[0]; 1026 $aBoundingBox = array(); 1027 for($i=0; $i < $nl; ++$i) { 1028 $wl = $this->GetTextWidth($tmp[$i]); 1029 $bbox = $this->GetTTFBBox($tmp[$i],$dir); 1030 if( $paragraph_align=='left' ) { 1031 $xl = $x; 1032 } 1033 elseif( $paragraph_align=='right' ) { 1034 $xl = $x + ($w-$wl); 1035 } 1036 else { 1037 // Center 1038 $xl = $x + $w/2 - $wl/2 ; 1039 } 1040 1041 // In theory we should adjust with full pre-lead to get the lines 1042 // lined up but this doesn't look good so therfore we only adjust with 1043 // half th pre-lead 1044 $xl -= $bbox[0]/2; 1045 $yl = $y - $yadj; 1046 //$xl = $xl- $xadj; 1047 ImageTTFText($this->img, $this->font_size, $dir, $xl, $yl-($h-$fh)+$fh*$i, 1048 $this->current_color,$this->font_file,$tmp[$i]); 1049 1050 // echo "xl=$xl,".$tmp[$i]." <br>"; 1051 if( $debug ) { 1052 // Draw the bounding rectangle around each line 1053 $box=@ImageTTFBBox($this->font_size,$dir,$this->font_file,$tmp[$i]); 1054 $p = array(); 1055 for($j=0; $j < 4; ++$j) { 1056 $p[] = $bbox[$j*2]+$xl; 1057 $p[] = $bbox[$j*2+1]+$yl-($h-$fh)+$fh*$i; 1058 } 1059 1060 // Draw bounding rectangle 1061 $this->PushColor('darkgreen'); 1062 $this->Polygon($p,true); 1063 $this->PopColor(); 1064 } 1065 } 1066 1067 // Get the bounding box 1068 $bbox = $this->GetBBoxTTF($txt,$dir); 1069 for($j=0; $j < 4; ++$j) { 1070 $bbox[$j*2]+= round($x); 1071 $bbox[$j*2+1]+= round($y - ($h-$fh) - $yadj); 1072 } 1073 $aBoundingBox = $bbox; 1074 1075 if( $debug ) { 1076 // Draw a cross at the anchor point 1077 $this->PushColor('red'); 1078 $this->Line($ox-25,$oy,$ox+25,$oy); 1079 $this->Line($ox,$oy-25,$ox,$oy+25); 1080 $this->PopColor(); 1081 } 1082 1083 } 1084 } 1085 744 1086 function StrokeText($x,$y,$txt,$dir=0,$paragraph_align="left",$debug=false) { 745 1087 746 $x = round($x); 747 $y = round($y); 748 749 // Do special language encoding 750 $txt = $this->langconv->Convert($txt,$this->font_family); 751 752 if( !is_numeric($dir) ) 753 JpGraphError::RaiseL(25094);//(" Direction for text most be given as an angle between 0 and 90."); 754 755 if( $this->font_family >= FF_FONT0 && $this->font_family <= FF_FONT2+1) { 756 $this->_StrokeBuiltinFont($x,$y,$txt,$dir,$paragraph_align,$boundingbox,$debug); 757 } 758 elseif($this->font_family >= _FIRST_FONT && $this->font_family <= _LAST_FONT) { 759 $this->_StrokeTTF($x,$y,$txt,$dir,$paragraph_align,$boundingbox,$debug); 760 } 761 else 762 JpGraphError::RaiseL(25095);//(" Unknown font font family specification. "); 763 return $boundingbox; 764 } 765 1088 $x = round($x); 1089 $y = round($y); 1090 1091 // Do special language encoding 1092 $txt = $this->langconv->Convert($txt,$this->font_family); 1093 1094 if( !is_numeric($dir) ) { 1095 JpGraphError::RaiseL(25094);//(" Direction for text most be given as an angle between 0 and 90."); 1096 } 1097 1098 if( $this->font_family >= FF_FONT0 && $this->font_family <= FF_FONT2+1) { 1099 $this->_StrokeBuiltinFont($x,$y,$txt,$dir,$paragraph_align,$boundingbox,$debug); 1100 } 1101 elseif( $this->font_family >= _FIRST_FONT && $this->font_family <= _LAST_FONT) { 1102 $this->_StrokeTTF($x,$y,$txt,$dir,$paragraph_align,$boundingbox,$debug); 1103 } 1104 else { 1105 JpGraphError::RaiseL(25095);//(" Unknown font font family specification. "); 1106 } 1107 return $boundingbox; 1108 } 1109 766 1110 function SetMargin($lm,$rm,$tm,$bm) { 767 $this->left_margin=$lm; 768 $this->right_margin=$rm; 769 $this->top_margin=$tm; 770 $this->bottom_margin=$bm; 771 $this->plotwidth=$this->width - $this->left_margin-$this->right_margin ; 772 $this->plotheight=$this->height - $this->top_margin-$this->bottom_margin ; 773 if( $this->width > 0 && $this->height > 0 ) { 774 if( $this->plotwidth < 0 || $this->plotheight < 0 ) 775 JpGraphError::raise("To small plot area. ($lm,$rm,$tm,$bm : $this->plotwidth x $this->plotheight). With the given image size and margins there is to little space left for the plot. Increase the plot size or reduce the margins."); 776 } 1111 1112 $this->left_margin=$lm; 1113 $this->right_margin=$rm; 1114 $this->top_margin=$tm; 1115 $this->bottom_margin=$bm; 1116 1117 $this->plotwidth = $this->width - $this->left_margin - $this->right_margin; 1118 $this->plotheight = $this->height - $this->top_margin - $this->bottom_margin; 1119 1120 if( $this->width > 0 && $this->height > 0 ) { 1121 if( $this->plotwidth < 0 || $this->plotheight < 0 ) { 1122 JpGraphError::RaiseL(25130, $this->plotwidth, $this->plotheight); 1123 //JpGraphError::raise("To small plot area. ($lm,$rm,$tm,$bm : $this->plotwidth x $this->plotheight). With the given image size and margins there is to little space left for the plot. Increase the plot size or reduce the margins."); 1124 } 1125 } 777 1126 } 778 1127 779 1128 function SetTransparent($color) { 780 781 } 782 1129 imagecolortransparent ($this->img,$this->rgb->allocate($color)); 1130 } 1131 783 1132 function SetColor($color,$aAlpha=0) { 784 785 786 787 788 789 //("Can't allocate any more colors. Image has already allocated maximum of <b>$tc colors</b>. This might happen if you have anti-aliasing turned on together with a background image or perhaps gradient fill since this requires many, many colors. Try to turn off anti-aliasing. If there is still a problem try downgrading the quality of the background image to use a smaller pallete to leave some entries for your graphs. You should try to limit the number of colors in your background image to 64. If there is still problem set the constant DEFINE(\"USE_APPROX_COLORS\",true); in jpgraph.php This will use approximative colors when the palette is full. Unfortunately there is not much JpGraph can do about this since the palette size is a limitation of current graphic format and what the underlying GD library suppports."); 790 791 792 } 793 1133 $this->current_color_name = $color; 1134 $this->current_color=$this->rgb->allocate($color,$aAlpha); 1135 if( $this->current_color == -1 ) { 1136 $tc=imagecolorstotal($this->img); 1137 JpGraphError::RaiseL(25096); 1138 //("Can't allocate any more colors. Image has already allocated maximum of <b>$tc colors</b>. This might happen if you have anti-aliasing turned on together with a background image or perhaps gradient fill since this requires many, many colors. Try to turn off anti-aliasing. If there is still a problem try downgrading the quality of the background image to use a smaller pallete to leave some entries for your graphs. You should try to limit the number of colors in your background image to 64. If there is still problem set the constant DEFINE(\"USE_APPROX_COLORS\",true); in jpgraph.php This will use approximative colors when the palette is full. Unfortunately there is not much JpGraph can do about this since the palette size is a limitation of current graphic format and what the underlying GD library suppports."); 1139 } 1140 return $this->current_color; 1141 } 1142 794 1143 function PushColor($color) { 795 796 797 798 799 800 801 802 803 804 } 805 1144 if( $color != "" ) { 1145 $this->colorstack[$this->colorstackidx]=$this->current_color_name; 1146 $this->colorstack[$this->colorstackidx+1]=$this->current_color; 1147 $this->colorstackidx+=2; 1148 $this->SetColor($color); 1149 } 1150 else { 1151 JpGraphError::RaiseL(25097);//("Color specified as empty string in PushColor()."); 1152 } 1153 } 1154 806 1155 function PopColor() { 807 if($this->colorstackidx<1) 808 JpGraphError::RaiseL(25098);//(" Negative Color stack index. Unmatched call to PopColor()"); 809 $this->current_color=$this->colorstack[--$this->colorstackidx]; 810 $this->current_color_name=$this->colorstack[--$this->colorstackidx]; 811 } 812 813 1156 if( $this->colorstackidx < 1 ) { 1157 JpGraphError::RaiseL(25098);//(" Negative Color stack index. Unmatched call to PopColor()"); 1158 } 1159 $this->current_color=$this->colorstack[--$this->colorstackidx]; 1160 $this->current_color_name=$this->colorstack[--$this->colorstackidx]; 1161 } 1162 1163 814 1164 function SetLineWeight($weight) { 815 imagesetthickness($this->img,$weight); 816 $this->line_weight = $weight; 817 } 818 1165 $old = $this->line_weight; 1166 imagesetthickness($this->img,$weight); 1167 $this->line_weight = $weight; 1168 return $old; 1169 } 1170 819 1171 function SetStartPoint($x,$y) { 820 821 822 } 823 1172 $this->lastx=round($x); 1173 $this->lasty=round($y); 1174 } 1175 824 1176 function Arc($cx,$cy,$w,$h,$s,$e) { 825 // GD Arc doesn't like negative angles 826 while( $s < 0) $s += 360; 827 while( $e < 0) $e += 360; 828 829 imagearc($this->img,round($cx),round($cy),round($w),round($h), 830 $s,$e,$this->current_color); 831 } 832 1177 // GD Arc doesn't like negative angles 1178 while( $s < 0) $s += 360; 1179 while( $e < 0) $e += 360; 1180 imagearc($this->img,round($cx),round($cy),round($w),round($h),$s,$e,$this->current_color); 1181 } 1182 833 1183 function FilledArc($xc,$yc,$w,$h,$s,$e,$style='') { 834 while( $s < 0 ) $s += 360; 835 while( $e < 0 ) $e += 360; 836 if( $style=='' ) 837 $style=IMG_ARC_PIE; 838 if( abs($s-$e) > 0.001 ) { 839 imagefilledarc($this->img,round($xc),round($yc),round($w),round($h), 840 round($s),round($e),$this->current_color,$style); 841 } 1184 $s = round($s); 1185 $e = round($e); 1186 while( $s < 0 ) $s += 360; 1187 while( $e < 0 ) $e += 360; 1188 if( $style=='' ) 1189 $style=IMG_ARC_PIE; 1190 if( abs($s-$e) > 0 ) { 1191 imagefilledarc($this->img,round($xc),round($yc),round($w),round($h),$s,$e,$this->current_color,$style); 1192 // $this->DrawImageSmoothArc($this->img,round($xc),round($yc),round($w),round($h),$s,$e,$this->current_color,$style); 1193 } 842 1194 } 843 1195 844 1196 function FilledCakeSlice($cx,$cy,$w,$h,$s,$e) { 845 1197 $this->CakeSlice($cx,$cy,$w,$h,$s,$e,$this->current_color_name); 846 1198 } 847 1199 848 1200 function CakeSlice($xc,$yc,$w,$h,$s,$e,$fillcolor="",$arccolor="") { 849 $s = round($s); $e = round($e); 850 $w = round($w); $h = round($h); 851 $xc = round($xc); $yc = round($yc); 852 if( $s ==$e ) { 853 // A full circle. We draw this a plain circle 854 $this->PushColor($fillcolor); 855 imagefilledellipse($this->img,$xc,$yc,2*$w,2*$h,$this->current_color); 856 $this->PopColor(); 857 $this->PushColor($arccolor); 858 imageellipse($this->img,$xc,$yc,2*$w,2*$h,$this->current_color); 859 $this->Line($xc,$yc,cos($s*M_PI/180)*$w+$xc,$yc+sin($s*M_PI/180)*$h); 860 $this->PopColor(); 861 } 862 else { 863 $this->PushColor($fillcolor); 864 $this->FilledArc($xc,$yc,2*$w,2*$h,$s,$e); 865 $this->PopColor(); 866 if( $arccolor != "" ) { 867 $this->PushColor($arccolor); 868 // We add 2 pixels to make the Arc() better aligned with 869 // the filled arc. 870 imagefilledarc($this->img,$xc,$yc,2*$w,2*$h,$s,$e,$this->current_color,IMG_ARC_NOFILL | IMG_ARC_EDGED ) ; 871 $this->PopColor(); 872 } 873 } 1201 $s = round($s); $e = round($e); 1202 $w = round($w); $h = round($h); 1203 $xc = round($xc); $yc = round($yc); 1204 if( $s == $e ) { 1205 // A full circle. We draw this a plain circle 1206 $this->PushColor($fillcolor); 1207 imagefilledellipse($this->img,$xc,$yc,2*$w,2*$h,$this->current_color); 1208 1209 // If antialiasing is used then we often don't have any color no the surrounding 1210 // arc. So, we need to check for this special case so we don't send an empty 1211 // color to the push function. In this case we use the fill color for the arc as well 1212 if( $arccolor != '' ) { 1213 $this->PopColor(); 1214 $this->PushColor($arccolor); 1215 } 1216 imageellipse($this->img,$xc,$yc,2*$w,2*$h,$this->current_color); 1217 $this->Line($xc,$yc,cos($s*M_PI/180)*$w+$xc,$yc+sin($s*M_PI/180)*$h); 1218 $this->PopColor(); 1219 } 1220 else { 1221 $this->PushColor($fillcolor); 1222 $this->FilledArc($xc,$yc,2*$w,2*$h,$s,$e); 1223 $this->PopColor(); 1224 if( $arccolor != "" ) { 1225 $this->PushColor($arccolor); 1226 // We add 2 pixels to make the Arc() better aligned with 1227 // the filled arc. 1228 imagefilledarc($this->img,$xc,$yc,2*$w,2*$h,$s,$e,$this->current_color,IMG_ARC_NOFILL | IMG_ARC_EDGED ) ; 1229 $this->PopColor(); 1230 } 1231 } 874 1232 } 875 1233 876 1234 function Ellipse($xc,$yc,$w,$h) { 877 878 } 879 1235 $this->Arc($xc,$yc,$w,$h,0,360); 1236 } 1237 880 1238 function Circle($xc,$yc,$r) { 881 imageellipse($this->img,round($xc),round($yc),$r*2,$r*2,$this->current_color); 882 } 883 1239 imageellipse($this->img,round($xc),round($yc),$r*2,$r*2,$this->current_color); 1240 // $this->DrawImageSmoothArc($this->img,round($xc),round($yc),$r*2+1,$r*2+1,0,360,$this->current_color); 1241 // $this->imageSmoothCircle($this->img, round($xc),round($yc), $r*2+1, $this->current_color); 1242 } 1243 884 1244 function FilledCircle($xc,$yc,$r) { 885 imagefilledellipse($this->img,round($xc),round($yc),2*$r,2*$r,$this->current_color); 886 } 887 1245 imagefilledellipse($this->img,round($xc),round($yc),2*$r,2*$r,$this->current_color); 1246 // $this->DrawImageSmoothArc($this->img, round($xc), round($yc), 2*$r, 2*$r, 0, 360, $this->current_color); 1247 } 1248 888 1249 // Linear Color InterPolation 889 1250 function lip($f,$t,$p) { 890 891 892 893 894 1251 $p = round($p,1); 1252 $r = $f[0] + ($t[0]-$f[0])*$p; 1253 $g = $f[1] + ($t[1]-$f[1])*$p; 1254 $b = $f[2] + ($t[2]-$f[2])*$p; 1255 return array($r,$g,$b); 895 1256 } 896 1257 897 1258 // Set line style dashed, dotted etc 898 1259 function SetLineStyle($s) { 899 if( is_numeric($s) ) { 900 if( $s<1 || $s>4 ) 901 JpGraphError::RaiseL(25101,$s);//(" Illegal numeric argument to SetLineStyle(): ($s)"); 902 } 903 elseif( is_string($s) ) { 904 if( $s == "solid" ) $s=1; 905 elseif( $s == "dotted" ) $s=2; 906 elseif( $s == "dashed" ) $s=3; 907 elseif( $s == "longdashed" ) $s=4; 908 else JpGraphError::RaiseL(25102,$s);//(" Illegal string argument to SetLineStyle(): $s"); 909 } 910 else { 911 JpGraphError::RaiseL(25103,$s);//(" Illegal argument to SetLineStyle $s"); 912 } 913 $old = $this->line_style; 914 $this->line_style=$s; 915 return $old; 916 } 917 1260 if( is_numeric($s) ) { 1261 if( $s<1 || $s>4 ) { 1262 JpGraphError::RaiseL(25101,$s);//(" Illegal numeric argument to SetLineStyle(): ($s)"); 1263 } 1264 } 1265 elseif( is_string($s) ) { 1266 if( $s == "solid" ) $s=1; 1267 elseif( $s == "dotted" ) $s=2; 1268 elseif( $s == "dashed" ) $s=3; 1269 elseif( $s == "longdashed" ) $s=4; 1270 else { 1271 JpGraphError::RaiseL(25102,$s);//(" Illegal string argument to SetLineStyle(): $s"); 1272 } 1273 } 1274 else { 1275 JpGraphError::RaiseL(25103,$s);//(" Illegal argument to SetLineStyle $s"); 1276 } 1277 $old = $this->line_style; 1278 $this->line_style=$s; 1279 return $old; 1280 } 1281 918 1282 // Same as Line but take the line_style into account 919 function StyleLine($x1,$y1,$x2,$y2,$aStyle='') { 920 if( $this->line_weight <= 0 ) 921 return; 922 923 if( $aStyle === '' ) { 924 $aStyle = $this->line_style; 925 } 926 927 // Add error check since dashed line will only work if anti-alias is disabled 928 // this is a limitation in GD 929 930 switch( $aStyle ) { 931 case 1:// Solid 932 $this->Line($x1,$y1,$x2,$y2); 933 break; 934 case 2: // Dotted 935 $this->DashedLine($x1,$y1,$x2,$y2,2,6); 936 break; 937 case 3: // Dashed 938 $this->DashedLine($x1,$y1,$x2,$y2,5,9); 939 break; 940 case 4: // Longdashes 941 $this->DashedLine($x1,$y1,$x2,$y2,9,13); 942 break; 943 default: 944 JpGraphError::RaiseL(25104,$this->line_style);//(" Unknown line style: $this->line_style "); 945 break; 946 } 947 } 948 1283 function StyleLine($x1,$y1,$x2,$y2,$aStyle='', $from_grid_class = false) { 1284 if( $this->line_weight <= 0 ) return; 1285 1286 if( $aStyle === '' ) { 1287 $aStyle = $this->line_style; 1288 } 1289 1290 $dashed_line_method = 'DashedLine'; 1291 if ($from_grid_class) { 1292 $dashed_line_method = 'DashedLineForGrid'; 1293 } 1294 1295 // Add error check since dashed line will only work if anti-alias is disabled 1296 // this is a limitation in GD 1297 1298 if( $aStyle == 1 ) { 1299 // Solid style. We can handle anti-aliasing for this 1300 $this->Line($x1,$y1,$x2,$y2); 1301 } 1302 else { 1303 // Since the GD routines doesn't handle AA for styled line 1304 // we have no option than to turn it off to get any lines at 1305 // all if the weight > 1 1306 $oldaa = $this->GetAntiAliasing(); 1307 if( $oldaa && $this->line_weight > 1 ) { 1308 $this->SetAntiAliasing(false); 1309 } 1310 1311 switch( $aStyle ) { 1312 case 2: // Dotted 1313 $this->$dashed_line_method($x1,$y1,$x2,$y2,2,6); 1314 break; 1315 case 3: // Dashed 1316 $this->$dashed_line_method($x1,$y1,$x2,$y2,5,9); 1317 break; 1318 case 4: // Longdashes 1319 $this->$dashed_line_method($x1,$y1,$x2,$y2,9,13); 1320 break; 1321 default: 1322 JpGraphError::RaiseL(25104,$this->line_style);//(" Unknown line style: $this->line_style "); 1323 break; 1324 } 1325 if( $oldaa ) { 1326 $this->SetAntiAliasing(true); 1327 } 1328 } 1329 } 1330 949 1331 function DashedLine($x1,$y1,$x2,$y2,$dash_length=1,$dash_space=4) { 950 1332 951 if( $this->line_weight <= 0 ) 952 return; 953 954 // Add error check to make sure anti-alias is not enabled. 955 // Dashed line does not work with anti-alias enabled. This 956 // is a limitation in GD. 957 if( $this->use_anti_aliasing ) { 958 JpGraphError::RaiseL(25129); // Anti-alias can not be used with dashed lines. Please disable anti-alias or use solid lines. 959 } 960 961 962 $x1 = round($x1); 963 $x2 = round($x2); 964 $y1 = round($y1); 965 $y2 = round($y2); 966 967 $style = array_fill(0,$dash_length,$this->current_color); 968 $style = array_pad($style,$dash_space,IMG_COLOR_TRANSPARENT); 969 imagesetstyle($this->img, $style); 970 imageline($this->img, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED); 971 $this->lastx=$x2; $this->lasty=$y2; 972 } 1333 if( $this->line_weight <= 0 ) return; 1334 1335 // Add error check to make sure anti-alias is not enabled. 1336 // Dashed line does not work with anti-alias enabled. This 1337 // is a limitation in GD. 1338 if( $this->use_anti_aliasing ) { 1339 // JpGraphError::RaiseL(25129); // Anti-alias can not be used with dashed lines. Please disable anti-alias or use solid lines. 1340 } 1341 1342 $x1 = round($x1); 1343 $x2 = round($x2); 1344 $y1 = round($y1); 1345 $y2 = round($y2); 1346 1347 $dash_length *= SUPERSAMPLING_SCALE; 1348 $dash_space *= SUPERSAMPLING_SCALE; 1349 1350 $style = array_fill(0,$dash_length,$this->current_color); 1351 $style = array_pad($style,$dash_space,IMG_COLOR_TRANSPARENT); 1352 imagesetstyle($this->img, $style); 1353 imageline($this->img, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED); 1354 1355 $this->lastx = $x2; 1356 $this->lasty = $y2; 1357 } 1358 1359 function DashedLineForGrid($x1,$y1,$x2,$y2,$dash_length=1,$dash_space=4) { 1360 1361 if( $this->line_weight <= 0 ) return; 1362 1363 // Add error check to make sure anti-alias is not enabled. 1364 // Dashed line does not work with anti-alias enabled. This 1365 // is a limitation in GD. 1366 if( $this->use_anti_aliasing ) { 1367 // JpGraphError::RaiseL(25129); // Anti-alias can not be used with dashed lines. Please disable anti-alias or use solid lines. 1368 } 1369 1370 $x1 = round($x1); 1371 $x2 = round($x2); 1372 $y1 = round($y1); 1373 $y2 = round($y2); 1374 1375 /* 1376 $dash_length *= $this->scale; 1377 $dash_space *= $this->scale; 1378 */ 1379 1380 $dash_length = 2; 1381 $dash_length = 4; 1382 imagesetthickness($this->img, 1); 1383 $style = array_fill(0,$dash_length, $this->current_color); //hexdec('CCCCCC')); 1384 $style = array_pad($style,$dash_space,IMG_COLOR_TRANSPARENT); 1385 imagesetstyle($this->img, $style); 1386 imageline($this->img, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED); 1387 1388 $this->lastx = $x2; 1389 $this->lasty = $y2; 1390 } 973 1391 974 1392 function Line($x1,$y1,$x2,$y2) { 975 1393 976 if( $this->line_weight <= 0 ) 977 return; 978 979 $x1 = round($x1); 980 $x2 = round($x2); 981 $y1 = round($y1); 982 $y2 = round($y2); 983 984 imageline($this->img,$x1,$y1,$x2,$y2,$this->current_color); 985 $this->lastx=$x2; $this->lasty=$y2; 1394 if( $this->line_weight <= 0 ) return; 1395 1396 $x1 = round($x1); 1397 $x2 = round($x2); 1398 $y1 = round($y1); 1399 $y2 = round($y2); 1400 1401 imageline($this->img,$x1,$y1,$x2,$y2,$this->current_color); 1402 // $this->DrawLine($this->img, $x1, $y1, $x2, $y2, $this->line_weight, $this->current_color); 1403 $this->lastx=$x2; 1404 $this->lasty=$y2; 986 1405 } 987 1406 988 1407 function Polygon($p,$closed=FALSE,$fast=FALSE) { 989 1408 990 if( $this->line_weight <= 0 ) 991 return; 992 993 $n=count($p);994 $oldx = $p[0];995 $oldy = $p[1]; 996 if( $fast) {997 for( $i=2; $i < $n; $i+=2 ) { 998 imageline($this->img,$oldx,$oldy,$p[$i],$p[$i+1],$this->current_color);999 $oldx = $p[$i];1000 $oldy = $p[$i+1]; 1001 } 1002 if( $closed ) { 1003 imageline($this->img,$p[$n*2-2],$p[$n*2-1],$p[0],$p[1],$this->current_color); 1004 1005 } 1006 else{1007 for( $i=2; $i < $n; $i+=2 ) { 1008 $this->StyleLine($oldx,$oldy,$p[$i],$p[$i+1]);1009 $oldx = $p[$i];1010 $oldy = $p[$i+1]; 1011 } 1012 if( $closed ) 1013 $this->StyleLine($oldx,$oldy,$p[0],$p[1]); 1014 1015 } 1016 1409 if( $this->line_weight <= 0 ) return; 1410 1411 $n=count($p); 1412 $oldx = $p[0]; 1413 $oldy = $p[1]; 1414 if( $fast ) { 1415 for( $i=2; $i < $n; $i+=2 ) { 1416 imageline($this->img,$oldx,$oldy,$p[$i],$p[$i+1],$this->current_color); 1417 $oldx = $p[$i]; 1418 $oldy = $p[$i+1]; 1419 } 1420 if( $closed ) { 1421 imageline($this->img,$p[$n*2-2],$p[$n*2-1],$p[0],$p[1],$this->current_color); 1422 } 1423 } 1424 else { 1425 for( $i=2; $i < $n; $i+=2 ) { 1426 $this->StyleLine($oldx,$oldy,$p[$i],$p[$i+1]); 1427 $oldx = $p[$i]; 1428 $oldy = $p[$i+1]; 1429 } 1430 if( $closed ) { 1431 $this->StyleLine($oldx,$oldy,$p[0],$p[1]); 1432 } 1433 } 1434 } 1435 1017 1436 function FilledPolygon($pts) { 1018 $n=count($pts); 1019 if( $n == 0 ) { 1020 JpGraphError::RaiseL(25105);//('NULL data specified for a filled polygon. Check that your data is not NULL.'); 1021 } 1022 for($i=0; $i < $n; ++$i) 1023 $pts[$i] = round($pts[$i]); 1024 imagefilledpolygon($this->img,$pts,count($pts)/2,$this->current_color); 1025 } 1026 1437 $n=count($pts); 1438 if( $n == 0 ) { 1439 JpGraphError::RaiseL(25105);//('NULL data specified for a filled polygon. Check that your data is not NULL.'); 1440 } 1441 for($i=0; $i < $n; ++$i) { 1442 $pts[$i] = round($pts[$i]); 1443 } 1444 $old = $this->line_weight; 1445 imagesetthickness($this->img,1); 1446 imagefilledpolygon($this->img,$pts,count($pts)/2,$this->current_color); 1447 $this->line_weight = $old; 1448 imagesetthickness($this->img,$old); 1449 } 1450 1027 1451 function Rectangle($xl,$yu,$xr,$yl) { 1028 1029 } 1030 1452 $this->Polygon(array($xl,$yu,$xr,$yu,$xr,$yl,$xl,$yl,$xl,$yu)); 1453 } 1454 1031 1455 function FilledRectangle($xl,$yu,$xr,$yl) { 1032 1456 $this->FilledPolygon(array($xl,$yu,$xr,$yu,$xr,$yl,$xl,$yl)); 1033 1457 } 1034 1458 1035 1459 function FilledRectangle2($xl,$yu,$xr,$yl,$color1,$color2,$style=1) { 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 } 1063 1064 function ShadowRectangle($xl,$yu,$xr,$yl,$fcolor=false,$shadow_width= 3,$shadow_color=array(102,102,102)) {1065 1460 // Fill a rectangle with lines of two colors 1461 if( $style===1 ) { 1462 // Horizontal stripe 1463 if( $yl < $yu ) { 1464 $t = $yl; $yl=$yu; $yu=$t; 1465 } 1466 for( $y=$yu; $y <= $yl; ++$y) { 1467 $this->SetColor($color1); 1468 $this->Line($xl,$y,$xr,$y); 1469 ++$y; 1470 $this->SetColor($color2); 1471 $this->Line($xl,$y,$xr,$y); 1472 } 1473 } 1474 else { 1475 if( $xl < $xl ) { 1476 $t = $xl; $xl=$xr; $xr=$t; 1477 } 1478 for( $x=$xl; $x <= $xr; ++$x) { 1479 $this->SetColor($color1); 1480 $this->Line($x,$yu,$x,$yl); 1481 ++$x; 1482 $this->SetColor($color2); 1483 $this->Line($x,$yu,$x,$yl); 1484 } 1485 } 1486 } 1487 1488 function ShadowRectangle($xl,$yu,$xr,$yl,$fcolor=false,$shadow_width=4,$shadow_color='darkgray',$useAlpha=true) { 1489 // This is complicated by the fact that we must also handle the case where 1066 1490 // the reactangle has no fill color 1067 $this->PushColor($shadow_color); 1068 $this->FilledRectangle($xr-$shadow_width,$yu+$shadow_width,$xr,$yl-$shadow_width-1); 1069 $this->FilledRectangle($xl+$shadow_width,$yl-$shadow_width,$xr,$yl); 1070 //$this->FilledRectangle($xl+$shadow_width,$yu+$shadow_width,$xr,$yl); 1071 $this->PopColor(); 1072 if( $fcolor==false ) 1073 $this->Rectangle($xl,$yu,$xr-$shadow_width-1,$yl-$shadow_width-1); 1074 else { 1075 $this->PushColor($fcolor); 1076 $this->FilledRectangle($xl,$yu,$xr-$shadow_width-1,$yl-$shadow_width-1); 1077 $this->PopColor(); 1078 $this->Rectangle($xl,$yu,$xr-$shadow_width-1,$yl-$shadow_width-1); 1079 } 1491 $xl = floor($xl); 1492 $yu = floor($yu); 1493 $xr = floor($xr); 1494 $yl = floor($yl); 1495 $this->PushColor($shadow_color); 1496 $shadowAlpha=0; 1497 $this->SetLineWeight(1); 1498 $this->SetLineStyle('solid'); 1499 $basecolor = $this->rgb->Color($shadow_color); 1500 $shadow_color = array($basecolor[0],$basecolor[1],$basecolor[2],); 1501 for( $i=0; $i < $shadow_width; ++$i ) { 1502 $this->SetColor($shadow_color,$shadowAlpha); 1503 $this->Line($xr-$shadow_width+$i, $yu+$shadow_width, 1504 $xr-$shadow_width+$i, $yl-$shadow_width-1+$i); 1505 $this->Line($xl+$shadow_width, $yl-$shadow_width+$i, 1506 $xr-$shadow_width+$i, $yl-$shadow_width+$i); 1507 if( $useAlpha ) $shadowAlpha += 1.0/$shadow_width; 1508 } 1509 1510 $this->PopColor(); 1511 if( $fcolor==false ) { 1512 $this->Rectangle($xl,$yu,$xr-$shadow_width-1,$yl-$shadow_width-1); 1513 } 1514 else { 1515 $this->PushColor($fcolor); 1516 $this->FilledRectangle($xl,$yu,$xr-$shadow_width-1,$yl-$shadow_width-1); 1517 $this->PopColor(); 1518 $this->Rectangle($xl,$yu,$xr-$shadow_width-1,$yl-$shadow_width-1); 1519 } 1080 1520 } 1081 1521 1082 1522 function FilledRoundedRectangle($xt,$yt,$xr,$yl,$r=5) { 1083 1084 1085 1086 1087 1088 1089 // when alphablending is enabled) we have no choice but 1090 1091 1092 1093 1094 1095 $this->FilledRectangle($xt+$r,$yt,$xr-$r,$yt+$r-1);1096 1097 $this->FilledRectangle($xt+$r,$yl-$r+1,$xr-$r,$yl);1098 1099 $this->FilledRectangle($xt,$yt+$r+1,$xt+$r-1,$yl-$r);1100 1101 $this->FilledRectangle($xr-$r+1,$yt+$r,$xr,$yl-$r);1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 } 1112 1113 function RoundedRectangle($xt,$yt,$xr,$yl,$r=5) { 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1523 if( $r==0 ) { 1524 $this->FilledRectangle($xt,$yt,$xr,$yl); 1525 return; 1526 } 1527 1528 // To avoid overlapping fillings (which will look strange 1529 // when alphablending is enabled) we have no choice but 1530 // to fill the five distinct areas one by one. 1531 1532 // Center square 1533 $this->FilledRectangle($xt+$r,$yt+$r,$xr-$r,$yl-$r); 1534 // Top band 1535 $this->FilledRectangle($xt+$r,$yt,$xr-$r,$yt+$r); 1536 // Bottom band 1537 $this->FilledRectangle($xt+$r,$yl-$r,$xr-$r,$yl); 1538 // Left band 1539 $this->FilledRectangle($xt,$yt+$r,$xt+$r,$yl-$r); 1540 // Right band 1541 $this->FilledRectangle($xr-$r,$yt+$r,$xr,$yl-$r); 1542 1543 // Topleft & Topright arc 1544 $this->FilledArc($xt+$r,$yt+$r,$r*2,$r*2,180,270); 1545 $this->FilledArc($xr-$r,$yt+$r,$r*2,$r*2,270,360); 1546 1547 // Bottomleft & Bottom right arc 1548 $this->FilledArc($xt+$r,$yl-$r,$r*2,$r*2,90,180); 1549 $this->FilledArc($xr-$r,$yl-$r,$r*2,$r*2,0,90); 1550 1551 } 1552 1553 function RoundedRectangle($xt,$yt,$xr,$yl,$r=5) { 1554 1555 if( $r==0 ) { 1556 $this->Rectangle($xt,$yt,$xr,$yl); 1557 return; 1558 } 1559 1560 // Top & Bottom line 1561 $this->Line($xt+$r,$yt,$xr-$r,$yt); 1562 $this->Line($xt+$r,$yl,$xr-$r,$yl); 1563 1564 // Left & Right line 1565 $this->Line($xt,$yt+$r,$xt,$yl-$r); 1566 $this->Line($xr,$yt+$r,$xr,$yl-$r); 1567 1568 // Topleft & Topright arc 1569 $this->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270); 1570 $this->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360); 1571 1572 // Bottomleft & Bottomright arc 1573 $this->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180); 1574 $this->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90); 1135 1575 } 1136 1576 1137 1577 function FilledBevel($x1,$y1,$x2,$y2,$depth=2,$color1='white@0.4',$color2='darkgray@0.4') { 1138 1139 1578 $this->FilledRectangle($x1,$y1,$x2,$y2); 1579 $this->Bevel($x1,$y1,$x2,$y2,$depth,$color1,$color2); 1140 1580 } 1141 1581 1142 1582 function Bevel($x1,$y1,$x2,$y2,$depth=2,$color1='white@0.4',$color2='black@0.5') { 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1583 $this->PushColor($color1); 1584 for( $i=0; $i < $depth; ++$i ) { 1585 $this->Line($x1+$i,$y1+$i,$x1+$i,$y2-$i); 1586 $this->Line($x1+$i,$y1+$i,$x2-$i,$y1+$i); 1587 } 1588 $this->PopColor(); 1589 1590 $this->PushColor($color2); 1591 for( $i=0; $i < $depth; ++$i ) { 1592 $this->Line($x1+$i,$y2-$i,$x2-$i,$y2-$i); 1593 $this->Line($x2-$i,$y1+$i,$x2-$i,$y2-$i-1); 1594 } 1595 $this->PopColor(); 1156 1596 } 1157 1597 1158 1598 function StyleLineTo($x,$y) { 1159 1160 1161 1162 } 1163 1599 $this->StyleLine($this->lastx,$this->lasty,$x,$y); 1600 $this->lastx=$x; 1601 $this->lasty=$y; 1602 } 1603 1164 1604 function LineTo($x,$y) { 1165 1166 1167 1168 } 1169 1605 $this->Line($this->lastx,$this->lasty,$x,$y); 1606 $this->lastx=$x; 1607 $this->lasty=$y; 1608 } 1609 1170 1610 function Point($x,$y) { 1171 1172 } 1173 1611 imagesetpixel($this->img,round($x),round($y),$this->current_color); 1612 } 1613 1174 1614 function Fill($x,$y) { 1175 1615 imagefill($this->img,round($x),round($y),$this->current_color); 1176 1616 } 1177 1617 1178 1618 function FillToBorder($x,$y,$aBordColor) { 1179 1180 1181 1182 1183 1619 $bc = $this->rgb->allocate($aBordColor); 1620 if( $bc == -1 ) { 1621 JpGraphError::RaiseL(25106);//('Image::FillToBorder : Can not allocate more colors'); 1622 } 1623 imagefilltoborder($this->img,round($x),round($y),$bc,$this->current_color); 1184 1624 } 1185 1625 1186 1626 function SetExpired($aFlg=true) { 1187 1188 } 1189 1627 $this->expired = $aFlg; 1628 } 1629 1190 1630 // Generate image header 1191 1631 function Headers() { 1192 1193 // In case we are running from the command line with the client version of 1194 // PHP we can't send any headers. 1195 $sapi = php_sapi_name(); 1196 if( $sapi == 'cli' ) 1197 return; 1198 1199 // These parameters are set by headers_sent() but they might cause 1200 // an undefined variable error unless they are initilized 1201 $file=''; 1202 $lineno=''; 1203 if( headers_sent($file,$lineno) ) { 1204 $file=basename($file); 1205 $t = new ErrMsgText(); 1206 $msg = $t->Get(10,$file,$lineno); 1207 die($msg); 1208 } 1209 1210 if ($this->expired) { 1211 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); 1212 header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT"); 1213 header("Cache-Control: no-cache, must-revalidate"); 1214 header("Pragma: no-cache"); 1215 } 1216 header("Content-type: image/$this->img_format"); 1632 1633 // In case we are running from the command line with the client version of 1634 // PHP we can't send any headers. 1635 $sapi = php_sapi_name(); 1636 if( $sapi == 'cli' ) return; 1637 1638 // These parameters are set by headers_sent() but they might cause 1639 // an undefined variable error unless they are initilized 1640 $file=''; 1641 $lineno=''; 1642 if( headers_sent($file,$lineno) ) { 1643 $file=basename($file); 1644 $t = new ErrMsgText(); 1645 $msg = $t->Get(10,$file,$lineno); 1646 die($msg); 1647 } 1648 1649 if ($this->expired) { 1650 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); 1651 header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT"); 1652 header("Cache-Control: no-cache, must-revalidate"); 1653 header("Pragma: no-cache"); 1654 } 1655 header("Content-type: image/$this->img_format"); 1217 1656 } 1218 1657 1219 1658 // Adjust image quality for formats that allow this 1220 1659 function SetQuality($q) { 1221 1222 } 1223 1660 $this->quality = $q; 1661 } 1662 1224 1663 // Stream image to browser or to file 1225 function Stream($aFile="") { 1226 $func="image".$this->img_format; 1227 if( $this->img_format=="jpeg" && $this->quality != null ) { 1228 $res = @$func($this->img,$aFile,$this->quality); 1229 } 1230 else { 1231 if( $aFile != "" ) { 1232 $res = @$func($this->img,$aFile); 1233 if( !$res ) 1234 JpGraphError::RaiseL(25107,$aFile);//("Can't write to file '$aFile'. Check that the process running PHP has enough permission."); 1235 } 1236 else { 1237 $res = @$func($this->img); 1238 if( !$res ) 1239 JpGraphError::RaiseL(25108);//("Can't stream image. This is most likely due to a faulty PHP/GD setup. Try to recompile PHP and use the built-in GD library that comes with PHP."); 1664 function Stream($aFile=NULL) { 1665 $this->DoSupersampling(); 1666 1667 $func="image".$this->img_format; 1668 if( $this->img_format=="jpeg" && $this->quality != null ) { 1669 $res = @$func($this->img,$aFile,$this->quality); 1670 1671 if(!$res){ 1672 if($aFile != NULL){ 1673 JpGraphError::RaiseL(25107,$aFile);//("Can't write to file '$aFile'. Check that the process running PHP has enough permission."); 1674 }else{ 1675 JpGraphError::RaiseL(25108);//("Can't stream image. This is most likely due to a faulty PHP/GD setup. Try to recompile PHP and use the built-in GD library that comes with PHP."); 1676 } 1240 1677 1241 } 1242 } 1243 } 1244 1245 // Clear resource tide up by image 1678 } 1679 } 1680 else { 1681 if( $aFile != NULL ) { 1682 $res = @$func($this->img,$aFile); 1683 if( !$res ) { 1684 JpGraphError::RaiseL(25107,$aFile);//("Can't write to file '$aFile'. Check that the process running PHP has enough permission."); 1685 } 1686 } 1687 else { 1688 $res = @$func($this->img); 1689 if( !$res ) { 1690 JpGraphError::RaiseL(25108);//("Can't stream image. This is most likely due to a faulty PHP/GD setup. Try to recompile PHP and use the built-in GD library that comes with PHP."); 1691 } 1692 1693 } 1694 } 1695 } 1696 1697 // Do SuperSampling using $scale 1698 function DoSupersampling() { 1699 if (SUPERSAMPLING_SCALE <= 1) { 1700 return $this->img; 1701 } 1702 1703 $dst_img = @imagecreatetruecolor($this->original_width, $this->original_height); 1704 imagecopyresampled($dst_img, $this->img, 0, 0, 0, 0, $this->original_width, $this->original_height, $this->width, $this->height); 1705 $this->Destroy(); 1706 return $this->img = $dst_img; 1707 } 1708 1709 // Clear resources used by image (this is normally not used since all resources are/should be 1710 // returned when the script terminates 1246 1711 function Destroy() { 1247 1248 } 1249 1712 imagedestroy($this->img); 1713 } 1714 1250 1715 // Specify image format. Note depending on your installation 1251 1716 // of PHP not all formats may be supported. 1252 function SetImgFormat($aFormat,$aQuality=75) { 1253 $this->quality = $aQuality; 1254 $aFormat = strtolower($aFormat); 1255 $tst = true; 1256 $supported = imagetypes(); 1257 if( $aFormat=="auto" ) { 1258 if( $supported & IMG_PNG ) 1259 $this->img_format="png"; 1260 elseif( $supported & IMG_JPG ) 1261 $this->img_format="jpeg"; 1262 elseif( $supported & IMG_GIF ) 1263 $this->img_format="gif"; 1264 elseif( $supported & IMG_WBMP ) 1265 $this->img_format="wbmp"; 1266 elseif( $supported & IMG_XPM ) 1267 $this->img_format="xpm"; 1268 else 1269 JpGraphError::RaiseL(25109);//("Your PHP (and GD-lib) installation does not appear to support any known graphic formats. You need to first make sure GD is compiled as a module to PHP. If you also want to use JPEG images you must get the JPEG library. Please see the PHP docs for details."); 1270 1271 return true; 1272 } 1273 else { 1274 if( $aFormat=="jpeg" || $aFormat=="png" || $aFormat=="gif" ) { 1275 if( $aFormat=="jpeg" && !($supported & IMG_JPG) ) 1276 $tst=false; 1277 elseif( $aFormat=="png" && !($supported & IMG_PNG) ) 1278 $tst=false; 1279 elseif( $aFormat=="gif" && !($supported & IMG_GIF) ) 1280 $tst=false; 1281 elseif( $aFormat=="wbmp" && !($supported & IMG_WBMP) ) 1282 $tst=false; 1283 elseif( $aFormat=="xpm" && !($supported & IMG_XPM) ) 1284 $tst=false; 1285 else { 1286 $this->img_format=$aFormat; 1287 return true; 1288 } 1289 } 1290 else 1291 $tst=false; 1292 if( !$tst ) 1293 JpGraphError::RaiseL(25110,$aFormat);//(" Your PHP installation does not support the chosen graphic format: $aFormat"); 1294 } 1295 } 1717 function SetImgFormat($aFormat,$aQuality=75) { 1718 $this->quality = $aQuality; 1719 $aFormat = strtolower($aFormat); 1720 $tst = true; 1721 $supported = imagetypes(); 1722 if( $aFormat=="auto" ) { 1723 if( $supported & IMG_PNG ) $this->img_format="png"; 1724 elseif( $supported & IMG_JPG ) $this->img_format="jpeg"; 1725 elseif( $supported & IMG_GIF ) $this->img_format="gif"; 1726 elseif( $supported & IMG_WBMP ) $this->img_format="wbmp"; 1727 elseif( $supported & IMG_XPM ) $this->img_format="xpm"; 1728 else { 1729 JpGraphError::RaiseL(25109);//("Your PHP (and GD-lib) installation does not appear to support any known graphic formats. You need to first make sure GD is compiled as a module to PHP. If you also want to use JPEG images you must get the JPEG library. Please see the PHP docs for details."); 1730 } 1731 return true; 1732 } 1733 else { 1734 if( $aFormat=="jpeg" || $aFormat=="png" || $aFormat=="gif" ) { 1735 if( $aFormat=="jpeg" && !($supported & IMG_JPG) ) $tst=false; 1736 elseif( $aFormat=="png" && !($supported & IMG_PNG) ) $tst=false; 1737 elseif( $aFormat=="gif" && !($supported & IMG_GIF) ) $tst=false; 1738 elseif( $aFormat=="wbmp" && !($supported & IMG_WBMP) ) $tst=false; 1739 elseif( $aFormat=="xpm" && !($supported & IMG_XPM) ) $tst=false; 1740 else { 1741 $this->img_format=$aFormat; 1742 return true; 1743 } 1744 } 1745 else { 1746 $tst=false; 1747 } 1748 if( !$tst ) { 1749 JpGraphError::RaiseL(25110,$aFormat);//(" Your PHP installation does not support the chosen graphic format: $aFormat"); 1750 } 1751 } 1752 } 1753 1754 /** 1755 * Draw Line 1756 */ 1757 function DrawLine($im, $x1, $y1, $x2, $y2, $weight, $color) { 1758 if ($weight == 1) { 1759 return imageline($im,$x1,$y1,$x2,$y2,$color); 1760 } 1761 1762 $angle=(atan2(($y1 - $y2), ($x2 - $x1))); 1763 1764 $dist_x = $weight * (sin($angle)) / 2; 1765 $dist_y = $weight * (cos($angle)) / 2; 1766 1767 $p1x=ceil(($x1 + $dist_x)); 1768 $p1y=ceil(($y1 + $dist_y)); 1769 $p2x=ceil(($x2 + $dist_x)); 1770 $p2y=ceil(($y2 + $dist_y)); 1771 $p3x=ceil(($x2 - $dist_x)); 1772 $p3y=ceil(($y2 - $dist_y)); 1773 $p4x=ceil(($x1 - $dist_x)); 1774 $p4y=ceil(($y1 - $dist_y)); 1775 1776 $array=array($p1x,$p1y,$p2x,$p2y,$p3x,$p3y,$p4x,$p4y); 1777 imagefilledpolygon ( $im, $array, (count($array)/2), $color ); 1778 1779 // for antialias 1780 imageline($im, $p1x, $p1y, $p2x, $p2y, $color); 1781 imageline($im, $p3x, $p3y, $p4x, $p4y, $color); 1782 return; 1783 1784 1785 1786 return imageline($this->img,$x1,$y1,$x2,$y2,$this->current_color); 1787 $weight = 8; 1788 if ($weight <= 1) { 1789 return imageline($this->img,$x1,$y1,$x2,$y2,$this->current_color); 1790 } 1791 1792 $pts = array(); 1793 1794 $weight /= 2; 1795 1796 if ($y2 - $y1 == 0) { 1797 // x line 1798 $pts = array(); 1799 $pts[] = $x1; $pts[] = $y1 - $weight; 1800 $pts[] = $x1; $pts[] = $y1 + $weight; 1801 $pts[] = $x2; $pts[] = $y2 + $weight; 1802 $pts[] = $x2; $pts[] = $y2 - $weight; 1803 1804 } elseif ($x2 - $x1 == 0) { 1805 // y line 1806 $pts = array(); 1807 $pts[] = $x1 - $weight; $pts[] = $y1; 1808 $pts[] = $x1 + $weight; $pts[] = $y1; 1809 $pts[] = $x2 + $weight; $pts[] = $y2; 1810 $pts[] = $x2 - $weight; $pts[] = $y2; 1811 1812 } else { 1813 1814 var_dump($x1, $x2, $y1, $y2); 1815 $length = sqrt(pow($x2 - $x1, 2) + pow($y2 - $y1, 2)); 1816 var_dump($length);exit; 1817 exit; 1818 1819 /* 1820 $lean = ($y2 - $y1) / ($x2 - $x1); 1821 $lean2 = -1 / $lean; 1822 $sin = $lean / ($y2 - $y1); 1823 $cos = $lean / ($x2 - $x1); 1824 1825 $pts[] = $x1 + (-$weight * $sin); $pts[] = $y1 + (-$weight * $cos); 1826 $pts[] = $x1 + (+$weight * $sin); $pts[] = $y1 + (+$weight * $cos); 1827 $pts[] = $x2 + (+$weight * $sin); $pts[] = $y2 + (+$weight * $cos); 1828 $pts[] = $x2 + (-$weight * $sin); $pts[] = $y2 + (-$weight * $cos); 1829 */ 1830 } 1831 1832 //print_r($pts);exit; 1833 if (count($pts)/2 < 3) { 1834 return; 1835 } 1836 1837 imagesetthickness($im, 1); 1838 imagefilledpolygon($im, $pts,count($pts)/2, $color); 1839 1840 1841 $weight *= 2; 1842 1843 // $this->DrawImageSmoothArc($im, $x1, $y1, $weight, $weight, 0, 360, $color); 1844 // $this->DrawImageSmoothArc($im, $x2, $y2, $weight, $weight, 0, 360, $color); 1845 } 1846 1847 1848 function DrawImageSmoothArc($im, $xc, $yc, $w, $h, $s, $e, $color, $style = null) { 1849 $tmp = $s; 1850 $s = (360 - $e) / 180 * M_PI; 1851 $e = (360 - $tmp) / 180 * M_PI; 1852 return imageSmoothArc($im, round($xc), round($yc), round($w), round($h), $this->CreateColorForImageSmoothArc($color), $s, $e); 1853 } 1854 1855 function CreateColorForImageSmoothArc($color) { 1856 $alpha = $color >> 24 & 0xFF; 1857 $red = $color >> 16 & 0xFF; 1858 $green = $color >> 8 & 0xFF; 1859 $blue = $color & 0xFF; 1860 1861 //var_dump($alpha, $red, $green, $blue);exit; 1862 1863 return array($red, $green, $blue, $alpha); 1864 } 1865 1866 function imageSmoothCircle( &$img, $cx, $cy, $cr, $color ) { 1867 $ir = $cr; 1868 $ix = 0; 1869 $iy = $ir; 1870 $ig = 2 * $ir - 3; 1871 $idgr = -6; 1872 $idgd = 4 * $ir - 10; 1873 $fill = imageColorExactAlpha( $img, $color[ 'R' ], $color[ 'G' ], $color[ 'B' ], 0 ); 1874 imageLine( $img, $cx + $cr - 1, $cy, $cx, $cy, $fill ); 1875 imageLine( $img, $cx - $cr + 1, $cy, $cx - 1, $cy, $fill ); 1876 imageLine( $img, $cx, $cy + $cr - 1, $cx, $cy + 1, $fill ); 1877 imageLine( $img, $cx, $cy - $cr + 1, $cx, $cy - 1, $fill ); 1878 $draw = imageColorExactAlpha( $img, $color[ 'R' ], $color[ 'G' ], $color[ 'B' ], 42 ); 1879 imageSetPixel( $img, $cx + $cr, $cy, $draw ); 1880 imageSetPixel( $img, $cx - $cr, $cy, $draw ); 1881 imageSetPixel( $img, $cx, $cy + $cr, $draw ); 1882 imageSetPixel( $img, $cx, $cy - $cr, $draw ); 1883 while ( $ix <= $iy - 2 ) { 1884 if ( $ig < 0 ) { 1885 $ig += $idgd; 1886 $idgd -= 8; 1887 $iy--; 1888 } else { 1889 $ig += $idgr; 1890 $idgd -= 4; 1891 } 1892 $idgr -= 4; 1893 $ix++; 1894 imageLine( $img, $cx + $ix, $cy + $iy - 1, $cx + $ix, $cy + $ix, $fill ); 1895 imageLine( $img, $cx + $ix, $cy - $iy + 1, $cx + $ix, $cy - $ix, $fill ); 1896 imageLine( $img, $cx - $ix, $cy + $iy - 1, $cx - $ix, $cy + $ix, $fill ); 1897 imageLine( $img, $cx - $ix, $cy - $iy + 1, $cx - $ix, $cy - $ix, $fill ); 1898 imageLine( $img, $cx + $iy - 1, $cy + $ix, $cx + $ix, $cy + $ix, $fill ); 1899 imageLine( $img, $cx + $iy - 1, $cy - $ix, $cx + $ix, $cy - $ix, $fill ); 1900 imageLine( $img, $cx - $iy + 1, $cy + $ix, $cx - $ix, $cy + $ix, $fill ); 1901 imageLine( $img, $cx - $iy + 1, $cy - $ix, $cx - $ix, $cy - $ix, $fill ); 1902 $filled = 0; 1903 for ( $xx = $ix - 0.45; $xx < $ix + 0.5; $xx += 0.2 ) { 1904 for ( $yy = $iy - 0.45; $yy < $iy + 0.5; $yy += 0.2 ) { 1905 if ( sqrt( pow( $xx, 2 ) + pow( $yy, 2 ) ) < $cr ) $filled += 4; 1906 } 1907 } 1908 $draw = imageColorExactAlpha( $img, $color[ 'R' ], $color[ 'G' ], $color[ 'B' ], ( 100 - $filled ) ); 1909 imageSetPixel( $img, $cx + $ix, $cy + $iy, $draw ); 1910 imageSetPixel( $img, $cx + $ix, $cy - $iy, $draw ); 1911 imageSetPixel( $img, $cx - $ix, $cy + $iy, $draw ); 1912 imageSetPixel( $img, $cx - $ix, $cy - $iy, $draw ); 1913 imageSetPixel( $img, $cx + $iy, $cy + $ix, $draw ); 1914 imageSetPixel( $img, $cx + $iy, $cy - $ix, $draw ); 1915 imageSetPixel( $img, $cx - $iy, $cy + $ix, $draw ); 1916 imageSetPixel( $img, $cx - $iy, $cy - $ix, $draw ); 1917 } 1918 } 1919 1920 function __get($name) { 1921 1922 if (strpos($name, 'raw_') !== false) { 1923 // if $name == 'raw_left_margin' , return $this->_left_margin; 1924 $variable_name = '_' . str_replace('raw_', '', $name); 1925 return $this->$variable_name; 1926 } 1927 1928 $variable_name = '_' . $name; 1929 1930 if (isset($this->$variable_name)) { 1931 return $this->$variable_name * SUPERSAMPLING_SCALE; 1932 } else { 1933 JpGraphError::RaiseL('25132', $name); 1934 } 1935 } 1936 1937 function __set($name, $value) { 1938 $this->{'_'.$name} = $value; 1939 } 1940 1296 1941 } // CLASS 1297 1942 … … 1303 1948 class RotImage extends Image { 1304 1949 public $a=0; 1305 public $dx=0,$dy=0,$transx=0,$transy=0; 1950 public $dx=0,$dy=0,$transx=0,$transy=0; 1306 1951 private $m=array(); 1307 1308 function RotImage($aWidth,$aHeight,$a=0,$aFormat=DEFAULT_GFORMAT,$aSetAutoMargin=true) {1309 $this->Image($aWidth,$aHeight,$aFormat,$aSetAutoMargin);1310 $this->dx=$this->left_margin+$this->plotwidth/2;1311 $this->dy=$this->top_margin+$this->plotheight/2;1312 $this->SetAngle($a); 1313 } 1314 1952 1953 function __construct($aWidth,$aHeight,$a=0,$aFormat=DEFAULT_GFORMAT,$aSetAutoMargin=true) { 1954 parent::__construct($aWidth,$aHeight,$aFormat,$aSetAutoMargin); 1955 $this->dx=$this->width/2; 1956 $this->dy=$this->height/2; 1957 $this->SetAngle($a); 1958 } 1959 1315 1960 function SetCenter($dx,$dy) { 1316 1317 1318 1319 1320 1321 1322 } 1323 1961 $old_dx = $this->dx; 1962 $old_dy = $this->dy; 1963 $this->dx=$dx; 1964 $this->dy=$dy; 1965 $this->SetAngle($this->a); 1966 return array($old_dx,$old_dy); 1967 } 1968 1324 1969 function SetTranslation($dx,$dy) { 1325 1326 1327 1328 1970 $old = array($this->transx,$this->transy); 1971 $this->transx = $dx; 1972 $this->transy = $dy; 1973 return $old; 1329 1974 } 1330 1975 1331 1976 function UpdateRotMatrice() { 1332 1333 1334 $sa=sin($a); $ca=cos($a); 1335 1336 1337 1338 1339 1340 1341 1977 $a = $this->a; 1978 $a *= M_PI/180; 1979 $sa=sin($a); $ca=cos($a); 1980 // Create the rotation matrix 1981 $this->m[0][0] = $ca; 1982 $this->m[0][1] = -$sa; 1983 $this->m[0][2] = $this->dx*(1-$ca) + $sa*$this->dy ; 1984 $this->m[1][0] = $sa; 1985 $this->m[1][1] = $ca; 1986 $this->m[1][2] = $this->dy*(1-$ca) - $sa*$this->dx ; 1342 1987 } 1343 1988 1344 1989 function SetAngle($a) { 1345 1346 1347 1348 1990 $tmp = $this->a; 1991 $this->a = $a; 1992 $this->UpdateRotMatrice(); 1993 return $tmp; 1349 1994 } 1350 1995 1351 1996 function Circle($xc,$yc,$r) { 1352 1353 1997 list($xc,$yc) = $this->Rotate($xc,$yc); 1998 parent::Circle($xc,$yc,$r); 1354 1999 } 1355 2000 1356 2001 function FilledCircle($xc,$yc,$r) { 1357 1358 1359 } 1360 1361 2002 list($xc,$yc) = $this->Rotate($xc,$yc); 2003 parent::FilledCircle($xc,$yc,$r); 2004 } 2005 2006 1362 2007 function Arc($xc,$yc,$w,$h,$s,$e) { 1363 1364 1365 1366 2008 list($xc,$yc) = $this->Rotate($xc,$yc); 2009 $s += $this->a; 2010 $e += $this->a; 2011 parent::Arc($xc,$yc,$w,$h,$s,$e); 1367 2012 } 1368 2013 1369 2014 function FilledArc($xc,$yc,$w,$h,$s,$e,$style='') { 1370 1371 1372 1373 2015 list($xc,$yc) = $this->Rotate($xc,$yc); 2016 $s += $this->a; 2017 $e += $this->a; 2018 parent::FilledArc($xc,$yc,$w,$h,$s,$e); 1374 2019 } 1375 2020 1376 2021 function SetMargin($lm,$rm,$tm,$bm) { 1377 parent::SetMargin($lm,$rm,$tm,$bm); 1378 $this->dx=$this->left_margin+$this->plotwidth/2; 1379 $this->dy=$this->top_margin+$this->plotheight/2; 1380 $this->UpdateRotMatrice(); 1381 } 1382 2022 parent::SetMargin($lm,$rm,$tm,$bm); 2023 $this->UpdateRotMatrice(); 2024 } 2025 1383 2026 function Rotate($x,$y) { 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 } 1394 2027 // Optimization. Ignore rotation if Angle==0 || Angle==360 2028 if( $this->a == 0 || $this->a == 360 ) { 2029 return array($x + $this->transx, $y + $this->transy ); 2030 } 2031 else { 2032 $x1=round($this->m[0][0]*$x + $this->m[0][1]*$y,1) + $this->m[0][2] + $this->transx; 2033 $y1=round($this->m[1][0]*$x + $this->m[1][1]*$y,1) + $this->m[1][2] + $this->transy; 2034 return array($x1,$y1); 2035 } 2036 } 2037 1395 2038 function CopyMerge($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth=-1,$fromHeight=-1,$aMix=100) { 1396 1397 2039 list($toX,$toY) = $this->Rotate($toX,$toY); 2040 parent::CopyMerge($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth,$fromHeight,$aMix); 1398 2041 1399 2042 } 1400 2043 1401 2044 function ArrRotate($pnts) { 1402 1403 1404 1405 1406 1407 2045 $n = count($pnts)-1; 2046 for($i=0; $i < $n; $i+=2) { 2047 list ($x,$y) = $this->Rotate($pnts[$i],$pnts[$i+1]); 2048 $pnts[$i] = $x; $pnts[$i+1] = $y; 2049 } 2050 return $pnts; 1408 2051 } 1409 2052 1410 2053 function DashedLine($x1,$y1,$x2,$y2,$dash_length=1,$dash_space=4) { 1411 1412 1413 1414 } 1415 2054 list($x1,$y1) = $this->Rotate($x1,$y1); 2055 list($x2,$y2) = $this->Rotate($x2,$y2); 2056 parent::DashedLine($x1,$y1,$x2,$y2,$dash_length,$dash_space); 2057 } 2058 1416 2059 function Line($x1,$y1,$x2,$y2) { 1417 1418 1419 2060 list($x1,$y1) = $this->Rotate($x1,$y1); 2061 list($x2,$y2) = $this->Rotate($x2,$y2); 2062 parent::Line($x1,$y1,$x2,$y2); 1420 2063 } 1421 2064 1422 2065 function Rectangle($x1,$y1,$x2,$y2) { 1423 1424 1425 } 1426 2066 // Rectangle uses Line() so it will be rotated through that call 2067 parent::Rectangle($x1,$y1,$x2,$y2); 2068 } 2069 1427 2070 function FilledRectangle($x1,$y1,$x2,$y2) { 1428 1429 1430 else 1431 1432 } 1433 2071 if( $y1==$y2 || $x1==$x2 ) 2072 $this->Line($x1,$y1,$x2,$y2); 2073 else 2074 $this->FilledPolygon(array($x1,$y1,$x2,$y1,$x2,$y2,$x1,$y2)); 2075 } 2076 1434 2077 function Polygon($pnts,$closed=FALSE,$fast=FALSE) { 1435 // Polygon uses Line() so it will be rotated through that call unless 1436 // fast drawing routines are used in which case a rotate is needed 1437 if( $fast ) { 1438 parent::Polygon($this->ArrRotate($pnts)); 1439 } 1440 else 1441 parent::Polygon($pnts,$closed,$fast); 1442 } 1443 2078 // Polygon uses Line() so it will be rotated through that call unless 2079 // fast drawing routines are used in which case a rotate is needed 2080 if( $fast ) { 2081 parent::Polygon($this->ArrRotate($pnts)); 2082 } 2083 else { 2084 parent::Polygon($pnts,$closed,$fast); 2085 } 2086 } 2087 1444 2088 function FilledPolygon($pnts) { 1445 1446 } 1447 2089 parent::FilledPolygon($this->ArrRotate($pnts)); 2090 } 2091 1448 2092 function Point($x,$y) { 1449 1450 1451 } 1452 2093 list($xp,$yp) = $this->Rotate($x,$y); 2094 parent::Point($xp,$yp); 2095 } 2096 1453 2097 function StrokeText($x,$y,$txt,$dir=0,$paragraph_align="left",$debug=false) { 1454 1455 2098 list($xp,$yp) = $this->Rotate($x,$y); 2099 return parent::StrokeText($xp,$yp,$txt,$dir,$paragraph_align,$debug); 1456 2100 } 1457 2101 } 1458 2102 1459 //=================================================== 2103 //======================================================================= 1460 2104 // CLASS ImgStreamCache 1461 // Description: Handle caching of graphs to files 1462 //=================================================== 2105 // Description: Handle caching of graphs to files. All image output goes 2106 // through this class 2107 //======================================================================= 1463 2108 class ImgStreamCache { 1464 private $cache_dir, $ img=null, $timeout=0;// Infinite timeout2109 private $cache_dir, $timeout=0; // Infinite timeout 1465 2110 //--------------- 1466 2111 // CONSTRUCTOR 1467 function ImgStreamCache($aImg, $aCacheDir=CACHE_DIR) { 1468 $this->img = $aImg; 1469 $this->cache_dir = $aCacheDir; 1470 } 1471 1472 //--------------- 1473 // PUBLIC METHODS 2112 function __construct($aCacheDir=CACHE_DIR) { 2113 $this->cache_dir = $aCacheDir; 2114 } 2115 2116 //--------------- 2117 // PUBLIC METHODS 1474 2118 1475 2119 // Specify a timeout (in minutes) for the file. If the file is older then the … … 1478 2122 // timeout is set to -1 this is the same as infinite small timeout 1479 2123 function SetTimeout($aTimeout) { 1480 $this->timeout=$aTimeout; 1481 } 1482 2124 $this->timeout=$aTimeout; 2125 } 2126 1483 2127 // Output image to browser and also write it to the cache 1484 2128 function PutAndStream($aImage,$aCacheFileName,$aInline,$aStrokeFileName) { 1485 // Some debugging code to brand the image with numbe of colors 1486 // used 1487 GLOBAL $gJpgBrandTiming; 1488 1489 if( $gJpgBrandTiming ) { 1490 global $tim; 1491 $t=$tim->Pop()/1000.0; 1492 $c=$aImage->SetColor("black"); 1493 $t=sprintf(BRAND_TIME_FORMAT,round($t,3)); 1494 imagestring($this->img->img,2,5,$this->img->height-20,$t,$c); 1495 } 1496 1497 // Check if we should stroke the image to an arbitrary file 1498 if( _FORCE_IMGTOFILE ) { 1499 $aStrokeFileName = _FORCE_IMGDIR.GenImgName(); 1500 } 1501 1502 if( $aStrokeFileName!="" ) { 1503 if( $aStrokeFileName == "auto" ) 1504 $aStrokeFileName = GenImgName(); 1505 if( file_exists($aStrokeFileName) ) { 1506 // Delete the old file 1507 if( !@unlink($aStrokeFileName) ) 1508 JpGraphError::RaiseL(25111,$aStrokeFileName);//(" Can't delete cached image $aStrokeFileName. Permission problem?"); 1509 } 1510 $aImage->Stream($aStrokeFileName); 1511 return; 1512 } 1513 1514 if( $aCacheFileName != "" && USE_CACHE) { 1515 1516 $aCacheFileName = $this->cache_dir . $aCacheFileName; 1517 if( file_exists($aCacheFileName) ) { 1518 if( !$aInline ) { 1519 // If we are generating image off-line (just writing to the cache) 1520 // and the file exists and is still valid (no timeout) 1521 // then do nothing, just return. 1522 $diff=time()-filemtime($aCacheFileName); 1523 if( $diff < 0 ) 1524 JpGraphError::RaiseL(25112,$aCacheFileName);//(" Cached imagefile ($aCacheFileName) has file date in the future!!"); 1525 if( $this->timeout>0 && ($diff <= $this->timeout*60) ) 1526 return; 1527 } 1528 if( !@unlink($aCacheFileName) ) 1529 JpGraphError::RaiseL(25113,$aStrokeFileName);//(" Can't delete cached image $aStrokeFileName. Permission problem?"); 1530 $aImage->Stream($aCacheFileName); 1531 } 1532 else { 1533 $this->MakeDirs(dirname($aCacheFileName)); 1534 if( !is_writeable(dirname($aCacheFileName)) ) { 1535 JpGraphError::RaiseL(25114,$aCacheFileName);//('PHP has not enough permissions to write to the cache file '.$aCacheFileName.'. Please make sure that the user running PHP has write permission for this file if you wan to use the cache system with JpGraph.'); 1536 } 1537 $aImage->Stream($aCacheFileName); 1538 } 1539 1540 $res=true; 1541 // Set group to specified 1542 if( CACHE_FILE_GROUP != "" ) 1543 $res = @chgrp($aCacheFileName,CACHE_FILE_GROUP); 1544 if( CACHE_FILE_MOD != "" ) 1545 $res = @chmod($aCacheFileName,CACHE_FILE_MOD); 1546 if( !$res ) 1547 JpGraphError::RaiseL(25115,$aStrokeFileName);//(" Can't set permission for cached image $aStrokeFileName. Permission problem?"); 1548 1549 $aImage->Destroy(); 1550 if( $aInline ) { 1551 if ($fh = @fopen($aCacheFileName, "rb") ) { 1552 $this->img->Headers(); 1553 fpassthru($fh); 1554 return; 1555 } 1556 else 1557 JpGraphError::RaiseL(25116,$aFile);//(" Cant open file from cache [$aFile]"); 1558 } 1559 } 1560 elseif( $aInline ) { 1561 $this->img->Headers(); 1562 $aImage->Stream(); 1563 return; 1564 } 1565 } 1566 2129 2130 // Check if we should always stroke the image to a file 2131 if( _FORCE_IMGTOFILE ) { 2132 $aStrokeFileName = _FORCE_IMGDIR.GenImgName(); 2133 } 2134 2135 if( $aStrokeFileName != '' ) { 2136 2137 if( $aStrokeFileName == 'auto' ) { 2138 $aStrokeFileName = GenImgName(); 2139 } 2140 2141 if( file_exists($aStrokeFileName) ) { 2142 2143 // Wait for lock (to make sure no readers are trying to access the image) 2144 $fd = fopen($aStrokeFileName,'w'); 2145 $lock = flock($fd, LOCK_EX); 2146 2147 // Since the image write routines only accepts a filename which must not 2148 // exist we need to delete the old file first 2149 if( !@unlink($aStrokeFileName) ) { 2150 $lock = flock($fd, LOCK_UN); 2151 JpGraphError::RaiseL(25111,$aStrokeFileName); 2152 //(" Can't delete cached image $aStrokeFileName. Permission problem?"); 2153 } 2154 $aImage->Stream($aStrokeFileName); 2155 $lock = flock($fd, LOCK_UN); 2156 fclose($fd); 2157 2158 } 2159 else { 2160 $aImage->Stream($aStrokeFileName); 2161 } 2162 2163 return; 2164 } 2165 2166 if( $aCacheFileName != '' && USE_CACHE) { 2167 2168 $aCacheFileName = $this->cache_dir . $aCacheFileName; 2169 if( file_exists($aCacheFileName) ) { 2170 if( !$aInline ) { 2171 // If we are generating image off-line (just writing to the cache) 2172 // and the file exists and is still valid (no timeout) 2173 // then do nothing, just return. 2174 $diff=time()-filemtime($aCacheFileName); 2175 if( $diff < 0 ) { 2176 JpGraphError::RaiseL(25112,$aCacheFileName); 2177 //(" Cached imagefile ($aCacheFileName) has file date in the future!!"); 2178 } 2179 if( $this->timeout>0 && ($diff <= $this->timeout*60) ) return; 2180 } 2181 2182 // Wait for lock (to make sure no readers are trying to access the image) 2183 $fd = fopen($aCacheFileName,'w'); 2184 $lock = flock($fd, LOCK_EX); 2185 2186 if( !@unlink($aCacheFileName) ) { 2187 $lock = flock($fd, LOCK_UN); 2188 JpGraphError::RaiseL(25113,$aStrokeFileName); 2189 //(" Can't delete cached image $aStrokeFileName. Permission problem?"); 2190 } 2191 $aImage->Stream($aCacheFileName); 2192 $lock = flock($fd, LOCK_UN); 2193 fclose($fd); 2194 2195 } 2196 else { 2197 $this->MakeDirs(dirname($aCacheFileName)); 2198 if( !is_writeable(dirname($aCacheFileName)) ) { 2199 JpGraphError::RaiseL(25114,$aCacheFileName); 2200 //('PHP has not enough permissions to write to the cache file '.$aCacheFileName.'. Please make sure that the user running PHP has write permission for this file if you wan to use the cache system with JpGraph.'); 2201 } 2202 $aImage->Stream($aCacheFileName); 2203 } 2204 2205 $res=true; 2206 // Set group to specified 2207 if( CACHE_FILE_GROUP != '' ) { 2208 $res = @chgrp($aCacheFileName,CACHE_FILE_GROUP); 2209 } 2210 if( CACHE_FILE_MOD != '' ) { 2211 $res = @chmod($aCacheFileName,CACHE_FILE_MOD); 2212 } 2213 if( !$res ) { 2214 JpGraphError::RaiseL(25115,$aStrokeFileName); 2215 //(" Can't set permission for cached image $aStrokeFileName. Permission problem?"); 2216 } 2217 2218 $aImage->Destroy(); 2219 if( $aInline ) { 2220 if ($fh = @fopen($aCacheFileName, "rb") ) { 2221 $aImage->Headers(); 2222 fpassthru($fh); 2223 return; 2224 } 2225 else { 2226 JpGraphError::RaiseL(25116,$aFile);//(" Cant open file from cache [$aFile]"); 2227 } 2228 } 2229 } 2230 elseif( $aInline ) { 2231 $aImage->Headers(); 2232 $aImage->Stream(); 2233 return; 2234 } 2235 } 2236 2237 function IsValid($aCacheFileName) { 2238 $aCacheFileName = $this->cache_dir.$aCacheFileName; 2239 if ( USE_CACHE && file_exists($aCacheFileName) ) { 2240 $diff=time()-filemtime($aCacheFileName); 2241 if( $this->timeout>0 && ($diff > $this->timeout*60) ) { 2242 return false; 2243 } 2244 else { 2245 return true; 2246 } 2247 } 2248 else { 2249 return false; 2250 } 2251 } 2252 2253 function StreamImgFile($aImage,$aCacheFileName) { 2254 $aCacheFileName = $this->cache_dir.$aCacheFileName; 2255 if ( $fh = @fopen($aCacheFileName, 'rb') ) { 2256 $lock = flock($fh, LOCK_SH); 2257 $aImage->Headers(); 2258 fpassthru($fh); 2259 $lock = flock($fh, LOCK_UN); 2260 fclose($fh); 2261 return true; 2262 } 2263 else { 2264 JpGraphError::RaiseL(25117,$aCacheFileName);//(" Can't open cached image \"$aCacheFileName\" for reading."); 2265 } 2266 } 2267 1567 2268 // Check if a given image is in cache and in that case 1568 2269 // pass it directly on to web browser. Return false if the 1569 2270 // image file doesn't exist or exists but is to old 1570 function GetAndStream($aCacheFileName) { 1571 $aCacheFileName = $this->cache_dir.$aCacheFileName; 1572 if ( USE_CACHE && file_exists($aCacheFileName) && $this->timeout>=0 ) { 1573 $diff=time()-filemtime($aCacheFileName); 1574 if( $this->timeout>0 && ($diff > $this->timeout*60) ) { 1575 return false; 1576 } 1577 else { 1578 if ($fh = @fopen($aCacheFileName, "rb")) { 1579 $this->img->Headers(); 1580 fpassthru($fh); 1581 return true; 1582 } 1583 else 1584 JpGraphError::RaiseL(25117,$aCacheFileName);//(" Can't open cached image \"$aCacheFileName\" for reading."); 1585 } 1586 } 1587 return false; 1588 } 1589 2271 function GetAndStream($aImage,$aCacheFileName) { 2272 if( $this->Isvalid($aCacheFileName) ) { 2273 $this->StreamImgFile($aImage,$aCacheFileName); 2274 } 2275 else { 2276 return false; 2277 } 2278 } 2279 1590 2280 //--------------- 1591 // PRIVATE METHODS 2281 // PRIVATE METHODS 1592 2282 // Create all necessary directories in a path 1593 2283 function MakeDirs($aFile) { 1594 $dirs = array(); 1595 while ( !(file_exists($aFile)) ) { 1596 $dirs[] = $aFile; 1597 $aFile = dirname($aFile); 1598 } 1599 for ($i = sizeof($dirs)-1; $i>=0; $i--) { 1600 if(! @mkdir($dirs[$i],0777) ) 1601 JpGraphError::RaiseL(25118,$aFile);//(" Can't create directory $aFile. Make sure PHP has write permission to this directory."); 1602 // We also specify mode here after we have changed group. 1603 // This is necessary if Apache user doesn't belong the 1604 // default group and hence can't specify group permission 1605 // in the previous mkdir() call 1606 if( CACHE_FILE_GROUP != "" ) { 1607 $res=true; 1608 $res =@chgrp($dirs[$i],CACHE_FILE_GROUP); 1609 $res = @chmod($dirs[$i],0777); 1610 if( !$res ) 1611 JpGraphError::RaiseL(25119,$aFile);//(" Can't set permissions for $aFile. Permission problems?"); 1612 } 1613 } 1614 return true; 1615 } 2284 $dirs = array(); 2285 // In order to better work when open_basedir is enabled 2286 // we do not create directories in the root path 2287 while ( $aFile != '/' && !(file_exists($aFile)) ) { 2288 $dirs[] = $aFile.'/'; 2289 $aFile = dirname($aFile); 2290 } 2291 for ($i = sizeof($dirs)-1; $i>=0; $i--) { 2292 if(! @mkdir($dirs[$i],0777) ) { 2293 JpGraphError::RaiseL(25118,$aFile);//(" Can't create directory $aFile. Make sure PHP has write permission to this directory."); 2294 } 2295 // We also specify mode here after we have changed group. 2296 // This is necessary if Apache user doesn't belong the 2297 // default group and hence can't specify group permission 2298 // in the previous mkdir() call 2299 if( CACHE_FILE_GROUP != "" ) { 2300 $res=true; 2301 $res =@chgrp($dirs[$i],CACHE_FILE_GROUP); 2302 $res = @chmod($dirs[$i],0777); 2303 if( !$res ) { 2304 JpGraphError::RaiseL(25119,$aFile);//(" Can't set permissions for $aFile. Permission problems?"); 2305 } 2306 } 2307 } 2308 return true; 2309 } 1616 2310 } // CLASS Cache 1617 2311 1618 1619 2312 ?> -
trunk/client/modules/Elezioni/grafici/imgdata_balls.inc.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: imgdata_balls.inc.php 860 2007-03-23 19:16:19Z ljp $3 // File: IMGDATA_ROUNDBALLS.INC 4 // Description: Base64 encoded images for small round markers 5 // Created: 2003-03-20 6 // Ver: $Id: imgdata_balls.inc.php 1106 2009-02-22 20:16:35Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 … … 12 12 protected $name = 'Round Balls'; 13 13 protected $an = array(MARK_IMG_LBALL => 'imgdata_large', 14 15 16 14 MARK_IMG_MBALL => 'imgdata_small', 15 MARK_IMG_SBALL => 'imgdata_xsmall', 16 MARK_IMG_BALL => 'imgdata_xsmall'); 17 17 protected $colors,$index,$maxidx; 18 18 private $colors_1 = array('blue','lightblue','brown','darkgreen', 19 19 'green','purple','red','gray','yellow','silver','gray'); 20 20 private $index_1 = array('blue'=>9,'lightblue'=>1,'brown'=>6,'darkgreen'=>7, 21 21 'green'=>8,'purple'=>4,'red'=>0,'gray'=>5,'silver'=>3,'yellow'=>2); 22 22 private $maxidx_1 = 9 ; 23 23 24 24 private $colors_2 = array('blue','bluegreen','brown','cyan', 25 26 27 28 29 25 'darkgray','greengray','gray','green', 26 'greenblue','lightblue','lightred', 27 'purple','red','white','yellow'); 28 29 30 30 private $index_2 = array('blue'=>9,'bluegreen'=>13,'brown'=>8,'cyan'=>12, 31 32 33 34 31 'darkgray'=>5,'greengray'=>6,'gray'=>2,'green'=>10, 32 'greenblue'=>3,'lightblue'=>1,'lightred'=>14, 33 'purple'=>7,'red'=>0,'white'=>11,'yellow'=>4); 34 35 35 private $maxidx_2 = 14 ; 36 36 37 37 38 38 private $colors_3 = array('bluegreen','cyan','darkgray','greengray', 39 40 41 39 'gray','graypurple','green','greenblue','lightblue', 40 'lightred','navy','orange','purple','red','yellow'); 41 42 42 private $index_3 = array('bluegreen'=>1,'cyan'=>11,'darkgray'=>14,'greengray'=>10, 43 44 45 43 'gray'=>3,'graypurple'=>4,'green'=>9,'greenblue'=>7, 44 'lightblue'=>13,'lightred'=>0,'navy'=>2,'orange'=>12, 45 'purple'=>8,'red'=>5,'yellow'=>6); 46 46 private $maxidx_3 = 14 ; 47 47 … … 50 50 51 51 function GetImg($aMark,$aIdx) { 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 52 switch( $aMark ) { 53 case MARK_IMG_SBALL: 54 case MARK_IMG_BALL: 55 $this->colors = $this->colors_3; 56 $this->index = $this->index_3 ; 57 $this->maxidx = $this->maxidx_3 ; 58 break; 59 case MARK_IMG_MBALL: 60 $this->colors = $this->colors_2; 61 $this->index = $this->index_2 ; 62 $this->maxidx = $this->maxidx_2 ; 63 break; 64 default: 65 $this->colors = $this->colors_1; 66 $this->index = $this->index_1 ; 67 $this->maxidx = $this->maxidx_1 ; 68 break; 69 } 70 return parent::GetImg($aMark,$aIdx); 71 71 } 72 72 73 function ImgData_Balls() {74 75 //==========================================================76 // File: bl_red.png77 //==========================================================78 79 $this->imgdata_large[0][1]= 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 //==========================================================111 // File: bl_bluegreen.png112 //==========================================================113 114 $this->imgdata_large[1][1]= 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 //==========================================================154 // File: bl_yellow.png155 //==========================================================156 157 $this->imgdata_large[2][1]= 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 //==========================================================190 // File: bl_silver.png191 //==========================================================192 193 $this->imgdata_large[3][1]= 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 //==========================================================236 // File: bl_purple.png237 //==========================================================238 239 $this->imgdata_large[4][1]= 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 //==========================================================273 // File: bl_gray.png274 //==========================================================275 276 $this->imgdata_large[5][1]= 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 //==========================================================304 // File: bl_brown.png305 //==========================================================306 307 $this->imgdata_large[6][1]= 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 //==========================================================339 // File: bl_darkgreen.png340 //==========================================================341 342 $this->imgdata_large[7][1]= 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 //==========================================================375 // File: bl_green.png376 //==========================================================377 378 $this->imgdata_large[8][1]= 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 //==========================================================421 // File: bl_blue.png422 //==========================================================423 424 $this->imgdata_large[9][1]= 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 //==========================================================459 // File: bs_red.png460 //==========================================================461 462 $this->imgdata_small[0][1]= 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 //==========================================================478 // File: bs_lightblue.png479 //==========================================================480 481 $this->imgdata_small[1][1]= 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 //==========================================================502 // File: bs_gray.png503 //==========================================================504 505 $this->imgdata_small[2][1]= 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 //==========================================================523 // File: bs_greenblue.png524 //==========================================================525 526 $this->imgdata_small[3][1]= 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 //==========================================================543 // File: bs_yellow.png544 //==========================================================545 546 $this->imgdata_small[4][1]= 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 //==========================================================563 // File: bs_darkgray.png564 //==========================================================565 566 $this->imgdata_small[5][1]= 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 //==========================================================587 // File: bs_darkgreen.png588 //==========================================================589 590 $this->imgdata_small[6][1]= 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 //==========================================================611 // File: bs_purple.png612 //==========================================================613 614 $this->imgdata_small[7][1]= 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 //==========================================================630 // File: bs_brown.png631 //==========================================================632 633 $this->imgdata_small[8][1]= 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 //==========================================================655 // File: bs_blue.png656 //==========================================================657 658 $this->imgdata_small[9][1]= 659 660 661 662 663 664 665 666 667 668 669 670 671 672 //==========================================================673 // File: bs_green.png674 //==========================================================675 676 $this->imgdata_small[10][1]= 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 //==========================================================693 // File: bs_white.png694 //==========================================================695 696 $this->imgdata_small[11][1]= 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 //==========================================================713 // File: bs_cyan.png714 //==========================================================715 716 $this->imgdata_small[12][1]= 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 //==========================================================736 // File: bs_bluegreen.png737 //==========================================================738 739 $this->imgdata_small[13][1]= 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 //==========================================================756 // File: bs_lightred.png757 //==========================================================758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 //==========================================================777 // File: bxs_lightred.png778 //==========================================================779 780 $this->imgdata_xsmall[0][1]= 781 782 783 784 785 786 787 788 789 790 791 792 793 794 //==========================================================795 // File: bxs_bluegreen.png796 //==========================================================797 798 $this->imgdata_xsmall[1][1]= 799 800 801 802 803 804 805 806 807 808 809 810 811 //==========================================================812 // File: bxs_navy.png813 //==========================================================814 815 $this->imgdata_xsmall[2][1]= 816 817 818 819 820 821 822 823 824 825 826 827 //==========================================================828 // File: bxs_gray.png829 //==========================================================830 831 $this->imgdata_xsmall[3][1]= 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 //==========================================================848 // File: bxs_graypurple.png849 //==========================================================850 851 $this->imgdata_xsmall[4][1]= 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 //==========================================================869 // File: bxs_red.png870 //==========================================================871 872 $this->imgdata_xsmall[5][1]= 873 874 875 876 877 878 879 880 881 882 883 884 //==========================================================885 // File: bxs_yellow.png886 //==========================================================887 888 $this->imgdata_xsmall[6][1]= 889 890 891 892 893 894 895 896 897 898 899 900 901 902 //==========================================================903 // File: bxs_greenblue.png904 //==========================================================905 906 $this->imgdata_xsmall[7][1]= 907 908 909 910 911 912 913 914 915 916 917 918 919 //==========================================================920 // File: bxs_purple.png921 //==========================================================922 923 $this->imgdata_xsmall[8][1]= 924 925 926 927 928 929 930 931 932 933 934 935 //==========================================================936 // File: bxs_green.png937 //==========================================================938 939 $this->imgdata_xsmall[9][1]= 940 941 942 943 944 945 946 947 948 949 950 951 //==========================================================952 // File: bxs_darkgreen.png953 //==========================================================954 955 $this->imgdata_xsmall[10][1]= 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 //==========================================================974 // File: bxs_cyan.png975 //==========================================================976 977 $this->imgdata_xsmall[11][1]= 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 //==========================================================995 // File: bxs_orange.png996 //==========================================================997 998 $this->imgdata_xsmall[12][1]= 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 //==========================================================1017 // File: bxs_lightblue.png1018 //==========================================================1019 1020 $this->imgdata_xsmall[13][1]= 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 //==========================================================1038 // File: bxs_darkgray.png1039 //==========================================================1040 1041 $this->imgdata_xsmall[14][1]= 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 73 function __construct() { 74 75 //========================================================== 76 // File: bl_red.png 77 //========================================================== 78 $this->imgdata_large[0][0]= 1072 ; 79 $this->imgdata_large[0][1]= 80 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAByF'. 81 'BMVEX/////////xsb/vb3/lIz/hIT/e3v/c3P/c2v/a2v/Y2P/'. 82 'UlL/Skr/SkL/Qjn/MTH/MSn/KSn/ISH/IRj/GBj/GBD/EBD/EA'. 83 'j/CAj/CAD/AAD3QkL3MTH3KSn3KSH3GBj3EBD3CAj3AAD1zMzv'. 84 'QkLvISHvIRjvGBjvEBDvEAjvAADnUlLnSkrnMTnnKSnnIRjnGB'. 85 'DnEBDnCAjnAADec3PeSkreISHeGBjeGBDeEAjWhITWa2vWUlLW'. 86 'SkrWISnWGBjWEBDWEAjWCAjWAADOnp7Oa2vOGCHOGBjOGBDOEB'. 87 'DOCAjOAADJrq7Gt7fGGBjGEBDGCAjGAADEpKS/v7+9QkK9GBC9'. 88 'EBC9CAi9AAC1e3u1a2u1Skq1KSm1EBC1CAi1AACtEBCtCBCtCA'. 89 'itAACngYGlCAilAACghIScOTmcCAicAACYgYGUGAiUCAiUAAiU'. 90 'AACMKSmMEACMAACEa2uEGAiEAAB7GBh7CAB7AABzOTlzGBBzCA'. 91 'BzAABrSkprOTlrGBhrAABjOTljAABaQkJaOTlaCABaAABSKSlS'. 92 'GBhSAABKKSlKGBhKAABCGBhCCABCAAA5CAA5AAAxCAAxAAApCA'. 93 'ApAAAhAAAYAACc9eRyAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgF'. 94 'HUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkRFD'. 95 'UHLytKAAAB4UlEQVR4nGNgIAK4mGjrmNq6BmFIWMmISUpKSmk5'. 96 'B8ZEokj4qoiLiQCBgqald3xaBpKMj6y4sLCQkJCIvIaFV0RaUR'. 97 'lCSk5cWEiAn19ASN7QwisuraihHiajKyEixM/NwckjoKrvEACU'. 98 'qumpg7pAUlREiJdNmZmLT9/cMzwps7Smc3I2WEpGUkxYkJuFiY'. 99 'lTxszePzY1v7Shc2oX2D+K4iLCgjzsrOw8embuYUmZeTVtPVOn'. 100 'gqSslYAOF+Ln4ZHWtXMPTcjMrWno7J82rRgoZWOsqaCgrqaqqm'. 101 'fn5peQmlsK1DR52vRaoFSIs5GRoYG5ub27n19CYm5pdVPnxKnT'. 102 'pjWDpLydnZwcHTz8QxMSEnJLgDL9U6dNnQ6Sio4PDAgICA+PTU'. 103 'zNzSkph8hADIxKS46Pj0tKTc3MLSksqWrtmQySAjuDIT8rKy0r'. 104 'Kz+vtLSmur6jb9JUIJgGdjxDQUVRUVFpaUVNQ1NrZ9+kKVOmTZ'. 105 'k6vR0sldJUAwQNTU2dnX0TgOJTQLrSIYFY2dPW1NbW2TNxwtQp'. 106 'U6ZMmjJt2rRGWNB3TO7vnzh5MsgSoB6gy7sREdY7bRrQEDAGOb'. 107 'wXOQW0TJsOEpwClmxBTTbZ7UDVIPkp7dkYaYqhuLa5trYYUxwL'. 108 'AADzm6uekAAcXAAAAABJRU5ErkJggg==' ; 109 110 //========================================================== 111 // File: bl_bluegreen.png 112 //========================================================== 113 $this->imgdata_large[1][0]= 1368 ; 114 $this->imgdata_large[1][1]= 115 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABm'. 116 'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'. 117 'B3RJTUUH0wMMFi8hE9b2uAAABOVJREFUeNq9lk2sJFUVx3+3qv'. 118 'tW95t57zFvhiFxmCFRUJRoNCQiJARMhiFx/Igxii5goTG6ZDAu'. 119 '/EhcSCIrTAgLEiKsJ8ywABNZEMJXEDYCukAmjgjzBkK/j35V1d'. 120 '333FtV97io97pfzwxfG86qcu/N+Z3zP+fcW/Apmfk4hx57+R/6'. 121 'Rqmc9ykhsWjlsUngAA1fXIQ7b73pI/186IGHnn9dH/8frC8v4I'. 122 'PiG53uaerR4GmKkv31mB8cyfjd946ZTwR66qVX9OTWIi8UKUv9'. 123 'BOrZXpYZvFeiBvzI0fgSUSFKwbVG+Pl1V3HH0VvNR4KeeukV/f'. 124 'PmMmdHhst76aXD64AbeVQ9bjNHaiGOC2o3wLrAb2/4LL/84ffn'. 125 'fCdzkOdayKpLppBemrBsU5Y1Zdmm9LJdGU6E/t4M24Q26jRDRL'. 126 'j3mdc49cSTekFsMzs5XuTsyLDUNSDQ25NwKOly9YIl22MYhJr/'. 127 'uoDtBBoT0CxBRGYOAhibIaOCe//2MpfM6KHnX9cXipSlbkKWmS'. 128 'nk9iv38J0jixw7vJfrTMYBOvhSoQHJBS09ANELloAGDxW8tfoW'. 129 'J+5/UC8CPS0LU7r3SpYarr7M8rmFjMPLXT6/33L4si7Z2GCrQC'. 130 '+0ctlOaNs9DReV8vSLr85ndPLpZ/WNvHW+01kAVFBOGvJx0wYg'. 131 'Sp47RIQ4Emwa8FGJXlDxSCFo5YlVgAo2hwPue/hRndboTV3EW2'. 132 'Wp3k6wBp8q56QiWzecW6vwQfnPRkAWhFgILnq08jQ+R2nlUzzN'. 133 'uES9Q7Vd+9fba7NmWJW61db2247qACmcjxXr45psYphsFGSLBu'. 134 'kIajxqtjNwHkvAjQt0sg3crhPA2+fPz0CuyNFOghsGsr19mnFg'. 135 'DGwrRm8UoAtNmQPQtRXDgdC4HImCFEKcCE0oieUWUYq2LtbiGp'. 136 'mBQmppfIkjw45DK0QNNkvQ0jMBtPL0UnDRM1rN+cxKwzvOo2NP'. 137 'tykR9a1kfpZNDLMG6QDYJqCTBvUe1+uxs+YKyPoGrTwY2HhvC4'. 138 'CDWQd5d4xNApNQEEMgjgLdUCLBQ5cprL/trwNwKG2IUmDqDFd5'. 139 'sr5BWrlxuSdLDFEFlqAzXGc4zFjupqh6uqYihpxJcEgp026l2w'. 140 '7wFUv7Z6AvrfRo/n0OYzPwIKE3HUKAJg2otMBiElnsF7wngis9'. 141 '3ZDjNnLi7huCWUZfueZKTu/M0V3HvmkOFDVxVKDG04ScejSgW5'. 142 'V0q5JYFEghuDLHlTmToqDeGOCKIVtrW9hsdmXufEcNLPSXuPHa'. 143 'a+bvuh9df5AH/v5PDFmbWQC3Mx+TVvfGVTRB2CodNgT2JBX003'. 144 'aANZAYS/BxCv32TV/l2C03G7jgmfjGiT/qmeEmibEYm7XzAO2k'. 145 'A+pbgHhBgydqu54YO5eRiLCy7yDvPP6Xqf+5Z+Lu277OYuOpiw'. 146 'H15oBmlNOMcmK5RbP+PrEscGU+DSAxdg4CICIkxnLP8aNz63Og'. 147 'H3/rdvOb795GVhuaYo0oBc3GGrEsUPVTwO6a7LYd+X51x3Hu/t'. 148 'lP5tS65FN+6okn9U+n/sqb596dTvhOF+02myXTmkQNrOw7yD3H'. 149 'j14E+UDQjp24/0E9/eKrbA4HH3aMK1b2ccvXvswjv//1J/s5ud'. 150 'Due/hRPfP+OmfOrk7vrn7a48ihA3zh8CH+8Iuffiw/n4r9H1ZZ'. 151 '0zz7G56hAAAAAElFTkSuQmCC' ; 152 153 //========================================================== 154 // File: bl_yellow.png 155 //========================================================== 156 $this->imgdata_large[2][0]= 1101 ; 157 $this->imgdata_large[2][1]= 158 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAB2l'. 159 'BMVEX//////////+///+f//9b//8b//73//7X//63//6X//5T/'. 160 '/4z//4T//3P//2v//1r//0r//0L//zH//yn//yH//xj//xD//w'. 161 'j//wD/90L/9zn/9zH/9xj/9xD/9wj/9wD39yn37zn37zH37yH3'. 162 '7xD37wj37wDv70Lv50rv50Lv5znv5yHv5xjv5wjv5wDn51Ln5x'. 163 'Dn3jHn3iHn3hjn3hDn3gje3oze3nPe3lLe1oze1nPe1lLe1ine'. 164 '1iHe1hje1hDe1gje1gDW1qXW1mvWzqXWzkLWzhjWzhDWzgjWzg'. 165 'DOzrXOzq3OzpzOzgDOxkrOxinOxhjOxhDOxgjOxgDGxqXGxnvG'. 166 'xmvGvRjGvRDGvQjGvQDFxbnAvr6/v7+9vaW9vZS9vQi9vQC9tR'. 167 'C9tQi9tQC7u7W1tZS1tXu1tTG1tQi1rRC1rQi1rQCtrYytrSGt'. 168 'rQitrQCtpYStpSGtpQitpQClpYSlpXulpQClnBClnAilnACcnG'. 169 'ucnAicnACclAiclACUlFqUlCmUlAiUlACUjFKUjAiUjACMjFKM'. 170 'jEqMjACMhACEhACEewB7ezF7exB7ewB7cwBzcylzcwBzaxBzaw'. 171 'BraxhrawhrawBrYxBrYwBjYwBjWgBaWgBaUgCXBwRMAAAAAXRS'. 172 'TlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAd'. 173 'LdfvwAAAAHdElNRQfTAwkRFBKiJZ4hAAAB7ElEQVR4nI3S+1vS'. 174 'UBgHcB67WJmIMWAVdDHEDLBC6Go0slj3Ft0m9RRBWQEmFZFDEM'. 175 'Qgt0EMFBY7p/+198hj1kM/9N1+++x73rOd6XT/kStnTx4fPzd9'. 176 'uwfOjFhomj7smAhwj/6Cm2O0xUwy6g7cCL99uCW3jtBmE7lsdr'. 177 'fvejgpzP7uEDFRRoqy2k8xQPnypo2BUMP6waF9Vpf3ciiSzErL'. 178 'XTkPc0zDe3bsHDAcc00yoVgqL3UWN2iENpspff+2vn6D0+NnZ9'. 179 '6lC5K6RuSqBTZn1O/a3rd7v/MSez+WyIpVFX8GuuCA9SjD4N6B'. 180 'oRNTfo5PCAVR0fBXoIuOQzab1XjwwNHx00GOj8/nKtV1DdeArk'. 181 '24R+0ul9PjmbrHPYl+EipyU0OoQSjg8/m83kl/MMhx0fjCkqio'. 182 'SMOE7t4JMAzDsizH81AqSdW2hroLPg4/CEF4PhKNx98vlevrbY'. 183 'QQXgV6kXwVfjkTiSXmhYVcSa7DIE1DOENe7GM6lUym0l+EXKks'. 184 'K20VAeH2M0JvVgrZfL5Qqkiy0lRVaMBd7H7EZUmsiJJcrTdVja'. 185 'wGpdbTLj3/3qwrUOjAfGgg4LnNA5tdQx14Hm00QFBm65hfNzAm'. 186 '+yIFhFtzuj+z2MI/MQn6Uez5pz4Ua41G7VumB/6RX4zMr1TKBr'. 187 'SXAAAAAElFTkSuQmCC' ; 188 189 //========================================================== 190 // File: bl_silver.png 191 //========================================================== 192 $this->imgdata_large[3][0]= 1481 ; 193 $this->imgdata_large[3][1]= 194 'iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAADAF'. 195 'BMVEUAAADOzs7Gxsa9vb21tbXOxsbOzsbGzsb3///O1ta1vb2c'. 196 'paVSWlpKWlpSY2ve5+97hIze7/9aY2vO5/9zhJRaa3tSY3PGzt'. 197 'aMlJxrc3tja3NKUlpCSlK1vcZze4RSWmPW5/+Upb3G3v9zhJxS'. 198 'Y3t7jKVaa4TO3veltc6ElK1re5Rjc4ycpbV7hJRaY3M5QlLn7/'. 199 '/Gzt6lrb2EjJzO3v9ja3vG1ve9zu+1xueltdacrc6UpcaMnL1C'. 200 'SlqElLV7jK1zhKVre5zW3u/O1ue1vc6ttcaMlKVze4xrc4RSWm'. 201 'tKUmPG1v+9zve1xu+tveeltd6crdbe5/+9xt6cpb17hJxaY3s5'. 202 'QlrW3vfO1u/Gzue1vdattc6lrcaUnLWMlK2EjKVze5Rrc4xja4'. 203 'RSWnNKUmtCSmO9xuecpcZ7hKVaY4TW3v/O1vfGzu+1vd6ttdal'. 204 'rc69xu+UnL2MlLWEjK1ze5xrc5R7hK1ja4zO1v+1veettd6lrd'. 205 'aMlL3Gzv/39//W1t7Gxs61tb29vcatrbWlpa2cnKWUlJyEhIx7'. 206 'e4TW1ufGxta1tcZSUlqcnK3W1u+UlKW9vda1tc57e4ytrcalpb'. 207 '1ra3vOzu9jY3OUlK29vd6MjKWEhJxaWmtSUmNzc4xKSlpjY3tK'. 208 'SmNCQlqUjJzOxs7///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'. 209 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'. 210 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'. 211 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'. 212 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'. 213 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'. 214 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'. 215 'AAAAAAAAAAAAAAAAAAAAAAAAD///9fnkWVAAAAAnRSTlP/AOW3'. 216 'MEoAAAABYktHRP+lB/LFAAAACXBIWXMAAABFAAAARQBP+QatAA'. 217 'AB/klEQVR42mNgxAsYqCdd3+lcb4hLmj8wMMvEu8DCMqYbU9op'. 218 'UEFB2MTb26eyysomFl06XEEhUCHLpAKo2z/fujikEUVaXUFBMB'. 219 'BouLePuV+VVWGRciIXknSEsImCQd3//xwmPr65llaFcSFJHkjS'. 220 '3iYmWUDZ//8NfCr989NjNUMSUyTg0jneSiaCINn/gmlVQM12qg'. 221 'lJnp5waTMTE5NAkCyHWZW/lXWNfUlikmdYK0zax7siS4EDKJtd'. 222 'mQeU1XRwLBdLkRGASucWmGVnZ4dnhZvn5lmm29iVOWpnJqcuko'. 223 'JKR1Wm5eTkRKYF5eblp9sU2ZeUJiV7zbfVg0pH56UFBQXNjIqK'. 224 'jgkujItX1koKTVmYajsdKu2qETVhwgSXiUDZ2Bn9xqUeoZ5e0t'. 225 'LzYYZ3B092ndjtOnmKTmycW1s7SHa+l5dtB8zlccE6RlN0dGbM'. 226 'mDVbd5KupNBcL6+F82XgHouLj5vRP2PWLGNdd4+ppnxe8tJec6'. 227 'XnNsKkm0uVQ5RDRHQTPTym68nPlZbvkfYCexsa5rpJ2qXa5Umm'. 228 'ocmec3m8vHjmSs+fgxyhC5JDQ8WSPT2lvbzm8vDIe0nbtiBLN8'. 229 '8BigNdu1B6Lsje+fPbUFMLi5TMfGmvHi/puUAv23q2YCTFNqH5'. 230 'MvPnSwPh3HasCbm3XUpv+nS5VtrkEkwAANSTpGHdye9PAAAASn'. 231 'RFWHRzaWduYXR1cmUANGJkODkyYmE4MWZhNTk4MTIyNDJjNjUx'. 232 'NzZhY2UxMDAzOGFhZjdhZWIyNzliNTM2ZGFmZDlkM2RiNDU3Zm'. 233 'NlNT9CliMAAAAASUVORK5CYII=' ; 234 235 //========================================================== 236 // File: bl_purple.png 237 //========================================================== 238 $this->imgdata_large[4][0]= 1149 ; 239 $this->imgdata_large[4][1]= 240 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAACAV'. 241 'BMVEX/////////7///5///1v//xv//rf//pf//lP//jP//hP//'. 242 'c///a///Wv//Wvf/Uv//Sv//Qv//Qvf/Off/Mf//Kf//If//If'. 243 'f/GP//GPf/EP//EPf/CP//CPf/CO//AP//APf3Oe/3Kff3Ke/3'. 244 'Ie/3GO/3EO/3AO/vSu/vSufvOefvMefvIefvGOfvEOfvCOfvAO'. 245 'fnUufnSufnMd7nId7nGN7nGNbnEN7nCN7nAN7ejN7ejNbec97e'. 246 'c9beUtbeQtbeIdbeGNbeENbeCNbeANbWpdbWa9bWQs7WGM7WEM'. 247 '7WCM7WAM7Otc7Orc7OnM7OSsbOIb3OGMbOEMbOCMbOAM7OAMbG'. 248 'pcbGnMbGe8bGa8bGKbXGEL3GCL3GAL3FucXBu73AvsC/v7+9pb'. 249 '29Ka29GLW9ELW9CLW9AL29ALW5rrm1lLW1e7W1MbW1GKW1EK21'. 250 'CLW1CK21AK2tjK2thKWtMaWtIaWtGJytCK2tCKWtAK2tAKWlhK'. 251 'Wle6WlEJylCJylAKWlAJyca5ycGJScEJScCJScAJycAJSUWpSU'. 252 'UoyUKZSUEIyUCIyUAJSUAIyMUoyMSoyMIYSMEISMCISMAIyMAI'. 253 'SECHuEAISEAHt7MXt7EHt7CHt7AHt7AHNzKXNzEGtzAHNzAGtr'. 254 'GGtrEGNrCGtrAGtrAGNjCFpjAGNjAFpaAFpaAFIpZn4bAAAAAX'. 255 'RSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsS'. 256 'AdLdfvwAAAAHdElNRQfTAwkRFB0ymoOwAAAB9UlEQVR4nGNgIA'. 257 'K42hhqGtm5+WFIWClKycvLK6gbuARGoEj4aMjLSElISUir6Tt7'. 258 'x+aEIWR8leQlwEBSTc/CK7awLguuR0lGQkJMVFRUTFJVzwko1d'. 259 'oFk9OQl5IQE+Dh5hVR0TV3CkkvbJgyASJjDZIR5GBl5eRX0TH1'. 260 'DEqrbJ2ypBEspSgvJSXKw8bMxMavbOLoGZNf1TZlybw4oIyfLN'. 261 'BxotxsLEzsQiaOHkFpBQ2905esrAZK2SpIAaUEuDm5+LTNPAKj'. 262 'C+pbps1evrIDKGWnLictKSkuLKyoZQyUya9o7Z2+YMXKGUApew'. 263 'M9PTVdXR0TEwf3wOjUirruafOXL18xFyjl72Kpb25qaurg4REU'. 264 'EFVe2zJ5zpLlK1aCpbydnZ2dnDwDA6NTopLLeiZNXbB8BcTAyP'. 265 'TQ0JDg4KCY1NS83JKmiVOBepYvX9UPlAovzEiPSU/LLyior2vq'. 266 'mjZr3vLlIF01IC+XVhUWFlZW1Lc290ycOGfxohVATSsXx4Oksn'. 267 'vaWlsb2tq6J0+bM2/RohVA81asbIcEYueU3t7JU6ZNnwNyGkhm'. 268 '+cp5CRCppJnzZ8+ZM3/JUogECBbBIixr8Yqly8FCy8F6ltUgoj'. 269 'lz7sqVK2ByK+cVMSCDxoUrwWDVysXt8WhJKqG4Y8bcuTP6qrGk'. 270 'QwwAABiMu7T4HMi4AAAAAElFTkSuQmCC' ; 271 272 //========================================================== 273 // File: bl_gray.png 274 //========================================================== 275 $this->imgdata_large[5][0]= 905 ; 276 $this->imgdata_large[5][1]= 277 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAABO1'. 278 'BMVEX////////3///39/fv7+/e5+fW3t7Wzs7WxsbG1tbGzsbG'. 279 'xsbDxMS/v7++wMC+v7+9zsa9xsa9vb29tbW9ra29pa24uLi1xs'. 280 'a1vb21tbWxtrattbWmpqalra2cra2cpaWcnJycjIyUpaWUnJyU'. 281 'lJSUjIyMnJyMnJSMlJSMlIyMjJSMjIyElJSElIyEjIyEhIR7jI'. 282 'x7hIR7hHt7e3t7e3N7e2tzhIRze3tze3Nzc3Nre3trc3Nrc2tr'. 283 'a2tjc3Njc2tja3Nja2tjY2NjWlpaa2taY2taY2NaY1paWlpaUl'. 284 'JSY2NSY1pSWlpSWlJSUlJSUkpKWlpKWlJKUlpKUlJKUkpKSkpK'. 285 'SkJCUlJCUkJCSkpCSkJCQkI5Sko5QkI5Qjk5OUI5OTkxQkIxOT'. 286 'kxMTkxMTEpMTEhMTEhKSkYISEpy7AFAAAAAXRSTlMAQObYZgAA'. 287 'AAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdE'. 288 'lNRQfTAwkRFQfW40uLAAABx0lEQVR4nI3SbXfSMBQA4NV3nce5'. 289 'TecAHUywRMHSgFuBCFsQUqwBS1OsWQh0GTj//y8wZUzdwQ/efM'. 290 'tzcm/uuXdj4z9ic/PR9k4qk1qDnf0X2/uZzKt8GaRvSubg4LVp'. 291 'mkWzCGAT/i3Zsm2XNQHLsm2n2937LaaNnGoJFAEo27B50qN0ay'. 292 'Wg26lXsw8fP8nmzcJb2CbsnF5JmmCE8ncN404KvLfsYwd7/MdV'. 293 'Pdgl/VbKMIzbuwVgVZw2JlSKJTVJ3609vWUY957lgAUd1KNcqr'. 294 'yWnOcOPn8q7d5/8PywAqsOOiVDrn42NFk+HQ7dVuXNYeFdBTpN'. 295 'nY5JdZl8xI5Y+HXYaTVqEDp1hAnRohZM03EUjMdhn5wghOoNnD'. 296 'wSK7KiiDPqEtz+iD4ctdyAifNYzUnScBSxwPd6GLfRURW7Ay5i'. 297 'pS5bmrY8348C5vvUI+TLiIVSJrVA0heK/GDkJxYMRoyfCSmk4s'. 298 'uWc3yic/oBo4yF374LGQs5Xw0GyQljI8bYmEsxVUoKxa6HMpAT'. 299 'vgyhU2mR8uU1pXmsa8ezqb6U4mwWF/5MeY8uLtQ0nmmQ8UWYvb'. 300 'EcJaYWar7QhztrO5Wr4Q4hDbAG/4hfTAF2iCiWrCEAAAAASUVO'. 301 'RK5CYII=' ; 302 303 //========================================================== 304 // File: bl_brown.png 305 //========================================================== 306 $this->imgdata_large[6][0]= 1053 ; 307 $this->imgdata_large[6][1]= 308 'iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAABoV'. 309 'BMVEX////Gzs7GvbXGrZTGpXu9nHO1nHO1nIy9taXGxs7GtaXO'. 310 'nHPGlFrGjEq9hEq1hEqte0Klczmcazmce1KtnIzGxsbGvb3OlF'. 311 'LOlFq9hFKte0qcc0KUYzGEWimMc1K9ta3OnGvOnGPWnGO9jFq9'. 312 'jFKlc0KUazmMYzl7UilzUjGtpZzGxr3GnGPWpWvepXO1hFJ7Wj'. 313 'FrSiFjUjG1ra3GnHPvxpT/5733zpythFKUa0KEYzlzUilaOSF7'. 314 'Wjm9jErvvYz/99b///f/78bnrYS1hFqle0p7UjFrSiljQiFCMR'. 315 'iMhHO9lGvGjFLWnGv/3q3////erXuthEqlc0paQiFKMRhSQin/'. 316 '1qX/997//++cc0pjSilaQilKORhCKRiclIy9pYzGlGPntYT33q'. 317 '3vvZSEWjlSOSE5KRB7c2O1lHutczmthFqte1JrWkqtjGtCKRBa'. 318 'SjmljGuca0KMYzGMaznOztaclISUYzmEWjFKOSF7a1qEYzFaSi'. 319 'GUjISEa0pKOSm9vb2llIxaQhg5IQiEc2tzY0paORilnJy1raVS'. 320 'OSljUkJjWkKTpvQWAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHU'. 321 'gAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkREiei'. 322 'zP2EAAAB9UlEQVR4nGWS/VfSUBjHL5QluhhBxtwyWcCus5Blpm'. 323 'wDC4ONaWXCyBi7RMZmpQ2Bypm9W/byV3cHHo/W88s95/s5z/d5'. 324 'uwCcCh/4L3zAf+bs0NC588On9QAYGSUuBINk6GI4cmnsBLk8Go'. 325 '1SFEGMkzRzZeLq5JE8FvDHouw1lqXiCZJOcnCKnx4AcP0GBqmZ'. 326 'mRgRT9MMB4Wbs7cGSXNRik3dnp9fiMUzNCNKgpzN9bsaWaQo9s'. 327 '7dfH7pXiFTZCBU1JK27LmtBO8TDx7mV1eXHqXXyiIUFLWiVzHx'. 328 'BxcJIvV4/cn6wkqmWOOwmVE3UQOAp6HxRKL5bGPj+VwhUhalFq'. 329 '8alm5vAt+LlySZTsebzcKrraIIW4JqZC3N3ga+1+EQTZKZta1M'. 330 'pCZCSeDViqVrThsEdsLJZLJYLpZrHVGScrKBvTQNtQHY6XIM02'. 331 'E6Ik7odRW1Dzy3N28n3kGuB3tQagm7UMBFXI/sATAs7L5vdbEs'. 332 '8Lycm923NB0j5wMe6KOsKIIyxcuqauxbrmlqyEWfPmPy5assY1'. 333 'U1SvWKZWom9nK/HfQ3+v2HYZSMStayTNN0PYKqg11P1nWsWq7u'. 334 '4gJeY8g9PLrddNXRdW8Iryv86I3ja/9s26gvukhDdvUQnIjlKr'. 335 'IdZCNH+3Xw779qbG63f//ZOzb6C4+ofdbzERrSAAAAAElFTkSu'. 336 'QmCC' ; 337 338 //========================================================== 339 // File: bl_darkgreen.png 340 //========================================================== 341 $this->imgdata_large[7][0]= 1113 ; 342 $this->imgdata_large[7][1]= 343 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAB2l'. 344 'BMVEX////////3///v///n/+/e99bW/+/W99bO786/v7++vr69'. 345 '/96999a7wb24vbu1/9a1zqW1u7itxrWosq6l772l1qWlxrWlxq'. 346 '2lva2cxpSU562U3q2UxqWUvaWUpZyM77WM57WMvYyMtZyMrZyM'. 347 'pZSMnJSEvZyEtYyErZSElIx7zpR7xpx7xpR7vZR7jIRz1pRzxp'. 348 'RzjIRrzpRrzoxrxoxrtYRrrYxrrXtrpYRrhHNjzoxjxoxjxoRj'. 349 'vYRjtYRjrXtjpXtjlGNje2tazoxazoRaxoxaxoRavYRatYRatX'. 350 'tarXtapXNanHNajFpae2tSzoRSxoRSvXtStXtSrXtSrXNSpXNS'. 351 'nHNSnGtSlGtSlGNSjGtSjGNKvXtKtXNKrXNKpWtKnGtKlGNKjG'. 352 'NKhGNKhFJKc1pKa1JCrWtCpWtCnGtClGNCjGNCjFpChFpCe1JC'. 353 'a1JCY1I5pWs5nGM5lGM5jFo5hFo5e1o5c0o5WkoxjFoxhFoxhF'. 354 'Ixe1Ixc1Ixc0oxa0ophFIpe0opc0opa0opa0IpY0IpWkIpWjkp'. 355 'UkIpUjkhc0oha0IhY0IhWjkhWjEhUjkhUjEhSjEhSikhQjEhQi'. 356 'kYWjkYSjEYSikYQjEYQikQSikQQikQQiEQOSExf8saAAAAAXRS'. 357 'TlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAd'. 358 'LdfvwAAAAHdElNRQfTAwkRFCaDkWqUAAAB+ElEQVR4nI3S+1vS'. 359 'UBgHcGZlPV0ks/vFrmQWFimJjiwiYUJWjFBWFhClyZCy5hLrwA'. 360 'x2EIwJC1w7zf2vnU0re+iHvs9++7x7zznvORbLf+TA6ct9fYMX'. 361 'jrfAUYefpp+/iM1ykxf/lmuhUZ/PTwXC8dml5Wcd23o5H5Mk6b'. 362 '5NUU8icXbhS67rNzn9JDnguOEYGQtEEtwC+Crs3RJ76P5A/znr'. 363 'vsNX7wQnEiwHCtK7TTkW8rvdZ9uJtvZTLkxpHhSrP66bNEj7/P'. 364 '3WNoLYeeSWQQCIpe9lQw7RNEU5rDsIYtcJ14Nocg7kRUlBNkxn'. 365 'YmGKcp7cv3vPwR7XOJPmc0VYU3Sv0e9NOBAYG7Hbz/cMjTMveZ'. 366 'CHkqxuTBv0PhYJB4N3XR6PJ5rMAPMnpGUxDX1IxSeMTEaZp1OZ'. 367 'nGAIQiYtsalUIhFlmGTy3sO3AizJCKn6DKYryxzHsWyaneMzr6'. 368 'cWxRVZVlFTe4SpE3zm+U/4+whyiwJcWVMQNr3XONirVWAklxcE'. 369 'EdbqchPhjhVzGpeqhUKhWBQhLElr9fo3pDaQPrw5xOl1CGG1JE'. 370 'k1uYEBIVkrb02+o6RItfq6rBhbw/tuINT96766KhuqYpY3UFPF'. 371 'BbY/19yZ1XF1U0UNBa9T7rZsz80K0jWk6bpWGW55UzbvTHZ+3t'. 372 'vbAv/IT+K1uCmhIrKJAAAAAElFTkSuQmCC' ; 373 374 //========================================================== 375 // File: bl_green.png 376 //========================================================== 377 $this->imgdata_large[8][0]= 1484 ; 378 $this->imgdata_large[8][1]= 379 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABm'. 380 'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'. 381 'B3RJTUUH0wMMFjM4kcoDJQAABVlJREFUeNq9ll2MJFUVx3/11V'. 382 'Vd/TE9vU0v4zLDwJIF16jBqLAPhsRXEiDqg0QTJiQSjcSNvCzw'. 383 'sBEDDxizhvAAxBgf1oR9QF9NiE9ESFZkQyZB5WtddmdnZ3qqqr'. 384 'uqbt367Cofqu3ZZpWVaDzJfbkf53//55z/PVdZXV3l/2H6f7Lp'. 385 '5VdOV/4Nb+GmHpUeA7AdBNxc3kafNb73jRPK9Xwon8ToxVefqU'. 386 'b91wibH5EkCQBCizFihTSviHUHR0hWws9xe3wvJ7/7nPKpgX5y'. 387 '9oFqt3eOgWniRBoAbUBGGqZUibSYaeoT2B5bnkdaSA6793Cv/S'. 388 'QPPbihXBfo5VdOV+8dfgnvwAU62YH5fCZ12sDujFkwyegCqTrB'. 389 'iUOKTOJKj8jr88jS8zy6cXwBTP048nuHX0I0nDlIp7RpTG7kM0'. 390 'sdyAYsTVukUuWGhlWHMq0ITL92lnUp9R1Obz/GmTNnqn9bDD8/'. 391 '+0D1oX0O0zQZZDYCsK2j3Gl9jQqDfHiei8GfiKVLlsZkJaBAN1'. 392 '0i6PgwUbB0GxG5/PrtE/xLRr959Znqw9452oVNI+jiJhnr1pe4'. 393 'k29zB1/nFr5Kj7tpt1YYhJ0FJ7nUYbcJQBgahN2MzeCP/OipR6'. 394 'prgN6Qr6ELFQFUWoRpNVjlKwxZB8DCpE+PtfEKqV1cUzxpVudu'. 395 'GTBHA5Y1g99e+dUio9O/P1Vpq+/WE5GGjDSMoAtAQjrf3C52IP'. 396 'QxpY4WK2hpReka9Gfrhqgz0bACRoCWjDh56kQ1z9FeuUUQxVhK'. 397 'B92sD1VahM+bAJgcoJhGjP/6Ln8rAgDiRCVRKiIzxMkkodBJ85'. 398 'im1IlEHbE4k1xyNveL4YP8HarmGJIOpqyjeQmfNHmTvnqZTWBt'. 399 'vIJXpPwlukJSuSTKGK3pEwtJmiX00ZlInTyNscImO6XBITvH1c'. 400 '8vVt2OucdKvIyeKRTNCivsEMgcpg6taYs30nfq0Gqg6hOSSFJ4'. 401 'BSnJPht0IqEjWmOGocEI6F0J94F0qaL6BntTF0MtUfweKQKAPU'. 402 'Wwp4OcVnQAmVb0p9DLOzjEhEKnGRmoRc7EzRGlwA6NujAKG4yP'. 403 '6Sjwc4aVznZ7DK0xXdkDoJf0kGmFBniFBOBGcZSCCSKd0IwN0k'. 404 'IS+QZWCGVZex4BnUxya3+Zt9iugQbcRFpIAtuHvAZulPUdLhUJ'. 405 'RqegI3WcqaSXddlT3idsWMSRRGkEtNwmyTifAwyBo7LP+11J0e'. 406 '7tM7pZOYblHkBLcqZ5LcYtw6Wbd4CM3SpE9foYZsIHoqDKCrbz'. 407 'mLSQtPwmuhXgtBLs0GBdbXOhFGB7WBKO2F8GXt9/VO97Ya3atF'. 408 '7nUHnwGjGGQqcPxFEdFqURkEidiZszAERoYIsGju1hq21kWee3'. 409 'bw15+8WpsvAy3K1+i3JkkhZyPpxxjjPOsfOYiZ+TFhLPzQnHOU'. 410 'tpzGB2dgA4tscIkKIx19Cxg/fPL7vQJu47eXt1VvsDK8pwPueZ'. 411 'PuZoQMOqhRoJHSs0kKLBWjvjYinmeQGw1TaX1RFdfZ3LMzYLjA'. 412 'C++dkn6AaH2Nobk6cxEzdnuG0TdC8zvdJkN0hqkFkO/jwL0fxa'. 413 'so8sBcuFzQ+/+MRC+BeAHnpwQzn++ee5KT9Eshuy46dcKAXm32'. 414 '0uzPQhS4GttkH2GQID2Wc0Y4LtAbDxhZ/x5A+e/uTG9+jGceXH'. 415 '9/ySnnIXnUzOxXe1038mW3ZynNmam4yYWkO+f9cv+Oljz16/lV'. 416 '9tDz/9nerc1hm8ZEScSRK7VvtYl1i1dklsOKyvc+zg/bzw1O8+'. 417 '/efkajt56kR1ydlEJBc5H46xzbrJ3dY9wrB7hGcff+6/+279L+'. 418 '0fHxyiE8XMLl4AAAAASUVORK5CYII=' ; 419 420 //========================================================== 421 // File: bl_blue.png 422 //========================================================== 423 $this->imgdata_large[9][0]= 1169 ; 424 $this->imgdata_large[9][1]= 425 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAACEF'. 426 'BMVEX/////////7//35//v1v/exv/Wvf/Wrf/Wpf/Orf+/v7+9'. 427 'tc69jP+9hP+5ucW1tc6tlP+rq7Wlpdalpcalpb2cnM6cnMacc/'. 428 '+cWv+UlLWUjN6UjK2Uc/+Ma/+MUv+EhKWEa/+EQvd7e8Z7e7V7'. 429 'e6V7c957Wv9za9Zza8ZzSv9ra5xrSv9rOf9rMe9jUudjQv9jOe'. 430 '9aWpRaUt5aUpRaSu9aSudSUoxSSs5SSoxSMf9KQtZKOfdKMedK'. 431 'Kf9KKe9CKf9CKb1CKa1CIfdCIedCId45MXs5Kfc5If85Iec5Id'. 432 'Y5GP8xMbUxMXsxKc4xKZQxIf8xGP8xGO8xGN4xGNYxGL0xGK0p'. 433 'KXMpIYwpGP8pGO8pGOcpGNYpGM4pEP8pEPcpEOcpEN4pENYpEM'. 434 'YpEL0hGKUhEP8hEPchEO8hEOchEN4hENYhEM4hEMYhELUhCP8h'. 435 'CO8hCN4YGJwYGGsYEL0YEK0YEHMYCN4YCM4YCMYYCL0YCKUYAP'. 436 '8QEJQQEIwQEHsQEGsQCM4QCLUQCK0QCKUQCJwQCJQQCIwQCHMQ'. 437 'CGsQAP8QAPcQAO8QAOcQAN4QANYQAM4QAMYQAL0QALUQAKUQAJ'. 438 'QQAIQICGsICGMIAO8IANYIAL0IALUIAK0IAKUIAJwIAJQIAIwI'. 439 'AIQIAHsIAHMIAGsIAGMAAN4AAMYAAK0AAJQAAIwAAIQAAHMAAG'. 440 'sAAGMAAFrR1dDlAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgA'. 441 'AAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkRFRPMOZ'. 442 '/2AAAB+klEQVR4nGNgIAIIqeqZmBqpi2JISNml5lVXV3d198Yo'. 443 'oUjwm1SnxsbGRsSm5ZfNXO4tjCTjVh0ABhFx6QV9E1Y0S8JkuN'. 444 '3yAgLc7W3t/QPi4jPKJ8ye1yoIlTKpjvVy15eVUbN0i4zKLJ8w'. 445 'ae6qcKgLqmMj3PUFWFl5NJ0CExLLJzbNW7BWCyxlXR0ba6/Axs'. 446 'zELmfnkRBT0QiSKgXJCOflxUbYy3KyMHEoOrtEZ1c2TZ6/cMl6'. 447 'eaCUamdsbIC7tjgPr4SBS3BMMVDTwkXr1hsDpYy6UmMj/O0tdX'. 448 'QNbDxjknJLWqYsXLx0vStQynxGflpkZGCgs7Onp29SbtNkoMy6'. 449 'pevCgFJWy3oyMuKjgoKCPWNCvEuqWhcsWrJ06XqQlPnMvrKyrM'. 450 'TomJjkZAfHlNa2qdOWrlu63gcopbG8v7+hvLwip7g4JdSxsLZu'. 451 '8dKlS9ettwBKic2eNXHChIkTG5tKqgpr2uo6loLAehWQx0LnzJ'. 452 '49p6mpeXLLlNq6RUvqly6dvnR9Bx9ISnnlvLmT582bMr9t4aL2'. 453 '+vrp60GaDCGB6Ld6wfwFCxYCJZYsXQ+SmL6+FBryInVrFi1atH'. 454 'jJkqVQsH6pNCzCJNvXrQW6CmQJREYFEc2CYevXrwMLAyXXl0oz'. 455 'IAOt0vVQUGSIkabkDV3DwlzNVDAksAAAfUbNQRCwr88AAAAASU'. 456 'VORK5CYII=' ; 457 458 //========================================================== 459 // File: bs_red.png 460 //========================================================== 461 $this->imgdata_small[0][0]= 437 ; 462 $this->imgdata_small[0][1]= 463 'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAk1'. 464 'BMVEX////////GxsbGra3/xsbOhITWhIT/hIT/e3v/c3P/a2vG'. 465 'UlK1SkrOUlL/Y2PWUlLGSkrnUlLeSkrnSkr/SkqEGBj/KSmlGB'. 466 'jeGBjvGBj3GBj/EBD/CAj/AAD3AADvAADnAADeAADWAADOAADG'. 467 'AAC9AAC1AACtAAClAACcAACUAACMAACEAAB7AABzAABrAABjAA'. 468 'BuukXBAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZ'. 469 'cwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkUGDNEMgOYAAAAm0'. 470 'lEQVR4nI3Q3RKCIBAFYGZMy9RKzX7MVUAUlQTe/+kS0K49d3wD'. 471 '7JlFaG+CvIR3FvzPXgpLatxevVVS+Jzv0BDGk/UJwOkQ1ph2g/'. 472 'Ct5ACX4wNT1o/zzUoJUFUGBiGfVnDTYGJgmrWy8iKEtp0Bpd2d'. 473 'jLGu56MB7f4JOOfDJAwoNwslk/jOUi+Jts6RVNrC1hkhPy50Ef'. 474 'u79/ADQMQSGQ8bBywAAAAASUVORK5CYII=' ; 475 476 477 //========================================================== 478 // File: bs_lightblue.png 479 //========================================================== 480 $this->imgdata_small[1][0]= 657 ; 481 $this->imgdata_small[1][1]= 482 'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAABVl'. 483 'BMVEX////////d///AwMC7wcS08P+y+P+xxdCwxM+uws2twMur'. 484 'vsinzNynytylzuKhyN6e5v6d5P+d1fOcwNWcu8ub4f+at8iZ3v'. 485 '+ZvdGY2/yW2f+VscGU1vuT1fqTr72Sx+SSxeKR0fWRz/GPz/OP'. 486 'rr+OyeqMy+6Myu2LyeyKxueJudSGw+SGorGDvt+Cvd6CvN2Aud'. 487 'p+uNd+t9Z9tdV8tdR8tNN6sc94r813rct2q8h0qcZ0qMVzp8Rx'. 488 'o8Bwor5tn7ptnrptnrlsnbhqmbRpmbNpi51ol7Flkqtkkqtkka'. 489 'pjj6hijaRhjaZgi6NfiqJfiaFdh55bhJtag5pZgphYgJZYf5VX'. 490 'cn9Ve5FSeI1RdopRdYlQdYlPc4dPcoZPcoVNcINLboBLbH9GZn'. 491 'hGZXdFZHZEY3RDYnJCXW4/W2s/WWg+Wmo7VmU7VGM7U2E6VGM6'. 492 'VGI5UV82T1wGxheQAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHU'. 493 'gAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkUGTok'. 494 '9Yp9AAAAtElEQVR4nGNgIBaw8wkpKghzwvksPAKiUsraprYiLF'. 495 'ARXkE2JiZ1PXMHXzGIAIekOFBE08TGLTCOCyzCLyvDxsZqZOnk'. 496 'E56kAhaRV9NQUjW2tPcMjs9wBYsY6Oobmlk7egRGpxZmgkW0zC'. 497 '2s7Jy9giKT8gohaiQcnVzc/UNjkrMLCyHmcHr7BYREJKTlFxbm'. 498 'QOxiEIuKTUzJKgQCaZibpdOzQfwCOZibGRi4dcJyw3S4iQ4HAL'. 499 'qvIlIAMH7YAAAAAElFTkSuQmCC' ; 500 501 //========================================================== 502 // File: bs_gray.png 503 //========================================================== 504 $this->imgdata_small[2][0]= 550 ; 505 $this->imgdata_small[2][1]= 506 'iVBORw0KGgoAAAANSUhEUgAAABEAAAAQCAMAAADH72RtAAABI1'. 507 'BMVEX///8AAAD8EAD8IAD8NAD8RAD8VAAYGBi/v7+goKCCgoJk'. 508 'ZGRGRkb8yAD83AD87AD8/AD4+ADo+ADY+ADI+AC0+ACk+ACU+A'. 509 'CE+AB0/ABk/ABU/ABE/AAw/AAg/AAQ/AAA/AAA+AAA6BAA2CAA'. 510 'yDQAtEQApFQAlGQAhHQAdIgAZJgAVKgARLgAMMgAINwAEOwAAP'. 511 'wAAPgIAPAQAOgYAOAkANgsANA0AMg8AMBEALhMALBUAKhcAKBo'. 512 'AJhwAJB4AIiAAID////4+Pjy8vLs7Ozm5ubg4ODa2trT09PNzc'. 513 '3Hx8fBwcG7u7u1tbWurq6oqKiioqKcnJyWlpaQkJCJiYmDg4N9'. 514 'fX13d3dxcXFra2tkZGReXl5YWFhSUlJMTExGRkZAQEA1BLn4AA'. 515 'AAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIA'. 516 'AAsSAdLdfvwAAAAHdElNRQfTAwkUGiIctEHoAAAAfElEQVR4nI'. 517 '2N2xKDIAwF+bZ2kAa8cNFosBD//yvKWGh9dN+yk9kjxH28R7ze'. 518 'wzBOYSX6CaNB927Z9qZ66KTSNmBM7UU9Hx2c5qjmJaWCaV5j4t'. 519 'o1ANr40sn5a+x4biElrqHgrXMeac/c1nEpFHG0LSFoo/jO/BeF'. 520 'lJnFbT58ayUf0BpA8wAAAABJRU5ErkJggg==' ; 521 522 //========================================================== 523 // File: bs_greenblue.png 524 //========================================================== 525 $this->imgdata_small[3][0]= 503 ; 526 $this->imgdata_small[3][1]= 527 'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAxl'. 528 'BMVEX///////+/v79znJQhSkJ7raU5hHtjraVKnJRCjIRClIyU'. 529 '9++E595avbVaxr2/v7+ctbWcvb17nJxrjIx7paUxQkK9//+Mvb'. 530 '17ra2Evb17tbVCY2MQGBiU5+ec9/eM5+d71tZanJxjra1rvb1j'. 531 'tbVSnJxara1rzs5jxsZKlJRChIQpUlIhQkJatbVSpaU5c3MxY2'. 532 'MYMTEQISFavb1Sra1KnJxCjIw5e3sxa2spWlpClJQhSkoYOTkp'. 533 'Y2MhUlIQKSkIGBgQMTH+e30mAAAAAXRSTlMAQObYZgAAAAFiS0'. 534 'dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfT'. 535 'AwkUGTIqLgJPAAAAqklEQVR4nI2QVxOCMBCEM6Mi2OiCvSslJB'. 536 'CUoqjn//9TYgCfubf9Zu9uZxFqO+rscO7b6l/LljMZX29J2pNr'. 537 'YjmX4ZaIEs2NeiWO19NNacl8rHAyD4LR6jjw6PMRdTjZE0JOiU'. 538 'dDv2ALTlzRvSdCCfAHGCc7yRPSrAQRQOWxKc3C/IUjBlDdUcM8'. 539 '97vFGwBY9QsZGBc/A4DWZNbeXIPWZEZI0c2lqSute/gCO9MXGY'. 540 '4/IOkAAAAASUVORK5CYII=' ; 541 542 //========================================================== 543 // File: bs_yellow.png 544 //========================================================== 545 $this->imgdata_small[4][0]= 507 ; 546 $this->imgdata_small[4][1]= 547 'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAzF'. 548 'BMVEX///////+/v79zYwCMewDOxoTWzoTezkr/5wj/5wDnzgDe'. 549 'xgC1pQCtnACllACcjACUhABjWgDGvVK1rUrOxlLGvUqEexilnB'. 550 'jv3hj35xj/7wj/7wD35wDv3gDn1gDezgDWxgDOvQDGtQC9rQCE'. 551 'ewB7cwBzawBrYwDWzlLn3lLe1krn3kre1hi9tQC1rQCtpQClnA'. 552 'CclACUjACMhAD/9wC/v7///8bOzoT//4T//3v//3P//2v//2Pn'. 553 '50r//0r//yn39xj//xD//wBjYwDO8noaAAAAAXRSTlMAQObYZg'. 554 'AAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAH'. 555 'dElNRQfTAwkUGSDZl3MHAAAAqElEQVR4nI3QWRNDMBAA4My09E'. 556 'IF1SME0VT1okXvM/3//6kEfbZv+81eswA0DfHxRpOV+M+zkDGG'. 557 'rL63zCoJ2ef2RLZDIqNqYexyvFrY9ePkxGWdpvfzC7tEGtIRly'. 558 'nqzboFKMlizAXbNnZyiFUKAy4bZ+B6W0lRaQDLmg4h/k7eFwDL'. 559 'OWIky8qhXUBQ7gKGmsxpC+ah1TdriwByqG8GQNDNr6kLjf/wAx'. 560 'KgEq+FpPbfAAAAAElFTkSuQmCC' ; 561 562 //========================================================== 563 // File: bs_darkgray.png 564 //========================================================== 565 $this->imgdata_small[5][0]= 611 ; 566 $this->imgdata_small[5][1]= 567 'iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAMAAAAMCGV4AAABJl'. 568 'BMVEX////////o8v/f6O7W4OnR3PXL1OTL0evEyLvCzePAwMC/'. 569 'v7a8wsq7t7C1xum1vtS1q6GzopmyxeKsrsOqvNWoq7anvN+nsb'. 570 'qhrcGgqbGfpq6cp7+bqMuVmJKRm7yPlKKMnL6FkKWFipOEkLSE'. 571 'j6qEhoqAiaB+jqd8haF7hZR4iJt4g5l3hZl2gIt2cod1hJVzeY'. 572 'VzboJvhp9sfJJsb41peY1pd5xpdoVod4xndI5lcHxka4BjcYVg'. 573 'Z3BfboFbb4lbZnZbYntaZ4laZYVZV3JYYWpXX3JWWm5VX4RVW2'. 574 'NUYX9SXHxPWn5OVFxNWWtNVXVMVWFKV3xHUGZGU3dGTldFSlxE'. 575 'Sk9ESXBCRlNBS3k/SGs/RU4+R1k9R2U6RFU2PUg0PEQxNU0ECL'. 576 'QWAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAA'. 577 'CxIAAAsSAdLdfvwAAAAHdElNRQfTAwkUGQmbJetrAAAAtklEQV'. 578 'R4nGNgwAK4JZTNNOWlYDxhMT4ZDTOzQE1uMF9CiJWVU0LbxDlS'. 579 'G8QVF+FnZ2KRNHAIiPUHaZGSlmZj5lH19A1KjLUA8lXU5MWllF'. 580 'yjo30TYr2BfG19G11b37CEeN84H38gX1HbwTUkOjo+zjfG3hLI'. 581 'l1exCvCNCwnxjfMz0gTyRdXNHXx9fUNCQu2MwU6SN3ZwD42LCH'. 582 'W30IK4T8vUJSAkNMhDiwPqYiktXWN9JZj7UQAAjWEfhlG+kScA'. 583 'AAAASUVORK5CYII=' ; 584 585 586 //========================================================== 587 // File: bs_darkgreen.png 588 //========================================================== 589 $this->imgdata_small[6][0]= 666 ; 590 $this->imgdata_small[6][1]= 591 'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAABX1'. 592 'BMVEX////////l/+nAwMC86r+8wb28wby8wLy78sCzw7SywrSx'. 593 'wLKwvrGuvK+syK+ryq2rx62n36ym3aumxKmk2qij0Keh16ahva'. 594 'Og1aSguKKe06KeuaCetZ+d0KGdtZ+bz6Cay56ZyZ2Zwp2Zr5qZ'. 595 'rpqYwJuXyZuXrJmVw5mUxZiTxJeTw5eTq5WRwJWPtJKOvZKKuI'. 596 '6Kt42Kn4yJt42ItIuGsomFsYmEsIiEr4eDr4eBrIR/qoN+qIJ8'. 597 'poB7pH56o356on14nnt2nXl0mndzmnZzmXZymHVwlXNvlHJukn'. 598 'FtiHBqjm1qjW1oi2toiWpniWplh2hlhmdkhWdig2VggGNgf2Je'. 599 'fmFdfGBde19bbl1aeFxXdFpWclhVclhVcVdUcFZTb1VSbVRQal'. 600 'JPaVFKY0xKYkxJYUtIYEpHX0lEWkZCWERCV0NCVkM/U0A+U0A+'. 601 'UUA+UEA9Uj89UT48Tj45TDvewfrHAAAAAXRSTlMAQObYZgAAAA'. 602 'FiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElN'. 603 'RQfTAwkUGRjxlcuZAAAAtElEQVR4nGNgIBZw8osqqIpzw/msfI'. 604 'IiUmr6lo6SbFARASEOJiYtQ2uXADmIAJeEGFBE18LBMySBBywi'. 605 'LC/LwcFiZuvmH5WiAxZR0tRW1DC3dfYJS8zyAouYGBibWtm7+o'. 606 'TEpZfkgEX0rG3snNx9Q2NSCksgaqRd3Ty8gyLiU/NKSiDmcPsF'. 607 'BodHJ2UUlZTkQ+xikIlNSE7LLgECZagL2VQyc0H8YnV2uD94jS'. 608 'ILIo14iQ4HALarJBNwbJVNAAAAAElFTkSuQmCC' ; 609 610 //========================================================== 611 // File: bs_purple.png 612 //========================================================== 613 $this->imgdata_small[7][0]= 447 ; 614 $this->imgdata_small[7][1]= 615 'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAnF'. 616 'BMVEX///////+/v7/Gvca9rb3Grcb/xv+1hLWte629hL21e7XG'. 617 'hMbWhNbOe87We9b/hP//e/97OXv/c///a///Y/+cOZz/Sv/WOd'. 618 'bnOefvOe//Kf9jCGNrCGv/EP//CP/nCOf/AP/3APfvAO/nAOfe'. 619 'AN7WANbOAM7GAMa9AL21ALWtAK2lAKWcAJyUAJSMAIyEAIR7AH'. 620 'tzAHNrAGtjAGPP1sZnAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgF'. 621 'HUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkUGS'. 622 'o5QpoZAAAAnElEQVR4nI3Q2xJDMBAG4MyQokWrZz3oSkJISJH3'. 623 'f7dK0Gv/Xb7J7vyzCK0NjtPsHuH/2wlhTE7LnTNLCO/TFQjjIp'. 624 'hHAA6bY06LSqppMAY47x+04HXTba2kAFlmQKr+YuVDCGUG2k6/'. 625 'rNwYK8rKwKCnPxHnVS0aA3rag4UQslUGhrlk0Kpv1+sx3tLZ6w'. 626 'dtYemMkOsnz8R3V9/hB87DEu2Wos5+AAAAAElFTkSuQmCC' ; 627 628 629 //========================================================== 630 // File: bs_brown.png 631 //========================================================== 632 $this->imgdata_small[8][0]= 677 ; 633 $this->imgdata_small[8][1]= 634 'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAABaF'. 635 'BMVEX//////////8X/3oD/3nj/1HX/0Gr/xGP/rkv/gBf+iS/2'. 636 'bAL1agDxaQDuZwDrZwLpZQDmZQLlZADjcx7gZATeYQDdZgraXw'. 637 'DZXwHYXgDXiEvXZAvUjlfUXwXTjVfTbR7ShUvRbR7RWwDMWQDL'. 638 'WADKooLKWADJoYLJgkvHWATGoILFn4LFgEvFVgDEZx7EVQDDt6'. 639 '/DVQDCt6/CnoLChlfCVADAwMC+hFe+UgC8UgC6UQC4gVe4UAC3'. 640 'gVe3UAC1gFe1eUu1TwC1TgCzTgCwTQKuTACrSgCqSgCpSgCpSQ'. 641 'CodEulSACkRwCiRgCdRACcRACaQwCYQgCWQgKVQQCVQACUQACS'. 642 'UR6RPwCOPgCNPQCLPACKPACJOwCEOQCBOAB+NwB9NgB8NgB7NQ'. 643 'B6NwJ4NAB3RR52MwB0MgBuLwBtLwBsLwBqLgBpLQBkLQJiKgBh'. 644 'KgBgKwRcKABbKQJbJwBaKQRaJwBYKAJVJQDZvdIYAAAAAXRSTl'. 645 'MAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLd'. 646 'fvwAAAAHdElNRQfTAwkUGho0tvl2AAAAtklEQVR4nGNgIBaoSg'. 647 'mLKGpowfkGMty8AqJKpi4mRlAROR5ONg4JFUv3YHOIgDo/HwsT'. 648 'q6yps29EsjZYREFIkJ2ZS9/OMzA20wEsIi8uKSZtaOPmH5WSFw'. 649 'YW0VRW07Vw8vCLSMguLwCL6FlaObp6B0TGZxSXQ9TouHv6+IXG'. 650 'JGYWlpdDzNEKCgmPjkvLKS0vL4LYxWAen5SelV8OBNZQFxrZ5h'. 651 'aC+GX2MDczMBh7pZakehkTHQ4AA0Am/jsB5gkAAAAASUVORK5C'. 652 'YII=' ; 653 654 //========================================================== 655 // File: bs_blue.png 656 //========================================================== 657 $this->imgdata_small[9][0]= 436 ; 658 $this->imgdata_small[9][1]= 659 'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAk1'. 660 'BMVEX///////+/v7+trcbGxv+EhM6EhNaEhP97e/9zc/9ra/9S'. 661 'UsZKSrVSUs5jY/9SUtZKSsZSUudKSt5KSudKSv8YGIQpKf8YGK'. 662 'UYGN4YGO8YGPcQEP8ICP8AAP8AAPcAAO8AAOcAAN4AANYAAM4A'. 663 'AMYAAL0AALUAAK0AAKUAAJwAAJQAAIwAAIQAAHsAAHMAAGsAAG'. 664 'ONFkFbAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZ'. 665 'cwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkUGhNNakHSAAAAmk'. 666 'lEQVR4nI3P2xKCIBAGYGfM6SBWo1nauIqogaDA+z9dK9Lhrv47'. 667 'vtl/2A2CfxNlJRRp9IETYGraJeEb7ocLNKznia8A7Db7umWDUG'. 668 'sxAzhurxRHxok4KQGqCuEhlL45oU1D2w5BztY4KRhj/bCAsetM'. 669 '2uObjwvY8/oX50JItYDxSyZSTrO2mNhvGMbaWAevnbFIcpuTr7'. 670 't+5AkyfBIKSJHdSQAAAABJRU5ErkJggg==' ; 671 672 //========================================================== 673 // File: bs_green.png 674 //========================================================== 675 $this->imgdata_small[10][0]= 452 ; 676 $this->imgdata_small[10][1]= 677 'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAn1'. 678 'BMVEX///////+/v7+/v7/G/8aUxpSMvYyUzpSMzoyM1oxarVqE'. 679 '/4R7/3tavVpKnEpaxlpz/3Nr/2tKtUpj/2Na51pKzkpK1kpK50'. 680 'pK/0oYcxgp/ykYlBgY3hgY7xgY9xgQ/xAI/wgA/wAA9wAA7wAA'. 681 '5wAA3gAA1gAAzgAAxgAAvQAAtQAArQAApQAAnAAAlAAAjAAAhA'. 682 'AAewAAcwAAawAAYwA0tyxUAAAAAXRSTlMAQObYZgAAAAFiS0dE'. 683 'AIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAw'. 684 'kUGgW5vvSDAAAAnklEQVR4nI3QSxKCMAwA0M4gqCgoiiJ+kEAL'. 685 'LQUq0PufzX7ENdnlJZNkgtDS2CYZvK6bf+7EoKLA9cH5SQzv6A'. 686 'YloTywsAbYr44FrlgrXCMJwHl3xxVtuuFkJAPIcw2tGB9GcFli'. 687 'oqEf5GTkSUhVMw2TtD0XSlnDOw3SznE5520vNEi7CwW9+Ayjyq'. 688 'U/3+yPuq5gvhkhL0xlGnqL//AFf14UIh4mkEkAAAAASUVORK5C'. 689 'YII=' ; 690 691 692 //========================================================== 693 // File: bs_white.png 694 //========================================================== 695 $this->imgdata_small[11][0]= 480 ; 696 $this->imgdata_small[11][1]= 697 'iVBORw0KGgoAAAANSUhEUgAAABEAAAAQCAYAAADwMZRfAAAABm'. 698 'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'. 699 'B3RJTUUH0wMLFTsY/ewvBQAAAW1JREFUeJytkz2u4jAUhT/jic'. 700 'gfBUKiZhE0bIKeVbCWrIKenp6eDiGlCEEEBArIxvzGU4xeZjLk'. 701 'jWb05lRXuvbx+exr4bouX1Xjyw7Atz81F4uFBYjjGIDhcCjq1o'. 702 'k6nN1uZwFerxfP55Msy1itVmRZBsB4PK6YveHkeW5d18XzPIIg'. 703 'wPd9Wq0WnU6HMAxJkoQoiuynOIfDwUopkVIihKAoCgAcx6Hdbm'. 704 'OMIU1T5vN55eBKEikljUYDIX6kFUKU9e8aDAZlmjcca+1b7TgO'. 705 '1+uVy+VS9nzfr8e53++VzdZaiqIgz3OMMWitOZ/PaK0JgqDeRC'. 706 'mF53lIKYGfr3O73TDGoJQiTVO01nS73XqT4/FIs9kkCAIej0eZ'. 707 'brPZEMcxSZKgtQZgMpmIWpN+vy+m06n1PK9yTx8Gy+WS/X5Pr9'. 708 'er9GuHLYoiG4YhSilOpxPr9Zrtdlti/JriU5MPjUYjq7UuEWaz'. 709 '2d+P/b/qv/zi75oetJcv7QQXAAAAAElFTkSuQmCC' ; 710 711 712 //========================================================== 713 // File: bs_cyan.png 714 //========================================================== 715 $this->imgdata_small[12][0]= 633 ; 716 $this->imgdata_small[12][1]= 717 'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAABPl'. 718 'BMVEX////////F///AwMCvxsaC1NSC0dGCz8+CzMyA//94//91'. 719 '//9q//9j//9X4uJX09NXz89Xx8dXxMRL//9L5uZL3d1L2NhLxs'. 720 'ZLt7cv//8e9fUe8fEe7u4e398epqYehoYX//8L+PgK//8F9fUE'. 721 '/v4E5+cEb28EZ2cC//8C/v4C/f0CzMwCrq4Cjo4CdXUCaWkCZW'. 722 'UB/PwA//8A/f0A+/sA8/MA7e0A7OwA6+sA5eUA5OQA4uIA4eEA'. 723 '3NwA2toA2NgA1dUA09MA0tIA0NAAysoAxsYAxcUAxMQAv78Avr'. 724 '4AvLwAtrYAtbUAs7MAsLAAra0Aq6sAqKgApaUApKQAoqIAoKAA'. 725 'n58AmpoAlZUAk5MAkpIAkJAAj48AjIwAiYkAh4cAf38AfX0Ae3'. 726 'sAenoAcnIAcHAAa2sAaWkAaGgAYmIUPEuTAAAAAXRSTlMAQObY'. 727 'ZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAA'. 728 'AHdElNRQfTAwkUGQDi+VPPAAAAtElEQVR4nGNgIBawikipyIiy'. 729 'wfksfJpGRkamNtr8LFARPiMFHmFDcztXfwGoFi0jLiZuZRtnry'. 730 'BddrCIiJEGL6eklYO7X3iCOFhE2thESdHawdUnJDZFDiyiamZh'. 731 'aevk5h0UlZSpBhaRtbN3dPHwDY5MSM+EqBFzc/f0DgiLTkjLzI'. 732 'SYw6bjHxgaEZeckZmpD7GLQSAqJj4xNRMIBGFuFtRLA/ENhGBu'. 733 'ZmDgkJBXl5fgIDocAAKcINaFePT4AAAAAElFTkSuQmCC' ; 734 735 //========================================================== 736 // File: bs_bluegreen.png 737 //========================================================== 738 $this->imgdata_small[13][0]= 493 ; 739 $this->imgdata_small[13][1]= 740 'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAvV'. 741 'BMVEX///////+/v79j//855/8x3v851v9Spb1C1v8AOUqEtcZK'. 742 'lK1StdYxzv8hxv8AY4QASmNSlK1KpcZKtd4YQlIYnM4YrecIvf'. 743 '8AtfcAre8AjL0AhLUAc5wAa5QAWnsAQloAKTkAGCFKhJxKrdYY'. 744 'jL0Ypd4Atf8ArfcApecAnN4AlM4AjMYAe60Ac6UAY4wAUnNSnL'. 745 '0AlNYAWoQASmsAOVIAITGEtc4YWnsAUnsAMUqtvcaErcYAKUIA'. 746 'GCkAECHUyVh/AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAA'. 747 'AJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkUGxNUcXCT'. 748 'AAAAqUlEQVR4nI2Q1xKCMBREM2NHLCCogAGCjd6SqLT8/2cZKT'. 749 '6zb3tm987OBWCsXoejp8rC35fi4+l6gXFZlD0Rz6fZ1tdDmKR9'. 750 'RdOmkzmP7DDpilfX3SzvRgQ/Vr1uiZplfsCBiVf03RJd140wgj'. 751 'kmNqMtuYXcxyYmNWJdRoYwzpM9qRvGujuCmSR7q7ARY00/MiWk'. 752 'sCnjkobNEm1+HknDZgAqR0GKU43+wxdu2hYzbsHU6AAAAABJRU'. 753 '5ErkJggg==' ; 754 755 //========================================================== 756 // File: bs_lightred.png 757 //========================================================== 758 $this->imgdata_small[14][0]= 532 ; 759 $this->imgdata_small[14][1]= 760 'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAA3l'. 761 'BMVEX///////+/v7/Gvb0hGBj/5///3v//zu//1u//xucpGCG9'. 762 'nK21lKVSQkp7Wms5KTExISlaOUpjQlIhEBj/tdbOhKXnrcbGjK'. 763 'Wla4TetcbGnK2EWmv/rc73pcZ7UmOcY3vOpbW1jJzenLW9e5Rz'. 764 'Slq1c4xrQlJSOULGhJz/pcb3nL2chIzOnK33rcbelK3WjKWMWm'. 765 'vGe5SEUmM5ISnOtb3GrbXerb3vpb2ca3v/rcaUY3POhJxCKTF7'. 766 'SlrWnK21e4ytc4TvnLXnlK2la3taOUK1lJxrSlLGhJRjQkpSMT'. 767 'lw+q2nAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZ'. 768 'cwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAwkUGjoP2Nm+AAAAr0'. 769 'lEQVR4nGNgIBaYiOk62imYwPnMkiIyso76yhJSzFARMxkRNk49'. 770 'a3t5OW6oFk1LVkYOfWUHKxUXiEYzLS12DnN3VXkjIRtFsIiSk5'. 771 '6evqGqhYGKugAfWMRa1FpD2UHeQEXQRlgALCJur+rgbCUNFOAS'. 772 'hqjRkZe3MpBTcwEKCEPMMTGSs3Xz8OQHCnBBHckt6OJpIyAMBD'. 773 'wwN/MYc4H4LK4wNzMwmGrzcvFqmxIdDgDiHRT6VVQkrAAAAABJ'. 774 'RU5ErkJggg==' ; 775 776 //========================================================== 777 // File: bxs_lightred.png 778 //========================================================== 779 $this->imgdata_xsmall[0][0]= 432 ; 780 $this->imgdata_xsmall[0][1]= 781 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAA3l'. 782 'BMVEX///////+/v7/Gvb0hGBj/5///3v//zu//1u//xucpGCG9'. 783 'nK21lKVSQkp7Wms5KTExISlaOUpjQlIhEBj/tdbOhKXnrcbGjK'. 784 'Wla4TetcbGnK2EWmv/rc73pcZ7UmOcY3vOpbW1jJzenLW9e5Rz'. 785 'Slq1c4xrQlJSOULGhJz/pcb3nL2chIzOnK33rcbelK3WjKWMWm'. 786 'vGe5SEUmM5ISnOtb3GrbXerb3vpb2ca3v/rcaUY3POhJxCKTF7'. 787 'SlrWnK21e4ytc4TvnLXnlK2la3taOUK1lJxrSlLGhJRjQkpSMT'. 788 'lw+q2nAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZ'. 789 'cwAACxEAAAsRAX9kX5EAAAAHdElNRQfTAwkUKBOgGhWjAAAAS0'. 790 'lEQVR4nGNgQAEmunYmEJaMCKe1vBxYzJKVQ9lKBSSupKdnaKGi'. 791 'zgdkiqs6WKnYcIGYJnK2HvzCwmCNgi42wsLCECNMeXlNUY0HAL'. 792 'DaB7Du8MiEAAAAAElFTkSuQmCC' ; 793 794 //========================================================== 795 // File: bxs_bluegreen.png 796 //========================================================== 797 $this->imgdata_xsmall[1][0]= 397 ; 798 $this->imgdata_xsmall[1][1]= 799 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAvV'. 800 'BMVEX///////+/v79j//855/8x3v851v9Spb1C1v8AOUqEtcZK'. 801 'lK1StdYxzv8hxv8AY4QASmNSlK1KpcZKtd4YQlIYnM4YrecIvf'. 802 '8AtfcAre8AjL0AhLUAc5wAa5QAWnsAQloAKTkAGCFKhJxKrdYY'. 803 'jL0Ypd4Atf8ArfcApecAnN4AlM4AjMYAe60Ac6UAY4wAUnNSnL'. 804 '0AlNYAWoQASmsAOVIAITGEtc4YWnsAUnsAMUqtvcaErcYAKUIA'. 805 'GCkAECHUyVh/AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAA'. 806 'AJcEhZcwAACxEAAAsRAX9kX5EAAAAHdElNRQfTAwkUKDVyF5Be'. 807 'AAAASUlEQVR4nGNgQAFmYqJcEJaEOJ+UrD5YTJKFTZrfGCQuaq'. 808 'glLWvMaQ5kqujo6hnbKIKYXPr68gp2dmCNJiZAlh3ECGsREWtU'. 809 '4wF1kwdpAHfnSwAAAABJRU5ErkJggg==' ; 810 811 //========================================================== 812 // File: bxs_navy.png 813 //========================================================== 814 $this->imgdata_xsmall[2][0]= 353 ; 815 $this->imgdata_xsmall[2][1]= 816 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAk1'. 817 'BMVEX///////+/v7+trcbGxv+EhM6EhNaEhP97e/9zc/9ra/9S'. 818 'UsZKSrVSUs5jY/9SUtZKSsZSUudKSt5KSudKSv8YGIQpKf8YGK'. 819 'UYGN4YGO8YGPcQEP8ICP8AAP8AAPcAAO8AAOcAAN4AANYAAM4A'. 820 'AMYAAL0AALUAAK0AAKUAAJwAAJQAAIwAAIQAAHsAAHMAAGsAAG'. 821 'ONFkFbAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZ'. 822 'cwAACxEAAAsRAX9kX5EAAAAHdElNRQfTAwkUJxXO4axZAAAAR0'. 823 'lEQVR4nGNgQAGskhKsEJaslIi8ijpYTJaDU1FVAyQuKSujoKKh'. 824 'LQ5kSigpqWro6oOYrOoaWroGBmCNWiCWAdQwUVFWVOMBOp4GCJ'. 825 's5S60AAAAASUVORK5CYII=' ; 826 827 //========================================================== 828 // File: bxs_gray.png 829 //========================================================== 830 $this->imgdata_xsmall[3][0]= 492 ; 831 $this->imgdata_xsmall[3][1]= 832 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAABI1'. 833 'BMVEX///8AAAD8EAD8IAD8NAD8RAD8VAAYGBi/v7+goKCCgoJk'. 834 'ZGRGRkb8yAD83AD87AD8/AD4+ADo+ADY+ADI+AC0+ACk+ACU+A'. 835 'CE+AB0/ABk/ABU/ABE/AAw/AAg/AAQ/AAA/AAA+AAA6BAA2CAA'. 836 'yDQAtEQApFQAlGQAhHQAdIgAZJgAVKgARLgAMMgAINwAEOwAAP'. 837 'wAAPgIAPAQAOgYAOAkANgsANA0AMg8AMBEALhMALBUAKhcAKBo'. 838 'AJhwAJB4AIiAAID////4+Pjy8vLs7Ozm5ubg4ODa2trT09PNzc'. 839 '3Hx8fBwcG7u7u1tbWurq6oqKiioqKcnJyWlpaQkJCJiYmDg4N9'. 840 'fX13d3dxcXFra2tkZGReXl5YWFhSUlJMTExGRkZAQEA1BLn4AA'. 841 'AAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxEA'. 842 'AAsRAX9kX5EAAAAHdElNRQfTAwkUKC74clmyAAAAQklEQVR4nG'. 843 'NgQAVBYVCGt5dXYEQ0mOnp5h4QFgVmeri6+4dHxYMVeHoFRUTH'. 844 'gTUFBIZBWAwMkZEx8bFQM2Lj0UwHANc/DV6yq/BiAAAAAElFTk'. 845 'SuQmCC' ; 846 847 //========================================================== 848 // File: bxs_graypurple.png 849 //========================================================== 850 $this->imgdata_xsmall[4][0]= 542 ; 851 $this->imgdata_xsmall[4][1]= 852 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAABSl'. 853 'BMVEX////////11P/MqdvKrNfAwMC+u7+9u7+4rr24lsi3rby3'. 854 'lMe1rLq1o720q7i0oL20ksSzoryyqbaykMGxlb2wkL+vnbiujb'. 855 '2sjLuri7qpl7GoirWoibenmK2mla6mjLKmhrSllauki7CjhrCj'. 856 'hLGihLChg6+ggq2fkqadkKOcfqqai6Gag6WYe6WXeqSWeaOTd6'. 857 'CTd5+Rdp6RdZ6RdZ2Qg5eOc5qMcpiLcZeJb5WIbpOHbZKGbJGE'. 858 'a4+CaY2AZ4t/Z4p/Zop/Zol+Zol7ZIZ6Y4V5YoR1ZH11X391Xn'. 859 '9zXX1yXXtxXHtvWnluWXhsV3VqVnNpVXJoVHFnU3BmUm9jUGth'. 860 'VGdgTmheTGZcS2RcSmRaSWJYR19XRl5SQllRQlhQQVdPQFZOP1'. 861 'VLPlFJO09IPE5IOk5FOEtEN0lDOEpDOElDNklCNkc/M0XhbrfD'. 862 'AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACx'. 863 'EAAAsRAX9kX5EAAAAHdElNRQfTAwkUKCgREfyHAAAATUlEQVR4'. 864 'nGNgQAEcIko8EBY3M5Ougy+IxSXMwmTsFsAHZMqrSRvZB0W7A5'. 865 'k6FlYugXEZICaPr394Um4uSAFDRFRCbm4uxAihsDAhVOMBHT0L'. 866 'hkeRpo8AAAAASUVORK5CYII=' ; 867 868 //========================================================== 869 // File: bxs_red.png 870 //========================================================== 871 $this->imgdata_xsmall[5][0]= 357 ; 872 $this->imgdata_xsmall[5][1]= 873 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAk1'. 874 'BMVEX////////GxsbGra3/xsbOhITWhIT/hIT/e3v/c3P/a2vG'. 875 'UlK1SkrOUlL/Y2PWUlLGSkrnUlLeSkrnSkr/SkqEGBj/KSmlGB'. 876 'jeGBjvGBj3GBj/EBD/CAj/AAD3AADvAADnAADeAADWAADOAADG'. 877 'AAC9AAC1AACtAAClAACcAACUAACMAACEAAB7AABzAABrAABjAA'. 878 'BuukXBAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZ'. 879 'cwAACxEAAAsRAX9kX5EAAAAHdElNRQfTAwkUIyjy5SVMAAAAS0'. 880 'lEQVR4nGNgQAFsUpJsEJastIi8ijpYTJaDU0FVgxXIlJKVUVDR'. 881 '0BYHMiUUlVQ1dPVBTDZ1dS1dAwOQAgYtbSDLAGIEq6goK6rxAD'. 882 'yXBg73lwGUAAAAAElFTkSuQmCC' ; 883 884 //========================================================== 885 // File: bxs_yellow.png 886 //========================================================== 887 $this->imgdata_xsmall[6][0]= 414 ; 888 $this->imgdata_xsmall[6][1]= 889 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAzF'. 890 'BMVEX///////+/v79zYwCMewDOxoTWzoTezkr/5wj/5wDnzgDe'. 891 'xgC1pQCtnACllACcjACUhABjWgDGvVK1rUrOxlLGvUqEexilnB'. 892 'jv3hj35xj/7wj/7wD35wDv3gDn1gDezgDWxgDOvQDGtQC9rQCE'. 893 'ewB7cwBzawBrYwDWzlLn3lLe1krn3kre1hi9tQC1rQCtpQClnA'. 894 'CclACUjACMhAD/9wC/v7///8bOzoT//4T//3v//3P//2v//2Pn'. 895 '50r//0r//yn39xj//xD//wBjYwDO8noaAAAAAXRSTlMAQObYZg'. 896 'AAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAAH'. 897 'dElNRQfTAwkUIzoBXFQEAAAAS0lEQVR4nGNgQAFsDhJsEJaTo5'. 898 '2skj5YzMnSSk7ZwBzIlOSUklPiMxYHMnW4FXT5VNVBTDZeXiNV'. 899 'QUGQAgYBYyBLEGIEq5gYK6rxAH4kBmHBaMQQAAAAAElFTkSuQm'. 900 'CC' ; 901 902 //========================================================== 903 // File: bxs_greenblue.png 904 //========================================================== 905 $this->imgdata_xsmall[7][0]= 410 ; 906 $this->imgdata_xsmall[7][1]= 907 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAxl'. 908 'BMVEX///////+/v79znJQhSkJ7raU5hHtjraVKnJRCjIRClIyU'. 909 '9++E595avbVaxr2/v7+ctbWcvb17nJxrjIx7paUxQkK9//+Mvb'. 910 '17ra2Evb17tbVCY2MQGBiU5+ec9/eM5+d71tZanJxjra1rvb1j'. 911 'tbVSnJxara1rzs5jxsZKlJRChIQpUlIhQkJatbVSpaU5c3MxY2'. 912 'MYMTEQISFavb1Sra1KnJxCjIw5e3sxa2spWlpClJQhSkoYOTkp'. 913 'Y2MhUlIQKSkIGBgQMTH+e30mAAAAAXRSTlMAQObYZgAAAAFiS0'. 914 'dEAIgFHUgAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAAHdElNRQfT'. 915 'AwkUJy5/6kV9AAAATUlEQVR4nGNgQAGCyuyCEJaGugKHviVYzF'. 916 'hO3sxCWwDIVNLTM9PXtpEGMhW12Cy0DR1ATEFLSxZ7BweQAgYd'. 917 'HUMHBweIEQKiogKoxgMAo/4H5AfSehsAAAAASUVORK5CYII=' ; 918 919 //========================================================== 920 // File: bxs_purple.png 921 //========================================================== 922 $this->imgdata_xsmall[8][0]= 364 ; 923 $this->imgdata_xsmall[8][1]= 924 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAnF'. 925 'BMVEX///////+/v7/Gvca9rb3Grcb/xv+1hLWte629hL21e7XG'. 926 'hMbWhNbOe87We9b/hP//e/97OXv/c///a///Y/+cOZz/Sv/WOd'. 927 'bnOefvOe//Kf9jCGNrCGv/EP//CP/nCOf/AP/3APfvAO/nAOfe'. 928 'AN7WANbOAM7GAMa9AL21ALWtAK2lAKWcAJyUAJSMAIyEAIR7AH'. 929 'tzAHNrAGtjAGPP1sZnAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgF'. 930 'HUgAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAAHdElNRQfTAwkUIj'. 931 'mBTjT/AAAASUlEQVR4nGNgQAGskhKsEJaCrJiSuhZYTEFASFlD'. 932 'GyQuqSCnrK6tJwpkiquoamgbGIGYrFpaugbGxmCNunpAljHECB'. 933 'ZBQRZU4wFSMAZsXeM71AAAAABJRU5ErkJggg==' ; 934 935 //========================================================== 936 // File: bxs_green.png 937 //========================================================== 938 $this->imgdata_xsmall[9][0]= 370 ; 939 $this->imgdata_xsmall[9][1]= 940 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAn1'. 941 'BMVEX///////+/v7+/v7/G/8aUxpSMvYyUzpSMzoyM1oxarVqE'. 942 '/4R7/3tavVpKnEpaxlpz/3Nr/2tKtUpj/2Na51pKzkpK1kpK50'. 943 'pK/0oYcxgp/ykYlBgY3hgY7xgY9xgQ/xAI/wgA/wAA9wAA7wAA'. 944 '5wAA3gAA1gAAzgAAxgAAvQAAtQAArQAApQAAnAAAlAAAjAAAhA'. 945 'AAewAAcwAAawAAYwA0tyxUAAAAAXRSTlMAQObYZgAAAAFiS0dE'. 946 'AIgFHUgAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAAHdElNRQfTAw'. 947 'kUKBrZxq0HAAAATElEQVR4nGNgQAGccrIcEJaivISyhjaIxa7I'. 948 'I6CiqcMKZMopKqho6OhLA5kyqmqaOobGICartraeoYkJSAGDnj'. 949 '6QZQIxgk1Skg3VeABlVgbItqEBUwAAAABJRU5ErkJggg==' ; 950 951 //========================================================== 952 // File: bxs_darkgreen.png 953 //========================================================== 954 $this->imgdata_xsmall[10][0]= 563 ; 955 $this->imgdata_xsmall[10][1]= 956 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAABX1'. 957 'BMVEX////////l/+nAwMC86r+8wb28wby8wLy78sCzw7SywrSx'. 958 'wLKwvrGuvK+syK+ryq2rx62n36ym3aumxKmk2qij0Keh16ahva'. 959 'Og1aSguKKe06KeuaCetZ+d0KGdtZ+bz6Cay56ZyZ2Zwp2Zr5qZ'. 960 'rpqYwJuXyZuXrJmVw5mUxZiTxJeTw5eTq5WRwJWPtJKOvZKKuI'. 961 '6Kt42Kn4yJt42ItIuGsomFsYmEsIiEr4eDr4eBrIR/qoN+qIJ8'. 962 'poB7pH56o356on14nnt2nXl0mndzmnZzmXZymHVwlXNvlHJukn'. 963 'FtiHBqjm1qjW1oi2toiWpniWplh2hlhmdkhWdig2VggGNgf2Je'. 964 'fmFdfGBde19bbl1aeFxXdFpWclhVclhVcVdUcFZTb1VSbVRQal'. 965 'JPaVFKY0xKYkxJYUtIYEpHX0lEWkZCWERCV0NCVkM/U0A+U0A+'. 966 'UUA+UEA9Uj89UT48Tj45TDvewfrHAAAAAXRSTlMAQObYZgAAAA'. 967 'FiS0dEAIgFHUgAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAAHdElN'. 968 'RQfTAwkUKCFozUQjAAAATUlEQVR4nGNgQAGcoqrcEJYQB5OhSw'. 969 'CIxSXGwWThGcIDZCppK5o7hyV6AZl6NnbuoSmFICZ3YHB0RkkJ'. 970 'SAFDbEJaSUkJxAjeyEheVOMBQj4MOEkWew4AAAAASUVORK5CYI'. 971 'I=' ; 972 973 //========================================================== 974 // File: bxs_cyan.png 975 //========================================================== 976 $this->imgdata_xsmall[11][0]= 530 ; 977 $this->imgdata_xsmall[11][1]= 978 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAABPl'. 979 'BMVEX////////F///AwMCvxsaC1NSC0dGCz8+CzMyA//94//91'. 980 '//9q//9j//9X4uJX09NXz89Xx8dXxMRL//9L5uZL3d1L2NhLxs'. 981 'ZLt7cv//8e9fUe8fEe7u4e398epqYehoYX//8L+PgK//8F9fUE'. 982 '/v4E5+cEb28EZ2cC//8C/v4C/f0CzMwCrq4Cjo4CdXUCaWkCZW'. 983 'UB/PwA//8A/f0A+/sA8/MA7e0A7OwA6+sA5eUA5OQA4uIA4eEA'. 984 '3NwA2toA2NgA1dUA09MA0tIA0NAAysoAxsYAxcUAxMQAv78Avr'. 985 '4AvLwAtrYAtbUAs7MAsLAAra0Aq6sAqKgApaUApKQAoqIAoKAA'. 986 'n58AmpoAlZUAk5MAkpIAkJAAj48AjIwAiYkAh4cAf38AfX0Ae3'. 987 'sAenoAcnIAcHAAa2sAaWkAaGgAYmIUPEuTAAAAAXRSTlMAQObY'. 988 'ZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxEAAAsRAX9kX5EAAA'. 989 'AHdElNRQfTAwkUKQFKuFWqAAAATUlEQVR4nGNgQAGsUjJsEJaR'. 990 'grC5qz9YzIiL28YriB3IlDZRsnYNiZUDMmXtHT2CE9JBTDb/wI'. 991 'jkzEyQAoaomMTMzEyIERzy8hyoxgMAN2MLVPW0f4gAAAAASUVO'. 992 'RK5CYII=' ; 993 994 //========================================================== 995 // File: bxs_orange.png 996 //========================================================== 997 $this->imgdata_xsmall[12][0]= 572 ; 998 $this->imgdata_xsmall[12][1]= 999 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAABaF'. 1000 'BMVEX//////////8X/3oD/3nj/1HX/0Gr/xGP/rkv/gBf+iS/2'. 1001 'bAL1agDxaQDuZwDrZwLpZQDmZQLlZADjcx7gZATeYQDdZgraXw'. 1002 'DZXwHYXgDXiEvXZAvUjlfUXwXTjVfTbR7ShUvRbR7RWwDMWQDL'. 1003 'WADKooLKWADJoYLJgkvHWATGoILFn4LFgEvFVgDEZx7EVQDDt6'. 1004 '/DVQDCt6/CnoLChlfCVADAwMC+hFe+UgC8UgC6UQC4gVe4UAC3'. 1005 'gVe3UAC1gFe1eUu1TwC1TgCzTgCwTQKuTACrSgCqSgCpSgCpSQ'. 1006 'CodEulSACkRwCiRgCdRACcRACaQwCYQgCWQgKVQQCVQACUQACS'. 1007 'UR6RPwCOPgCNPQCLPACKPACJOwCEOQCBOAB+NwB9NgB8NgB7NQ'. 1008 'B6NwJ4NAB3RR52MwB0MgBuLwBtLwBsLwBqLgBpLQBkLQJiKgBh'. 1009 'KgBgKwRcKABbKQJbJwBaKQRaJwBYKAJVJQDZvdIYAAAAAXRSTl'. 1010 'MAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxEAAAsRAX9k'. 1011 'X5EAAAAHdElNRQfTAwkUJBSSy88MAAAATUlEQVR4nGNgQAGqwo'. 1012 'paEBYPJ4eKezCIpc7HwmrqG6ENZMpLihm6RaWEAZl6Vo7ekRnF'. 1013 'IKZWSHhcTnk5SAFDfFJWeXk5xAjj1FRjVOMBeFwNcWYSLjsAAA'. 1014 'AASUVORK5CYII=' ; 1015 1016 //========================================================== 1017 // File: bxs_lightblue.png 1018 //========================================================== 1019 $this->imgdata_xsmall[13][0]= 554 ; 1020 $this->imgdata_xsmall[13][1]= 1021 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAABVl'. 1022 'BMVEX////////d///AwMC7wcS08P+y+P+xxdCwxM+uws2twMur'. 1023 'vsinzNynytylzuKhyN6e5v6d5P+d1fOcwNWcu8ub4f+at8iZ3v'. 1024 '+ZvdGY2/yW2f+VscGU1vuT1fqTr72Sx+SSxeKR0fWRz/GPz/OP'. 1025 'rr+OyeqMy+6Myu2LyeyKxueJudSGw+SGorGDvt+Cvd6CvN2Aud'. 1026 'p+uNd+t9Z9tdV8tdR8tNN6sc94r813rct2q8h0qcZ0qMVzp8Rx'. 1027 'o8Bwor5tn7ptnrptnrlsnbhqmbRpmbNpi51ol7Flkqtkkqtkka'. 1028 'pjj6hijaRhjaZgi6NfiqJfiaFdh55bhJtag5pZgphYgJZYf5VX'. 1029 'cn9Ve5FSeI1RdopRdYlQdYlPc4dPcoZPcoVNcINLboBLbH9GZn'. 1030 'hGZXdFZHZEY3RDYnJCXW4/W2s/WWg+Wmo7VmU7VGM7U2E6VGM6'. 1031 'VGI5UV82T1wGxheQAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHU'. 1032 'gAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAAHdElNRQfTAwkUJziL'. 1033 'PvAsAAAATUlEQVR4nGNgQAHsQgqcEJYgG5Oegy+IxSHOxmTiFs'. 1034 'gFZMprKBnbB8e7AplaFlbOQUl5ICanX0BEWmEhSAFDVGxKYWEh'. 1035 'xAjusDBuVOMBJO8LrFHRAykAAAAASUVORK5CYII=' ; 1036 1037 //========================================================== 1038 // File: bxs_darkgray.png 1039 //========================================================== 1040 $this->imgdata_xsmall[14][0]= 574 ; 1041 $this->imgdata_xsmall[14][1]= 1042 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABm'. 1043 'JLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsRAAALEQF/ZF+RAAAB'. 1044 'iElEQVR42k3QPU8TYRwA8P//ebkXrgdIColXRAOEkJqbaExMut'. 1045 'DBhE1GNjYHPg+DG6ODiU6QOLjVxITBcFKBYCstlAC2Bz17fe76'. 1046 'vLD6+wg/1FpTRFR5lpaub/u1eGBGaAT4HneD4OlXx7avtDYUjT'. 1047 'HQabd2Ti8e3vVSKzxrtHS32wIpFVldno22Nqvvg2Bhl0gp/aNm'. 1048 'vJ3qqXAtLIva+ks1H0wqlSXi4+d6+OFTfRsAfHJx2d1od24rZP'. 1049 'xP2HzopINr1mkesX7ccojqif0v9crxWXODZTno3+dNGA7uWLsd'. 1050 'mUYU4fHJCViMG9umLBmM4L6fagZGg9QKfjZ+Qfy3C3G/B3mugF'. 1051 'IHHNcDf64E3KJALApk2p8CSolUUqLjFkyxOGMsTtFyJ+Wz57NQ'. 1052 '8DghS4sLB0svioeZZo7nPhFoUKZDIVFbglkTTnl5/rC8snjAkJ'. 1053 'Bk/XV5LxHC/v7tR8jzTFPbg8LENK9WX0Vv31T2AEmCSmlKCCoh'. 1054 'ROnP1U1tPFYjJBRcbtzSf+GPsFTAQBq1n4AAAABKdEVYdHNpZ2'. 1055 '5hdHVyZQBiYzYyMDIyNjgwYThjODMyMmUxNjk0NWUzZjljOGFh'. 1056 'N2VmZWFhMjA4OTE2ZjkwOTdhZWE1MzYyMjk0MWRkM2I5EqaPDA'. 1057 'AAAABJRU5ErkJggg==' ; 1058 1058 } 1059 1059 } -
trunk/client/modules/Elezioni/grafici/imgdata_bevels.inc.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: imgdata_bevels.inc.php 860 2007-03-23 19:16:19Z ljp $3 // File: IMGDATA_BEVELS.INC 4 // Description: Base64 encoded images for round bevels 5 // Created: 2003-03-20 6 // Ver: $Id: imgdata_bevels.inc.php 1106 2009-02-22 20:16:35Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 … … 12 12 protected $name = 'Round Bevels'; 13 13 protected $an = array(MARK_IMG_BEVEL => 'imgdata'); 14 14 15 15 protected $colors = array('green','purple','orange','red','yellow'); 16 16 protected $index = array('green'=>1,'purple'=>4,'orange'=>2,'red'=>0,'yellow'=>3); … … 19 19 protected $imgdata ; 20 20 21 function ImgData_Bevels() {22 //==========================================================23 // File: bullets_balls_red_013.png24 //==========================================================25 26 $this->imgdata[0][1]= 27 28 29 30 31 32 33 34 35 36 21 function __construct() { 22 //========================================================== 23 // File: bullets_balls_red_013.png 24 //========================================================== 25 $this->imgdata[0][0]= 337 ; 26 $this->imgdata[0][1]= 27 'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAM1'. 28 'BMVEX////////27t/f3+LFwcmNxMuxm62DmqKth1VpZmIWg6fv'. 29 'HCa7K0BwMEytCjFnIyUlEBg9vhQvAAAAAXRSTlMAQObYZgAAAA'. 30 'FiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElN'. 31 'RQfTAxcBNhk+pYJVAAAAl0lEQVR4nE2Q2xLDIAgFHUWBKJf//9'. 32 'oekmbafVDZARRbK/pYTKP9WNcNv64zzUdd9BjmrgnsVXRNSzO3'. 33 'CJ5ahdhy0XKQkxld1kxb45j7dp0x2lBNOyVgQpMaoadX7Hs7zr'. 34 'P1yKj47DKBnKaBKiSAkNss7O6PkMx6kIgYXISQJpcZCqdY6KR+'. 35 'J1PkS5Xob/h7MNz8x6D3fz5DKQjpkZOBYAAAAABJRU5ErkJggg'. 36 '==' ; 37 37 38 //==========================================================39 // File: bullets_balls_green_013.png40 //==========================================================41 42 $this->imgdata[1][1]= 43 44 45 46 47 48 49 50 51 52 38 //========================================================== 39 // File: bullets_balls_green_013.png 40 //========================================================== 41 $this->imgdata[1][0]= 344 ; 42 $this->imgdata[1][1]= 43 'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAM1'. 44 'BMVEX////////27t/e3+K3vriUub/Dm18j4xc3ob10k0ItqQlU'. 45 'e5JBmwpxY1ENaKBgUh0iHgwsSre9AAAAAXRSTlMAQObYZgAAAA'. 46 'FiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElN'. 47 'RQfTAxcBNTfJXtxZAAAAnklEQVR4nE2QWY4EMQhDUVhSIRC4/2'. 48 'kbaqLp9p+f2AxAayAzDfiK9znPORuvH0x8Ss9z6I9sHp6tcxE9'. 49 'nLmWmebmt5F5p2AR0+C9AWpLBjXRaZsCAT3SqklVp0YkAWaGtd'. 50 'c5Z41/STYpPzW7BjyiRrwkVmQto/Cw9tNEMvsgcekyCyFPboIu'. 51 'IsuXiKffYB4NK4r/h6d4g9HPPwCR7i8+GscIiiaonUAAAAAASU'. 52 'VORK5CYII=' ; 53 53 54 //==========================================================55 // File: bullets_balls_oy_035.png56 //==========================================================57 58 $this->imgdata[2][1]= 59 60 61 62 63 64 65 66 67 68 54 //========================================================== 55 // File: bullets_balls_oy_035.png 56 //========================================================== 57 $this->imgdata[2][0]= 341 ; 58 $this->imgdata[2][1]= 59 'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAM1'. 60 'BMVEX////////27t/f3+K5tbqNwcjnkjXjbxR2i5anfEoNkbis'. 61 'PBxpU0sZbZejKgdqIRIlERIwYtkYAAAAAXRSTlMAQObYZgAAAA'. 62 'FiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElN'. 63 'RQfTAxcBNgK0wEu5AAAAm0lEQVR4nE3QVxIEIQgEUErAgTHA/U'. 64 '+7zbipf9RXgoGo0liMmX6RdSPLPtZM9F4LuuSIaZtZWffiU6Iz'. 65 'Y8SOMF0NogBj30ioGRGLZgiPvce1TbIRz6oBQEbOFGK0rIoxrn'. 66 '5hDomMA1cfGRCaRVhjS3gkzheM+4HtnlkXcvdZhWG4qZawewe6'. 67 '9Jnz/TKLB/ML6HUepn//QczazuwFO/0Ivpolhi4AAAAASUVORK'. 68 '5CYII=' ; 69 69 70 //==========================================================71 // File: bullets_balls_oy_036.png72 //==========================================================73 74 $this->imgdata[3][1]= 75 76 77 78 79 80 81 82 83 70 //========================================================== 71 // File: bullets_balls_oy_036.png 72 //========================================================== 73 $this->imgdata[3][0]= 340 ; 74 $this->imgdata[3][1]= 75 'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAM1'. 76 'BMVEX////////27t/e3+LO3hfYzz65ubiNwci6uQ12ipadgVGa'. 77 'fwsNkbhnVkcaZ5dwSA8lFg7CEepmAAAAAXRSTlMAQObYZgAAAA'. 78 'FiS0dEAIgFHUgAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAAHdElN'. 79 'RQfTAxcCBySi1nevAAAAjElEQVR4nFXPWw7EIAgFUNMoCMhj/6'. 80 'staKczc/2RkwjS2glQ+w3YytgXCXCZpRo8gJdGxZadJws13CUP'. 81 '4SZI4MYiUxypeiGGw1XShVBTNN9kLXP2GRrZPFvKgd7z/sqGGV'. 82 '7C7r7r3l09alYN3iA8Yn+ImdVrNoEeSRqJPAaHfhZzLYwXstdZ'. 83 'rP3n2bvdAI4INwtihiwAAAAASUVORK5CYII=' ; 84 84 85 //==========================================================86 // File: bullets_balls_pp_019.png87 //==========================================================88 89 $this->imgdata[4][1]= 90 91 92 93 94 95 96 97 98 85 //========================================================== 86 // File: bullets_balls_pp_019.png 87 //========================================================== 88 $this->imgdata[4][0]= 334 ; 89 $this->imgdata[4][1]= 90 'iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAMAAAAMs7fIAAAAM1'. 91 'BMVEX////+/v7i4eO/w8eHxcvKroNVormtfkjrMN2BeXQrepPc'. 92 'Esy4IL+OFaR7F25LHF8mFRh5XXtUAAAAAXRSTlMAQObYZgAAAA'. 93 'FiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElN'. 94 'RQfTAxcBNgkjEpIxAAAAlElEQVR4nE2QAQ7FIAhDDTAVndL7n3'. 95 'ZV/7JfEwMvFIWUlkTMVNInbVv5ZeJqG7Smh2QTBwJBpsdizAZP'. 96 '5NyW0awhK8kYodnZxS6ECvPRp2sI+y7PBv1mN02KH7h77QCJ8D'. 97 '4VvY5NUgEmCwj6ZMzHtJRgRSXwC1gfcqJJH0GBnSnK1kUQ72DY'. 98 'CPBv+MCS/e0jib77eQAJxwiEWm7hFwAAAABJRU5ErkJggg==' ; 99 99 100 100 } -
trunk/client/modules/Elezioni/grafici/imgdata_diamonds.inc.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: imgdata_diamonds.inc.php 860 2007-03-23 19:16:19Z ljp $3 // File: IMGDATA_DIAMONDS.INC 4 // Description: Base64 encoded images for diamonds 5 // Created: 2003-03-20 6 // Ver: $Id: imgdata_diamonds.inc.php 1106 2009-02-22 20:16:35Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 … … 12 12 protected $name = 'Diamonds'; 13 13 protected $an = array(MARK_IMG_DIAMOND =>'imgdata'); 14 protected $colors = array('lightblue','darkblue','gray', 15 16 protected $index = array('lightblue' =>7,'darkblue'=>2,'gray'=>6, 17 14 protected $colors = array('lightblue','darkblue','gray', 15 'blue','pink','purple','red','yellow'); 16 protected $index = array('lightblue' =>7,'darkblue'=>2,'gray'=>6, 17 'blue'=>4,'pink'=>1,'purple'=>5,'red'=>0,'yellow'=>3); 18 18 19 19 protected $maxidx = 7 ; 20 20 protected $imgdata ; 21 21 22 function ImgData_Diamonds() {23 //==========================================================24 // File: diam_red.png25 //==========================================================26 27 $this->imgdata[0][1]= 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 22 function __construct() { 23 //========================================================== 24 // File: diam_red.png 25 //========================================================== 26 $this->imgdata[0][0]= 668 ; 27 $this->imgdata[0][1]= 28 'iVBORw0KGgoAAAANSUhEUgAAABsAAAAbCAMAAAC6CgRnAAAA/F'. 29 'BMVEX///////+cAAD/AADOAABjAABrAADWGBjOCAj/CAj/GBj/'. 30 'EBCcCAiMOTl7KSl7ISFzGBilGBjOEBBrCAjv5+eMQkK1QkKtMT'. 31 'GtKSnWKSn/KSlzEBCcEBDexsb/tbXOe3ucWlqcUlKUSkr/e3vn'. 32 'a2u9UlL/a2uEMTHeUlLeSkqtOTn/UlL/SkrWOTn/QkL/OTmlIS'. 33 'H/MTH/ISH39/f/9/f35+fezs7/5+fvzs7WtbXOra3nvb3/zs7G'. 34 'nJzvtbXGlJTepaW9jIy1hITWlJS1e3uta2ulY2P/lJTnhITne3'. 35 'vGY2O9Wlr/c3PeY2O1Skr/Y2P/WlreQkLWISGlEBCglEUaAAAA'. 36 'AXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAA'. 37 'sSAdLdfvwAAAAHdElNRQfTAwsWEw5WI4qnAAABGUlEQVR4nHXQ'. 38 '1XLDMBAFUKUCM1NiO8zcpIxpp8z0//9SWY7b2LHv6EU6s1qtAN'. 39 'iMBAojLPkigpJvogKC4pxDuQipjanlICXof1RQDkYEF21mKIfg'. 40 '/GGKtjAmOKt9oSyuCU7OhyiDCQnjowGfRnooCJIkiWJvv8NxnG'. 41 'nyNAwFcekvZpPP3mu7Vrp8fOq8DYbTyjdnAvBj7Jbd7nP95urs'. 42 '+MC2D6unF+Cu0VJULQBAlsOQuueN3Hrp2nGUvqppemBZ0aU7Se'. 43 'SXvYZFMKaLJn7MH3btJmZEMEmGSOreqy0SI/4ffo3uiUOYEACy'. 44 'OFopmNWlP5uZd9uPWmUoxvK9ilO9NtBo6mS7KkZD0fOJYqgGBU'. 45 'S/T7OKCAA9tfsFOicXcbxt29cAAAAASUVORK5CYII=' ; 46 46 47 //==========================================================48 // File: diam_pink.png49 //==========================================================50 51 $this->imgdata[1][1]= 52 53 54 55 56 57 58 59 47 //========================================================== 48 // File: diam_pink.png 49 //========================================================== 50 $this->imgdata[1][0]= 262 ; 51 $this->imgdata[1][1]= 52 'iVBORw0KGgoAAAANSUhEUgAAABsAAAAbBAMAAAB/+ulmAAAAEl'. 53 'BMVEX///+AgID/M5n/Zpn/zMz/mZn1xELhAAAAAXRSTlMAQObY'. 54 'ZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAA'. 55 'AHdElNRQfTAwsWEi3tX8qUAAAAbUlEQVR4nFXJwQ3AMAhDUdRm'. 56 'kKojuCswABf2X6UEEiC+WF+PyDfoGEuvwXogq3Rk1Y6W0tBSG8'. 57 '6Uwpla6CmJnpoYKRsjjb/Y63vo9kIkLcZCCsbGYGwMRqIzEp1R'. 58 'OBmFk9HQGA2N0ZEIz5HX+h/jailYpfz4dAAAAABJRU5ErkJggg'. 59 '==' ; 60 60 61 //==========================================================62 // File: diam_blue.png63 //==========================================================64 65 $this->imgdata[2][1]= 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 61 //========================================================== 62 // File: diam_blue.png 63 //========================================================== 64 $this->imgdata[2][0]= 662 ; 65 $this->imgdata[2][1]= 66 'iVBORw0KGgoAAAANSUhEUgAAABsAAAAbCAMAAAC6CgRnAAAA+V'. 67 'BMVEX///+AgIAAAJwAAP8AAM4AAGMAAGsQEP8YGHMQEHMYGP8Q'. 68 'EKUICJwICM5KSpQxMYQpKXsYGNYQEM4ICGsICP97e85aWpw5OY'. 69 'xSUv85ObVCQt4xMa0pKa0hIaUpKf+9vd6EhLVra+dzc/9SUr1r'. 70 'a/9aWt5SUt5CQrVaWv9KSv8hIXs5Of8xMf8pKdYhIdYYGKUhIf'. 71 '/Ozs739//v7/fn5+/v7//n5/fW1ufOzufOzu/W1v+trc69veel'. 72 'pc6trd6UlMa9vf+MjL21tfe1tf+UlNZzc61ra6Wlpf+EhOeMjP'. 73 '9ra8ZSUpyEhP9CQoxKSrVCQv85Od4xMdYQENZnJhlWAAAAAXRS'. 74 'TlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAd'. 75 'LdfvwAAAAHdElNRQfTAwsWEx3Snct5AAABFklEQVR4nHXR5XbD'. 76 'IBgGYM6AuHsaqbvOfeuknev9X8xISbplSd5/8JyXwwcA/I0AKm'. 77 'PFchVBdvKNKggKQx2VIoRwMZihMiQE49YUlWBCcPL0hYq4ITh+'. 78 'qKECUoLDZWqoQNA766F/mJHlHXblPJJNiyURhM5eU9cNw5BlmS'. 79 'IrLOLxhzfotF7vwO2j3ez2ap/TmW4AIM7DoN9+tu+vLk6Pdg9O'. 80 '6ufXjfXLm6pxPACSJIpRFAa+/26DhuK6qjbiON40k0N3skjOvm'. 81 'NijBmchF5mi+1jhQqDmWyIzPp1hUlrv8On5l+6mMm1tigFNyrt'. 82 '5R97g+FKKyGKkTNKesXPJTZXOFIrUoKiypcTQVHjK4g8H2dWEQ'. 83 'B8bvUDLSQXSr41rmEAAAAASUVORK5CYII=' ; 84 84 85 //==========================================================86 // File: diam_yellow.png87 //==========================================================88 89 $this->imgdata[3][1]= 90 91 92 93 94 95 96 97 85 //========================================================== 86 // File: diam_yellow.png 87 //========================================================== 88 $this->imgdata[3][0]= 262 ; 89 $this->imgdata[3][1]= 90 'iVBORw0KGgoAAAANSUhEUgAAABsAAAAbBAMAAAB/+ulmAAAAEl'. 91 'BMVEX///+AgIBmMwCZZgD/zADMmQD/QLMZAAAAAXRSTlMAQObY'. 92 'ZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAA'. 93 'AHdElNRQfTAwsWEwcv/zIDAAAAbUlEQVR4nFXJwQ3AMAhDUdRm'. 94 'kKojuCswABf2X6UEEiC+WF+PyDfoGEuvwXogq3Rk1Y6W0tBSG8'. 95 '6Uwpla6CmJnpoYKRsjjb/Y63vo9kIkLcZCCsbGYGwMRqIzEp1R'. 96 'OBmFk9HQGA2N0ZEIz5HX+h/jailYpfz4dAAAAABJRU5ErkJggg'. 97 '==' ; 98 98 99 //==========================================================100 // File: diam_lightblue.png101 //==========================================================102 103 $this->imgdata[4][1]= 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 99 //========================================================== 100 // File: diam_lightblue.png 101 //========================================================== 102 $this->imgdata[4][0]= 671 ; 103 $this->imgdata[4][1]= 104 'iVBORw0KGgoAAAANSUhEUgAAABsAAAAbCAMAAAC6CgRnAAAA/1'. 105 'BMVEX///+AgIAAnP8A//8Azv8AY/8Aa/8I//8Y1v8Izv8Y//8Q'. 106 '//8InP8Qzv8Ypf85jP8he/8Yc/8Ia/8pe/8p//8p1v9Ctf8xrf'. 107 '8prf8QnP8Qc/9CjP+1//97//9r//9S//9K//9C//85//8x//8h'. 108 '//9r5/9K3v9S3v851v97zv9Svf85rf8hpf/G3v9SnP9anP9KlP'. 109 '8xhP/n7//v7+f3///n///O//+U//9z//9j//9a//975/9C3v8h'. 110 '1v+E5/+17/9j3v/O7//n9/+95/+l3v9jxv+U1v8Qpf9avf9Ktf'. 111 '+Uxv+11v97tf9rrf+cxv+Mvf9jpf+tzv+Etf/O3v/39/8Akkxr'. 112 'AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACx'. 113 'IAAAsSAdLdfvwAAAAHdElNRQfTAwsWEiHk6Ya/AAABGUlEQVR4'. 114 'nHXQ13KDMBAF0J2o0E01GHDvJa7p3em95/+/JQJMYjDc0Yt0Zr'. 115 'VaAaxHgtxwbSGPkGQpOIeQ2ORxJiJmNWYZyAhZR0WcgQGhViU0'. 116 'nEGoedDHGxgRapRPcRpXhOr7XZzCmLjaXk9IIjvkOEmSRLG62+'. 117 'F5XlEElhA5sW21GvXj6mGlDBfnJ51lr9svnvEKwH1hu2QPbwd3'. 118 'N9eXVzuL7/Hn29frdKaamgcgy67L3HFG9gDefV+dm5qme4YRXL'. 119 'oVR374mRqUELZYosf84XAxISFRQuMh4rrH8YxGSP6HX6H97NNQ'. 120 'KEAaR08qCeuSnx2a8zIPWqUowtKHSRK91rAw0elmVYQFVc8mhq'. 121 '7p5RD7Ps3IIwA9sfsFxFUX6eZ4Zh4AAAAASUVORK5CYII=' ; 122 122 123 //==========================================================124 // File: diam_purple.png125 //==========================================================126 127 $this->imgdata[5][1]= 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 123 //========================================================== 124 // File: diam_purple.png 125 //========================================================== 126 $this->imgdata[5][0]= 657 ; 127 $this->imgdata[5][1]= 128 'iVBORw0KGgoAAAANSUhEUgAAABsAAAAbCAMAAAC6CgRnAAAA/F'. 129 'BMVEX///////8xAP/OAP+cAP9jAP9rAP+cCP85CP/OEP9SKf/O'. 130 'CP9CEP9zGP9rCP+lGP/WOf/WIf9KIf9jOf+MQv+EMf97If9zEP'. 131 '+1Sv+lIf/ne//eUv/na//n5//Oxv/Wzv+chP9zUv97Wv9rQv9a'. 132 'Mf9KGP/v5/+te/97Kf+9Y/+tOf+tKf+lEP/vtf/WMf/WKf/v7+'. 133 'f39/+tnP+9rf9rSv9jQv9CGP+ljP+EY//Gtf+tlP+Ma/9zSv/e'. 134 'zv+UUv+9lP+cWv+lY/+cUv+MOf+EKf+UQv/Opf/OhP/Ga/+1Qv'. 135 '/Oe/+9Uv/ntf/eWv/eSv/WGP/3zv/vlP/WEP//9/+pL4oHAAAA'. 136 'AXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAA'. 137 'sSAdLdfvwAAAAHdElNRQfTAwsWEjX+M1LCAAABDklEQVR4nHXQ'. 138 '1bLDIBAGYFqIEW+ksbr7cXd3ff93OUCamdOE/Mxw882yywLwPz'. 139 '+gNKotlRFUVnNUQlCxTMRFCKEdE+MgpJaEiIOU4DKaoSIygtb3'. 140 'FBUQrm3xjPK4JvXjK0A5hFniYSBtIilQVYUm+X0KTVNiYah+2q'. 141 'ulFb8nUbSovD2+TCavwXQWmnMA6ro+di+uR5cPzfPhVqPV3N1p'. 142 'n3b3+rimAWAYhP3xnXd7P6oc9vadPsa1wYEs00dFQRAFehlX21'. 143 '25Sg9NOgwF5jeNTjVL9om0TjDc1lmeCKZ17nFPzhPtSRt6J06R'. 144 'WKUoeG3MoXRa/wjLHGLodwZcotPqjsYngnWslRBZH91hWTbpD2'. 145 'EdF1ECWW1SAAAAAElFTkSuQmCC' ; 146 146 147 //==========================================================148 // File: diam_gray.png149 //==========================================================150 151 $this->imgdata[6][1]= 152 153 154 155 156 157 158 159 147 //========================================================== 148 // File: diam_gray.png 149 //========================================================== 150 $this->imgdata[6][0]= 262 ; 151 $this->imgdata[6][1]= 152 'iVBORw0KGgoAAAANSUhEUgAAABsAAAAbBAMAAAB/+ulmAAAAEl'. 153 'BMVEX//////wAzMzNmZmbMzMyZmZlq4Qo5AAAAAXRSTlMAQObY'. 154 'ZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAA'. 155 'AHdElNRQfTAwsWExZFTxLxAAAAbUlEQVR4nFXJwQ3AMAhDUdRm'. 156 'kKojuCswABf2X6UEEiC+WF+PyDfoGEuvwXogq3Rk1Y6W0tBSG8'. 157 '6Uwpla6CmJnpoYKRsjjb/Y63vo9kIkLcZCCsbGYGwMRqIzEp1R'. 158 'OBmFk9HQGA2N0ZEIz5HX+h/jailYpfz4dAAAAABJRU5ErkJggg'. 159 '==' ; 160 160 161 //==========================================================162 // File: diam_blgr.png163 //==========================================================164 165 $this->imgdata[7][1]= 166 167 168 169 170 171 172 173 161 //========================================================== 162 // File: diam_blgr.png 163 //========================================================== 164 $this->imgdata[7][0]= 262 ; 165 $this->imgdata[7][1]= 166 'iVBORw0KGgoAAAANSUhEUgAAABsAAAAbBAMAAAB/+ulmAAAAEl'. 167 'BMVEX///+AgIBmzP9m///M//+Z//8hMmBVAAAAAXRSTlMAQObY'. 168 'ZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAA'. 169 'AHdElNRQfTAwsWEwCxm6egAAAAbUlEQVR4nFXJwQ3AMAhDUdRm'. 170 'kKojuCswABf2X6UEEiC+WF+PyDfoGEuvwXogq3Rk1Y6W0tBSG8'. 171 '6Uwpla6CmJnpoYKRsjjb/Y63vo9kIkLcZCCsbGYGwMRqIzEp1R'. 172 'OBmFk9HQGA2N0ZEIz5HX+h/jailYpfz4dAAAAABJRU5ErkJggg'. 173 '==' ; 174 174 } 175 175 } -
trunk/client/modules/Elezioni/grafici/imgdata_pushpins.inc.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: imgdata_pushpins.inc.php 860 2007-03-23 19:16:19Z ljp $3 // File: IMGDATA_PUSHPINS.INC 4 // Description: Base64 encoded images for pushpins 5 // Created: 2003-03-20 6 // Ver: $Id: imgdata_pushpins.inc.php 1106 2009-02-22 20:16:35Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 … … 12 12 protected $name = 'Push pins'; 13 13 protected $an = array(MARK_IMG_PUSHPIN => 'imgdata_small', 14 15 14 MARK_IMG_SPUSHPIN => 'imgdata_small', 15 MARK_IMG_LPUSHPIN => 'imgdata_large'); 16 16 17 17 protected $colors = array('blue','green','orange','pink','red'); … … 20 20 protected $imgdata_large, $imgdata_small ; 21 21 22 function ImgData_PushPins() {23 24 25 26 27 28 29 //==========================================================30 // File: ppl_red.png31 //==========================================================32 33 $this->imgdata_large[0][1]= 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 //==========================================================103 // File: ppl_orange.png104 //==========================================================105 106 $this->imgdata_large[1][1]= 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 //==========================================================183 // File: ppl_pink.png184 //==========================================================185 186 $this->imgdata_large[2][1]= 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 //==========================================================264 // File: ppl_blue.png265 //==========================================================266 267 $this->imgdata_large[3][1]= 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 //==========================================================331 // File: ppl_green.png332 //==========================================================333 334 $this->imgdata_large[4][1]= 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 //==========================================================415 // File: pp_red.png416 //==========================================================417 418 $this->imgdata_small[0][1]= 419 420 421 422 423 424 425 426 427 428 429 430 431 //==========================================================432 // File: pp_orange.png433 //==========================================================434 435 $this->imgdata_small[1][1]= 436 437 438 439 440 441 442 443 444 445 446 447 448 //==========================================================449 // File: pp_pink.png450 //==========================================================451 452 $this->imgdata_small[2][1]= 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 //==========================================================468 // File: pp_blue.png469 //==========================================================470 471 $this->imgdata_small[3][1]= 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 //==========================================================498 // File: pp_green.png499 //==========================================================500 501 $this->imgdata_small[4][1]= 502 503 504 505 506 507 508 509 510 511 512 513 22 function __construct() { 23 24 // The anchor should be where the needle "hits" the paper 25 // (bottom left corner) 26 $this->anchor_x = 0; 27 $this->anchor_y = 1; 28 29 //========================================================== 30 // File: ppl_red.png 31 //========================================================== 32 $this->imgdata_large[0][0]= 2490 ; 33 $this->imgdata_large[0][1]= 34 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABm'. 35 'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'. 36 'B3RJTUUH0wMKBh4Ryh89CgAACUdJREFUeJy9mNtTFFcexz+/7p'. 37 '4Lw1wZJKDGCAwmDAqUySamcCq1ed6k9mn3UfMP7F+1T3nYqn2J'. 38 'lZdoDEjpbq0KG8EBFBFBEJye6Zmenkv32Ydu5GYiUMmeqq6uqT'. 39 '6Xz3zP73aOcIKmAQkIFyD3N/jrBPwlKjLQEglVlJKyUjR3u7cc'. 40 'WLoP3/4dvv03LNrQ8I6x1rFbDML9kOmHvh7IRHU9JKmUSG8vpF'. 41 'IoXX/TV0AiEM5A5jT0noFMFMJHXUt/d5f9TUAbhtQ3cPFruDog'. 42 '8klHMnmO0dGYe/myOJGINEwTz3F2higFXgy8PpAkOC+h8hoaCt'. 43 '4ppHFcQAWSgOQlyI/p+lUjmRxWAwNJd3xca/f34yoFi4tgmjtD'. 44 'NIFkJ4xcgBCgVqEBFJ9DqcZea/gNAAVEg7AOGYnHe9XoaJd3+X'. 45 'LISSSwnz6lsbKCZ9sHh4UVdBkwdA6cPwNnIfJPmC3Ctgft3wwQ'. 46 'QPkvTZJJnbExzfvsM2nMzVG7e5fG48d4lnXwTwEYCjJxuHQBog'. 47 'BHUfKkgAIIhiGk06hTp/Dm5qS1uYlXLvtWd4gPgIiCrAEcVckT'. 48 'Ab5p7TaYJrK1hQaEenrwSiVfQdc91P0kSp7Ii89D5ksY/kAkLy'. 49 'IZXFdXkQjS1YUSEbdcRu168V6+HTUNIKJDRwdE+sBIQmP9Ld59'. 50 'bEBA3of4F/D+uXb7rGaaCSmXI3pPj64PDaHCYfEqFVSjgWo2D2'. 51 '73XlJNQTgCyQykIuBWoNKEeh1aLXBPBCggGdBOgxZVSjoajVhH'. 52 'o5HWlIpq4bCQSgm9vXhK4ZZKh5SUYygp4J1EQVUD9xlU18BJQD'. 53 'bUbJ5T5XJStyxN9fSI099P3baxV1dRloW2h2ivx/yakg2ot6F1'. 54 'EkCa4G1D+zVEq5ArKTWM42Q6HUczQV7U66w9e0ZpdRXlOIQ5vF'. 55 'VHUXILKify4jiEzkOqC3peQMoBQymFlMt4Dx6wUSxSsm2UZXEK'. 56 'P30QvOUt8/2Sd78CdWwFDTA+gsw3cOlPcPUD+CQB52oQ21RKXM'. 57 'eRhGXhOg7VoKrx8KuS4ygZhVg3ZI8FGIfwR9BVgAtfwxdXdP3L'. 58 '86nUR91dXelNXTeWWy10paQHX602YAP1ADASAL7LJvFtMpOCc0'. 59 'cG3FHuGlz6Gr4YEpnoTCbzsdHRbOzy5RCRiLRMk5rjyOtAimwA'. 60 'U4U3SurBN/0wnAASBCVDIKpB4kiAB5Ub0/UvO9LpPAMDGfn005'. 61 'AxPCzxep3Q6iqPLUseBoufCZRsAE6g5g5kKIDfKUj3wnpAG8QB'. 62 '/Z1OIqANQuI65AtwNScyYXR2XlAXL2YZHzcklRKWl5GVFXFtGx'. 63 'MoAiV/EQaAGH6BUQNWgQpwFngv+Ca8KUAQEBcwgTJHyMV7679R'. 64 'XS8YqdSI6u/PMD5ukMtJY3GR2uQkr5aXeWVZOEALmA8WsIAxfL'. 65 'd0goVLAdCOd+/YpgqeVtBv4yiA++q/RKKXixe7GB8PSyoljcVF'. 66 'yg8fyubyMpulEk2lyAIfAAvAC+B+oOQFoAt/+0rAejB/EzjNri'. 67 'vvqNnCd64jxcE39V8spnP+vMbAgDSePKE2NcXm06dslMuUlcID'. 68 'TuFvqwXMBU8N39bGgRR+ki0Dz4L5DSAe9NGD7zq+6kcN1L6H2b'. 69 'ao5WWaQHllRTafPmWrVMJUimoAQrBYJFjQwre7B6A8YAi8LCgD'. 70 '5DVo6/hbb/iHK1KggvFeD3hHziQKEMuiNTNDbXGRTdtmw7Iwla'. 71 'KGH0oqwbscLOoG46rAY6AOzRhY74PT6QuUKEN4PegXxd/yEDTT'. 72 'YMWOk+oEaLkuFdNk0zTZwjfkavDUArXWgGXgFb4dEShXhfYqlI'. 73 'ow3w9rg3B6ED60IOOA5oEYQBrcpG+mj9bg0VG8GMJhVDZLyzAo'. 74 'VSq8rFYxXXefcjVgG9+uisDrXUCApoKSBcUHMBmHhfcgNwhtD3'. 75 'q9IG6Lr15b4OUTmPwBJt8JqGuapp05o0mhoHnptLQfPsR+8IBK'. 76 'uYyNH3yr+B77LHheA3tK1Ta+IrMeTL2C6Xl48TOsNWDDgAz7s5'. 77 '/r+krP/eddCsbj8fDQ4GBm9MqVvvRXX2VULBayRGRzaYn1SoWa'. 78 'UjgB4PIB5QK4ZgBXBKaAHxQsrED1H7CRgCUPwgHZDqACmhWwXv'. 79 '2aDRqGYeRyufS169cvThQKV88PDuYbW1vJ5VRK+5euqxWlPMdX'. 80 'SRqgreHbZGN3ijfKBXBTAeh2Fdwi2MofshP/dvKwCmKhp4m83Y'. 81 'vj8Xg4l8tlCoXC0MTExMTFkZE/1m37wvLGRvKRacoD1209E7Fc'. 82 'pZwYREOQqEJ4z3HskHLsz4AoXykPIBSN0t3dTTQafROoHdumXC'. 83 '4fjoMiog0ODiauX7+eLxQKV3O53ETdti88nJnJ3rl505ifmWm3'. 84 'arWSodR8GNbycDoNHy5C5jFold1k8d+DyvELNwg93d18/vnn9P'. 85 'X1oes6nufx/Plz7t+/fxhQKSWJRCI5NjaWHxkZKdj1+sjSwkJm'. 86 '+uZN/dZ337VqCwullGUVdZjsgIUC5LqhrUPvCugWuApeApPAzY'. 87 'PKHWyaphGNRunt7WVwcBARwfM8Ojo6sCzrMKBhGLphGFEF2Wq1'. 88 '2jc7M5OZ/vHH0MPbt93awkJJmeZsC6ZaMK3DCwvWdNioQUb5B6'. 89 'AdBR+9SzkAz/NwHIeXL18iIui6TjgcJplMMjY2th8wHo+Hh4aG'. 90 'MsPDw6fddru7+Phxx51bt/RbN260qwsLpZhlFZsw9QJ+2Pbrga'. 91 'oJG2FY2oKwuTtVEz9uV34NbqdtbW0xPT1NNBoF4MyZM1y5coWu'. 92 'rq5dQBHRcrlc4tq1a/l8Pj9RMs38ndu3Ez//9JNXLRZNyuXZJk'. 93 'xVYKoExQpsK/+IaAuYb7no8zjC/R+A4zisrq7u+53NZjl16tQ+'. 94 'QIlEIslsNpuPRCJXZ2dnh2/duNFRW1oy07a96MKd575yxRqU1B'. 95 '5vPMpF5HHa1tYW9+7do7Ozc/eQpZTSQ6FQt1Lq8pMnT/5w7969'. 96 'nuLcXE1rNufO9fRMhlKpOyvt9qPtVmvb25fFfvvWbrepVCqHwo'. 97 'xaX19vff/996ZhGC8qlkW9Wt1Onz073fXxxz+6MB+9e9dUjuO+'. 98 '7ebq9wLdB9hoNCrr6+s/4wf3FCJW3fPmTZhXsNWCprjuW66Dfr'. 99 '928KAfBhJAEgiJSLuzs7OSTqctoFkqlZRt26j/I+L/AGjPTN4d'. 100 'Nqn4AAAAAElFTkSuQmCC' ; 101 102 //========================================================== 103 // File: ppl_orange.png 104 //========================================================== 105 $this->imgdata_large[1][0]= 2753 ; 106 $this->imgdata_large[1][1]= 107 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABm'. 108 'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'. 109 'B3RJTUUH0wMLFQ0VCkHCzQAACk5JREFUeJytmGtzG0d2hp8zNw'. 110 'AEcRdJ6EJK9FL0CqZUm9jWbkwq3vhDstl8dmLvz8rP2H8Q75ZT'. 111 'pkRfpLgqsS6WIFEKGYkiSBCDO+banQ8DUpRWEkklXQUUqlCDfv'. 112 'rp857pgfAOQ4AMOJdg4R/hX96Hf06bvDc5iT07i8yeg8ksiIAI'. 113 '4TBi/ds9/vivD/njapNHvRBfHXMu410AM+BUoVSF05NQsi1sO4'. 114 '8402AXwLQTuP31OAZO2aG0MEn14iSlnI1z3LnMk8IZYJyBwjIs'. 115 '/TWsVIWPJkvMFS4zMfMhUp5BsoCpAAEBLYKaMFGn00jBxnvu02'. 116 '35+JHmSJEnBpQEcPo38MmCxd/nS9Ry71Ga/g1W9a8gn0GsHkgA'. 117 '6DGjxkqb5CoO+YxF3A3p+jGjQUzoK+L/V0ADzFMwtSR8eLbAr8'. 118 'uXOTf9NzhTc0geSLUQcYHgYEH786RMg0zWJHV2Aitv4x/HpHVS'. 119 'QA2YBqTTGIUq5qkPMWaWkVwPnPtAA/BevmZcjxaaUtHh8pJJGu'. 120 'DpCB9FvT7A7YT7S3p5vFMNzmWo/O0MSx/Ms3TqI8r59zFTfUQe'. 121 'I7SBODE3tnfoIxYnNHligwik0zAzDdVpyKbA8sff5YAeMEwgkV'. 122 'cufQeTJzZoCsaFLKXPTnNpoUTNsSgJmNoGsuNQjIDwYD2HlnZy'. 123 'k++yxTKXZfKTU8zOpjhneeQYkorSmGERtIlICBKRbLX+y98YN3'. 124 'ADcNIm+bJD4U3pPnmbEaRgYVRTGBkDSSsmxKfY7ZLuDJA4hdjl'. 125 'JEgyBB2SJOvQ9RzTpNKoEwNq0CNFvOXR3/HxMgYVPObaz8kPmh'. 126 'hkEWMatAfRONGGvLizyOE9P8KkpwhPDAgQKJQbELUD0oOIhbbH'. 127 'JeVTmowxjAgZutB5AoOngA+2DdYrcTyOyYZP9+QpBvI29vwEhb'. 128 'It042BVQgDy9KTMfkwQG1A9ACCLlgBBGUwxxoc52WDh2ATyEPp'. 129 '1hoaPvrEBh0Dq5an9OUsl/9hylk5b5c+mowLc4E2Jtw4Eoljyf'. 130 'ogA/AGEAagNRjGyUxOmEycyVA5EWDBxrmUp3ytLIv/NJP69Goh'. 131 '+9mFydIvS5PZYkvH1oY/RFtKymlwBFQAgQd+kAA6qSQ8pvn2mp'. 132 'SkJkuVFHPHBnQMrEt5Sl+e4/Lvp51PF1PF5Xy6WMvOWZXMom8z'. 133 'OZTQ8+j5sbQiMEwopsCIwRtBGIJSCdzbTGo9NimkDcgdC7Bg49'. 134 'TG5n4/nfr0Si77WdYp1YzyZEkWPdteaEnB7pPqBTxuIf/VgciE'. 135 'SgasCPwh+GNIkaNNag1RiPge5pEhMQVjfoLcF+eoXSvbKxedwn'. 136 'LKzC3KWbOi5/sW5a44/SHFUSgVA7SCzRG0AvA9mPOgFIETgu4n'. 137 'Ww0wNQWFAqRSL6D2ZQYBdDrQ7R7jXiwgRcvIL02makuTmWtpM/'. 138 '+BlLMl5vuWzLVEuwH6oYnR1KS8kJINGXMM2YdfRlALoQoQQKeb'. 139 'bDVwoMdxQMaLCwLo96HZTF5HbrEhmOftianfZisfzueKv7ZmrX'. 140 'MsjhxKXZGBjzyeEHmSE3oWiggtyVGmE8DTIXTC5NxgAxOAGUM8'. 141 'fun9mnSSLQ/CxNzOTgJ3LIMgoGwkKBiiMyaVviHVkdCO4FEKNv'. 142 'LQzWBYHfITPa4UBVM0LR/WB7ARJsdDDTjA6deYFIFUOimJ3d0E'. 143 'sNdLavYYgBpthqKcjiiJRO8K6CK0CsJTjfQAGaJtD9vQFAxNNQ'. 144 '1FB0yBAfA8gdMAIagLoCVAen0M00zMOTYShNDtoHs9CAIUoI4E'. 145 '1IBihCdNhsMhsj6NuV7BCC2IBpBqQaaFOENCCeiEsO1BO4RQgy'. 146 'I5Hm4k4oIU9MrgZSAdBeTabZz+ODxKQRRBFBJo6IUc51anYRQo'. 147 'dto+24FNxYCiaWKkQsj00KkO4gxRRkAngJ868M0u3OkkM+hxQA'. 148 'cQ7YD7GO5XYSsPZybh/TCkFIYY+kWniTW4Q7jXgHvHMhiRpmuW'. 149 'ca08GZkkZ/nY6TZMNhCnf2CuPoDVJvxpB+q9BHA8Ag1uH+oP4c'. 150 'YEPCzDwmzSLquShHW/E0YRbG/BjZtw40hAy7aNzJlzRn75E6N0'. 151 'qiwTzafI7kOU3gWrhzZC2iHcbsPqLlxvJnCt4KC1RYAL3I5hzY'. 152 'Xv/huePYCtITQMKEnyB4KQvMURuJvw889HGSwUCs7CwkLpo6tX'. 153 'Ty/+7nel6VLGDn/8N9m+eZuo1UP8iNhLau6b3RfmOsHBGTUYw9'. 154 'WBNeDrGB4+h/4qNLKwTnLbHj9CJw/6GoIh9Jpvq0HHcayFhYXi'. 155 'l3/4w9LK8vLKexfma3G/mb/3n1njTivS7tNQaaU1grQDjJ868D'. 156 'Axx6vmxnBrY9C9IcSbSXbavNjb/S3eN6/0m1JcKBScixcvllZW'. 157 'Vi6uLC8v12q1v/M8b/HxVjP//YYr32yE4dYWvShO0ogi14xwxq'. 158 'F4rbnxZ3cMjtpvEEeMvwA0TdOYn5/PffHFF7Vr166tvPeLXyx7'. 159 'nrd4+/btyg/frFo//Xgncnd67qCn78earQqcmYD3fSi1wPCTSV'. 160 '3gzqvm9uFOMl5nUAqFQn5paal26dKla57vf7D+6FHph9VV88af'. 161 'vgq79bo70e3VT2l9A3hYg4UiRALVHTCHSZvYBm4A//6quf8zoG'. 162 '3bpuM4acMwKr1+//SDe/dK31+/bv90/Xrcq9fduNW6rbVeC+E7'. 163 'gWdD2DKg4UEpBmPcm10RuScida31ntb62HAigoigDw6Gh0axWH'. 164 'QWFhZKi4uLZ+I4PrVer2e+u37dXPvqq6hbr7tOp1NXWq89h6/b'. 165 '8FBB34WGBesdcPrj38lkMkGlUuml0+mu53nR3t4eo9HoSLhMJk'. 166 'OlUiGdTuN5Hq7rvgA0TdO4cOFC7vPPP6/VarXldqdTu7m2lrv7'. 167 '7beq++BBO263b/tKrfWSXlbvwJ6CuAtDgTYiaBFMw6BSqfDxxx'. 168 '+rarWqGo0GN2/eZGtrC6XenAkRoVKpcPXqVWZmZmg0Gty6desF'. 169 'oIhIOp3Ol8vlmmVZK3fv3Lm09uc/Zwbr653ccPgoNIzvnmn99Z'. 170 '7W9QG46lAaM5mM2l95GIYUi0VOnz7N7OwsWmsymQzyuse5Q8Mw'. 171 'DNLpNDMzM5w/f/7A6AGgUkoajYa9urpayOXzUz/fvZutr68Pim'. 172 'F4/2y1+n2o9Q/ru7uPesPhXnyo4A+vfHp6mmazybNnz9jZ2UFr'. 173 'TbPZJAhe+8/aS0Mphed5NBoNABqNBqPR6MWBVWstvu/nnj9/Pv'. 174 'vo0aPq5uZmPBgM/qcwPf39xV/9ajU1M3Nvq9PZaw8GoT50PjdN'. 175 'k6mpKa5cucL58+eJ45j19XWePHnCzs4OnudhmiaWZRGGIVH05r'. 176 'yEYYjrumxubrKxsfFyDQJ6NBp1Pc+7C4jWumBaVm+kVL2l1H2l'. 177 '1G6otS+H6V6z8u3tbVzXpdFooJRicXGRqakptre3uXXr1ltrcT'. 178 'Qa8ezZszemWAE9rfUdYBOwtVLRbrPZ+48ff+wDvuu6Sr3MB4Dr'. 179 'uty6desgfa1WC3iRyrNnz4pSSmezWUzTfGtYtNYcdvC/9sMlgP'. 180 'n5N4cAAAAASUVORK5CYII=' ; 181 182 //========================================================== 183 // File: ppl_pink.png 184 //========================================================== 185 $this->imgdata_large[2][0]= 2779 ; 186 $this->imgdata_large[2][1]= 187 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABm'. 188 'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'. 189 'B3RJTUUH0wMLFQolY9lkpgAACmhJREFUeJy9mOtzFNl5h5+3b9'. 190 'Mz0kzPBWmEVtIiWYhIiC0HCDhB8lb8ISk7nzdZ5+/zJ/8BTmpT'. 191 '660CZLwG1pVFgBkgGIHECEaa+/T9nHzQCCQuRpCNz6mp6g893U'. 192 '8/c37ve3qEjxiC4OA4n/Lp/EUu/tsMM/+aEWduVBx7WhdkShcY'. 193 'xUH2zo0Dwod/5N6vf8V//PoGdx8M8EOFPtK9jI8BdHCcMuVSmf'. 194 'LxHLmSZdm2U8xIbmKETDGDZZnIy4dBbCynyGhphurEDBOlHFnn'. 195 'qPcyPxTOwDCOccw7w5nlBRZWylI+ny/mZ6rL1dzUZ5/IWGZU3D'. 196 'ZIOMQDDaJcHDVGWUbJBi9odVr0QoVSPzigIEaZ8vgSS/8wZU3/'. 197 'k1fylipz5dLM2WlrZqHKaGCKbEbontq3KAKWQyZfZKTgYqc9Bp'. 198 '2I2PcJ4ogk/UEBQcwipbFZmT13vDBx8fhnE1Ofnp9yJopFyT3X'. 199 'yANfks0QHSQMDaL37pOxMLIu2UyVkjVKLjyKSeuD8dAYCFkso1'. 200 'gYMaeWJ40T56cl8yAi/O4FSa2P6kYczIDsgVpAqcDImZPMuAB1'. 201 'dkLQtcc8a/bwox8IUHAxZVxGZMouSLVYwKuMkD5IxN+JSdsRJB'. 202 'pexuTVgYYM6EoGmxkmg3/hEhNUMr/hd7dqbOzExMn/GRDAxWZc'. 203 'j3I8HiXfMjF2FQowKw7pjoN6E/Llw/GBJj8qxVOMlX4ipxc/lY'. 204 'kl2zBLkmrTcEzMkoNoRLVidLi/9g+Z3I+1xRHX5EcAihxnbPRv'. 205 'OTU9kZSmpKPy9FTGrLimPZ1H+UiyGaF67w6n7E1DwMngFDxGvc'. 206 'w70v0xZUby5IxjlIyMssUJrJwVWkXBdbXvSvwEibcSdKCAFI16'. 207 '4/sc0SRo9cGAGq1DwvQFzV6DVuBiV4zYnlEts6A2TSPcSiXoxo'. 208 'QqJCEEFMbQ2b69o5qMiOOPqIMQkagu/aSL7waE8101WFShLjk9'. 209 'yxgEvjRUiyYd+gwAjY2J9VpXfZ/JEXLhDp3OR6U4T97+hEnPwx'. 210 'tv4HsRjy2tTQSFzQgDUnwSLBQRI+x1ZgcH87Vcv4SF19Kt0ezS'. 211 '1h9s0Ma25pgr/YJfnLnEysok0+ezjM6EBLldGqKIJYuDRhOQEJ'. 212 'Oih8X9Q0xmcXNjlCofBJgn78wxVz7L2YWf8tPPz1hnfjbjzfxN'. 213 'qVwutq2etZXUQSXikcXGIgUiUkJSDIQMJgYGJsaB3c7b1qQ4GZ'. 214 'xSkdGZIwMeNLfK6uezMnvJK3pLxeVixfvMsyVjSNSO6IV9adPG'. 215 'AArkEEz8oUkFmBjYGO80qfd6pCWIayD59wIKcsjcKqufn7JO/S'. 216 'xfyi+5c24pey5rZ09mJRNkiDdT/tzbkBr3SYkpMYpgEaIJSYhI'. 217 'kSOY1GhilAQk5ntDIojxCZ/kf87Pl85xbuWEnLiUy+cW3NNuJX'. 218 'MmY5meKf6mT7wZS+THdOjxlG06tIlIOMZxchSxcFFEGAwAGGME'. 219 'jwyZYSnWL3cXWiIUbUI6hO/vxXuFOV84ycmlBWthNeflTjuzTi'. 220 'lzJmM5s46Ej0J63/ZoPmoy6PYxtYVNhmfs0mbAND1mmKVMBY1L'. 221 'mxA1LN7WgXQbCApNhKJHRIM+DQbv7yQGhjnJ5NgFuXBuxpu5mD'. 222 'udm3LPuY7pmZLUE6L1SIJaIPFuDAqyw9lnwDYv6NFHkWJh4ZDB'. 223 'wCBFD3uMxsTAwcBAiElpE/KcPg36dIiOvpsRxDCyhmlP2YY9ZU'. 224 'v8NMb/1id+FGO0DTztkSXLOONUqeITsMkW2zwnJEIDFhYGx+A1'. 225 'kwK4mASkvKDPc3p0iYhRRwYUhZLUTyV6Eu0t4s1Y4kcx6W6KaM'. 226 'EZThcXH59RRhGEgIAddnBwNEBKqqpUtWBIF22YDIhJsbEkJqFN'. 227 'qLtERHs7GnUkwISEQAf0uj30bY39PzbiC6qrDu2cExJ69Nhhhz'. 228 '59UlIUipCQOnVi4sjG7ubJBy6um0C+he/0iDHQKIQERYyKFLqr'. 229 'SI/W6kJCnvOcrWSLSquC1/Jw9Ks3R0FQKHr0uMc9bnCDGjX69A'. 230 'H0XlcJkibN5jOe/alCZStHbjJL9lSMLkXExvCXRiDV6GZEeGeX'. 231 '3TvvBVQoEjfBL/v0rT75Th7VU5C8gktI6NLlMY+5yU3WWGODDf'. 232 'r098tHpNFNH7/2lKdXXdz7efLzVaqJIBOCmK8AJUlI6g0aV+9y'. 233 '9+p7AR3bMQpTBWPy7yeN6fy0jNwewfpvC9Xe+3kFoUuXe9zj5n'. 234 'BusEGHjh6GIAGawC2FWuvSvbbF1maFylZAsC1ISZADBiVNSJrP'. 235 'eX73MY//skHP85z5+fnSxQsXj//4n39cmnPn7LbZlsajBmEnBL'. 236 '1nuEGDG9x4aa5Ldz+h0RCuBqwBv1Wo+7vs9r7n++0MmYeAM+zB'. 237 '+61EK1QUEnbbtN+9Bh3Hsebn54u//PdfLq9eWl2ZnZ1dSnaSwu'. 238 'Pin40b9g3doKE0WoNIl65xj3v75njd3BBubQi6ExKmDWkMRKSl'. 239 'tSbVKQcMao1Go5Ugb0+x53nOyZMnSysrKydXLq1cWlxa/McgCB'. 240 'Yev3hU+GPrD3I5/q94k3pXYQY58q6B5Bs0HB//neaGx00gyWaz'. 241 'VCoV7bquCoKAnZ0dfN/f03egLGj0m3XQNE1jdnY2/+WXXy6trq'. 242 '6uzP3oR5eCIFi4detW5feXL1vr679Let37zVB3/mQytjXJwmSB'. 243 'wikHp9ShY0RESqObwPrr5oBERKhUKly4cIFqtUq9XufmzZtsbW'. 244 '2hXvuDwTTNtxZq8TyvsLy8vLS4uLgahOHphw8elL69fNlc++qr'. 245 'uFOrNXPddm1cczVL5f5P+Lv5MuOJgTGxwYbZpZsCdeAq8M1Bcw'. 246 'CGYeC6LtVqlRMnTjAyMkKn0yGXyx0N0LZt03Ec1zCMSrfXO37v'. 247 'zp3S769csb+/ciXt1mrNdHf3ltZ6Lca8ZpJsduhtCdb2gEFJoQ'. 248 'xADYHuHDS3f32lFEEQUK/XGRkZoVAocP78eZaXl9FaI/Jq25Uk'. 249 'yWHAYrHozM/PlxYWFibTND32sFbLXrtyxVz76qukXas1M61WTW'. 250 'm99gx+20TdN9jqtfjP7QzOwwYNp037Zd0DukDnIByA1pqdnR2+'. 251 '++472u02Z8+eZWJiAsMwDsEBRNGBzYJpmsaJEyfyX3zxxdLS0t'. 252 'KlVqu1dP3q1cLta9ekU6u1dat1J9b6Sk9kraV1rYXegW7apDYw'. 253 'kFY6fPc4MNTw88bwfZ/NzU2UUnieRxAEiAiGcXiXfcigiIjruo'. 254 'VyubxkWdbK7fX1xWvffFMInjzBM82uMT5+p++6V1UUrSe7u03t'. 255 '+8lezlKt3gHyl0aSJDQaDa5fv876+vo+w6FzDq1BpZRsb2/bly'. 256 '9f9vL5/Njdu3fzG0+eMJHNxsfn532vXN5NPG/7abPZal6/Hvfe'. 257 'kroPHfsm98f7AHW9Xo+//vrrlmVZm71+37QNw3JnZ9PK4uJGpV'. 258 'pt4Dh+vLGhsrmcfv1iHzu01m89HjIdCon2fb8TBMHtvYeRUn50'. 259 '1Oj4vqp3Ok1f5LYSadfr9dQfDN642P/XeF2DA+SBAuA4jkOhUK'. 260 'BQKESO43S11p3BYBDt7u4y+CtB/i/q7jp1GMiw2AAAAABJRU5E'. 261 'rkJggg==' ; 262 263 //========================================================== 264 // File: ppl_blue.png 265 //========================================================== 266 $this->imgdata_large[3][0]= 2284 ; 267 $this->imgdata_large[3][1]= 268 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABm'. 269 'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'. 270 'B3RJTUUH0wMLFRAiTZAL3gAACHlJREFUeJy9mGtv29YZgJ9zKF'. 271 'F3y/Q9jh05tuQkarKgbYasde0UBdZgwNou/Vqga/sD9mP2B4a1'. 272 'BbZ9atFPxb5sqOtmXbI19bqsluPYiR3HN90vFEWRZx/IJI5zqa'. 273 'x0OwBBSgR5Hj7v+55zSEFXTUgIJyA9C6/9RsjMjAyFIxxJCDc7'. 274 'iBqKgyZACGg3G2x9+xXf/fG33P3mC9qNKsp1O+1JdkEnQTdgIO'. 275 'ttCSMUi8gj072MnugllAyB9G8rBGi6RsToJTF6iuRoFi1kHKZf'. 276 '7fB8Iggj0/Dy23D2dakNTR3JDsXPvzstxmZGRMER1EwHhQAEgE'. 277 'CLhIkPD6InY9S3djGLJVBtQP1Qb4HDAyoJYQOOZkPx49nhTH9i'. 278 '7MUBGT7egxkJgd70wZS/CUkoZtA/fRoE1DZ2ACiv52ibReCp4e'. 279 '7CIEHomxDiuVdGTqUnf/ZeOjR8fpiVXZul5ZrY3bWwbdcLr/dA'. 280 'AAIpAwQjUWIjQ+g9HZvswiCgBVF9/SI6OSLGzo0i+oLi6+Utbq'. 281 '+bKEftgwOE/0Ohocf66M+cBjo22U2RQLIHMhmYnvaOpR9S8bSU'. 282 'UqCURGpRkuMZMm9cIvPGJZLj0yBjT2LprkiSkykx9cuXIhOnUs'. 283 'm+QNC2XdG02ggBTcvFabsPWwTPpBAChSCgh4kYBpoeplWp47Qs'. 284 '7EYDt21xINzd5GCAxLExRl89Z+nHjpbKMmjbmkgfDzI0JEW53K'. 285 'Jaa6NcAOEX8v52uJzsBlAS6u0hcnTIccPRqhWPCUcLD+s1EaUp'. 286 'HCEhEMCyHNpt9SjgIU12A6iw6xb123vYhaaKjB9tlgMD5X+uBp'. 287 'zdkpg6azA8EaNQtKlVba+Xez4eCntnJrsDdFsW5nYFpxlFN846'. 288 'DXe8utkM4mhi+EgQmjYbS2WqexZKk6BpjwJ2YlK5VjeA3pNDiH'. 289 'YjRWPzPE7tmBo8EWwGhkXx+z3uXL7D3rU97LIF8RBEAl6lK/Uo'. 290 '6JNM1rZ2aTcr3eUgIQOGTgbdwXMGyRejenLYTvQGbAdRuetSud'. 291 'OivVuFZgtCEgICghICnZoMhmlVTPR49LCAEkQUhk/B7KXe0MWf'. 292 'nxj8xVR/cDheK14WZmtVMJSBnlGoN6FmQq0FLfdwJgORKPHRo/'. 293 'Snzx4G0F/FjJ4KiOdmjPCrrx8bffnMybMv9MQGNG3rzlVqtR1B'. 294 'sh/CYXCD4Aag1oCW7ZnUOjSp6WFi/QNEB8Y7BfTNjZyCmUvJ0I'. 295 'XXT47MTp98Ybon9VZCk8cVazfqlNargsY34G7ByAlIjkHd9CCr'. 296 'LbBdiHViUgiECuDKYCdz8b2cywREdiYZOj8zNnLuzOTzx6ODp+'. 297 'OaGaqwVzBFqz0Idhz2loE7YEwBLaAJLQcKbW8qjAcBF5Jh0AMP'. 298 'IOHe6kxgtb3UMO2OxkF//ffK28nQqxfvm3szrtnDVa799Qb/+v'. 299 'NtsbNSpm3tAv8B+w7Ub0FhAyoBcMPec9oK6raXk48ziQBXQcmC'. 300 'pT3YqHa0mpEBkTR6wz/Jjo2cy04+fzwxdDquNfQKO7sFUbpu0c'. 301 'wp3JoAYsA42Bbkl4GCryUNDEM7Avm6Z/CgSYBWG8pNuFuDu1Wo'. 302 'tjoxKIJGeHIiM/jmK9NnX5ycuJQMtUcqXPvLDTa+qIie4hAJ1U'. 303 'vdrmO2HaDfB931twJgAn1A4lGT96obPHPLBbhVgUoTHHWo9aAA'. 304 'JVAKpyKEmQNzWRENAsL18ycKjAFN/9gCNvzLB/390MMmE7pnDi'. 305 'Bvwt0K5Jv3O+0oB22nJ1Vvjb/UMhOpcKknqN1OiMB2DNHU2G5s'. 306 'sVndpGJVcZXjX1IAlvw9PmhRQcOFPhsSDkiBrQR1G7brgs0a7D'. 307 'ag3FK4rguqBXarI4Nt1SJv5gls7TEWtJDRBO2GwnIs8maevFnA'. 308 'Gx6awLZvzeTBu4kFbLigijC47pscpx0xyDfkvtUEnlarCDtrUC'. 309 't2HGIhvPHVdVwqjTIrxRU2a5uUrYoP0QZ2gMvACl7+3V/LuKDq'. 310 'sJuDy597516+CEezIHXv7vcgXQu2l+Bvn8He9Y4AE4kgk5P9DE'. 311 'R6aFdq5Et5Nit3yTf3m9sBcsAN3+D98c0Fit5JawE25r1zg1Fo'. 312 '5B8GFD7g+nVYnu8EUEop9XTa0N/9dUbqcphP/rDJzbUClVbpgR'. 313 'y2fXM3fND95qj75J8AC6BWPINfVSBieK+x+6cS5UCzCLu3oFV9'. 314 'GqCMx2NGOp2Znpv7aXZudsool3T5J/179sxVlHJ4kGPrP2COBX'. 315 '/7DmiApWCjxIMXpYNznYuXM+6TAKWUMppOZzLvv//ery5cuDCT'. 316 'SqVS336bCwr1JfAPB9r+2KAFwJS+OcETzZHz/7v3etl6ipz77X'. 317 'GAMh6PG+l0OjM3NzczOzs3k0pNnFlbW43+e/GKtMqrblSsF03V'. 318 'WHcJA0PjIAzvg9JTze2H67g9DjAwOTmZ+uCDD96anZ2dnZiYmF'. 319 '5dW41++Lvfa1fnr7qllVK9103mXNTnJgPA+YugsvB3HTaEl+Qs'. 320 'AZ/yeHPPDCiTyaRx5syZbGoilV1dW00szC9oV+avusuLy0Xd0X'. 321 'MgFkDM+zkYBZEHV8f7wwKu84zmngQoNU0LaZoWUa4K31y5qX/8'. 322 '4cfyyvwVN5/L10NOKNeg8UmDxoKF5Vfj1xXAgD0JrgAcvBDfel'. 323 'a4g4AykUgY6XR6emJiIru2ttZXq9S0K19eUcuLy8WQE8o5OAsN'. 324 'Ggsmpl+NpoL1g9X4UBU+C9xDgEKIwNTUVOqdd955M9mbnJ3/cj'. 325 '6Vu5aTheXCQXNdVeMzAwJSCGEA2XKpnF1cXIzlFnOVhJPIKdR+'. 326 'c88ctq4AlVKsrKzw0UcfKcC5uXqzXnNqSzb2pwLxOHP/l7Z/BN'. 327 'eB01LKt4HTrusKvGr8jB+hGn8MQAkYQMrfw4Nq/MFPtf+rdvDb'. 328 'k8QL+/5Z4Uepxm7bfwHuTAVUWpWaqAAAAABJRU5ErkJggg==' ; 329 330 //========================================================== 331 // File: ppl_green.png 332 //========================================================== 333 $this->imgdata_large[4][0]= 2854 ; 334 $this->imgdata_large[4][1]= 335 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABm'. 336 'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'. 337 'B3RJTUUH0wMLFQ4hANhluwAACrNJREFUeJytmF1zE1eagJ+3u9'. 338 'XdkvUty2AbmLEtEzDBgZ0UpDBOalNTUzU3czl7tct/2n+wt3M/'. 339 'NVM12SSTQQSyW2TA+QAJQogtYYFtyfrqL3WfvWj5g8AEjzfvhS'. 340 'SXjk8//Zz3Pf3qCMcJAWxMKlT4kH+jwu/FknnJSUItKFHzCrKA'. 341 'BggBQx5ziz/wn/yBz3hED4/oaJfSjgVoYjJJgTLTZCjohp7IGT'. 342 'k5aZ4kb+bRTR30Q7djj8f/kpPMUSCFedRL6W8e8qMQNE6S4xpv'. 343 'c5HrTPFubiJ3ZnlyOXV59rJYU5Z00h1c3d0brxAiUkScRijisk'. 344 '6XLTyiN3s8HuAJpniXa/q8/pt8Or+0kF8oXJm5YiydWcIpOrJu'. 345 'rjOQwd54AQwsMpTJYhPSoYuLQ58An/DnBQSdImXO8avsTPbqpc'. 346 'lLp67OXDVzMznZLGxSs2qyIRu4at8gKHQEC50kE1icxqCAdxST'. 347 'xjEA44tqaJlERl8uLWvvnX5PHuQfcCdxh5qq0aX76vj4WgWyXO'. 348 'QiNgBP8IAaddr08X8+wHFmJSQhBbPAZGoSZSt5wQs6qoNC7UEd'. 349 '4AEoLIQSCaCCy78Dv8Tiv1hjjW1CRj8XIAgEKqDtt9keboMJZa'. 350 'vMjuzQVd3Xr9prTJo+GF/jKZea95R25Lxs8jg5qFGiwDnOS0mW'. 351 'NE0rjNRIt3WbklUCA9mV3Zdz8OBT/JfCQLB0SKYVVjGFYSfx/E'. 352 '26ow4e6uDujlPFQpE0FU6P8qNTHdXJdEdda0qf0itWBVM3pa/3'. 353 'ccUlIECJet0cAJoeYk5EZCeS5IwEoerSxccJBwRqFFf38QCTaO'. 354 'TRVFKJm3NTbtLNSyh2IkhIXsvLCesEGNCWdmwyruSD/z9kUlRc'. 355 '3bqNlSxhJNJ43p5JITrOEis8Qtr0cXEpU/JT/pmO18n2vb42pU'. 356 '3JnDnHMBqyPlpnoAaxhr2llv1ZUBqEGlqYwDQMsskMOcMgVL3Y'. 357 'ZOQTHAcQQiIGjHCwCaiovjrv4hbcpKuJJjIcDHm685RGr4GLCx'. 358 'YHkAcrLoAoDSLBiAQrMkjqybHJCbxgh+7xAC1MpsgzwRwD3qHL'. 359 'WyTIBdlAa6u2rHfXaew06PV78ZZjAwleNnkolECoH5i090wOcY'. 360 '+TgwYzFHiPi1zkOkXexeAMASnVU+LiyiA1wFUuaqggACLizeWw'. 361 'ycMzyssmVYKkbpGyC5T+OUALk2mKLHKWf+ED/az+YW42d66YL+'. 362 'aNrmEEzQCFEnKw368EgEvcN1m80eTIQIt0TFOjMJHkzNEBBYPp'. 363 'sblf8QHzrORO5JaWZ5ZLl6cuJyyxpNPv4PZdoT+GyIxBfI5uUg'. 364 'eJMCwP2/bIHO1JEudcgUUWOceKNq99mCvnzs5PzRcuTV4y5mRO'. 365 'SMIjo47z5S7a94oQCNKgJsZwO7D/IDNg3/LLhRNXt4JohBb4aG'. 366 '82GLdXcf93mQ+Y43r2RHZp+cRy6cqJK4l8MS+tdItaqiYtc0Mm'. 367 'QpfJARh98HYh9IiXVcaAo58wGb+LBAjbSPgCOcoSa0wzxXtc08'. 368 '/pv8mfyL+9MLVQvDJ1JVHJV6SZbFI1qtTsB+KlehRtRTGE8Afo'. 369 'P4DRcAxiEudhAHjjzz+ubgX4oHowakHQOlqzICQwyVPITGVOXi'. 370 'xfLF6aumzmczl5lHzMff2+fCdPaGttEkXoLQAO9B7C6EugPYby'. 371 'gVPjGXc5eIbNAJPjGwiAbaAJUQv8wVG7GROkJFpyOqn/ovgLba'. 372 '44L0+sDaraXb6jzq7aBQWjBOyUoHcaopOgmaA3IRyNDZnA1HjO'. 373 'HSBkr7eEFDAEngHrQCf+/s2A8cSiSkqcKUeeTjwFy2Jd78t3+L'. 374 'TR4itIiBLwLQhzkJyB5Cx4HXDaENVQCBAQcRqFIHTRaBIvuYXg'. 375 'AdsouuNxEL0ZUBHnSQp66R73zYfUtQ6OytKT8RckQAJQoLtgO5'. 376 'BJgj0D/WfgdyHaAHx8THoUcbGx8ciwhUl3bDEiToURPooeI7pH'. 377 'MziK9Yd9nU5a6GgKjOH41vsgI4hAcyC5AZkapF+AoYNrjjsuhx'. 378 'FbtPmeB5ykyQQzTPAWAQWC8S9oAI0QRRuPb9jkmyMZNAOTklvC'. 379 'GGYZaFkGmkVAh8h4DtKFMIBunG+pB5B5AIkGBDsQ+qBiL20caj'. 380 'zhJknq5KlgMkLjJHJos4kYEbFJi5vc5eYbATVN02bNWe19+32t'. 381 'aJWlFm3wbf8Rz5NbDFJdlOFBF/g7cBf0JkrbBb+F6j1DOduEkU'. 382 '8bWCOiSofPWadBnSZDWmgUkEMGhZCINut8S/0NBtPptFlZrBSu'. 383 'vnt1+ndnflfIp9OJ/279Ubbbd+lP7KBKPoEBsgnqLph/BRzwdS'. 384 'LnBUFvHcfdpRsGPAGqwMco6jynz+e0SPKYCHMfLX5VKHwcenR+'. 385 'Igd1XTcqlUr+xn/cePv91fevzy8sLO2OtrOpWkqL7gXKSAVRdh'. 386 'ZFEmEXoYkwBNqovoc/3GHH3aUR+jwC1oD/AWrANi4hGwyBzqEG'. 387 'Vvb77Dgi0eT1VZzJZMxKpVJYXV1dXF1dXVm6sPSvruue3Xzcyj'. 388 '6/syvDzwj0lNazK6Fj5LFCRZouZpBABj6jXouu3+Np6HNvDHaf'. 389 'g91t74msbMuOJicnSSaTKKUQEUQEpRSO69But1/dB0VEm5uby9'. 390 'y4cWNpdXX1+sLCworrume//PuXpeqnVeOban0U1PW2kcx+O9L7'. 391 'Te9sUB4lWFR9SqNtNGcHx+/RDD2+Am4D94CnQA8OjjlEhMnyJC'. 392 'srK8zOzu7BiYioMAzZ2Njg9u3brwIqpSSXy2WXl5eXLly4sOo4'. 393 'zoV6vV6oflrVP/7Tx8Hmw1Zb6ydqmpWp7ha8h4O3gjOhzVANmF'. 394 'XPMNQWvdDnCXCXuHR+APqH4fbCtm2mp6eZn59H13WJuYXRaKSU'. 395 'UiSTyVcBdV3XDcOwRaTU7/en19bWCn/79G+JL/76RbhZ22y7u+'. 396 '6ahl71nPDz/nO17m7wAxlabFOihy4+DvAcqAMbPzZ3OFzX5dmz'. 397 'Z2iahoiosUUVhiGNRgPHcV4GzGQy5uLiYuH8+fMzo9FoslarJW'. 398 '9+elP75E+fBJu1zY7qqpqBUW3T/niohnVvy+1zm5aVtp+WE2XT'. 399 'nrHFzbjh1tYLz3XdPjD4R3BKKba2tqhWq4dzUO3noBPn4H5PKy'. 400 'LaO++8U7hx48byhQsXVne7u6tf3/v64t3P7mbq9+odt+OuaWi3'. 401 'PLxbW2ytubjbQCgiMnt6VlaurWgz0zM0m02q1WrUaDSUUuqI56'. 402 'ivDxE5MCgiYllWtlwuL5mmufLV/a/O/uXPf9Ff1F+80Lv6Yx29'. 403 '2qHzyZBh3cdvc7gaTZuZkzPh/Py8ACqVSv1/uPZDKXUAGEWRtF'. 404 'qtxEcffZTL5XLF+2v39fqjeivshA/TpP83JLwzYFBzcA4370Cc'. 405 'S81nTRBUs9lkOByi1GuOPI4Rh3+26JZlnSkWi781DOPXvV4v3+'. 406 '/2G0R8kSBxB/jew+tERK+c49m2TblcxrZtXNfl+fPneJ6HZVmU'. 407 'y2VJJpNyaJ9TSinlOA5bW1u4rntkQA0oAG8D54gb9W3ianxM3A'. 408 'e/cn73U3Hq1Cm5du2aPjs7a+ztcSIShmE4ajQa6tatWzQajZ+0'. 409 'fbiKI+It4SvijVUj7kL2qvGfgkskEqTTaZmcnDROnTplJhIJTU'. 410 'QiwPd9P/Q8T6XTaQzDIAiCfzjP/wFVfszuFqdHXgAAAABJRU5E'. 411 'rkJggg==' ; 412 413 414 //========================================================== 415 // File: pp_red.png 416 //========================================================== 417 $this->imgdata_small[0][0]= 384 ; 418 $this->imgdata_small[0][1]= 419 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABm'. 420 'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsSAAALEgHS3X78AAAA'. 421 'B3RJTUUH0wMJFhouFobZrQAAAQ1JREFUeJyV1dFtwyAQBuD/og'. 422 'xQdYxa8gRY6hJ0jK6QdohMkTEuE5wUj5ERen05IoLvID7Jkn2G'. 423 'j8MgTMyMXqRlUQBYq9ydmaL2h1cwqD7l30t+L1iwlbYFRegY7I'. 424 'SHjkEifGg4ww3aBa/l4+9AhxWWr/dLhEunXUGHq6yGniw3QkOw'. 425 '3jJ7UBd82n/VVAlAtvsfp98lAj2sAJOhU4AeQ7DC1ubVBODWDJ'. 426 'TtCsEWa6u5M1NeFs1NzgdtuhHGtj+9Q2IDppQUAL6Cyrlz0gDN'. 427 'ohSMiJCt861672EiAhEhESG3woJ9V9OKTkwRKbdqz4cHmFLSFg'. 428 's69+LvAZKdeZ/n89uLnd2g0S+gjd5g8zzjH5Y/eLLi+NPEAAAA'. 429 'AElFTkSuQmCC' ; 430 431 //========================================================== 432 // File: pp_orange.png 433 //========================================================== 434 $this->imgdata_small[1][0]= 403 ; 435 $this->imgdata_small[1][1]= 436 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABm'. 437 'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsSAAALEgHS3X78AAAA'. 438 'B3RJTUUH0wMJFhwAnApz5AAAASBJREFUeJyN1dFthDAMBuDf7S'. 439 '3BCm2VCRKpS4QxbhikW6IewzcBqm6Fm6JyH7iEEByCn5AJH38g'. 440 'BBIRHNUzBAWAGNfe/SrUGv92CtNt309BrfFdMGPjvt9CD8Fyml'. 441 'ZZaDchRgA/59FDMD18pvNoNyHxMnUmgLmPHoJ+CqqfMaNAH22C'. 442 'fgqKRwR+GRpxGjXBEiuXDBWQhTK3plxijyWWvtKVS5KNG1xM8I'. 443 'OBr7geV1WupDqpmTAPKjCqLhxk/z0PImQmjKrAuI6vMXlhFroD'. 444 'vfdqITXWqg2YMSJEAFcReoag6UXU2DzPG8w5t09YYsAyLWvHrL'. 445 'HUy6D3XmvMAAhAay8kAJpBosX4vt0G4+4Jam6s6Rz1fgFG0ncA'. 446 'f3XfOQcA+Acv5IUSdQw9hgAAAABJRU5ErkJggg==' ; 447 448 //========================================================== 449 // File: pp_pink.png 450 //========================================================== 451 $this->imgdata_small[2][0]= 419 ; 452 $this->imgdata_small[2][1]= 453 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABm'. 454 'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsSAAALEgHS3X78AAAA'. 455 'B3RJTUUH0wMJFhsQzvz1RwAAATBJREFUeJyd1MFthDAQheF/oi'. 456 'gF+JYWQKICkCJRA1vGtrDbxFbhGvY0HVjCLeS2BeTiHFgTB2wg'. 457 'eRISstCnmcG2qCpbuXf3ADBQzWsPfZfS9y9HsEu4/Fo33Wf4Fx'. 458 'gxL3a1XkI3wbTNXHLoboVeLFUYDqObYBy+Fw/Uh9DdCmtOwIjF'. 459 'YvG76CZoOhNGRmpO8zz30CJoOhMAqlDxFzQLppgXj2XaNlP7FF'. 460 'GLL7ccMYCBgZERgCvXLBrfi2DEclmiKZwFY4tp6sW26bVfnede'. 461 'e5Hc5dC2bUgrXGKqWrwcXnNYDjmCrcCIiQgDcFYV05kQ8SXmnB'. 462 'NgPiVN06wrTDGAhz5EWY/FOccTk+cTnHM/YNu2YYllgFxCWuUM'. 463 'ikzGx+2Gc+4N+CoJW8n+5a2UKm2aBoBvGA6L7wfl8aoAAAAASU'. 464 'VORK5CYII=' ; 465 466 467 //========================================================== 468 // File: pp_blue.png 469 //========================================================== 470 $this->imgdata_small[3][0]= 883 ; 471 $this->imgdata_small[3][1]= 472 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAACi1'. 473 'BMVEX///8AAAAAADMAAGYAAJkAAMwAAP8zAAAzADMzAGYzAJkz'. 474 'AMwzAP9mAABmADNmAGZmAJlmAMxmAP+ZAACZADOZAGaZAJmZAM'. 475 'yZAP/MAADMADPMAGbMAJnMAMzMAP//AAD/ADP/AGb/AJn/AMz/'. 476 'AP8AMwAAMzMAM2YAM5kAM8wAM/8zMwAzMzMzM2YzM5kzM8wzM/'. 477 '9mMwBmMzNmM2ZmM5lmM8xmM/+ZMwCZMzOZM2aZM5mZM8yZM//M'. 478 'MwDMMzPMM2bMM5nMM8zMM///MwD/MzP/M2b/M5n/M8z/M/8AZg'. 479 'AAZjMAZmYAZpkAZswAZv8zZgAzZjMzZmYzZpkzZswzZv9mZgBm'. 480 'ZjNmZmZmZplmZsxmZv+ZZgCZZjOZZmaZZpmZZsyZZv/MZgDMZj'. 481 'PMZmbMZpnMZszMZv//ZgD/ZjP/Zmb/Zpn/Zsz/Zv8AmQAAmTMA'. 482 'mWYAmZkAmcwAmf8zmQAzmTMzmWYzmZkzmcwzmf9mmQBmmTNmmW'. 483 'ZmmZlmmcxmmf+ZmQCZmTOZmWaZmZmZmcyZmf/MmQDMmTPMmWbM'. 484 'mZnMmczMmf//mQD/mTP/mWb/mZn/mcz/mf8AzAAAzDMAzGYAzJ'. 485 'kAzMwAzP8zzAAzzDMzzGYzzJkzzMwzzP9mzABmzDNmzGZmzJlm'. 486 'zMxmzP+ZzACZzDOZzGaZzJmZzMyZzP/MzADMzDPMzGbMzJnMzM'. 487 'zMzP//zAD/zDP/zGb/zJn/zMz/zP8A/wAA/zMA/2YA/5kA/8wA'. 488 '//8z/wAz/zMz/2Yz/5kz/8wz//9m/wBm/zNm/2Zm/5lm/8xm//'. 489 '+Z/wCZ/zOZ/2aZ/5mZ/8yZ///M/wDM/zPM/2bM/5nM/8zM////'. 490 '/wD//zP//2b//5n//8z///9jJVUgAAAAAXRSTlMAQObYZgAAAA'. 491 'FiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElN'. 492 'RQfTAwkWGTNerea3AAAAYUlEQVR4nHXNwQ3AIAxDUUfyoROxRZ'. 493 'icARin0EBTIP3Hp1gBRqSqYo0seqjZpnngojlWBir5+b8o06lM'. 494 'ha5uFKEpDZulV8l52axhVzqaCdxQp32qVSSwC1wN3fYiw7b76w'. 495 'bN4SMue4/KbwAAAABJRU5ErkJggg==' ; 496 497 //========================================================== 498 // File: pp_green.png 499 //========================================================== 500 $this->imgdata_small[4][0]= 447 ; 501 $this->imgdata_small[4][1]= 502 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABm'. 503 'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsSAAALEgHS3X78AAAA'. 504 'B3RJTUUH0wMJFhkLdq9eKQAAAUxJREFUeJyN1LFVwzAQxvH/8f'. 505 'IeDS0FLKABlN6eIwPYAzCHB0gWYI2jj+i1ABUTQN4TRSQ7iiWZ'. 506 'qxLn9Mt9ydmiqrSq930AYFiu6YdKrf/hP1gYQn6960PxwBaYMG'. 507 'E9UA3dBFtVQjdBOQmBakLennK0CapRwbZRZ3N0O/IeEsqp3HKL'. 508 'Smtt5pUZgTPg4gdDud+6xoS97wM2rsxxmRSoTgoVcMZsXJkBho'. 509 'SmKqCuOuEtls6nmGMFPTUmxBKx/MeyNfQGLoOOiC2ddsxb1Kzv'. 510 'ZzUqu5IXbGDvBJf+hDisi77qFSuhq7Xpuu66TyJLRGbsXVUPxV'. 511 'SxsgkzDMt0mKT3/RcjL8C5hHnvJToXY0xYRZ4xnVKsV/S+a8YA'. 512 'AvCb3s9g13UhYj+TTo93B3fApRV1FVlEAD6H42DjN9/WvzDYuJ'. 513 'dL5b1/ji+/IX8EGWP4AwRii8PdFHTqAAAAAElFTkSuQmCC' ; 514 514 } 515 515 } -
trunk/client/modules/Elezioni/grafici/imgdata_squares.inc.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: imgdata_squares.inc.php 860 2007-03-23 19:16:19Z ljp $3 // File: IMGDATA_SQUARES.INC 4 // Description: Base64 encoded images for squares 5 // Created: 2003-03-20 6 // Ver: $Id: imgdata_squares.inc.php 1106 2009-02-22 20:16:35Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 … … 12 12 protected $name = 'Squares'; 13 13 protected $an = array(MARK_IMG_SQUARE =>'imgdata'); 14 15 protected $colors = array('bluegreen','blue','green', 16 17 protected $index = array('bluegreen' =>2,'blue'=>5,'green'=>6, 18 14 15 protected $colors = array('bluegreen','blue','green', 16 'lightblue','orange','purple','red','yellow'); 17 protected $index = array('bluegreen' =>2,'blue'=>5,'green'=>6, 18 'lightblue'=>0,'orange'=>7,'purple'=>4,'red'=>3,'yellow'=>1); 19 19 protected $maxidx = 7 ; 20 20 protected $imgdata ; 21 21 22 22 function ImgData_Squares () { 23 //==========================================================24 //sq_lblue.png25 //==========================================================26 27 $this->imgdata[0][1]= 28 29 30 31 32 33 34 35 36 37 23 //========================================================== 24 //sq_lblue.png 25 //========================================================== 26 $this->imgdata[0][0]= 362 ; 27 $this->imgdata[0][1]= 28 'iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAIAAADZrBkAAAAABm'. 29 'JLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsRAAALEQF/ZF+RAAAA'. 30 'B3RJTUUH0wMLFgojiPx/ygAAAPdJREFUeNpj/P377+kzHx89/c'. 31 'VAHNBQ5VBX52HavPWWjg6nnDQbkXoUFTnnL7zD9PPXrz17HxCj'. 32 'E6Jn6fL7H7/+ZWJgYCBGJ7IeBgYGJogofp1oehDa8OjE1IOiDa'. 33 'tOrHoYGBhY0NwD0enirMDAwMDFxYRVD7ptyDrNTAU0NXix6sGu'. 34 'jYGBgZOT9e/f/0xMjFyczFgVsGAKCfBza2kKzpl3hIuT1c9Xb/'. 35 'PW58/foKchJqx6tmy98vbjj8cvPm/afMnXW1JShA2fNmQ9EBFc'. 36 'Opnw6MGjkwm/Hlw6mQjqwaqTiRg9mDoZv//4M2/+UYJ64EBWgj'. 37 'cm2hwA8l24oNDl+DMAAAAASUVORK5CYII=' ; 38 38 39 //==========================================================40 //sq_yellow.png41 //==========================================================42 43 $this->imgdata[1][1]= 44 45 46 47 48 49 50 51 52 53 39 //========================================================== 40 //sq_yellow.png 41 //========================================================== 42 $this->imgdata[1][0]= 338 ; 43 $this->imgdata[1][1]= 44 'iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAWl'. 45 'BMVEX////+/+H+/9/9/9v8/8P8/8H8/7v8/7n6/4P5/335/3n5'. 46 '/3X4/1f4/1P3/031/w30/wn0/wPt+ADp9ADm8ADk7gDc5gDa5A'. 47 'DL1ADFzgCwuACqsgClrABzeAC9M0MzAAAAAWJLR0QAiAUdSAAA'. 48 'AAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU1FB9MDCxYEDlOgDj'. 49 'EAAAB+SURBVHjaVcpbCsQgDEDRGERGKopjDa2a/W9zfLWj9/Nw'. 50 'Ac21ZRBOtZlRN9ApzSYFaDUj79KIorRDbJNO9bN/GUSh2ZRJFJ'. 51 'S18iorURBiyksO8buT0zkfYaUqzI91ckfhWhoGXTLzsDjI68Sz'. 52 'pGMjrzPzauA/iXk1AtykmvgBC8UcWUdc9HkAAAAASUVORK5CYI'. 53 'I=' ; 54 54 55 //==========================================================56 //sq_blgr.png57 //==========================================================58 59 $this->imgdata[2][1]= 60 61 62 63 64 65 66 67 68 69 55 //========================================================== 56 //sq_blgr.png 57 //========================================================== 58 $this->imgdata[2][0]= 347 ; 59 $this->imgdata[2][1]= 60 'iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAZl'. 61 'BMVEX////0+vv0+vrz+fry+frv+Png7e/d7e/a6+zY6+250tSz'. 62 '0tSyztCtztGM0NWIz9SDzdNfsLVcrrRZrbJOp61MpqtIr7dHn6'. 63 'RErrZArLQ6q7M2g4kygYcsp68npa4ctr8QZ20JnqepKsl4AAAA'. 64 'AWJLR0QAiAUdSAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU'. 65 '1FB9MDCxYEByp8tpUAAAB7SURBVHjaVcjRFoIgDADQWZpWJpjY'. 66 'MsnG//9kzIFn3McLzfArDA3MndFjrhvgfDHFBEB9pt0CVzwrY3'. 67 'n2yicjhY4vTSp0nbXtN+hCV53SHDWe61dZY+/9463r2XuifHAM'. 68 '0SoH+6xEcovUlCfefeFSIwfTTQ3fB+pi4lV/bTIgvmaA7a0AAA'. 69 'AASUVORK5CYII=' ; 70 70 71 //==========================================================72 //sq_red.png73 //==========================================================74 75 $this->imgdata[3][1]= 76 77 78 79 80 81 82 83 84 71 //========================================================== 72 //sq_red.png 73 //========================================================== 74 $this->imgdata[3][0]= 324 ; 75 $this->imgdata[3][1]= 76 'iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAXV'. 77 'BMVEX////++Pn99/j99ff99fb98/X98/T98PL55uj43+P24+bw'. 78 'kKPvjaHviJ3teJHpxMnoL2Pjs73WW3rWNljVWXnUVnbUK1DTJk'. 79 '3SUHPOBz/KQmmxPVmuOFasNFOeIkWVka/fAAAAAWJLR0QAiAUd'. 80 'SAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU1FB9MDCxYEHd'. 81 'ceT+8AAABtSURBVHjaVchbAkMwEAXQq6i3VrQiQfa/zDYTw8z5'. 82 'PCjGt9JVWFt1XWPh1fWNdfDy+tq6WPfRUPENNKnSnXNWPB4uv2'. 83 'b54nSZ8jHrMtOxvWZZZtpD4KP6xLkO9/AhzhaCOMhJh68cOjzV'. 84 '/K/4Ac2cG+nBcaRuAAAAAElFTkSuQmCC' ; 85 85 86 //==========================================================87 //sq_pink.png88 //==========================================================89 90 $this->imgdata[4][1]= 91 92 93 94 95 96 97 98 99 100 101 102 86 //========================================================== 87 //sq_pink.png 88 //========================================================== 89 $this->imgdata[4][0]= 445 ; 90 $this->imgdata[4][1]= 91 'iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAApV'. 92 'BMVEX////6+Pz69/v49Pr38/r17/jr4+/l3Onj2efh1ua/L+i+'. 93 'q8m+Lue9Lua8qsS8LuW8LeS7pca5LOG4LN+2Y9O2YNW1ZdO1Kt'. 94 'y0atC0aNGzb82zbc6zKtuzKdqycsuwa8qtJtOISZ2GRpuFN6GE'. 95 'NqCDQpmCMZ+BPpd/LJ1/K519S5B9Jpx9Jpt9JZt6RY11BJZ1BJ'. 96 'V0BJV0BJRzBJNvNoRtIoJUEmdZ/XbrAAAAAWJLR0QAiAUdSAAA'. 97 'AAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU1FB9MDCxYDF3iKMD'. 98 'YAAACeSURBVHjaVczbEoIgGARgCiMtrexoWpaa2FHUgvd/tH4Y'. 99 'BnEvv9ldhNPradPnnGBUTtPDzMRPSIF46SaBoR25dYjz3I20Lb'. 100 'ek6BgQz73Il7KKpSgCO0pTHU0886J1sCe0ZYbALjGhjFnEM2es'. 101 'VhZVI4d+B1QtfnV47ywCEaKeP/p7JdLejSYt0j6NIiOq1wJZIs'. 102 'QTDA0ELHwhPBCwyR/Cni9cOmzJtwAAAABJRU5ErkJggg==' ; 103 103 104 //==========================================================105 //sq_blue.png106 //==========================================================107 108 $this->imgdata[5][1]= 109 110 111 112 113 114 115 116 104 //========================================================== 105 //sq_blue.png 106 //========================================================== 107 $this->imgdata[5][0]= 283 ; 108 $this->imgdata[5][1]= 109 'iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAQl'. 110 'BMVEX////4+fz39/z19vvy8vru7/ni4+7g4fHW1ue8vteXmt6B'. 111 'hdhiZ7FQVaZETcxCSJo1Oq4zNoMjKakhJHcKFaMEC2jRVYdWAA'. 112 'AAAWJLR0QAiAUdSAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAAd0'. 113 'SU1FB9MDCxYDN0PkEP4AAABfSURBVHjaVchHAoAgDATAVcCCIF'. 114 'j4/1elJEjmOFDHKVgDv4iz640gLs+LMF6ZUv/VqcXXplU7Gqpy'. 115 'PFzBT5qml9NzlOX259riWHlS4kOffviHD8PQYZx2EFMPRkw+9Q'. 116 'FSnRPeWEDzKAAAAABJRU5ErkJggg==' ; 117 117 118 //==========================================================119 //sq_green.png120 //==========================================================121 122 $this->imgdata[6][1]= 123 124 125 126 127 128 129 130 131 118 //========================================================== 119 //sq_green.png 120 //========================================================== 121 $this->imgdata[6][0]= 325 ; 122 $this->imgdata[6][1]= 123 'iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAXV'. 124 'BMVEX////2+vX1+vX1+fT0+fPz+PPx9/Dv9u7u9e3h7uHe697a'. 125 '6dnO2s3I1sa10LOvza2ay5aEwYBWlE9TqE5Tkk1RkEpMrUJMg0'. 126 'hKiUNGpEFBojw8oTcsbScaYBMWlwmMT0NtAAAAAWJLR0QAiAUd'. 127 'SAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU1FB9MDCxYEFd'. 128 'nFx90AAABuSURBVHjaVc9HAoAgDADB2HuJWLDx/2cKBITscW4L'. 129 '5byzMIWtZobNDZIZtrcCGZsRQ8GwvRSRNxIiMuysODKG3alikl'. 130 'ueOPlpKTLBaRmOZxQxaXlfb5ZWI9om4WntrXiDSJzp7SBkwMQa'. 131 'FEy0VR/NAB2kNuj7rgAAAABJRU5ErkJggg==' ; 132 132 133 //==========================================================134 //sq_orange.png135 //==========================================================136 137 $this->imgdata[7][1]= 138 139 140 141 142 143 144 145 146 133 //========================================================== 134 //sq_orange.png 135 //========================================================== 136 $this->imgdata[7][0]= 321 ; 137 $this->imgdata[7][1]= 138 'iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAUV'. 139 'BMVEX/////8+n/8uf/8OP/59H/5Mv/zqH/zJ3/ypv/yJf/vYH/'. 140 'u33/uXn/n0n/nUX/m0H/lzn/ljf/lDP/kS3/kCv/iR//hxv/fg'. 141 'n/fAX/eQDYZgDW6ia5AAAAAWJLR0QAiAUdSAAAAAlwSFlzAAAL'. 142 'EgAACxIB0t1+/AAAAAd0SU1FB9MDCxYEJIgbx+cAAAB2SURBVH'. 143 'jaVczRCoQwDETRbLAWLZSGUA35/w/dVI0283i4DODew3YESmWW'. 144 'kg5gWkoQAe6TleUQI/66Sy7i56+kLk7cht2N0+hcnJgQu0SqiC'. 145 '1SzSIbzWSi6gavqJ63wSduRi2f+kwyD5rEukwCdZ1kGAMGMfv9'. 146 'AbWuGMOr5COSAAAAAElFTkSuQmCC' ; 147 147 } 148 148 } -
trunk/client/modules/Elezioni/grafici/imgdata_stars.inc.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: imgdata_stars.inc.php 860 2007-03-23 19:16:19Z ljp $3 // File: IMGDATA_STARS.INC 4 // Description: Base64 encoded images for stars 5 // Created: 2003-03-20 6 // Ver: $Id: imgdata_stars.inc.php 1106 2009-02-22 20:16:35Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 … … 15 15 16 16 protected $colors = array('bluegreen','lightblue','purple','blue','green','pink','red','yellow'); 17 protected $index = array('bluegreen'=>3,'lightblue'=>4,'purple'=>1, 18 17 protected $index = array('bluegreen'=>3,'lightblue'=>4,'purple'=>1, 18 'blue'=>5,'green'=>0,'pink'=>7,'red'=>2,'yellow'=>6); 19 19 protected $maxidx = 7 ; 20 20 protected $imgdata ; 21 21 22 function ImgData_Stars() {23 //==========================================================24 // File: bstar_green_001.png25 //==========================================================26 27 $this->imgdata[0][1]= 28 29 30 31 32 33 34 35 36 37 //==========================================================38 // File: bstar_blred.png39 //==========================================================40 41 $this->imgdata[1][1]= 42 43 44 45 46 47 48 49 50 22 function __construct() { 23 //========================================================== 24 // File: bstar_green_001.png 25 //========================================================== 26 $this->imgdata[0][0]= 329 ; 27 $this->imgdata[0][1]= 28 'iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAMAAABsDg4iAAAAUV'. 29 'BMVEX///////+/v7+83rqcyY2Q/4R7/15y/1tp/05p/0lg/zdX'. 30 '/zdX/zVV/zdO/zFJ9TFJvDFD4yg+8Bw+3iU68hwurhYotxYosx'. 31 'YokBoTfwANgQFUp7DWAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgF'. 32 'HUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAxYTJj'. 33 'CRyxgTAAAAcUlEQVR4nH3MSw6AIAwEUBL/IKBWwXL/g0pLojUS'. 34 'ZzGLl8ko9Zumhr5iy66/GH0dp49llNPB5sTotDY5PVuLG6tnM9'. 35 'CVKSIe1joSgPsAKSuANNaENFQvTAGzmheSkUpMBWeJZwqBT8wo'. 36 'hmysD4bnnPsC/x8ItUdGPfAAAAAASUVORK5CYII=' ; 37 //========================================================== 38 // File: bstar_blred.png 39 //========================================================== 40 $this->imgdata[1][0]= 325 ; 41 $this->imgdata[1][1]= 42 'iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAMAAABsDg4iAAAATl'. 43 'BMVEX///+/v79uRJ6jWPOSUtKrb+ejWO+gWPaGTruJTr6rZvF2'. 44 'RqC2ocqdVuCeV+egV/GsnLuIXL66rMSpcOyATbipY/OdWOp+VK'. 45 'aTU9WhV+yJKBoLAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgA'. 46 'AAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAxYTJwynv1'. 47 'XVAAAAcElEQVR4nH3MyQ6AIAwEUFIqiwju2///qLQmWiJxDnN4'. 48 'mYxSv5lqGCs2nvaLLtZx/VhGOW1MjnPJWp0zsw2wsUY2jd09BY'. 49 'DFmESC+BwA5UCUxhqAhqrA4CGrLpCMVGK4sZe4B+/5RLdiyMb6'. 50 'on/PuS9CdQNC7yBXEQAAAABJRU5ErkJggg==' ; 51 51 52 //==========================================================53 // File: bstar_red_001.png54 //==========================================================55 56 $this->imgdata[2][1]= 57 58 59 60 61 62 63 64 65 52 //========================================================== 53 // File: bstar_red_001.png 54 //========================================================== 55 $this->imgdata[2][0]= 325 ; 56 $this->imgdata[2][1]= 57 'iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAMAAABsDg4iAAAATl'. 58 'BMVEX///+/v7+eRFHzWG3SUmHnb37vWGr2WHG7Tlm+TljxZneg'. 59 'Rk3KoaXgVmXnV2nxV227nJ++XGzErK3scIS4TVzzY3fqWG2mVF'. 60 'zVU2PsV2rJFw9VAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgA'. 61 'AAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAxYTJzCI0C'. 62 'lSAAAAcElEQVR4nH3MyQ6AIAwEUFIqiwju2///qLQmWiJxDnN4'. 63 'mYxSv5lqGCs2nvaLLtZx/VhGOW1MjnPJWp0zsw2wsUY2jd09BY'. 64 'DFmESC+BwA5UCUxhqAhqrA4CGrLpCMVGK4sZe4B+/5RLdiyMb6'. 65 'on/PuS9CdQNC7yBXEQAAAABJRU5ErkJggg==' ; 66 66 67 //==========================================================68 // File: bstar_blgr_001.png69 //==========================================================70 71 $this->imgdata[3][1]= 72 73 74 75 76 77 78 79 80 67 //========================================================== 68 // File: bstar_blgr_001.png 69 //========================================================== 70 $this->imgdata[3][0]= 325 ; 71 $this->imgdata[3][1]= 72 'iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAMAAABsDg4iAAAATl'. 73 'BMVEX///+/v79Ehp5Yx/NSq9Jvw+dYwu9YzfZOmbtOmb5myPFG'. 74 'gqChvcpWteBXvedXxvGcsbtcpb6su8RwzOxNmrhjyvNYwupUjK'. 75 'ZTr9VXwOyJhmWNAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgA'. 76 'AAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAxYTJTC65k'. 77 'vQAAAAcElEQVR4nH3MyQ6AIAwEUFIqiwju2///qLQmWiJxDnN4'. 78 'mYxSv5lqGCs2nvaLLtZx/VhGOW1MjnPJWp0zsw2wsUY2jd09BY'. 79 'DFmESC+BwA5UCUxhqAhqrA4CGrLpCMVGK4sZe4B+/5RLdiyMb6'. 80 'on/PuS9CdQNC7yBXEQAAAABJRU5ErkJggg==' ; 81 81 82 //==========================================================83 // File: bstar_blgr_002.png84 //==========================================================85 86 $this->imgdata[4][1]= 87 88 89 90 91 92 93 94 95 82 //========================================================== 83 // File: bstar_blgr_002.png 84 //========================================================== 85 $this->imgdata[4][0]= 325 ; 86 $this->imgdata[4][1]= 87 'iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAMAAABsDg4iAAAATl'. 88 'BMVEX///+/v79EnpxY8/FS0dJv5+dY7+9Y9vBOubtOur5m8fFG'. 89 'nKChycpW3uBX5+ZX8e2curtcvrqswsRw7OdNuLZj8/BY6udUpK'. 90 'ZT1dRX7OtNkrW5AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgA'. 91 'AAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAxYTJgXHeN'. 92 'wwAAAAcElEQVR4nH3MyQ6AIAwEUFIqiwju2///qLQmWiJxDnN4'. 93 'mYxSv5lqGCs2nvaLLtZx/VhGOW1MjnPJWp0zsw2wsUY2jd09BY'. 94 'DFmESC+BwA5UCUxhqAhqrA4CGrLpCMVGK4sZe4B+/5RLdiyMb6'. 95 'on/PuS9CdQNC7yBXEQAAAABJRU5ErkJggg==' ; 96 96 97 //==========================================================98 // File: bstar_blue_001.png99 //==========================================================100 101 $this->imgdata[5][1]= 102 103 104 105 106 107 108 109 110 97 //========================================================== 98 // File: bstar_blue_001.png 99 //========================================================== 100 $this->imgdata[5][0]= 325 ; 101 $this->imgdata[5][1]= 102 'iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAMAAABsDg4iAAAATl'. 103 'BMVEX///+/v79EY55Yi/NSetJvledYiO9YkPZOb7tObr5mkvFG'. 104 'X6ChrcpWgOBXhedXi/Gcpbtcf76sssRwnOxNcbhjk/NYiepUbK'. 105 'ZTfdVXh+ynNEzzAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgA'. 106 'AAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAxYTJhStyP'. 107 'zCAAAAcElEQVR4nH3MyQ6AIAwEUFIqiwju2///qLQmWiJxDnN4'. 108 'mYxSv5lqGCs2nvaLLtZx/VhGOW1MjnPJWp0zsw2wsUY2jd09BY'. 109 'DFmESC+BwA5UCUxhqAhqrA4CGrLpCMVGK4sZe4B+/5RLdiyMb6'. 110 'on/PuS9CdQNC7yBXEQAAAABJRU5ErkJggg==' ; 111 111 112 //==========================================================113 // File: bstar_oy_007.png114 //==========================================================115 116 $this->imgdata[6][1]= 117 118 119 120 121 122 123 124 125 112 //========================================================== 113 // File: bstar_oy_007.png 114 //========================================================== 115 $this->imgdata[6][0]= 325 ; 116 $this->imgdata[6][1]= 117 'iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAMAAABsDg4iAAAATl'. 118 'BMVEX///+/v7+ejUTz11jSvVLn02/v1lj21li7q06+r07x2mag'. 119 'lUbKxKHgy1bnz1fx1Ve7t5y+qlzEwqzs03C4pE3z2WPqz1imml'. 120 'TVv1Ps01dGRjeyAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgA'. 121 'AAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAxYTJjsGGc'. 122 'GbAAAAcElEQVR4nH3MyQ6AIAwEUFIqiwju2///qLQmWiJxDnN4'. 123 'mYxSv5lqGCs2nvaLLtZx/VhGOW1MjnPJWp0zsw2wsUY2jd09BY'. 124 'DFmESC+BwA5UCUxhqAhqrA4CGrLpCMVGK4sZe4B+/5RLdiyMb6'. 125 'on/PuS9CdQNC7yBXEQAAAABJRU5ErkJggg==' ; 126 126 127 //==========================================================128 // File: bstar_lred.png129 //==========================================================130 131 $this->imgdata[7][1]= 132 133 134 135 136 137 138 139 140 127 //========================================================== 128 // File: bstar_lred.png 129 //========================================================== 130 $this->imgdata[7][0]= 325 ; 131 $this->imgdata[7][1]= 132 'iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAMAAABsDg4iAAAATl'. 133 'BMVEX///+/v7+eRJPzWN3SUr7nb9TvWNj2WOS7Tqi+TqnxZtyg'. 134 'Ro/KocPgVsjnV9LxV927nLa+XLTErL7scN24TarzY9/qWNemVJ'. 135 'jVU8LsV9VCwcc9AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgA'. 136 'AAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTAxYTJxi9ZY'. 137 'GoAAAAcElEQVR4nH3MyQ6AIAwEUFIqiwju2///qLQmWiJxDnN4'. 138 'mYxSv5lqGCs2nvaLLtZx/VhGOW1MjnPJWp0zsw2wsUY2jd09BY'. 139 'DFmESC+BwA5UCUxhqAhqrA4CGrLpCMVGK4sZe4B+/5RLdiyMb6'. 140 'on/PuS9CdQNC7yBXEQAAAABJRU5ErkJggg==' ; 141 141 } 142 142 } -
trunk/client/modules/Elezioni/grafici/jpg-config.inc.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpg-config.inc.php 1091 2009-01-18 22:57:40Z ljp $3 // File: JPG-CONFIG.INC 4 // Description: Configuration file for JpGraph library 5 // Created: 2004-03-27 6 // Ver: $Id: jpg-config.inc.php 1871 2009-09-29 05:56:39Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 11 11 12 13 12 //------------------------------------------------------------------------ 14 // Directories for cache and font directory. 13 // Directories for cache and font directory. 15 14 // 16 15 // CACHE_DIR: … … 29 28 // CACHE_DIR /tmp/jpgraph_cache/ 30 29 // TTF_DIR /usr/share/fonts/truetype/ 31 // MBTTF_DIR /usr/share/fonts/ ja/TrueType/30 // MBTTF_DIR /usr/share/fonts/truetype/ 32 31 // 33 define("TTF_DIR","/usr/share/fonts/truetype/ttf-dejavu/");34 32 // WINDOWS: 35 33 // CACHE_DIR $SERVER_TEMP/jpgraph_cache/ … … 38 36 // 39 37 //------------------------------------------------------------------------ 40 // define( "CACHE_DIR","/tmp/jpgraph_cache/");41 // define( "TTF_DIR","/usr/share/fonts/truetype/");42 // define( "MBTTF_DIR","/usr/share/fonts/ja/TrueType/");38 // define('CACHE_DIR','/tmp/jpgraph_cache/'); 39 // define('TTF_DIR','/usr/share/fonts/TrueType/'); 40 // define('MBTTF_DIR','/usr/share/fonts/TrueType/'); 43 41 44 42 //------------------------------------------------------------------------- … … 46 44 // using the cache. 47 45 // The directory must be the filesysystem name as seen by PHP 48 // and the 'http' version must be the same directory but as 49 // seen by the HTTP server relative to the 'htdocs' ddirectory. 46 // and the 'http' version must be the same directory but as 47 // seen by the HTTP server relative to the 'htdocs' ddirectory. 50 48 // If a relative path is specified it is taken to be relative from where 51 49 // the image script is executed. 52 // Note: The default setting is to create a subdirectory in the 50 // Note: The default setting is to create a subdirectory in the 53 51 // directory from where the image script is executed and store all files 54 52 // there. As ususal this directory must be writeable by the PHP process. 55 define("CSIMCACHE_DIR","csimcache/"); 56 define("CSIMCACHE_HTTP_DIR","csimcache/"); 57 58 //------------------------------------------------------------------------ 59 // Defines for font setup 60 //------------------------------------------------------------------------ 61 62 // Actual name of the TTF file used together with FF_CHINESE aka FF_BIG5 63 // This is the TTF file being used when the font family is specified as 64 // either FF_CHINESE or FF_BIG5 65 define('CHINESE_TTF_FONT','bkai00mp.ttf'); 66 67 // Special unicode greek language support 68 define("LANGUAGE_GREEK",false); 69 70 // If you are setting this config to true the conversion of greek characters 71 // will assume that the input text is windows 1251 72 define("GREEK_FROM_WINDOWS",false); 73 74 // Special unicode cyrillic language support 75 define("LANGUAGE_CYRILLIC",false); 76 77 // If you are setting this config to true the conversion 78 // will assume that the input text is windows 1251, if 79 // false it will assume koi8-r 80 define("CYRILLIC_FROM_WINDOWS",false); 81 82 // The following constant is used to auto-detect 83 // whether cyrillic conversion is really necessary 84 // if enabled. Just replace 'windows-1251' with a variable 85 // containing the input character encoding string 86 // of your application calling jpgraph. 87 // A typical such string would be 'UTF-8' or 'utf-8'. 88 // The comparison is case-insensitive. 89 // If this charset is not a 'koi8-r' or 'windows-1251' 90 // derivate then no conversion is done. 91 // 92 // This constant can be very important in multi-user 93 // multi-language environments where a cyrillic conversion 94 // could be needed for some cyrillic people 95 // and resulting in just erraneous conversions 96 // for not-cyrillic language based people. 97 // 98 // Example: In the free project management 99 // software dotproject.net $locale_char_set is dynamically 100 // set by the language environment the user has chosen. 101 // 102 // Usage: define('LANGUAGE_CHARSET', $locale_char_set); 103 // 104 // where $locale_char_set is a GLOBAL (string) variable 105 // from the application including JpGraph. 106 // 107 define('LANGUAGE_CHARSET', null); 108 109 // Japanese TrueType font used with FF_MINCHO, FF_PMINCHO, FF_GOTHIC, FF_PGOTHIC 110 define('MINCHO_TTF_FONT','ipam.ttf'); 111 define('PMINCHO_TTF_FONT','ipamp.ttf'); 112 define('GOTHIC_TTF_FONT','ipag.ttf'); 113 define('PGOTHIC_TTF_FONT','ipagp.ttf'); 114 115 // Assume that Japanese text have been entered in EUC-JP encoding. 116 // If this define is true then conversion from EUC-JP to UTF8 is done 117 // automatically in the library using the mbstring module in PHP. 118 define('ASSUME_EUCJP_ENCODING',false); 53 define('CSIMCACHE_DIR','csimcache/'); 54 define('CSIMCACHE_HTTP_DIR','csimcache/'); 119 55 120 56 //------------------------------------------------------------------------ … … 128 64 define('DEFAULT_ERR_LOCALE','en'); 129 65 130 // Deafult graphic format set to "auto"which will automatically66 // Deafult graphic format set to 'auto' which will automatically 131 67 // choose the best available format in the order png,gif,jpeg 132 68 // (The supported format depends on what your PHP installation supports) 133 define( "DEFAULT_GFORMAT","auto");69 define('DEFAULT_GFORMAT','auto'); 134 70 135 71 // Should the cache be used at all? By setting this to false no 136 // files will be generated in the cache directory. 72 // files will be generated in the cache directory. 137 73 // The difference from READ_CACHE being that setting READ_CACHE to 138 74 // false will still create the image in the cache directory 139 75 // just not use it. By setting USE_CACHE=false no files will even 140 76 // be generated in the cache directory. 141 define( "USE_CACHE",false);77 define('USE_CACHE',false); 142 78 143 // Should we try to find an image in the cache before generating it? 79 // Should we try to find an image in the cache before generating it? 144 80 // Set this define to false to bypass the reading of the cache and always 145 // regenerate the image. Note that even if reading the cache is 81 // regenerate the image. Note that even if reading the cache is 146 82 // disabled the cached will still be updated with the newly generated 147 // image. Set also "USE_CACHE"below.148 define( "READ_CACHE",true);83 // image. Set also 'USE_CACHE' below. 84 define('READ_CACHE',true); 149 85 150 86 // Determine if the error handler should be image based or purely 151 87 // text based. Image based makes it easier since the script will 152 88 // always return an image even in case of errors. 153 define( "USE_IMAGE_ERROR_HANDLER",true);89 define('USE_IMAGE_ERROR_HANDLER',true); 154 90 155 // Should the library examin the global php_errmsg string and convert91 // Should the library examine the global php_errmsg string and convert 156 92 // any error in it to a graphical representation. This is handy for the 157 93 // occasions when, for example, header files cannot be found and this results 158 // in the graph not being created and just a "red-cross"image would be seen.94 // in the graph not being created and just a 'red-cross' image would be seen. 159 95 // This should be turned off for a production site. 160 define( "CATCH_PHPERRMSG",true);96 define('CATCH_PHPERRMSG',true); 161 97 162 98 // Determine if the library should also setup the default PHP 163 99 // error handler to generate a graphic error mesage. This is useful 164 100 // during development to be able to see the error message as an image 165 // instead as a "red-cross" in a page where an image is expected. 166 define("INSTALL_PHP_ERR_HANDLER",false); 167 168 // If the color palette is full should JpGraph try to allocate 169 // the closest match? If you plan on using background images or 170 // gradient fills it might be a good idea to enable this. 171 // If not you will otherwise get an error saying that the color palette is 172 // exhausted. The drawback of using approximations is that the colors 173 // might not be exactly what you specified. 174 // Note1: This does only apply to paletted images, not truecolor 175 // images since they don't have the limitations of maximum number 176 // of colors. 177 define("USE_APPROX_COLORS",true); 101 // instead as a 'red-cross' in a page where an image is expected. 102 define('INSTALL_PHP_ERR_HANDLER',false); 178 103 179 104 // Should usage of deprecated functions and parameters give a fatal error? 180 105 // (Useful to check if code is future proof.) 181 define( "ERR_DEPRECATED",true);106 define('ERR_DEPRECATED',true); 182 107 183 // Should the time taken to generate each picture be branded to the lower 184 // left in corner in each generated image? Useful for performace measurements 185 // generating graphs 186 define("BRAND_TIMING",false); 187 188 // What format should be used for the timing string? 189 define("BRAND_TIME_FORMAT","(%01.3fs)"); 108 // The builtin GD function imagettfbbox() fuction which calculates the bounding box for 109 // text using TTF fonts is buggy. By setting this define to true the library 110 // uses its own compensation for this bug. However this will give a 111 // slightly different visual apparance than not using this compensation. 112 // Enabling this compensation will in general give text a bit more space to more 113 // truly reflect the actual bounding box which is a bit larger than what the 114 // GD function thinks. 115 define('USE_LIBRARY_IMAGETTFBBOX',true); 190 116 191 117 //------------------------------------------------------------------------ … … 194 120 195 121 // What group should the cached file belong to 196 // (Set to "" will give the default group for the "PHP-user")122 // (Set to '' will give the default group for the 'PHP-user') 197 123 // Please note that the Apache user must be a member of the 198 124 // specified group since otherwise it is impossible for Apache 199 125 // to set the specified group. 200 define( "CACHE_FILE_GROUP","wwwadmin");126 define('CACHE_FILE_GROUP','www'); 201 127 202 128 // What permissions should the cached file have 203 // (Set to "" will give the default persmissions for the "PHP-user")204 define( "CACHE_FILE_MOD",0664);129 // (Set to '' will give the default persmissions for the 'PHP-user') 130 define('CACHE_FILE_MOD',0664); 205 131 206 // Decide if we should use the bresenham circle algorithm or the 207 // built in Arc(). Bresenham gives better visual apperance of circles 208 // but is more CPU intensive and slower then the built in Arc() function 209 // in GD. Turned off by default for speed 210 define("USE_BRESENHAM",false); 132 // Default theme class name 133 define('DEFAULT_THEME_CLASS', 'UniversalTheme'); 211 134 212 // Special file name to indicate that we only want to calc 213 // the image map in the call to Graph::Stroke() used 214 // internally from the GetHTMLCSIM() method. 215 define("_CSIM_SPECIALFILE","_csim_special_"); 216 217 // HTTP GET argument that is used with image map 218 // to indicate to the script to just generate the image 219 // and not the full CSIM HTML page. 220 define("_CSIM_DISPLAY","_jpg_csimd"); 221 222 // Special filename for Graph::Stroke(). If this filename is given 223 // then the image will NOT be streamed to browser of file. Instead the 224 // Stroke call will return the handler for the created GD image. 225 define("_IMG_HANDLER","__handle"); 226 135 define('SUPERSAMPLING', true); 136 define('SUPERSAMPLING_SCALE', 1); 227 137 228 138 ?> -
trunk/client/modules/Elezioni/grafici/jpgraph.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph.php 1091 2009-01-18 22:57:40Z ljp $3 // File: JPGRAPH.PHP 4 // Description: PHP Graph Plotting library. Base module. 5 // Created: 2001-01-08 6 // Ver: $Id: jpgraph.php 1924 2010-01-11 14:03:26Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 … … 16 16 require_once('jpgraph_text.inc.php'); 17 17 require_once('jpgraph_legend.inc.php'); 18 require_once('jpgraph_theme.inc.php'); 19 require_once('gd_image.inc.php'); 18 20 19 21 // Version info 20 define('JPG_VERSION',' 2.3.5-dev');22 define('JPG_VERSION','4.2.6'); 21 23 22 24 // Minimum required PHP version 23 25 define('MIN_PHPVERSION','5.1.0'); 24 26 25 // Should the image be a truecolor image? 26 define('USE_TRUECOLOR',true); 27 28 //------------------------------------------------------------------------ 29 // Automatic settings of path for cache and font directory 30 // if they have not been previously specified 31 //------------------------------------------------------------------------ 32 if(USE_CACHE) { 33 if (!defined('CACHE_DIR')) { 34 if ( strstr( PHP_OS, 'WIN') ) { 35 if( empty($_SERVER['TEMP']) ) { 36 $t = new ErrMsgText(); 37 $msg = $t->Get(11,$file,$lineno); 38 die($msg); 39 } 40 else { 41 define('CACHE_DIR', $_SERVER['TEMP'] . '/'); 42 } 43 } else { 44 define('CACHE_DIR','/tmp/jpgraph_cache/'); 45 } 46 } 47 } 48 elseif( !defined('CACHE_DIR') ) { 49 define('CACHE_DIR', ''); 50 } 51 52 if (!defined('TTF_DIR')) { 53 if (strstr( PHP_OS, 'WIN') ) { 54 $sroot = getenv('SystemRoot'); 55 if( empty($sroot) ) { 56 $t = new ErrMsgText(); 57 $msg = $t->Get(12,$file,$lineno); 58 die($msg); 59 } 60 else { 61 define('TTF_DIR', $sroot.'/fonts/'); 62 } 63 } else { 64 define('TTF_DIR','/usr/share/fonts/truetype/'); 65 } 66 } 67 68 if (!defined('MBTTF_DIR')) { 69 if (strstr( PHP_OS, 'WIN') ) { 70 $sroot = getenv('SystemRoot'); 71 if( empty($sroot) ) { 72 $t = new ErrMsgText(); 73 $msg = $t->Get(12,$file,$lineno); 74 die($msg); 75 } 76 else { 77 define('TTF_DIR', $sroot.'/fonts/'); 78 } 79 } else { 80 define('MBTTF_DIR','/usr/share/fonts/ja/TrueType/'); 81 } 82 } 83 84 //------------------------------------------------------------------ 85 // Constants which are used as parameters for the method calls 86 //------------------------------------------------------------------ 87 27 // Special file name to indicate that we only want to calc 28 // the image map in the call to Graph::Stroke() used 29 // internally from the GetHTMLCSIM() method. 30 define('_CSIM_SPECIALFILE','_csim_special_'); 31 32 // HTTP GET argument that is used with image map 33 // to indicate to the script to just generate the image 34 // and not the full CSIM HTML page. 35 define('_CSIM_DISPLAY','_jpg_csimd'); 36 37 // Special filename for Graph::Stroke(). If this filename is given 38 // then the image will NOT be streamed to browser of file. Instead the 39 // Stroke call will return the handler for the created GD image. 40 define('_IMG_HANDLER','__handle'); 41 42 // Special filename for Graph::Stroke(). If this filename is given 43 // the image will be stroked to a file with a name based on the script name. 44 define('_IMG_AUTO','auto'); 88 45 89 46 // Tick density … … 93 50 define("TICKD_VERYSPARSE",4); 94 51 95 // Side for ticks and labels. 52 // Side for ticks and labels. 96 53 define("SIDE_LEFT",-1); 97 54 define("SIDE_RIGHT",1); … … 156 113 define("HORIZONTAL",0); 157 114 158 159 115 // Axis styles for scientific style axis 160 116 define('AXSTYLE_SIMPLE',1); … … 176 132 define('TITLEBKG_FILLSTYLE_SOLID',3); 177 133 134 // Styles for axis labels background 135 define('LABELBKG_NONE',0); 136 define('LABELBKG_XAXIS',1); 137 define('LABELBKG_YAXIS',2); 138 define('LABELBKG_XAXISFULL',3); 139 define('LABELBKG_YAXISFULL',4); 140 define('LABELBKG_XYFULL',5); 141 define('LABELBKG_XY',6); 142 143 178 144 // Style for background gradient fills 179 145 define('BGRAD_FRAME',1); … … 191 157 define('SKEW3D_RIGHT',3); 192 158 193 // Line styles194 define('LINESTYLE_SOLID',1);195 define('LINESTYLE_DOTTED',2);196 define('LINESTYLE_DASHED',3);197 define('LINESTYLE_LONGDASH',4);198 199 159 // For internal use only 200 160 define("_JPG_DEBUG",false); … … 202 162 define("_FORCE_IMGDIR",'/tmp/jpgimg/'); 203 163 204 require_once('gd_image.inc.php'); 205 206 function CheckPHPVersion($aMinVersion) 207 { 208 list($majorC, $minorC, $editC) = split('[/.-]', PHP_VERSION); 209 list($majorR, $minorR, $editR) = split('[/.-]', $aMinVersion); 210 211 if ($majorC != $majorR) return false; 164 165 // 166 // Automatic settings of path for cache and font directory 167 // if they have not been previously specified 168 // 169 if(USE_CACHE) { 170 if (!defined('CACHE_DIR')) { 171 if ( strstr( PHP_OS, 'WIN') ) { 172 if( empty($_SERVER['TEMP']) ) { 173 $t = new ErrMsgText(); 174 $msg = $t->Get(11,$file,$lineno); 175 die($msg); 176 } 177 else { 178 define('CACHE_DIR', $_SERVER['TEMP'] . '/'); 179 } 180 } else { 181 define('CACHE_DIR','/tmp/jpgraph_cache/'); 182 } 183 } 184 } 185 elseif( !defined('CACHE_DIR') ) { 186 define('CACHE_DIR', ''); 187 } 188 189 // 190 // Setup path for western/latin TTF fonts 191 // 192 if (!defined('TTF_DIR')) { 193 if (strstr( PHP_OS, 'WIN') ) { 194 $sroot = getenv('SystemRoot'); 195 if( empty($sroot) ) { 196 $t = new ErrMsgText(); 197 $msg = $t->Get(12,$file,$lineno); 198 die($msg); 199 } 200 else { 201 define('TTF_DIR', $sroot.'/fonts/'); 202 } 203 } else { 204 define('TTF_DIR','/usr/share/fonts/truetype/'); 205 } 206 } 207 208 // 209 // Setup path for MultiByte TTF fonts (japanese, chinese etc.) 210 // 211 if (!defined('MBTTF_DIR')) { 212 if (strstr( PHP_OS, 'WIN') ) { 213 $sroot = getenv('SystemRoot'); 214 if( empty($sroot) ) { 215 $t = new ErrMsgText(); 216 $msg = $t->Get(12,$file,$lineno); 217 die($msg); 218 } 219 else { 220 define('MBTTF_DIR', $sroot.'/fonts/'); 221 } 222 } else { 223 define('MBTTF_DIR','/usr/share/fonts/truetype/'); 224 } 225 } 226 227 // 228 // Check minimum PHP version 229 // 230 function CheckPHPVersion($aMinVersion) { 231 list($majorC, $minorC, $editC) = preg_split('/[\/.-]/', PHP_VERSION); 232 list($majorR, $minorR, $editR) = preg_split('/[\/.-]/', $aMinVersion); 233 212 234 if ($majorC < $majorR) return false; 213 // same major - check ninor 214 if ($minorC > $minorR) return true; 215 if ($minorC < $minorR) return false; 216 // and same minor 217 if ($editC >= $editR) return true; 235 236 if ($majorC == $majorR) { 237 if($minorC < $minorR) return false; 238 239 if($minorC == $minorR){ 240 if($editC < $editR) return false; 241 } 242 } 243 218 244 return true; 219 245 } … … 227 253 } 228 254 229 230 255 // 231 256 // Make GD sanity check … … 233 258 if( !function_exists("imagetypes") || !function_exists('imagecreatefromstring') ) { 234 259 JpGraphError::RaiseL(25001); 235 //("This PHP installation is not configured with the GD library. Please recompile PHP with GD support to run JpGraph. (Neither function imagetypes() nor imagecreatefromstring() does exist)");260 //("This PHP installation is not configured with the GD library. Please recompile PHP with GD support to run JpGraph. (Neither function imagetypes() nor imagecreatefromstring() does exist)"); 236 261 } 237 262 … … 242 267 // Respect current error level 243 268 if( $errno & error_reporting() ) { 244 JpGraphError::RaiseL(25003,basename($filename),$linenum,$errmsg); 269 JpGraphError::RaiseL(25003,basename($filename),$linenum,$errmsg); 245 270 } 246 271 } … … 251 276 252 277 // 253 //Check if there were any warnings, perhaps some wrong includes by the 254 //user 278 // Check if there were any warnings, perhaps some wrong includes by the user. In this 279 // case we raise it immediately since otherwise the image will not show and makes 280 // debugging difficult. This is controlled by the user setting CATCH_PHPERRMSG 255 281 // 256 if( isset($GLOBALS['php_errormsg']) && CATCH_PHPERRMSG && 257 !preg_match('/|Deprecated|/i', $GLOBALS['php_errormsg']) ) { 282 if( isset($GLOBALS['php_errormsg']) && CATCH_PHPERRMSG && !preg_match('/|Deprecated|/i', $GLOBALS['php_errormsg']) ) { 258 283 JpGraphError::RaiseL(25004,$GLOBALS['php_errormsg']); 259 284 } 260 285 261 262 286 // Useful mathematical function 263 287 function sign($a) {return $a >= 0 ? 1 : -1;} 264 288 289 // 265 290 // Utility function to generate an image name based on the filename we 266 291 // are running from and assuming we use auto detection of graphic format 267 292 // (top level), i.e it is safe to call this function 268 293 // from a script that uses JpGraph 294 // 269 295 function GenImgName() { 270 296 // Determine what format we should use when we save the images 271 297 $supported = imagetypes(); 272 if( $supported & IMG_PNG ) 298 if( $supported & IMG_PNG ) $img_format="png"; 273 299 elseif( $supported & IMG_GIF ) $img_format="gif"; 274 300 elseif( $supported & IMG_JPG ) $img_format="jpeg"; … … 277 303 278 304 279 if( !isset($_SERVER['PHP_SELF']) ) 280 JpGraphError::RaiseL(25005); 281 //(" Can't access PHP_SELF, PHP global variable. You can't run PHP from command line if you want to use the 'auto' naming of cache or image files."); 305 if( !isset($_SERVER['PHP_SELF']) ) { 306 JpGraphError::RaiseL(25005); 307 //(" Can't access PHP_SELF, PHP global variable. You can't run PHP from command line if you want to use the 'auto' naming of cache or image files."); 308 } 282 309 $fname = basename($_SERVER['PHP_SELF']); 283 310 if( !empty($_SERVER['QUERY_STRING']) ) { 284 285 311 $q = @$_SERVER['QUERY_STRING']; 312 $fname .= '_'.preg_replace("/\W/", "_", $q).'.'.$img_format; 286 313 } 287 314 else { 288 315 $fname = substr($fname,0,strlen($fname)-4).'.'.$img_format; 289 316 } 290 317 return $fname; 291 318 } 292 293 319 294 320 //=================================================== … … 299 325 //=================================================== 300 326 class JpgTimer { 301 private $start, $idx; 302 //--------------- 303 // CONSTRUCTOR 304 function JpgTimer() { 305 $this->idx=0; 306 } 307 308 //--------------- 309 // PUBLIC METHODS 327 private $start, $idx; 328 329 function __construct() { 330 $this->idx=0; 331 } 310 332 311 333 // Push a new timer start on stack 312 334 function Push() { 313 list($ms,$s)=explode(" ",microtime()); 314 $this->start[$this->idx++]=floor($ms*1000) + 1000*$s; 335 list($ms,$s)=explode(" ",microtime()); 336 $this->start[$this->idx++]=floor($ms*1000) + 1000*$s; 315 337 } 316 338 … … 318 340 // current time 319 341 function Pop() { 320 321 list($ms,$s)=explode(" ",microtime()); 322 323 324 342 assert($this->idx>0); 343 list($ms,$s)=explode(" ",microtime()); 344 $etime=floor($ms*1000) + (1000*$s); 345 $this->idx--; 346 return $etime-$this->start[$this->idx]; 325 347 } 326 348 } // Class 327 349 328 $gJpgBrandTiming = BRAND_TIMING;329 350 //=================================================== 330 351 // CLASS DateLocale … … 332 353 //=================================================== 333 354 class DateLocale { 334 355 335 356 public $iLocale = 'C'; // environmental locale be used by default 336 357 private $iDayAbb = null, $iShortDay = null, $iShortMonth = null, $iMonthName = null; 337 358 338 //--------------- 339 // CONSTRUCTOR 340 function DateLocale() { 341 settype($this->iDayAbb, 'array'); 342 settype($this->iShortDay, 'array'); 343 settype($this->iShortMonth, 'array'); 344 settype($this->iMonthName, 'array'); 345 346 347 $this->Set('C'); 348 } 349 350 //--------------- 351 // PUBLIC METHODS 359 function __construct() { 360 settype($this->iDayAbb, 'array'); 361 settype($this->iShortDay, 'array'); 362 settype($this->iShortMonth, 'array'); 363 settype($this->iMonthName, 'array'); 364 $this->Set('C'); 365 } 366 352 367 function Set($aLocale) { 353 if ( in_array($aLocale, array_keys($this->iDayAbb)) ){ 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 if ( ! $res ){374 375 //("You are trying to use the locale ($aLocale) which your PHP installation does not support. Hint: Use '' to indicate the default locale for this geographic region.");376 377 378 379 380 for ( $i = 0, $ofs = 0 - strftime('%w'); $i < 7; $i++, $ofs++ ){381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 368 if ( in_array($aLocale, array_keys($this->iDayAbb)) ){ 369 $this->iLocale = $aLocale; 370 return TRUE; // already cached nothing else to do! 371 } 372 373 $pLocale = setlocale(LC_TIME, 0); // get current locale for LC_TIME 374 375 if (is_array($aLocale)) { 376 foreach ($aLocale as $loc) { 377 $res = @setlocale(LC_TIME, $loc); 378 if ( $res ) { 379 $aLocale = $loc; 380 break; 381 } 382 } 383 } 384 else { 385 $res = @setlocale(LC_TIME, $aLocale); 386 } 387 388 if ( ! $res ) { 389 JpGraphError::RaiseL(25007,$aLocale); 390 //("You are trying to use the locale ($aLocale) which your PHP installation does not support. Hint: Use '' to indicate the default locale for this geographic region."); 391 return FALSE; 392 } 393 394 $this->iLocale = $aLocale; 395 for( $i = 0, $ofs = 0 - strftime('%w'); $i < 7; $i++, $ofs++ ) { 396 $day = strftime('%a', strtotime("$ofs day")); 397 $day[0] = strtoupper($day[0]); 398 $this->iDayAbb[$aLocale][]= $day[0]; 399 $this->iShortDay[$aLocale][]= $day; 400 } 401 402 for($i=1; $i<=12; ++$i) { 403 list($short ,$full) = explode('|', strftime("%b|%B",strtotime("2001-$i-01"))); 404 $this->iShortMonth[$aLocale][] = ucfirst($short); 405 $this->iMonthName [$aLocale][] = ucfirst($full); 406 } 407 408 setlocale(LC_TIME, $pLocale); 409 410 return TRUE; 396 411 } 397 412 398 413 399 414 function GetDayAbb() { 400 401 } 402 415 return $this->iDayAbb[$this->iLocale]; 416 } 417 403 418 function GetShortDay() { 404 419 return $this->iShortDay[$this->iLocale]; 405 420 } 406 421 407 422 function GetShortMonth() { 408 409 } 410 423 return $this->iShortMonth[$this->iLocale]; 424 } 425 411 426 function GetShortMonthName($aNbr) { 412 427 return $this->iShortMonth[$this->iLocale][$aNbr]; 413 428 } 414 429 415 430 function GetLongMonthName($aNbr) { 416 431 return $this->iMonthName[$this->iLocale][$aNbr]; 417 432 } 418 433 419 434 function GetMonth() { 420 435 return $this->iMonthName[$this->iLocale]; 421 436 } 422 437 } 423 438 439 // Global object handlers 424 440 $gDateLocale = new DateLocale(); 425 441 $gJpgDateLocale = new DateLocale(); … … 432 448 public $iLeftMargin = 3, $iRightMargin = 3, $iBottomMargin = 3 ; 433 449 public $left,$center,$right; 434 435 function Footer() { 436 $this->left = new Text(); 437 $this->left->ParagraphAlign('left'); 438 $this->center = new Text(); 439 $this->center->ParagraphAlign('center'); 440 $this->right = new Text(); 441 $this->right->ParagraphAlign('right'); 450 private $iTimer=null, $itimerpoststring=''; 451 452 function __construct() { 453 $this->left = new Text(); 454 $this->left->ParagraphAlign('left'); 455 $this->center = new Text(); 456 $this->center->ParagraphAlign('center'); 457 $this->right = new Text(); 458 $this->right->ParagraphAlign('right'); 459 } 460 461 function SetTimer($aTimer,$aTimerPostString='') { 462 $this->iTimer = $aTimer; 463 $this->itimerpoststring = $aTimerPostString; 442 464 } 443 465 444 466 function SetMargin($aLeft=3,$aRight=3,$aBottom=3) { 445 446 447 467 $this->iLeftMargin = $aLeft; 468 $this->iRightMargin = $aRight; 469 $this->iBottomMargin = $aBottom; 448 470 } 449 471 450 472 function Stroke($aImg) { 451 $y = $aImg->height - $this->iBottomMargin; 452 $x = $this->iLeftMargin; 453 $this->left->Align('left','bottom'); 454 $this->left->Stroke($aImg,$x,$y); 455 456 $x = ($aImg->width - $this->iLeftMargin - $this->iRightMargin)/2; 457 $this->center->Align('center','bottom'); 458 $this->center->Stroke($aImg,$x,$y); 459 460 $x = $aImg->width - $this->iRightMargin; 461 $this->right->Align('right','bottom'); 462 $this->right->Stroke($aImg,$x,$y); 473 $y = $aImg->height - $this->iBottomMargin; 474 $x = $this->iLeftMargin; 475 $this->left->Align('left','bottom'); 476 $this->left->Stroke($aImg,$x,$y); 477 478 $x = ($aImg->width - $this->iLeftMargin - $this->iRightMargin)/2; 479 $this->center->Align('center','bottom'); 480 $this->center->Stroke($aImg,$x,$y); 481 482 $x = $aImg->width - $this->iRightMargin; 483 $this->right->Align('right','bottom'); 484 if( $this->iTimer != null ) { 485 $this->right->Set( $this->right->t . sprintf('%.3f',$this->iTimer->Pop()/1000.0) . $this->itimerpoststring ); 486 } 487 $this->right->Stroke($aImg,$x,$y); 463 488 } 464 489 } … … 470 495 //=================================================== 471 496 class Graph { 472 public $cache=null; 473 public $img=null; 474 public $plots=array(); 475 public $y2plots=array(); 497 public $cache=null; // Cache object (singleton) 498 public $img=null; // Img object (singleton) 499 public $plots=array(); // Array of all plot object in the graph (for Y 1 axis) 500 public $y2plots=array(); // Array of all plot object in the graph (for Y 2 axis) 476 501 public $ynplots=array(); 477 public $xscale=null; 502 public $xscale=null; // X Scale object (could be instance of LinearScale or LogScale 478 503 public $yscale=null,$y2scale=null, $ynscale=array(); 479 public $iIcons = array(); // Array of Icons to add to480 public $cache_name; 481 public $xgrid=null; 482 public $ygrid=null,$y2grid=null; 483 public $doframe =true,$frame_color=array(0,0,0), $frame_weight=1;// Frame around graph484 public $boxed=false, $box_color= array(0,0,0), $box_weight=1;// Box around plot area485 public $doshadow=false,$shadow_width=4,$shadow_color= array(102,102,102);// Shadow for graph486 public $xaxis=null; 487 public $yaxis=null, $y2axis=null, $ynaxis=array(); 488 public $margin_color =array(200,200,200);// Margin color of graph489 public $plotarea_color=array(255,255,255); 490 public $title,$subtitle,$subsubtitle; 491 public $axtype="linlin"; 492 public $xtick_factor,$ytick_factor; 493 public $texts=null, $y2texts=null; 504 public $iIcons = array(); // Array of Icons to add to 505 public $cache_name; // File name to be used for the current graph in the cache directory 506 public $xgrid=null; // X Grid object (linear or logarithmic) 507 public $ygrid=null,$y2grid=null; //dito for Y 508 public $doframe,$frame_color, $frame_weight; // Frame around graph 509 public $boxed=false, $box_color='black', $box_weight=1; // Box around plot area 510 public $doshadow=false,$shadow_width=4,$shadow_color='gray@0.5'; // Shadow for graph 511 public $xaxis=null; // X-axis (instane of Axis class) 512 public $yaxis=null, $y2axis=null, $ynaxis=array(); // Y axis (instance of Axis class) 513 public $margin_color; // Margin color of graph 514 public $plotarea_color=array(255,255,255); // Plot area color 515 public $title,$subtitle,$subsubtitle; // Title and subtitle(s) text object 516 public $axtype="linlin"; // Type of axis 517 public $xtick_factor,$ytick_factor; // Factor to determine the maximum number of ticks depending on the plot width 518 public $texts=null, $y2texts=null; // Text object to ge shown in the graph 494 519 public $lines=null, $y2lines=null; 495 520 public $bands=null, $y2bands=null; 496 public $text_scale_off=0, $text_scale_abscenteroff=-1; 497 public $background_image= "",$background_image_type=-1,$background_image_format="png";521 public $text_scale_off=0, $text_scale_abscenteroff=-1; // Text scale in fractions and for centering bars 522 public $background_image='',$background_image_type=-1,$background_image_format="png"; 498 523 public $background_image_bright=0,$background_image_contr=0,$background_image_sat=0; 499 524 public $background_image_xpos=0,$background_image_ypos=0; … … 501 526 public $inline; 502 527 public $showcsim=0,$csimcolor="red";//debug stuff, draw the csim boundaris on the image if <>0 503 public $grid_depth=DEPTH_BACK; 528 public $grid_depth=DEPTH_BACK; // Draw grid under all plots as default 504 529 public $iAxisStyle = AXSTYLE_SIMPLE; 505 530 public $iCSIMdisplay=false,$iHasStroked = false; … … 511 536 public $bkg_gradtype=-1,$bkg_gradstyle=BGRAD_MARGIN; 512 537 public $bkg_gradfrom='navy', $bkg_gradto='silver'; 538 public $plot_gradtype=-1,$plot_gradstyle=BGRAD_MARGIN; 539 public $plot_gradfrom='silver', $plot_gradto='navy'; 540 513 541 public $titlebackground = false; 514 542 public $titlebackground_color = 'lightblue', 515 516 $titlebackground_framecolor = 'blue',517 $titlebackground_framestyle = 2,518 $titlebackground_frameweight = 1,519 $titlebackground_bevelheight = 3;543 $titlebackground_style = 1, 544 $titlebackground_framecolor, 545 $titlebackground_framestyle, 546 $titlebackground_frameweight, 547 $titlebackground_bevelheight; 520 548 public $titlebkg_fillstyle=TITLEBKG_FILLSTYLE_SOLID; 521 549 public $titlebkg_scolor1='black',$titlebkg_scolor2='white'; 522 public $framebevel = false, $framebeveldepth = 2;523 public $framebevelborder = false, $framebevelbordercolor='black';524 public $framebevelcolor1 ='white@0.4', $framebevelcolor2='black@0.4';550 public $framebevel, $framebeveldepth; 551 public $framebevelborder, $framebevelbordercolor; 552 public $framebevelcolor1, $framebevelcolor2; 525 553 public $background_image_mix=100; 526 554 public $background_cflag = ''; … … 528 556 public $background_cflag_mix = 100; 529 557 public $iImgTrans=false, 530 531 532 533 558 $iImgTransHorizon = 100,$iImgTransSkewDist=150, 559 $iImgTransDirection = 1, $iImgTransMinSize = true, 560 $iImgTransFillColor='white',$iImgTransHighQ=false, 561 $iImgTransBorder=false,$iImgTransHorizonPos=0.5; 534 562 public $legend; 563 public $graph_theme; 535 564 protected $iYAxisDeltaPos=50; 536 565 protected $iIconDepth=DEPTH_BACK; 537 566 protected $iAxisLblBgType = 0, 538 539 567 $iXAxisLblBgFillColor = 'lightgray', $iXAxisLblBgColor = 'black', 568 $iYAxisLblBgFillColor = 'lightgray', $iYAxisLblBgColor = 'black'; 540 569 protected $iTables=NULL; 541 570 542 //--------------- 543 // CONSTRUCTOR 544 545 // aWIdth Width in pixels of image 546 // aHeight Height in pixels of image 547 // aCachedName Name for image file in cache directory 548 // aTimeOut Timeout in minutes for image in cache 549 // aInline If true the image is streamed back in the call to Stroke() 550 // If false the image is just created in the cache 551 function Graph($aWidth=300,$aHeight=200,$aCachedName="",$aTimeOut=0,$aInline=true) { 552 GLOBAL $gJpgBrandTiming; 553 // If timing is used create a new timing object 554 if( $gJpgBrandTiming ) { 555 global $tim; 556 $tim = new JpgTimer(); 557 $tim->Push(); 558 } 559 560 if( !is_numeric($aWidth) || !is_numeric($aHeight) ) { 561 JpGraphError::RaiseL(25008);//('Image width/height argument in Graph::Graph() must be numeric'); 562 } 563 564 // Automatically generate the image file name based on the name of the script that 565 // generates the graph 566 if( $aCachedName=="auto" ) 567 $aCachedName=GenImgName(); 568 569 // Should the image be streamed back to the browser or only to the cache? 570 $this->inline=$aInline; 571 572 $this->img = new RotImage($aWidth,$aHeight); 573 574 $this->cache = new ImgStreamCache($this->img); 575 $this->cache->SetTimeOut($aTimeOut); 576 577 $this->title = new Text(); 578 $this->title->ParagraphAlign('center'); 579 $this->title->SetFont(FF_FONT2,FS_BOLD); 580 $this->title->SetMargin(3); 581 $this->title->SetAlign('center'); 582 583 $this->subtitle = new Text(); 584 $this->subtitle->ParagraphAlign('center'); 585 $this->subtitle->SetMargin(2); 586 $this->subtitle->SetAlign('center'); 587 588 $this->subsubtitle = new Text(); 589 $this->subsubtitle->ParagraphAlign('center'); 590 $this->subsubtitle->SetMargin(2); 591 $this->subsubtitle->SetAlign('center'); 592 593 $this->legend = new Legend(); 594 $this->footer = new Footer(); 595 596 // Window doesn't like '?' in the file name so replace it with an '_' 597 $aCachedName = str_replace("?","_",$aCachedName); 598 599 // If the cached version exist just read it directly from the 600 // cache, stream it back to browser and exit 601 if( $aCachedName!="" && READ_CACHE && $aInline ) 602 if( $this->cache->GetAndStream($aCachedName) ) { 603 exit(); 604 } 605 606 $this->cache_name = $aCachedName; 607 $this->SetTickDensity(); // Normal density 608 609 $this->tabtitle = new GraphTabTitle(); 610 } 611 //--------------- 612 // PUBLIC METHODS 613 571 protected $isRunningClear = false; 572 protected $inputValues; 573 protected $isAfterSetScale = false; 574 575 // aWIdth Width in pixels of image 576 // aHeight Height in pixels of image 577 // aCachedName Name for image file in cache directory 578 // aTimeOut Timeout in minutes for image in cache 579 // aInline If true the image is streamed back in the call to Stroke() 580 // If false the image is just created in the cache 581 function __construct($aWidth=300,$aHeight=200,$aCachedName='',$aTimeout=0,$aInline=true) { 582 583 if( !is_numeric($aWidth) || !is_numeric($aHeight) ) { 584 JpGraphError::RaiseL(25008);//('Image width/height argument in Graph::Graph() must be numeric'); 585 } 586 587 // Initialize frame and margin 588 $this->InitializeFrameAndMargin(); 589 590 // Automatically generate the image file name based on the name of the script that 591 // generates the graph 592 if( $aCachedName == 'auto' ) { 593 $aCachedName=GenImgName(); 594 } 595 596 // Should the image be streamed back to the browser or only to the cache? 597 $this->inline=$aInline; 598 599 $this->img = new RotImage($aWidth,$aHeight); 600 $this->cache = new ImgStreamCache(); 601 602 // Window doesn't like '?' in the file name so replace it with an '_' 603 $aCachedName = str_replace("?","_",$aCachedName); 604 $this->SetupCache($aCachedName, $aTimeout); 605 606 $this->title = new Text(); 607 $this->title->ParagraphAlign('center'); 608 $this->title->SetFont(FF_DEFAULT,FS_NORMAL); //FF_FONT2, FS_BOLD 609 $this->title->SetMargin(5); 610 $this->title->SetAlign('center'); 611 612 $this->subtitle = new Text(); 613 $this->subtitle->ParagraphAlign('center'); 614 $this->subtitle->SetMargin(3); 615 $this->subtitle->SetAlign('center'); 616 617 $this->subsubtitle = new Text(); 618 $this->subsubtitle->ParagraphAlign('center'); 619 $this->subsubtitle->SetMargin(3); 620 $this->subsubtitle->SetAlign('center'); 621 622 $this->legend = new Legend(); 623 $this->footer = new Footer(); 624 625 // If the cached version exist just read it directly from the 626 // cache, stream it back to browser and exit 627 if( $aCachedName!='' && READ_CACHE && $aInline ) { 628 if( $this->cache->GetAndStream($this->img,$aCachedName) ) { 629 exit(); 630 } 631 } 632 633 $this->SetTickDensity(); // Normal density 634 635 $this->tabtitle = new GraphTabTitle(); 636 637 if (!$this->isRunningClear) { 638 $this->inputValues = array(); 639 $this->inputValues['aWidth'] = $aWidth; 640 $this->inputValues['aHeight'] = $aHeight; 641 $this->inputValues['aCachedName'] = $aCachedName; 642 $this->inputValues['aTimeout'] = $aTimeout; 643 $this->inputValues['aInline'] = $aInline; 644 645 $theme_class = DEFAULT_THEME_CLASS; 646 if (class_exists($theme_class)) { 647 $this->graph_theme = new $theme_class(); 648 } 649 } 650 } 651 652 function InitializeFrameAndMargin() { 653 $this->doframe=true; 654 $this->frame_color='black'; 655 $this->frame_weight=1; 656 657 $this->titlebackground_framecolor = 'blue'; 658 $this->titlebackground_framestyle = 2; 659 $this->titlebackground_frameweight = 1; 660 $this->titlebackground_bevelheight = 3; 661 $this->titlebkg_fillstyle=TITLEBKG_FILLSTYLE_SOLID; 662 $this->titlebkg_scolor1='black'; 663 $this->titlebkg_scolor2='white'; 664 $this->framebevel = false; 665 $this->framebeveldepth = 2; 666 $this->framebevelborder = false; 667 $this->framebevelbordercolor='black'; 668 $this->framebevelcolor1='white@0.4'; 669 $this->framebevelcolor2='black@0.4'; 670 671 $this->margin_color = array(250,250,250); 672 } 673 674 function SetupCache($aFilename,$aTimeout=60) { 675 $this->cache_name = $aFilename; 676 $this->cache->SetTimeOut($aTimeout); 677 } 678 614 679 // Enable final image perspective transformation 615 680 function Set3DPerspective($aDir=1,$aHorizon=100,$aSkewDist=120,$aQuality=false,$aFillColor='#FFFFFF',$aBorder=false,$aMinSize=true,$aHorizonPos=0.5) { 616 617 618 619 620 621 622 623 624 681 $this->iImgTrans = true; 682 $this->iImgTransHorizon = $aHorizon; 683 $this->iImgTransSkewDist= $aSkewDist; 684 $this->iImgTransDirection = $aDir; 685 $this->iImgTransMinSize = $aMinSize; 686 $this->iImgTransFillColor=$aFillColor; 687 $this->iImgTransHighQ=$aQuality; 688 $this->iImgTransBorder=$aBorder; 689 $this->iImgTransHorizonPos=$aHorizonPos; 625 690 } 626 691 627 692 function SetUserFont($aNormal,$aBold='',$aItalic='',$aBoldIt='') { 628 693 $this->img->ttf->SetUserFont($aNormal,$aBold,$aItalic,$aBoldIt); 629 694 } 630 695 631 696 function SetUserFont1($aNormal,$aBold='',$aItalic='',$aBoldIt='') { 632 697 $this->img->ttf->SetUserFont1($aNormal,$aBold,$aItalic,$aBoldIt); 633 698 } 634 699 635 700 function SetUserFont2($aNormal,$aBold='',$aItalic='',$aBoldIt='') { 636 701 $this->img->ttf->SetUserFont2($aNormal,$aBold,$aItalic,$aBoldIt); 637 702 } 638 703 639 704 function SetUserFont3($aNormal,$aBold='',$aItalic='',$aBoldIt='') { 640 705 $this->img->ttf->SetUserFont3($aNormal,$aBold,$aItalic,$aBoldIt); 641 706 } 642 707 643 708 // Set Image format and optional quality 644 709 function SetImgFormat($aFormat,$aQuality=75) { 645 710 $this->img->SetImgFormat($aFormat,$aQuality); 646 711 } 647 712 648 713 // Should the grid be in front or back of the plot? 649 714 function SetGridDepth($aDepth) { 650 715 $this->grid_depth=$aDepth; 651 716 } 652 717 653 718 function SetIconDepth($aDepth) { 654 655 } 656 719 $this->iIconDepth=$aDepth; 720 } 721 657 722 // Specify graph angle 0-360 degrees. 658 723 function SetAngle($aAngle) { 659 724 $this->img->SetAngle($aAngle); 660 725 } 661 726 662 727 function SetAlphaBlending($aFlg=true) { 663 728 $this->img->SetAlphaBlending($aFlg); 664 729 } 665 730 666 731 // Shortcut to image margin 667 732 function SetMargin($lm,$rm,$tm,$bm) { 668 733 $this->img->SetMargin($lm,$rm,$tm,$bm); 669 734 } 670 735 671 736 function SetY2OrderBack($aBack=true) { 672 673 } 674 675 // Rotate the graph 90 degrees and set the margin 737 $this->y2orderback = $aBack; 738 } 739 740 // Rotate the graph 90 degrees and set the margin 676 741 // when we have done a 90 degree rotation 677 742 function Set90AndMargin($lm=0,$rm=0,$tm=0,$bm=0) { 678 $lm = $lm ==0 ? floor(0.2 * $this->img->width) : $lm ; 679 $rm = $rm ==0 ? floor(0.1 * $this->img->width) : $rm ; 680 $tm = $tm ==0 ? floor(0.2 * $this->img->height) : $tm ; 681 $bm = $bm ==0 ? floor(0.1 * $this->img->height) : $bm ; 682 683 $adj = ($this->img->height - $this->img->width)/2; 684 $this->img->SetMargin($tm-$adj,$bm-$adj,$rm+$adj,$lm+$adj); 685 $this->img->SetCenter(floor($this->img->width/2),floor($this->img->height/2)); 686 $this->SetAngle(90); 687 if( empty($this->yaxis) || empty($this->xaxis) ) { 688 JpgraphError::RaiseL(25009);//('You must specify what scale to use with a call to Graph::SetScale()'); 689 } 690 $this->xaxis->SetLabelAlign('right','center'); 691 $this->yaxis->SetLabelAlign('center','bottom'); 692 } 693 743 $adj = ($this->img->height - $this->img->width)/2; 744 $this->img->SetMargin($tm-$adj,$bm-$adj,$rm+$adj,$lm+$adj); 745 $this->img->SetCenter(floor($this->img->width/2),floor($this->img->height/2)); 746 $this->SetAngle(90); 747 if( empty($this->yaxis) || empty($this->xaxis) ) { 748 JpgraphError::RaiseL(25009);//('You must specify what scale to use with a call to Graph::SetScale()'); 749 } 750 $this->xaxis->SetLabelAlign('right','center'); 751 $this->yaxis->SetLabelAlign('center','bottom'); 752 } 753 694 754 function SetClipping($aFlg=true) { 695 755 $this->iDoClipping = $aFlg ; 696 756 } 697 757 698 758 // Add a plot object to the graph 699 759 function Add($aPlot) { 700 if( $aPlot == null ) 701 JpGraphError::RaiseL(25010);//("Graph::Add() You tried to add a null plot to the graph."); 702 if( is_array($aPlot) && count($aPlot) > 0 ) 703 $cl = $aPlot[0]; 704 else 705 $cl = $aPlot; 706 707 if( $cl instanceof Text ) 708 $this->AddText($aPlot); 709 elseif( $cl instanceof PlotLine ) 710 $this->AddLine($aPlot); 711 elseif( class_exists('PlotBand',false) && ($cl instanceof PlotBand) ) 712 $this->AddBand($aPlot); 713 elseif( class_exists('IconPlot',false) && ($cl instanceof IconPlot) ) 714 $this->AddIcon($aPlot); 715 elseif( class_exists('GTextTable',false) && ($cl instanceof GTextTable) ) 716 $this->AddTable($aPlot); 717 else 718 $this->plots[] = $aPlot; 760 if( $aPlot == null ) { 761 JpGraphError::RaiseL(25010);//("Graph::Add() You tried to add a null plot to the graph."); 762 } 763 if( is_array($aPlot) && count($aPlot) > 0 ) { 764 $cl = $aPlot[0]; 765 } 766 else { 767 $cl = $aPlot; 768 } 769 770 if( $cl instanceof Text ) $this->AddText($aPlot); 771 elseif( class_exists('PlotLine',false) && ($cl instanceof PlotLine) ) $this->AddLine($aPlot); 772 elseif( class_exists('PlotBand',false) && ($cl instanceof PlotBand) ) $this->AddBand($aPlot); 773 elseif( class_exists('IconPlot',false) && ($cl instanceof IconPlot) ) $this->AddIcon($aPlot); 774 elseif( class_exists('GTextTable',false) && ($cl instanceof GTextTable) ) $this->AddTable($aPlot); 775 else { 776 if( is_array($aPlot) ) { 777 $this->plots = array_merge($this->plots,$aPlot); 778 } 779 else { 780 $this->plots[] = $aPlot; 781 } 782 } 783 784 if ($this->graph_theme) { 785 $this->graph_theme->SetupPlot($aPlot); 786 } 719 787 } 720 788 721 789 function AddTable($aTable) { 722 if( is_array($aTable) ) { 723 for($i=0; $i < count($aTable); ++$i ) 724 $this->iTables[]=$aTable[$i]; 725 } 726 else { 727 $this->iTables[] = $aTable ; 728 } 790 if( is_array($aTable) ) { 791 for($i=0; $i < count($aTable); ++$i ) { 792 $this->iTables[]=$aTable[$i]; 793 } 794 } 795 else { 796 $this->iTables[] = $aTable ; 797 } 729 798 } 730 799 731 800 function AddIcon($aIcon) { 732 if( is_array($aIcon) ) { 733 for($i=0; $i < count($aIcon); ++$i ) 734 $this->iIcons[]=$aIcon[$i]; 735 } 736 else { 737 $this->iIcons[] = $aIcon ; 738 } 801 if( is_array($aIcon) ) { 802 for($i=0; $i < count($aIcon); ++$i ) { 803 $this->iIcons[]=$aIcon[$i]; 804 } 805 } 806 else { 807 $this->iIcons[] = $aIcon ; 808 } 739 809 } 740 810 741 811 // Add plot to second Y-scale 742 812 function AddY2($aPlot) { 743 if( $aPlot == null ) 744 JpGraphError::RaiseL(25011);//("Graph::AddY2() You tried to add a null plot to the graph."); 745 746 if( is_array($aPlot) && count($aPlot) > 0 ) 747 $cl = $aPlot[0]; 748 else 749 $cl = $aPlot; 750 751 if( $cl instanceof Text ) 752 $this->AddText($aPlot,true); 753 elseif( $cl instanceof PlotLine ) 754 $this->AddLine($aPlot,true); 755 elseif( class_exists('PlotBand',false) && ($cl instanceof PlotBand) ) 756 $this->AddBand($aPlot,true); 757 else 758 $this->y2plots[] = $aPlot; 759 } 760 813 if( $aPlot == null ) { 814 JpGraphError::RaiseL(25011);//("Graph::AddY2() You tried to add a null plot to the graph."); 815 } 816 817 if( is_array($aPlot) && count($aPlot) > 0 ) { 818 $cl = $aPlot[0]; 819 } 820 else { 821 $cl = $aPlot; 822 } 823 824 if( $cl instanceof Text ) { 825 $this->AddText($aPlot,true); 826 } 827 elseif( class_exists('PlotLine',false) && ($cl instanceof PlotLine) ) { 828 $this->AddLine($aPlot,true); 829 } 830 elseif( class_exists('PlotBand',false) && ($cl instanceof PlotBand) ) { 831 $this->AddBand($aPlot,true); 832 } 833 else { 834 $this->y2plots[] = $aPlot; 835 } 836 837 if ($this->graph_theme) { 838 $this->graph_theme->SetupPlot($aPlot); 839 } 840 } 841 761 842 // Add plot to the extra Y-axises 762 843 function AddY($aN,$aPlot) { 763 844 764 if( $aPlot == null ) 765 JpGraphError::RaiseL(25012);//("Graph::AddYN() You tried to add a null plot to the graph."); 766 767 if( is_array($aPlot) && count($aPlot) > 0 ) 768 $cl = $aPlot[0]; 769 else 770 $cl = $aPlot; 771 772 if( ($cl instanceof Text) || ($cl instanceof PlotLine) || 773 (class_exists('PlotBand',false) && ($cl instanceof PlotBand)) ) 774 JpGraph::RaiseL(25013);//('You can only add standard plots to multiple Y-axis'); 775 else 776 $this->ynplots[$aN][] = $aPlot; 845 if( $aPlot == null ) { 846 JpGraphError::RaiseL(25012);//("Graph::AddYN() You tried to add a null plot to the graph."); 847 } 848 849 if( is_array($aPlot) && count($aPlot) > 0 ) { 850 $cl = $aPlot[0]; 851 } 852 else { 853 $cl = $aPlot; 854 } 855 856 if( ($cl instanceof Text) || 857 (class_exists('PlotLine',false) && ($cl instanceof PlotLine)) || 858 (class_exists('PlotBand',false) && ($cl instanceof PlotBand)) ) { 859 JpGraph::RaiseL(25013);//('You can only add standard plots to multiple Y-axis'); 860 } 861 else { 862 $this->ynplots[$aN][] = $aPlot; 863 } 864 865 if ($this->graph_theme) { 866 $this->graph_theme->SetupPlot($aPlot); 867 } 777 868 } 778 869 779 870 // Add text object to the graph 780 871 function AddText($aTxt,$aToY2=false) { 781 if( $aTxt == null ) 782 JpGraphError::RaiseL(25014);//("Graph::AddText() You tried to add a null text to the graph."); 783 if( $aToY2 ) { 784 if( is_array($aTxt) ) { 785 for($i=0; $i < count($aTxt); ++$i ) 786 $this->y2texts[]=$aTxt[$i]; 787 } 788 else 789 $this->y2texts[] = $aTxt; 790 } 791 else { 792 if( is_array($aTxt) ) { 793 for($i=0; $i < count($aTxt); ++$i ) 794 $this->texts[]=$aTxt[$i]; 795 } 796 else 797 $this->texts[] = $aTxt; 798 } 799 } 800 872 if( $aTxt == null ) { 873 JpGraphError::RaiseL(25014);//("Graph::AddText() You tried to add a null text to the graph."); 874 } 875 if( $aToY2 ) { 876 if( is_array($aTxt) ) { 877 for($i=0; $i < count($aTxt); ++$i ) { 878 $this->y2texts[]=$aTxt[$i]; 879 } 880 } 881 else { 882 $this->y2texts[] = $aTxt; 883 } 884 } 885 else { 886 if( is_array($aTxt) ) { 887 for($i=0; $i < count($aTxt); ++$i ) { 888 $this->texts[]=$aTxt[$i]; 889 } 890 } 891 else { 892 $this->texts[] = $aTxt; 893 } 894 } 895 } 896 801 897 // Add a line object (class PlotLine) to the graph 802 898 function AddLine($aLine,$aToY2=false) { 803 if( $aLine == null ) 804 JpGraphError::RaiseL(25015);//("Graph::AddLine() You tried to add a null line to the graph."); 805 806 if( $aToY2 ) { 807 if( is_array($aLine) ) { 808 for($i=0; $i < count($aLine); ++$i ) 809 $this->y2lines[]=$aLine[$i]; 810 } 811 else 812 $this->y2lines[] = $aLine; 813 } 814 else { 815 if( is_array($aLine) ) { 816 for($i=0; $i<count($aLine); ++$i ) 817 $this->lines[]=$aLine[$i]; 818 } 819 else 820 $this->lines[] = $aLine; 821 } 899 if( $aLine == null ) { 900 JpGraphError::RaiseL(25015);//("Graph::AddLine() You tried to add a null line to the graph."); 901 } 902 903 if( $aToY2 ) { 904 if( is_array($aLine) ) { 905 for($i=0; $i < count($aLine); ++$i ) { 906 //$this->y2lines[]=$aLine[$i]; 907 $this->y2plots[]=$aLine[$i]; 908 } 909 } 910 else { 911 //$this->y2lines[] = $aLine; 912 $this->y2plots[]=$aLine; 913 } 914 } 915 else { 916 if( is_array($aLine) ) { 917 for($i=0; $i<count($aLine); ++$i ) { 918 //$this->lines[]=$aLine[$i]; 919 $this->plots[]=$aLine[$i]; 920 } 921 } 922 else { 923 //$this->lines[] = $aLine; 924 $this->plots[] = $aLine; 925 } 926 } 822 927 } 823 928 824 929 // Add vertical or horizontal band 825 930 function AddBand($aBand,$aToY2=false) { 826 if( $aBand == null ) 827 JpGraphError::RaiseL(25016);//(" Graph::AddBand() You tried to add a null band to the graph."); 828 829 if( $aToY2 ) { 830 if( is_array($aBand) ) { 831 for($i=0; $i < count($aBand); ++$i ) 832 $this->y2bands[] = $aBand[$i]; 833 } 834 else 835 $this->y2bands[] = $aBand; 836 } 837 else { 838 if( is_array($aBand) ) { 839 for($i=0; $i < count($aBand); ++$i ) 840 $this->bands[] = $aBand[$i]; 841 } 842 else 843 $this->bands[] = $aBand; 844 } 931 if( $aBand == null ) { 932 JpGraphError::RaiseL(25016);//(" Graph::AddBand() You tried to add a null band to the graph."); 933 } 934 935 if( $aToY2 ) { 936 if( is_array($aBand) ) { 937 for($i=0; $i < count($aBand); ++$i ) { 938 $this->y2bands[] = $aBand[$i]; 939 } 940 } 941 else { 942 $this->y2bands[] = $aBand; 943 } 944 } 945 else { 946 if( is_array($aBand) ) { 947 for($i=0; $i < count($aBand); ++$i ) { 948 $this->bands[] = $aBand[$i]; 949 } 950 } 951 else { 952 $this->bands[] = $aBand; 953 } 954 } 955 } 956 957 function SetPlotGradient($aFrom='navy',$aTo='silver',$aGradType=2) { 958 $this->plot_gradtype=$aGradType; 959 $this->plot_gradfrom = $aFrom; 960 $this->plot_gradto = $aTo; 845 961 } 846 962 847 963 function SetBackgroundGradient($aFrom='navy',$aTo='silver',$aGradType=2,$aStyle=BGRAD_FRAME) { 848 849 850 851 852 } 853 964 $this->bkg_gradtype=$aGradType; 965 $this->bkg_gradstyle=$aStyle; 966 $this->bkg_gradfrom = $aFrom; 967 $this->bkg_gradto = $aTo; 968 } 969 854 970 // Set a country flag in the background 855 971 function SetBackgroundCFlag($aName,$aBgType=BGIMG_FILLPLOT,$aMix=100) { 856 857 858 972 $this->background_cflag = $aName; 973 $this->background_cflag_type = $aBgType; 974 $this->background_cflag_mix = $aMix; 859 975 } 860 976 861 977 // Alias for the above method 862 978 function SetBackgroundCountryFlag($aName,$aBgType=BGIMG_FILLPLOT,$aMix=100) { 863 864 865 979 $this->background_cflag = $aName; 980 $this->background_cflag_type = $aBgType; 981 $this->background_cflag_mix = $aMix; 866 982 } 867 983 868 984 869 985 // Specify a background image 870 function SetBackgroundImage($aFileName,$aBgType=BGIMG_FILLPLOT,$aImgFormat="auto") { 871 872 if( !USE_TRUECOLOR ) { 873 JpGraphError::RaiseL(25017);//("You are using GD 2.x and are trying to use a background images on a non truecolor image. To use background images with GD 2.x you <b>must</b> enable truecolor by setting the USE_TRUECOLOR constant to TRUE. Due to a bug in GD 2.0.1 using any truetype fonts with truecolor images will result in very poor quality fonts."); 874 } 875 876 // Get extension to determine image type 877 if( $aImgFormat == "auto" ) { 878 $e = explode('.',$aFileName); 879 if( !$e ) { 880 JpGraphError::RaiseL(25018,$aFileName);//('Incorrect file name for Graph::SetBackgroundImage() : '.$aFileName.' Must have a valid image extension (jpg,gif,png) when using autodetection of image type'); 881 } 882 883 $valid_formats = array('png', 'jpg', 'gif'); 884 $aImgFormat = strtolower($e[count($e)-1]); 885 if ($aImgFormat == 'jpeg') { 886 $aImgFormat = 'jpg'; 887 } 888 elseif (!in_array($aImgFormat, $valid_formats) ) { 889 JpGraphError::RaiseL(25019,$aImgFormat);//('Unknown file extension ($aImgFormat) in Graph::SetBackgroundImage() for filename: '.$aFileName); 890 } 891 } 892 893 $this->background_image = $aFileName; 894 $this->background_image_type=$aBgType; 895 $this->background_image_format=$aImgFormat; 986 function SetBackgroundImage($aFileName,$aBgType=BGIMG_FILLPLOT,$aImgFormat='auto') { 987 988 // Get extension to determine image type 989 if( $aImgFormat == 'auto' ) { 990 $e = explode('.',$aFileName); 991 if( !$e ) { 992 JpGraphError::RaiseL(25018,$aFileName);//('Incorrect file name for Graph::SetBackgroundImage() : '.$aFileName.' Must have a valid image extension (jpg,gif,png) when using autodetection of image type'); 993 } 994 995 $valid_formats = array('png', 'jpg', 'gif'); 996 $aImgFormat = strtolower($e[count($e)-1]); 997 if ($aImgFormat == 'jpeg') { 998 $aImgFormat = 'jpg'; 999 } 1000 elseif (!in_array($aImgFormat, $valid_formats) ) { 1001 JpGraphError::RaiseL(25019,$aImgFormat);//('Unknown file extension ($aImgFormat) in Graph::SetBackgroundImage() for filename: '.$aFileName); 1002 } 1003 } 1004 1005 $this->background_image = $aFileName; 1006 $this->background_image_type=$aBgType; 1007 $this->background_image_format=$aImgFormat; 896 1008 } 897 1009 898 1010 function SetBackgroundImageMix($aMix) { 899 900 } 901 1011 $this->background_image_mix = $aMix ; 1012 } 1013 902 1014 // Adjust background image position 903 1015 function SetBackgroundImagePos($aXpos,$aYpos) { 904 905 906 } 907 1016 $this->background_image_xpos = $aXpos ; 1017 $this->background_image_ypos = $aYpos ; 1018 } 1019 908 1020 // Specify axis style (boxed or single) 909 1021 function SetAxisStyle($aStyle) { 910 1022 $this->iAxisStyle = $aStyle ; 911 1023 } 912 1024 913 1025 // Set a frame around the plot area 914 1026 function SetBox($aDrawPlotFrame=true,$aPlotFrameColor=array(0,0,0),$aPlotFrameWeight=1) { 915 916 917 918 } 919 1027 $this->boxed = $aDrawPlotFrame; 1028 $this->box_weight = $aPlotFrameWeight; 1029 $this->box_color = $aPlotFrameColor; 1030 } 1031 920 1032 // Specify color for the plotarea (not the margins) 921 1033 function SetColor($aColor) { 922 923 } 924 1034 $this->plotarea_color=$aColor; 1035 } 1036 925 1037 // Specify color for the margins (all areas outside the plotarea) 926 1038 function SetMarginColor($aColor) { 927 928 } 929 1039 $this->margin_color=$aColor; 1040 } 1041 930 1042 // Set a frame around the entire image 931 1043 function SetFrame($aDrawImgFrame=true,$aImgFrameColor=array(0,0,0),$aImgFrameWeight=1) { 932 933 934 1044 $this->doframe = $aDrawImgFrame; 1045 $this->frame_color = $aImgFrameColor; 1046 $this->frame_weight = $aImgFrameWeight; 935 1047 } 936 1048 937 1049 function SetFrameBevel($aDepth=3,$aBorder=false,$aBorderColor='black',$aColor1='white@0.4',$aColor2='darkgray@0.4',$aFlg=true) { 938 939 940 941 942 943 944 945 1050 $this->framebevel = $aFlg ; 1051 $this->framebeveldepth = $aDepth ; 1052 $this->framebevelborder = $aBorder ; 1053 $this->framebevelbordercolor = $aBorderColor ; 1054 $this->framebevelcolor1 = $aColor1 ; 1055 $this->framebevelcolor2 = $aColor2 ; 1056 1057 $this->doshadow = false ; 946 1058 } 947 1059 948 1060 // Set the shadow around the whole image 949 function SetShadow($aShowShadow=true,$aShadowWidth=5,$aShadowColor= array(102,102,102)) {950 951 952 953 954 1061 function SetShadow($aShowShadow=true,$aShadowWidth=5,$aShadowColor='darkgray') { 1062 $this->doshadow = $aShowShadow; 1063 $this->shadow_color = $aShadowColor; 1064 $this->shadow_width = $aShadowWidth; 1065 $this->footer->iBottomMargin += $aShadowWidth; 1066 $this->footer->iRightMargin += $aShadowWidth; 955 1067 } 956 1068 … … 958 1070 // you must also specify the tick distance with a call to Ticks::Set() 959 1071 function SetScale($aAxisType,$aYMin=1,$aYMax=1,$aXMin=1,$aXMax=1) { 960 $this->axtype = $aAxisType; 961 962 if( $aYMax < $aYMin || $aXMax < $aXMin ) 963 JpGraphError::RaiseL(25020);//('Graph::SetScale(): Specified Max value must be larger than the specified Min value.'); 964 965 $yt=substr($aAxisType,-3,3); 966 if( $yt=="lin" ) 967 $this->yscale = new LinearScale($aYMin,$aYMax); 968 elseif( $yt == "int" ) { 969 $this->yscale = new LinearScale($aYMin,$aYMax); 970 $this->yscale->SetIntScale(); 971 } 972 elseif( $yt=="log" ) 973 $this->yscale = new LogScale($aYMin,$aYMax); 974 else 975 JpGraphError::RaiseL(25021,$aAxisType);//("Unknown scale specification for Y-scale. ($aAxisType)"); 976 977 $xt=substr($aAxisType,0,3); 978 if( $xt == "lin" || $xt == "tex" ) { 979 $this->xscale = new LinearScale($aXMin,$aXMax,"x"); 980 $this->xscale->textscale = ($xt == "tex"); 981 } 982 elseif( $xt == "int" ) { 983 $this->xscale = new LinearScale($aXMin,$aXMax,"x"); 984 $this->xscale->SetIntScale(); 985 } 986 elseif( $xt == "dat" ) { 987 $this->xscale = new DateScale($aXMin,$aXMax,"x"); 988 } 989 elseif( $xt == "log" ) 990 $this->xscale = new LogScale($aXMin,$aXMax,"x"); 991 else 992 JpGraphError::RaiseL(25022,$aAxisType);//(" Unknown scale specification for X-scale. ($aAxisType)"); 993 994 $this->xaxis = new Axis($this->img,$this->xscale); 995 $this->yaxis = new Axis($this->img,$this->yscale); 996 $this->xgrid = new Grid($this->xaxis); 997 $this->ygrid = new Grid($this->yaxis); 998 $this->ygrid->Show(); 999 } 1000 1072 $this->axtype = $aAxisType; 1073 1074 if( $aYMax < $aYMin || $aXMax < $aXMin ) { 1075 JpGraphError::RaiseL(25020);//('Graph::SetScale(): Specified Max value must be larger than the specified Min value.'); 1076 } 1077 1078 $yt=substr($aAxisType,-3,3); 1079 if( $yt == 'lin' ) { 1080 $this->yscale = new LinearScale($aYMin,$aYMax); 1081 } 1082 elseif( $yt == 'int' ) { 1083 $this->yscale = new LinearScale($aYMin,$aYMax); 1084 $this->yscale->SetIntScale(); 1085 } 1086 elseif( $yt == 'log' ) { 1087 $this->yscale = new LogScale($aYMin,$aYMax); 1088 } 1089 else { 1090 JpGraphError::RaiseL(25021,$aAxisType);//("Unknown scale specification for Y-scale. ($aAxisType)"); 1091 } 1092 1093 $xt=substr($aAxisType,0,3); 1094 if( $xt == 'lin' || $xt == 'tex' ) { 1095 $this->xscale = new LinearScale($aXMin,$aXMax,'x'); 1096 $this->xscale->textscale = ($xt == 'tex'); 1097 } 1098 elseif( $xt == 'int' ) { 1099 $this->xscale = new LinearScale($aXMin,$aXMax,'x'); 1100 $this->xscale->SetIntScale(); 1101 } 1102 elseif( $xt == 'dat' ) { 1103 $this->xscale = new DateScale($aXMin,$aXMax,'x'); 1104 } 1105 elseif( $xt == 'log' ) { 1106 $this->xscale = new LogScale($aXMin,$aXMax,'x'); 1107 } 1108 else { 1109 JpGraphError::RaiseL(25022,$aAxisType);//(" Unknown scale specification for X-scale. ($aAxisType)"); 1110 } 1111 1112 $this->xaxis = new Axis($this->img,$this->xscale); 1113 $this->yaxis = new Axis($this->img,$this->yscale); 1114 $this->xgrid = new Grid($this->xaxis); 1115 $this->ygrid = new Grid($this->yaxis); 1116 $this->ygrid->Show(); 1117 1118 1119 if (!$this->isRunningClear) { 1120 $this->inputValues['aAxisType'] = $aAxisType; 1121 $this->inputValues['aYMin'] = $aYMin; 1122 $this->inputValues['aYMax'] = $aYMax; 1123 $this->inputValues['aXMin'] = $aXMin; 1124 $this->inputValues['aXMax'] = $aXMax; 1125 1126 if ($this->graph_theme) { 1127 $this->graph_theme->ApplyGraph($this); 1128 } 1129 } 1130 1131 $this->isAfterSetScale = true; 1132 } 1133 1001 1134 // Specify secondary Y scale 1002 function SetY2Scale($aAxisType="lin",$aY2Min=1,$aY2Max=1) { 1003 if( $aAxisType=="lin" ) 1004 $this->y2scale = new LinearScale($aY2Min,$aY2Max); 1005 elseif( $aAxisType == "int" ) { 1006 $this->y2scale = new LinearScale($aY2Min,$aY2Max); 1007 $this->y2scale->SetIntScale(); 1008 } 1009 elseif( $aAxisType=="log" ) { 1010 $this->y2scale = new LogScale($aY2Min,$aY2Max); 1011 } 1012 else JpGraphError::RaiseL(25023,$aAxisType);//("JpGraph: Unsupported Y2 axis type: $aAxisType\nMust be one of (lin,log,int)"); 1013 1014 $this->y2axis = new Axis($this->img,$this->y2scale); 1015 $this->y2axis->scale->ticks->SetDirection(SIDE_LEFT); 1016 $this->y2axis->SetLabelSide(SIDE_RIGHT); 1017 $this->y2axis->SetPos('max'); 1018 $this->y2axis->SetTitleSide(SIDE_RIGHT); 1019 1020 // Deafult position is the max x-value 1021 $this->y2grid = new Grid($this->y2axis); 1135 function SetY2Scale($aAxisType='lin',$aY2Min=1,$aY2Max=1) { 1136 if( $aAxisType == 'lin' ) { 1137 $this->y2scale = new LinearScale($aY2Min,$aY2Max); 1138 } 1139 elseif( $aAxisType == 'int' ) { 1140 $this->y2scale = new LinearScale($aY2Min,$aY2Max); 1141 $this->y2scale->SetIntScale(); 1142 } 1143 elseif( $aAxisType == 'log' ) { 1144 $this->y2scale = new LogScale($aY2Min,$aY2Max); 1145 } 1146 else { 1147 JpGraphError::RaiseL(25023,$aAxisType);//("JpGraph: Unsupported Y2 axis type: $aAxisType\nMust be one of (lin,log,int)"); 1148 } 1149 1150 $this->y2axis = new Axis($this->img,$this->y2scale); 1151 $this->y2axis->scale->ticks->SetDirection(SIDE_LEFT); 1152 $this->y2axis->SetLabelSide(SIDE_RIGHT); 1153 $this->y2axis->SetPos('max'); 1154 $this->y2axis->SetTitleSide(SIDE_RIGHT); 1155 1156 // Deafult position is the max x-value 1157 $this->y2grid = new Grid($this->y2axis); 1158 1159 if ($this->graph_theme) { 1160 $this->graph_theme->ApplyGraph($this); 1161 } 1022 1162 } 1023 1163 1024 1164 // Set the delta position (in pixels) between the multiple Y-axis 1025 1165 function SetYDeltaDist($aDist) { 1026 1166 $this->iYAxisDeltaPos = $aDist; 1027 1167 } 1028 1168 … … 1030 1170 function SetYScale($aN,$aAxisType="lin",$aYMin=1,$aYMax=1) { 1031 1171 1032 if( $aAxisType=="lin" ) 1033 $this->ynscale[$aN] = new LinearScale($aYMin,$aYMax); 1034 elseif( $aAxisType == "int" ) { 1035 $this->ynscale[$aN] = new LinearScale($aYMin,$aYMax); 1036 $this->ynscale[$aN]->SetIntScale(); 1037 } 1038 elseif( $aAxisType=="log" ) { 1039 $this->ynscale[$aN] = new LogScale($aYMin,$aYMax); 1040 } 1041 else JpGraphError::RaiseL(25024,$aAxisType);//("JpGraph: Unsupported Y axis type: $aAxisType\nMust be one of (lin,log,int)"); 1042 1043 $this->ynaxis[$aN] = new Axis($this->img,$this->ynscale[$aN]); 1044 $this->ynaxis[$aN]->scale->ticks->SetDirection(SIDE_LEFT); 1045 $this->ynaxis[$aN]->SetLabelSide(SIDE_RIGHT); 1172 if( $aAxisType == 'lin' ) { 1173 $this->ynscale[$aN] = new LinearScale($aYMin,$aYMax); 1174 } 1175 elseif( $aAxisType == 'int' ) { 1176 $this->ynscale[$aN] = new LinearScale($aYMin,$aYMax); 1177 $this->ynscale[$aN]->SetIntScale(); 1178 } 1179 elseif( $aAxisType == 'log' ) { 1180 $this->ynscale[$aN] = new LogScale($aYMin,$aYMax); 1181 } 1182 else { 1183 JpGraphError::RaiseL(25024,$aAxisType);//("JpGraph: Unsupported Y axis type: $aAxisType\nMust be one of (lin,log,int)"); 1184 } 1185 1186 $this->ynaxis[$aN] = new Axis($this->img,$this->ynscale[$aN]); 1187 $this->ynaxis[$aN]->scale->ticks->SetDirection(SIDE_LEFT); 1188 $this->ynaxis[$aN]->SetLabelSide(SIDE_RIGHT); 1189 1190 if ($this->graph_theme) { 1191 $this->graph_theme->ApplyGraph($this); 1192 } 1046 1193 } 1047 1194 1048 1195 // Specify density of ticks when autoscaling 'normal', 'dense', 'sparse', 'verysparse' 1049 // The dividing factor have been determined heuristically according to my aesthetic 1196 // The dividing factor have been determined heuristically according to my aesthetic 1050 1197 // sense (or lack off) y.m.m.v ! 1051 1198 function SetTickDensity($aYDensity=TICKD_NORMAL,$aXDensity=TICKD_NORMAL) { 1052 1053 $this->ytick_factor=25; 1054 1055 1056 $this->ytick_factor=12; 1057 1058 1059 $this->ytick_factor=25; 1060 1061 1062 $this->ytick_factor=40; 1063 1064 1065 $this->ytick_factor=100; 1066 break; 1067 1068 1069 1070 1071 1072 $this->xtick_factor=15; 1073 1074 1075 $this->xtick_factor=30; 1076 1077 1078 $this->xtick_factor=45; 1079 1080 1081 $this->xtick_factor=60; 1082 break; 1083 1084 1085 } 1086 } 1087 1088 1089 // Get a string of all image map areas 1199 $this->xtick_factor=30; 1200 $this->ytick_factor=25; 1201 switch( $aYDensity ) { 1202 case TICKD_DENSE: 1203 $this->ytick_factor=12; 1204 break; 1205 case TICKD_NORMAL: 1206 $this->ytick_factor=25; 1207 break; 1208 case TICKD_SPARSE: 1209 $this->ytick_factor=40; 1210 break; 1211 case TICKD_VERYSPARSE: 1212 $this->ytick_factor=100; 1213 break; 1214 default: 1215 JpGraphError::RaiseL(25025,$densy);//("JpGraph: Unsupported Tick density: $densy"); 1216 } 1217 switch( $aXDensity ) { 1218 case TICKD_DENSE: 1219 $this->xtick_factor=15; 1220 break; 1221 case TICKD_NORMAL: 1222 $this->xtick_factor=30; 1223 break; 1224 case TICKD_SPARSE: 1225 $this->xtick_factor=45; 1226 break; 1227 case TICKD_VERYSPARSE: 1228 $this->xtick_factor=60; 1229 break; 1230 default: 1231 JpGraphError::RaiseL(25025,$densx);//("JpGraph: Unsupported Tick density: $densx"); 1232 } 1233 } 1234 1235 1236 // Get a string of all image map areas 1090 1237 function GetCSIMareas() { 1091 if( !$this->iHasStroked ) 1092 $this->Stroke(_CSIM_SPECIALFILE); 1093 1094 $csim = $this->title->GetCSIMAreas(); 1095 $csim .= $this->subtitle->GetCSIMAreas(); 1096 $csim .= $this->subsubtitle->GetCSIMAreas(); 1097 $csim .= $this->legend->GetCSIMAreas(); 1098 1099 if( $this->y2axis != NULL ) { 1100 $csim .= $this->y2axis->title->GetCSIMAreas(); 1101 } 1102 1103 if( $this->texts != null ) { 1104 $n = count($this->texts); 1105 for($i=0; $i < $n; ++$i ) { 1106 $csim .= $this->texts[$i]->GetCSIMAreas(); 1107 } 1108 } 1109 1110 if( $this->y2texts != null && $this->y2scale != null ) { 1111 $n = count($this->y2texts); 1112 for($i=0; $i < $n; ++$i ) { 1113 $csim .= $this->y2texts[$i]->GetCSIMAreas(); 1114 } 1115 } 1116 1117 if( $this->yaxis != null && $this->xaxis != null ) { 1118 $csim .= $this->yaxis->title->GetCSIMAreas(); 1119 $csim .= $this->xaxis->title->GetCSIMAreas(); 1120 } 1121 1122 $n = count($this->plots); 1123 for( $i=0; $i < $n; ++$i ) 1124 $csim .= $this->plots[$i]->GetCSIMareas(); 1125 1126 $n = count($this->y2plots); 1127 for( $i=0; $i < $n; ++$i ) 1128 $csim .= $this->y2plots[$i]->GetCSIMareas(); 1129 1130 $n = count($this->ynaxis); 1131 for( $i=0; $i < $n; ++$i ) { 1132 $m = count($this->ynplots[$i]); 1133 for($j=0; $j < $m; ++$j ) { 1134 $csim .= $this->ynplots[$i][$j]->GetCSIMareas(); 1135 } 1136 } 1137 1138 $n = count($this->iTables); 1139 for( $i=0; $i < $n; ++$i ) { 1140 $csim .= $this->iTables[$i]->GetCSIMareas(); 1141 } 1142 1143 return $csim; 1144 } 1145 1238 if( !$this->iHasStroked ) { 1239 $this->Stroke(_CSIM_SPECIALFILE); 1240 } 1241 1242 $csim = $this->title->GetCSIMAreas(); 1243 $csim .= $this->subtitle->GetCSIMAreas(); 1244 $csim .= $this->subsubtitle->GetCSIMAreas(); 1245 $csim .= $this->legend->GetCSIMAreas(); 1246 1247 if( $this->y2axis != NULL ) { 1248 $csim .= $this->y2axis->title->GetCSIMAreas(); 1249 } 1250 1251 if( $this->texts != null ) { 1252 $n = count($this->texts); 1253 for($i=0; $i < $n; ++$i ) { 1254 $csim .= $this->texts[$i]->GetCSIMAreas(); 1255 } 1256 } 1257 1258 if( $this->y2texts != null && $this->y2scale != null ) { 1259 $n = count($this->y2texts); 1260 for($i=0; $i < $n; ++$i ) { 1261 $csim .= $this->y2texts[$i]->GetCSIMAreas(); 1262 } 1263 } 1264 1265 if( $this->yaxis != null && $this->xaxis != null ) { 1266 $csim .= $this->yaxis->title->GetCSIMAreas(); 1267 $csim .= $this->xaxis->title->GetCSIMAreas(); 1268 } 1269 1270 $n = count($this->plots); 1271 for( $i=0; $i < $n; ++$i ) { 1272 $csim .= $this->plots[$i]->GetCSIMareas(); 1273 } 1274 1275 $n = count($this->y2plots); 1276 for( $i=0; $i < $n; ++$i ) { 1277 $csim .= $this->y2plots[$i]->GetCSIMareas(); 1278 } 1279 1280 $n = count($this->ynaxis); 1281 for( $i=0; $i < $n; ++$i ) { 1282 $m = count($this->ynplots[$i]); 1283 for($j=0; $j < $m; ++$j ) { 1284 $csim .= $this->ynplots[$i][$j]->GetCSIMareas(); 1285 } 1286 } 1287 1288 if($this->iTables != null) { 1289 $n = count($this->iTables); 1290 for ($i = 0; $i < $n; ++$i) { 1291 $csim .= $this->iTables[$i]->GetCSIMareas(); 1292 } 1293 } 1294 1295 return $csim; 1296 } 1297 1146 1298 // Get a complete <MAP>..</MAP> tag for the final image map 1147 1299 function GetHTMLImageMap($aMapName) { 1148 1149 1150 $im .= "</map>"; 1151 1300 $im = "<map name=\"$aMapName\" id=\"$aMapName\" >\n"; 1301 $im .= $this->GetCSIMareas(); 1302 $im .= "</map>"; 1303 return $im; 1152 1304 } 1153 1305 1154 1306 function CheckCSIMCache($aCacheName,$aTimeOut=60) { 1155 global $_SERVER; 1156 1157 if( $aCacheName=='auto' ) 1158 $aCacheName=basename($_SERVER['PHP_SELF']); 1159 1160 $urlarg = $this->GetURLArguments(); 1161 $this->csimcachename = CSIMCACHE_DIR.$aCacheName.$urlarg; 1162 $this->csimcachetimeout = $aTimeOut; 1163 1164 // First determine if we need to check for a cached version 1165 // This differs from the standard cache in the sense that the 1166 // image and CSIM map HTML file is written relative to the directory 1167 // the script executes in and not the specified cache directory. 1168 // The reason for this is that the cache directory is not necessarily 1169 // accessible from the HTTP server. 1170 if( $this->csimcachename != '' ) { 1171 $dir = dirname($this->csimcachename); 1172 $base = basename($this->csimcachename); 1173 $base = strtok($base,'.'); 1174 $suffix = strtok('.'); 1175 $basecsim = $dir.'/'.$base.'?'.$urlarg.'_csim_.html'; 1176 $baseimg = $dir.'/'.$base.'?'.$urlarg.'.'.$this->img->img_format; 1177 1178 $timedout=false; 1179 // Does it exist at all ? 1180 1181 if( file_exists($basecsim) && file_exists($baseimg) ) { 1182 // Check that it hasn't timed out 1183 $diff=time()-filemtime($basecsim); 1184 if( $this->csimcachetimeout>0 && ($diff > $this->csimcachetimeout*60) ) { 1185 $timedout=true; 1186 @unlink($basecsim); 1187 @unlink($baseimg); 1188 } 1189 else { 1190 if ($fh = @fopen($basecsim, "r")) { 1191 fpassthru($fh); 1192 return true; 1193 } 1194 else 1195 JpGraphError::RaiseL(25027,$basecsim);//(" Can't open cached CSIM \"$basecsim\" for reading."); 1196 } 1197 } 1198 } 1199 return false; 1307 global $_SERVER; 1308 1309 if( $aCacheName=='auto' ) { 1310 $aCacheName=basename($_SERVER['PHP_SELF']); 1311 } 1312 1313 $urlarg = $this->GetURLArguments(); 1314 $this->csimcachename = CSIMCACHE_DIR.$aCacheName.$urlarg; 1315 $this->csimcachetimeout = $aTimeOut; 1316 1317 // First determine if we need to check for a cached version 1318 // This differs from the standard cache in the sense that the 1319 // image and CSIM map HTML file is written relative to the directory 1320 // the script executes in and not the specified cache directory. 1321 // The reason for this is that the cache directory is not necessarily 1322 // accessible from the HTTP server. 1323 if( $this->csimcachename != '' ) { 1324 $dir = dirname($this->csimcachename); 1325 $base = basename($this->csimcachename); 1326 $base = strtok($base,'.'); 1327 $suffix = strtok('.'); 1328 $basecsim = $dir.'/'.$base.'?'.$urlarg.'_csim_.html'; 1329 $baseimg = $dir.'/'.$base.'?'.$urlarg.'.'.$this->img->img_format; 1330 1331 $timedout=false; 1332 // Does it exist at all ? 1333 1334 if( file_exists($basecsim) && file_exists($baseimg) ) { 1335 // Check that it hasn't timed out 1336 $diff=time()-filemtime($basecsim); 1337 if( $this->csimcachetimeout>0 && ($diff > $this->csimcachetimeout*60) ) { 1338 $timedout=true; 1339 @unlink($basecsim); 1340 @unlink($baseimg); 1341 } 1342 else { 1343 if ($fh = @fopen($basecsim, "r")) { 1344 fpassthru($fh); 1345 return true; 1346 } 1347 else { 1348 JpGraphError::RaiseL(25027,$basecsim);//(" Can't open cached CSIM \"$basecsim\" for reading."); 1349 } 1350 } 1351 } 1352 } 1353 return false; 1200 1354 } 1201 1355 1202 1356 // Build the argument string to be used with the csim images 1203 function GetURLArguments() { 1204 1205 // This is a JPGRAPH internal defined that prevents 1206 // us from recursively coming here again 1207 $urlarg = _CSIM_DISPLAY.'=1'; 1208 1209 // Now reconstruct any user URL argument 1210 reset($_GET); 1211 while( list($key,$value) = each($_GET) ) { 1212 if( is_array($value) ) { 1213 foreach ( $value as $k => $v ) { 1214 $urlarg .= '&'.$key.'%5B'.$k.'%5D='.urlencode($v); 1215 } 1216 } 1217 else { 1218 $urlarg .= '&'.$key.'='.urlencode($value); 1219 } 1220 } 1221 1222 // It's not ideal to convert POST argument to GET arguments 1223 // but there is little else we can do. One idea for the 1224 // future might be recreate the POST header in case. 1225 reset($_POST); 1226 while( list($key,$value) = each($_POST) ) { 1227 if( is_array($value) ) { 1228 foreach ( $value as $k => $v ) { 1229 $urlarg .= '&'.$key.'%5B'.$k.'%5D='.urlencode($v); 1230 } 1231 } 1232 else { 1233 $urlarg .= '&'.$key.'='.urlencode($value); 1234 } 1235 } 1236 1237 return $urlarg; 1357 static function GetURLArguments($aAddRecursiveBlocker=false) { 1358 1359 if( $aAddRecursiveBlocker ) { 1360 // This is a JPGRAPH internal defined that prevents 1361 // us from recursively coming here again 1362 $urlarg = _CSIM_DISPLAY.'=1'; 1363 } 1364 1365 // Now reconstruct any user URL argument 1366 reset($_GET); 1367 foreach ($_GET as $key => $value) { 1368 if( is_array($value) ) { 1369 foreach ( $value as $k => $v ) { 1370 $urlarg .= '&'.$key.'%5B'.$k.'%5D='.urlencode($v); 1371 } 1372 } 1373 else { 1374 $urlarg .= '&'.$key.'='.urlencode($value); 1375 } 1376 } 1377 1378 // It's not ideal to convert POST argument to GET arguments 1379 // but there is little else we can do. One idea for the 1380 // future might be recreate the POST header in case. 1381 reset($_POST); 1382 foreach ($_POST as $key => $value) { 1383 if( is_array($value) ) { 1384 foreach ( $value as $k => $v ) { 1385 $urlarg .= '&'.$key.'%5B'.$k.'%5D='.urlencode($v); 1386 } 1387 } 1388 else { 1389 $urlarg .= '&'.$key.'='.urlencode($value); 1390 } 1391 } 1392 1393 return $urlarg; 1238 1394 } 1239 1395 1240 1396 function SetCSIMImgAlt($aAlt) { 1241 1397 $this->iCSIMImgAlt = $aAlt; 1242 1398 } 1243 1399 1244 1400 function StrokeCSIM($aScriptName='auto',$aCSIMName='',$aBorder=0) { 1245 if( $aCSIMName=='' ) { 1246 // create a random map name 1247 srand ((double) microtime() * 1000000); 1248 $r = rand(0,100000); 1249 $aCSIMName='__mapname'.$r.'__'; 1250 } 1251 1252 if( $aScriptName=='auto' ) 1253 $aScriptName=basename($_SERVER['PHP_SELF']); 1254 1255 $urlarg = $this->GetURLArguments(); 1256 1257 if( empty($_GET[_CSIM_DISPLAY]) ) { 1258 // First determine if we need to check for a cached version 1259 // This differs from the standard cache in the sense that the 1260 // image and CSIM map HTML file is written relative to the directory 1261 // the script executes in and not the specified cache directory. 1262 // The reason for this is that the cache directory is not necessarily 1263 // accessible from the HTTP server. 1264 if( $this->csimcachename != '' ) { 1265 $dir = dirname($this->csimcachename); 1266 $base = basename($this->csimcachename); 1267 $base = strtok($base,'.'); 1268 $suffix = strtok('.'); 1269 $basecsim = $dir.'/'.$base.'?'.$urlarg.'_csim_.html'; 1270 $baseimg = $base.'?'.$urlarg.'.'.$this->img->img_format; 1271 1272 // Check that apache can write to directory specified 1273 1274 if( file_exists($dir) && !is_writeable($dir) ) { 1275 JpgraphError::RaiseL(25028,$dir);//('Apache/PHP does not have permission to write to the CSIM cache directory ('.$dir.'). Check permissions.'); 1276 } 1277 1278 // Make sure directory exists 1279 $this->cache->MakeDirs($dir); 1280 1281 // Write the image file 1282 $this->Stroke(CSIMCACHE_DIR.$baseimg); 1283 1284 // Construct wrapper HTML and write to file and send it back to browser 1285 1286 // In the src URL we must replace the '?' with its encoding to prevent the arguments 1287 // to be converted to real arguments. 1288 $tmp = str_replace('?','%3f',$baseimg); 1289 $htmlwrap = $this->GetHTMLImageMap($aCSIMName)."\n". 1290 '<img src="'.CSIMCACHE_HTTP_DIR.$tmp.'" ismap="ismap" usemap="#'.$aCSIMName.'" border="'.$aBorder.'" width="'.$this->img->width.'" height="'.$this->img->height."\" alt=\"".$this->iCSIMImgAlt."\" />\n"; 1291 1292 if($fh = @fopen($basecsim,'w') ) { 1293 fwrite($fh,$htmlwrap); 1294 fclose($fh); 1295 echo $htmlwrap; 1296 } 1297 else 1298 JpGraphError::RaiseL(25029,$basecsim);//(" Can't write CSIM \"$basecsim\" for writing. Check free space and permissions."); 1299 } 1300 else { 1301 1302 if( $aScriptName=='' ) { 1303 JpGraphError::RaiseL(25030);//('Missing script name in call to StrokeCSIM(). You must specify the name of the actual image script as the first parameter to StrokeCSIM().'); 1304 } 1305 echo $this->GetHTMLImageMap($aCSIMName); 1306 echo "<img src=\"".$aScriptName.'?'.$urlarg."\" ismap=\"ismap\" usemap=\"#".$aCSIMName.'" border="'.$aBorder.'" width="'.$this->img->width.'" height="'.$this->img->height."\" alt=\"".$this->iCSIMImgAlt."\" />\n"; 1307 } 1308 } 1309 else { 1310 $this->Stroke(); 1311 } 1401 if( $aCSIMName=='' ) { 1402 // create a random map name 1403 srand ((double) microtime() * 1000000); 1404 $r = rand(0,100000); 1405 $aCSIMName='__mapname'.$r.'__'; 1406 } 1407 1408 if( $aScriptName=='auto' ) { 1409 $aScriptName=basename($_SERVER['PHP_SELF']); 1410 } 1411 1412 $urlarg = $this->GetURLArguments(true); 1413 1414 if( empty($_GET[_CSIM_DISPLAY]) ) { 1415 // First determine if we need to check for a cached version 1416 // This differs from the standard cache in the sense that the 1417 // image and CSIM map HTML file is written relative to the directory 1418 // the script executes in and not the specified cache directory. 1419 // The reason for this is that the cache directory is not necessarily 1420 // accessible from the HTTP server. 1421 if( $this->csimcachename != '' ) { 1422 $dir = dirname($this->csimcachename); 1423 $base = basename($this->csimcachename); 1424 $base = strtok($base,'.'); 1425 $suffix = strtok('.'); 1426 $basecsim = $dir.'/'.$base.'?'.$urlarg.'_csim_.html'; 1427 $baseimg = $base.'?'.$urlarg.'.'.$this->img->img_format; 1428 1429 // Check that apache can write to directory specified 1430 1431 if( file_exists($dir) && !is_writeable($dir) ) { 1432 JpgraphError::RaiseL(25028,$dir);//('Apache/PHP does not have permission to write to the CSIM cache directory ('.$dir.'). Check permissions.'); 1433 } 1434 1435 // Make sure directory exists 1436 $this->cache->MakeDirs($dir); 1437 1438 // Write the image file 1439 $this->Stroke(CSIMCACHE_DIR.$baseimg); 1440 1441 // Construct wrapper HTML and write to file and send it back to browser 1442 1443 // In the src URL we must replace the '?' with its encoding to prevent the arguments 1444 // to be converted to real arguments. 1445 $tmp = str_replace('?','%3f',$baseimg); 1446 $htmlwrap = $this->GetHTMLImageMap($aCSIMName)."\n". 1447 '<img src="'.CSIMCACHE_HTTP_DIR.$tmp.'" ismap="ismap" usemap="#'.$aCSIMName.' width="'.$this->img->width.'" height="'.$this->img->height."\" alt=\"".$this->iCSIMImgAlt."\" />\n"; 1448 1449 if($fh = @fopen($basecsim,'w') ) { 1450 fwrite($fh,$htmlwrap); 1451 fclose($fh); 1452 echo $htmlwrap; 1453 } 1454 else { 1455 JpGraphError::RaiseL(25029,$basecsim);//(" Can't write CSIM \"$basecsim\" for writing. Check free space and permissions."); 1456 } 1457 } 1458 else { 1459 1460 if( $aScriptName=='' ) { 1461 JpGraphError::RaiseL(25030);//('Missing script name in call to StrokeCSIM(). You must specify the name of the actual image script as the first parameter to StrokeCSIM().'); 1462 } 1463 echo $this->GetHTMLImageMap($aCSIMName) . $this->GetCSIMImgHTML($aCSIMName, $aScriptName, $aBorder); 1464 } 1465 } 1466 else { 1467 $this->Stroke(); 1468 } 1469 } 1470 1471 function StrokeCSIMImage() { 1472 if( @$_GET[_CSIM_DISPLAY] == 1 ) { 1473 $this->Stroke(); 1474 } 1475 } 1476 1477 function GetCSIMImgHTML($aCSIMName, $aScriptName='auto', $aBorder=0 ) { 1478 if( $aScriptName=='auto' ) { 1479 $aScriptName=basename($_SERVER['PHP_SELF']); 1480 } 1481 $urlarg = $this->GetURLArguments(true); 1482 return "<img src=\"".$aScriptName.'?'.$urlarg."\" ismap=\"ismap\" usemap=\"#".$aCSIMName.'" height="'.$this->img->height."\" alt=\"".$this->iCSIMImgAlt."\" />\n"; 1312 1483 } 1313 1484 1314 1485 function GetTextsYMinMax($aY2=false) { 1315 if( $aY2 ) 1316 $txts = $this->y2texts; 1317 else 1318 $txts = $this->texts; 1319 $n = count($txts); 1320 $min=null; 1321 $max=null; 1322 for( $i=0; $i < $n; ++$i ) { 1323 if( $txts[$i]->iScalePosY !== null && 1324 $txts[$i]->iScalePosX !== null ) { 1325 if( $min === null ) { 1326 $min = $max = $txts[$i]->iScalePosY ; 1327 } 1328 else { 1329 $min = min($min,$txts[$i]->iScalePosY); 1330 $max = max($max,$txts[$i]->iScalePosY); 1331 } 1332 } 1333 } 1334 if( $min !== null ) { 1335 return array($min,$max); 1336 } 1337 else 1338 return null; 1486 if( $aY2 ) { 1487 $txts = $this->y2texts; 1488 } 1489 else { 1490 $txts = $this->texts; 1491 } 1492 $n = is_array($txts) ? count($txts) : 0; 1493 $min=null; 1494 $max=null; 1495 for( $i=0; $i < $n; ++$i ) { 1496 if( $txts[$i]->iScalePosY !== null && $txts[$i]->iScalePosX !== null ) { 1497 if( $min === null ) { 1498 $min = $max = $txts[$i]->iScalePosY ; 1499 } 1500 else { 1501 $min = min($min,$txts[$i]->iScalePosY); 1502 $max = max($max,$txts[$i]->iScalePosY); 1503 } 1504 } 1505 } 1506 if( $min !== null ) { 1507 return array($min,$max); 1508 } 1509 else { 1510 return null; 1511 } 1339 1512 } 1340 1513 1341 1514 function GetTextsXMinMax($aY2=false) { 1342 if( $aY2 ) 1343 $txts = $this->y2texts; 1344 else 1345 $txts = $this->texts; 1346 $n = count($txts); 1347 $min=null; 1348 $max=null; 1349 for( $i=0; $i < $n; ++$i ) { 1350 if( $txts[$i]->iScalePosY !== null && 1351 $txts[$i]->iScalePosX !== null ) { 1352 if( $min === null ) { 1353 $min = $max = $txts[$i]->iScalePosX ; 1354 } 1355 else { 1356 $min = min($min,$txts[$i]->iScalePosX); 1357 $max = max($max,$txts[$i]->iScalePosX); 1358 } 1359 } 1360 } 1361 if( $min !== null ) { 1362 return array($min,$max); 1363 } 1364 else 1365 return null; 1515 if( $aY2 ) { 1516 $txts = $this->y2texts; 1517 } 1518 else { 1519 $txts = $this->texts; 1520 } 1521 $n = is_array($txts) ? count($txts) : 0; 1522 $min=null; 1523 $max=null; 1524 for( $i=0; $i < $n; ++$i ) { 1525 if( $txts[$i]->iScalePosY !== null && $txts[$i]->iScalePosX !== null ) { 1526 if( $min === null ) { 1527 $min = $max = $txts[$i]->iScalePosX ; 1528 } 1529 else { 1530 $min = min($min,$txts[$i]->iScalePosX); 1531 $max = max($max,$txts[$i]->iScalePosX); 1532 } 1533 } 1534 } 1535 if( $min !== null ) { 1536 return array($min,$max); 1537 } 1538 else { 1539 return null; 1540 } 1366 1541 } 1367 1542 1368 1543 function GetXMinMax() { 1369 list($min,$ymin) = $this->plots[0]->Min(); 1370 list($max,$ymax) = $this->plots[0]->Max(); 1371 foreach( $this->plots as $p ) { 1372 list($xmin,$ymin) = $p->Min(); 1373 list($xmax,$ymax) = $p->Max(); 1374 $min = Min($xmin,$min); 1375 $max = Max($xmax,$max); 1376 } 1377 1378 if( $this->y2axis != null ) { 1379 foreach( $this->y2plots as $p ) { 1380 list($xmin,$ymin) = $p->Min(); 1381 list($xmax,$ymax) = $p->Max(); 1382 $min = Min($xmin,$min); 1383 $max = Max($xmax,$max); 1384 } 1385 } 1386 1387 $n = count($this->ynaxis); 1388 for( $i=0; $i < $n; ++$i ) { 1389 if( $this->ynaxis[$i] != null) { 1390 foreach( $this->ynplots[$i] as $p ) { 1391 list($xmin,$ymin) = $p->Min(); 1392 list($xmax,$ymax) = $p->Max(); 1393 $min = Min($xmin,$min); 1394 $max = Max($xmax,$max); 1395 } 1396 } 1397 } 1398 return array($min,$max); 1544 1545 list($min,$ymin) = $this->plots[0]->Min(); 1546 list($max,$ymax) = $this->plots[0]->Max(); 1547 1548 $i=0; 1549 // Some plots, e.g. PlotLine should not affect the scale 1550 // and will return (null,null). We should ignore those 1551 // values. 1552 while( ($min===null || $max === null) && ($i < count($this->plots)-1) ) { 1553 ++$i; 1554 list($min,$ymin) = $this->plots[$i]->Min(); 1555 list($max,$ymax) = $this->plots[$i]->Max(); 1556 } 1557 1558 foreach( $this->plots as $p ) { 1559 list($xmin,$ymin) = $p->Min(); 1560 list($xmax,$ymax) = $p->Max(); 1561 1562 if( $xmin !== null && $xmax !== null ) { 1563 $min = Min($xmin,$min); 1564 $max = Max($xmax,$max); 1565 } 1566 } 1567 1568 if( $this->y2axis != null ) { 1569 foreach( $this->y2plots as $p ) { 1570 list($xmin,$ymin) = $p->Min(); 1571 list($xmax,$ymax) = $p->Max(); 1572 if( $xmin !== null && $xmax !== null ) { 1573 $min = Min($xmin, $min); 1574 $max = Max($xmax, $max); 1575 } 1576 } 1577 } 1578 1579 $n = count($this->ynaxis); 1580 for( $i=0; $i < $n; ++$i ) { 1581 if( $this->ynaxis[$i] != null) { 1582 foreach( $this->ynplots[$i] as $p ) { 1583 list($xmin,$ymin) = $p->Min(); 1584 list($xmax,$ymax) = $p->Max(); 1585 if( $xmin !== null && $xmax !== null ) { 1586 $min = Min($xmin, $min); 1587 $max = Max($xmax, $max); 1588 } 1589 } 1590 } 1591 } 1592 return array($min,$max); 1399 1593 } 1400 1594 1401 1595 function AdjustMarginsForTitles() { 1402 $totrequired = 1403 ($this->title->t != '' ? 1404 $this->title->GetTextHeight($this->img) + $this->title->margin + 5 : 0 ) + 1405 ($this->subtitle->t != '' ? 1406 $this->subtitle->GetTextHeight($this->img) + $this->subtitle->margin + 5 : 0 ) + 1407 ($this->subsubtitle->t != '' ? 1408 $this->subsubtitle->GetTextHeight($this->img) + $this->subsubtitle->margin + 5 : 0 ) ; 1409 1410 1411 $btotrequired = 0; 1412 if($this->xaxis != null && !$this->xaxis->hide && !$this->xaxis->hide_labels ) { 1413 // Minimum bottom margin 1414 if( $this->xaxis->title->t != '' ) { 1415 if( $this->img->a == 90 ) 1416 $btotrequired = $this->yaxis->title->GetTextHeight($this->img) + 5 ; 1417 else 1418 $btotrequired = $this->xaxis->title->GetTextHeight($this->img) + 5 ; 1419 } 1420 else 1421 $btotrequired = 0; 1422 1423 if( $this->img->a == 90 ) { 1424 $this->img->SetFont($this->yaxis->font_family,$this->yaxis->font_style, 1425 $this->yaxis->font_size); 1426 $lh = $this->img->GetTextHeight('Mg',$this->yaxis->label_angle); 1427 } 1428 else { 1429 $this->img->SetFont($this->xaxis->font_family,$this->xaxis->font_style, 1430 $this->xaxis->font_size); 1431 $lh = $this->img->GetTextHeight('Mg',$this->xaxis->label_angle); 1432 } 1433 1434 $btotrequired += $lh + 5; 1435 } 1436 1437 if( $this->img->a == 90 ) { 1438 // DO Nothing. It gets too messy to do this properly for 90 deg... 1439 } 1440 else{ 1441 if( $this->img->top_margin < $totrequired ) { 1442 $this->SetMargin($this->img->left_margin,$this->img->right_margin, 1443 $totrequired,$this->img->bottom_margin); 1444 } 1445 if( $this->img->bottom_margin < $btotrequired ) { 1446 $this->SetMargin($this->img->left_margin,$this->img->right_margin, 1447 $this->img->top_margin,$btotrequired); 1448 } 1449 } 1450 } 1596 $totrequired = 1597 ($this->title->t != '' 1598 ? $this->title->GetTextHeight($this->img) + $this->title->margin + 5 * SUPERSAMPLING_SCALE 1599 : 0 ) + 1600 ($this->subtitle->t != '' 1601 ? $this->subtitle->GetTextHeight($this->img) + $this->subtitle->margin + 5 * SUPERSAMPLING_SCALE 1602 : 0 ) + 1603 ($this->subsubtitle->t != '' 1604 ? $this->subsubtitle->GetTextHeight($this->img) + $this->subsubtitle->margin + 5 * SUPERSAMPLING_SCALE 1605 : 0 ) ; 1606 1607 $btotrequired = 0; 1608 if($this->xaxis != null && !$this->xaxis->hide && !$this->xaxis->hide_labels ) { 1609 // Minimum bottom margin 1610 if( $this->xaxis->title->t != '' ) { 1611 if( $this->img->a == 90 ) { 1612 $btotrequired = $this->yaxis->title->GetTextHeight($this->img) + 7 ; 1613 } 1614 else { 1615 $btotrequired = $this->xaxis->title->GetTextHeight($this->img) + 7 ; 1616 } 1617 } 1618 else { 1619 $btotrequired = 0; 1620 } 1621 1622 if( $this->img->a == 90 ) { 1623 $this->img->SetFont($this->yaxis->font_family,$this->yaxis->font_style, 1624 $this->yaxis->font_size); 1625 $lh = $this->img->GetTextHeight('Mg',$this->yaxis->label_angle); 1626 } 1627 else { 1628 $this->img->SetFont($this->xaxis->font_family,$this->xaxis->font_style, 1629 $this->xaxis->font_size); 1630 $lh = $this->img->GetTextHeight('Mg',$this->xaxis->label_angle); 1631 } 1632 1633 $btotrequired += $lh + 6; 1634 } 1635 1636 if( $this->img->a == 90 ) { 1637 // DO Nothing. It gets too messy to do this properly for 90 deg... 1638 } 1639 else{ 1640 // need more top margin 1641 if( $this->img->top_margin < $totrequired ) { 1642 $this->SetMargin( 1643 $this->img->raw_left_margin, 1644 $this->img->raw_right_margin, 1645 $totrequired / SUPERSAMPLING_SCALE, 1646 $this->img->raw_bottom_margin 1647 ); 1648 } 1649 1650 // need more bottom margin 1651 if( $this->img->bottom_margin < $btotrequired ) { 1652 $this->SetMargin( 1653 $this->img->raw_left_margin, 1654 $this->img->raw_right_margin, 1655 $this->img->raw_top_margin, 1656 $btotrequired / SUPERSAMPLING_SCALE 1657 ); 1658 } 1659 } 1660 } 1661 1662 function StrokeStore($aStrokeFileName) { 1663 // Get the handler to prevent the library from sending the 1664 // image to the browser 1665 $ih = $this->Stroke(_IMG_HANDLER); 1666 1667 // Stroke it to a file 1668 $this->img->Stream($aStrokeFileName); 1669 1670 // Send it back to browser 1671 $this->img->Headers(); 1672 $this->img->Stream(); 1673 } 1674 1675 function doAutoscaleXAxis() { 1676 //Check if we should autoscale x-axis 1677 if( !$this->xscale->IsSpecified() ) { 1678 if( substr($this->axtype,0,4) == "text" ) { 1679 $max=0; 1680 $n = count($this->plots); 1681 for($i=0; $i < $n; ++$i ) { 1682 $p = $this->plots[$i]; 1683 // We need some unfortunate sub class knowledge here in order 1684 // to increase number of data points in case it is a line plot 1685 // which has the barcenter set. If not it could mean that the 1686 // last point of the data is outside the scale since the barcenter 1687 // settings means that we will shift the entire plot half a tick step 1688 // to the right in oder to align with the center of the bars. 1689 if( class_exists('BarPlot',false) ) { 1690 $cl = strtolower(get_class($p)); 1691 if( (class_exists('BarPlot',false) && ($p instanceof BarPlot)) || empty($p->barcenter) ) { 1692 $max=max($max,$p->numpoints-1); 1693 } 1694 else { 1695 $max=max($max,$p->numpoints); 1696 } 1697 } 1698 else { 1699 if( empty($p->barcenter) ) { 1700 $max=max($max,$p->numpoints-1); 1701 } 1702 else { 1703 $max=max($max,$p->numpoints); 1704 } 1705 } 1706 } 1707 $min=0; 1708 if( $this->y2axis != null ) { 1709 foreach( $this->y2plots as $p ) { 1710 $max=max($max,$p->numpoints-1); 1711 } 1712 } 1713 $n = count($this->ynaxis); 1714 for( $i=0; $i < $n; ++$i ) { 1715 if( $this->ynaxis[$i] != null) { 1716 foreach( $this->ynplots[$i] as $p ) { 1717 $max=max($max,$p->numpoints-1); 1718 } 1719 } 1720 } 1721 1722 $this->xscale->Update($this->img,$min,$max); 1723 $this->xscale->ticks->Set($this->xaxis->tick_step,1); 1724 $this->xscale->ticks->SupressMinorTickMarks(); 1725 } 1726 else { 1727 list($min,$max) = $this->GetXMinMax(); 1728 1729 $lres = $this->GetLinesXMinMax($this->lines); 1730 if( $lres ) { 1731 list($linmin,$linmax) = $lres ; 1732 $min = min($min,$linmin); 1733 $max = max($max,$linmax); 1734 } 1735 1736 $lres = $this->GetLinesXMinMax($this->y2lines); 1737 if( $lres ) { 1738 list($linmin,$linmax) = $lres ; 1739 $min = min($min,$linmin); 1740 $max = max($max,$linmax); 1741 } 1742 1743 $tres = $this->GetTextsXMinMax(); 1744 if( $tres ) { 1745 list($tmin,$tmax) = $tres ; 1746 $min = min($min,$tmin); 1747 $max = max($max,$tmax); 1748 } 1749 1750 $tres = $this->GetTextsXMinMax(true); 1751 if( $tres ) { 1752 list($tmin,$tmax) = $tres ; 1753 $min = min($min,$tmin); 1754 $max = max($max,$tmax); 1755 } 1756 1757 $this->xscale->AutoScale($this->img,$min,$max,round($this->img->plotwidth/$this->xtick_factor)); 1758 } 1759 1760 //Adjust position of y-axis and y2-axis to minimum/maximum of x-scale 1761 if( !is_numeric($this->yaxis->pos) && !is_string($this->yaxis->pos) ) { 1762 $this->yaxis->SetPos($this->xscale->GetMinVal()); 1763 } 1764 } 1765 elseif( $this->xscale->IsSpecified() && 1766 ( $this->xscale->auto_ticks || !$this->xscale->ticks->IsSpecified()) ) { 1767 // The tick calculation will use the user suplied min/max values to determine 1768 // the ticks. If auto_ticks is false the exact user specifed min and max 1769 // values will be used for the scale. 1770 // If auto_ticks is true then the scale might be slightly adjusted 1771 // so that the min and max values falls on an even major step. 1772 $min = $this->xscale->scale[0]; 1773 $max = $this->xscale->scale[1]; 1774 $this->xscale->AutoScale($this->img,$min,$max,round($this->img->plotwidth/$this->xtick_factor),false); 1775 1776 // Now make sure we show enough precision to accurate display the 1777 // labels. If this is not done then the user might end up with 1778 // a scale that might actually start with, say 13.5, butdue to rounding 1779 // the scale label will ony show 14. 1780 if( abs(floor($min)-$min) > 0 ) { 1781 1782 // If the user has set a format then we bail out 1783 if( $this->xscale->ticks->label_formatstr == '' && $this->xscale->ticks->label_dateformatstr == '' ) { 1784 $this->xscale->ticks->precision = abs( floor(log10( abs(floor($min)-$min))) )+1; 1785 } 1786 } 1787 } 1788 1789 // Position the optional Y2 and Yn axis to the rightmost position of the x-axis 1790 if( $this->y2axis != null ) { 1791 if( !is_numeric($this->y2axis->pos) && !is_string($this->y2axis->pos) ) { 1792 $this->y2axis->SetPos($this->xscale->GetMaxVal()); 1793 } 1794 $this->y2axis->SetTitleSide(SIDE_RIGHT); 1795 } 1796 1797 $n = count($this->ynaxis); 1798 $nY2adj = $this->y2axis != null ? $this->iYAxisDeltaPos : 0; 1799 for( $i=0; $i < $n; ++$i ) { 1800 if( $this->ynaxis[$i] != null ) { 1801 if( !is_numeric($this->ynaxis[$i]->pos) && !is_string($this->ynaxis[$i]->pos) ) { 1802 $this->ynaxis[$i]->SetPos($this->xscale->GetMaxVal()); 1803 $this->ynaxis[$i]->SetPosAbsDelta($i*$this->iYAxisDeltaPos + $nY2adj); 1804 } 1805 $this->ynaxis[$i]->SetTitleSide(SIDE_RIGHT); 1806 } 1807 } 1808 } 1809 1810 1811 function doAutoScaleYnAxis() { 1812 1813 if( $this->y2scale != null) { 1814 if( !$this->y2scale->IsSpecified() && count($this->y2plots)>0 ) { 1815 list($min,$max) = $this->GetPlotsYMinMax($this->y2plots); 1816 1817 $lres = $this->GetLinesYMinMax($this->y2lines); 1818 if( is_array($lres) ) { 1819 list($linmin,$linmax) = $lres ; 1820 $min = min($min,$linmin); 1821 $max = max($max,$linmax); 1822 } 1823 $tres = $this->GetTextsYMinMax(true); 1824 if( is_array($tres) ) { 1825 list($tmin,$tmax) = $tres ; 1826 $min = min($min,$tmin); 1827 $max = max($max,$tmax); 1828 } 1829 $this->y2scale->AutoScale($this->img,$min,$max,$this->img->plotheight/$this->ytick_factor); 1830 } 1831 elseif( $this->y2scale->IsSpecified() && ( $this->y2scale->auto_ticks || !$this->y2scale->ticks->IsSpecified()) ) { 1832 // The tick calculation will use the user suplied min/max values to determine 1833 // the ticks. If auto_ticks is false the exact user specifed min and max 1834 // values will be used for the scale. 1835 // If auto_ticks is true then the scale might be slightly adjusted 1836 // so that the min and max values falls on an even major step. 1837 $min = $this->y2scale->scale[0]; 1838 $max = $this->y2scale->scale[1]; 1839 $this->y2scale->AutoScale($this->img,$min,$max, 1840 $this->img->plotheight/$this->ytick_factor, 1841 $this->y2scale->auto_ticks); 1842 1843 // Now make sure we show enough precision to accurate display the 1844 // labels. If this is not done then the user might end up with 1845 // a scale that might actually start with, say 13.5, butdue to rounding 1846 // the scale label will ony show 14. 1847 if( abs(floor($min)-$min) > 0 ) { 1848 // If the user has set a format then we bail out 1849 if( $this->y2scale->ticks->label_formatstr == '' && $this->y2scale->ticks->label_dateformatstr == '' ) { 1850 $this->y2scale->ticks->precision = abs( floor(log10( abs(floor($min)-$min))) )+1; 1851 } 1852 } 1853 1854 } 1855 } 1856 1857 1858 // 1859 // Autoscale the extra Y-axises 1860 // 1861 $n = count($this->ynaxis); 1862 for( $i=0; $i < $n; ++$i ) { 1863 if( $this->ynscale[$i] != null) { 1864 if( !$this->ynscale[$i]->IsSpecified() && count($this->ynplots[$i])>0 ) { 1865 list($min,$max) = $this->GetPlotsYMinMax($this->ynplots[$i]); 1866 $this->ynscale[$i]->AutoScale($this->img,$min,$max,$this->img->plotheight/$this->ytick_factor); 1867 } 1868 elseif( $this->ynscale[$i]->IsSpecified() && ( $this->ynscale[$i]->auto_ticks || !$this->ynscale[$i]->ticks->IsSpecified()) ) { 1869 // The tick calculation will use the user suplied min/max values to determine 1870 // the ticks. If auto_ticks is false the exact user specifed min and max 1871 // values will be used for the scale. 1872 // If auto_ticks is true then the scale might be slightly adjusted 1873 // so that the min and max values falls on an even major step. 1874 $min = $this->ynscale[$i]->scale[0]; 1875 $max = $this->ynscale[$i]->scale[1]; 1876 $this->ynscale[$i]->AutoScale($this->img,$min,$max, 1877 $this->img->plotheight/$this->ytick_factor, 1878 $this->ynscale[$i]->auto_ticks); 1879 1880 // Now make sure we show enough precision to accurate display the 1881 // labels. If this is not done then the user might end up with 1882 // a scale that might actually start with, say 13.5, butdue to rounding 1883 // the scale label will ony show 14. 1884 if( abs(floor($min)-$min) > 0 ) { 1885 // If the user has set a format then we bail out 1886 if( $this->ynscale[$i]->ticks->label_formatstr == '' && $this->ynscale[$i]->ticks->label_dateformatstr == '' ) { 1887 $this->ynscale[$i]->ticks->precision = abs( floor(log10( abs(floor($min)-$min))) )+1; 1888 } 1889 } 1890 } 1891 } 1892 } 1893 } 1894 1895 function doAutoScaleYAxis() { 1896 1897 //Check if we should autoscale y-axis 1898 if( !$this->yscale->IsSpecified() && count($this->plots)>0 ) { 1899 list($min,$max) = $this->GetPlotsYMinMax($this->plots); 1900 $lres = $this->GetLinesYMinMax($this->lines); 1901 if( is_array($lres) ) { 1902 list($linmin,$linmax) = $lres ; 1903 $min = min($min,$linmin); 1904 $max = max($max,$linmax); 1905 } 1906 $tres = $this->GetTextsYMinMax(); 1907 if( is_array($tres) ) { 1908 list($tmin,$tmax) = $tres ; 1909 $min = min($min,$tmin); 1910 $max = max($max,$tmax); 1911 } 1912 $this->yscale->AutoScale($this->img,$min,$max, 1913 $this->img->plotheight/$this->ytick_factor); 1914 } 1915 elseif( $this->yscale->IsSpecified() && ( $this->yscale->auto_ticks || !$this->yscale->ticks->IsSpecified()) ) { 1916 // The tick calculation will use the user suplied min/max values to determine 1917 // the ticks. If auto_ticks is false the exact user specifed min and max 1918 // values will be used for the scale. 1919 // If auto_ticks is true then the scale might be slightly adjusted 1920 // so that the min and max values falls on an even major step. 1921 $min = $this->yscale->scale[0]; 1922 $max = $this->yscale->scale[1]; 1923 $this->yscale->AutoScale($this->img,$min,$max, 1924 $this->img->plotheight/$this->ytick_factor, 1925 $this->yscale->auto_ticks); 1926 1927 // Now make sure we show enough precision to accurate display the 1928 // labels. If this is not done then the user might end up with 1929 // a scale that might actually start with, say 13.5, butdue to rounding 1930 // the scale label will ony show 14. 1931 if( abs(floor($min)-$min) > 0 ) { 1932 1933 // If the user has set a format then we bail out 1934 if( $this->yscale->ticks->label_formatstr == '' && $this->yscale->ticks->label_dateformatstr == '' ) { 1935 $this->yscale->ticks->precision = abs( floor(log10( abs(floor($min)-$min))) )+1; 1936 } 1937 } 1938 } 1939 1940 } 1941 1942 function InitScaleConstants() { 1943 // Setup scale constants 1944 if( $this->yscale ) $this->yscale->InitConstants($this->img); 1945 if( $this->xscale ) $this->xscale->InitConstants($this->img); 1946 if( $this->y2scale ) $this->y2scale->InitConstants($this->img); 1947 1948 $n=count($this->ynscale); 1949 for($i=0; $i < $n; ++$i) { 1950 if( $this->ynscale[$i] ) { 1951 $this->ynscale[$i]->InitConstants($this->img); 1952 } 1953 } 1954 } 1955 1956 function doPrestrokeAdjustments() { 1957 1958 // Do any pre-stroke adjustment that is needed by the different plot types 1959 // (i.e bar plots want's to add an offset to the x-labels etc) 1960 for($i=0; $i < count($this->plots) ; ++$i ) { 1961 $this->plots[$i]->PreStrokeAdjust($this); 1962 $this->plots[$i]->DoLegend($this); 1963 } 1964 1965 // Any plots on the second Y scale? 1966 if( $this->y2scale != null ) { 1967 for($i=0; $i<count($this->y2plots) ; ++$i ) { 1968 $this->y2plots[$i]->PreStrokeAdjust($this); 1969 $this->y2plots[$i]->DoLegend($this); 1970 } 1971 } 1972 1973 // Any plots on the extra Y axises? 1974 $n = count($this->ynaxis); 1975 for($i=0; $i<$n ; ++$i ) { 1976 if( $this->ynplots == null || $this->ynplots[$i] == null) { 1977 JpGraphError::RaiseL(25032,$i);//("No plots for Y-axis nbr:$i"); 1978 } 1979 $m = count($this->ynplots[$i]); 1980 for($j=0; $j < $m; ++$j ) { 1981 $this->ynplots[$i][$j]->PreStrokeAdjust($this); 1982 $this->ynplots[$i][$j]->DoLegend($this); 1983 } 1984 } 1985 } 1986 1987 function StrokeBands($aDepth,$aCSIM) { 1988 // Stroke bands 1989 if( $this->bands != null && !$aCSIM) { 1990 for($i=0; $i < count($this->bands); ++$i) { 1991 // Stroke all bands that asks to be in the background 1992 if( $this->bands[$i]->depth == $aDepth ) { 1993 $this->bands[$i]->Stroke($this->img,$this->xscale,$this->yscale); 1994 } 1995 } 1996 } 1997 1998 if( $this->y2bands != null && $this->y2scale != null && !$aCSIM ) { 1999 for($i=0; $i < count($this->y2bands); ++$i) { 2000 // Stroke all bands that asks to be in the foreground 2001 if( $this->y2bands[$i]->depth == $aDepth ) { 2002 $this->y2bands[$i]->Stroke($this->img,$this->xscale,$this->y2scale); 2003 } 2004 } 2005 } 2006 } 2007 1451 2008 1452 2009 // Stroke the graph 1453 // $aStrokeFileName 2010 // $aStrokeFileName If != "" the image will be written to this file and NOT 1454 2011 // streamed back to the browser 1455 function Stroke($aStrokeFileName="") { 1456 1457 // Fist make a sanity check that user has specified a scale 1458 if( empty($this->yscale) ) { 1459 JpGraphError::RaiseL(25031);//('You must specify what scale to use with a call to Graph::SetScale().'); 1460 } 1461 1462 // Start by adjusting the margin so that potential titles will fit. 1463 $this->AdjustMarginsForTitles(); 1464 1465 // Setup scale constants 1466 if( $this->yscale ) $this->yscale->InitConstants($this->img); 1467 if( $this->xscale ) $this->xscale->InitConstants($this->img); 1468 if( $this->y2scale ) $this->y2scale->InitConstants($this->img); 1469 1470 $n=count($this->ynscale); 1471 for($i=0; $i < $n; ++$i) { 1472 if( $this->ynscale[$i] ) $this->ynscale[$i]->InitConstants($this->img); 1473 } 1474 1475 // If the filename is the predefined value = '_csim_special_' 1476 // we assume that the call to stroke only needs to do enough 1477 // to correctly generate the CSIM maps. 1478 // We use this variable to skip things we don't strictly need 1479 // to do to generate the image map to improve performance 1480 // a best we can. Therefor you will see a lot of tests !$_csim in the 1481 // code below. 1482 $_csim = ($aStrokeFileName===_CSIM_SPECIALFILE); 1483 1484 // We need to know if we have stroked the plot in the 1485 // GetCSIMareas. Otherwise the CSIM hasn't been generated 1486 // and in the case of GetCSIM called before stroke to generate 1487 // CSIM without storing an image to disk GetCSIM must call Stroke. 1488 $this->iHasStroked = true; 1489 1490 // Do any pre-stroke adjustment that is needed by the different plot types 1491 // (i.e bar plots want's to add an offset to the x-labels etc) 1492 for($i=0; $i < count($this->plots) ; ++$i ) { 1493 $this->plots[$i]->PreStrokeAdjust($this); 1494 $this->plots[$i]->DoLegend($this); 1495 } 1496 1497 // Any plots on the second Y scale? 1498 if( $this->y2scale != null ) { 1499 for($i=0; $i<count($this->y2plots) ; ++$i ) { 1500 $this->y2plots[$i]->PreStrokeAdjust($this); 1501 $this->y2plots[$i]->DoLegend($this); 1502 } 1503 } 1504 1505 // Any plots on the extra Y axises? 1506 $n = count($this->ynaxis); 1507 for($i=0; $i<$n ; ++$i ) { 1508 if( $this->ynplots == null || $this->ynplots[$i] == null) { 1509 JpGraphError::RaiseL(25032,$i);//("No plots for Y-axis nbr:$i"); 1510 } 1511 $m = count($this->ynplots[$i]); 1512 for($j=0; $j < $m; ++$j ) { 1513 $this->ynplots[$i][$j]->PreStrokeAdjust($this); 1514 $this->ynplots[$i][$j]->DoLegend($this); 1515 } 1516 } 1517 1518 // Bail out if any of the Y-axis not been specified and 1519 // has no plots. (This means it is impossible to do autoscaling and 1520 // no other scale was given so we can't possible draw anything). If you use manual 1521 // scaling you also have to supply the tick steps as well. 1522 if( (!$this->yscale->IsSpecified() && count($this->plots)==0) || 1523 ($this->y2scale!=null && !$this->y2scale->IsSpecified() && count($this->y2plots)==0) ) { 1524 //$e = "n=".count($this->y2plots)."\n"; 1525 // $e = "Can't draw unspecified Y-scale.<br>\nYou have either:<br>\n"; 1526 // $e .= "1. Specified an Y axis for autoscaling but have not supplied any plots<br>\n"; 1527 // $e .= "2. Specified a scale manually but have forgot to specify the tick steps"; 1528 JpGraphError::RaiseL(25026); 1529 } 1530 1531 // Bail out if no plots and no specified X-scale 1532 if( (!$this->xscale->IsSpecified() && count($this->plots)==0 && count($this->y2plots)==0) ) 1533 JpGraphError::RaiseL(25034);//("<strong>JpGraph: Can't draw unspecified X-scale.</strong><br>No plots.<br>"); 1534 1535 //Check if we should autoscale y-axis 1536 if( !$this->yscale->IsSpecified() && count($this->plots)>0 ) { 1537 list($min,$max) = $this->GetPlotsYMinMax($this->plots); 1538 $lres = $this->GetLinesYMinMax($this->lines); 1539 if( is_array($lres) ) { 1540 list($linmin,$linmax) = $lres ; 1541 $min = min($min,$linmin); 1542 $max = max($max,$linmax); 1543 } 1544 $tres = $this->GetTextsYMinMax(); 1545 if( is_array($tres) ) { 1546 list($tmin,$tmax) = $tres ; 1547 $min = min($min,$tmin); 1548 $max = max($max,$tmax); 1549 } 1550 $this->yscale->AutoScale($this->img,$min,$max, 1551 $this->img->plotheight/$this->ytick_factor); 1552 } 1553 elseif( $this->yscale->IsSpecified() && 1554 ( $this->yscale->auto_ticks || !$this->yscale->ticks->IsSpecified()) ) { 1555 // The tick calculation will use the user suplied min/max values to determine 1556 // the ticks. If auto_ticks is false the exact user specifed min and max 1557 // values will be used for the scale. 1558 // If auto_ticks is true then the scale might be slightly adjusted 1559 // so that the min and max values falls on an even major step. 1560 $min = $this->yscale->scale[0]; 1561 $max = $this->yscale->scale[1]; 1562 $this->yscale->AutoScale($this->img,$min,$max, 1563 $this->img->plotheight/$this->ytick_factor, 1564 $this->yscale->auto_ticks); 1565 1566 // Now make sure we show enough precision to accurate display the 1567 // labels. If this is not done then the user might end up with 1568 // a scale that might actually start with, say 13.5, butdue to rounding 1569 // the scale label will ony show 14. 1570 if( abs(floor($min)-$min) > 0 ) { 1571 1572 // If the user has set a format then we bail out 1573 if( $this->yscale->ticks->label_formatstr == '' && $this->yscale->ticks->label_dateformatstr == '' ) { 1574 $this->yscale->ticks->precision = abs( floor(log10( abs(floor($min)-$min))) )+1; 1575 } 1576 } 1577 } 1578 1579 if( $this->y2scale != null) { 1580 if( !$this->y2scale->IsSpecified() && count($this->y2plots)>0 ) { 1581 list($min,$max) = $this->GetPlotsYMinMax($this->y2plots); 1582 1583 $lres = $this->GetLinesYMinMax($this->y2lines); 1584 if( is_array($lres) ) { 1585 list($linmin,$linmax) = $lres ; 1586 $min = min($min,$linmin); 1587 $max = max($max,$linmax); 1588 } 1589 $tres = $this->GetTextsYMinMax(true); 1590 if( is_array($tres) ) { 1591 list($tmin,$tmax) = $tres ; 1592 $min = min($min,$tmin); 1593 $max = max($max,$tmax); 1594 } 1595 $this->y2scale->AutoScale($this->img,$min,$max,$this->img->plotheight/$this->ytick_factor); 1596 } 1597 elseif( $this->y2scale->IsSpecified() && 1598 ( $this->y2scale->auto_ticks || !$this->y2scale->ticks->IsSpecified()) ) { 1599 // The tick calculation will use the user suplied min/max values to determine 1600 // the ticks. If auto_ticks is false the exact user specifed min and max 1601 // values will be used for the scale. 1602 // If auto_ticks is true then the scale might be slightly adjusted 1603 // so that the min and max values falls on an even major step. 1604 $min = $this->y2scale->scale[0]; 1605 $max = $this->y2scale->scale[1]; 1606 $this->y2scale->AutoScale($this->img,$min,$max, 1607 $this->img->plotheight/$this->ytick_factor, 1608 $this->y2scale->auto_ticks); 1609 1610 // Now make sure we show enough precision to accurate display the 1611 // labels. If this is not done then the user might end up with 1612 // a scale that might actually start with, say 13.5, butdue to rounding 1613 // the scale label will ony show 14. 1614 if( abs(floor($min)-$min) > 0 ) { 1615 1616 // If the user has set a format then we bail out 1617 if( $this->y2scale->ticks->label_formatstr == '' && $this->y2scale->ticks->label_dateformatstr == '' ) { 1618 $this->y2scale->ticks->precision = abs( floor(log10( abs(floor($min)-$min))) )+1; 1619 } 1620 } 1621 1622 } 1623 } 1624 1625 // 1626 // Autoscale the extra Y-axises 1627 // 1628 $n = count($this->ynaxis); 1629 for( $i=0; $i < $n; ++$i ) { 1630 if( $this->ynscale[$i] != null) { 1631 if( !$this->ynscale[$i]->IsSpecified() && count($this->ynplots[$i])>0 ) { 1632 list($min,$max) = $this->GetPlotsYMinMax($this->ynplots[$i]); 1633 $this->ynscale[$i]->AutoScale($this->img,$min,$max,$this->img->plotheight/$this->ytick_factor); 1634 } 1635 elseif( $this->ynscale[$i]->IsSpecified() && 1636 ( $this->ynscale[$i]->auto_ticks || !$this->ynscale[$i]->ticks->IsSpecified()) ) { 1637 // The tick calculation will use the user suplied min/max values to determine 1638 // the ticks. If auto_ticks is false the exact user specifed min and max 1639 // values will be used for the scale. 1640 // If auto_ticks is true then the scale might be slightly adjusted 1641 // so that the min and max values falls on an even major step. 1642 $min = $this->ynscale[$i]->scale[0]; 1643 $max = $this->ynscale[$i]->scale[1]; 1644 $this->ynscale[$i]->AutoScale($this->img,$min,$max, 1645 $this->img->plotheight/$this->ytick_factor, 1646 $this->ynscale[$i]->auto_ticks); 1647 1648 // Now make sure we show enough precision to accurate display the 1649 // labels. If this is not done then the user might end up with 1650 // a scale that might actually start with, say 13.5, butdue to rounding 1651 // the scale label will ony show 14. 1652 if( abs(floor($min)-$min) > 0 ) { 1653 1654 // If the user has set a format then we bail out 1655 if( $this->ynscale[$i]->ticks->label_formatstr == '' && $this->ynscale[$i]->ticks->label_dateformatstr == '' ) { 1656 $this->ynscale[$i]->ticks->precision = abs( floor(log10( abs(floor($min)-$min))) )+1; 1657 } 1658 } 1659 1660 } 1661 } 1662 } 1663 1664 //Check if we should autoscale x-axis 1665 if( !$this->xscale->IsSpecified() ) { 1666 if( substr($this->axtype,0,4) == "text" ) { 1667 $max=0; 1668 $n = count($this->plots); 1669 for($i=0; $i < $n; ++$i ) { 1670 $p = $this->plots[$i]; 1671 // We need some unfortunate sub class knowledge here in order 1672 // to increase number of data points in case it is a line plot 1673 // which has the barcenter set. If not it could mean that the 1674 // last point of the data is outside the scale since the barcenter 1675 // settings means that we will shift the entire plot half a tick step 1676 // to the right in oder to align with the center of the bars. 1677 if( class_exists('BarPlot',false) ) { 1678 $cl = strtolower(get_class($p)); 1679 if( (class_exists('BarPlot',false) && ($p instanceof BarPlot)) || 1680 empty($p->barcenter) ) 1681 $max=max($max,$p->numpoints-1); 1682 else { 1683 $max=max($max,$p->numpoints); 1684 } 1685 } 1686 else { 1687 if( empty($p->barcenter) ) { 1688 $max=max($max,$p->numpoints-1); 1689 } 1690 else { 1691 $max=max($max,$p->numpoints); 1692 } 1693 } 1694 } 1695 $min=0; 1696 if( $this->y2axis != null ) { 1697 foreach( $this->y2plots as $p ) { 1698 $max=max($max,$p->numpoints-1); 1699 } 1700 } 1701 $n = count($this->ynaxis); 1702 for( $i=0; $i < $n; ++$i ) { 1703 if( $this->ynaxis[$i] != null) { 1704 foreach( $this->ynplots[$i] as $p ) { 1705 $max=max($max,$p->numpoints-1); 1706 } 1707 } 1708 } 1709 1710 $this->xscale->Update($this->img,$min,$max); 1711 $this->xscale->ticks->Set($this->xaxis->tick_step,1); 1712 $this->xscale->ticks->SupressMinorTickMarks(); 1713 } 1714 else { 1715 list($min,$max) = $this->GetXMinMax(); 1716 1717 $lres = $this->GetLinesXMinMax($this->lines); 1718 if( $lres ) { 1719 list($linmin,$linmax) = $lres ; 1720 $min = min($min,$linmin); 1721 $max = max($max,$linmax); 1722 } 1723 1724 $lres = $this->GetLinesXMinMax($this->y2lines); 1725 if( $lres ) { 1726 list($linmin,$linmax) = $lres ; 1727 $min = min($min,$linmin); 1728 $max = max($max,$linmax); 1729 } 1730 1731 $tres = $this->GetTextsXMinMax(); 1732 if( $tres ) { 1733 list($tmin,$tmax) = $tres ; 1734 $min = min($min,$tmin); 1735 $max = max($max,$tmax); 1736 } 1737 1738 $tres = $this->GetTextsXMinMax(true); 1739 if( $tres ) { 1740 list($tmin,$tmax) = $tres ; 1741 $min = min($min,$tmin); 1742 $max = max($max,$tmax); 1743 } 1744 1745 $this->xscale->AutoScale($this->img,$min,$max,round($this->img->plotwidth/$this->xtick_factor)); 1746 } 1747 1748 //Adjust position of y-axis and y2-axis to minimum/maximum of x-scale 1749 if( !is_numeric($this->yaxis->pos) && !is_string($this->yaxis->pos) ) 1750 $this->yaxis->SetPos($this->xscale->GetMinVal()); 1751 if( $this->y2axis != null ) { 1752 if( !is_numeric($this->y2axis->pos) && !is_string($this->y2axis->pos) ) 1753 $this->y2axis->SetPos($this->xscale->GetMaxVal()); 1754 $this->y2axis->SetTitleSide(SIDE_RIGHT); 1755 } 1756 $n = count($this->ynaxis); 1757 $nY2adj = $this->y2axis != null ? $this->iYAxisDeltaPos : 0; 1758 for( $i=0; $i < $n; ++$i ) { 1759 if( $this->ynaxis[$i] != null ) { 1760 if( !is_numeric($this->ynaxis[$i]->pos) && !is_string($this->ynaxis[$i]->pos) ) { 1761 $this->ynaxis[$i]->SetPos($this->xscale->GetMaxVal()); 1762 $this->ynaxis[$i]->SetPosAbsDelta($i*$this->iYAxisDeltaPos + $nY2adj); 1763 } 1764 $this->ynaxis[$i]->SetTitleSide(SIDE_RIGHT); 1765 } 1766 } 1767 1768 } 1769 elseif( $this->xscale->IsSpecified() && 1770 ( $this->xscale->auto_ticks || !$this->xscale->ticks->IsSpecified()) ) { 1771 // The tick calculation will use the user suplied min/max values to determine 1772 // the ticks. If auto_ticks is false the exact user specifed min and max 1773 // values will be used for the scale. 1774 // If auto_ticks is true then the scale might be slightly adjusted 1775 // so that the min and max values falls on an even major step. 1776 $min = $this->xscale->scale[0]; 1777 $max = $this->xscale->scale[1]; 1778 $this->xscale->AutoScale($this->img,$min,$max, 1779 round($this->img->plotwidth/$this->xtick_factor), 1780 false); 1781 1782 // Now make sure we show enough precision to accurate display the 1783 // labels. If this is not done then the user might end up with 1784 // a scale that might actually start with, say 13.5, butdue to rounding 1785 // the scale label will ony show 14. 1786 if( abs(floor($min)-$min) > 0 ) { 1787 1788 // If the user has set a format then we bail out 1789 if( $this->xscale->ticks->label_formatstr == '' && $this->xscale->ticks->label_dateformatstr == '' ) { 1790 $this->xscale->ticks->precision = abs( floor(log10( abs(floor($min)-$min))) )+1; 1791 } 1792 } 1793 1794 1795 if( $this->y2axis != null ) { 1796 if( !is_numeric($this->y2axis->pos) && !is_string($this->y2axis->pos) ) 1797 $this->y2axis->SetPos($this->xscale->GetMaxVal()); 1798 $this->y2axis->SetTitleSide(SIDE_RIGHT); 1799 } 1800 1801 } 1802 1803 // If we have a negative values and x-axis position is at 0 1804 // we need to supress the first and possible the last tick since 1805 // they will be drawn on top of the y-axis (and possible y2 axis) 1806 // The test below might seem strange the reasone being that if 1807 // the user hasn't specified a value for position this will not 1808 // be set until we do the stroke for the axis so as of now it 1809 // is undefined. 1810 // For X-text scale we ignore all this since the tick are usually 1811 // much further in and not close to the Y-axis. Hence the test 1812 // for 'text' 1813 1814 if( ($this->yaxis->pos==$this->xscale->GetMinVal() || 1815 (is_string($this->yaxis->pos) && $this->yaxis->pos=='min')) && 1816 !is_numeric($this->xaxis->pos) && $this->yscale->GetMinVal() < 0 && 1817 substr($this->axtype,0,4) != 'text' && $this->xaxis->pos!="min" ) { 1818 1819 //$this->yscale->ticks->SupressZeroLabel(false); 1820 $this->xscale->ticks->SupressFirst(); 1821 if( $this->y2axis != null ) { 1822 $this->xscale->ticks->SupressLast(); 1823 } 1824 } 1825 elseif( !is_numeric($this->yaxis->pos) && $this->yaxis->pos=='max' ) { 1826 $this->xscale->ticks->SupressLast(); 1827 } 1828 1829 1830 if( !$_csim ) { 1831 $this->StrokePlotArea(); 1832 if( $this->iIconDepth == DEPTH_BACK ) { 1833 $this->StrokeIcons(); 1834 } 1835 } 1836 $this->StrokeAxis(false); 1837 1838 // Stroke bands 1839 if( $this->bands != null && !$_csim) 1840 for($i=0; $i < count($this->bands); ++$i) { 1841 // Stroke all bands that asks to be in the background 1842 if( $this->bands[$i]->depth == DEPTH_BACK ) 1843 $this->bands[$i]->Stroke($this->img,$this->xscale,$this->yscale); 1844 } 1845 1846 if( $this->y2bands != null && $this->y2scale != null && !$_csim ) 1847 for($i=0; $i < count($this->y2bands); ++$i) { 1848 // Stroke all bands that asks to be in the foreground 1849 if( $this->y2bands[$i]->depth == DEPTH_BACK ) 1850 $this->y2bands[$i]->Stroke($this->img,$this->xscale,$this->y2scale); 1851 } 1852 1853 1854 if( $this->grid_depth == DEPTH_BACK && !$_csim) { 1855 $this->ygrid->Stroke(); 1856 $this->xgrid->Stroke(); 1857 } 1858 1859 // Stroke Y2-axis 1860 if( $this->y2axis != null && !$_csim) { 1861 $this->y2axis->Stroke($this->xscale); 1862 $this->y2grid->Stroke(); 1863 } 1864 1865 // Stroke yn-axis 1866 $n = count($this->ynaxis); 1867 for( $i=0; $i < $n; ++$i ) { 1868 $this->ynaxis[$i]->Stroke($this->xscale); 1869 } 1870 1871 $oldoff=$this->xscale->off; 1872 if(substr($this->axtype,0,4)=="text") { 1873 if( $this->text_scale_abscenteroff > -1 ) { 1874 // For a text scale the scale factor is the number of pixel per step. 1875 // Hence we can use the scale factor as a substitute for number of pixels 1876 // per major scale step and use that in order to adjust the offset so that 1877 // an object of width "abscenteroff" becomes centered. 1878 $this->xscale->off += round($this->xscale->scale_factor/2)-round($this->text_scale_abscenteroff/2); 1879 } 1880 else { 1881 $this->xscale->off += 1882 ceil($this->xscale->scale_factor*$this->text_scale_off*$this->xscale->ticks->minor_step); 1883 } 1884 } 1885 1886 if( $this->iDoClipping ) { 1887 $oldimage = $this->img->CloneCanvasH(); 1888 } 1889 1890 if( ! $this->y2orderback ) { 1891 // Stroke all plots for Y1 axis 1892 for($i=0; $i < count($this->plots); ++$i) { 1893 $this->plots[$i]->Stroke($this->img,$this->xscale,$this->yscale); 1894 $this->plots[$i]->StrokeMargin($this->img); 1895 } 1896 } 1897 1898 // Stroke all plots for Y2 axis 1899 if( $this->y2scale != null ) 1900 for($i=0; $i< count($this->y2plots); ++$i ) { 1901 $this->y2plots[$i]->Stroke($this->img,$this->xscale,$this->y2scale); 1902 } 1903 1904 if( $this->y2orderback ) { 1905 // Stroke all plots for Y1 axis 1906 for($i=0; $i < count($this->plots); ++$i) { 1907 $this->plots[$i]->Stroke($this->img,$this->xscale,$this->yscale); 1908 $this->plots[$i]->StrokeMargin($this->img); 1909 } 1910 } 1911 1912 $n = count($this->ynaxis); 1913 for( $i=0; $i < $n; ++$i ) { 1914 $m = count($this->ynplots[$i]); 1915 for( $j=0; $j < $m; ++$j ) { 1916 $this->ynplots[$i][$j]->Stroke($this->img,$this->xscale,$this->ynscale[$i]); 1917 $this->ynplots[$i][$j]->StrokeMargin($this->img); 1918 } 1919 } 1920 1921 if( $this->iIconDepth == DEPTH_FRONT) { 1922 $this->StrokeIcons(); 1923 } 1924 1925 if( $this->iDoClipping ) { 1926 // Clipping only supports graphs at 0 and 90 degrees 1927 if( $this->img->a == 0 ) { 1928 $this->img->CopyCanvasH($oldimage,$this->img->img, 1929 $this->img->left_margin,$this->img->top_margin, 1930 $this->img->left_margin,$this->img->top_margin, 1931 $this->img->plotwidth+1,$this->img->plotheight); 1932 } 1933 elseif( $this->img->a == 90 ) { 1934 $adj = ($this->img->height - $this->img->width)/2; 1935 $this->img->CopyCanvasH($oldimage,$this->img->img, 1936 $this->img->bottom_margin-$adj,$this->img->left_margin+$adj, 1937 $this->img->bottom_margin-$adj,$this->img->left_margin+$adj, 1938 $this->img->plotheight+1,$this->img->plotwidth); 1939 } 1940 else { 1941 JpGraphError::RaiseL(25035,$this->img->a);//('You have enabled clipping. Cliping is only supported for graphs at 0 or 90 degrees rotation. Please adjust you current angle (='.$this->img->a.' degrees) or disable clipping.'); 1942 } 1943 $this->img->Destroy(); 1944 $this->img->SetCanvasH($oldimage); 1945 } 1946 1947 $this->xscale->off=$oldoff; 1948 1949 if( $this->grid_depth == DEPTH_FRONT && !$_csim ) { 1950 $this->ygrid->Stroke(); 1951 $this->xgrid->Stroke(); 1952 } 1953 1954 // Stroke bands 1955 if( $this->bands!= null ) 1956 for($i=0; $i < count($this->bands); ++$i) { 1957 // Stroke all bands that asks to be in the foreground 1958 if( $this->bands[$i]->depth == DEPTH_FRONT ) 1959 $this->bands[$i]->Stroke($this->img,$this->xscale,$this->yscale); 1960 } 1961 1962 if( $this->y2bands!= null && $this->y2scale != null ) 1963 for($i=0; $i < count($this->y2bands); ++$i) { 1964 // Stroke all bands that asks to be in the foreground 1965 if( $this->y2bands[$i]->depth == DEPTH_FRONT ) 1966 $this->y2bands[$i]->Stroke($this->img,$this->xscale,$this->y2scale); 1967 } 1968 1969 1970 // Stroke any lines added 1971 if( $this->lines != null ) { 1972 for($i=0; $i < count($this->lines); ++$i) { 1973 $this->lines[$i]->Stroke($this->img,$this->xscale,$this->yscale); 1974 $this->lines[$i]->DoLegend($this); 1975 } 1976 } 1977 1978 if( $this->y2lines != null && $this->y2scale != null ) { 1979 for($i=0; $i < count($this->y2lines); ++$i) { 1980 $this->y2lines[$i]->Stroke($this->img,$this->xscale,$this->y2scale); 1981 $this->y2lines[$i]->DoLegend($this); 1982 } 1983 } 1984 1985 // Finally draw the axis again since some plots may have nagged 1986 // the axis in the edges. 1987 if( !$_csim ) { 1988 $this->StrokeAxis(); 1989 } 1990 1991 if( $this->y2scale != null && !$_csim ) 1992 $this->y2axis->Stroke($this->xscale,false); 1993 1994 if( !$_csim ) { 1995 $this->StrokePlotBox(); 1996 } 1997 1998 // The titles and legends never gets rotated so make sure 1999 // that the angle is 0 before stroking them 2000 $aa = $this->img->SetAngle(0); 2001 $this->StrokeTitles(); 2002 $this->footer->Stroke($this->img); 2003 $this->legend->Stroke($this->img); 2004 $this->img->SetAngle($aa); 2005 $this->StrokeTexts(); 2006 $this->StrokeTables(); 2007 2008 if( !$_csim ) { 2009 2010 $this->img->SetAngle($aa); 2011 2012 // Draw an outline around the image map 2013 if(_JPG_DEBUG) { 2014 $this->DisplayClientSideaImageMapAreas(); 2015 } 2016 2017 // Should we do any final image transformation 2018 if( $this->iImgTrans ) { 2019 if( !class_exists('ImgTrans',false) ) { 2020 require_once('jpgraph_imgtrans.php'); 2021 //JpGraphError::Raise('In order to use image transformation you must include the file jpgraph_imgtrans.php in your script.'); 2022 } 2023 2024 $tform = new ImgTrans($this->img->img); 2025 $this->img->img = $tform->Skew3D($this->iImgTransHorizon,$this->iImgTransSkewDist, 2026 $this->iImgTransDirection,$this->iImgTransHighQ, 2027 $this->iImgTransMinSize,$this->iImgTransFillColor, 2028 $this->iImgTransBorder); 2029 } 2030 2031 // If the filename is given as the special "__handle" 2032 // then the image handler is returned and the image is NOT 2033 // streamed back 2034 if( $aStrokeFileName == _IMG_HANDLER ) { 2035 return $this->img->img; 2036 } 2037 else { 2038 // Finally stream the generated picture 2039 $this->cache->PutAndStream($this->img,$this->cache_name,$this->inline,$aStrokeFileName); 2040 } 2041 } 2012 function Stroke($aStrokeFileName='') { 2013 // Fist make a sanity check that user has specified a scale 2014 if( empty($this->yscale) ) { 2015 JpGraphError::RaiseL(25031);//('You must specify what scale to use with a call to Graph::SetScale().'); 2016 } 2017 2018 // Start by adjusting the margin so that potential titles will fit. 2019 $this->AdjustMarginsForTitles(); 2020 2021 // Give the plot a chance to do any scale adjuments the individual plots 2022 // wants to do. Right now this is only used by the contour plot to set scale 2023 // limits 2024 for($i=0; $i < count($this->plots) ; ++$i ) { 2025 $this->plots[$i]->PreScaleSetup($this); 2026 } 2027 2028 // Init scale constants that are used to calculate the transformation from 2029 // world to pixel coordinates 2030 $this->InitScaleConstants(); 2031 2032 // If the filename is the predefined value = '_csim_special_' 2033 // we assume that the call to stroke only needs to do enough 2034 // to correctly generate the CSIM maps. 2035 // We use this variable to skip things we don't strictly need 2036 // to do to generate the image map to improve performance 2037 // a best we can. Therefor you will see a lot of tests !$_csim in the 2038 // code below. 2039 $_csim = ($aStrokeFileName===_CSIM_SPECIALFILE); 2040 2041 // If we are called the second time (perhaps the user has called GetHTMLImageMap() 2042 // himself then the legends have alsready been populated once in order to get the 2043 // CSIM coordinats. Since we do not want the legends to be populated a second time 2044 // we clear the legends 2045 $this->legend->Clear(); 2046 2047 // We need to know if we have stroked the plot in the 2048 // GetCSIMareas. Otherwise the CSIM hasn't been generated 2049 // and in the case of GetCSIM called before stroke to generate 2050 // CSIM without storing an image to disk GetCSIM must call Stroke. 2051 $this->iHasStroked = true; 2052 2053 // Setup pre-stroked adjustments and Legends 2054 $this->doPrestrokeAdjustments(); 2055 2056 if ($this->graph_theme) { 2057 $this->graph_theme->PreStrokeApply($this); 2058 } 2059 2060 // Bail out if any of the Y-axis not been specified and 2061 // has no plots. (This means it is impossible to do autoscaling and 2062 // no other scale was given so we can't possible draw anything). If you use manual 2063 // scaling you also have to supply the tick steps as well. 2064 if( (!$this->yscale->IsSpecified() && count($this->plots)==0) || 2065 ($this->y2scale!=null && !$this->y2scale->IsSpecified() && count($this->y2plots)==0) ) { 2066 //$e = "n=".count($this->y2plots)."\n"; 2067 // $e = "Can't draw unspecified Y-scale.<br>\nYou have either:<br>\n"; 2068 // $e .= "1. Specified an Y axis for autoscaling but have not supplied any plots<br>\n"; 2069 // $e .= "2. Specified a scale manually but have forgot to specify the tick steps"; 2070 JpGraphError::RaiseL(25026); 2071 } 2072 2073 // Bail out if no plots and no specified X-scale 2074 if( (!$this->xscale->IsSpecified() && count($this->plots)==0 && count($this->y2plots)==0) ) { 2075 JpGraphError::RaiseL(25034);//("<strong>JpGraph: Can't draw unspecified X-scale.</strong><br>No plots.<br>"); 2076 } 2077 2078 // Autoscale the normal Y-axis 2079 $this->doAutoScaleYAxis(); 2080 2081 // Autoscale all additiopnal y-axis 2082 $this->doAutoScaleYnAxis(); 2083 2084 // Autoscale the regular x-axis and position the y-axis properly 2085 $this->doAutoScaleXAxis(); 2086 2087 // If we have a negative values and x-axis position is at 0 2088 // we need to supress the first and possible the last tick since 2089 // they will be drawn on top of the y-axis (and possible y2 axis) 2090 // The test below might seem strange the reasone being that if 2091 // the user hasn't specified a value for position this will not 2092 // be set until we do the stroke for the axis so as of now it 2093 // is undefined. 2094 // For X-text scale we ignore all this since the tick are usually 2095 // much further in and not close to the Y-axis. Hence the test 2096 // for 'text' 2097 if( ($this->yaxis->pos==$this->xscale->GetMinVal() || (is_string($this->yaxis->pos) && $this->yaxis->pos=='min')) && 2098 !is_numeric($this->xaxis->pos) && $this->yscale->GetMinVal() < 0 && 2099 substr($this->axtype,0,4) != 'text' && $this->xaxis->pos != 'min' ) { 2100 2101 //$this->yscale->ticks->SupressZeroLabel(false); 2102 $this->xscale->ticks->SupressFirst(); 2103 if( $this->y2axis != null ) { 2104 $this->xscale->ticks->SupressLast(); 2105 } 2106 } 2107 elseif( !is_numeric($this->yaxis->pos) && $this->yaxis->pos=='max' ) { 2108 $this->xscale->ticks->SupressLast(); 2109 } 2110 2111 if( !$_csim ) { 2112 $this->StrokePlotArea(); 2113 if( $this->iIconDepth == DEPTH_BACK ) { 2114 $this->StrokeIcons(); 2115 } 2116 } 2117 $this->StrokeAxis(false); 2118 2119 // Stroke colored bands 2120 $this->StrokeBands(DEPTH_BACK,$_csim); 2121 2122 if( $this->grid_depth == DEPTH_BACK && !$_csim) { 2123 $this->ygrid->Stroke(); 2124 $this->xgrid->Stroke(); 2125 } 2126 2127 // Stroke Y2-axis 2128 if( $this->y2axis != null && !$_csim) { 2129 $this->y2axis->Stroke($this->xscale); 2130 $this->y2grid->Stroke(); 2131 } 2132 2133 // Stroke yn-axis 2134 $n = count($this->ynaxis); 2135 for( $i=0; $i < $n; ++$i ) { 2136 $this->ynaxis[$i]->Stroke($this->xscale); 2137 } 2138 2139 $oldoff=$this->xscale->off; 2140 if( substr($this->axtype,0,4) == 'text' ) { 2141 if( $this->text_scale_abscenteroff > -1 ) { 2142 // For a text scale the scale factor is the number of pixel per step. 2143 // Hence we can use the scale factor as a substitute for number of pixels 2144 // per major scale step and use that in order to adjust the offset so that 2145 // an object of width "abscenteroff" becomes centered. 2146 $this->xscale->off += round($this->xscale->scale_factor/2)-round($this->text_scale_abscenteroff/2); 2147 } 2148 else { 2149 $this->xscale->off += ceil($this->xscale->scale_factor*$this->text_scale_off*$this->xscale->ticks->minor_step); 2150 } 2151 } 2152 2153 if( $this->iDoClipping ) { 2154 $oldimage = $this->img->CloneCanvasH(); 2155 } 2156 2157 if( ! $this->y2orderback ) { 2158 // Stroke all plots for Y1 axis 2159 for($i=0; $i < count($this->plots); ++$i) { 2160 $this->plots[$i]->Stroke($this->img,$this->xscale,$this->yscale); 2161 $this->plots[$i]->StrokeMargin($this->img); 2162 } 2163 } 2164 2165 // Stroke all plots for Y2 axis 2166 if( $this->y2scale != null ) { 2167 for($i=0; $i< count($this->y2plots); ++$i ) { 2168 $this->y2plots[$i]->Stroke($this->img,$this->xscale,$this->y2scale); 2169 } 2170 } 2171 2172 if( $this->y2orderback ) { 2173 // Stroke all plots for Y1 axis 2174 for($i=0; $i < count($this->plots); ++$i) { 2175 $this->plots[$i]->Stroke($this->img,$this->xscale,$this->yscale); 2176 $this->plots[$i]->StrokeMargin($this->img); 2177 } 2178 } 2179 2180 $n = count($this->ynaxis); 2181 for( $i=0; $i < $n; ++$i ) { 2182 $m = count($this->ynplots[$i]); 2183 for( $j=0; $j < $m; ++$j ) { 2184 $this->ynplots[$i][$j]->Stroke($this->img,$this->xscale,$this->ynscale[$i]); 2185 $this->ynplots[$i][$j]->StrokeMargin($this->img); 2186 } 2187 } 2188 2189 if( $this->iIconDepth == DEPTH_FRONT) { 2190 $this->StrokeIcons(); 2191 } 2192 2193 if( $this->iDoClipping ) { 2194 // Clipping only supports graphs at 0 and 90 degrees 2195 if( $this->img->a == 0 ) { 2196 $this->img->CopyCanvasH($oldimage,$this->img->img, 2197 $this->img->left_margin,$this->img->top_margin, 2198 $this->img->left_margin,$this->img->top_margin, 2199 $this->img->plotwidth+1,$this->img->plotheight); 2200 } 2201 elseif( $this->img->a == 90 ) { 2202 $adj = ($this->img->height - $this->img->width)/2; 2203 $this->img->CopyCanvasH($oldimage,$this->img->img, 2204 $this->img->bottom_margin-$adj,$this->img->left_margin+$adj, 2205 $this->img->bottom_margin-$adj,$this->img->left_margin+$adj, 2206 $this->img->plotheight+1,$this->img->plotwidth); 2207 } 2208 else { 2209 JpGraphError::RaiseL(25035,$this->img->a);//('You have enabled clipping. Cliping is only supported for graphs at 0 or 90 degrees rotation. Please adjust you current angle (='.$this->img->a.' degrees) or disable clipping.'); 2210 } 2211 $this->img->Destroy(); 2212 $this->img->SetCanvasH($oldimage); 2213 } 2214 2215 $this->xscale->off=$oldoff; 2216 2217 if( $this->grid_depth == DEPTH_FRONT && !$_csim ) { 2218 $this->ygrid->Stroke(); 2219 $this->xgrid->Stroke(); 2220 } 2221 2222 // Stroke colored bands 2223 $this->StrokeBands(DEPTH_FRONT,$_csim); 2224 2225 // Finally draw the axis again since some plots may have nagged 2226 // the axis in the edges. 2227 if( !$_csim ) { 2228 $this->StrokeAxis(); 2229 } 2230 2231 if( $this->y2scale != null && !$_csim ) { 2232 $this->y2axis->Stroke($this->xscale,false); 2233 } 2234 2235 if( !$_csim ) { 2236 $this->StrokePlotBox(); 2237 } 2238 2239 // The titles and legends never gets rotated so make sure 2240 // that the angle is 0 before stroking them 2241 $aa = $this->img->SetAngle(0); 2242 $this->StrokeTitles(); 2243 $this->footer->Stroke($this->img); 2244 $this->legend->Stroke($this->img); 2245 $this->img->SetAngle($aa); 2246 $this->StrokeTexts(); 2247 $this->StrokeTables(); 2248 2249 if( !$_csim ) { 2250 2251 $this->img->SetAngle($aa); 2252 2253 // Draw an outline around the image map 2254 if(_JPG_DEBUG) { 2255 $this->DisplayClientSideaImageMapAreas(); 2256 } 2257 2258 // Should we do any final image transformation 2259 if( $this->iImgTrans ) { 2260 if( !class_exists('ImgTrans',false) ) { 2261 require_once('jpgraph_imgtrans.php'); 2262 //JpGraphError::Raise('In order to use image transformation you must include the file jpgraph_imgtrans.php in your script.'); 2263 } 2264 2265 $tform = new ImgTrans($this->img->img); 2266 $this->img->img = $tform->Skew3D($this->iImgTransHorizon,$this->iImgTransSkewDist, 2267 $this->iImgTransDirection,$this->iImgTransHighQ, 2268 $this->iImgTransMinSize,$this->iImgTransFillColor, 2269 $this->iImgTransBorder); 2270 } 2271 2272 // If the filename is given as the special "__handle" 2273 // then the image handler is returned and the image is NOT 2274 // streamed back 2275 if( $aStrokeFileName == _IMG_HANDLER ) { 2276 return $this->img->img; 2277 } 2278 else { 2279 // Finally stream the generated picture 2280 $this->cache->PutAndStream($this->img,$this->cache_name,$this->inline,$aStrokeFileName); 2281 } 2282 } 2042 2283 } 2043 2284 2044 2285 function SetAxisLabelBackground($aType,$aXFColor='lightgray',$aXColor='black',$aYFColor='lightgray',$aYColor='black') { 2045 $this->iAxisLblBgType = $aType; 2046 $this->iXAxisLblBgFillColor = $aXFColor; 2047 $this->iXAxisLblBgColor = $aXColor; 2048 $this->iYAxisLblBgFillColor = $aYFColor; 2049 $this->iYAxisLblBgColor = $aYColor; 2050 } 2051 2052 //--------------- 2053 // PRIVATE METHODS 2286 $this->iAxisLblBgType = $aType; 2287 $this->iXAxisLblBgFillColor = $aXFColor; 2288 $this->iXAxisLblBgColor = $aXColor; 2289 $this->iYAxisLblBgFillColor = $aYFColor; 2290 $this->iYAxisLblBgColor = $aYColor; 2291 } 2054 2292 2055 2293 function StrokeAxisLabelBackground() { 2056 // Types 2057 // 0 = No background 2058 // 1 = Only X-labels, length of axis 2059 // 2 = Only Y-labels, length of axis 2060 // 3 = As 1 but extends to width of graph 2061 // 4 = As 2 but extends to height of graph 2062 // 5 = Combination of 3 & 4 2063 // 6 = Combination of 1 & 2 2064 2065 $t = $this->iAxisLblBgType ; 2066 if( $t < 1 ) return; 2067 // Stroke optional X-axis label background color 2068 if( $t == 1 || $t == 3 || $t == 5 || $t == 6 ) { 2069 $this->img->PushColor($this->iXAxisLblBgFillColor); 2070 if( $t == 1 || $t == 6 ) { 2071 $xl = $this->img->left_margin; 2072 $yu = $this->img->height - $this->img->bottom_margin + 1; 2073 $xr = $this->img->width - $this->img->right_margin ; 2074 $yl = $this->img->height-1-$this->frame_weight; 2075 } 2076 else { // t==3 || t==5 2077 $xl = $this->frame_weight; 2078 $yu = $this->img->height - $this->img->bottom_margin + 1; 2079 $xr = $this->img->width - 1 - $this->frame_weight; 2080 $yl = $this->img->height-1-$this->frame_weight; 2081 } 2082 2083 $this->img->FilledRectangle($xl,$yu,$xr,$yl); 2084 $this->img->PopColor(); 2085 2086 // Check if we should add the vertical lines at left and right edge 2087 if( $this->iXAxisLblBgColor !== '' ) { 2088 // Hardcode to one pixel wide 2089 $this->img->SetLineWeight(1); 2090 $this->img->PushColor($this->iXAxisLblBgColor); 2091 if( $t == 1 || $t == 6 ) { 2092 $this->img->Line($xl,$yu,$xl,$yl); 2093 $this->img->Line($xr,$yu,$xr,$yl); 2094 } 2095 else { 2096 $xl = $this->img->width - $this->img->right_margin ; 2097 $this->img->Line($xl,$yu-1,$xr,$yu-1); 2098 } 2099 $this->img->PopColor(); 2100 } 2101 } 2102 2103 if( $t == 2 || $t == 4 || $t == 5 || $t == 6 ) { 2104 $this->img->PushColor($this->iYAxisLblBgFillColor); 2105 if( $t == 2 || $t == 6 ) { 2106 $xl = $this->frame_weight; 2107 $yu = $this->frame_weight+$this->img->top_margin; 2108 $xr = $this->img->left_margin - 1; 2109 $yl = $this->img->height - $this->img->bottom_margin + 1; 2110 } 2111 else { 2112 $xl = $this->frame_weight; 2113 $yu = $this->frame_weight; 2114 $xr = $this->img->left_margin - 1; 2115 $yl = $this->img->height-1-$this->frame_weight; 2116 } 2117 2118 $this->img->FilledRectangle($xl,$yu,$xr,$yl); 2119 $this->img->PopColor(); 2120 2121 // Check if we should add the vertical lines at left and right edge 2122 if( $this->iXAxisLblBgColor !== '' ) { 2123 $this->img->PushColor($this->iXAxisLblBgColor); 2124 if( $t == 2 || $t == 6 ) { 2125 $this->img->Line($xl,$yu-1,$xr,$yu-1); 2126 $this->img->Line($xl,$yl-1,$xr,$yl-1); 2127 } 2128 else { 2129 $this->img->Line($xr+1,$yu,$xr+1,$this->img->top_margin); 2130 } 2131 $this->img->PopColor(); 2132 } 2133 2134 } 2294 // Types 2295 // 0 = No background 2296 // 1 = Only X-labels, length of axis 2297 // 2 = Only Y-labels, length of axis 2298 // 3 = As 1 but extends to width of graph 2299 // 4 = As 2 but extends to height of graph 2300 // 5 = Combination of 3 & 4 2301 // 6 = Combination of 1 & 2 2302 2303 $t = $this->iAxisLblBgType ; 2304 if( $t < 1 ) return; 2305 2306 // Stroke optional X-axis label background color 2307 if( $t == 1 || $t == 3 || $t == 5 || $t == 6 ) { 2308 $this->img->PushColor($this->iXAxisLblBgFillColor); 2309 if( $t == 1 || $t == 6 ) { 2310 $xl = $this->img->left_margin; 2311 $yu = $this->img->height - $this->img->bottom_margin + 1; 2312 $xr = $this->img->width - $this->img->right_margin ; 2313 $yl = $this->img->height-1-$this->frame_weight; 2314 } 2315 else { // t==3 || t==5 2316 $xl = $this->frame_weight; 2317 $yu = $this->img->height - $this->img->bottom_margin + 1; 2318 $xr = $this->img->width - 1 - $this->frame_weight; 2319 $yl = $this->img->height-1-$this->frame_weight; 2320 } 2321 2322 $this->img->FilledRectangle($xl,$yu,$xr,$yl); 2323 $this->img->PopColor(); 2324 2325 // Check if we should add the vertical lines at left and right edge 2326 if( $this->iXAxisLblBgColor !== '' ) { 2327 // Hardcode to one pixel wide 2328 $this->img->SetLineWeight(1); 2329 $this->img->PushColor($this->iXAxisLblBgColor); 2330 if( $t == 1 || $t == 6 ) { 2331 $this->img->Line($xl,$yu,$xl,$yl); 2332 $this->img->Line($xr,$yu,$xr,$yl); 2333 } 2334 else { 2335 $xl = $this->img->width - $this->img->right_margin ; 2336 $this->img->Line($xl,$yu-1,$xr,$yu-1); 2337 } 2338 $this->img->PopColor(); 2339 } 2340 } 2341 2342 if( $t == 2 || $t == 4 || $t == 5 || $t == 6 ) { 2343 $this->img->PushColor($this->iYAxisLblBgFillColor); 2344 if( $t == 2 || $t == 6 ) { 2345 $xl = $this->frame_weight; 2346 $yu = $this->frame_weight+$this->img->top_margin; 2347 $xr = $this->img->left_margin - 1; 2348 $yl = $this->img->height - $this->img->bottom_margin + 1; 2349 } 2350 else { 2351 $xl = $this->frame_weight; 2352 $yu = $this->frame_weight; 2353 $xr = $this->img->left_margin - 1; 2354 $yl = $this->img->height-1-$this->frame_weight; 2355 } 2356 2357 $this->img->FilledRectangle($xl,$yu,$xr,$yl); 2358 $this->img->PopColor(); 2359 2360 // Check if we should add the vertical lines at left and right edge 2361 if( $this->iXAxisLblBgColor !== '' ) { 2362 $this->img->PushColor($this->iXAxisLblBgColor); 2363 if( $t == 2 || $t == 6 ) { 2364 $this->img->Line($xl,$yu-1,$xr,$yu-1); 2365 $this->img->Line($xl,$yl-1,$xr,$yl-1); 2366 } 2367 else { 2368 $this->img->Line($xr+1,$yu,$xr+1,$this->img->top_margin); 2369 } 2370 $this->img->PopColor(); 2371 } 2372 2373 } 2135 2374 } 2136 2375 2137 2376 function StrokeAxis($aStrokeLabels=true) { 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 $bottompos = SIDE_DOWN; 2155 2156 2157 2158 2159 $toppos = FALSE; 2160 2161 2162 2163 2164 2165 2166 $bottompos = SIDE_DOWN; 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 $this->xscale->ticks->SupressFirst(false); 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 // No title for the top X-axis 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 // No title for the right side 2209 2210 2211 2212 2213 2214 $this->yaxis->Stroke($this->xscale,$aStrokeLabels); 2215 2216 2217 2218 $this->yaxis->Stroke($this->xscale,$aStrokeLabels); 2219 2377 2378 if( $aStrokeLabels ) { 2379 $this->StrokeAxisLabelBackground(); 2380 } 2381 2382 // Stroke axis 2383 if( $this->iAxisStyle != AXSTYLE_SIMPLE ) { 2384 switch( $this->iAxisStyle ) { 2385 case AXSTYLE_BOXIN : 2386 $toppos = SIDE_DOWN; 2387 $bottompos = SIDE_UP; 2388 $leftpos = SIDE_RIGHT; 2389 $rightpos = SIDE_LEFT; 2390 break; 2391 case AXSTYLE_BOXOUT : 2392 $toppos = SIDE_UP; 2393 $bottompos = SIDE_DOWN; 2394 $leftpos = SIDE_LEFT; 2395 $rightpos = SIDE_RIGHT; 2396 break; 2397 case AXSTYLE_YBOXIN: 2398 $toppos = FALSE; 2399 $bottompos = SIDE_UP; 2400 $leftpos = SIDE_RIGHT; 2401 $rightpos = SIDE_LEFT; 2402 break; 2403 case AXSTYLE_YBOXOUT: 2404 $toppos = FALSE; 2405 $bottompos = SIDE_DOWN; 2406 $leftpos = SIDE_LEFT; 2407 $rightpos = SIDE_RIGHT; 2408 break; 2409 default: 2410 JpGRaphError::RaiseL(25036,$this->iAxisStyle); //('Unknown AxisStyle() : '.$this->iAxisStyle); 2411 break; 2412 } 2413 2414 // By default we hide the first label so it doesn't cross the 2415 // Y-axis in case the positon hasn't been set by the user. 2416 // However, if we use a box we always want the first value 2417 // displayed so we make sure it will be displayed. 2418 $this->xscale->ticks->SupressFirst(false); 2419 2420 // Now draw the bottom X-axis 2421 $this->xaxis->SetPos('min'); 2422 $this->xaxis->SetLabelSide(SIDE_DOWN); 2423 $this->xaxis->scale->ticks->SetSide($bottompos); 2424 $this->xaxis->Stroke($this->yscale,$aStrokeLabels); 2425 2426 if( $toppos !== FALSE ) { 2427 // We also want a top X-axis 2428 $this->xaxis = $this->xaxis; 2429 $this->xaxis->SetPos('max'); 2430 $this->xaxis->SetLabelSide(SIDE_UP); 2431 // No title for the top X-axis 2432 if( $aStrokeLabels ) { 2433 $this->xaxis->title->Set(''); 2434 } 2435 $this->xaxis->scale->ticks->SetSide($toppos); 2436 $this->xaxis->Stroke($this->yscale,$aStrokeLabels); 2437 } 2438 2439 // Stroke the left Y-axis 2440 $this->yaxis->SetPos('min'); 2441 $this->yaxis->SetLabelSide(SIDE_LEFT); 2442 $this->yaxis->scale->ticks->SetSide($leftpos); 2443 $this->yaxis->Stroke($this->xscale,$aStrokeLabels); 2444 2445 // Stroke the right Y-axis 2446 $this->yaxis->SetPos('max'); 2447 // No title for the right side 2448 if( $aStrokeLabels ) { 2449 $this->yaxis->title->Set(''); 2450 } 2451 $this->yaxis->SetLabelSide(SIDE_RIGHT); 2452 $this->yaxis->scale->ticks->SetSide($rightpos); 2453 $this->yaxis->Stroke($this->xscale,$aStrokeLabels); 2454 } 2455 else { 2456 $this->xaxis->Stroke($this->yscale,$aStrokeLabels); 2457 $this->yaxis->Stroke($this->xscale,$aStrokeLabels); 2458 } 2220 2459 } 2221 2460 … … 2223 2462 // Private helper function for backgound image 2224 2463 static function LoadBkgImage($aImgFormat='',$aFile='',$aImgStr='') { 2225 if( $aImgStr != '' ) { 2226 return Image::CreateFromString($aImgStr); 2227 } 2228 2229 // Remove case sensitivity and setup appropriate function to create image 2230 // Get file extension. This should be the LAST '.' separated part of the filename 2231 $e = explode('.',$aFile); 2232 $ext = strtolower($e[count($e)-1]); 2233 if ($ext == "jpeg") { 2234 $ext = "jpg"; 2235 } 2236 2237 if( trim($ext) == '' ) 2238 $ext = 'png'; // Assume PNG if no extension specified 2239 2240 if( $aImgFormat == '' ) 2241 $imgtag = $ext; 2242 else 2243 $imgtag = $aImgFormat; 2244 2245 $supported = imagetypes(); 2246 if( ( $ext == 'jpg' && !($supported & IMG_JPG) ) || 2247 ( $ext == 'gif' && !($supported & IMG_GIF) ) || 2248 ( $ext == 'png' && !($supported & IMG_PNG) ) || 2249 ( $ext == 'bmp' && !($supported & IMG_WBMP) ) || 2250 ( $ext == 'xpm' && !($supported & IMG_XPM) ) ) { 2251 2252 JpGraphError::RaiseL(25037,$aFile);//('The image format of your background image ('.$aFile.') is not supported in your system configuration. '); 2253 } 2254 2255 2256 if( $imgtag == "jpg" || $imgtag == "jpeg") 2257 { 2258 $f = "imagecreatefromjpeg"; 2259 $imgtag = "jpg"; 2260 } 2261 else 2262 { 2263 $f = "imagecreatefrom".$imgtag; 2264 } 2265 2266 // Compare specified image type and file extension 2267 if( $imgtag != $ext ) { 2268 //$t = "Background image seems to be of different type (has different file extension) than specified imagetype. Specified: '".$aImgFormat."'File: '".$aFile."'"; 2269 JpGraphError::RaiseL(25038, $aImgFormat, $aFile); 2270 } 2271 2272 $img = @$f($aFile); 2273 if( !$img ) { 2274 JpGraphError::RaiseL(25039,$aFile);//(" Can't read background image: '".$aFile."'"); 2275 } 2276 return $img; 2277 } 2464 if( $aImgStr != '' ) { 2465 return Image::CreateFromString($aImgStr); 2466 } 2467 2468 // Remove case sensitivity and setup appropriate function to create image 2469 // Get file extension. This should be the LAST '.' separated part of the filename 2470 $e = explode('.',$aFile); 2471 $ext = strtolower($e[count($e)-1]); 2472 if ($ext == "jpeg") { 2473 $ext = "jpg"; 2474 } 2475 2476 if( trim($ext) == '' ) { 2477 $ext = 'png'; // Assume PNG if no extension specified 2478 } 2479 2480 if( $aImgFormat == '' ) { 2481 $imgtag = $ext; 2482 } 2483 else { 2484 $imgtag = $aImgFormat; 2485 } 2486 2487 $supported = imagetypes(); 2488 if( ( $ext == 'jpg' && !($supported & IMG_JPG) ) || 2489 ( $ext == 'gif' && !($supported & IMG_GIF) ) || 2490 ( $ext == 'png' && !($supported & IMG_PNG) ) || 2491 ( $ext == 'bmp' && !($supported & IMG_WBMP) ) || 2492 ( $ext == 'xpm' && !($supported & IMG_XPM) ) ) { 2493 2494 JpGraphError::RaiseL(25037,$aFile);//('The image format of your background image ('.$aFile.') is not supported in your system configuration. '); 2495 } 2496 2497 2498 if( $imgtag == "jpg" || $imgtag == "jpeg") { 2499 $f = "imagecreatefromjpeg"; 2500 $imgtag = "jpg"; 2501 } 2502 else { 2503 $f = "imagecreatefrom".$imgtag; 2504 } 2505 2506 // Compare specified image type and file extension 2507 if( $imgtag != $ext ) { 2508 //$t = "Background image seems to be of different type (has different file extension) than specified imagetype. Specified: '".$aImgFormat."'File: '".$aFile."'"; 2509 JpGraphError::RaiseL(25038, $aImgFormat, $aFile); 2510 } 2511 2512 $img = @$f($aFile); 2513 if( !$img ) { 2514 JpGraphError::RaiseL(25039,$aFile);//(" Can't read background image: '".$aFile."'"); 2515 } 2516 return $img; 2517 } 2518 2519 function StrokePlotGrad() { 2520 if( $this->plot_gradtype < 0 ) 2521 return; 2522 2523 $grad = new Gradient($this->img); 2524 $xl = $this->img->left_margin; 2525 $yt = $this->img->top_margin; 2526 $xr = $xl + $this->img->plotwidth+1 ; 2527 $yb = $yt + $this->img->plotheight ; 2528 $grad->FilledRectangle($xl,$yt,$xr,$yb,$this->plot_gradfrom,$this->plot_gradto,$this->plot_gradtype); 2529 2530 } 2278 2531 2279 2532 function StrokeBackgroundGrad() { 2280 if( $this->bkg_gradtype < 0 ) 2281 return; 2282 $grad = new Gradient($this->img); 2283 if( $this->bkg_gradstyle == BGRAD_PLOT ) { 2284 $xl = $this->img->left_margin; 2285 $yt = $this->img->top_margin; 2286 $xr = $xl + $this->img->plotwidth+1 ; 2287 $yb = $yt + $this->img->plotheight ; 2288 $grad->FilledRectangle($xl,$yt,$xr,$yb,$this->bkg_gradfrom,$this->bkg_gradto,$this->bkg_gradtype); 2289 } 2290 else { 2291 $xl = 0; 2292 $yt = 0; 2293 $xr = $xl + $this->img->width - 1; 2294 $yb = $yt + $this->img->height ; 2295 if( $this->doshadow ) { 2296 $xr -= $this->shadow_width; 2297 $yb -= $this->shadow_width; 2298 } 2299 if( $this->doframe ) { 2300 $yt += $this->frame_weight; 2301 $yb -= $this->frame_weight; 2302 $xl += $this->frame_weight; 2303 $xr -= $this->frame_weight; 2304 } 2305 $aa = $this->img->SetAngle(0); 2306 $grad->FilledRectangle($xl,$yt,$xr,$yb,$this->bkg_gradfrom,$this->bkg_gradto,$this->bkg_gradtype); 2307 $aa = $this->img->SetAngle($aa); 2308 } 2533 if( $this->bkg_gradtype < 0 ) 2534 return; 2535 2536 $grad = new Gradient($this->img); 2537 if( $this->bkg_gradstyle == BGRAD_PLOT ) { 2538 $xl = $this->img->left_margin; 2539 $yt = $this->img->top_margin; 2540 $xr = $xl + $this->img->plotwidth+1 ; 2541 $yb = $yt + $this->img->plotheight ; 2542 $grad->FilledRectangle($xl,$yt,$xr,$yb,$this->bkg_gradfrom,$this->bkg_gradto,$this->bkg_gradtype); 2543 } 2544 else { 2545 $xl = 0; 2546 $yt = 0; 2547 $xr = $xl + $this->img->width - 1; 2548 $yb = $yt + $this->img->height - 1 ; 2549 if( $this->doshadow ) { 2550 $xr -= $this->shadow_width; 2551 $yb -= $this->shadow_width; 2552 } 2553 if( $this->doframe ) { 2554 $yt += $this->frame_weight; 2555 $yb -= $this->frame_weight; 2556 $xl += $this->frame_weight; 2557 $xr -= $this->frame_weight; 2558 } 2559 $aa = $this->img->SetAngle(0); 2560 $grad->FilledRectangle($xl,$yt,$xr,$yb,$this->bkg_gradfrom,$this->bkg_gradto,$this->bkg_gradtype); 2561 $aa = $this->img->SetAngle($aa); 2562 } 2309 2563 } 2310 2564 2311 2565 function StrokeFrameBackground() { 2312 if( $this->background_image != "" && $this->background_cflag != "" ) { 2313 JpGraphError::RaiseL(25040);//('It is not possible to specify both a background image and a background country flag.'); 2314 } 2315 if( $this->background_image != "" ) { 2316 $bkgimg = $this->LoadBkgImage($this->background_image_format,$this->background_image); 2317 } 2318 elseif( $this->background_cflag != "" ) { 2319 if( ! class_exists('FlagImages',false) ) { 2320 JpGraphError::RaiseL(25041);//('In order to use Country flags as backgrounds you must include the "jpgraph_flags.php" file.'); 2321 } 2322 $fobj = new FlagImages(FLAGSIZE4); 2323 $dummy=''; 2324 $bkgimg = $fobj->GetImgByName($this->background_cflag,$dummy); 2325 $this->background_image_mix = $this->background_cflag_mix; 2326 $this->background_image_type = $this->background_cflag_type; 2327 } 2328 else { 2329 return ; 2330 } 2331 2332 $bw = ImageSX($bkgimg); 2333 $bh = ImageSY($bkgimg); 2334 2335 // No matter what the angle is we always stroke the image and frame 2336 // assuming it is 0 degree 2337 $aa = $this->img->SetAngle(0); 2338 2339 switch( $this->background_image_type ) { 2340 case BGIMG_FILLPLOT: // Resize to just fill the plotarea 2341 $this->FillMarginArea(); 2342 $this->StrokeFrame(); 2343 // Special case to hande 90 degree rotated graph corectly 2344 if( $aa == 90 ) { 2345 $this->img->SetAngle(90); 2346 $this->FillPlotArea(); 2347 $aa = $this->img->SetAngle(0); 2348 $adj = ($this->img->height - $this->img->width)/2; 2349 $this->img->CopyMerge($bkgimg, 2350 $this->img->bottom_margin-$adj,$this->img->left_margin+$adj, 2351 0,0, 2352 $this->img->plotheight+1,$this->img->plotwidth, 2353 $bw,$bh,$this->background_image_mix); 2354 2355 } 2356 else { 2357 $this->FillPlotArea(); 2358 $this->img->CopyMerge($bkgimg, 2359 $this->img->left_margin,$this->img->top_margin, 2360 0,0,$this->img->plotwidth+1,$this->img->plotheight, 2361 $bw,$bh,$this->background_image_mix); 2362 } 2363 break; 2364 case BGIMG_FILLFRAME: // Fill the whole area from upper left corner, resize to just fit 2365 $hadj=0; $vadj=0; 2366 if( $this->doshadow ) { 2367 $hadj = $this->shadow_width; 2368 $vadj = $this->shadow_width; 2369 } 2370 $this->FillMarginArea(); 2371 $this->FillPlotArea(); 2372 $this->img->CopyMerge($bkgimg,0,0,0,0,$this->img->width-$hadj,$this->img->height-$vadj, 2373 $bw,$bh,$this->background_image_mix); 2374 $this->StrokeFrame(); 2375 break; 2376 case BGIMG_COPY: // Just copy the image from left corner, no resizing 2377 $this->FillMarginArea(); 2378 $this->FillPlotArea(); 2379 $this->img->CopyMerge($bkgimg,0,0,0,0,$bw,$bh, 2380 $bw,$bh,$this->background_image_mix); 2381 $this->StrokeFrame(); 2382 break; 2383 case BGIMG_CENTER: // Center original image in the plot area 2384 $this->FillMarginArea(); 2385 $this->FillPlotArea(); 2386 $centerx = round($this->img->plotwidth/2+$this->img->left_margin-$bw/2); 2387 $centery = round($this->img->plotheight/2+$this->img->top_margin-$bh/2); 2388 $this->img->CopyMerge($bkgimg,$centerx,$centery,0,0,$bw,$bh, 2389 $bw,$bh,$this->background_image_mix); 2390 $this->StrokeFrame(); 2391 break; 2392 case BGIMG_FREE: // Just copy the image to the specified location 2393 $this->img->CopyMerge($bkgimg, 2394 $this->background_image_xpos,$this->background_image_ypos, 2395 0,0,$bw,$bh,$bw,$bh,$this->background_image_mix); 2396 $this->StrokeFrame(); // New 2397 break; 2398 default: 2399 JpGraphError::RaiseL(25042);//(" Unknown background image layout"); 2400 } 2401 $this->img->SetAngle($aa); 2566 if( $this->background_image != '' && $this->background_cflag != '' ) { 2567 JpGraphError::RaiseL(25040);//('It is not possible to specify both a background image and a background country flag.'); 2568 } 2569 if( $this->background_image != '' ) { 2570 $bkgimg = $this->LoadBkgImage($this->background_image_format,$this->background_image); 2571 } 2572 elseif( $this->background_cflag != '' ) { 2573 if( ! class_exists('FlagImages',false) ) { 2574 JpGraphError::RaiseL(25041);//('In order to use Country flags as backgrounds you must include the "jpgraph_flags.php" file.'); 2575 } 2576 $fobj = new FlagImages(FLAGSIZE4); 2577 $dummy=''; 2578 $bkgimg = $fobj->GetImgByName($this->background_cflag,$dummy); 2579 $this->background_image_mix = $this->background_cflag_mix; 2580 $this->background_image_type = $this->background_cflag_type; 2581 } 2582 else { 2583 return ; 2584 } 2585 2586 $bw = ImageSX($bkgimg); 2587 $bh = ImageSY($bkgimg); 2588 2589 // No matter what the angle is we always stroke the image and frame 2590 // assuming it is 0 degree 2591 $aa = $this->img->SetAngle(0); 2592 2593 switch( $this->background_image_type ) { 2594 case BGIMG_FILLPLOT: // Resize to just fill the plotarea 2595 $this->FillMarginArea(); 2596 $this->StrokeFrame(); 2597 // Special case to hande 90 degree rotated graph corectly 2598 if( $aa == 90 ) { 2599 $this->img->SetAngle(90); 2600 $this->FillPlotArea(); 2601 $aa = $this->img->SetAngle(0); 2602 $adj = ($this->img->height - $this->img->width)/2; 2603 $this->img->CopyMerge($bkgimg, 2604 $this->img->bottom_margin-$adj,$this->img->left_margin+$adj, 2605 0,0, 2606 $this->img->plotheight+1,$this->img->plotwidth, 2607 $bw,$bh,$this->background_image_mix); 2608 } 2609 else { 2610 $this->FillPlotArea(); 2611 $this->img->CopyMerge($bkgimg, 2612 $this->img->left_margin,$this->img->top_margin+1, 2613 0,0,$this->img->plotwidth+1,$this->img->plotheight, 2614 $bw,$bh,$this->background_image_mix); 2615 } 2616 break; 2617 case BGIMG_FILLFRAME: // Fill the whole area from upper left corner, resize to just fit 2618 $hadj=0; $vadj=0; 2619 if( $this->doshadow ) { 2620 $hadj = $this->shadow_width; 2621 $vadj = $this->shadow_width; 2622 } 2623 $this->FillMarginArea(); 2624 $this->FillPlotArea(); 2625 $this->img->CopyMerge($bkgimg,0,0,0,0,$this->img->width-$hadj,$this->img->height-$vadj, 2626 $bw,$bh,$this->background_image_mix); 2627 $this->StrokeFrame(); 2628 break; 2629 case BGIMG_COPY: // Just copy the image from left corner, no resizing 2630 $this->FillMarginArea(); 2631 $this->FillPlotArea(); 2632 $this->img->CopyMerge($bkgimg,0,0,0,0,$bw,$bh, 2633 $bw,$bh,$this->background_image_mix); 2634 $this->StrokeFrame(); 2635 break; 2636 case BGIMG_CENTER: // Center original image in the plot area 2637 $this->FillMarginArea(); 2638 $this->FillPlotArea(); 2639 $centerx = round($this->img->plotwidth/2+$this->img->left_margin-$bw/2); 2640 $centery = round($this->img->plotheight/2+$this->img->top_margin-$bh/2); 2641 $this->img->CopyMerge($bkgimg,$centerx,$centery,0,0,$bw,$bh, 2642 $bw,$bh,$this->background_image_mix); 2643 $this->StrokeFrame(); 2644 break; 2645 case BGIMG_FREE: // Just copy the image to the specified location 2646 $this->img->CopyMerge($bkgimg, 2647 $this->background_image_xpos,$this->background_image_ypos, 2648 0,0,$bw,$bh,$bw,$bh,$this->background_image_mix); 2649 $this->StrokeFrame(); // New 2650 break; 2651 default: 2652 JpGraphError::RaiseL(25042);//(" Unknown background image layout"); 2653 } 2654 $this->img->SetAngle($aa); 2402 2655 } 2403 2656 … … 2405 2658 // Draw a frame around the image 2406 2659 function StrokeFrame() { 2407 if( !$this->doframe ) return; 2408 2409 if( $this->background_image_type <= 1 && 2410 ($this->bkg_gradtype < 0 || ($this->bkg_gradtype > 0 && $this->bkg_gradstyle==BGRAD_PLOT)) ) { 2411 $c = $this->margin_color; 2412 } 2413 else { 2414 $c = false; 2415 } 2416 2417 if( $this->doshadow ) { 2418 $this->img->SetColor($this->frame_color); 2419 $this->img->ShadowRectangle(0,0,$this->img->width,$this->img->height, 2420 $c,$this->shadow_width,$this->shadow_color); 2421 } 2422 elseif( $this->framebevel ) { 2423 if( $c ) { 2424 $this->img->SetColor($this->margin_color); 2425 $this->img->FilledRectangle(0,0,$this->img->width-1,$this->img->height-1); 2426 } 2427 $this->img->Bevel(1,1,$this->img->width-2,$this->img->height-2, 2428 $this->framebeveldepth, 2429 $this->framebevelcolor1,$this->framebevelcolor2); 2430 if( $this->framebevelborder ) { 2431 $this->img->SetColor($this->framebevelbordercolor); 2432 $this->img->Rectangle(0,0,$this->img->width-1,$this->img->height-1); 2433 } 2434 } 2435 else { 2436 $this->img->SetLineWeight($this->frame_weight); 2437 if( $c ) { 2438 $this->img->SetColor($this->margin_color); 2439 $this->img->FilledRectangle(0,0,$this->img->width-1,$this->img->height-1); 2440 } 2441 $this->img->SetColor($this->frame_color); 2442 $this->img->Rectangle(0,0,$this->img->width-1,$this->img->height-1); 2443 } 2660 if( !$this->doframe ) return; 2661 2662 if( $this->background_image_type <= 1 && ($this->bkg_gradtype < 0 || ($this->bkg_gradtype > 0 && $this->bkg_gradstyle==BGRAD_PLOT)) ) { 2663 $c = $this->margin_color; 2664 } 2665 else { 2666 $c = false; 2667 } 2668 2669 if( $this->doshadow ) { 2670 $this->img->SetColor($this->frame_color); 2671 $this->img->ShadowRectangle(0,0,$this->img->width,$this->img->height, 2672 $c,$this->shadow_width,$this->shadow_color); 2673 } 2674 elseif( $this->framebevel ) { 2675 if( $c ) { 2676 $this->img->SetColor($this->margin_color); 2677 $this->img->FilledRectangle(0,0,$this->img->width-1,$this->img->height-1); 2678 } 2679 $this->img->Bevel(1,1,$this->img->width-2,$this->img->height-2, 2680 $this->framebeveldepth, 2681 $this->framebevelcolor1,$this->framebevelcolor2); 2682 if( $this->framebevelborder ) { 2683 $this->img->SetColor($this->framebevelbordercolor); 2684 $this->img->Rectangle(0,0,$this->img->width-1,$this->img->height-1); 2685 } 2686 } 2687 else { 2688 $this->img->SetLineWeight($this->frame_weight); 2689 if( $c ) { 2690 $this->img->SetColor($this->margin_color); 2691 $this->img->FilledRectangle(0,0,$this->img->width-1,$this->img->height-1); 2692 } 2693 $this->img->SetColor($this->frame_color); 2694 $this->img->Rectangle(0,0,$this->img->width-1,$this->img->height-1); 2695 } 2444 2696 } 2445 2697 2446 2698 function FillMarginArea() { 2447 2448 2449 2450 2451 2452 2453 2454 // $this->img->FilledRectangle(0,0,$this->img->width-1-$hadj,$this->img->height-1-$vadj); 2455 2456 $this->img->FilledRectangle(0,0,$this->img->width-1-$hadj,$this->img->top_margin); 2457 $this->img->FilledRectangle(0,$this->img->top_margin,$this->img->left_margin,$this->img->height-1-$hadj); 2458 2459 2460 2461 $this->img->height-1-$hadj); 2462 2463 2464 2465 $this->img->height-$this->img->bottom_margin-1); 2699 $hadj=0; $vadj=0; 2700 if( $this->doshadow ) { 2701 $hadj = $this->shadow_width; 2702 $vadj = $this->shadow_width; 2703 } 2704 2705 $this->img->SetColor($this->margin_color); 2706 $this->img->FilledRectangle(0,0,$this->img->width-1-$hadj,$this->img->height-1-$vadj); 2707 2708 $this->img->FilledRectangle(0,0,$this->img->width-1-$hadj,$this->img->top_margin); 2709 $this->img->FilledRectangle(0,$this->img->top_margin,$this->img->left_margin,$this->img->height-1-$hadj); 2710 $this->img->FilledRectangle($this->img->left_margin+1, 2711 $this->img->height-$this->img->bottom_margin, 2712 $this->img->width-1-$hadj, 2713 $this->img->height-1-$hadj); 2714 $this->img->FilledRectangle($this->img->width-$this->img->right_margin, 2715 $this->img->top_margin+1, 2716 $this->img->width-1-$hadj, 2717 $this->img->height-$this->img->bottom_margin-1); 2466 2718 } 2467 2719 2468 2720 function FillPlotArea() { 2469 2470 2471 2472 2473 $this->img->height-$this->img->bottom_margin); 2474 2475 } 2476 2721 $this->img->PushColor($this->plotarea_color); 2722 $this->img->FilledRectangle($this->img->left_margin, 2723 $this->img->top_margin, 2724 $this->img->width-$this->img->right_margin, 2725 $this->img->height-$this->img->bottom_margin); 2726 $this->img->PopColor(); 2727 } 2728 2477 2729 // Stroke the plot area with either a solid color or a background image 2478 2730 function StrokePlotArea() { 2479 2480 2481 2482 // means it has no way of compensating for the adjusted plotarea in case of a 2483 2484 2485 2486 2487 2488 if( $this->background_image != "" || $this->background_cflag != "") {2489 2490 2491 2492 2493 2494 2495 $this->StrokeBackgroundGrad(); 2496 if( $this->bkg_gradtype < 0 || 2497 ($this->bkg_gradtype > 0 && $this->bkg_gradstyle==BGRAD_MARGIN) ) { 2498 $this->FillPlotArea(); 2499 } 2500 } 2501 } 2731 // Note: To be consistent we really should take a possible shadow 2732 // into account. However, that causes some problem for the LinearScale class 2733 // since in the current design it does not have any links to class Graph which 2734 // means it has no way of compensating for the adjusted plotarea in case of a 2735 // shadow. So, until I redesign LinearScale we can't compensate for this. 2736 // So just set the two adjustment parameters to zero for now. 2737 $boxadj = 0; //$this->doframe ? $this->frame_weight : 0 ; 2738 $adj = 0; //$this->doshadow ? $this->shadow_width : 0 ; 2739 2740 if( $this->background_image != '' || $this->background_cflag != '' ) { 2741 $this->StrokeFrameBackground(); 2742 } 2743 else { 2744 $aa = $this->img->SetAngle(0); 2745 $this->StrokeFrame(); 2746 $aa = $this->img->SetAngle($aa); 2747 $this->StrokeBackgroundGrad(); 2748 if( $this->bkg_gradtype < 0 || ($this->bkg_gradtype > 0 && $this->bkg_gradstyle==BGRAD_MARGIN) ) { 2749 $this->FillPlotArea(); 2750 } 2751 $this->StrokePlotGrad(); 2752 } 2753 } 2502 2754 2503 2755 function StrokeIcons() { 2504 2505 2506 2507 2508 } 2509 2756 $n = count($this->iIcons); 2757 for( $i=0; $i < $n; ++$i ) { 2758 $this->iIcons[$i]->StrokeWithScale($this->img,$this->xscale,$this->yscale); 2759 } 2760 } 2761 2510 2762 function StrokePlotBox() { 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 } 2523 } 2763 // Should we draw a box around the plot area? 2764 if( $this->boxed ) { 2765 $this->img->SetLineWeight(1); 2766 $this->img->SetLineStyle('solid'); 2767 $this->img->SetColor($this->box_color); 2768 for($i=0; $i < $this->box_weight; ++$i ) { 2769 $this->img->Rectangle( 2770 $this->img->left_margin-$i,$this->img->top_margin-$i, 2771 $this->img->width-$this->img->right_margin+$i, 2772 $this->img->height-$this->img->bottom_margin+$i); 2773 } 2774 } 2775 } 2524 2776 2525 2777 function SetTitleBackgroundFillStyle($aStyle,$aColor1='black',$aColor2='white') { 2526 2527 2528 2778 $this->titlebkg_fillstyle = $aStyle; 2779 $this->titlebkg_scolor1 = $aColor1; 2780 $this->titlebkg_scolor2 = $aColor2; 2529 2781 } 2530 2782 2531 2783 function SetTitleBackground($aBackColor='gray', $aStyle=TITLEBKG_STYLE1, $aFrameStyle=TITLEBKG_FRAME_NONE, $aFrameColor='black', $aFrameWeight=1, $aBevelHeight=3, $aEnable=true) { 2532 2533 2534 2535 2536 2537 $this->titlebackground_frameweight = $aFrameWeight; 2538 2784 $this->titlebackground = $aEnable; 2785 $this->titlebackground_color = $aBackColor; 2786 $this->titlebackground_style = $aStyle; 2787 $this->titlebackground_framecolor = $aFrameColor; 2788 $this->titlebackground_framestyle = $aFrameStyle; 2789 $this->titlebackground_frameweight = $aFrameWeight; 2790 $this->titlebackground_bevelheight = $aBevelHeight ; 2539 2791 } 2540 2792 … … 2542 2794 function StrokeTitles() { 2543 2795 2544 $margin=3; 2545 2546 if( $this->titlebackground ) { 2547 2548 // Find out height 2549 $this->title->margin += 2 ; 2550 $h = $this->title->GetTextHeight($this->img)+$this->title->margin+$margin; 2551 if( $this->subtitle->t != "" && !$this->subtitle->hide ) { 2552 $h += $this->subtitle->GetTextHeight($this->img)+$margin+ 2553 $this->subtitle->margin; 2554 $h += 2; 2555 } 2556 if( $this->subsubtitle->t != "" && !$this->subsubtitle->hide ) { 2557 $h += $this->subsubtitle->GetTextHeight($this->img)+$margin+ 2558 $this->subsubtitle->margin; 2559 $h += 2; 2560 } 2561 $this->img->PushColor($this->titlebackground_color); 2562 if( $this->titlebackground_style === TITLEBKG_STYLE1 ) { 2563 // Inside the frame 2564 if( $this->framebevel ) { 2565 $x1 = $y1 = $this->framebeveldepth + 1 ; 2566 $x2 = $this->img->width - $this->framebeveldepth - 2 ; 2567 $this->title->margin += $this->framebeveldepth + 1 ; 2568 $h += $y1 ; 2569 $h += 2; 2570 } 2571 else { 2572 $x1 = $y1 = $this->frame_weight; 2573 $x2 = $this->img->width - 2*$x1; 2574 } 2575 } 2576 elseif( $this->titlebackground_style === TITLEBKG_STYLE2 ) { 2577 // Cover the frame as well 2578 $x1 = $y1 = 0; 2579 $x2 = $this->img->width - 1 ; 2580 } 2581 elseif( $this->titlebackground_style === TITLEBKG_STYLE3 ) { 2582 // Cover the frame as well (the difference is that 2583 // for style==3 a bevel frame border is on top 2584 // of the title background) 2585 $x1 = $y1 = 0; 2586 $x2 = $this->img->width - 1 ; 2587 $h += $this->framebeveldepth ; 2588 $this->title->margin += $this->framebeveldepth ; 2589 } 2590 else { 2591 JpGraphError::RaiseL(25043);//('Unknown title background style.'); 2592 } 2593 2594 if( $this->titlebackground_framestyle === 3 ) { 2595 $h += $this->titlebackground_bevelheight*2 + 1 ; 2596 $this->title->margin += $this->titlebackground_bevelheight ; 2597 } 2598 2599 if( $this->doshadow ) { 2600 $x2 -= $this->shadow_width ; 2601 } 2602 2603 $indent=0; 2604 if( $this->titlebackground_framestyle == TITLEBKG_FRAME_BEVEL ) { 2605 $ind = $this->titlebackground_bevelheight; 2606 } 2607 2608 if( $this->titlebkg_fillstyle==TITLEBKG_FILLSTYLE_HSTRIPED ) { 2609 $this->img->FilledRectangle2($x1+$ind,$y1+$ind,$x2-$ind,$h-$ind, 2610 $this->titlebkg_scolor1, 2611 $this->titlebkg_scolor2); 2612 } 2613 elseif( $this->titlebkg_fillstyle==TITLEBKG_FILLSTYLE_VSTRIPED ) { 2614 $this->img->FilledRectangle2($x1+$ind,$y1+$ind,$x2-$ind,$h-$ind, 2615 $this->titlebkg_scolor1, 2616 $this->titlebkg_scolor2,2); 2617 } 2618 else { 2619 // Solid fill 2620 $this->img->FilledRectangle($x1,$y1,$x2,$h); 2621 } 2622 $this->img->PopColor(); 2623 2624 $this->img->PushColor($this->titlebackground_framecolor); 2625 $this->img->SetLineWeight($this->titlebackground_frameweight); 2626 if( $this->titlebackground_framestyle == TITLEBKG_FRAME_FULL ) { 2627 // Frame background 2628 $this->img->Rectangle($x1,$y1,$x2,$h); 2629 } 2630 elseif( $this->titlebackground_framestyle == TITLEBKG_FRAME_BOTTOM ) { 2631 // Bottom line only 2632 $this->img->Line($x1,$h,$x2,$h); 2633 } 2634 elseif( $this->titlebackground_framestyle == TITLEBKG_FRAME_BEVEL ) { 2635 $this->img->Bevel($x1,$y1,$x2,$h,$this->titlebackground_bevelheight); 2636 } 2637 $this->img->PopColor(); 2638 2639 // This is clumsy. But we neeed to stroke the whole graph frame if it is 2640 // set to bevel to get the bevel shading on top of the text background 2641 if( $this->framebevel && $this->doframe && 2642 $this->titlebackground_style === 3 ) { 2643 $this->img->Bevel(1,1,$this->img->width-2,$this->img->height-2, 2644 $this->framebeveldepth, 2645 $this->framebevelcolor1,$this->framebevelcolor2); 2646 if( $this->framebevelborder ) { 2647 $this->img->SetColor($this->framebevelbordercolor); 2648 $this->img->Rectangle(0,0,$this->img->width-1,$this->img->height-1); 2649 } 2650 } 2651 } 2652 2653 // Stroke title 2654 $y = $this->title->margin; 2655 if( $this->title->halign == 'center' ) 2656 $this->title->Center(0,$this->img->width,$y); 2657 elseif( $this->title->halign == 'left' ) { 2658 $this->title->SetPos($this->title->margin+2,$y); 2659 } 2660 elseif( $this->title->halign == 'right' ) { 2661 $indent = 0; 2662 if( $this->doshadow ) 2663 $indent = $this->shadow_width+2; 2664 $this->title->SetPos($this->img->width-$this->title->margin-$indent,$y,'right'); 2665 } 2666 $this->title->Stroke($this->img); 2667 2668 // ... and subtitle 2669 $y += $this->title->GetTextHeight($this->img) + $margin + $this->subtitle->margin; 2670 if( $this->subtitle->halign == 'center' ) 2671 $this->subtitle->Center(0,$this->img->width,$y); 2672 elseif( $this->subtitle->halign == 'left' ) { 2673 $this->subtitle->SetPos($this->subtitle->margin+2,$y); 2674 } 2675 elseif( $this->subtitle->halign == 'right' ) { 2676 $indent = 0; 2677 if( $this->doshadow ) 2678 $indent = $this->shadow_width+2; 2679 $this->subtitle->SetPos($this->img->width-$this->subtitle->margin-$indent,$y,'right'); 2680 } 2681 $this->subtitle->Stroke($this->img); 2682 2683 // ... and subsubtitle 2684 $y += $this->subtitle->GetTextHeight($this->img) + $margin + $this->subsubtitle->margin; 2685 if( $this->subsubtitle->halign == 'center' ) 2686 $this->subsubtitle->Center(0,$this->img->width,$y); 2687 elseif( $this->subsubtitle->halign == 'left' ) { 2688 $this->subsubtitle->SetPos($this->subsubtitle->margin+2,$y); 2689 } 2690 elseif( $this->subsubtitle->halign == 'right' ) { 2691 $indent = 0; 2692 if( $this->doshadow ) 2693 $indent = $this->shadow_width+2; 2694 $this->subsubtitle->SetPos($this->img->width-$this->subsubtitle->margin-$indent,$y,'right'); 2695 } 2696 $this->subsubtitle->Stroke($this->img); 2697 2698 // ... and fancy title 2699 $this->tabtitle->Stroke($this->img); 2796 $margin=3; 2797 2798 if( $this->titlebackground ) { 2799 // Find out height 2800 $this->title->margin += 2 ; 2801 $h = $this->title->GetTextHeight($this->img)+$this->title->margin+$margin; 2802 if( $this->subtitle->t != '' && !$this->subtitle->hide ) { 2803 $h += $this->subtitle->GetTextHeight($this->img)+$margin+ 2804 $this->subtitle->margin; 2805 $h += 2; 2806 } 2807 if( $this->subsubtitle->t != '' && !$this->subsubtitle->hide ) { 2808 $h += $this->subsubtitle->GetTextHeight($this->img)+$margin+ 2809 $this->subsubtitle->margin; 2810 $h += 2; 2811 } 2812 $this->img->PushColor($this->titlebackground_color); 2813 if( $this->titlebackground_style === TITLEBKG_STYLE1 ) { 2814 // Inside the frame 2815 if( $this->framebevel ) { 2816 $x1 = $y1 = $this->framebeveldepth + 1 ; 2817 $x2 = $this->img->width - $this->framebeveldepth - 2 ; 2818 $this->title->margin += $this->framebeveldepth + 1 ; 2819 $h += $y1 ; 2820 $h += 2; 2821 } 2822 else { 2823 $x1 = $y1 = $this->frame_weight; 2824 $x2 = $this->img->width - $this->frame_weight-1; 2825 } 2826 } 2827 elseif( $this->titlebackground_style === TITLEBKG_STYLE2 ) { 2828 // Cover the frame as well 2829 $x1 = $y1 = 0; 2830 $x2 = $this->img->width - 1 ; 2831 } 2832 elseif( $this->titlebackground_style === TITLEBKG_STYLE3 ) { 2833 // Cover the frame as well (the difference is that 2834 // for style==3 a bevel frame border is on top 2835 // of the title background) 2836 $x1 = $y1 = 0; 2837 $x2 = $this->img->width - 1 ; 2838 $h += $this->framebeveldepth ; 2839 $this->title->margin += $this->framebeveldepth ; 2840 } 2841 else { 2842 JpGraphError::RaiseL(25043);//('Unknown title background style.'); 2843 } 2844 2845 if( $this->titlebackground_framestyle === 3 ) { 2846 $h += $this->titlebackground_bevelheight*2 + 1 ; 2847 $this->title->margin += $this->titlebackground_bevelheight ; 2848 } 2849 2850 if( $this->doshadow ) { 2851 $x2 -= $this->shadow_width ; 2852 } 2853 2854 $indent=0; 2855 if( $this->titlebackground_framestyle == TITLEBKG_FRAME_BEVEL ) { 2856 $indent = $this->titlebackground_bevelheight; 2857 } 2858 2859 if( $this->titlebkg_fillstyle==TITLEBKG_FILLSTYLE_HSTRIPED ) { 2860 $this->img->FilledRectangle2($x1+$indent,$y1+$indent,$x2-$indent,$h-$indent, 2861 $this->titlebkg_scolor1, 2862 $this->titlebkg_scolor2); 2863 } 2864 elseif( $this->titlebkg_fillstyle==TITLEBKG_FILLSTYLE_VSTRIPED ) { 2865 $this->img->FilledRectangle2($x1+$indent,$y1+$indent,$x2-$indent,$h-$indent, 2866 $this->titlebkg_scolor1, 2867 $this->titlebkg_scolor2,2); 2868 } 2869 else { 2870 // Solid fill 2871 $this->img->FilledRectangle($x1,$y1,$x2,$h); 2872 } 2873 $this->img->PopColor(); 2874 2875 $this->img->PushColor($this->titlebackground_framecolor); 2876 $this->img->SetLineWeight($this->titlebackground_frameweight); 2877 if( $this->titlebackground_framestyle == TITLEBKG_FRAME_FULL ) { 2878 // Frame background 2879 $this->img->Rectangle($x1,$y1,$x2,$h); 2880 } 2881 elseif( $this->titlebackground_framestyle == TITLEBKG_FRAME_BOTTOM ) { 2882 // Bottom line only 2883 $this->img->Line($x1,$h,$x2,$h); 2884 } 2885 elseif( $this->titlebackground_framestyle == TITLEBKG_FRAME_BEVEL ) { 2886 $this->img->Bevel($x1,$y1,$x2,$h,$this->titlebackground_bevelheight); 2887 } 2888 $this->img->PopColor(); 2889 2890 // This is clumsy. But we neeed to stroke the whole graph frame if it is 2891 // set to bevel to get the bevel shading on top of the text background 2892 if( $this->framebevel && $this->doframe && $this->titlebackground_style === 3 ) { 2893 $this->img->Bevel(1,1,$this->img->width-2,$this->img->height-2, 2894 $this->framebeveldepth, 2895 $this->framebevelcolor1,$this->framebevelcolor2); 2896 if( $this->framebevelborder ) { 2897 $this->img->SetColor($this->framebevelbordercolor); 2898 $this->img->Rectangle(0,0,$this->img->width-1,$this->img->height-1); 2899 } 2900 } 2901 } 2902 2903 // Stroke title 2904 $y = $this->title->margin; 2905 if( $this->title->halign == 'center' ) { 2906 $this->title->Center(0,$this->img->width,$y); 2907 } 2908 elseif( $this->title->halign == 'left' ) { 2909 $this->title->SetPos($this->title->margin+2,$y); 2910 } 2911 elseif( $this->title->halign == 'right' ) { 2912 $indent = 0; 2913 if( $this->doshadow ) { 2914 $indent = $this->shadow_width+2; 2915 } 2916 $this->title->SetPos($this->img->width-$this->title->margin-$indent,$y,'right'); 2917 } 2918 $this->title->Stroke($this->img); 2919 2920 // ... and subtitle 2921 $y += $this->title->GetTextHeight($this->img) + $margin + $this->subtitle->margin; 2922 if( $this->subtitle->halign == 'center' ) { 2923 $this->subtitle->Center(0,$this->img->width,$y); 2924 } 2925 elseif( $this->subtitle->halign == 'left' ) { 2926 $this->subtitle->SetPos($this->subtitle->margin+2,$y); 2927 } 2928 elseif( $this->subtitle->halign == 'right' ) { 2929 $indent = 0; 2930 if( $this->doshadow ) 2931 $indent = $this->shadow_width+2; 2932 $this->subtitle->SetPos($this->img->width-$this->subtitle->margin-$indent,$y,'right'); 2933 } 2934 $this->subtitle->Stroke($this->img); 2935 2936 // ... and subsubtitle 2937 $y += $this->subtitle->GetTextHeight($this->img) + $margin + $this->subsubtitle->margin; 2938 if( $this->subsubtitle->halign == 'center' ) { 2939 $this->subsubtitle->Center(0,$this->img->width,$y); 2940 } 2941 elseif( $this->subsubtitle->halign == 'left' ) { 2942 $this->subsubtitle->SetPos($this->subsubtitle->margin+2,$y); 2943 } 2944 elseif( $this->subsubtitle->halign == 'right' ) { 2945 $indent = 0; 2946 if( $this->doshadow ) 2947 $indent = $this->shadow_width+2; 2948 $this->subsubtitle->SetPos($this->img->width-$this->subsubtitle->margin-$indent,$y,'right'); 2949 } 2950 $this->subsubtitle->Stroke($this->img); 2951 2952 // ... and fancy title 2953 $this->tabtitle->Stroke($this->img); 2700 2954 2701 2955 } 2702 2956 2703 2957 function StrokeTexts() { 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2958 // Stroke any user added text objects 2959 if( $this->texts != null ) { 2960 for($i=0; $i < count($this->texts); ++$i) { 2961 $this->texts[$i]->StrokeWithScale($this->img,$this->xscale,$this->yscale); 2962 } 2963 } 2964 2965 if( $this->y2texts != null && $this->y2scale != null ) { 2966 for($i=0; $i < count($this->y2texts); ++$i) { 2967 $this->y2texts[$i]->StrokeWithScale($this->img,$this->xscale,$this->y2scale); 2968 } 2969 } 2716 2970 2717 2971 } 2718 2972 2719 2973 function StrokeTables() { 2720 2721 2722 2723 2724 2725 2974 if( $this->iTables != null ) { 2975 $n = count($this->iTables); 2976 for( $i=0; $i < $n; ++$i ) { 2977 $this->iTables[$i]->StrokeWithScale($this->img,$this->xscale,$this->yscale); 2978 } 2979 } 2726 2980 } 2727 2981 2728 2982 function DisplayClientSideaImageMapAreas() { 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 if ($coords[1][$i]=="poly") {2740 2741 2742 2743 2744 2745 2746 } else if ($coords[1][$i]=="rect") {2747 2748 2749 2750 2751 2752 $this->img->LineTo($pts[0],$pts[1]); 2753 2754 2755 2983 // Debug stuff - display the outline of the image map areas 2984 $csim=''; 2985 foreach ($this->plots as $p) { 2986 $csim.= $p->GetCSIMareas(); 2987 } 2988 $csim .= $this->legend->GetCSIMareas(); 2989 if (preg_match_all("/area shape=\"(\w+)\" coords=\"([0-9\, ]+)\"/", $csim, $coords)) { 2990 $this->img->SetColor($this->csimcolor); 2991 $n = count($coords[0]); 2992 for ($i=0; $i < $n; $i++) { 2993 if ( $coords[1][$i] == 'poly' ) { 2994 preg_match_all('/\s*([0-9]+)\s*,\s*([0-9]+)\s*,*/',$coords[2][$i],$pts); 2995 $this->img->SetStartPoint($pts[1][count($pts[0])-1],$pts[2][count($pts[0])-1]); 2996 $m = count($pts[0]); 2997 for ($j=0; $j < $m; $j++) { 2998 $this->img->LineTo($pts[1][$j],$pts[2][$j]); 2999 } 3000 } elseif ( $coords[1][$i] == 'rect' ) { 3001 $pts = preg_split('/,/', $coords[2][$i]); 3002 $this->img->SetStartPoint($pts[0],$pts[1]); 3003 $this->img->LineTo($pts[2],$pts[1]); 3004 $this->img->LineTo($pts[2],$pts[3]); 3005 $this->img->LineTo($pts[0],$pts[3]); 3006 $this->img->LineTo($pts[0],$pts[1]); 3007 } 3008 } 3009 } 2756 3010 } 2757 3011 2758 3012 // Text scale offset in world coordinates 2759 3013 function SetTextScaleOff($aOff) { 2760 2761 3014 $this->text_scale_off = $aOff; 3015 $this->xscale->text_scale_off = $aOff; 2762 3016 } 2763 3017 2764 3018 // Text width of bar to be centered in absolute pixels 2765 3019 function SetTextScaleAbsCenterOff($aOff) { 2766 3020 $this->text_scale_abscenteroff = $aOff; 2767 3021 } 2768 3022 2769 3023 // Get Y min and max values for added lines 2770 3024 function GetLinesYMinMax( $aLines ) { 2771 $n = count($aLines);2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 3025 $n = is_array($aLines) ? count($aLines) : 0; 3026 if( $n == 0 ) return false; 3027 $min = $aLines[0]->scaleposition ; 3028 $max = $min ; 3029 $flg = false; 3030 for( $i=0; $i < $n; ++$i ) { 3031 if( $aLines[$i]->direction == HORIZONTAL ) { 3032 $flg = true ; 3033 $v = $aLines[$i]->scaleposition ; 3034 if( $min > $v ) $min = $v ; 3035 if( $max < $v ) $max = $v ; 3036 } 3037 } 3038 return $flg ? array($min,$max) : false ; 2785 3039 } 2786 3040 2787 3041 // Get X min and max values for added lines 2788 3042 function GetLinesXMinMax( $aLines ) { 2789 $n = count($aLines);2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 3043 $n = is_array($aLines) ? count($aLines) : 0; 3044 if( $n == 0 ) return false ; 3045 $min = $aLines[0]->scaleposition ; 3046 $max = $min ; 3047 $flg = false; 3048 for( $i=0; $i < $n; ++$i ) { 3049 if( $aLines[$i]->direction == VERTICAL ) { 3050 $flg = true ; 3051 $v = $aLines[$i]->scaleposition ; 3052 if( $min > $v ) $min = $v ; 3053 if( $max < $v ) $max = $v ; 3054 } 3055 } 3056 return $flg ? array($min,$max) : false ; 2803 3057 } 2804 3058 2805 3059 // Get min and max values for all included plots 2806 3060 function GetPlotsYMinMax($aPlots) { 2807 $n = count($aPlots); 2808 $i=0; 2809 do { 2810 list($xmax,$max) = $aPlots[$i]->Max(); 2811 } while( ++$i < $n && !is_numeric($max) ); 2812 2813 $i=0; 2814 do { 2815 list($xmin,$min) = $aPlots[$i]->Min(); 2816 } while( ++$i < $n && !is_numeric($min) ); 2817 2818 if( !is_numeric($min) || !is_numeric($max) ) { 2819 JpGraphError::RaiseL(25044);//('Cannot use autoscaling since it is impossible to determine a valid min/max value of the Y-axis (only null values).'); 2820 } 2821 2822 for($i=0; $i < $n; ++$i ) { 2823 list($xmax,$ymax)=$aPlots[$i]->Max(); 2824 list($xmin,$ymin)=$aPlots[$i]->Min(); 2825 if (is_numeric($ymax)) $max=max($max,$ymax); 2826 if (is_numeric($ymin)) $min=min($min,$ymin); 2827 } 2828 if( $min == '' ) $min = 0; 2829 if( $max == '' ) $max = 0; 2830 if( $min == 0 && $max == 0 ) { 2831 // Special case if all values are 0 2832 $min=0;$max=1; 2833 } 2834 return array($min,$max); 3061 $n = count($aPlots); 3062 $i=0; 3063 do { 3064 list($xmax,$max) = $aPlots[$i]->Max(); 3065 } while( ++$i < $n && !is_numeric($max) ); 3066 3067 $i=0; 3068 do { 3069 list($xmin,$min) = $aPlots[$i]->Min(); 3070 } while( ++$i < $n && !is_numeric($min) ); 3071 3072 if( !is_numeric($min) || !is_numeric($max) ) { 3073 JpGraphError::RaiseL(25044);//('Cannot use autoscaling since it is impossible to determine a valid min/max value of the Y-axis (only null values).'); 3074 } 3075 3076 for($i=0; $i < $n; ++$i ) { 3077 list($xmax,$ymax)=$aPlots[$i]->Max(); 3078 list($xmin,$ymin)=$aPlots[$i]->Min(); 3079 if (is_numeric($ymax)) $max=max($max,$ymax); 3080 if (is_numeric($ymin)) $min=min($min,$ymin); 3081 } 3082 if( $min == '' ) $min = 0; 3083 if( $max == '' ) $max = 0; 3084 if( $min == 0 && $max == 0 ) { 3085 // Special case if all values are 0 3086 $min=0;$max=1; 3087 } 3088 return array($min,$max); 3089 } 3090 3091 function hasLinePlotAndBarPlot() { 3092 $has_line = false; 3093 $has_bar = false; 3094 3095 foreach ($this->plots as $plot) { 3096 if ($plot instanceof LinePlot) { 3097 $has_line = true; 3098 } 3099 if ($plot instanceof BarPlot) { 3100 $has_bar = true; 3101 } 3102 } 3103 3104 if ($has_line && $has_bar) { 3105 return true; 3106 } 3107 3108 return false; 3109 } 3110 3111 function SetTheme($graph_theme) { 3112 3113 if (!($this instanceof PieGraph)) { 3114 if (!$this->isAfterSetScale) { 3115 JpGraphError::RaiseL(25133);//('Use Graph::SetTheme() after Graph::SetScale().'); 3116 } 3117 } 3118 3119 if ($this->graph_theme) { 3120 $this->ClearTheme(); 3121 } 3122 $this->graph_theme = $graph_theme; 3123 $this->graph_theme->ApplyGraph($this); 3124 } 3125 3126 function ClearTheme() { 3127 $this->graph_theme = null; 3128 3129 $this->isRunningClear = true; 3130 3131 $this->__construct( 3132 $this->inputValues['aWidth'], 3133 $this->inputValues['aHeight'], 3134 $this->inputValues['aCachedName'], 3135 $this->inputValues['aTimeout'], 3136 $this->inputValues['aInline'] 3137 ); 3138 3139 if (!($this instanceof PieGraph)) { 3140 if ($this->isAfterSetScale) { 3141 $this->SetScale( 3142 $this->inputValues['aAxisType'], 3143 $this->inputValues['aYMin'], 3144 $this->inputValues['aYMax'], 3145 $this->inputValues['aXMin'], 3146 $this->inputValues['aXMax'] 3147 ); 3148 } 3149 } 3150 3151 $this->isRunningClear = false; 3152 } 3153 3154 function SetSupersampling($do = false, $scale = 2) { 3155 if ($do) { 3156 define('SUPERSAMPLING_SCALE', $scale); 3157 // $this->img->scale = $scale; 3158 } else { 3159 define('SUPERSAMPLING_SCALE', 1); 3160 //$this->img->scale = 0; 3161 } 2835 3162 } 2836 3163 … … 2842 3169 //=================================================== 2843 3170 class LineProperty { 2844 public $iWeight=1, $iColor="black",$iStyle="solid",$iShow=true; 2845 2846 //--------------- 2847 // PUBLIC METHODS 3171 public $iWeight=1, $iColor='black', $iStyle='solid', $iShow=false; 3172 3173 function __construct($aWeight=1,$aColor='black',$aStyle='solid') { 3174 $this->iWeight = $aWeight; 3175 $this->iColor = $aColor; 3176 $this->iStyle = $aStyle; 3177 } 3178 2848 3179 function SetColor($aColor) { 2849 2850 } 2851 3180 $this->iColor = $aColor; 3181 } 3182 2852 3183 function SetWeight($aWeight) { 2853 2854 } 2855 3184 $this->iWeight = $aWeight; 3185 } 3186 2856 3187 function SetStyle($aStyle) { 2857 2858 } 2859 3188 $this->iStyle = $aStyle; 3189 } 3190 2860 3191 function Show($aShow=true) { 2861 2862 } 2863 3192 $this->iShow=$aShow; 3193 } 3194 2864 3195 function Stroke($aImg,$aX1,$aY1,$aX2,$aY2) { 2865 2866 2867 2868 2869 2870 $aImg->SetLineStyle($this->iStyle); 2871 2872 2873 2874 2875 2876 3196 if( $this->iShow ) { 3197 $aImg->PushColor($this->iColor); 3198 $oldls = $aImg->line_style; 3199 $oldlw = $aImg->line_weight; 3200 $aImg->SetLineWeight($this->iWeight); 3201 $aImg->SetLineStyle($this->iStyle); 3202 $aImg->StyleLine($aX1,$aY1,$aX2,$aY2); 3203 $aImg->PopColor($this->iColor); 3204 $aImg->line_style = $oldls; 3205 $aImg->line_weight = $oldlw; 3206 3207 } 2877 3208 } 2878 3209 } 2879 3210 3211 //=================================================== 3212 // CLASS GraphTabTitle 3213 // Description: Draw "tab" titles on top of graphs 3214 //=================================================== 2880 3215 class GraphTabTitle extends Text{ 2881 3216 private $corner = 6 , $posx = 7, $posy = 4; 2882 3217 private $fillcolor='lightyellow',$bordercolor='black'; 2883 3218 private $align = 'left', $width=TABTITLE_WIDTHFIT; 2884 function GraphTabTitle() {2885 2886 2887 2888 3219 function __construct() { 3220 $this->t = ''; 3221 $this->font_style = FS_BOLD; 3222 $this->hide = true; 3223 $this->color = 'darkred'; 2889 3224 } 2890 3225 2891 3226 function SetColor($aTxtColor,$aFillColor='lightyellow',$aBorderColor='black') { 2892 2893 2894 3227 $this->color = $aTxtColor; 3228 $this->fillcolor = $aFillColor; 3229 $this->bordercolor = $aBorderColor; 2895 3230 } 2896 3231 2897 3232 function SetFillColor($aFillColor) { 2898 3233 $this->fillcolor = $aFillColor; 2899 3234 } 2900 3235 2901 3236 function SetTabAlign($aAlign) { 2902 2903 } 2904 3237 $this->align = $aAlign; 3238 } 3239 2905 3240 function SetWidth($aWidth) { 2906 3241 $this->width = $aWidth ; 2907 3242 } 2908 3243 2909 3244 function Set($t) { 2910 2911 3245 $this->t = $t; 3246 $this->hide = false; 2912 3247 } 2913 3248 2914 3249 function SetCorner($aD) { 2915 3250 $this->corner = $aD ; 2916 3251 } 2917 3252 2918 3253 function Stroke($aImg,$aDummy1=null,$aDummy2=null) { 2919 if( $this->hide ) 2920 return; 2921 $this->boxed = false; 2922 $w = $this->GetWidth($aImg) + 2*$this->posx; 2923 $h = $this->GetTextHeight($aImg) + 2*$this->posy; 2924 2925 $x = $aImg->left_margin; 2926 $y = $aImg->top_margin; 2927 2928 if( $this->width === TABTITLE_WIDTHFIT ) { 2929 if( $this->align == 'left' ) { 2930 $p = array($x, $y, 2931 $x, $y-$h+$this->corner, 2932 $x + $this->corner,$y-$h, 2933 $x + $w - $this->corner, $y-$h, 2934 $x + $w, $y-$h+$this->corner, 2935 $x + $w, $y); 2936 } 2937 elseif( $this->align == 'center' ) { 2938 $x += round($aImg->plotwidth/2) - round($w/2); 2939 $p = array($x, $y, 2940 $x, $y-$h+$this->corner, 2941 $x + $this->corner, $y-$h, 2942 $x + $w - $this->corner, $y-$h, 2943 $x + $w, $y-$h+$this->corner, 2944 $x + $w, $y); 2945 } 2946 else { 2947 $x += $aImg->plotwidth -$w; 2948 $p = array($x, $y, 2949 $x, $y-$h+$this->corner, 2950 $x + $this->corner,$y-$h, 2951 $x + $w - $this->corner, $y-$h, 2952 $x + $w, $y-$h+$this->corner, 2953 $x + $w, $y); 2954 } 2955 } 2956 else { 2957 if( $this->width === TABTITLE_WIDTHFULL ) 2958 $w = $aImg->plotwidth ; 2959 else 2960 $w = $this->width ; 2961 2962 // Make the tab fit the width of the plot area 2963 $p = array($x, $y, 2964 $x, $y-$h+$this->corner, 2965 $x + $this->corner,$y-$h, 2966 $x + $w - $this->corner, $y-$h, 2967 $x + $w, $y-$h+$this->corner, 2968 $x + $w, $y); 2969 2970 } 2971 if( $this->halign == 'left' ) { 2972 $aImg->SetTextAlign('left','bottom'); 2973 $x += $this->posx; 2974 $y -= $this->posy; 2975 } 2976 elseif( $this->halign == 'center' ) { 2977 $aImg->SetTextAlign('center','bottom'); 2978 $x += $w/2; 2979 $y -= $this->posy; 2980 } 2981 else { 2982 $aImg->SetTextAlign('right','bottom'); 2983 $x += $w - $this->posx; 2984 $y -= $this->posy; 2985 } 2986 2987 $aImg->SetColor($this->fillcolor); 2988 $aImg->FilledPolygon($p); 2989 2990 $aImg->SetColor($this->bordercolor); 2991 $aImg->Polygon($p,true); 2992 2993 $aImg->SetColor($this->color); 2994 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 2995 $aImg->StrokeText($x,$y,$this->t,0,'center'); 3254 if( $this->hide ) 3255 return; 3256 $this->boxed = false; 3257 $w = $this->GetWidth($aImg) + 2*$this->posx; 3258 $h = $this->GetTextHeight($aImg) + 2*$this->posy; 3259 3260 $x = $aImg->left_margin; 3261 $y = $aImg->top_margin; 3262 3263 if( $this->width === TABTITLE_WIDTHFIT ) { 3264 if( $this->align == 'left' ) { 3265 $p = array($x, $y, 3266 $x, $y-$h+$this->corner, 3267 $x + $this->corner,$y-$h, 3268 $x + $w - $this->corner, $y-$h, 3269 $x + $w, $y-$h+$this->corner, 3270 $x + $w, $y); 3271 } 3272 elseif( $this->align == 'center' ) { 3273 $x += round($aImg->plotwidth/2) - round($w/2); 3274 $p = array($x, $y, 3275 $x, $y-$h+$this->corner, 3276 $x + $this->corner, $y-$h, 3277 $x + $w - $this->corner, $y-$h, 3278 $x + $w, $y-$h+$this->corner, 3279 $x + $w, $y); 3280 } 3281 else { 3282 $x += $aImg->plotwidth -$w; 3283 $p = array($x, $y, 3284 $x, $y-$h+$this->corner, 3285 $x + $this->corner,$y-$h, 3286 $x + $w - $this->corner, $y-$h, 3287 $x + $w, $y-$h+$this->corner, 3288 $x + $w, $y); 3289 } 3290 } 3291 else { 3292 if( $this->width === TABTITLE_WIDTHFULL ) { 3293 $w = $aImg->plotwidth ; 3294 } 3295 else { 3296 $w = $this->width ; 3297 } 3298 3299 // Make the tab fit the width of the plot area 3300 $p = array($x, $y, 3301 $x, $y-$h+$this->corner, 3302 $x + $this->corner,$y-$h, 3303 $x + $w - $this->corner, $y-$h, 3304 $x + $w, $y-$h+$this->corner, 3305 $x + $w, $y); 3306 3307 } 3308 if( $this->halign == 'left' ) { 3309 $aImg->SetTextAlign('left','bottom'); 3310 $x += $this->posx; 3311 $y -= $this->posy; 3312 } 3313 elseif( $this->halign == 'center' ) { 3314 $aImg->SetTextAlign('center','bottom'); 3315 $x += $w/2; 3316 $y -= $this->posy; 3317 } 3318 else { 3319 $aImg->SetTextAlign('right','bottom'); 3320 $x += $w - $this->posx; 3321 $y -= $this->posy; 3322 } 3323 3324 $aImg->SetColor($this->fillcolor); 3325 $aImg->FilledPolygon($p); 3326 3327 $aImg->SetColor($this->bordercolor); 3328 $aImg->Polygon($p,true); 3329 3330 $aImg->SetColor($this->color); 3331 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 3332 $aImg->StrokeText($x,$y,$this->t,0,'center'); 2996 3333 } 2997 3334 … … 3003 3340 //=================================================== 3004 3341 class SuperScriptText extends Text { 3005 private $iSuper= "";3006 private $sfont_family= "",$sfont_style="",$sfont_size=8;3342 private $iSuper=''; 3343 private $sfont_family='',$sfont_style='',$sfont_size=8; 3007 3344 private $iSuperMargin=2,$iVertOverlap=4,$iSuperScale=0.65; 3008 3345 private $iSDir=0; 3009 3346 private $iSimple=false; 3010 3347 3011 function SuperScriptText($aTxt="",$aSuper="",$aXAbsPos=0,$aYAbsPos=0) {3012 parent::Text($aTxt,$aXAbsPos,$aYAbsPos);3013 3348 function __construct($aTxt='',$aSuper='',$aXAbsPos=0,$aYAbsPos=0) { 3349 parent::__construct($aTxt,$aXAbsPos,$aYAbsPos); 3350 $this->iSuper = $aSuper; 3014 3351 } 3015 3352 3016 3353 function FromReal($aVal,$aPrecision=2) { 3017 // Convert a floating point number to scientific notation 3018 $neg=1.0; 3019 if( $aVal < 0 ) { 3020 $neg = -1.0; 3021 $aVal = -$aVal; 3022 } 3023 3024 $l = floor(log10($aVal)); 3025 $a = sprintf("%0.".$aPrecision."f",round($aVal / pow(10,$l),$aPrecision)); 3026 $a *= $neg; 3027 if( $this->iSimple && ($a == 1 || $a==-1) ) $a = ''; 3028 3029 if( $a != '' ) 3030 $this->t = $a.' * 10'; 3031 else { 3032 if( $neg == 1 ) 3033 $this->t = '10'; 3034 else 3035 $this->t = '-10'; 3036 } 3037 $this->iSuper = $l; 3038 } 3039 3040 function Set($aTxt,$aSuper="") { 3041 $this->t = $aTxt; 3042 $this->iSuper = $aSuper; 3354 // Convert a floating point number to scientific notation 3355 $neg=1.0; 3356 if( $aVal < 0 ) { 3357 $neg = -1.0; 3358 $aVal = -$aVal; 3359 } 3360 3361 $l = floor(log10($aVal)); 3362 $a = sprintf("%0.".$aPrecision."f",round($aVal / pow(10,$l),$aPrecision)); 3363 $a *= $neg; 3364 if( $this->iSimple && ($a == 1 || $a==-1) ) $a = ''; 3365 3366 if( $a != '' ) { 3367 $this->t = $a.' * 10'; 3368 } 3369 else { 3370 if( $neg == 1 ) { 3371 $this->t = '10'; 3372 } 3373 else { 3374 $this->t = '-10'; 3375 } 3376 } 3377 $this->iSuper = $l; 3378 } 3379 3380 function Set($aTxt,$aSuper='') { 3381 $this->t = $aTxt; 3382 $this->iSuper = $aSuper; 3043 3383 } 3044 3384 3045 3385 function SetSuperFont($aFontFam,$aFontStyle=FS_NORMAL,$aFontSize=8) { 3046 3047 3048 3386 $this->sfont_family = $aFontFam; 3387 $this->sfont_style = $aFontStyle; 3388 $this->sfont_size = $aFontSize; 3049 3389 } 3050 3390 3051 3391 // Total width of text 3052 3392 function GetWidth($aImg) { 3053 3054 3055 3056 3057 3058 3059 } 3060 3393 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 3394 $w = $aImg->GetTextWidth($this->t); 3395 $aImg->SetFont($this->sfont_family,$this->sfont_style,$this->sfont_size); 3396 $w += $aImg->GetTextWidth($this->iSuper); 3397 $w += $this->iSuperMargin; 3398 return $w; 3399 } 3400 3061 3401 // Hight of font (approximate the height of the text) 3062 3402 function GetFontHeight($aImg) { 3063 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 3064 3065 3066 3067 3403 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 3404 $h = $aImg->GetFontHeight(); 3405 $aImg->SetFont($this->sfont_family,$this->sfont_style,$this->sfont_size); 3406 $h += $aImg->GetFontHeight(); 3407 return $h; 3068 3408 } 3069 3409 3070 3410 // Hight of text 3071 3411 function GetTextHeight($aImg) { 3072 3073 3074 3075 3076 3412 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 3413 $h = $aImg->GetTextHeight($this->t); 3414 $aImg->SetFont($this->sfont_family,$this->sfont_style,$this->sfont_size); 3415 $h += $aImg->GetTextHeight($this->iSuper); 3416 return $h; 3077 3417 } 3078 3418 3079 3419 function Stroke($aImg,$ax=-1,$ay=-1) { 3080 3420 3081 3421 // To position the super script correctly we need different 3082 // cases to handle the alignmewnt specified since that will 3083 // determine how we can interpret the x,y coordinates 3084 3085 $w = parent::GetWidth($aImg); 3086 $h = parent::GetTextHeight($aImg); 3087 switch( $this->valign ) { 3088 case 'top': 3089 $sy = $this->y; 3090 break; 3091 case 'center': 3092 $sy = $this->y - $h/2; 3093 break; 3094 case 'bottom': 3095 $sy = $this->y - $h; 3096 break; 3097 default: 3098 JpGraphError::RaiseL(25052);//('PANIC: Internal error in SuperScript::Stroke(). Unknown vertical alignment for text'); 3099 break; 3100 } 3101 3102 switch( $this->halign ) { 3103 case 'left': 3104 $sx = $this->x + $w; 3105 break; 3106 case 'center': 3107 $sx = $this->x + $w/2; 3108 break; 3109 case 'right': 3110 $sx = $this->x; 3111 break; 3112 default: 3113 JpGraphError::RaiseL(25053);//('PANIC: Internal error in SuperScript::Stroke(). Unknown horizontal alignment for text'); 3114 break; 3115 } 3116 3117 $sx += $this->iSuperMargin; 3118 $sy += $this->iVertOverlap; 3119 3120 // Should we automatically determine the font or 3121 // has the user specified it explicetly? 3122 if( $this->sfont_family == "" ) { 3123 if( $this->font_family <= FF_FONT2 ) { 3124 if( $this->font_family == FF_FONT0 ) { 3125 $sff = FF_FONT0; 3126 } 3127 elseif( $this->font_family == FF_FONT1 ) { 3128 if( $this->font_style == FS_NORMAL ) 3129 $sff = FF_FONT0; 3130 else 3131 $sff = FF_FONT1; 3132 } 3133 else { 3134 $sff = FF_FONT1; 3135 } 3136 $sfs = $this->font_style; 3137 $sfz = $this->font_size; 3138 } 3139 else { 3140 // TTF fonts 3141 $sff = $this->font_family; 3142 $sfs = $this->font_style; 3143 $sfz = floor($this->font_size*$this->iSuperScale); 3144 if( $sfz < 8 ) $sfz = 8; 3145 } 3146 $this->sfont_family = $sff; 3147 $this->sfont_style = $sfs; 3148 $this->sfont_size = $sfz; 3149 } 3150 else { 3151 $sff = $this->sfont_family; 3152 $sfs = $this->sfont_style; 3153 $sfz = $this->sfont_size; 3154 } 3155 3156 parent::Stroke($aImg,$ax,$ay); 3157 3158 3159 // For the builtin fonts we need to reduce the margins 3160 // since the bounding bx reported for the builtin fonts 3161 // are much larger than for the TTF fonts. 3162 if( $sff <= FF_FONT2 ) { 3163 $sx -= 2; 3164 $sy += 3; 3165 } 3166 3167 $aImg->SetTextAlign('left','bottom'); 3168 $aImg->SetFont($sff,$sfs,$sfz); 3169 $aImg->PushColor($this->color); 3170 $aImg->StrokeText($sx,$sy,$this->iSuper,$this->iSDir,'left'); 3171 $aImg->PopColor(); 3422 // cases to handle the alignmewnt specified since that will 3423 // determine how we can interpret the x,y coordinates 3424 3425 $w = parent::GetWidth($aImg); 3426 $h = parent::GetTextHeight($aImg); 3427 switch( $this->valign ) { 3428 case 'top': 3429 $sy = $this->y; 3430 break; 3431 case 'center': 3432 $sy = $this->y - $h/2; 3433 break; 3434 case 'bottom': 3435 $sy = $this->y - $h; 3436 break; 3437 default: 3438 JpGraphError::RaiseL(25052);//('PANIC: Internal error in SuperScript::Stroke(). Unknown vertical alignment for text'); 3439 break; 3440 } 3441 3442 switch( $this->halign ) { 3443 case 'left': 3444 $sx = $this->x + $w; 3445 break; 3446 case 'center': 3447 $sx = $this->x + $w/2; 3448 break; 3449 case 'right': 3450 $sx = $this->x; 3451 break; 3452 default: 3453 JpGraphError::RaiseL(25053);//('PANIC: Internal error in SuperScript::Stroke(). Unknown horizontal alignment for text'); 3454 break; 3455 } 3456 3457 $sx += $this->iSuperMargin; 3458 $sy += $this->iVertOverlap; 3459 3460 // Should we automatically determine the font or 3461 // has the user specified it explicetly? 3462 if( $this->sfont_family == '' ) { 3463 if( $this->font_family <= FF_FONT2 ) { 3464 if( $this->font_family == FF_FONT0 ) { 3465 $sff = FF_FONT0; 3466 } 3467 elseif( $this->font_family == FF_FONT1 ) { 3468 if( $this->font_style == FS_NORMAL ) { 3469 $sff = FF_FONT0; 3470 } 3471 else { 3472 $sff = FF_FONT1; 3473 } 3474 } 3475 else { 3476 $sff = FF_FONT1; 3477 } 3478 $sfs = $this->font_style; 3479 $sfz = $this->font_size; 3480 } 3481 else { 3482 // TTF fonts 3483 $sff = $this->font_family; 3484 $sfs = $this->font_style; 3485 $sfz = floor($this->font_size*$this->iSuperScale); 3486 if( $sfz < 8 ) $sfz = 8; 3487 } 3488 $this->sfont_family = $sff; 3489 $this->sfont_style = $sfs; 3490 $this->sfont_size = $sfz; 3491 } 3492 else { 3493 $sff = $this->sfont_family; 3494 $sfs = $this->sfont_style; 3495 $sfz = $this->sfont_size; 3496 } 3497 3498 parent::Stroke($aImg,$ax,$ay); 3499 3500 // For the builtin fonts we need to reduce the margins 3501 // since the bounding bx reported for the builtin fonts 3502 // are much larger than for the TTF fonts. 3503 if( $sff <= FF_FONT2 ) { 3504 $sx -= 2; 3505 $sy += 3; 3506 } 3507 3508 $aImg->SetTextAlign('left','bottom'); 3509 $aImg->SetFont($sff,$sfs,$sfz); 3510 $aImg->PushColor($this->color); 3511 $aImg->StrokeText($sx,$sy,$this->iSuper,$this->iSDir,'left'); 3512 $aImg->PopColor(); 3172 3513 } 3173 3514 } … … 3181 3522 protected $img; 3182 3523 protected $scale; 3183 protected $ grid_color='#DDDDDD',$grid_mincolor='#DDDDDD';3184 protected $ type="solid";3185 protected $show=false, $showMinor=false,$ weight=1;3524 protected $majorcolor='#CCCCCC',$minorcolor='#DDDDDD'; 3525 protected $majortype='solid',$minortype='solid'; 3526 protected $show=false, $showMinor=false,$majorweight=1,$minorweight=1; 3186 3527 protected $fill=false,$fillcolor=array('#EFEFEF','#BBCCFF'); 3187 //--------------- 3188 // CONSTRUCTOR 3189 function Grid($aAxis) { 3190 $this->scale = $aAxis->scale; 3191 $this->img = $aAxis->img; 3192 } 3193 //--------------- 3194 // PUBLIC METHODS 3528 3529 function __construct($aAxis) { 3530 $this->scale = $aAxis->scale; 3531 $this->img = $aAxis->img; 3532 } 3533 3195 3534 function SetColor($aMajColor,$aMinColor=false) { 3196 $this->grid_color=$aMajColor; 3197 if( $aMinColor === false ) 3198 $aMinColor = $aMajColor ; 3199 $this->grid_mincolor = $aMinColor; 3200 } 3201 3202 function SetWeight($aWeight) { 3203 $this->weight=$aWeight; 3204 } 3205 3535 $this->majorcolor=$aMajColor; 3536 if( $aMinColor === false ) { 3537 $aMinColor = $aMajColor ; 3538 } 3539 $this->minorcolor = $aMinColor; 3540 } 3541 3542 function SetWeight($aMajorWeight,$aMinorWeight=1) { 3543 $this->majorweight=$aMajorWeight; 3544 $this->minorweight=$aMinorWeight; 3545 } 3546 3206 3547 // Specify if grid should be dashed, dotted or solid 3207 function SetLineStyle($aType) { 3208 $this->type = $aType; 3209 } 3210 3548 function SetLineStyle($aMajorType,$aMinorType='solid') { 3549 $this->majortype = $aMajorType; 3550 $this->minortype = $aMinorType; 3551 } 3552 3553 function SetStyle($aMajorType,$aMinorType='solid') { 3554 $this->SetLineStyle($aMajorType,$aMinorType); 3555 } 3556 3211 3557 // Decide if both major and minor grid should be displayed 3212 3558 function Show($aShowMajor=true,$aShowMinor=false) { 3213 3214 3215 } 3216 3559 $this->show=$aShowMajor; 3560 $this->showMinor=$aShowMinor; 3561 } 3562 3217 3563 function SetFill($aFlg=true,$aColor1='lightgray',$aColor2='lightblue') { 3218 3219 3220 } 3221 3564 $this->fill = $aFlg; 3565 $this->fillcolor = array( $aColor1, $aColor2 ); 3566 } 3567 3222 3568 // Display the grid 3223 3569 function Stroke() { 3224 if( $this->showMinor && !$this->scale->textscale ) { 3225 $tmp = $this->grid_color; 3226 $this->grid_color = $this->grid_mincolor; 3227 $this->DoStroke($this->scale->ticks->ticks_pos); 3228 3229 $this->grid_color = $tmp; 3230 $this->DoStroke($this->scale->ticks->maj_ticks_pos); 3231 } 3232 else { 3233 $this->DoStroke($this->scale->ticks->maj_ticks_pos); 3234 } 3235 } 3236 3237 //-------------- 3238 // Private methods 3570 if( $this->showMinor && !$this->scale->textscale ) { 3571 $this->DoStroke($this->scale->ticks->ticks_pos,$this->minortype,$this->minorcolor,$this->minorweight); 3572 $this->DoStroke($this->scale->ticks->maj_ticks_pos,$this->majortype,$this->majorcolor,$this->majorweight); 3573 } 3574 else { 3575 $this->DoStroke($this->scale->ticks->maj_ticks_pos,$this->majortype,$this->majorcolor,$this->majorweight); 3576 } 3577 } 3578 3579 //-------------- 3580 // Private methods 3239 3581 // Draw the grid 3240 function DoStroke($aTicksPos) { 3241 if( !$this->show ) 3242 return; 3243 $nbrgrids = count($aTicksPos); 3244 3245 if( $this->scale->type=="y" ) { 3246 $xl=$this->img->left_margin; 3247 $xr=$this->img->width-$this->img->right_margin; 3248 3249 if( $this->fill ) { 3250 // Draw filled areas 3251 $y2 = $aTicksPos[0]; 3252 $i=1; 3253 while( $i < $nbrgrids ) { 3254 $y1 = $y2; 3255 $y2 = $aTicksPos[$i++]; 3256 $this->img->SetColor($this->fillcolor[$i & 1]); 3257 $this->img->FilledRectangle($xl,$y1,$xr,$y2); 3258 } 3259 } 3260 3261 $this->img->SetColor($this->grid_color); 3262 $this->img->SetLineWeight($this->weight); 3263 3264 // Draw grid lines 3265 switch( $this->type ) { 3266 case "solid": $style = LINESTYLE_SOLID; break; 3267 case "dotted": $style = LINESTYLE_DOTTED; break; 3268 case "dashed": $style = LINESTYLE_DASHED; break; 3269 case "longdashed": $style = LINESTYLE_LONGDASH; break; 3270 default: 3271 $style = LINESTYLE_SOLID; break; 3272 } 3273 3274 for($i=0; $i < $nbrgrids; ++$i) { 3275 $y=$aTicksPos[$i]; 3276 $this->img->StyleLine($xl,$y,$xr,$y,$style); 3277 } 3278 } 3279 elseif( $this->scale->type=="x" ) { 3280 $yu=$this->img->top_margin; 3281 $yl=$this->img->height-$this->img->bottom_margin; 3282 $limit=$this->img->width-$this->img->right_margin; 3283 3284 if( $this->fill ) { 3285 // Draw filled areas 3286 $x2 = $aTicksPos[0]; 3287 $i=1; 3288 while( $i < $nbrgrids ) { 3289 $x1 = $x2; 3290 $x2 = min($aTicksPos[$i++],$limit) ; 3291 $this->img->SetColor($this->fillcolor[$i & 1]); 3292 $this->img->FilledRectangle($x1,$yu,$x2,$yl); 3293 } 3294 } 3295 3296 $this->img->SetColor($this->grid_color); 3297 $this->img->SetLineWeight($this->weight); 3298 3299 // We must also test for limit since we might have 3300 // an offset and the number of ticks is calculated with 3301 // assumption offset==0 so we might end up drawing one 3302 // to many gridlines 3303 $i=0; 3304 $x=$aTicksPos[$i]; 3305 while( $i<count($aTicksPos) && ($x=$aTicksPos[$i]) <= $limit ) { 3306 if( $this->type == "solid" ) 3307 $this->img->Line($x,$yl,$x,$yu); 3308 elseif( $this->type == "dotted" ) 3309 $this->img->DashedLine($x,$yl,$x,$yu,1,6); 3310 elseif( $this->type == "dashed" ) 3311 $this->img->DashedLine($x,$yl,$x,$yu,2,4); 3312 elseif( $this->type == "longdashed" ) 3313 $this->img->DashedLine($x,$yl,$x,$yu,8,6); 3314 ++$i; 3315 } 3316 } 3317 else { 3318 JpGraphError::RaiseL(25054,$this->scale->type);//('Internal error: Unknown grid axis ['.$this->scale->type.']'); 3319 } 3320 return true; 3582 function DoStroke($aTicksPos,$aType,$aColor,$aWeight) { 3583 if( !$this->show ) return; 3584 $nbrgrids = count($aTicksPos); 3585 3586 if( $this->scale->type == 'y' ) { 3587 $xl=$this->img->left_margin; 3588 $xr=$this->img->width-$this->img->right_margin; 3589 3590 if( $this->fill ) { 3591 // Draw filled areas 3592 $y2 = !empty($aTicksPos) ? $aTicksPos[0] : null; 3593 $i=1; 3594 while( $i < $nbrgrids ) { 3595 $y1 = $y2; 3596 $y2 = $aTicksPos[$i++]; 3597 $this->img->SetColor($this->fillcolor[$i & 1]); 3598 $this->img->FilledRectangle($xl,$y1,$xr,$y2); 3599 } 3600 } 3601 3602 $this->img->SetColor($aColor); 3603 $this->img->SetLineWeight($aWeight); 3604 3605 // Draw grid lines 3606 switch( $aType ) { 3607 case 'solid': $style = LINESTYLE_SOLID; break; 3608 case 'dotted': $style = LINESTYLE_DOTTED; break; 3609 case 'dashed': $style = LINESTYLE_DASHED; break; 3610 case 'longdashed': $style = LINESTYLE_LONGDASH; break; 3611 default: 3612 $style = LINESTYLE_SOLID; break; 3613 } 3614 3615 for($i=0; $i < $nbrgrids; ++$i) { 3616 $y=$aTicksPos[$i]; 3617 $this->img->StyleLine($xl,$y,$xr,$y,$style,true); 3618 } 3619 } 3620 elseif( $this->scale->type == 'x' ) { 3621 $yu=$this->img->top_margin; 3622 $yl=$this->img->height-$this->img->bottom_margin; 3623 $limit=$this->img->width-$this->img->right_margin; 3624 3625 if( $this->fill ) { 3626 // Draw filled areas 3627 $x2 = $aTicksPos[0]; 3628 $i=1; 3629 while( $i < $nbrgrids ) { 3630 $x1 = $x2; 3631 $x2 = min($aTicksPos[$i++],$limit) ; 3632 $this->img->SetColor($this->fillcolor[$i & 1]); 3633 $this->img->FilledRectangle($x1,$yu,$x2,$yl); 3634 } 3635 } 3636 3637 $this->img->SetColor($aColor); 3638 $this->img->SetLineWeight($aWeight); 3639 3640 // We must also test for limit since we might have 3641 // an offset and the number of ticks is calculated with 3642 // assumption offset==0 so we might end up drawing one 3643 // to many gridlines 3644 $i=0; 3645 $x=$aTicksPos[$i]; 3646 while( $i<count($aTicksPos) && ($x=$aTicksPos[$i]) <= $limit ) { 3647 if ( $aType == 'solid' ) $this->img->Line($x,$yl,$x,$yu); 3648 elseif( $aType == 'dotted' ) $this->img->DashedLineForGrid($x,$yl,$x,$yu,1,6); 3649 elseif( $aType == 'dashed' ) $this->img->DashedLineForGrid($x,$yl,$x,$yu,2,4); 3650 elseif( $aType == 'longdashed' ) $this->img->DashedLineForGrid($x,$yl,$x,$yu,8,6); 3651 ++$i; 3652 } 3653 } 3654 else { 3655 JpGraphError::RaiseL(25054,$this->scale->type);//('Internal error: Unknown grid axis ['.$this->scale->type.']'); 3656 } 3657 return true; 3321 3658 } 3322 3659 } // Class … … 3328 3665 // several occasion must know wheter it's an X or Y axis. 3329 3666 // This was a design decision to make the code easier to 3330 // follow. 3667 // follow. 3331 3668 //=================================================== 3332 3669 class AxisPrototype { 3333 public $scale=null; 3670 public $scale=null; 3334 3671 public $img=null; 3335 3672 public $hide=false,$hide_labels=false; 3336 3673 public $title=null; 3337 public $font_family=FF_ FONT1,$font_style=FS_NORMAL,$font_size=12,$label_angle=0;3674 public $font_family=FF_DEFAULT,$font_style=FS_NORMAL,$font_size=8,$label_angle=0; 3338 3675 public $tick_step=1; 3339 3676 public $pos = false; … … 3348 3685 protected $labelPos=0; // Which side of the axis should the labels be? 3349 3686 protected $title_adjust,$title_margin,$title_side=SIDE_LEFT; 3350 protected $tick_label_margin= 7;3687 protected $tick_label_margin=5; 3351 3688 protected $label_halign = '',$label_valign = '', $label_para_align='left'; 3352 3689 protected $hide_line=false; 3353 3690 protected $iDeltaAbsPos=0; 3354 3691 3355 //--------------- 3356 // CONSTRUCTOR 3357 function Axis($img,$aScale,$color=array(0,0,0)) { 3358 $this->img = $img; 3359 $this->scale = $aScale; 3360 $this->color = $color; 3361 $this->title=new Text(""); 3362 3363 if( $aScale->type=="y" ) { 3364 $this->title_margin = 25; 3365 $this->title_adjust="middle"; 3366 $this->title->SetOrientation(90); 3367 $this->tick_label_margin=7; 3368 $this->labelPos=SIDE_LEFT; 3369 } 3370 else { 3371 $this->title_margin = 5; 3372 $this->title_adjust="high"; 3373 $this->title->SetOrientation(0); 3374 $this->tick_label_margin=7; 3375 $this->labelPos=SIDE_DOWN; 3376 $this->title_side=SIDE_DOWN; 3377 } 3378 } 3379 //--------------- 3380 // PUBLIC METHODS 3381 3692 function __construct($img,$aScale,$color = array(0,0,0)) { 3693 $this->img = $img; 3694 $this->scale = $aScale; 3695 $this->color = $color; 3696 $this->title=new Text(''); 3697 3698 if( $aScale->type == 'y' ) { 3699 $this->title_margin = 25; 3700 $this->title_adjust = 'middle'; 3701 $this->title->SetOrientation(90); 3702 $this->tick_label_margin=7; 3703 $this->labelPos=SIDE_LEFT; 3704 } 3705 else { 3706 $this->title_margin = 5; 3707 $this->title_adjust = 'high'; 3708 $this->title->SetOrientation(0); 3709 $this->tick_label_margin=5; 3710 $this->labelPos=SIDE_DOWN; 3711 $this->title_side=SIDE_DOWN; 3712 } 3713 } 3714 3382 3715 function SetLabelFormat($aFormStr) { 3383 3716 $this->scale->ticks->SetLabelFormat($aFormStr); 3384 3717 } 3385 3718 3386 3719 function SetLabelFormatString($aFormStr,$aDate=false) { 3387 3388 } 3389 3720 $this->scale->ticks->SetLabelFormat($aFormStr,$aDate); 3721 } 3722 3390 3723 function SetLabelFormatCallback($aFuncName) { 3391 3392 } 3393 3394 function SetLabelAlign($aHAlign,$aVAlign= "top",$aParagraphAlign='left') {3395 3396 3397 3398 } 3724 $this->scale->ticks->SetFormatCallback($aFuncName); 3725 } 3726 3727 function SetLabelAlign($aHAlign,$aVAlign='top',$aParagraphAlign='left') { 3728 $this->label_halign = $aHAlign; 3729 $this->label_valign = $aVAlign; 3730 $this->label_para_align = $aParagraphAlign; 3731 } 3399 3732 3400 3733 // Don't display the first label 3401 3734 function HideFirstTickLabel($aShow=false) { 3402 3735 $this->show_first_label=$aShow; 3403 3736 } 3404 3737 3405 3738 function HideLastTickLabel($aShow=false) { 3406 3739 $this->show_last_label=$aShow; 3407 3740 } 3408 3741 3409 3742 // Manually specify the major and (optional) minor tick position and labels 3410 3743 function SetTickPositions($aMajPos,$aMinPos=NULL,$aLabels=NULL) { 3411 3744 $this->scale->ticks->SetTickPositions($aMajPos,$aMinPos,$aLabels); 3412 3745 } 3413 3746 3414 3747 // Manually specify major tick positions and optional labels 3415 3748 function SetMajTickPositions($aMajPos,$aLabels=NULL) { 3416 3749 $this->scale->ticks->SetTickPositions($aMajPos,NULL,$aLabels); 3417 3750 } 3418 3751 3419 3752 // Hide minor or major tick marks 3420 3753 function HideTicks($aHideMinor=true,$aHideMajor=true) { 3421 3422 3754 $this->scale->ticks->SupressMinorTickMarks($aHideMinor); 3755 $this->scale->ticks->SupressTickMarks($aHideMajor); 3423 3756 } 3424 3757 3425 3758 // Hide zero label 3426 3759 function HideZeroLabel($aFlag=true) { 3427 3428 } 3429 3760 $this->scale->ticks->SupressZeroLabel(); 3761 } 3762 3430 3763 function HideFirstLastLabel() { 3431 // The two first calls to ticks method will supress 3432 3433 3434 3435 3436 3437 3438 $this->show_first_label= false;3439 3440 } 3441 3764 // The two first calls to ticks method will supress 3765 // automatically generated scale values. However, that 3766 // will not affect manually specified value, e.g text-scales. 3767 // therefor we also make a kludge here to supress manually 3768 // specified scale labels. 3769 $this->scale->ticks->SupressLast(); 3770 $this->scale->ticks->SupressFirst(); 3771 $this->show_first_label = false; 3772 $this->show_last_label = false; 3773 } 3774 3442 3775 // Hide the axis 3443 3776 function Hide($aHide=true) { 3444 3777 $this->hide=$aHide; 3445 3778 } 3446 3779 3447 3780 // Hide the actual axis-line, but still print the labels 3448 3781 function HideLine($aHide=true) { 3449 3782 $this->hide_line = $aHide; 3450 3783 } 3451 3784 3452 3785 function HideLabels($aHide=true) { 3453 $this->hide_labels = $aHide; 3454 } 3455 3786 $this->hide_labels = $aHide; 3787 } 3456 3788 3457 3789 // Weight of axis 3458 3790 function SetWeight($aWeight) { 3459 3791 $this->weight = $aWeight; 3460 3792 } 3461 3793 3462 3794 // Axis color 3463 3795 function SetColor($aColor,$aLabelColor=false) { 3464 3465 3466 3467 } 3468 3796 $this->color = $aColor; 3797 if( !$aLabelColor ) $this->label_color = $aColor; 3798 else $this->label_color = $aLabelColor; 3799 } 3800 3469 3801 // Title on axis 3470 function SetTitle($aTitle,$aAdjustAlign= "high") {3471 3472 3473 } 3474 3802 function SetTitle($aTitle,$aAdjustAlign='high') { 3803 $this->title->Set($aTitle); 3804 $this->title_adjust=$aAdjustAlign; 3805 } 3806 3475 3807 // Specify distance from the axis 3476 3808 function SetTitleMargin($aMargin) { 3477 3478 } 3479 3809 $this->title_margin=$aMargin; 3810 } 3811 3480 3812 // Which side of the axis should the axis title be? 3481 3813 function SetTitleSide($aSideOfAxis) { 3482 $this->title_side = $aSideOfAxis; 3483 } 3484 3485 // Utility function to set the direction for tick marks 3486 function SetTickDirection($aDir) { 3487 // Will be deprecated from 1.7 3488 if( ERR_DEPRECATED ) 3489 JpGraphError::RaiseL(25055);//('Axis::SetTickDirection() is deprecated. Use Axis::SetTickSide() instead'); 3490 $this->scale->ticks->SetSide($aDir); 3491 } 3492 3814 $this->title_side = $aSideOfAxis; 3815 } 3816 3493 3817 function SetTickSide($aDir) { 3494 $this->scale->ticks->SetSide($aDir); 3495 } 3496 3818 $this->scale->ticks->SetSide($aDir); 3819 } 3820 3821 function SetTickSize($aMajSize,$aMinSize=3) { 3822 $this->scale->ticks->SetSize($aMajSize,$aMinSize=3); 3823 } 3824 3497 3825 // Specify text labels for the ticks. One label for each data point 3498 3826 function SetTickLabels($aLabelArray,$aLabelColorArray=null) { 3499 $this->ticks_label = $aLabelArray; 3500 $this->ticks_label_colors = $aLabelColorArray; 3501 } 3502 3503 // How far from the axis should the labels be drawn 3504 function SetTickLabelMargin($aMargin) { 3505 if( ERR_DEPRECATED ) 3506 JpGraphError::RaiseL(25056);//('SetTickLabelMargin() is deprecated. Use Axis::SetLabelMargin() instead.'); 3507 $this->tick_label_margin=$aMargin; 3827 $this->ticks_label = $aLabelArray; 3828 $this->ticks_label_colors = $aLabelColorArray; 3508 3829 } 3509 3830 3510 3831 function SetLabelMargin($aMargin) { 3511 3512 } 3513 3832 $this->tick_label_margin=$aMargin; 3833 } 3834 3514 3835 // Specify that every $step of the ticks should be displayed starting 3515 3836 // at $start 3516 // DEPRECATED FUNCTION: USE SetTextTickInterval() INSTEAD3517 function SetTextTicks($step,$start=0) {3518 JpGraphError::RaiseL(25057);//(" SetTextTicks() is deprecated. Use SetTextTickInterval() instead.");3519 }3520 3521 // Specify that every $step of the ticks should be displayed starting3522 // at $start3523 3837 function SetTextTickInterval($aStep,$aStart=0) { 3524 3525 3526 } 3527 3528 // Specify that every $step tick mark should have a label 3838 $this->scale->ticks->SetTextLabelStart($aStart); 3839 $this->tick_step=$aStep; 3840 } 3841 3842 // Specify that every $step tick mark should have a label 3529 3843 // should be displayed starting 3530 3844 function SetTextLabelInterval($aStep) { 3531 if( $aStep < 1 ) 3532 JpGraphError::RaiseL(25058);//(" Text label interval must be specified >= 1."); 3533 $this->label_step=$aStep; 3534 } 3535 3536 // Which side of the axis should the labels be on? 3537 function SetLabelPos($aSidePos) { 3538 // This will be deprecated from 1.7 3539 if( ERR_DEPRECATED ) 3540 JpGraphError::RaiseL(25059);//('SetLabelPos() is deprecated. Use Axis::SetLabelSide() instead.'); 3541 $this->labelPos=$aSidePos; 3542 } 3543 3845 if( $aStep < 1 ) { 3846 JpGraphError::RaiseL(25058);//(" Text label interval must be specified >= 1."); 3847 } 3848 $this->label_step=$aStep; 3849 } 3850 3544 3851 function SetLabelSide($aSidePos) { 3545 3852 $this->labelPos=$aSidePos; 3546 3853 } 3547 3854 3548 3855 // Set the font 3549 3856 function SetFont($aFamily,$aStyle=FS_NORMAL,$aSize=10) { 3550 3551 3552 3857 $this->font_family = $aFamily; 3858 $this->font_style = $aStyle; 3859 $this->font_size = $aSize; 3553 3860 } 3554 3861 3555 3862 // Position for axis line on the "other" scale 3556 3863 function SetPos($aPosOnOtherScale) { 3557 3558 } 3559 3560 // Set the position of the axis to be X-pixels delta to the right 3864 $this->pos=$aPosOnOtherScale; 3865 } 3866 3867 // Set the position of the axis to be X-pixels delta to the right 3561 3868 // of the max X-position (used to position the multiple Y-axis) 3562 3869 function SetPosAbsDelta($aDelta) { 3563 $this->iDeltaAbsPos=$aDelta;3564 } 3565 3870 $this->iDeltaAbsPos=$aDelta; 3871 } 3872 3566 3873 // Specify the angle for the tick labels 3567 3874 function SetLabelAngle($aAngle) { 3568 3569 } 3875 $this->label_angle = $aAngle; 3876 } 3570 3877 3571 3878 } // Class … … 3578 3885 // several occasion must know wheter it's an X or Y axis. 3579 3886 // This was a design decision to make the code easier to 3580 // follow. 3887 // follow. 3581 3888 //=================================================== 3582 3889 class Axis extends AxisPrototype { 3583 3890 3584 function Axis($img,$aScale,$color=array(0,0,0)) {3585 parent::Axis($img,$aScale,$color);3586 } 3587 3891 function __construct($img,$aScale,$color='black') { 3892 parent::__construct($img,$aScale,$color); 3893 } 3894 3588 3895 // Stroke the axis. 3589 function Stroke($aOtherAxisScale,$aStrokeLabels=true) { 3590 if( $this->hide ) return; 3591 if( is_numeric($this->pos) ) { 3592 $pos=$aOtherAxisScale->Translate($this->pos); 3593 } 3594 else { // Default to minimum of other scale if pos not set 3595 if( ($aOtherAxisScale->GetMinVal() >= 0 && $this->pos==false) || $this->pos=="min" ) { 3596 $pos = $aOtherAxisScale->scale_abs[0]; 3597 } 3598 elseif($this->pos == "max") { 3599 $pos = $aOtherAxisScale->scale_abs[1]; 3600 } 3601 else { // If negative set x-axis at 0 3602 $this->pos=0; 3603 $pos=$aOtherAxisScale->Translate(0); 3604 } 3605 } 3606 $pos += $this->iDeltaAbsPos; 3607 $this->img->SetLineWeight($this->weight); 3608 $this->img->SetColor($this->color); 3609 $this->img->SetFont($this->font_family,$this->font_style,$this->font_size); 3610 if( $this->scale->type == "x" ) { 3611 if( !$this->hide_line ) 3612 $this->img->FilledRectangle($this->img->left_margin,$pos, 3613 $this->img->width-$this->img->right_margin,$pos+$this->weight-1); 3614 if( $this->title_side == SIDE_DOWN ) { 3615 $y = $pos + $this->img->GetFontHeight() + $this->title_margin + $this->title->margin; 3616 $yalign = 'top'; 3617 } 3618 else { 3619 $y = $pos - $this->img->GetFontHeight() - $this->title_margin - $this->title->margin; 3620 $yalign = 'bottom'; 3621 } 3622 3623 if( $this->title_adjust=='high' ) 3624 $this->title->SetPos($this->img->width-$this->img->right_margin,$y,'right',$yalign); 3625 elseif( $this->title_adjust=='middle' || $this->title_adjust=='center' ) 3626 $this->title->SetPos(($this->img->width-$this->img->left_margin-$this->img->right_margin)/2+$this->img->left_margin,$y,'center',$yalign); 3627 elseif($this->title_adjust=='low') 3628 $this->title->SetPos($this->img->left_margin,$y,'left',$yalign); 3629 else { 3630 JpGraphError::RaiseL(25060,$this->title_adjust);//('Unknown alignment specified for X-axis title. ('.$this->title_adjust.')'); 3631 } 3632 } 3633 elseif( $this->scale->type == "y" ) { 3634 // Add line weight to the height of the axis since 3635 // the x-axis could have a width>1 and we want the axis to fit nicely together. 3636 if( !$this->hide_line ) 3637 $this->img->FilledRectangle($pos-$this->weight+1,$this->img->top_margin, 3638 $pos,$this->img->height-$this->img->bottom_margin+$this->weight-1); 3639 $x=$pos ; 3640 if( $this->title_side == SIDE_LEFT ) { 3641 $x -= $this->title_margin; 3642 $x -= $this->title->margin; 3643 $halign="right"; 3644 } 3645 else { 3646 $x += $this->title_margin; 3647 $x += $this->title->margin; 3648 $halign="left"; 3649 } 3650 // If the user has manually specified an hor. align 3651 // then we override the automatic settings with this 3652 // specifed setting. Since default is 'left' we compare 3653 // with that. (This means a manually set 'left' align 3654 // will have no effect.) 3655 if( $this->title->halign != 'left' ) 3656 $halign = $this->title->halign; 3657 if( $this->title_adjust=="high" ) 3658 $this->title->SetPos($x,$this->img->top_margin,$halign,"top"); 3659 elseif($this->title_adjust=="middle" || $this->title_adjust=="center") 3660 $this->title->SetPos($x,($this->img->height-$this->img->top_margin-$this->img->bottom_margin)/2+$this->img->top_margin,$halign,"center"); 3661 elseif($this->title_adjust=="low") 3662 $this->title->SetPos($x,$this->img->height-$this->img->bottom_margin,$halign,"bottom"); 3663 else 3664 JpGraphError::RaiseL(25061,$this->title_adjust);//('Unknown alignment specified for Y-axis title. ('.$this->title_adjust.')'); 3665 3666 } 3667 $this->scale->ticks->Stroke($this->img,$this->scale,$pos); 3668 if( $aStrokeLabels ) { 3669 if( !$this->hide_labels ) 3670 $this->StrokeLabels($pos); 3671 $this->title->Stroke($this->img); 3672 } 3673 } 3674 3675 //--------------- 3676 // PRIVATE METHODS 3896 function Stroke($aOtherAxisScale,$aStrokeLabels=true) { 3897 if( $this->hide ) 3898 return; 3899 if( is_numeric($this->pos) ) { 3900 $pos=$aOtherAxisScale->Translate($this->pos); 3901 } 3902 else { // Default to minimum of other scale if pos not set 3903 if( ($aOtherAxisScale->GetMinVal() >= 0 && $this->pos==false) || $this->pos == 'min' ) { 3904 $pos = $aOtherAxisScale->scale_abs[0]; 3905 } 3906 elseif($this->pos == "max") { 3907 $pos = $aOtherAxisScale->scale_abs[1]; 3908 } 3909 else { // If negative set x-axis at 0 3910 $this->pos=0; 3911 $pos=$aOtherAxisScale->Translate(0); 3912 } 3913 } 3914 3915 $pos += $this->iDeltaAbsPos; 3916 $this->img->SetLineWeight($this->weight); 3917 $this->img->SetColor($this->color); 3918 $this->img->SetFont($this->font_family,$this->font_style,$this->font_size); 3919 3920 if( $this->scale->type == "x" ) { 3921 if( !$this->hide_line ) { 3922 // Stroke X-axis 3923 $this->img->FilledRectangle( 3924 $this->img->left_margin, 3925 $pos, 3926 $this->img->width - $this->img->right_margin, 3927 $pos + $this->weight-1 3928 ); 3929 } 3930 if( $this->title_side == SIDE_DOWN ) { 3931 $y = $pos + $this->img->GetFontHeight() + $this->title_margin + $this->title->margin; 3932 $yalign = 'top'; 3933 } 3934 else { 3935 $y = $pos - $this->img->GetFontHeight() - $this->title_margin - $this->title->margin; 3936 $yalign = 'bottom'; 3937 } 3938 3939 if( $this->title_adjust=='high' ) { 3940 $this->title->SetPos($this->img->width-$this->img->right_margin,$y,'right',$yalign); 3941 } 3942 elseif( $this->title_adjust=='middle' || $this->title_adjust=='center' ) { 3943 $this->title->SetPos(($this->img->width-$this->img->left_margin-$this->img->right_margin)/2+$this->img->left_margin,$y,'center',$yalign); 3944 } 3945 elseif($this->title_adjust=='low') { 3946 $this->title->SetPos($this->img->left_margin,$y,'left',$yalign); 3947 } 3948 else { 3949 JpGraphError::RaiseL(25060,$this->title_adjust);//('Unknown alignment specified for X-axis title. ('.$this->title_adjust.')'); 3950 } 3951 } 3952 elseif( $this->scale->type == "y" ) { 3953 // Add line weight to the height of the axis since 3954 // the x-axis could have a width>1 and we want the axis to fit nicely together. 3955 if( !$this->hide_line ) { 3956 // Stroke Y-axis 3957 $this->img->FilledRectangle( 3958 $pos - $this->weight + 1, 3959 $this->img->top_margin, 3960 $pos, 3961 $this->img->height - $this->img->bottom_margin + $this->weight - 1 3962 ); 3963 } 3964 3965 $x=$pos ; 3966 if( $this->title_side == SIDE_LEFT ) { 3967 $x -= $this->title_margin; 3968 $x -= $this->title->margin; 3969 $halign = 'right'; 3970 } 3971 else { 3972 $x += $this->title_margin; 3973 $x += $this->title->margin; 3974 $halign = 'left'; 3975 } 3976 // If the user has manually specified an hor. align 3977 // then we override the automatic settings with this 3978 // specifed setting. Since default is 'left' we compare 3979 // with that. (This means a manually set 'left' align 3980 // will have no effect.) 3981 if( $this->title->halign != 'left' ) { 3982 $halign = $this->title->halign; 3983 } 3984 if( $this->title_adjust == 'high' ) { 3985 $this->title->SetPos($x,$this->img->top_margin,$halign,'top'); 3986 } 3987 elseif($this->title_adjust=='middle' || $this->title_adjust=='center') { 3988 $this->title->SetPos($x,($this->img->height-$this->img->top_margin-$this->img->bottom_margin)/2+$this->img->top_margin,$halign,"center"); 3989 } 3990 elseif($this->title_adjust=='low') { 3991 $this->title->SetPos($x,$this->img->height-$this->img->bottom_margin,$halign,'bottom'); 3992 } 3993 else { 3994 JpGraphError::RaiseL(25061,$this->title_adjust);//('Unknown alignment specified for Y-axis title. ('.$this->title_adjust.')'); 3995 } 3996 } 3997 $this->scale->ticks->Stroke($this->img,$this->scale,$pos); 3998 if( $aStrokeLabels ) { 3999 if( !$this->hide_labels ) { 4000 $this->StrokeLabels($pos); 4001 } 4002 $this->title->Stroke($this->img); 4003 } 4004 } 4005 4006 //--------------- 4007 // PRIVATE METHODS 3677 4008 // Draw all the tick labels on major tick marks 3678 4009 function StrokeLabels($aPos,$aMinor=false,$aAbsLabel=false) { 3679 4010 3680 $this->img->SetColor($this->label_color); 3681 $this->img->SetFont($this->font_family,$this->font_style,$this->font_size); 3682 $yoff=$this->img->GetFontHeight()/2; 3683 3684 // Only draw labels at major tick marks 3685 $nbr = count($this->scale->ticks->maj_ticks_label); 3686 3687 // We have the option to not-display the very first mark 3688 // (Usefull when the first label might interfere with another 3689 // axis.) 3690 $i = $this->show_first_label ? 0 : 1 ; 3691 if( !$this->show_last_label ) --$nbr; 3692 // Now run through all labels making sure we don't overshoot the end 3693 // of the scale. 3694 $ncolor=0; 3695 if( isset($this->ticks_label_colors) ) 3696 $ncolor=count($this->ticks_label_colors); 3697 while( $i<$nbr ) { 3698 // $tpos holds the absolute text position for the label 3699 $tpos=$this->scale->ticks->maj_ticklabels_pos[$i]; 3700 3701 // Note. the $limit is only used for the x axis since we 3702 // might otherwise overshoot if the scale has been centered 3703 // This is due to us "loosing" the last tick mark if we center. 3704 if( $this->scale->type=="x" && $tpos > $this->img->width-$this->img->right_margin+1 ) { 3705 return; 3706 } 3707 // we only draw every $label_step label 3708 if( ($i % $this->label_step)==0 ) { 3709 3710 // Set specific label color if specified 3711 if( $ncolor > 0 ) 3712 $this->img->SetColor($this->ticks_label_colors[$i % $ncolor]); 3713 3714 // If the label has been specified use that and in other case 3715 // just label the mark with the actual scale value 3716 $m=$this->scale->ticks->GetMajor(); 3717 3718 // ticks_label has an entry for each data point and is the array 3719 // that holds the labels set by the user. If the user hasn't 3720 // specified any values we use whats in the automatically asigned 3721 // labels in the maj_ticks_label 3722 if( isset($this->ticks_label[$i*$m]) ) 3723 $label=$this->ticks_label[$i*$m]; 3724 else { 3725 if( $aAbsLabel ) 3726 $label=abs($this->scale->ticks->maj_ticks_label[$i]); 3727 else 3728 $label=$this->scale->ticks->maj_ticks_label[$i]; 3729 if( $this->scale->textscale && $this->scale->ticks->label_formfunc == '' ) { 3730 ++$label; 3731 } 3732 } 3733 3734 if( $this->scale->type == "x" ) { 3735 if( $this->labelPos == SIDE_DOWN ) { 3736 if( $this->label_angle==0 || $this->label_angle==90 ) { 3737 if( $this->label_halign=='' && $this->label_valign=='') 3738 $this->img->SetTextAlign('center','top'); 3739 else 3740 $this->img->SetTextAlign($this->label_halign,$this->label_valign); 3741 3742 } 3743 else { 3744 if( $this->label_halign=='' && $this->label_valign=='') 3745 $this->img->SetTextAlign("right","top"); 3746 else 3747 $this->img->SetTextAlign($this->label_halign,$this->label_valign); 3748 } 3749 $this->img->StrokeText($tpos,$aPos+$this->tick_label_margin+1,$label, 3750 $this->label_angle,$this->label_para_align); 3751 } 3752 else { 3753 if( $this->label_angle==0 || $this->label_angle==90 ) { 3754 if( $this->label_halign=='' && $this->label_valign=='') 3755 $this->img->SetTextAlign("center","bottom"); 3756 else 3757 $this->img->SetTextAlign($this->label_halign,$this->label_valign); 3758 } 3759 else { 3760 if( $this->label_halign=='' && $this->label_valign=='') 3761 $this->img->SetTextAlign("right","bottom"); 3762 else 3763 $this->img->SetTextAlign($this->label_halign,$this->label_valign); 3764 } 3765 $this->img->StrokeText($tpos,$aPos-$this->tick_label_margin-1,$label, 3766 $this->label_angle,$this->label_para_align); 3767 } 3768 } 3769 else { 3770 // scale->type == "y" 3771 //if( $this->label_angle!=0 ) 3772 //JpGraphError::Raise(" Labels at an angle are not supported on Y-axis"); 3773 if( $this->labelPos == SIDE_LEFT ) { // To the left of y-axis 3774 if( $this->label_halign=='' && $this->label_valign=='') 3775 $this->img->SetTextAlign("right","center"); 3776 else 3777 $this->img->SetTextAlign($this->label_halign,$this->label_valign); 3778 $this->img->StrokeText($aPos-$this->tick_label_margin,$tpos,$label,$this->label_angle,$this->label_para_align); 3779 } 3780 else { // To the right of the y-axis 3781 if( $this->label_halign=='' && $this->label_valign=='') 3782 $this->img->SetTextAlign("left","center"); 3783 else 3784 $this->img->SetTextAlign($this->label_halign,$this->label_valign); 3785 $this->img->StrokeText($aPos+$this->tick_label_margin,$tpos,$label,$this->label_angle,$this->label_para_align); 3786 } 3787 } 3788 } 3789 ++$i; 3790 } 3791 } 4011 if( is_array($this->label_color) && count($this->label_color) > 3 ) { 4012 $this->ticks_label_colors = $this->label_color; 4013 $this->img->SetColor($this->label_color[0]); 4014 } 4015 else { 4016 $this->img->SetColor($this->label_color); 4017 } 4018 $this->img->SetFont($this->font_family,$this->font_style,$this->font_size); 4019 $yoff=$this->img->GetFontHeight()/2; 4020 4021 // Only draw labels at major tick marks 4022 $nbr = count($this->scale->ticks->maj_ticks_label); 4023 4024 // We have the option to not-display the very first mark 4025 // (Usefull when the first label might interfere with another 4026 // axis.) 4027 $i = $this->show_first_label ? 0 : 1 ; 4028 if( !$this->show_last_label ) { 4029 --$nbr; 4030 } 4031 // Now run through all labels making sure we don't overshoot the end 4032 // of the scale. 4033 $ncolor=0; 4034 if( isset($this->ticks_label_colors) ) { 4035 $ncolor=count($this->ticks_label_colors); 4036 } 4037 while( $i < $nbr ) { 4038 // $tpos holds the absolute text position for the label 4039 $tpos=$this->scale->ticks->maj_ticklabels_pos[$i]; 4040 4041 // Note. the $limit is only used for the x axis since we 4042 // might otherwise overshoot if the scale has been centered 4043 // This is due to us "loosing" the last tick mark if we center. 4044 if( $this->scale->type == 'x' && $tpos > $this->img->width-$this->img->right_margin+1 ) { 4045 return; 4046 } 4047 // we only draw every $label_step label 4048 if( ($i % $this->label_step)==0 ) { 4049 4050 // Set specific label color if specified 4051 if( $ncolor > 0 ) { 4052 $this->img->SetColor($this->ticks_label_colors[$i % $ncolor]); 4053 } 4054 4055 // If the label has been specified use that and in other case 4056 // just label the mark with the actual scale value 4057 $m=$this->scale->ticks->GetMajor(); 4058 4059 // ticks_label has an entry for each data point and is the array 4060 // that holds the labels set by the user. If the user hasn't 4061 // specified any values we use whats in the automatically asigned 4062 // labels in the maj_ticks_label 4063 if( isset($this->ticks_label[$i*$m]) ) { 4064 $label=$this->ticks_label[$i*$m]; 4065 } 4066 else { 4067 if( $aAbsLabel ) { 4068 $label=abs($this->scale->ticks->maj_ticks_label[$i]); 4069 } 4070 else { 4071 $label=$this->scale->ticks->maj_ticks_label[$i]; 4072 } 4073 4074 // We number the scale from 1 and not from 0 so increase by one 4075 if( $this->scale->textscale && 4076 $this->scale->ticks->label_formfunc == '' && 4077 ! $this->scale->ticks->HaveManualLabels() ) { 4078 4079 ++$label; 4080 4081 } 4082 } 4083 4084 if( $this->scale->type == "x" ) { 4085 if( $this->labelPos == SIDE_DOWN ) { 4086 if( $this->label_angle==0 || $this->label_angle==90 ) { 4087 if( $this->label_halign=='' && $this->label_valign=='') { 4088 $this->img->SetTextAlign('center','top'); 4089 } 4090 else { 4091 $this->img->SetTextAlign($this->label_halign,$this->label_valign); 4092 } 4093 4094 } 4095 else { 4096 if( $this->label_halign=='' && $this->label_valign=='') { 4097 $this->img->SetTextAlign("right","top"); 4098 } 4099 else { 4100 $this->img->SetTextAlign($this->label_halign,$this->label_valign); 4101 } 4102 } 4103 $this->img->StrokeText($tpos,$aPos+$this->tick_label_margin,$label, 4104 $this->label_angle,$this->label_para_align); 4105 } 4106 else { 4107 if( $this->label_angle==0 || $this->label_angle==90 ) { 4108 if( $this->label_halign=='' && $this->label_valign=='') { 4109 $this->img->SetTextAlign("center","bottom"); 4110 } 4111 else { 4112 $this->img->SetTextAlign($this->label_halign,$this->label_valign); 4113 } 4114 } 4115 else { 4116 if( $this->label_halign=='' && $this->label_valign=='') { 4117 $this->img->SetTextAlign("right","bottom"); 4118 } 4119 else { 4120 $this->img->SetTextAlign($this->label_halign,$this->label_valign); 4121 } 4122 } 4123 $this->img->StrokeText($tpos,$aPos-$this->tick_label_margin-1,$label, 4124 $this->label_angle,$this->label_para_align); 4125 } 4126 } 4127 else { 4128 // scale->type == "y" 4129 //if( $this->label_angle!=0 ) 4130 //JpGraphError::Raise(" Labels at an angle are not supported on Y-axis"); 4131 if( $this->labelPos == SIDE_LEFT ) { // To the left of y-axis 4132 if( $this->label_halign=='' && $this->label_valign=='') { 4133 $this->img->SetTextAlign("right","center"); 4134 } 4135 else { 4136 $this->img->SetTextAlign($this->label_halign,$this->label_valign); 4137 } 4138 $this->img->StrokeText($aPos-$this->tick_label_margin,$tpos,$label,$this->label_angle,$this->label_para_align); 4139 } 4140 else { // To the right of the y-axis 4141 if( $this->label_halign=='' && $this->label_valign=='') { 4142 $this->img->SetTextAlign("left","center"); 4143 } 4144 else { 4145 $this->img->SetTextAlign($this->label_halign,$this->label_valign); 4146 } 4147 $this->img->StrokeText($aPos+$this->tick_label_margin,$tpos,$label,$this->label_angle,$this->label_para_align); 4148 } 4149 } 4150 } 4151 ++$i; 4152 } 4153 } 3792 4154 3793 4155 } … … 3805 4167 public $direction=1; // Should ticks be in(=1) the plot area or outside (=-1) 3806 4168 public $supress_last=false,$supress_tickmarks=false,$supress_minor_tickmarks=false; 3807 public $maj_ticks_pos = array(), $maj_ticklabels_pos = array(), 3808 4169 public $maj_ticks_pos = array(), $maj_ticklabels_pos = array(), 4170 $ticks_pos = array(), $maj_ticks_label = array(); 3809 4171 public $precision; 3810 4172 … … 3813 4175 protected $is_set=false; 3814 4176 protected $supress_zerolabel=false,$supress_first=false; 3815 protected $mincolor= "",$majcolor="";4177 protected $mincolor='',$majcolor=''; 3816 4178 protected $weight=1; 3817 4179 protected $label_usedateformat=FALSE; 3818 4180 3819 //--------------- 3820 // CONSTRUCTOR 3821 function Ticks($aScale) { 3822 $this->scale=$aScale; 3823 $this->precision = -1; 3824 } 3825 3826 //--------------- 3827 // PUBLIC METHODS 4181 function __construct($aScale) { 4182 $this->scale=$aScale; 4183 $this->precision = -1; 4184 } 4185 3828 4186 // Set format string for automatic labels 3829 4187 function SetLabelFormat($aFormatString,$aDate=FALSE) { 3830 3831 3832 } 3833 4188 $this->label_formatstr=$aFormatString; 4189 $this->label_usedateformat=$aDate; 4190 } 4191 3834 4192 function SetLabelDateFormat($aFormatString) { 3835 3836 } 3837 4193 $this->label_dateformatstr=$aFormatString; 4194 } 4195 3838 4196 function SetFormatCallback($aCallbackFuncName) { 3839 3840 } 3841 4197 $this->label_formfunc = $aCallbackFuncName; 4198 } 4199 3842 4200 // Don't display the first zero label 3843 4201 function SupressZeroLabel($aFlag=true) { 3844 3845 } 3846 4202 $this->supress_zerolabel=$aFlag; 4203 } 4204 3847 4205 // Don't display minor tick marks 3848 4206 function SupressMinorTickMarks($aHide=true) { 3849 3850 } 3851 4207 $this->supress_minor_tickmarks=$aHide; 4208 } 4209 3852 4210 // Don't display major tick marks 3853 4211 function SupressTickMarks($aHide=true) { 3854 3855 } 3856 4212 $this->supress_tickmarks=$aHide; 4213 } 4214 3857 4215 // Hide the first tick mark 3858 4216 function SupressFirst($aHide=true) { 3859 3860 } 3861 4217 $this->supress_first=$aHide; 4218 } 4219 3862 4220 // Hide the last tick mark 3863 4221 function SupressLast($aHide=true) { 3864 4222 $this->supress_last=$aHide; 3865 4223 } 3866 4224 3867 4225 // Size (in pixels) of minor tick marks 3868 4226 function GetMinTickAbsSize() { 3869 3870 } 3871 4227 return $this->minor_abs_size; 4228 } 4229 3872 4230 // Size (in pixels) of major tick marks 3873 4231 function GetMajTickAbsSize() { 3874 return $this->major_abs_size; 3875 } 3876 4232 return $this->major_abs_size; 4233 } 4234 3877 4235 function SetSize($aMajSize,$aMinSize=3) { 3878 $this->major_abs_size = $aMajSize; 3879 $this->minor_abs_size = $aMinSize; 4236 $this->major_abs_size = $aMajSize; 4237 $this->minor_abs_size = $aMinSize; 3880 4238 } 3881 4239 3882 4240 // Have the ticks been specified 3883 4241 function IsSpecified() { 3884 return $this->is_set; 3885 } 3886 3887 // Specify number of decimals in automatic labels 3888 // Deprecated from 1.4. Use SetFormatString() instead 3889 function SetPrecision($aPrecision) { 3890 if( ERR_DEPRECATED ) 3891 JpGraphError::RaiseL(25063);//('Ticks::SetPrecision() is deprecated. Use Ticks::SetLabelFormat() (or Ticks::SetFormatCallback()) instead'); 3892 $this->precision=$aPrecision; 4242 return $this->is_set; 3893 4243 } 3894 4244 3895 4245 function SetSide($aSide) { 3896 3897 } 3898 4246 $this->direction=$aSide; 4247 } 4248 3899 4249 // Which side of the axis should the ticks be on 3900 4250 function SetDirection($aSide=SIDE_RIGHT) { 3901 3902 } 3903 4251 $this->direction=$aSide; 4252 } 4253 3904 4254 // Set colors for major and minor tick marks 3905 function SetMarkColor($aMajorColor,$aMinorColor="") { 3906 $this->SetColor($aMajorColor,$aMinorColor); 3907 } 3908 3909 function SetColor($aMajorColor,$aMinorColor="") { 3910 $this->majcolor=$aMajorColor; 3911 3912 // If not specified use same as major 3913 if( $aMinorColor=="" ) 3914 $this->mincolor=$aMajorColor; 3915 else 3916 $this->mincolor=$aMinorColor; 3917 } 3918 4255 function SetMarkColor($aMajorColor,$aMinorColor='') { 4256 $this->SetColor($aMajorColor,$aMinorColor); 4257 } 4258 4259 function SetColor($aMajorColor,$aMinorColor='') { 4260 $this->majcolor=$aMajorColor; 4261 4262 // If not specified use same as major 4263 if( $aMinorColor == '' ) { 4264 $this->mincolor=$aMajorColor; 4265 } 4266 else { 4267 $this->mincolor=$aMinorColor; 4268 } 4269 } 4270 3919 4271 function SetWeight($aWeight) { 3920 3921 } 3922 4272 $this->weight=$aWeight; 4273 } 4274 3923 4275 } // Class 3924 4276 … … 3936 4288 private $iAdjustForDST = false; // If a date falls within the DST period add one hour to the diaplyed time 3937 4289 3938 //--------------- 3939 // CONSTRUCTOR 3940 function LinearTicks() { 3941 $this->precision = -1; 3942 } 3943 3944 //--------------- 3945 // PUBLIC METHODS 3946 3947 4290 function __construct() { 4291 $this->precision = -1; 4292 } 4293 3948 4294 // Return major step size in world coordinates 3949 4295 function GetMajor() { 3950 3951 } 3952 4296 return $this->major_step; 4297 } 4298 3953 4299 // Return minor step size in world coordinates 3954 4300 function GetMinor() { 3955 3956 } 3957 4301 return $this->minor_step; 4302 } 4303 3958 4304 // Set Minor and Major ticks (in world coordinates) 3959 4305 function Set($aMajStep,$aMinStep=false) { 3960 if( $aMinStep==false ) 3961 $aMinStep=$aMajStep; 3962 3963 if( $aMajStep <= 0 || $aMinStep <= 0 ) { 3964 JpGraphError::RaiseL(25064); 3965 //(" 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."); 3966 } 3967 3968 $this->major_step=$aMajStep; 3969 $this->minor_step=$aMinStep; 3970 $this->is_set = true; 4306 if( $aMinStep==false ) { 4307 $aMinStep=$aMajStep; 4308 } 4309 4310 if( $aMajStep <= 0 || $aMinStep <= 0 ) { 4311 JpGraphError::RaiseL(25064); 4312 //(" 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."); 4313 } 4314 4315 $this->major_step=$aMajStep; 4316 $this->minor_step=$aMinStep; 4317 $this->is_set = true; 3971 4318 } 3972 4319 3973 4320 function SetMajTickPositions($aMajPos,$aLabels=NULL) { 3974 4321 $this->SetTickPositions($aMajPos,NULL,$aLabels); 3975 4322 } 3976 4323 3977 4324 function SetTickPositions($aMajPos,$aMinPos=NULL,$aLabels=NULL) { 3978 3979 3980 3981 3982 3983 3984 3985 return; 3986 } 3987 $this->iManualTickPos = $aMajPos;3988 $this->iManualMinTickPos = $aMinPos;3989 $this->iManualTickLabels = $aLabels; 3990 } 3991 3992 // Specify all the tick positions manually and possible also the exact labels3993 function _doManualTickPos($aScale) {3994 $n=count($this->iManualTickPos); 3995 $m=count($this->iManualMinTickPos); 3996 $doLbl=count($this->iManualTickLabels) > 0; 3997 3998 $this->maj_ticks_pos = array();3999 $this->maj_ticklabels_pos = array();4000 $this->ticks_pos = array(); 4001 4002 // Now loop through the supplied positions and translate them to screen coordinates 4003 // and store them in the maj_label_positions 4004 $minScale = $aScale->scale[0]; 4005 $maxScale = $aScale->scale[1]; 4006 $j=0; 4007 for($i=0; $i < $n ; ++$i ) { 4008 // First make sure that the first tick is not lower than the lower scale value 4009 if( !isset($this->iManualTickPos[$i]) || 4010 $this->iManualTickPos[$i] < $minScale || $this->iManualTickPos[$i] > $maxScale) {4011 continue; 4012 } 4013 4014 4015 $this->maj_ticks_pos[$j] = $aScale->Translate($this->iManualTickPos[$i]); 4016 $this->maj_ticklabels_pos[$j] = $this->maj_ticks_pos[$j]; 4017 4018 // Set the minor tick marks the same as major if not specified 4019 if( $m <= 0 ) { 4020 $this->ticks_pos[$j] = $this->maj_ticks_pos[$j]; 4021 } 4022 4023 if( $doLbl ) { 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 if( empty($this->iManualMinTickPos[$i]) || 4041 $this->iManualMinTickPos[$i] < $minScale || $this->iManualMinTickPos[$i] > $maxScale) 4042 continue; 4043 4044 4045 4325 if( !is_array($aMajPos) || ($aMinPos!==NULL && !is_array($aMinPos)) ) { 4326 JpGraphError::RaiseL(25065);//('Tick positions must be specifued as an array()'); 4327 return; 4328 } 4329 $n=count($aMajPos); 4330 if( is_array($aLabels) && (count($aLabels) != $n) ) { 4331 JpGraphError::RaiseL(25066);//('When manually specifying tick positions and labels the number of labels must be the same as the number of specified ticks.'); 4332 } 4333 $this->iManualTickPos = $aMajPos; 4334 $this->iManualMinTickPos = $aMinPos; 4335 $this->iManualTickLabels = $aLabels; 4336 } 4337 4338 function HaveManualLabels() { 4339 return is_array($this->iManualTickLabels) ? count($this->iManualTickLabels) > 0 : false; 4340 } 4341 4342 // Specify all the tick positions manually and possible also the exact labels 4343 function _doManualTickPos($aScale) { 4344 $n=count($this->iManualTickPos); 4345 $m= is_array($this->iManualMinTickPos) ? count($this->iManualMinTickPos) : 0; 4346 $doLbl= is_array($this->iManualTickLabels) ? count($this->iManualTickLabels) > 0 : false; 4347 4348 $this->maj_ticks_pos = array(); 4349 $this->maj_ticklabels_pos = array(); 4350 $this->ticks_pos = array(); 4351 4352 // Now loop through the supplied positions and translate them to screen coordinates 4353 // and store them in the maj_label_positions 4354 $minScale = $aScale->scale[0]; 4355 $maxScale = $aScale->scale[1]; 4356 $j=0; 4357 for($i=0; $i < $n ; ++$i ) { 4358 // First make sure that the first tick is not lower than the lower scale value 4359 if( !isset($this->iManualTickPos[$i]) || $this->iManualTickPos[$i] < $minScale || $this->iManualTickPos[$i] > $maxScale) { 4360 continue; 4361 } 4362 4363 $this->maj_ticks_pos[$j] = $aScale->Translate($this->iManualTickPos[$i]); 4364 $this->maj_ticklabels_pos[$j] = $this->maj_ticks_pos[$j]; 4365 4366 // Set the minor tick marks the same as major if not specified 4367 if( $m <= 0 ) { 4368 $this->ticks_pos[$j] = $this->maj_ticks_pos[$j]; 4369 } 4370 if( $doLbl ) { 4371 $this->maj_ticks_label[$j] = $this->iManualTickLabels[$i]; 4372 } 4373 else { 4374 $this->maj_ticks_label[$j]=$this->_doLabelFormat($this->iManualTickPos[$i],$i,$n); 4375 } 4376 ++$j; 4377 } 4378 4379 // Some sanity check 4380 if( count($this->maj_ticks_pos) < 2 ) { 4381 JpGraphError::RaiseL(25067);//('Your manually specified scale and ticks is not correct. The scale seems to be too small to hold any of the specified tickl marks.'); 4382 } 4383 4384 // Setup the minor tick marks 4385 $j=0; 4386 for($i=0; $i < $m; ++$i ) { 4387 if( empty($this->iManualMinTickPos[$i]) || $this->iManualMinTickPos[$i] < $minScale || $this->iManualMinTickPos[$i] > $maxScale) { 4388 continue; 4389 } 4390 $this->ticks_pos[$j] = $aScale->Translate($this->iManualMinTickPos[$i]); 4391 ++$j; 4392 } 4046 4393 } 4047 4394 4048 4395 function _doAutoTickPos($aScale) { 4049 $maj_step_abs = $aScale->scale_factor*$this->major_step; 4050 $min_step_abs = $aScale->scale_factor*$this->minor_step; 4051 4052 if( $min_step_abs==0 || $maj_step_abs==0 ) { 4053 JpGraphError::RaiseL(25068);//("A plot has an illegal scale. This could for example be that you are trying to use text autoscaling to draw a line plot with only one point or that the plot area is too small. It could also be that no input data value is numeric (perhaps only '-' or 'x')"); 4054 } 4055 // We need to make this an int since comparing it below 4056 // with the result from round() can give wrong result, such that 4057 // (40 < 40) == TRUE !!! 4058 $limit = (int)$aScale->scale_abs[1]; 4059 4060 if( $aScale->textscale ) { 4061 // This can only be true for a X-scale (horizontal) 4062 // Define ticks for a text scale. This is slightly different from a 4063 // normal linear type of scale since the position might be adjusted 4064 // and the labels start at on 4065 $label = (float)$aScale->GetMinVal()+$this->text_label_start+$this->label_offset; 4066 $start_abs=$aScale->scale_factor*$this->text_label_start; 4067 $nbrmajticks=round(($aScale->GetMaxVal()-$aScale->GetMinVal()-$this->text_label_start )/$this->major_step)+1; 4068 4069 $x = $aScale->scale_abs[0]+$start_abs+$this->xlabel_offset*$min_step_abs; 4070 for( $i=0; $label <= $aScale->GetMaxVal()+$this->label_offset; ++$i ) { 4071 // Apply format to label 4072 $this->maj_ticks_label[$i]=$this->_doLabelFormat($label,$i,$nbrmajticks); 4073 $label+=$this->major_step; 4074 4075 // The x-position of the tick marks can be different from the labels. 4076 // Note that we record the tick position (not the label) so that the grid 4077 // happen upon tick marks and not labels. 4078 $xtick=$aScale->scale_abs[0]+$start_abs+$this->xtick_offset*$min_step_abs+$i*$maj_step_abs; 4079 $this->maj_ticks_pos[$i]=$xtick; 4080 $this->maj_ticklabels_pos[$i] = round($x); 4081 $x += $maj_step_abs; 4082 } 4083 } 4084 else { 4085 $label = $aScale->GetMinVal(); 4086 $abs_pos = $aScale->scale_abs[0]; 4087 $j=0; $i=0; 4088 $step = round($maj_step_abs/$min_step_abs); 4089 if( $aScale->type == "x" ) { 4090 // For a normal linear type of scale the major ticks will always be multiples 4091 // of the minor ticks. In order to avoid any rounding issues the major ticks are 4092 // defined as every "step" minor ticks and not calculated separately 4093 $nbrmajticks=round(($aScale->GetMaxVal()-$aScale->GetMinVal()-$this->text_label_start )/$this->major_step)+1; 4094 while( round($abs_pos) <= $limit ) { 4095 $this->ticks_pos[] = round($abs_pos); 4096 $this->ticks_label[] = $label; 4097 if( $step== 0 || $i % $step == 0 && $j < $nbrmajticks ) { 4098 $this->maj_ticks_pos[$j] = round($abs_pos); 4099 $this->maj_ticklabels_pos[$j] = round($abs_pos); 4100 $this->maj_ticks_label[$j]=$this->_doLabelFormat($label,$j,$nbrmajticks); 4101 ++$j; 4102 } 4103 ++$i; 4104 $abs_pos += $min_step_abs; 4105 $label+=$this->minor_step; 4106 } 4107 } 4108 elseif( $aScale->type == "y" ) { 4109 $nbrmajticks=round(($aScale->GetMaxVal()-$aScale->GetMinVal())/$this->major_step)+1; 4110 while( round($abs_pos) >= $limit ) { 4111 $this->ticks_pos[$i] = round($abs_pos); 4112 $this->ticks_label[$i]=$label; 4113 if( $step== 0 || $i % $step == 0 && $j < $nbrmajticks) { 4114 $this->maj_ticks_pos[$j] = round($abs_pos); 4115 $this->maj_ticklabels_pos[$j] = round($abs_pos); 4116 $this->maj_ticks_label[$j]=$this->_doLabelFormat($label,$j,$nbrmajticks); 4117 ++$j; 4118 } 4119 ++$i; 4120 $abs_pos += $min_step_abs; 4121 $label += $this->minor_step; 4122 } 4123 } 4124 } 4396 $maj_step_abs = $aScale->scale_factor*$this->major_step; 4397 $min_step_abs = $aScale->scale_factor*$this->minor_step; 4398 4399 if( $min_step_abs==0 || $maj_step_abs==0 ) { 4400 JpGraphError::RaiseL(25068);//("A plot has an illegal scale. This could for example be that you are trying to use text autoscaling to draw a line plot with only one point or that the plot area is too small. It could also be that no input data value is numeric (perhaps only '-' or 'x')"); 4401 } 4402 // We need to make this an int since comparing it below 4403 // with the result from round() can give wrong result, such that 4404 // (40 < 40) == TRUE !!! 4405 $limit = (int)$aScale->scale_abs[1]; 4406 4407 if( $aScale->textscale ) { 4408 // This can only be true for a X-scale (horizontal) 4409 // Define ticks for a text scale. This is slightly different from a 4410 // normal linear type of scale since the position might be adjusted 4411 // and the labels start at on 4412 $label = (float)$aScale->GetMinVal()+$this->text_label_start+$this->label_offset; 4413 $start_abs=$aScale->scale_factor*$this->text_label_start; 4414 $nbrmajticks=round(($aScale->GetMaxVal()-$aScale->GetMinVal()-$this->text_label_start )/$this->major_step)+1; 4415 4416 $x = $aScale->scale_abs[0]+$start_abs+$this->xlabel_offset*$min_step_abs; 4417 for( $i=0; $label <= $aScale->GetMaxVal()+$this->label_offset; ++$i ) { 4418 // Apply format to label 4419 $this->maj_ticks_label[$i]=$this->_doLabelFormat($label,$i,$nbrmajticks); 4420 $label+=$this->major_step; 4421 4422 // The x-position of the tick marks can be different from the labels. 4423 // Note that we record the tick position (not the label) so that the grid 4424 // happen upon tick marks and not labels. 4425 $xtick=$aScale->scale_abs[0]+$start_abs+$this->xtick_offset*$min_step_abs+$i*$maj_step_abs; 4426 $this->maj_ticks_pos[$i]=$xtick; 4427 $this->maj_ticklabels_pos[$i] = round($x); 4428 $x += $maj_step_abs; 4429 } 4430 } 4431 else { 4432 $label = $aScale->GetMinVal(); 4433 $abs_pos = $aScale->scale_abs[0]; 4434 $j=0; $i=0; 4435 $step = round($maj_step_abs/$min_step_abs); 4436 if( $aScale->type == "x" ) { 4437 // For a normal linear type of scale the major ticks will always be multiples 4438 // of the minor ticks. In order to avoid any rounding issues the major ticks are 4439 // defined as every "step" minor ticks and not calculated separately 4440 $nbrmajticks=round(($aScale->GetMaxVal()-$aScale->GetMinVal()-$this->text_label_start )/$this->major_step)+1; 4441 while( round($abs_pos) <= $limit ) { 4442 $this->ticks_pos[] = round($abs_pos); 4443 $this->ticks_label[] = $label; 4444 if( $step== 0 || $i % $step == 0 && $j < $nbrmajticks ) { 4445 $this->maj_ticks_pos[$j] = round($abs_pos); 4446 $this->maj_ticklabels_pos[$j] = round($abs_pos); 4447 $this->maj_ticks_label[$j]=$this->_doLabelFormat($label,$j,$nbrmajticks); 4448 ++$j; 4449 } 4450 ++$i; 4451 $abs_pos += $min_step_abs; 4452 $label+=$this->minor_step; 4453 } 4454 } 4455 elseif( $aScale->type == "y" ) { 4456 //@todo s=2:20,12 s=1:50,6 $this->major_step:$nbr 4457 // abs_point,limit s=1:270,80 s=2:540,160 4458 // $this->major_step = 50; 4459 $nbrmajticks=round(($aScale->GetMaxVal()-$aScale->GetMinVal())/$this->major_step)+1; 4460 // $step = 5; 4461 while( round($abs_pos) >= $limit ) { 4462 $this->ticks_pos[$i] = round($abs_pos); 4463 $this->ticks_label[$i]=$label; 4464 if( $step== 0 || $i % $step == 0 && $j < $nbrmajticks) { 4465 $this->maj_ticks_pos[$j] = round($abs_pos); 4466 $this->maj_ticklabels_pos[$j] = round($abs_pos); 4467 $this->maj_ticks_label[$j]=$this->_doLabelFormat($label,$j,$nbrmajticks); 4468 ++$j; 4469 } 4470 ++$i; 4471 $abs_pos += $min_step_abs; 4472 $label += $this->minor_step; 4473 } 4474 } 4475 } 4125 4476 } 4126 4477 4127 4478 function AdjustForDST($aFlg=true) { 4128 4479 $this->iAdjustForDST = $aFlg; 4129 4480 } 4130 4481 … … 4132 4483 function _doLabelFormat($aVal,$aIdx,$aNbrTicks) { 4133 4484 4134 // If precision hasn't been specified set it to a sensible value 4135 if( $this->precision==-1 ) { 4136 $t = log10($this->minor_step); 4137 if( $t > 0 ) 4138 $precision = 0; 4139 else 4140 $precision = -floor($t); 4141 } 4142 else 4143 $precision = $this->precision; 4144 4145 if( $this->label_formfunc != '' ) { 4146 $f=$this->label_formfunc; 4147 $l = call_user_func($f,$aVal); 4148 } 4149 elseif( $this->label_formatstr != '' || $this->label_dateformatstr != '' ) { 4150 if( $this->label_usedateformat ) { 4151 // Adjust the value to take daylight savings into account 4152 if (date("I",$aVal)==1 && $this->iAdjustForDST ) // DST 4153 $aVal+=3600; 4154 4155 $l = date($this->label_formatstr,$aVal); 4156 if( $this->label_formatstr == 'W' ) { 4157 // If we use week formatting then add a single 'w' in front of the 4158 // week number to differentiate it from dates 4159 $l = 'w'.$l; 4160 } 4161 } 4162 else { 4163 if( $this->label_dateformatstr !== '' ) { 4164 // Adjust the value to take daylight savings into account 4165 if (date("I",$aVal)==1 && $this->iAdjustForDST ) // DST 4166 $aVal+=3600; 4167 4168 $l = date($this->label_dateformatstr,$aVal); 4169 if( $this->label_formatstr == 'W' ) { 4170 // If we use week formatting then add a single 'w' in front of the 4171 // week number to differentiate it from dates 4172 $l = 'w'.$l; 4173 } 4174 } 4175 else 4176 $l = sprintf($this->label_formatstr,$aVal); 4177 } 4178 } 4179 else { 4180 $l = sprintf('%01.'.$precision.'f',round($aVal,$precision)); 4181 } 4182 4183 if( ($this->supress_zerolabel && $l==0) || ($this->supress_first && $aIdx==0) || 4184 ($this->supress_last && $aIdx==$aNbrTicks-1) ) { 4185 $l=''; 4186 } 4187 return $l; 4485 // If precision hasn't been specified set it to a sensible value 4486 if( $this->precision==-1 ) { 4487 $t = log10($this->minor_step); 4488 if( $t > 0 || $t === 0.0) { 4489 $precision = 0; 4490 } 4491 else { 4492 $precision = -floor($t); 4493 } 4494 } 4495 else { 4496 $precision = $this->precision; 4497 } 4498 4499 if( $this->label_formfunc != '' ) { 4500 $f=$this->label_formfunc; 4501 if( $this->label_formatstr == '' ) { 4502 $l = call_user_func($f,$aVal); 4503 } 4504 else { 4505 $l = sprintf($this->label_formatstr, call_user_func($f,$aVal)); 4506 } 4507 } 4508 elseif( $this->label_formatstr != '' || $this->label_dateformatstr != '' ) { 4509 if( $this->label_usedateformat ) { 4510 // Adjust the value to take daylight savings into account 4511 if (date("I",$aVal)==1 && $this->iAdjustForDST ) { 4512 // DST 4513 $aVal+=3600; 4514 } 4515 4516 $l = date($this->label_formatstr,$aVal); 4517 if( $this->label_formatstr == 'W' ) { 4518 // If we use week formatting then add a single 'w' in front of the 4519 // week number to differentiate it from dates 4520 $l = 'w'.$l; 4521 } 4522 } 4523 else { 4524 if( $this->label_dateformatstr !== '' ) { 4525 // Adjust the value to take daylight savings into account 4526 if (date("I",$aVal)==1 && $this->iAdjustForDST ) { 4527 // DST 4528 $aVal+=3600; 4529 } 4530 4531 $l = date($this->label_dateformatstr,$aVal); 4532 if( $this->label_formatstr == 'W' ) { 4533 // If we use week formatting then add a single 'w' in front of the 4534 // week number to differentiate it from dates 4535 $l = 'w'.$l; 4536 } 4537 } 4538 else { 4539 $l = sprintf($this->label_formatstr,$aVal); 4540 } 4541 } 4542 } 4543 else { 4544 $l = sprintf('%01.'.$precision.'f',round($aVal,$precision)); 4545 } 4546 4547 if( ($this->supress_zerolabel && $l==0) || ($this->supress_first && $aIdx==0) || ($this->supress_last && $aIdx==$aNbrTicks-1) ) { 4548 $l=''; 4549 } 4550 return $l; 4188 4551 } 4189 4552 4190 4553 // Stroke ticks on either X or Y axis 4191 4554 function _StrokeTicks($aImg,$aScale,$aPos) { 4192 $hor = $aScale->type == 'x'; 4193 $aImg->SetLineWeight($this->weight); 4194 4195 // We need to make this an int since comparing it below 4196 // with the result from round() can give wrong result, such that 4197 // (40 < 40) == TRUE !!! 4198 $limit = (int)$aScale->scale_abs[1]; 4199 4200 // A text scale doesn't have any minor ticks 4201 if( !$aScale->textscale ) { 4202 // Stroke minor ticks 4203 $yu = $aPos - $this->direction*$this->GetMinTickAbsSize(); 4204 $xr = $aPos + $this->direction*$this->GetMinTickAbsSize(); 4205 $n = count($this->ticks_pos); 4206 for($i=0; $i < $n; ++$i ) { 4207 if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) { 4208 if( $this->mincolor!="" ) $aImg->PushColor($this->mincolor); 4209 if( $hor ) { 4210 //if( $this->ticks_pos[$i] <= $limit ) 4211 $aImg->Line($this->ticks_pos[$i],$aPos,$this->ticks_pos[$i],$yu); 4212 } 4213 else { 4214 //if( $this->ticks_pos[$i] >= $limit ) 4215 $aImg->Line($aPos,$this->ticks_pos[$i],$xr,$this->ticks_pos[$i]); 4216 } 4217 if( $this->mincolor!="" ) $aImg->PopColor(); 4218 } 4219 } 4220 } 4221 4222 // Stroke major ticks 4223 $yu = $aPos - $this->direction*$this->GetMajTickAbsSize(); 4224 $xr = $aPos + $this->direction*$this->GetMajTickAbsSize(); 4225 $nbrmajticks=round(($aScale->GetMaxVal()-$aScale->GetMinVal()-$this->text_label_start )/$this->major_step)+1; 4226 $n = count($this->maj_ticks_pos); 4227 for($i=0; $i < $n ; ++$i ) { 4228 if(!($this->xtick_offset > 0 && $i==$nbrmajticks-1) && !$this->supress_tickmarks) { 4229 if( $this->majcolor!="" ) $aImg->PushColor($this->majcolor); 4230 if( $hor ) { 4231 //if( $this->maj_ticks_pos[$i] <= $limit ) 4232 $aImg->Line($this->maj_ticks_pos[$i],$aPos,$this->maj_ticks_pos[$i],$yu); 4233 } 4234 else { 4235 //if( $this->maj_ticks_pos[$i] >= $limit ) 4236 $aImg->Line($aPos,$this->maj_ticks_pos[$i],$xr,$this->maj_ticks_pos[$i]); 4237 } 4238 if( $this->majcolor!="" ) $aImg->PopColor(); 4239 } 4240 } 4241 4555 $hor = $aScale->type == 'x'; 4556 $aImg->SetLineWeight($this->weight); 4557 4558 // We need to make this an int since comparing it below 4559 // with the result from round() can give wrong result, such that 4560 // (40 < 40) == TRUE !!! 4561 $limit = (int)$aScale->scale_abs[1]; 4562 4563 // A text scale doesn't have any minor ticks 4564 if( !$aScale->textscale ) { 4565 // Stroke minor ticks 4566 $yu = $aPos - $this->direction*$this->GetMinTickAbsSize(); 4567 $xr = $aPos + $this->direction*$this->GetMinTickAbsSize(); 4568 $n = count($this->ticks_pos); 4569 for($i=0; $i < $n; ++$i ) { 4570 if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) { 4571 if( $this->mincolor != '') { 4572 $aImg->PushColor($this->mincolor); 4573 } 4574 if( $hor ) { 4575 //if( $this->ticks_pos[$i] <= $limit ) 4576 $aImg->Line($this->ticks_pos[$i],$aPos,$this->ticks_pos[$i],$yu); 4577 } 4578 else { 4579 //if( $this->ticks_pos[$i] >= $limit ) 4580 $aImg->Line($aPos,$this->ticks_pos[$i],$xr,$this->ticks_pos[$i]); 4581 } 4582 if( $this->mincolor != '' ) { 4583 $aImg->PopColor(); 4584 } 4585 } 4586 } 4587 } 4588 4589 // Stroke major ticks 4590 $yu = $aPos - $this->direction*$this->GetMajTickAbsSize(); 4591 $xr = $aPos + $this->direction*$this->GetMajTickAbsSize(); 4592 $nbrmajticks=round(($aScale->GetMaxVal()-$aScale->GetMinVal()-$this->text_label_start )/$this->major_step)+1; 4593 $n = count($this->maj_ticks_pos); 4594 for($i=0; $i < $n ; ++$i ) { 4595 if(!($this->xtick_offset > 0 && $i==$nbrmajticks-1) && !$this->supress_tickmarks) { 4596 if( $this->majcolor != '') { 4597 $aImg->PushColor($this->majcolor); 4598 } 4599 if( $hor ) { 4600 //if( $this->maj_ticks_pos[$i] <= $limit ) 4601 $aImg->Line($this->maj_ticks_pos[$i],$aPos,$this->maj_ticks_pos[$i],$yu); 4602 } 4603 else { 4604 //if( $this->maj_ticks_pos[$i] >= $limit ) 4605 $aImg->Line($aPos,$this->maj_ticks_pos[$i],$xr,$this->maj_ticks_pos[$i]); 4606 } 4607 if( $this->majcolor != '') { 4608 $aImg->PopColor(); 4609 } 4610 } 4611 } 4612 4242 4613 } 4243 4614 4244 4615 // Draw linear ticks 4245 4616 function Stroke($aImg,$aScale,$aPos) { 4246 if( $this->iManualTickPos != NULL ) 4247 $this->_doManualTickPos($aScale); 4248 else 4249 $this->_doAutoTickPos($aScale); 4250 $this->_StrokeTicks($aImg,$aScale,$aPos, $aScale->type == 'x' ); 4251 } 4252 4253 //--------------- 4254 // PRIVATE METHODS 4617 if( $this->iManualTickPos != NULL ) { 4618 $this->_doManualTickPos($aScale); 4619 } 4620 else { 4621 $this->_doAutoTickPos($aScale); 4622 } 4623 $this->_StrokeTicks($aImg,$aScale,$aPos, $aScale->type == 'x' ); 4624 } 4625 4626 //--------------- 4627 // PRIVATE METHODS 4255 4628 // Spoecify the offset of the displayed tick mark with the tick "space" 4256 // Legal values for $o is [0,1] used to adjust where the tick marks and label 4629 // Legal values for $o is [0,1] used to adjust where the tick marks and label 4257 4630 // should be positioned within the major tick-size 4258 4631 // $lo specifies the label offset and $to specifies the tick offset … … 4260 4633 // tick but have the labels displayed halfway under the bars. 4261 4634 function SetXLabelOffset($aLabelOff,$aTickOff=-1) { 4262 $this->xlabel_offset=$aLabelOff; 4263 if( $aTickOff==-1 ) // Same as label offset 4264 $this->xtick_offset=$aLabelOff; 4265 else 4266 $this->xtick_offset=$aTickOff; 4267 if( $aLabelOff>0 ) 4268 $this->SupressLast(); // The last tick wont fit 4635 $this->xlabel_offset=$aLabelOff; 4636 if( $aTickOff==-1 ) { 4637 // Same as label offset 4638 $this->xtick_offset=$aLabelOff; 4639 } 4640 else { 4641 $this->xtick_offset=$aTickOff; 4642 } 4643 if( $aLabelOff>0 ) { 4644 $this->SupressLast(); // The last tick wont fit 4645 } 4269 4646 } 4270 4647 4271 4648 // Which tick label should we start with? 4272 4649 function SetTextLabelStart($aTextLabelOff) { 4273 4274 } 4275 4650 $this->text_label_start=$aTextLabelOff; 4651 } 4652 4276 4653 } // Class 4277 4654 4278 4655 //=================================================== 4279 4656 // CLASS LinearScale 4280 // Description: Handle linear scaling between screen and world 4657 // Description: Handle linear scaling between screen and world 4281 4658 //=================================================== 4282 4659 class LinearScale { … … 4297 4674 public $auto_ticks=false; // When using manual scale should the ticks be automatically set? 4298 4675 public $world_abs_size; // Plot area size in pixels (Needed public in jpgraph_radar.php) 4299 public $world_size; // Plot area size in world coordinates4300 4676 public $intscale=false; // Restrict autoscale to integers 4301 4677 protected $autoscale_min=false; // Forced minimum value, auto determine max 4302 4678 protected $autoscale_max=false; // Forced maximum value, auto determine min 4303 4679 private $gracetop=0,$gracebottom=0; 4304 //--------------- 4305 // CONSTRUCTOR 4306 function LinearScale($aMin=0,$aMax=0,$aType="y") { 4307 assert($aType=="x" || $aType=="y" ); 4308 assert($aMin<=$aMax); 4309 4310 $this->type=$aType; 4311 $this->scale=array($aMin,$aMax); 4312 $this->world_size=$aMax-$aMin; 4313 $this->ticks = new LinearTicks(); 4314 } 4315 4316 //--------------- 4317 // PUBLIC METHODS 4680 4681 private $_world_size; // Plot area size in world coordinates 4682 4683 function __construct($aMin=0,$aMax=0,$aType='y') { 4684 assert($aType=='x' || $aType=='y' ); 4685 assert($aMin<=$aMax); 4686 4687 $this->type=$aType; 4688 $this->scale=array($aMin,$aMax); 4689 $this->world_size=$aMax-$aMin; 4690 $this->ticks = new LinearTicks(); 4691 } 4692 4318 4693 // Check if scale is set or if we should autoscale 4319 4694 // We should do this is either scale or ticks has not been set 4320 4695 function IsSpecified() { 4321 if( $this->GetMinVal()==$this->GetMaxVal() ) {// Scale not set4322 4323 4324 4325 } 4326 4327 // Set the minimum data value when the autoscaling is used. 4696 if( $this->GetMinVal()==$this->GetMaxVal() ) { // Scale not set 4697 return false; 4698 } 4699 return true; 4700 } 4701 4702 // Set the minimum data value when the autoscaling is used. 4328 4703 // Usefull if you want a fix minimum (like 0) but have an 4329 4704 // automatic maximum 4330 4705 function SetAutoMin($aMin) { 4331 4332 } 4333 4334 // Set the minimum data value when the autoscaling is used. 4706 $this->autoscale_min=$aMin; 4707 } 4708 4709 // Set the minimum data value when the autoscaling is used. 4335 4710 // Usefull if you want a fix minimum (like 0) but have an 4336 4711 // automatic maximum 4337 4712 function SetAutoMax($aMax) { 4338 4713 $this->autoscale_max=$aMax; 4339 4714 } 4340 4715 … … 4342 4717 // still be set automatically? 4343 4718 function SetAutoTicks($aFlag=true) { 4344 4719 $this->auto_ticks = $aFlag; 4345 4720 } 4346 4721 4347 4722 // Specify scale "grace" value (top and bottom) 4348 4723 function SetGrace($aGraceTop,$aGraceBottom=0) { 4349 if( $aGraceTop<0 || $aGraceBottom < 0 ) 4350 JpGraphError::RaiseL(25069);//(" Grace must be larger then 0"); 4351 $this->gracetop=$aGraceTop; 4352 $this->gracebottom=$aGraceBottom; 4353 } 4354 4724 if( $aGraceTop<0 || $aGraceBottom < 0 ) { 4725 JpGraphError::RaiseL(25069);//(" Grace must be larger then 0"); 4726 } 4727 $this->gracetop=$aGraceTop; 4728 $this->gracebottom=$aGraceBottom; 4729 } 4730 4355 4731 // Get the minimum value in the scale 4356 4732 function GetMinVal() { 4357 4358 } 4359 4733 return $this->scale[0]; 4734 } 4735 4360 4736 // get maximum value for scale 4361 4737 function GetMaxVal() { 4362 4363 } 4364 4365 // Specify a new min/max value for sclae 4738 return $this->scale[1]; 4739 } 4740 4741 // Specify a new min/max value for sclae 4366 4742 function Update($aImg,$aMin,$aMax) { 4367 $this->scale=array($aMin,$aMax); 4368 $this->world_size=$aMax-$aMin; 4369 $this->InitConstants($aImg); 4370 } 4371 4743 $this->scale=array($aMin,$aMax); 4744 $this->world_size=$aMax-$aMin; 4745 $this->InitConstants($aImg); 4746 } 4747 4372 4748 // Translate between world and screen 4373 4749 function Translate($aCoord) { 4374 if( !is_numeric($aCoord) ) { 4375 if( $aCoord != '' && $aCoord != '-' && $aCoord != 'x' ) 4376 JpGraphError::RaiseL(25070);//('Your data contains non-numeric values.'); 4377 return 0; 4378 } 4379 else { 4380 return $this->off+($aCoord - $this->scale[0]) * $this->scale_factor; 4381 } 4382 } 4383 4750 if( !is_numeric($aCoord) ) { 4751 if( $aCoord != '' && $aCoord != '-' && $aCoord != 'x' ) { 4752 JpGraphError::RaiseL(25070);//('Your data contains non-numeric values.'); 4753 } 4754 return 0; 4755 } 4756 else { 4757 return round($this->off+($aCoord - $this->scale[0]) * $this->scale_factor); 4758 } 4759 } 4760 4384 4761 // Relative translate (don't include offset) usefull when we just want 4385 4762 // to know the relative position (in pixels) on the axis 4386 4763 function RelTranslate($aCoord) { 4387 if( !is_numeric($aCoord) ) { 4388 if( $aCoord != '' && $aCoord != '-' && $aCoord != 'x' ) 4389 JpGraphError::RaiseL(25070);//('Your data contains non-numeric values.'); 4390 return 0; 4391 } 4392 else { 4393 return ($aCoord - $this->scale[0]) * $this->scale_factor; 4394 } 4395 } 4396 4764 if( !is_numeric($aCoord) ) { 4765 if( $aCoord != '' && $aCoord != '-' && $aCoord != 'x' ) { 4766 JpGraphError::RaiseL(25070);//('Your data contains non-numeric values.'); 4767 } 4768 return 0; 4769 } 4770 else { 4771 return ($aCoord - $this->scale[0]) * $this->scale_factor; 4772 } 4773 } 4774 4397 4775 // Restrict autoscaling to only use integers 4398 4776 function SetIntScale($aIntScale=true) { 4399 4400 } 4401 4777 $this->intscale=$aIntScale; 4778 } 4779 4402 4780 // Calculate an integer autoscale 4403 4781 function IntAutoScale($img,$min,$max,$maxsteps,$majend=true) { 4404 // Make sure limits are integers 4405 $min=floor($min); 4406 $max=ceil($max); 4407 if( abs($min-$max)==0 ) { 4408 --$min; ++$max; 4409 } 4410 $maxsteps = floor($maxsteps); 4411 4412 $gracetop=round(($this->gracetop/100.0)*abs($max-$min)); 4413 $gracebottom=round(($this->gracebottom/100.0)*abs($max-$min)); 4414 if( is_numeric($this->autoscale_min) ) { 4415 $min = ceil($this->autoscale_min); 4416 if( $min >= $max ) { 4417 JpGraphError::RaiseL(25071);//('You have specified a min value with SetAutoMin() which is larger than the maximum value used for the scale. This is not possible.'); 4418 } 4419 } 4420 4421 if( is_numeric($this->autoscale_max) ) { 4422 $max = ceil($this->autoscale_max); 4423 if( $min >= $max ) { 4424 JpGraphError::RaiseL(25072);//('You have specified a max value with SetAutoMax() which is smaller than the miminum value used for the scale. This is not possible.'); 4425 } 4426 } 4427 4428 if( abs($min-$max ) == 0 ) { 4429 ++$max; 4430 --$min; 4431 } 4432 4433 $min -= $gracebottom; 4434 $max += $gracetop; 4435 4436 // First get tickmarks as multiples of 1, 10, ... 4437 if( $majend ) { 4438 list($num1steps,$adj1min,$adj1max,$maj1step) = 4439 $this->IntCalcTicks($maxsteps,$min,$max,1); 4440 } 4441 else { 4442 $adj1min = $min; 4443 $adj1max = $max; 4444 list($num1steps,$maj1step) = 4445 $this->IntCalcTicksFreeze($maxsteps,$min,$max,1); 4446 } 4447 4448 if( abs($min-$max) > 2 ) { 4449 // Then get tick marks as 2:s 2, 20, ... 4450 if( $majend ) { 4451 list($num2steps,$adj2min,$adj2max,$maj2step) = 4452 $this->IntCalcTicks($maxsteps,$min,$max,5); 4453 } 4454 else { 4455 $adj2min = $min; 4456 $adj2max = $max; 4457 list($num2steps,$maj2step) = 4458 $this->IntCalcTicksFreeze($maxsteps,$min,$max,5); 4459 } 4460 } 4461 else { 4462 $num2steps = 10000; // Dummy high value so we don't choose this 4463 } 4464 4465 if( abs($min-$max) > 5 ) { 4466 // Then get tickmarks as 5:s 5, 50, 500, ... 4467 if( $majend ) { 4468 list($num5steps,$adj5min,$adj5max,$maj5step) = 4469 $this->IntCalcTicks($maxsteps,$min,$max,2); 4470 } 4471 else { 4472 $adj5min = $min; 4473 $adj5max = $max; 4474 list($num5steps,$maj5step) = 4475 $this->IntCalcTicksFreeze($maxsteps,$min,$max,2); 4476 } 4477 } 4478 else { 4479 $num5steps = 10000; // Dummy high value so we don't choose this 4480 } 4481 4482 // Check to see whichof 1:s, 2:s or 5:s fit better with 4483 // the requested number of major ticks 4484 $match1=abs($num1steps-$maxsteps); 4485 $match2=abs($num2steps-$maxsteps); 4486 if( !empty($maj5step) && $maj5step > 1 ) 4487 $match5=abs($num5steps-$maxsteps); 4488 else 4489 $match5=10000; // Dummy high value 4490 4491 // Compare these three values and see which is the closest match 4492 // We use a 0.6 weight to gravitate towards multiple of 5:s 4493 if( $match1 < $match2 ) { 4494 if( $match1 < $match5 ) 4495 $r=1; 4496 else 4497 $r=3; 4498 } 4499 else { 4500 if( $match2 < $match5 ) 4501 $r=2; 4502 else 4503 $r=3; 4504 } 4505 // Minsteps are always the same as maxsteps for integer scale 4506 switch( $r ) { 4507 case 1: 4508 $this->ticks->Set($maj1step,$maj1step); 4509 $this->Update($img,$adj1min,$adj1max); 4510 break; 4511 case 2: 4512 $this->ticks->Set($maj2step,$maj2step); 4513 $this->Update($img,$adj2min,$adj2max); 4514 break; 4515 case 3: 4516 $this->ticks->Set($maj5step,$maj5step); 4517 $this->Update($img,$adj5min,$adj5max); 4518 break; 4519 default: 4520 JpGraphError::RaiseL(25073,$r);//('Internal error. Integer scale algorithm comparison out of bound (r=$r)'); 4521 } 4522 } 4523 4524 4782 // Make sure limits are integers 4783 $min=floor($min); 4784 $max=ceil($max); 4785 if( abs($min-$max)==0 ) { 4786 --$min; ++$max; 4787 } 4788 $maxsteps = floor($maxsteps); 4789 4790 $gracetop=round(($this->gracetop/100.0)*abs($max-$min)); 4791 $gracebottom=round(($this->gracebottom/100.0)*abs($max-$min)); 4792 if( is_numeric($this->autoscale_min) ) { 4793 $min = ceil($this->autoscale_min); 4794 if( $min >= $max ) { 4795 JpGraphError::RaiseL(25071);//('You have specified a min value with SetAutoMin() which is larger than the maximum value used for the scale. This is not possible.'); 4796 } 4797 } 4798 4799 if( is_numeric($this->autoscale_max) ) { 4800 $max = ceil($this->autoscale_max); 4801 if( $min >= $max ) { 4802 JpGraphError::RaiseL(25072);//('You have specified a max value with SetAutoMax() which is smaller than the miminum value used for the scale. This is not possible.'); 4803 } 4804 } 4805 4806 if( abs($min-$max ) == 0 ) { 4807 ++$max; 4808 --$min; 4809 } 4810 4811 $min -= $gracebottom; 4812 $max += $gracetop; 4813 4814 // First get tickmarks as multiples of 1, 10, ... 4815 if( $majend ) { 4816 list($num1steps,$adj1min,$adj1max,$maj1step) = $this->IntCalcTicks($maxsteps,$min,$max,1); 4817 } 4818 else { 4819 $adj1min = $min; 4820 $adj1max = $max; 4821 list($num1steps,$maj1step) = $this->IntCalcTicksFreeze($maxsteps,$min,$max,1); 4822 } 4823 4824 if( abs($min-$max) > 2 ) { 4825 // Then get tick marks as 2:s 2, 20, ... 4826 if( $majend ) { 4827 list($num2steps,$adj2min,$adj2max,$maj2step) = $this->IntCalcTicks($maxsteps,$min,$max,5); 4828 } 4829 else { 4830 $adj2min = $min; 4831 $adj2max = $max; 4832 list($num2steps,$maj2step) = $this->IntCalcTicksFreeze($maxsteps,$min,$max,5); 4833 } 4834 } 4835 else { 4836 $num2steps = 10000; // Dummy high value so we don't choose this 4837 } 4838 4839 if( abs($min-$max) > 5 ) { 4840 // Then get tickmarks as 5:s 5, 50, 500, ... 4841 if( $majend ) { 4842 list($num5steps,$adj5min,$adj5max,$maj5step) = $this->IntCalcTicks($maxsteps,$min,$max,2); 4843 } 4844 else { 4845 $adj5min = $min; 4846 $adj5max = $max; 4847 list($num5steps,$maj5step) = $this->IntCalcTicksFreeze($maxsteps,$min,$max,2); 4848 } 4849 } 4850 else { 4851 $num5steps = 10000; // Dummy high value so we don't choose this 4852 } 4853 4854 // Check to see whichof 1:s, 2:s or 5:s fit better with 4855 // the requested number of major ticks 4856 $match1=abs($num1steps-$maxsteps); 4857 $match2=abs($num2steps-$maxsteps); 4858 if( !empty($maj5step) && $maj5step > 1 ) { 4859 $match5=abs($num5steps-$maxsteps); 4860 } 4861 else { 4862 $match5=10000; // Dummy high value 4863 } 4864 4865 // Compare these three values and see which is the closest match 4866 // We use a 0.6 weight to gravitate towards multiple of 5:s 4867 if( $match1 < $match2 ) { 4868 if( $match1 < $match5 ) $r=1; 4869 else $r=3; 4870 } 4871 else { 4872 if( $match2 < $match5 ) $r=2; 4873 else $r=3; 4874 } 4875 // Minsteps are always the same as maxsteps for integer scale 4876 switch( $r ) { 4877 case 1: 4878 $this->ticks->Set($maj1step,$maj1step); 4879 $this->Update($img,$adj1min,$adj1max); 4880 break; 4881 case 2: 4882 $this->ticks->Set($maj2step,$maj2step); 4883 $this->Update($img,$adj2min,$adj2max); 4884 break; 4885 case 3: 4886 $this->ticks->Set($maj5step,$maj5step); 4887 $this->Update($img,$adj5min,$adj5max); 4888 break; 4889 default: 4890 JpGraphError::RaiseL(25073,$r);//('Internal error. Integer scale algorithm comparison out of bound (r=$r)'); 4891 } 4892 } 4893 4894 4525 4895 // Calculate autoscale. Used if user hasn't given a scale and ticks 4526 4896 // $maxsteps is the maximum number of major tickmarks allowed. 4527 4897 function AutoScale($img,$min,$max,$maxsteps,$majend=true) { 4528 if( $this->intscale ) { 4529 $this->IntAutoScale($img,$min,$max,$maxsteps,$majend); 4530 return; 4531 } 4532 if( abs($min-$max) < 0.00001 ) { 4533 // We need some difference to be able to autoscale 4534 // make it 5% above and 5% below value 4535 if( $min==0 && $max==0 ) { // Special case 4536 $min=-1; $max=1; 4537 } 4538 else { 4539 $delta = (abs($max)+abs($min))*0.005; 4540 $min -= $delta; 4541 $max += $delta; 4542 } 4543 } 4544 4545 $gracetop=($this->gracetop/100.0)*abs($max-$min); 4546 $gracebottom=($this->gracebottom/100.0)*abs($max-$min); 4547 if( is_numeric($this->autoscale_min) ) { 4548 $min = $this->autoscale_min; 4549 if( $min >= $max ) { 4550 JpGraphError::RaiseL(25071);//('You have specified a min value with SetAutoMin() which is larger than the maximum value used for the scale. This is not possible.'); 4551 } 4552 if( abs($min-$max ) < 0.00001 ) 4553 $max *= 1.2; 4554 } 4555 4556 if( is_numeric($this->autoscale_max) ) { 4557 $max = $this->autoscale_max; 4558 if( $min >= $max ) { 4559 JpGraphError::RaiseL(25072);//('You have specified a max value with SetAutoMax() which is smaller than the miminum value used for the scale. This is not possible.'); 4560 } 4561 if( abs($min-$max ) < 0.00001 ) 4562 $min *= 0.8; 4563 } 4564 4565 $min -= $gracebottom; 4566 $max += $gracetop; 4567 4568 4569 // First get tickmarks as multiples of 0.1, 1, 10, ... 4570 if( $majend ) { 4571 list($num1steps,$adj1min,$adj1max,$min1step,$maj1step) = 4572 $this->CalcTicks($maxsteps,$min,$max,1,2); 4573 } 4574 else { 4575 $adj1min=$min; 4576 $adj1max=$max; 4577 list($num1steps,$min1step,$maj1step) = 4578 $this->CalcTicksFreeze($maxsteps,$min,$max,1,2,false); 4579 } 4580 4581 // Then get tick marks as 2:s 0.2, 2, 20, ... 4582 if( $majend ) { 4583 list($num2steps,$adj2min,$adj2max,$min2step,$maj2step) = 4584 $this->CalcTicks($maxsteps,$min,$max,5,2); 4585 } 4586 else { 4587 $adj2min=$min; 4588 $adj2max=$max; 4589 list($num2steps,$min2step,$maj2step) = 4590 $this->CalcTicksFreeze($maxsteps,$min,$max,5,2,false); 4591 } 4592 4593 // Then get tickmarks as 5:s 0.05, 0.5, 5, 50, ... 4594 if( $majend ) { 4595 list($num5steps,$adj5min,$adj5max,$min5step,$maj5step) = 4596 $this->CalcTicks($maxsteps,$min,$max,2,5); 4597 } 4598 else { 4599 $adj5min=$min; 4600 $adj5max=$max; 4601 list($num5steps,$min5step,$maj5step) = 4602 $this->CalcTicksFreeze($maxsteps,$min,$max,2,5,false); 4603 } 4604 4605 // Check to see whichof 1:s, 2:s or 5:s fit better with 4606 // the requested number of major ticks 4607 $match1=abs($num1steps-$maxsteps); 4608 $match2=abs($num2steps-$maxsteps); 4609 $match5=abs($num5steps-$maxsteps); 4610 // Compare these three values and see which is the closest match 4611 // We use a 0.8 weight to gravitate towards multiple of 5:s 4612 $r=$this->MatchMin3($match1,$match2,$match5,0.8); 4613 switch( $r ) { 4614 case 1: 4615 $this->Update($img,$adj1min,$adj1max); 4616 $this->ticks->Set($maj1step,$min1step); 4617 break; 4618 case 2: 4619 $this->Update($img,$adj2min,$adj2max); 4620 $this->ticks->Set($maj2step,$min2step); 4621 break; 4622 case 3: 4623 $this->Update($img,$adj5min,$adj5max); 4624 $this->ticks->Set($maj5step,$min5step); 4625 break; 4626 } 4627 } 4628 4629 //--------------- 4630 // PRIVATE METHODS 4898 4899 if( !is_numeric($min) || !is_numeric($max) ) { 4900 JpGraphError::Raise(25044); 4901 } 4902 4903 if( $this->intscale ) { 4904 $this->IntAutoScale($img,$min,$max,$maxsteps,$majend); 4905 return; 4906 } 4907 if( abs($min-$max) < 0.00001 ) { 4908 // We need some difference to be able to autoscale 4909 // make it 5% above and 5% below value 4910 if( $min==0 && $max==0 ) { // Special case 4911 $min=-1; $max=1; 4912 } 4913 else { 4914 $delta = (abs($max)+abs($min))*0.005; 4915 $min -= $delta; 4916 $max += $delta; 4917 } 4918 } 4919 4920 $gracetop=($this->gracetop/100.0)*abs($max-$min); 4921 $gracebottom=($this->gracebottom/100.0)*abs($max-$min); 4922 if( is_numeric($this->autoscale_min) ) { 4923 $min = $this->autoscale_min; 4924 if( $min >= $max ) { 4925 JpGraphError::RaiseL(25071);//('You have specified a min value with SetAutoMin() which is larger than the maximum value used for the scale. This is not possible.'); 4926 } 4927 if( abs($min-$max ) < 0.001 ) { 4928 $max *= 1.2; 4929 } 4930 } 4931 4932 if( is_numeric($this->autoscale_max) ) { 4933 $max = $this->autoscale_max; 4934 if( $min >= $max ) { 4935 JpGraphError::RaiseL(25072);//('You have specified a max value with SetAutoMax() which is smaller than the miminum value used for the scale. This is not possible.'); 4936 } 4937 if( abs($min-$max ) < 0.001 ) { 4938 $min *= 0.8; 4939 } 4940 } 4941 4942 $min -= $gracebottom; 4943 $max += $gracetop; 4944 4945 // First get tickmarks as multiples of 0.1, 1, 10, ... 4946 if( $majend ) { 4947 list($num1steps,$adj1min,$adj1max,$min1step,$maj1step) = $this->CalcTicks($maxsteps,$min,$max,1,2); 4948 } 4949 else { 4950 $adj1min=$min; 4951 $adj1max=$max; 4952 list($num1steps,$min1step,$maj1step) = $this->CalcTicksFreeze($maxsteps,$min,$max,1,2,false); 4953 } 4954 4955 // Then get tick marks as 2:s 0.2, 2, 20, ... 4956 if( $majend ) { 4957 list($num2steps,$adj2min,$adj2max,$min2step,$maj2step) = $this->CalcTicks($maxsteps,$min,$max,5,2); 4958 } 4959 else { 4960 $adj2min=$min; 4961 $adj2max=$max; 4962 list($num2steps,$min2step,$maj2step) = $this->CalcTicksFreeze($maxsteps,$min,$max,5,2,false); 4963 } 4964 4965 // Then get tickmarks as 5:s 0.05, 0.5, 5, 50, ... 4966 if( $majend ) { 4967 list($num5steps,$adj5min,$adj5max,$min5step,$maj5step) = $this->CalcTicks($maxsteps,$min,$max,2,5); 4968 } 4969 else { 4970 $adj5min=$min; 4971 $adj5max=$max; 4972 list($num5steps,$min5step,$maj5step) = $this->CalcTicksFreeze($maxsteps,$min,$max,2,5,false); 4973 } 4974 4975 // Check to see whichof 1:s, 2:s or 5:s fit better with 4976 // the requested number of major ticks 4977 $match1=abs($num1steps-$maxsteps); 4978 $match2=abs($num2steps-$maxsteps); 4979 $match5=abs($num5steps-$maxsteps); 4980 4981 // Compare these three values and see which is the closest match 4982 // We use a 0.8 weight to gravitate towards multiple of 5:s 4983 $r=$this->MatchMin3($match1,$match2,$match5,0.8); 4984 switch( $r ) { 4985 case 1: 4986 $this->Update($img,$adj1min,$adj1max); 4987 $this->ticks->Set($maj1step,$min1step); 4988 break; 4989 case 2: 4990 $this->Update($img,$adj2min,$adj2max); 4991 $this->ticks->Set($maj2step,$min2step); 4992 break; 4993 case 3: 4994 $this->Update($img,$adj5min,$adj5max); 4995 $this->ticks->Set($maj5step,$min5step); 4996 break; 4997 } 4998 } 4999 5000 //--------------- 5001 // PRIVATE METHODS 4631 5002 4632 5003 // This method recalculates all constants that are depending on the … … 4635 5006 // that image. Should really be installed as an observer of that image. 4636 5007 function InitConstants($img) { 4637 if( $this->type=="x" ) { 4638 $this->world_abs_size=$img->width - $img->left_margin - $img->right_margin; 4639 $this->off=$img->left_margin; 4640 $this->scale_factor = 0; 4641 if( $this->world_size > 0 ) 4642 $this->scale_factor=$this->world_abs_size/($this->world_size*1.0); 4643 } 4644 else { // y scale 4645 $this->world_abs_size=$img->height - $img->top_margin - $img->bottom_margin; 4646 $this->off=$img->top_margin+$this->world_abs_size; 4647 $this->scale_factor = 0; 4648 if( $this->world_size > 0 ) 4649 $this->scale_factor=-$this->world_abs_size/($this->world_size*1.0); 4650 } 4651 $size = $this->world_size * $this->scale_factor; 4652 $this->scale_abs=array($this->off,$this->off + $size); 4653 } 4654 5008 if( $this->type=='x' ) { 5009 $this->world_abs_size=$img->width - $img->left_margin - $img->right_margin; 5010 $this->off=$img->left_margin; 5011 $this->scale_factor = 0; 5012 if( $this->world_size > 0 ) { 5013 $this->scale_factor=$this->world_abs_size/($this->world_size*0.999999); 5014 } 5015 } 5016 else { // y scale 5017 $this->world_abs_size=$img->height - $img->top_margin - $img->bottom_margin; 5018 $this->off=$img->top_margin+$this->world_abs_size; 5019 $this->scale_factor = 0; 5020 if( $this->world_size > 0 ) { 5021 $this->scale_factor=-$this->world_abs_size/($this->world_size*0.999999); 5022 } 5023 } 5024 $size = $this->world_size * $this->scale_factor; 5025 $this->scale_abs=array($this->off,$this->off + $size); 5026 } 5027 4655 5028 // Initialize the conversion constants for this scale 4656 5029 // This tries to pre-calculate as much as possible to speed up the 4657 5030 // actual conversion (with Translate()) later on 4658 // $start 4659 // 4660 // $len =absolute length in pixels of scale5031 // $start =scale start in absolute pixels (for x-scale this is an y-position 5032 // and for an y-scale this is an x-position 5033 // $len =absolute length in pixels of scale 4661 5034 function SetConstants($aStart,$aLen) { 4662 $this->world_abs_size=$aLen; 4663 $this->off=$aStart; 4664 4665 if( $this->world_size<=0 ) { 4666 // This should never ever happen !! 4667 JpGraphError::RaiseL(25074); 4668 //("You have unfortunately stumbled upon a bug in JpGraph. It seems like the scale range is ".$this->world_size." [for ".$this->type." scale] <br> Please report Bug #01 to jpgraph@aditus.nu and include the script that gave this error. This problem could potentially be caused by trying to use \"illegal\" values in the input data arrays (like trying to send in strings or only NULL values) which causes the autoscaling to fail."); 4669 4670 } 4671 4672 // scale_factor = number of pixels per world unit 4673 $this->scale_factor=$this->world_abs_size/($this->world_size*1.0); 4674 4675 // scale_abs = start and end points of scale in absolute pixels 4676 $this->scale_abs=array($this->off,$this->off+$this->world_size*$this->scale_factor); 4677 } 4678 4679 5035 $this->world_abs_size=$aLen; 5036 $this->off=$aStart; 5037 5038 if( $this->world_size<=0 ) { 5039 // This should never ever happen !! 5040 JpGraphError::RaiseL(25074); 5041 //("You have unfortunately stumbled upon a bug in JpGraph. It seems like the scale range is ".$this->world_size." [for ".$this->type." scale] <br> Please report Bug #01 to info@jpgraph.net and include the script that gave this error. This problem could potentially be caused by trying to use \"illegal\" values in the input data arrays (like trying to send in strings or only NULL values) which causes the autoscaling to fail."); 5042 } 5043 5044 // scale_factor = number of pixels per world unit 5045 $this->scale_factor=$this->world_abs_size/($this->world_size*1.0); 5046 5047 // scale_abs = start and end points of scale in absolute pixels 5048 $this->scale_abs=array($this->off,$this->off+$this->world_size*$this->scale_factor); 5049 } 5050 5051 4680 5052 // Calculate number of ticks steps with a specific division 4681 5053 // $a is the divisor of 10**x to generate the first maj tick intervall … … 4684 5056 // $a=2, $b=5 give major ticks with multiple of 5:s ...,0.5,5,50,... 4685 5057 // We return a vector of 4686 // 5058 // [$numsteps,$adjmin,$adjmax,$minstep,$majstep] 4687 5059 // If $majend==true then the first and last marks on the axis will be major 4688 5060 // labeled tick marks otherwise it will be adjusted to the closest min tick mark 4689 5061 function CalcTicks($maxsteps,$min,$max,$a,$b,$majend=true) { 4690 $diff=$max-$min; 4691 if( $diff==0 ) 4692 $ld=0; 4693 else 4694 $ld=floor(log10($diff)); 4695 4696 // Gravitate min towards zero if we are close 4697 if( $min>0 && $min < pow(10,$ld) ) $min=0; 4698 4699 //$majstep=pow(10,$ld-1)/$a; 4700 $majstep=pow(10,$ld)/$a; 4701 $minstep=$majstep/$b; 4702 4703 $adjmax=ceil($max/$minstep)*$minstep; 4704 $adjmin=floor($min/$minstep)*$minstep; 4705 $adjdiff = $adjmax-$adjmin; 4706 $numsteps=$adjdiff/$majstep; 4707 4708 while( $numsteps>$maxsteps ) { 4709 $majstep=pow(10,$ld)/$a; 4710 $numsteps=$adjdiff/$majstep; 4711 ++$ld; 4712 } 4713 4714 $minstep=$majstep/$b; 4715 $adjmin=floor($min/$minstep)*$minstep; 4716 $adjdiff = $adjmax-$adjmin; 4717 if( $majend ) { 4718 $adjmin = floor($min/$majstep)*$majstep; 4719 $adjdiff = $adjmax-$adjmin; 4720 $adjmax = ceil($adjdiff/$majstep)*$majstep+$adjmin; 4721 } 4722 else 4723 $adjmax=ceil($max/$minstep)*$minstep; 4724 4725 return array($numsteps,$adjmin,$adjmax,$minstep,$majstep); 5062 $diff=$max-$min; 5063 if( $diff==0 ) { 5064 $ld=0; 5065 } 5066 else { 5067 $ld=floor(log10($diff)); 5068 } 5069 5070 // Gravitate min towards zero if we are close 5071 if( $min>0 && $min < pow(10,$ld) ) $min=0; 5072 5073 //$majstep=pow(10,$ld-1)/$a; 5074 $majstep=pow(10,$ld)/$a; 5075 $minstep=$majstep/$b; 5076 5077 $adjmax=ceil($max/$minstep)*$minstep; 5078 $adjmin=floor($min/$minstep)*$minstep; 5079 $adjdiff = $adjmax-$adjmin; 5080 $numsteps=$adjdiff/$majstep; 5081 5082 while( $numsteps>$maxsteps ) { 5083 $majstep=pow(10,$ld)/$a; 5084 $numsteps=$adjdiff/$majstep; 5085 ++$ld; 5086 } 5087 5088 $minstep=$majstep/$b; 5089 $adjmin=floor($min/$minstep)*$minstep; 5090 $adjdiff = $adjmax-$adjmin; 5091 if( $majend ) { 5092 $adjmin = floor($min/$majstep)*$majstep; 5093 $adjdiff = $adjmax-$adjmin; 5094 $adjmax = ceil($adjdiff/$majstep)*$majstep+$adjmin; 5095 } 5096 else { 5097 $adjmax=ceil($max/$minstep)*$minstep; 5098 } 5099 5100 return array($numsteps,$adjmin,$adjmax,$minstep,$majstep); 4726 5101 } 4727 5102 4728 5103 function CalcTicksFreeze($maxsteps,$min,$max,$a,$b) { 4729 // Same as CalcTicks but don't adjust min/max values 4730 $diff=$max-$min; 4731 if( $diff==0 ) 4732 $ld=0; 4733 else 4734 $ld=floor(log10($diff)); 4735 4736 //$majstep=pow(10,$ld-1)/$a; 4737 $majstep=pow(10,$ld)/$a; 4738 $minstep=$majstep/$b; 4739 $numsteps=floor($diff/$majstep); 4740 4741 while( $numsteps > $maxsteps ) { 4742 $majstep=pow(10,$ld)/$a; 4743 $numsteps=floor($diff/$majstep); 4744 ++$ld; 4745 } 4746 $minstep=$majstep/$b; 4747 return array($numsteps,$minstep,$majstep); 4748 } 4749 4750 5104 // Same as CalcTicks but don't adjust min/max values 5105 $diff=$max-$min; 5106 if( $diff==0 ) { 5107 $ld=0; 5108 } 5109 else { 5110 $ld=floor(log10($diff)); 5111 } 5112 5113 //$majstep=pow(10,$ld-1)/$a; 5114 $majstep=pow(10,$ld)/$a; 5115 $minstep=$majstep/$b; 5116 $numsteps=floor($diff/$majstep); 5117 5118 while( $numsteps > $maxsteps ) { 5119 $majstep=pow(10,$ld)/$a; 5120 $numsteps=floor($diff/$majstep); 5121 ++$ld; 5122 } 5123 $minstep=$majstep/$b; 5124 return array($numsteps,$minstep,$majstep); 5125 } 5126 5127 4751 5128 function IntCalcTicks($maxsteps,$min,$max,$a,$majend=true) { 4752 $diff=$max-$min; 4753 if( $diff==0 ) 4754 JpGraphError::RaiseL(25075);//('Can\'t automatically determine ticks since min==max.'); 4755 else 4756 $ld=floor(log10($diff)); 4757 4758 // Gravitate min towards zero if we are close 4759 if( $min>0 && $min < pow(10,$ld) ) $min=0; 4760 4761 if( $ld == 0 ) $ld=1; 4762 4763 if( $a == 1 ) 4764 $majstep = 1; 4765 else 4766 $majstep=pow(10,$ld)/$a; 4767 $adjmax=ceil($max/$majstep)*$majstep; 4768 4769 $adjmin=floor($min/$majstep)*$majstep; 4770 $adjdiff = $adjmax-$adjmin; 4771 $numsteps=$adjdiff/$majstep; 4772 while( $numsteps>$maxsteps ) { 4773 $majstep=pow(10,$ld)/$a; 4774 $numsteps=$adjdiff/$majstep; 4775 ++$ld; 4776 } 4777 4778 $adjmin=floor($min/$majstep)*$majstep; 4779 $adjdiff = $adjmax-$adjmin; 4780 if( $majend ) { 4781 $adjmin = floor($min/$majstep)*$majstep; 4782 $adjdiff = $adjmax-$adjmin; 4783 $adjmax = ceil($adjdiff/$majstep)*$majstep+$adjmin; 4784 } 4785 else 4786 $adjmax=ceil($max/$majstep)*$majstep; 4787 4788 return array($numsteps,$adjmin,$adjmax,$majstep); 5129 $diff=$max-$min; 5130 if( $diff==0 ) { 5131 JpGraphError::RaiseL(25075);//('Can\'t automatically determine ticks since min==max.'); 5132 } 5133 else { 5134 $ld=floor(log10($diff)); 5135 } 5136 5137 // Gravitate min towards zero if we are close 5138 if( $min>0 && $min < pow(10,$ld) ) { 5139 $min=0; 5140 } 5141 if( $ld == 0 ) { 5142 $ld=1; 5143 } 5144 if( $a == 1 ) { 5145 $majstep = 1; 5146 } 5147 else { 5148 $majstep=pow(10,$ld)/$a; 5149 } 5150 $adjmax=ceil($max/$majstep)*$majstep; 5151 5152 $adjmin=floor($min/$majstep)*$majstep; 5153 $adjdiff = $adjmax-$adjmin; 5154 $numsteps=$adjdiff/$majstep; 5155 while( $numsteps>$maxsteps ) { 5156 $majstep=pow(10,$ld)/$a; 5157 $numsteps=$adjdiff/$majstep; 5158 ++$ld; 5159 } 5160 5161 $adjmin=floor($min/$majstep)*$majstep; 5162 $adjdiff = $adjmax-$adjmin; 5163 if( $majend ) { 5164 $adjmin = floor($min/$majstep)*$majstep; 5165 $adjdiff = $adjmax-$adjmin; 5166 $adjmax = ceil($adjdiff/$majstep)*$majstep+$adjmin; 5167 } 5168 else { 5169 $adjmax=ceil($max/$majstep)*$majstep; 5170 } 5171 5172 return array($numsteps,$adjmin,$adjmax,$majstep); 4789 5173 } 4790 5174 4791 5175 4792 5176 function IntCalcTicksFreeze($maxsteps,$min,$max,$a) { 4793 // Same as IntCalcTick but don't change min/max values 4794 $diff=$max-$min; 4795 if( $diff==0 ) 4796 JpGraphError::RaiseL(25075);//('Can\'t automatically determine ticks since min==max.'); 4797 else 4798 $ld=floor(log10($diff)); 4799 4800 if( $ld == 0 ) $ld=1; 4801 4802 if( $a == 1 ) 4803 $majstep = 1; 4804 else 4805 $majstep=pow(10,$ld)/$a; 4806 4807 $numsteps=floor($diff/$majstep); 4808 while( $numsteps > $maxsteps ) { 4809 $majstep=pow(10,$ld)/$a; 4810 $numsteps=floor($diff/$majstep); 4811 ++$ld; 4812 } 4813 4814 return array($numsteps,$majstep); 4815 } 4816 4817 4818 5177 // Same as IntCalcTick but don't change min/max values 5178 $diff=$max-$min; 5179 if( $diff==0 ) { 5180 JpGraphError::RaiseL(25075);//('Can\'t automatically determine ticks since min==max.'); 5181 } 5182 else { 5183 $ld=floor(log10($diff)); 5184 } 5185 if( $ld == 0 ) { 5186 $ld=1; 5187 } 5188 if( $a == 1 ) { 5189 $majstep = 1; 5190 } 5191 else { 5192 $majstep=pow(10,$ld)/$a; 5193 } 5194 5195 $numsteps=floor($diff/$majstep); 5196 while( $numsteps > $maxsteps ) { 5197 $majstep=pow(10,$ld)/$a; 5198 $numsteps=floor($diff/$majstep); 5199 ++$ld; 5200 } 5201 5202 return array($numsteps,$majstep); 5203 } 5204 4819 5205 // Determine the minimum of three values witha weight for last value 4820 5206 function MatchMin3($a,$b,$c,$weight) { 4821 if( $a < $b ) { 4822 if( $a < ($c*$weight) ) 4823 return 1; // $a smallest 4824 else 4825 return 3; // $c smallest 4826 } 4827 elseif( $b < ($c*$weight) ) 4828 return 2; // $b smallest 4829 return 3; // $c smallest 5207 if( $a < $b ) { 5208 if( $a < ($c*$weight) ) { 5209 return 1; // $a smallest 5210 } 5211 else { 5212 return 3; // $c smallest 5213 } 5214 } 5215 elseif( $b < ($c*$weight) ) { 5216 return 2; // $b smallest 5217 } 5218 return 3; // $c smallest 5219 } 5220 5221 function __get($name) { 5222 $variable_name = '_' . $name; 5223 5224 if (isset($this->$variable_name)) { 5225 return $this->$variable_name * SUPERSAMPLING_SCALE; 5226 } else { 5227 JpGraphError::RaiseL('25132', $name); 5228 } 5229 } 5230 5231 function __set($name, $value) { 5232 $this->{'_'.$name} = $value; 4830 5233 } 4831 5234 } // Class … … 4839 5242 public $margin=5; 4840 5243 public $show=false; 4841 public $valign= "",$halign="center";4842 public $format= "%.1f",$negformat="";4843 private $ff=FF_ FONT1,$fs=FS_NORMAL,$fsize=10;5244 public $valign='',$halign='center'; 5245 public $format='%.1f',$negformat=''; 5246 private $ff=FF_DEFAULT,$fs=FS_NORMAL,$fsize=8; 4844 5247 private $iFormCallback=''; 4845 5248 private $angle=0; 4846 private $color= "navy",$negcolor="";5249 private $color='navy',$negcolor=''; 4847 5250 private $iHideZero=false; 5251 public $txt=null; 5252 5253 function __construct() { 5254 $this->txt = new Text(); 5255 } 4848 5256 4849 5257 function Show($aFlag=true) { 4850 4851 } 4852 4853 function SetColor($aColor,$aNegcolor= "") {4854 4855 4856 } 4857 4858 function SetFont($aFontFamily,$aFontStyle=FS_NORMAL,$aFontSize= 10) {4859 4860 4861 5258 $this->show=$aFlag; 5259 } 5260 5261 function SetColor($aColor,$aNegcolor='') { 5262 $this->color = $aColor; 5263 $this->negcolor = $aNegcolor; 5264 } 5265 5266 function SetFont($aFontFamily,$aFontStyle=FS_NORMAL,$aFontSize=8) { 5267 $this->ff=$aFontFamily; 5268 $this->fs=$aFontStyle; 5269 $this->fsize=$aFontSize; 4862 5270 } 4863 5271 4864 5272 function ApplyFont($aImg) { 4865 5273 $aImg->SetFont($this->ff,$this->fs,$this->fsize); 4866 5274 } 4867 5275 4868 5276 function SetMargin($aMargin) { 4869 5277 $this->margin = $aMargin; 4870 5278 } 4871 5279 4872 5280 function SetAngle($aAngle) { 4873 5281 $this->angle = $aAngle; 4874 5282 } 4875 5283 4876 5284 function SetAlign($aHAlign,$aVAlign='') { 4877 4878 4879 } 4880 4881 function SetFormat($aFormat,$aNegFormat= "") {4882 4883 5285 $this->halign = $aHAlign; 5286 $this->valign = $aVAlign; 5287 } 5288 5289 function SetFormat($aFormat,$aNegFormat='') { 5290 $this->format= $aFormat; 5291 $this->negformat= $aNegFormat; 4884 5292 } 4885 5293 4886 5294 function SetFormatCallback($aFunc) { 4887 5295 $this->iFormCallback = $aFunc; 4888 5296 } 4889 5297 4890 5298 function HideZero($aFlag=true) { 4891 5299 $this->iHideZero=$aFlag; 4892 5300 } 4893 5301 4894 5302 function Stroke($img,$aVal,$x,$y) { 4895 4896 if( $this->show ) 4897 { 4898 if( $this->negformat=="" ) $this->negformat=$this->format; 4899 if( $this->negcolor=="" ) $this->negcolor=$this->color; 4900 4901 if( $aVal===NULL || (is_string($aVal) && ($aVal=="" || $aVal=="-" || $aVal=="x" ) ) ) 4902 return; 4903 4904 if( is_numeric($aVal) && $aVal==0 && $this->iHideZero ) { 4905 return; 4906 } 4907 4908 // Since the value is used in different cirumstances we need to check what 4909 // kind of formatting we shall use. For example, to display values in a line 4910 // graph we simply display the formatted value, but in the case where the user 4911 // has already specified a text string we don't fo anything. 4912 if( $this->iFormCallback != '' ) { 4913 $f = $this->iFormCallback; 4914 $sval = call_user_func($f,$aVal); 4915 } 4916 elseif( is_numeric($aVal) ) { 4917 if( $aVal >= 0 ) 4918 $sval=sprintf($this->format,$aVal); 4919 else 4920 $sval=sprintf($this->negformat,$aVal); 4921 } 4922 else 4923 $sval=$aVal; 4924 4925 $y = $y-sign($aVal)*$this->margin; 4926 4927 $txt = new Text($sval,$x,$y); 4928 $txt->SetFont($this->ff,$this->fs,$this->fsize); 4929 if( $this->valign == "" ) { 4930 if( $aVal >= 0 ) 4931 $valign = "bottom"; 4932 else 4933 $valign = "top"; 4934 } 4935 else 4936 $valign = $this->valign; 4937 $txt->Align($this->halign,$valign); 4938 4939 $txt->SetOrientation($this->angle); 4940 if( $aVal > 0 ) 4941 $txt->SetColor($this->color); 4942 else 4943 $txt->SetColor($this->negcolor); 4944 $txt->Stroke($img); 4945 } 5303 5304 if( $this->show ) 5305 { 5306 if( $this->negformat=='' ) { 5307 $this->negformat=$this->format; 5308 } 5309 if( $this->negcolor=='' ) { 5310 $this->negcolor=$this->color; 5311 } 5312 5313 if( $aVal===NULL || (is_string($aVal) && ($aVal=='' || $aVal=='-' || $aVal=='x' ) ) ) { 5314 return; 5315 } 5316 5317 if( is_numeric($aVal) && $aVal==0 && $this->iHideZero ) { 5318 return; 5319 } 5320 5321 // Since the value is used in different cirumstances we need to check what 5322 // kind of formatting we shall use. For example, to display values in a line 5323 // graph we simply display the formatted value, but in the case where the user 5324 // has already specified a text string we don't fo anything. 5325 if( $this->iFormCallback != '' ) { 5326 $f = $this->iFormCallback; 5327 $sval = call_user_func($f,$aVal); 5328 } 5329 elseif( is_numeric($aVal) ) { 5330 if( $aVal >= 0 ) { 5331 $sval=sprintf($this->format,$aVal); 5332 } 5333 else { 5334 $sval=sprintf($this->negformat,$aVal); 5335 } 5336 } 5337 else { 5338 $sval=$aVal; 5339 } 5340 5341 $y = $y-sign($aVal)*$this->margin; 5342 5343 $this->txt->Set($sval); 5344 $this->txt->SetPos($x,$y); 5345 $this->txt->SetFont($this->ff,$this->fs,$this->fsize); 5346 if( $this->valign == '' ) { 5347 if( $aVal >= 0 ) { 5348 $valign = "bottom"; 5349 } 5350 else { 5351 $valign = "top"; 5352 } 5353 } 5354 else { 5355 $valign = $this->valign; 5356 } 5357 $this->txt->Align($this->halign,$valign); 5358 5359 $this->txt->SetOrientation($this->angle); 5360 if( $aVal > 0 ) { 5361 $this->txt->SetColor($this->color); 5362 } 5363 else { 5364 $this->txt->SetColor($this->negcolor); 5365 } 5366 $this->txt->Stroke($img); 5367 } 4946 5368 } 4947 5369 } … … 4956 5378 public $legend=''; 4957 5379 public $coords=array(); 4958 public $color= "black";5380 public $color='black'; 4959 5381 public $hidelegend=false; 4960 5382 public $line_weight=1; 4961 5383 public $csimtargets=array(),$csimwintargets=array(); // Array of targets for CSIM 4962 public $csimareas= ""; // Resultant CSIM area tags4963 public $csimalts=null; 5384 public $csimareas=''; // Resultant CSIM area tags 5385 public $csimalts=null; // ALT:s for corresponding target 4964 5386 public $legendcsimtarget='',$legendcsimwintarget=''; 4965 5387 public $legendcsimalt=''; 4966 protected $weight=1; 5388 protected $weight=1; 4967 5389 protected $center=false; 4968 //--------------- 4969 // CONSTRUCTOR 4970 function Plot($aDatay,$aDatax=false) { 4971 $this->numpoints = count($aDatay); 4972 if( $this->numpoints==0 ) 4973 JpGraphError::RaiseL(25121);//("Empty input data array specified for plot. Must have at least one data point."); 4974 $this->coords[0]=$aDatay; 4975 if( is_array($aDatax) ) { 4976 $this->coords[1]=$aDatax; 4977 $n = count($aDatax); 4978 for($i=0; $i < $n; ++$i ) { 4979 if( !is_numeric($aDatax[$i]) ) { 4980 JpGraphError::RaiseL(25070); 4981 } 4982 } 4983 } 4984 $this->value = new DisplayValue(); 4985 } 4986 4987 //--------------- 4988 // PUBLIC METHODS 5390 5391 protected $inputValues; 5392 protected $isRunningClear = false; 5393 5394 function __construct($aDatay,$aDatax=false) { 5395 $this->numpoints = count($aDatay); 5396 if( $this->numpoints==0 ) { 5397 JpGraphError::RaiseL(25121);//("Empty input data array specified for plot. Must have at least one data point."); 5398 } 5399 5400 if (!$this->isRunningClear) { 5401 $this->inputValues = array(); 5402 $this->inputValues['aDatay'] = $aDatay; 5403 $this->inputValues['aDatax'] = $aDatax; 5404 } 5405 5406 $this->coords[0]=$aDatay; 5407 if( is_array($aDatax) ) { 5408 $this->coords[1]=$aDatax; 5409 $n = count($aDatax); 5410 for( $i=0; $i < $n; ++$i ) { 5411 if( !is_numeric($aDatax[$i]) ) { 5412 JpGraphError::RaiseL(25070); 5413 } 5414 } 5415 } 5416 $this->value = new DisplayValue(); 5417 } 4989 5418 4990 5419 // Stroke the plot … … 4992 5421 // the subclasses 4993 5422 function Stroke($aImg,$aXScale,$aYScale) { 4994 5423 JpGraphError::RaiseL(25122);//("JpGraph: Stroke() must be implemented by concrete subclass to class Plot"); 4995 5424 } 4996 5425 4997 5426 function HideLegend($f=true) { 4998 5427 $this->hidelegend = $f; 4999 5428 } 5000 5429 5001 5430 function DoLegend($graph) { 5002 5003 5431 if( !$this->hidelegend ) 5432 $this->Legend($graph); 5004 5433 } 5005 5434 5006 5435 function StrokeDataValue($img,$aVal,$x,$y) { 5007 5008 } 5009 5010 // Set href targets for CSIM 5436 $this->value->Stroke($img,$aVal,$x,$y); 5437 } 5438 5439 // Set href targets for CSIM 5011 5440 function SetCSIMTargets($aTargets,$aAlts='',$aWinTargets='') { 5012 5013 5014 $this->csimalts=$aAlts; 5015 } 5016 5441 $this->csimtargets=$aTargets; 5442 $this->csimwintargets=$aWinTargets; 5443 $this->csimalts=$aAlts; 5444 } 5445 5017 5446 // Get all created areas 5018 5447 function GetCSIMareas() { 5019 5020 } 5021 5448 return $this->csimareas; 5449 } 5450 5022 5451 // "Virtual" function which gets called before any scale 5023 5452 // or axis are stroked used to do any plot specific adjustment 5024 5453 function PreStrokeAdjust($aGraph) { 5025 if( substr($aGraph->axtype,0,4) == "text" && (isset($this->coords[1])) ) 5026 JpGraphError::RaiseL(25123);//("JpGraph: You can't use a text X-scale with specified X-coords. Use a \"int\" or \"lin\" scale instead."); 5027 return true; 5028 } 5029 5454 if( substr($aGraph->axtype,0,4) == "text" && (isset($this->coords[1])) ) { 5455 JpGraphError::RaiseL(25123);//("JpGraph: You can't use a text X-scale with specified X-coords. Use a \"int\" or \"lin\" scale instead."); 5456 } 5457 return true; 5458 } 5459 5460 // Virtual function to the the concrete plot class to make any changes to the graph 5461 // and scale before the stroke process begins 5462 function PreScaleSetup($aGraph) { 5463 // Empty 5464 } 5465 5030 5466 // Get minimum values in plot 5031 5467 function Min() { 5032 if( isset($this->coords[1]) ) 5033 5034 else 5035 $x=""; 5036 if( $x != "" && count($x) > 0 ) { 5037 $xm=min($x); 5038 } 5039 else 5040 $xm=0; 5041 $y=$this->coords[0]; 5042 $cnt = count($y);5043 if( $cnt > 0 ) { 5044 /* 5045 if( ! isset($y[0]) ) { 5046 JpGraphError('The input data array must have consecutive values from position 0 and forward. The given y-array starts with empty values (NULL)'); 5047 } 5048 $ym = $y[0]; 5049 */ 5050 $i=0; 5051 while( $i<$cnt && !is_numeric($ym=$y[$i]) ) 5052 $i++; 5053 while( $i < $cnt) { 5054 if( is_numeric($y[$i]) ) 5055 $ym=min($ym,$y[$i]);5056 ++$i; 5057 } 5058 } 5059 else 5060 $ym=""; 5061 5062 } 5063 5468 if( isset($this->coords[1]) ) { 5469 $x=$this->coords[1]; 5470 } 5471 else { 5472 $x=''; 5473 } 5474 if( $x != '' && count($x) > 0 ) { 5475 $xm=min($x); 5476 } 5477 else { 5478 $xm=0; 5479 } 5480 $y=$this->coords[0]; 5481 $cnt = count($y); 5482 if( $cnt > 0 ) { 5483 $i=0; 5484 while( $i<$cnt && !is_numeric($ym=$y[$i]) ) { 5485 $i++; 5486 } 5487 while( $i < $cnt) { 5488 if( is_numeric($y[$i]) ) { 5489 $ym=min($ym,$y[$i]); 5490 } 5491 ++$i; 5492 } 5493 } 5494 else { 5495 $ym=''; 5496 } 5497 return array($xm,$ym); 5498 } 5499 5064 5500 // Get maximum value in plot 5065 5501 function Max() { 5066 if( isset($this->coords[1]) ) 5067 $x=$this->coords[1]; 5068 else 5069 $x=""; 5070 5071 if( $x!="" && count($x) > 0 ) 5072 $xm=max($x); 5073 else { 5074 $xm = $this->numpoints-1; 5075 } 5076 $y=$this->coords[0]; 5077 if( count($y) > 0 ) { 5078 /* 5079 if( !isset($y[0]) ) { 5080 JpGraphError::Raise('The input data array must have consecutive values from position 0 and forward. The given y-array starts with empty values (NULL)'); 5081 // $y[0] = 0; 5082 // Change in 1.5.1 Don't treat this as an error any more. Just silently convert to 0 5083 // Change in 1.17 Treat his as an error again !! This is the right way to do !! 5084 } 5085 */ 5086 $cnt = count($y); 5087 $i=0; 5088 while( $i<$cnt && !is_numeric($ym=$y[$i]) ) 5089 $i++; 5090 while( $i < $cnt ) { 5091 if( is_numeric($y[$i]) ) 5092 $ym=max($ym,$y[$i]); 5093 ++$i; 5094 } 5095 } 5096 else 5097 $ym=""; 5098 return array($xm,$ym); 5099 } 5100 5502 if( isset($this->coords[1]) ) { 5503 $x=$this->coords[1]; 5504 } 5505 else { 5506 $x=''; 5507 } 5508 5509 if( $x!='' && count($x) > 0 ) { 5510 $xm=max($x); 5511 } 5512 else { 5513 $xm = $this->numpoints-1; 5514 } 5515 $y=$this->coords[0]; 5516 if( count($y) > 0 ) { 5517 $cnt = count($y); 5518 $i=0; 5519 while( $i<$cnt && !is_numeric($ym=$y[$i]) ) { 5520 $i++; 5521 } 5522 while( $i < $cnt ) { 5523 if( is_numeric($y[$i]) ) { 5524 $ym=max($ym,$y[$i]); 5525 } 5526 ++$i; 5527 } 5528 } 5529 else { 5530 $ym=''; 5531 } 5532 return array($xm,$ym); 5533 } 5534 5101 5535 function SetColor($aColor) { 5102 5103 } 5104 5536 $this->color=$aColor; 5537 } 5538 5105 5539 function SetLegend($aLegend,$aCSIM='',$aCSIMAlt='',$aCSIMWinTarget='') { 5106 5107 5108 5109 5540 $this->legend = $aLegend; 5541 $this->legendcsimtarget = $aCSIM; 5542 $this->legendcsimwintarget = $aCSIMWinTarget; 5543 $this->legendcsimalt = $aCSIMAlt; 5110 5544 } 5111 5545 5112 5546 function SetWeight($aWeight) { 5113 5114 } 5115 5547 $this->weight=$aWeight; 5548 } 5549 5116 5550 function SetLineWeight($aWeight=1) { 5117 5118 } 5119 5551 $this->line_weight=$aWeight; 5552 } 5553 5120 5554 function SetCenter($aCenter=true) { 5121 5122 } 5123 5555 $this->center = $aCenter; 5556 } 5557 5124 5558 // This method gets called by Graph class to plot anything that should go 5125 5559 // into the margin after the margin color has been set. 5126 5560 function StrokeMargin($aImg) { 5127 5561 return true; 5128 5562 } 5129 5563 5130 5564 // Framework function the chance for each plot class to set a legend 5131 5565 function Legend($aGraph) { 5132 if( $this->legend != "" ) 5133 $aGraph->legend->Add($this->legend,$this->color,"",0,$this->legendcsimtarget, 5134 $this->legendcsimalt,$this->legendcsimwintarget); 5135 } 5136 5566 if( $this->legend != '' ) { 5567 $aGraph->legend->Add($this->legend,$this->color,'',0,$this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 5568 } 5569 } 5570 5571 function Clear() { 5572 $this->isRunningClear = true; 5573 $this->__construct($this->inputValues['aDatay'], $this->inputValues['aDatax']); 5574 $this->isRunningClear = false; 5575 } 5576 5137 5577 } // Class 5138 5578 5139 5579 5140 //=================================================== 5141 // CLASS PlotLine 5142 // Description: 5143 // Data container class to hold properties for a static 5144 // line that is drawn directly in the plot area. 5145 // Usefull to add static borders inside a plot to show 5146 // for example set-values 5147 //=================================================== 5148 class PlotLine { 5149 public $scaleposition, $direction=-1; 5150 protected $weight=1; 5151 protected $color="black"; 5152 private $legend='',$hidelegend=false, $legendcsimtarget='', $legendcsimalt='',$legendcsimwintarget=''; 5153 private $iLineStyle='solid'; 5154 5155 //--------------- 5156 // CONSTRUCTOR 5157 function PlotLine($aDir=HORIZONTAL,$aPos=0,$aColor="black",$aWeight=1) { 5158 $this->direction = $aDir; 5159 $this->color=$aColor; 5160 $this->weight=$aWeight; 5161 $this->scaleposition=$aPos; 5162 } 5163 5164 //--------------- 5165 // PUBLIC METHODS 5166 5167 function SetLegend($aLegend,$aCSIM='',$aCSIMAlt='',$aCSIMWinTarget='') { 5168 $this->legend = $aLegend; 5169 $this->legendcsimtarget = $aCSIM; 5170 $this->legendcsimwintarget = $aCSIMWinTarget; 5171 $this->legendcsimalt = $aCSIMAlt; 5172 } 5173 5174 function HideLegend($f=true) { 5175 $this->hidelegend = $f; 5176 } 5177 5178 function SetPosition($aScalePosition) { 5179 $this->scaleposition=$aScalePosition; 5180 } 5181 5182 function SetDirection($aDir) { 5183 $this->direction = $aDir; 5184 } 5185 5186 function SetColor($aColor) { 5187 $this->color=$aColor; 5188 } 5189 5190 function SetWeight($aWeight) { 5191 $this->weight=$aWeight; 5192 } 5193 5194 function SetLineStyle($aStyle) { 5195 $this->iLineStyle = $aStyle; 5196 } 5197 5198 //--------------- 5199 // PRIVATE METHODS 5200 5201 function DoLegend(&$graph) { 5202 if( !$this->hidelegend ) 5203 $this->Legend($graph); 5204 } 5205 5206 // Framework function the chance for each plot class to set a legend 5207 function Legend(&$aGraph) { 5208 if( $this->legend != "" ) { 5209 $dummyPlotMark = new PlotMark(); 5210 $lineStyle = 1; 5211 $aGraph->legend->Add($this->legend,$this->color,$dummyPlotMark,$lineStyle, 5212 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 5213 } 5214 } 5215 5216 function PreStrokeAdjust($aGraph) { 5217 // Nothing to do 5218 } 5219 5220 function Stroke($aImg,$aXScale,$aYScale) { 5221 $aImg->SetColor($this->color); 5222 $aImg->SetLineWeight($this->weight); 5223 $oldStyle = $aImg->SetLineStyle($this->iLineStyle); 5224 if( $this->direction == VERTICAL ) { 5225 $ymin_abs=$aYScale->Translate($aYScale->GetMinVal()); 5226 $ymax_abs=$aYScale->Translate($aYScale->GetMaxVal()); 5227 $xpos_abs=$aXScale->Translate($this->scaleposition); 5228 $aImg->StyleLine($xpos_abs, $ymin_abs, $xpos_abs, $ymax_abs); 5229 } 5230 elseif( $this->direction == HORIZONTAL ) { 5231 $xmin_abs=$aXScale->Translate($aXScale->GetMinVal()); 5232 $xmax_abs=$aXScale->Translate($aXScale->GetMaxVal()); 5233 $ypos_abs=$aYScale->Translate($this->scaleposition); 5234 $aImg->StyleLine($xmin_abs, $ypos_abs, $xmax_abs, $ypos_abs); 5235 } 5236 else { 5237 JpGraphError::RaiseL(25125);//(" Illegal direction for static line"); 5238 } 5239 $aImg->SetLineStyle($oldStyle); 5240 } 5580 // Provide a deterministic list of new colors whenever the getColor() method 5581 // is called. Used to automatically set colors of plots. 5582 class ColorFactory { 5583 5584 static private $iIdx = 0; 5585 static private $iColorList = array( 5586 'black', 5587 'blue', 5588 'orange', 5589 'darkgreen', 5590 'red', 5591 'AntiqueWhite3', 5592 'aquamarine3', 5593 'azure4', 5594 'brown', 5595 'cadetblue3', 5596 'chartreuse4', 5597 'chocolate', 5598 'darkblue', 5599 'darkgoldenrod3', 5600 'darkorchid3', 5601 'darksalmon', 5602 'darkseagreen4', 5603 'deepskyblue2', 5604 'dodgerblue4', 5605 'gold3', 5606 'hotpink', 5607 'lawngreen', 5608 'lightcoral', 5609 'lightpink3', 5610 'lightseagreen', 5611 'lightslateblue', 5612 'mediumpurple', 5613 'olivedrab', 5614 'orangered1', 5615 'peru', 5616 'slategray', 5617 'yellow4', 5618 'springgreen2'); 5619 static private $iNum = 33; 5620 5621 static function getColor() { 5622 if( ColorFactory::$iIdx >= ColorFactory::$iNum ) 5623 ColorFactory::$iIdx = 0; 5624 return ColorFactory::$iColorList[ColorFactory::$iIdx++]; 5625 } 5626 5241 5627 } 5242 5628 -
trunk/client/modules/Elezioni/grafici/jpgraph_antispam-digits.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph_antispam-digits.php 781 2006-10-08 08:07:47Z ljp $3 // File: JPGRAPH_ANTISPAM.PHP 4 // Description: Genarate anti-spam challenge 5 // Created: 2004-10-07 6 // Ver: $Id: jpgraph_antispam-digits.php 1930 2010-01-22 20:19:27Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 … … 13 13 public $iHeight=30, $iWidth=30; 14 14 15 function HandDigits() {16 //==========================================================17 // d6-small.jpg18 //==========================================================19 20 $this->digits['6'][1]= 21 22 23 24 25 26 27 28 29 30 31 //==========================================================32 // d2-small.jpg33 //==========================================================34 35 $this->digits['2'][1]= 36 37 38 39 40 41 42 43 44 45 46 //==========================================================47 // d9-small.jpg48 //==========================================================49 50 $this->digits['9'][1]= 51 52 53 54 55 56 57 58 59 60 61 62 //==========================================================63 // d5-small.jpg64 //==========================================================65 66 $this->digits['5'][1]= 67 68 69 70 71 72 73 74 75 76 77 //==========================================================78 // d1-small.jpg79 //==========================================================80 81 $this->digits['1'][1]= 82 83 84 85 86 87 88 89 90 91 92 //==========================================================93 // d8-small.jpg94 //==========================================================95 96 $this->digits['8'][1]= 97 98 99 100 101 102 103 104 105 106 107 108 //==========================================================109 // d4-small.jpg110 //==========================================================111 112 $this->digits['4'][1]= 113 114 115 116 117 118 119 120 121 122 123 //==========================================================124 // d7-small.jpg125 //==========================================================126 127 $this->digits['7'][1]= 128 129 130 131 132 133 134 135 136 137 138 //==========================================================139 // d3-small.jpg140 //==========================================================141 142 $this->digits['3'][1]= 143 144 145 146 147 148 149 150 151 152 } 15 function __construct() { 16 //========================================================== 17 // d6-small.jpg 18 //========================================================== 19 $this->digits['6'][0]= 645 ; 20 $this->digits['6'][1]= 21 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 22 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. 23 'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAZAAEBAAMBAAAAAAAAAAAAAAAABgMEBwX/xAAvEAABAwMC'. 24 'BAQEBwAAAAAAAAABAgMEAAURBiESIjFRBxMUQRUWMmFTYnGRkrHC/8QAFgEBAQEAAAAAAAAAAAAAAAAAAAEC/8QAFhEBAQEAAAAA'. 25 'AAAAAAAAAAAAAAER/9oADAMBAAIRAxEAPwDslwiR3oDku8ONttsAvDiVyMcO/ET7ke5/aoOz6k1Vr5htNjW7a7M1yO3NTQU9JUDu'. 26 'GgrlSn8xyf6p4gXaHJvNps9/mKZtSkGdMjRwpfqAFBLLACRlZUrJONsI2717No1lbZ10kx7XGnRpKWQ/6GVGMfzEJ5VFIVtsOH6e'. 27 'wyKVhYsia0y22pLThSkJK1uniVgdThOM0ol+StIUhpopIyCFq3H8aUVCwnG3PGe4Rp6fLXJtMdyM0ojcIWvIz3HFnAPfrWTXb6GN'. 28 'WaLXDwZjVz8pKEfhuIUFg/bAz9sVJ61nt61mxJFslLtq7e5yPqiBT4UDklKw4MDpt+u+9bFiu9riXNu83R+fcr6tohuQ5HQhmK37'. 29 'paaC8DruScmg6X8KkjZEhbaB9KEyFYSOw26Uqd+e7Qerl5z74DY/1SomP//Z' ; 30 31 //========================================================== 32 // d2-small.jpg 33 //========================================================== 34 $this->digits['2'][0]= 606 ; 35 $this->digits['2'][1]= 36 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 37 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. 38 'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEQMBIgACEQEDEQH/xAAYAAEBAQEBAAAAAAAAAAAAAAAFAAQHAv/EACsQAAEDBAEC'. 39 'BAYDAAAAAAAAAAIBAwQABQYRIRIxQVFhcQcTFSJSU5GU0f/EABcBAAMBAAAAAAAAAAAAAAAAAAECAwT/xAAZEQACAwEAAAAAAAAA'. 40 'AAAAAAAAARESUUH/2gAMAwEAAhEDEQA/AOqXm/Q8dxmOL4PPSnCSNFixx6nXnkXgRT3Te17JWbGsveueSyLZdbPItNxOKLzTLjou'. 41 'gYCSoSoY8ISKSbFeUrzkdlnTL1YshskiErkQnFEZaF8kkdBBVdjyi6RNL5+9F486eS/ECVkcBtDt1vZcho5viS8ZCp9C9tAIAm/F'. 42 'VoPRU+HRtJ5JVRP1kP0PfwP+1VKrHBMliXG4Nw8VgE4xGkuqk2S1wTUNEVdIvgpL9iL6KtNxY7WOwo9tt0RCitj0sR2uCbFPPzH1'. 43 '7+6rRuSRcljMBMsUy2tky045KOawZk5xtEFBJEROO3hx61kh2rPCIX3MhsyC4QmfTbC6lH8dq5212qwkiG5H6Y/9R2qm+ofxqqsL'. 44 'DLZ6f//Z' ; 45 46 //========================================================== 47 // d9-small.jpg 48 //========================================================== 49 $this->digits['9'][0]= 680 ; 50 $this->digits['9'][1]= 51 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 52 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. 53 'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAZAAACAwEAAAAAAAAAAAAAAAAABAUGBwP/xAArEAABAwMD'. 54 'AgYBBQAAAAAAAAABAgMEBQYRABIhE1EUIjEzQUIHMlJhcdH/xAAWAQEBAQAAAAAAAAAAAAAAAAACAQD/xAAYEQEAAwEAAAAAAAAA'. 55 'AAAAAAAAAREhQf/aAAwDAQACEQMRAD8AkK7brF6X7XpMeGoKhFMLEeT4ZUheEhanF4OcZ2pTgDykk92bZpdCsi7aezLjxkIPUZiV'. 56 'RSCy8hah7EkZ27yM7V+iscal5bE22Lon1qNDmSKROd8Sl+Ix1lMOlIS4HGgQpbStoUCnlJz8HmsXtW3Lst2rmBAelLMRRekOwnYz'. 57 'Edls9QKKnOVLyk7UgcbzzrdBthqEJJwZbAI4x1U/7o1TaFa9lG36aXaZTy54VrcXUgrzsGdx+T30aNydweqVw1GS87T6Lb86Q4ha'. 58 'my/IAYjZBx+snKk99oOQMf1AViE65SY348hzFy6hPKnqtKz7DC1lbqyPrvJKUJ7H+M6Wrt3InP7o1brFNp4bCDGhxGAsqz69VSiQ'. 59 'ORwBxrrQ7itm1ac7Hp0WoGTIc3PSn0pccdcP2WorycfA1RaRHjxosZqOyhtDTSAhCf2gDAGjVHTd9sKSCumynFEZK1tIJUe58/ro'. 60 '1V1//9k=' ; 61 62 //========================================================== 63 // d5-small.jpg 64 //========================================================== 65 $this->digits['5'][0]= 632 ; 66 $this->digits['5'][1]= 67 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 68 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. 69 'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAZAAACAwEAAAAAAAAAAAAAAAAABgIFBwT/xAAoEAABAwME'. 70 'AQQCAwAAAAAAAAABAgMEBQYRABIhIkEUMVFhBxNCgaH/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAv/EABcRAQEBAQAAAAAAAAAAAAAA'. 71 'AAABEUH/2gAMAwEAAhEDEQA/ANGvW4YVOeiRX5b4mv5Sin05IdlupPKdo/j2SO3+6TbPNQvOsTVz33KRT4csR3YUF7Dsh5OSFvug'. 72 'kqG4FPBxnjxpvvi4KZb1pTpU+QwxUi2Y7ZIAefUk5ATxnB9/gbtL/wCH1UpuhPUlZlMVaQ0mS8zJjqZOPfc2TwpIUonI9tw40R1r'. 73 'WNGq/wBdJR1XT3lqHBUnGCfkfWjRWs1ve249erQqQYjOtN1FqPUpCXQ4WIzQSsJwT0UpRwQPG0nzqyuNHobjsl9kBuWqoOoXtT1/'. 74 'WppZcA8lKRj64HxqU+3KpAr6plElRVKef3S4E0K9O8pLXVzKcqSsJAB9wSAca6bSoNXeuA1+5pEV+SGFNU1iKVFqI0Vdx2AJUeoz'. 75 '8DGlTDwG3CAf3q/pI0ah6MDhLz6U+EpXwPoaNMU//9k=' ; 76 77 //========================================================== 78 // d1-small.jpg 79 //========================================================== 80 $this->digits['1'][0]= 646 ; 81 $this->digits['1'][1]= 82 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 83 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. 84 'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEwMBIgACEQEDEQH/xAAZAAADAAMAAAAAAAAAAAAAAAAABQYCBAf/xAApEAACAQMD'. 85 'AwQBBQAAAAAAAAABAgMEBREABiESMUEHEyJRkSNCYXGB/8QAFgEBAQEAAAAAAAAAAAAAAAAAAAEC/8QAFxEBAQEBAAAAAAAAAAAA'. 86 'AAAAAAEREv/aAAwDAQACEQMRAD8A6jdd4WLbstILnc4Uq0VoWpkJknb6IjXLHJUePOlez923fcW4r1SxWlqC2UbdKirQif3Xw3yA'. 87 'OFAGT09/kO3OmV3a20MFRf6lIYPcpy7yRRAzgxjIy2M8YwcdiBzpX6d22VNvUlTXsFkuwkrKqNSfnK7F8OTzwrAY+l5zoxKskudN'. 88 'EgQPUT9PBkWF3DH+1GPxo1mLnRoAqF2VRgGOFmX/AAgY/GjRUP6hVMFv2FuFqUvUGrpDFJMBnpdyF5bsAQew7Hxzp6LZNT0yQ1DI'. 89 'wp0QCFBhD0jCsfLZHxbx5xxpTuvb1+v9PV7Ztk9roLPLCjmSSN3mX5ZwqjCgZX7PfWxDQb2in96pv9qq46aTE0bW4x9ceAWAYPwS'. 90 'PsYzoixgmheBGjIVcYCnjp/jHjHbRpe1JLn9OnopE/a0ykvjwDx47aNMXqP/2Q==' ; 91 92 //========================================================== 93 // d8-small.jpg 94 //========================================================== 95 $this->digits['8'][0]= 694 ; 96 $this->digits['8'][1]= 97 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 98 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. 99 'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AFQMBIgACEQEDEQH/xAAYAAADAQEAAAAAAAAAAAAAAAAABgcEBf/EACsQAAEDAwMD'. 100 'AwMFAAAAAAAAAAECAwQFBhEAEiEUMVEHE0EVYYEiIzJCsf/EABYBAQEBAAAAAAAAAAAAAAAAAAIAAf/EABcRAQEBAQAAAAAAAAAA'. 101 'AAAAAAABERL/2gAMAwEAAhEDEQA/AKL6gVVUa0i1T5QjvTprUJMlxW4R9zgQXe/AH+kaWrntqlWjaq7gpcmotXAw82ht9yY4tch8'. 102 'uAFC0k7VBXPGMY51ruiaue+bThIj+7NbWqS+7HDxajFf6AlB/k44o8ZOABk4xkL0X0tZiojKrlRuGRJjugqldSlKGf6t7BuUQe3J'. 103 '44xxxrA1a4KVJipLidri8uLHgqOcfjOPxo0o2hdDvS1CmV2Yl6fS5ioipIQR1CAlKkLKR2UUqAI8g6NRSwuuyHab6s1ufLI/Zai7'. 104 'UBJOxhTS0+6B32pWSFH4CidOdWU0ukLiN1BLr0zG5Sdm3GRvcPhIT858DvjXNrVsSLnm/VIdTXS6tTnFsxZTSN3jchaTwps+O/z9'. 105 'tcBVq3hIX0tYqlIiQHdy5CqRHKHXEjAOMgBKjnvyRk4xrQa7OiGt1K5biYZL8SoVEpjOqkFsONtJCNwASeCQrn7aNUKnQYtLp7EC'. 106 'EylmLHQltptPZKQOBo1FzH//2Q==' ; 107 108 //========================================================== 109 // d4-small.jpg 110 //========================================================== 111 $this->digits['4'][0]= 643 ; 112 $this->digits['4'][1]= 113 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 114 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. 115 'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAYAAADAQEAAAAAAAAAAAAAAAAABAYHAv/EAC0QAAIBAwQA'. 116 'BAMJAAAAAAAAAAECAwQFEQAGEiETFDFBUmGBByIjUVNxobHR/8QAFgEBAQEAAAAAAAAAAAAAAAAAAAIB/8QAGBEBAAMBAAAAAAAA'. 117 'AAAAAAAAAAERIVH/2gAMAwEAAhEDEQA/ANjM00Nxmt1xiWW31CZp5uJwoAAaOQ/n7qfcZHqO5my3q5XX7R6ijiqnNut9u4NyJ4yv'. 118 'JJyjYr8Xhrn5g599J7x3ulBNU7Zo7dXXXcLQ8kURYi4epYtkALjOePv1nUvbLvV7P3BZm3DR3eh88Kp7pVzBZI6iUhGWRRGWwE44'. 119 'HX3V+uiL1uHgt+vL/H+aNJQ3CSeCOaFqSaJ1DJKs/TqRkMOvQjvRorHE4pRDLNWLGlRHGUeYIORXs9e5B7OP31E0fmdyb/t0DJ4Q'. 120 '27bfx3YZzPUIoAAz7IpOD6cuxq0uNumqLfVNDOqXBoZEjnZcqhIPXH4c46+WkdoWOltu3IDDLLLVVR83UVcuPEmmcZZ2/rHoAANG'. 121 'GI7KIY1ijoLeEQBVCwIoAHpgY6Hy0aZe7mJ2jeHLKcEhusj6aNKgzr//2Q==' ; 122 123 //========================================================== 124 // d7-small.jpg 125 //========================================================== 126 $this->digits['7'][0]= 658 ; 127 $this->digits['7'][1]= 128 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 129 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. 130 'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAZAAACAwEAAAAAAAAAAAAAAAAABgEFBwT/xAAuEAABAwIE'. 131 'BAQGAwAAAAAAAAABAgMEBREABiExEhMiQSMyUXEHFBclVJFhk9L/xAAXAQADAQAAAAAAAAAAAAAAAAAAAQID/8QAGREBAQEAAwAA'. 132 'AAAAAAAAAAAAAAEREiFR/9oADAMBAAIRAxEAPwDXq9mCjZeQ05VZ5ZST4bfEpa3VdglCbqUe+g9MZ5Uq7V8415WXoMSdQ6etgSps'. 133 '19wpkCMDZKUpv0FZvbi1NzpYasMDLDUbMVXrtQdbeeU23xLWkj5RlLYK0J7anW9gbAjCzkOtsVSUJUdtc6dVZK51UeaFm4LKbhpC'. 134 'l7EhIFkDW974GbRI2XorUVls1OTdKAOqUpR0Hc3198GITQ6k+hLwrEpoODiDenRfW23bBicg78JXxPpD0mgVOW5PAivNNpahsPW5'. 135 '8xxQaSVkboQnhsnYm5OHqDGp1IpsalMKjMsMIC3+XZKbJFth62/QOEfMOZqZXp9JcKZTcGmTky3meSi7xQklI81vMR+sXIz/AEgp'. 136 'Q0qPNu6ea8Q2jqtbp8+2w9h/OKORc/cpHjt1dDSHOtLZ4ekHW23bBjj+o9H/AB539aP94MG0+L//2Q==' ; 137 138 //========================================================== 139 // d3-small.jpg 140 //========================================================== 141 $this->digits['3'][0]= 662 ; 142 $this->digits['3'][1]= 143 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 144 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. 145 'MjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAB4AEgMBIgACEQEDEQH/xAAZAAACAwEAAAAAAAAAAAAAAAAABAUGBwL/xAArEAABBAED'. 146 'AwMDBQEAAAAAAAABAgMEBREABhIhMUEiMmETFZEHFkJDUdH/xAAWAQEBAQAAAAAAAAAAAAAAAAABAAL/xAAYEQEBAQEBAAAAAAAA'. 147 'AAAAAAAAEQExQf/aAAwDAQACEQMRAD8A0vclruBdk3VVLLUNssGRJsZSCtqOjlgJAHvcOD6c4HnOdIbcttw1W5P29cFEhuawqTXS'. 148 'VsJjnCMBxKkJJx7goAde+ceJfdNxU0UNlyymyXHi6kxWUNl1S3EnkAEIHX2nv86qtTuZr9Q9+1VhRsOoYpYcgSVyAE/TdewkJxnK'. 149 'sBCjkdPGpnOtFMd3PqsXgfOAgD8Y0aX+11H9rDDjn8lr9yj5J+dGqsqxaw6Cc9cQZU4Sp7zTJsIrKlcUEKwhSin1JABI45GUjqOu'. 150 'lbOvjbc3Ts9ynjGCy445UuFLYRzbWgrT6fhSCQSMDke+pew2zYVly/d7YchNqkMJZnQpgV9J8IzwWFJyUrAJHYgjvpLbu37G5nR7'. 151 'vck5C3YRKYEOEVJZj8kjKypXqWvirjk9h+dB9i4faa89TDZUfKlIyT8k+To10a6KTkpcJ/0vL/7o0TS//9k=' ; 152 } 153 153 } 154 154 155 155 class AntiSpam { 156 156 157 var$iNumber='';158 159 function AntiSpam($aNumber='') {160 157 private $iNumber=''; 158 159 function __construct($aNumber='') { 160 $this->iNumber = $aNumber; 161 161 } 162 162 163 163 function Rand($aLen) { 164 165 166 167 168 169 164 $d=''; 165 for($i=0; $i < $aLen; ++$i) { 166 $d .= rand(1,9); 167 } 168 $this->iNumber = $d; 169 return $d; 170 170 } 171 171 172 172 function Stroke() { 173 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 174 $n=strlen($this->iNumber); 175 for($i=0; $i < $n; ++$i ) { 176 if( !is_numeric($this->iNumber[$i]) || $this->iNumber[$i]==0 ) { 177 return false; 178 } 179 } 180 181 $dd = new HandDigits(); 182 $n = strlen($this->iNumber); 183 $img = @imagecreatetruecolor($n*$dd->iWidth, $dd->iHeight); 184 if( $img < 1 ) { 185 return false; 186 } 187 $start=0; 188 for($i=0; $i < $n; ++$i ) { 189 $size = $dd->digits[$this->iNumber[$i]][0]; 190 $dimg = imagecreatefromstring(base64_decode($dd->digits[$this->iNumber[$i]][1])); 191 imagecopy($img,$dimg,$start,0,0,0,imagesx($dimg), $dd->iHeight); 192 $start += imagesx($dimg); 193 } 194 $resimg = @imagecreatetruecolor($start+4, $dd->iHeight+4); 195 if( $resimg < 1 ) { 196 return false; 197 } 198 imagecopy($resimg,$img,2,2,0,0,$start, $dd->iHeight); 199 header("Content-type: image/jpeg"); 200 imagejpeg($resimg); 201 return true; 202 202 } 203 203 } -
trunk/client/modules/Elezioni/grafici/jpgraph_antispam.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph_antispam.php 808 2006-11-28 19:10:40Z ljp $3 // File: JPGRAPH_ANTISPAM.PHP 4 // Description: Genarate anti-spam challenge 5 // Created: 2004-10-07 6 // Ver: $Id: jpgraph_antispam.php 1106 2009-02-22 20:16:35Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 … … 13 13 public $iHeight=30, $iWidth=30; 14 14 15 function HandDigits() {16 17 //==========================================================18 // lj-small.jpg19 //==========================================================20 $this->chars['j'][0]= 658 ;21 $this->chars['j'][1]= 15 function __construct() { 16 17 //========================================================== 18 // lj-small.jpg 19 //========================================================== 20 $this->chars['j'][0]= 658 ; 21 $this->chars['j'][1]= 22 22 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 23 23 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 30 30 'cEgeNHhi7D3qC3UN69M8tIakRhgrh9o748+eNGtcCiKjjpkQKlMTEg3ZwoxtHHtgfTRpYXArvp//2Q==' ; 31 31 32 //==========================================================33 // lf-small.jpg34 //==========================================================35 $this->chars['f'][0]= 633 ;36 $this->chars['f'][1]= 32 //========================================================== 33 // lf-small.jpg 34 //========================================================== 35 $this->chars['f'][0]= 633 ; 36 $this->chars['f'][1]= 37 37 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 38 38 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 45 45 '4+mjUrURyrUNMZFEkkIOFuFAbsP9d/OjVIQ6Vh4tP//Z' ; 46 46 47 //==========================================================48 // lb-small.jpg49 //==========================================================50 $this->chars['b'][0]= 645 ;51 $this->chars['b'][1]= 47 //========================================================== 48 // lb-small.jpg 49 //========================================================== 50 $this->chars['b'][0]= 645 ; 51 $this->chars['b'][1]= 52 52 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 53 53 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 60 60 '8AcU3UzFuhUSBFud6nRXoz96mqmJZWg7m2dqUNhWBwdqQSP1UU5c/FFCn//Z' ; 61 61 62 //==========================================================63 // d6-small.jpg64 //==========================================================65 $this->chars['6'][0]= 645 ;66 $this->chars['6'][1]= 62 //========================================================== 63 // d6-small.jpg 64 //========================================================== 65 $this->chars['6'][0]= 645 ; 66 $this->chars['6'][1]= 67 67 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 68 68 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 75 75 'paaC8DruScmg6X8KkjZEhbaB9KEyFYSOw26Uqd+e7Qerl5z74DY/1SomP//Z' ; 76 76 77 //==========================================================78 // lx-small.jpg79 //==========================================================80 $this->chars['x'][0]= 650 ;81 $this->chars['x'][1]= 77 //========================================================== 78 // lx-small.jpg 79 //========================================================== 80 $this->chars['x'][0]= 650 ; 81 $this->chars['x'][1]= 82 82 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 83 83 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 90 90 'uKgwqtTZDTMOU0FttqRkoHggnPkEEHRrkJ6t1SlSHYUOc6zHaWrsbQrATk5/vRqK/9k=' ; 91 91 92 //==========================================================93 // d2-small.jpg94 //==========================================================95 $this->chars['2'][0]= 606 ;96 $this->chars['2'][1]= 92 //========================================================== 93 // d2-small.jpg 94 //========================================================== 95 $this->chars['2'][0]= 606 ; 96 $this->chars['2'][1]= 97 97 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 98 98 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 105 105 'DLZ6f//Z' ; 106 106 107 //==========================================================108 // lm-small.jpg109 //==========================================================110 $this->chars['m'][0]= 649 ;111 $this->chars['m'][1]= 107 //========================================================== 108 // lm-small.jpg 109 //========================================================== 110 $this->chars['m'][0]= 649 ; 111 $this->chars['m'][1]= 112 112 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 113 113 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 120 120 'jg2zf50W9zk524GAEihuz+xbIOD82jW5TkjtRPZkTkJ+4VgDhQfuj/f3OjUxl1f/2Q==' ; 121 121 122 //==========================================================123 // lt-small.jpg124 //==========================================================125 $this->chars['t'][0]= 648 ;126 $this->chars['t'][1]= 122 //========================================================== 123 // lt-small.jpg 124 //========================================================== 125 $this->chars['t'][0]= 648 ; 126 $this->chars['t'][1]= 127 127 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 128 128 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 135 135 'D46EnuD+6Nc1smDNrTlRkxqtMo1vzKhIdYgU9YDqVpISrLhHxSSd21I0aYyqP//Z' ; 136 136 137 //==========================================================138 // li-small.jpg139 //==========================================================140 $this->chars['i'][0]= 639 ;141 $this->chars['i'][1]=137 //========================================================== 138 // li-small.jpg 139 //========================================================== 140 $this->chars['i'][0]= 639 ; 141 $this->chars['i'][1]= 142 142 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 143 143 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 149 149 'Yf8AOl7JTdw5eOCz0jw3+LbYCfA9nz71msb8KMxoTGTw+5srjsipAdDqFBQBIuiOl6KrdYyJMyTCshlw2G3Fr/HiNqNNAqJJUoGl'. 150 150 'KND+h47km1bZwsvCbYYjycxIyK1qDv2yEi0hQviK8atKDcy9j//Z' ; 151 152 153 //==========================================================154 // lp-small.jpg155 //==========================================================156 $this->chars['p'][0]= 700 ;157 $this->chars['p'][1]= 151 152 153 //========================================================== 154 // lp-small.jpg 155 //========================================================== 156 $this->chars['p'][0]= 700 ; 157 $this->chars['p'][1]= 158 158 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 159 159 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 167 167 'C5LwAyq2EtpHZI7mxPYDRqoctdESimz/2Q==' ; 168 168 169 //==========================================================170 // le-small.jpg171 //==========================================================172 $this->chars['e'][0]= 700 ;173 $this->chars['e'][1]= 169 //========================================================== 170 // le-small.jpg 171 //========================================================== 172 $this->chars['e'][0]= 700 ; 173 $this->chars['e'][1]= 174 174 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 175 175 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 183 183 'LBNF6qrzG6t0spEu6+fpL7YMXhUndp//2Q==' ; 184 184 185 //==========================================================186 // la-small.jpg187 //==========================================================188 $this->chars['a'][0]= 730 ;189 $this->chars['a'][1]=185 //========================================================== 186 // la-small.jpg 187 //========================================================== 188 $this->chars['a'][0]= 730 ; 189 $this->chars['a'][1]= 190 190 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 191 191 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 199 199 'HVDtXStE5K5jlPU7PF3Q41+okJFkjgC+3OuNSYiSzHaLtRcW4UDMpLYSCbakDW3thhum5p//2Q==' ; 200 200 201 //==========================================================202 // d9-small.jpg203 //==========================================================204 $this->chars['9'][0]= 680 ;205 $this->chars['9'][1]= 201 //========================================================== 202 // d9-small.jpg 203 //========================================================== 204 $this->chars['9'][0]= 680 ; 205 $this->chars['9'][1]= 206 206 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 207 207 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 215 215 '1V1//9k=' ; 216 216 217 //==========================================================218 // d5-small.jpg219 //==========================================================220 $this->chars['5'][0]= 632 ;221 $this->chars['5'][1]= 217 //========================================================== 218 // d5-small.jpg 219 //========================================================== 220 $this->chars['5'][0]= 632 ; 221 $this->chars['5'][1]= 222 222 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 223 223 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 230 230 '8DGlTDwG3CAf3q/pI0ah6MDhLz6U+EpXwPoaNMU//9k=' ; 231 231 232 //==========================================================233 // d1-small.jpg234 //==========================================================235 $this->chars['1'][0]= 646 ;236 $this->chars['1'][1]= 232 //========================================================== 233 // d1-small.jpg 234 //========================================================== 235 $this->chars['1'][0]= 646 ; 236 $this->chars['1'][1]= 237 237 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 238 238 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 245 245 'PsYzoixgmheBGjIVcYCnjp/jHjHbRpe1JLn9OnopE/a0ykvjwDx47aNMXqP/2Q==' ; 246 246 247 //==========================================================248 // ll-small.jpg249 //==========================================================250 $this->chars['l'][0]= 626 ;251 $this->chars['l'][1]=247 //========================================================== 248 // ll-small.jpg 249 //========================================================== 250 $this->chars['l'][0]= 626 ; 251 $this->chars['l'][1]= 252 252 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 253 253 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 261 261 262 262 263 //==========================================================264 // ls-small.jpg265 //==========================================================266 $this->chars['s'][0]= 701 ;267 $this->chars['s'][1]= 263 //========================================================== 264 // ls-small.jpg 265 //========================================================== 266 $this->chars['s'][0]= 701 ; 267 $this->chars['s'][1]= 268 268 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 269 269 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 277 277 'lymUOLdWfJyoHA+gA7AAAaNPE3ysJdLT/9k=' ; 278 278 279 //==========================================================280 // lh-small.jpg281 //==========================================================282 $this->chars['h'][0]= 677 ;283 $this->chars['h'][1]= 279 //========================================================== 280 // lh-small.jpg 281 //========================================================== 282 $this->chars['h'][0]= 677 ; 283 $this->chars['h'][1]= 284 284 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 285 285 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 294 294 295 295 296 //==========================================================297 // ld-small.jpg298 //==========================================================299 $this->chars['d'][0]= 681 ;300 $this->chars['d'][1]=296 //========================================================== 297 // ld-small.jpg 298 //========================================================== 299 $this->chars['d'][0]= 681 ; 300 $this->chars['d'][1]= 301 301 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 302 302 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 310 310 'Ia1JX//Z' ; 311 311 312 //==========================================================313 // d8-small.jpg314 //==========================================================315 $this->chars['8'][0]= 694 ;316 $this->chars['8'][1]= 312 //========================================================== 313 // d8-small.jpg 314 //========================================================== 315 $this->chars['8'][0]= 694 ; 316 $this->chars['8'][1]= 317 317 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 318 318 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 326 326 'EylmLHQltptPZKQOBo1FzH//2Q==' ; 327 327 328 //==========================================================329 // lz-small.jpg330 //==========================================================331 $this->chars['z'][0]= 690 ;332 $this->chars['z'][1]=328 //========================================================== 329 // lz-small.jpg 330 //========================================================== 331 $this->chars['z'][0]= 690 ; 332 $this->chars['z'][1]= 333 333 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 334 334 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 342 342 'KrnsKH06I/rVrQKkf//Z' ; 343 343 344 //==========================================================345 // d4-small.jpg346 //==========================================================347 $this->chars['4'][0]= 643 ;348 $this->chars['4'][1]= 344 //========================================================== 345 // d4-small.jpg 346 //========================================================== 347 $this->chars['4'][0]= 643 ; 348 $this->chars['4'][1]= 349 349 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 350 350 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 357 357 'GI7KIY1ijoLeEQBVCwIoAHpgY6Hy0aZe7mJ2jeHLKcEhusj6aNKgzr//2Q==' ; 358 358 359 //==========================================================360 // lv-small.jpg361 //==========================================================362 $this->chars['v'][0]= 648 ;363 $this->chars['v'][1]=359 //========================================================== 360 // lv-small.jpg 361 //========================================================== 362 $this->chars['v'][0]= 648 ; 363 $this->chars['v'][1]= 364 364 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 365 365 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 372 372 'ubmMBCVJdjx0pRyLoWR4I8aNIQ8BvZMNtMTeUcsptKfc4tC1gAkCyFC+K0aJtf/Z' ; 373 373 374 //==========================================================375 // lk-small.jpg376 //==========================================================377 $this->chars['k'][0]= 680 ;378 $this->chars['k'][1]= 374 //========================================================== 375 // lk-small.jpg 376 //========================================================== 377 $this->chars['k'][0]= 680 ; 378 $this->chars['k'][1]= 379 379 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 380 380 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 388 388 'k9aP/9k=' ; 389 389 390 //==========================================================391 // lr-small.jpg392 //==========================================================393 $this->chars['r'][0]= 681 ;394 $this->chars['r'][1]= 390 //========================================================== 391 // lr-small.jpg 392 //========================================================== 393 $this->chars['r'][0]= 681 ; 394 $this->chars['r'][1]= 395 395 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 396 396 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 404 404 'ZeKZ1//Z' ; 405 405 406 //==========================================================407 // lg-small.jpg408 //==========================================================409 $this->chars['g'][0]= 655 ;410 $this->chars['g'][1]=406 //========================================================== 407 // lg-small.jpg 408 //========================================================== 409 $this->chars['g'][0]= 655 ; 410 $this->chars['g'][1]= 411 411 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 412 412 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 419 419 '4ywltanVJvuJI+RQs/sHRqy2r003JhsImEc/CUyhxRZBjKV2oJ8eRXNmufPnRo1WIz3DdNn/2Q==' ; 420 420 421 //==========================================================422 // lc-small.jpg423 //==========================================================424 $this->chars['c'][0]= 629 ;425 $this->chars['c'][1]= 421 //========================================================== 422 // lc-small.jpg 423 //========================================================== 424 $this->chars['c'][0]= 629 ; 425 $this->chars['c'][1]= 426 426 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 427 427 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 434 434 '3Ls3TqNs5Hc9h23w49NWL9K+Q/VD5T/zhwPH/9k=' ; 435 435 436 //==========================================================437 // d7-small.jpg438 //==========================================================439 $this->chars['7'][0]= 658 ;440 $this->chars['7'][1]= 436 //========================================================== 437 // d7-small.jpg 438 //========================================================== 439 $this->chars['7'][0]= 658 ; 440 $this->chars['7'][1]= 441 441 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 442 442 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 449 449 'Q0qPNu6ea8Q2jqtbp8+2w9h/OKORc/cpHjt1dDSHOtLZ4ekHW23bBjj+o9H/AB539aP94MG0+L//2Q==' ; 450 450 451 //==========================================================452 // ly-small.jpg453 //==========================================================454 $this->chars['y'][0]= 672 ;455 $this->chars['y'][1]= 451 //========================================================== 452 // ly-small.jpg 453 //========================================================== 454 $this->chars['y'][0]= 672 ; 455 $this->chars['y'][1]= 456 456 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 457 457 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 464 464 'uvmXdlme6n4dCwlRBKEgA2tj99QG7Ilncp5QqpU31PMsJ6x7A32f6SPxo0hPVCD45oVyKf0MtgeT97/nRrO7UOCFla3tn//Z' ; 465 465 466 //==========================================================467 // d3-small.jpg468 //==========================================================469 $this->chars['3'][0]= 662 ;470 $this->chars['3'][1]= 466 //========================================================== 467 // d3-small.jpg 468 //========================================================== 469 $this->chars['3'][0]= 662 ; 470 $this->chars['3'][1]= 471 471 '/9j/4AAQSkZJRgABAQEASgBKAAD//gAJSnBHcmFwaP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicg'. 472 472 'IiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 479 479 'vck5C3YRKYEOEVJZj8kjKypXqWvirjk9h+dB9i4faa89TDZUfKlIyT8k+To10a6KTkpcJ/0vL/7o0TS//9k=' ; 480 480 481 //==========================================================482 // ln-small.jpg483 //==========================================================484 $this->chars['n'][0]= 643 ;485 $this->chars['n'][1]= 481 //========================================================== 482 // ln-small.jpg 483 //========================================================== 484 $this->chars['n'][0]= 643 ; 485 $this->chars['n'][1]= 486 486 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 487 487 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 494 494 '5+WNAh5ZCu/r2+dGrgq0pi0DhmlRsSSAfqMd+b6ZyNu3po1Rk1yNBe3/2Q==' ; 495 495 496 //==========================================================497 // lu-small.jpg498 //==========================================================499 $this->chars['u'][0]= 671 ;500 $this->chars['u'][1]= 496 //========================================================== 497 // lu-small.jpg 498 //========================================================== 499 $this->chars['u'][0]= 671 ; 500 $this->chars['u'][1]= 501 501 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 502 502 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 509 509 'jT7Xc74HtOYnHyUOh8yWUvKeHhy0CiPVUAPoDRrm+OeznTva6lzsyMjCYbbaiNJjJSWElagD5tRpNUSALFeNGoOCH7Bv/9k=' ; 510 510 511 //==========================================================512 // lw-small.jpg513 //==========================================================514 $this->chars['w'][0]= 673 ;515 $this->chars['w'][1]=511 //========================================================== 512 // lw-small.jpg 513 //========================================================== 514 $this->chars['w'][0]= 673 ; 515 $this->chars['w'][1]= 516 516 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 517 517 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 524 524 'Rsn+tVpiyJnqv09YfOXu5AycgZZQEhBZjgDBOOgwO/po0sttWHdNzqLruioa4UwmdaC3kYp4IwSvJlBHKQ4OSe3po0qxM6P/2Q==' ; 525 525 526 //==========================================================527 // lq-small.jpg528 //==========================================================529 $this->chars['q'][0]= 671 ;530 $this->chars['q'][1]=526 //========================================================== 527 // lq-small.jpg 528 //========================================================== 529 $this->chars['q'][0]= 671 ; 530 $this->chars['q'][1]= 531 531 '/9j/4AAQSkZJRgABAQEASgBKAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx'. 532 532 'NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy'. … … 541 541 542 542 543 } 543 } 544 544 } 545 545 … … 549 549 private $iDD=null; 550 550 551 function AntiSpam($aData='') {552 553 $this->iDD = new HandDigits(); 551 function __construct($aData='') { 552 $this->iData = $aData; 553 $this->iDD = new HandDigits(); 554 554 } 555 555 556 556 function Set($aData) { 557 557 $this->iData = $aData; 558 558 } 559 559 560 560 function Rand($aLen) { 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 561 $d=''; 562 for($i=0; $i < $aLen; ++$i) { 563 if( rand(0,9) < 6 ) { 564 // Digits 565 $d .= chr( ord('1') + rand(0,8) ); 566 } 567 else { 568 // Letters 569 do { 570 $offset = rand(0,25); 571 } while ( $offset==14 ); 572 $d .= chr( ord('a') + $offset ); 573 } 574 } 575 $this->iData = $d; 576 return $d; 577 577 } 578 578 579 579 function Stroke() { 580 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 581 $n=strlen($this->iData); 582 if( $n==0 ) { 583 return false; 584 } 585 586 for($i=0; $i < $n; ++$i ) { 587 if( $this->iData[$i]==='0' || strtolower($this->iData[$i])==='o') { 588 return false; 589 } 590 } 591 592 $img = @imagecreatetruecolor($n*$this->iDD->iWidth, $this->iDD->iHeight); 593 if( $img < 1 ) { 594 return false; 595 } 596 597 $start=0; 598 for($i=0; $i < $n; ++$i ) { 599 $dimg = imagecreatefromstring(base64_decode($this->iDD->chars[strtolower($this->iData[$i])][1])); 600 imagecopy($img,$dimg,$start,0,0,0,imagesx($dimg), $this->iDD->iHeight); 601 $start += imagesx($dimg); 602 } 603 $resimg = @imagecreatetruecolor($start+4, $this->iDD->iHeight+4); 604 if( $resimg < 1 ) { 605 return false; 606 } 607 608 imagecopy($resimg,$img,2,2,0,0,$start, $this->iDD->iHeight); 609 header("Content-type: image/jpeg"); 610 imagejpeg($resimg); 611 return true; 612 612 } 613 613 } -
trunk/client/modules/Elezioni/grafici/jpgraph_bar.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_BAR.PHP4 // Description:Bar plot extension for JpGraph5 // Created:2001-01-086 // Ver: $Id: jpgraph_bar.php 1017 2008-07-08 06:09:28Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */3 // File: JPGRAPH_BAR.PHP 4 // Description: Bar plot extension for JpGraph 5 // Created: 2001-01-08 6 // Ver: $Id: jpgraph_bar.php 1905 2009-10-06 18:00:21Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 require_once('jpgraph_plotband.php'); … … 26 26 //=================================================== 27 27 // CLASS BarPlot 28 // Description: Main code to produce a bar plot 28 // Description: Main code to produce a bar plot 29 29 //=================================================== 30 30 class BarPlot extends Plot { … … 37 37 protected $width=0.4; // in percent of major ticks 38 38 protected $abswidth=-1; // Width in absolute pixels 39 protected $ybase=0; // Bars start at 0 39 protected $ybase=0; // Bars start at 0 40 40 protected $align="center"; 41 41 protected $bar_shadow=false; 42 42 protected $bar_shadow_color="black"; 43 protected $bar_shadow_hsize=3,$bar_shadow_vsize=3; 44 45 //--------------- 46 // CONSTRUCTOR 47 function BarPlot($datay,$datax=false) { 48 $this->Plot($datay,$datax); 49 ++$this->numpoints; 50 } 51 52 //--------------- 53 // PUBLIC METHODS 54 43 protected $bar_shadow_hsize=3,$bar_shadow_vsize=3; 44 protected $bar_3d=false; 45 protected $bar_3d_hsize=3,$bar_3d_vsize=3; 46 47 //--------------- 48 // CONSTRUCTOR 49 function __construct($datay,$datax=false) { 50 parent::__construct($datay,$datax); 51 ++$this->numpoints; 52 } 53 54 //--------------- 55 // PUBLIC METHODS 56 55 57 // Set a drop shadow for the bar (or rather an "up-right" shadow) 56 function SetShadow($color="black",$hsize=3,$vsize=3,$show=true) { 57 $this->bar_shadow=$show; 58 $this->bar_shadow_color=$color; 59 $this->bar_shadow_vsize=$vsize; 60 $this->bar_shadow_hsize=$hsize; 61 62 // Adjust the value margin to compensate for shadow 63 $this->value->margin += $vsize; 64 } 65 58 function SetShadow($aColor="black",$aHSize=3,$aVSize=3,$aShow=true) { 59 $this->bar_shadow=$aShow; 60 $this->bar_shadow_color=$aColor; 61 $this->bar_shadow_vsize=$aVSize; 62 $this->bar_shadow_hsize=$aHSize; 63 64 // Adjust the value margin to compensate for shadow 65 $this->value->margin += $aVSize; 66 } 67 68 function Set3D($aHSize=3,$aVSize=3,$aShow=true) { 69 $this->bar_3d=$aShow; 70 $this->bar_3d_vsize=$aVSize; 71 $this->bar_3d_hsize=$aHSize; 72 73 $this->value->margin += $aVSize; 74 } 75 66 76 // DEPRECATED use SetYBase instead 67 77 function SetYMin($aYStartValue) { 68 //die("JpGraph Error: Deprecated function SetYMin. Use SetYBase() instead."); 69 78 //die("JpGraph Error: Deprecated function SetYMin. Use SetYBase() instead."); 79 $this->ybase=$aYStartValue; 70 80 } 71 81 72 82 // Specify the base value for the bars 73 83 function SetYBase($aYStartValue) { 74 $this->ybase=$aYStartValue; 75 } 76 84 $this->ybase=$aYStartValue; 85 } 86 87 // The method will take the specified pattern anre 88 // return a pattern index that corresponds to the original 89 // patterm being rotated 90 degreees. This is needed when plottin 90 // Horizontal bars 91 function RotatePattern($aPat,$aRotate=true) { 92 $rotate = array(1 => 2, 2 => 1, 3 => 3, 4 => 5, 5 => 4, 6 => 6, 7 => 7, 8 => 8); 93 if( $aRotate ) { 94 return $rotate[$aPat]; 95 } 96 else { 97 return $aPat; 98 } 99 } 100 77 101 function Legend($graph) { 78 if( $this->grad && $this->legend!="" && !$this->fill ) { 79 $color=array($this->grad_fromcolor,$this->grad_tocolor); 80 // In order to differentiate between gradients and cooors specified as an RGB triple 81 $graph->legend->Add($this->legend,$color,"",-$this->grad_style, 82 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 83 } 84 elseif( $this->legend!="" && ($this->iPattern > -1 || is_array($this->iPattern)) ) { 85 if( is_array($this->iPattern) ) { 86 $p1 = $this->iPattern[0]; 87 $p2 = $this->iPatternColor[0]; 88 $p3 = $this->iPatternDensity[0]; 89 } 90 else { 91 $p1 = $this->iPattern; 92 $p2 = $this->iPatternColor; 93 $p3 = $this->iPatternDensity; 94 } 95 $color = array($p1,$p2,$p3,$this->fill_color); 96 // A kludge: Too mark that we add a pattern we use a type value of < 100 97 $graph->legend->Add($this->legend,$color,"",-101, 98 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 99 } 100 elseif( $this->fill_color && $this->legend!="" ) { 101 if( is_array($this->fill_color) ) { 102 $graph->legend->Add($this->legend,$this->fill_color[0],"",0, 103 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 104 } 105 else { 106 $graph->legend->Add($this->legend,$this->fill_color,"",0, 107 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 108 } 109 } 102 if( $this->grad && $this->legend!="" && !$this->fill ) { 103 $color=array($this->grad_fromcolor,$this->grad_tocolor); 104 // In order to differentiate between gradients and cooors specified as an RGB triple 105 $graph->legend->Add($this->legend,$color,"",-$this->grad_style, 106 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 107 } 108 elseif( $this->legend!="" && ($this->iPattern > -1 || is_array($this->iPattern)) ) { 109 if( is_array($this->iPattern) ) { 110 $p1 = $this->RotatePattern( $this->iPattern[0], $graph->img->a == 90 ); 111 $p2 = $this->iPatternColor[0]; 112 $p3 = $this->iPatternDensity[0]; 113 } 114 else { 115 $p1 = $this->RotatePattern( $this->iPattern, $graph->img->a == 90 ); 116 $p2 = $this->iPatternColor; 117 $p3 = $this->iPatternDensity; 118 } 119 if( $p3 < 90 ) $p3 += 5; 120 $color = array($p1,$p2,$p3,$this->fill_color); 121 // A kludge: Too mark that we add a pattern we use a type value of < 100 122 $graph->legend->Add($this->legend,$color,"",-101, 123 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 124 } 125 elseif( $this->fill_color && $this->legend!="" ) { 126 if( is_array($this->fill_color) ) { 127 $graph->legend->Add($this->legend,$this->fill_color[0],"",0, 128 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 129 } 130 else { 131 $graph->legend->Add($this->legend,$this->fill_color,"",0, 132 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 133 } 134 } 110 135 } 111 136 112 137 // Gets called before any axis are stroked 113 138 function PreStrokeAdjust($graph) { 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 // Center the bars 129 130 131 132 133 134 135 136 $graph->SetTextScaleOff(1-$this->width); 137 138 139 elseif( ($this instanceof AccBarPlot) || ($this instanceof GroupBarPlot) ) { 140 141 142 143 139 parent::PreStrokeAdjust($graph); 140 141 // If we are using a log Y-scale we want the base to be at the 142 // minimum Y-value unless the user have specifically set some other 143 // value than the default. 144 if( substr($graph->axtype,-3,3)=="log" && $this->ybase==0 ) 145 $this->ybase = $graph->yaxis->scale->GetMinVal(); 146 147 // For a "text" X-axis scale we will adjust the 148 // display of the bars a little bit. 149 if( substr($graph->axtype,0,3)=="tex" ) { 150 // Position the ticks between the bars 151 $graph->xaxis->scale->ticks->SetXLabelOffset(0.5,0); 152 153 // Center the bars 154 if( $this->abswidth > -1 ) { 155 $graph->SetTextScaleAbsCenterOff($this->abswidth); 156 } 157 else { 158 if( $this->align == "center" ) 159 $graph->SetTextScaleOff(0.5-$this->width/2); 160 elseif( $this->align == "right" ) 161 $graph->SetTextScaleOff(1-$this->width); 162 } 163 } 164 elseif( ($this instanceof AccBarPlot) || ($this instanceof GroupBarPlot) ) { 165 // We only set an absolute width for linear and int scale 166 // for text scale the width will be set to a fraction of 167 // the majstep width. 168 if( $this->abswidth == -1 ) { 144 169 // Not set 145 146 147 148 170 // set width to a visuable sensible default 171 $this->abswidth = $graph->img->plotwidth/(2*$this->numpoints); 172 } 173 } 149 174 } 150 175 151 176 function Min() { 152 $m = parent::Min(); 153 if( $m[1] >= $this->ybase ) 154 $m[1] = $this->ybase; 155 return $m; 177 $m = parent::Min(); 178 if( $m[1] >= $this->ybase ) $m[1] = $this->ybase; 179 return $m; 156 180 } 157 181 158 182 function Max() { 159 $m = parent::Max(); 160 if( $m[1] <= $this->ybase ) 161 $m[1] = $this->ybase; 162 return $m; 163 } 164 183 $m = parent::Max(); 184 if( $m[1] <= $this->ybase ) $m[1] = $this->ybase; 185 return $m; 186 } 187 165 188 // Specify width as fractions of the major stepo size 166 189 function SetWidth($aWidth) { 167 if( $aWidth > 1 ) { 168 // Interpret this as absolute width 169 $this->abswidth=$aWidth; 170 } 171 else 172 $this->width=$aWidth; 173 } 174 190 if( $aWidth > 1 ) { 191 // Interpret this as absolute width 192 $this->abswidth=$aWidth; 193 } 194 else { 195 $this->width=$aWidth; 196 } 197 } 198 175 199 // Specify width in absolute pixels. If specified this 176 200 // overrides SetWidth() 177 201 function SetAbsWidth($aWidth) { 178 179 } 180 202 $this->abswidth=$aWidth; 203 } 204 181 205 function SetAlign($aAlign) { 182 183 } 184 206 $this->align=$aAlign; 207 } 208 185 209 function SetNoFill() { 186 187 188 189 } 190 210 $this->grad = false; 211 $this->fill_color=false; 212 $this->fill=false; 213 } 214 191 215 function SetFillColor($aColor) { 192 $this->fill = true ; 193 $this->fill_color=$aColor; 194 } 195 216 // Do an extra error check if the color is specified as an RGB array triple 217 // In that case convert it to a hex string since it will otherwise be 218 // interpretated as an array of colors for each individual bar. 219 220 $aColor = RGB::tryHexConversion($aColor); 221 $this->fill = true ; 222 $this->fill_color=$aColor; 223 224 } 225 196 226 function SetFillGradient($aFromColor,$aToColor=null,$aStyle=null) { 197 198 199 200 201 } 202 227 $this->grad = true; 228 $this->grad_fromcolor = $aFromColor; 229 $this->grad_tocolor = $aToColor; 230 $this->grad_style = $aStyle; 231 } 232 203 233 function SetValuePos($aPos) { 204 234 $this->valuepos = $aPos; 205 235 } 206 236 207 237 function SetPattern($aPattern, $aColor='black'){ 208 if( is_array($aPattern) ) { 209 $n = count($aPattern); 210 $this->iPattern = array(); 211 $this->iPatternDensity = array(); 212 if( is_array($aColor) ) { 213 $this->iPatternColor = array(); 214 if( count($aColor) != $n ) { 215 JpGraphError::RaiseL(2001);//('NUmber of colors is not the same as the number of patterns in BarPlot::SetPattern()'); 216 } 217 } 218 else 219 $this->iPatternColor = $aColor; 220 for( $i=0; $i < $n; ++$i ) { 221 $this->_SetPatternHelper($aPattern[$i], $this->iPattern[$i], $this->iPatternDensity[$i]); 222 if( is_array($aColor) ) { 223 $this->iPatternColor[$i] = $aColor[$i]; 224 } 225 } 226 } 227 else { 228 $this->_SetPatternHelper($aPattern, $this->iPattern, $this->iPatternDensity); 229 $this->iPatternColor = $aColor; 230 } 238 if( is_array($aPattern) ) { 239 $n = count($aPattern); 240 $this->iPattern = array(); 241 $this->iPatternDensity = array(); 242 if( is_array($aColor) ) { 243 $this->iPatternColor = array(); 244 if( count($aColor) != $n ) { 245 JpGraphError::RaiseL(2001);//('NUmber of colors is not the same as the number of patterns in BarPlot::SetPattern()'); 246 } 247 } 248 else { 249 $this->iPatternColor = $aColor; 250 } 251 for( $i=0; $i < $n; ++$i ) { 252 $this->_SetPatternHelper($aPattern[$i], $this->iPattern[$i], $this->iPatternDensity[$i]); 253 if( is_array($aColor) ) { 254 $this->iPatternColor[$i] = $aColor[$i]; 255 } 256 } 257 } 258 else { 259 $this->_SetPatternHelper($aPattern, $this->iPattern, $this->iPatternDensity); 260 $this->iPatternColor = $aColor; 261 } 231 262 } 232 263 233 264 function _SetPatternHelper($aPattern, &$aPatternValue, &$aDensity){ 234 switch( $aPattern ) { 235 case PATTERN_DIAG1: 236 $aPatternValue= 1; 237 $aDensity = 90; 238 break; 239 case PATTERN_DIAG2: 240 $aPatternValue= 1; 241 $aDensity = 75; 242 break; 243 case PATTERN_DIAG3: 244 $aPatternValue= 2; 245 $aDensity = 90; 246 break; 247 case PATTERN_DIAG4: 248 $aPatternValue= 2; 249 $aDensity = 75; 250 break; 251 case PATTERN_CROSS1: 252 $aPatternValue= 8; 253 $aDensity = 90; 254 break; 255 case PATTERN_CROSS2: 256 $aPatternValue= 8; 257 $aDensity = 78; 258 break; 259 case PATTERN_CROSS3: 260 $aPatternValue= 8; 261 $aDensity = 65; 262 break; 263 case PATTERN_CROSS4: 264 $aPatternValue= 7; 265 $aDensity = 90; 266 break; 267 case PATTERN_STRIPE1: 268 $aPatternValue= 5; 269 $aDensity = 90; 270 break; 271 case PATTERN_STRIPE2: 272 $aPatternValue= 5; 273 $aDensity = 75; 274 break; 275 default: 276 JpGraphError::RaiseL(2002); 277 //('Unknown pattern specified in call to BarPlot::SetPattern()'); 278 } 279 } 280 281 function Stroke($img,$xscale,$yscale) { 282 283 $numpoints = count($this->coords[0]); 284 if( isset($this->coords[1]) ) { 285 if( count($this->coords[1])!=$numpoints ) 286 JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints); 287 //"Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])."Number of Y-points:$numpoints"); 288 else 289 $exist_x = true; 290 } 291 else 292 $exist_x = false; 293 294 295 $numbars=count($this->coords[0]); 296 297 // Use GetMinVal() instead of scale[0] directly since in the case 298 // of log scale we get a correct value. Log scales will have negative 299 // values for values < 1 while still not representing negative numbers. 300 if( $yscale->GetMinVal() >= 0 ) 301 $zp=$yscale->scale_abs[0]; 302 else { 303 $zp=$yscale->Translate(0); 304 } 305 306 if( $this->abswidth > -1 ) { 307 $abswidth=$this->abswidth; 308 } 309 else 310 $abswidth=round($this->width*$xscale->scale_factor,0); 311 312 // Count pontetial pattern array to avoid doing the count for each iteration 313 if( is_array($this->iPattern) ) { 314 $np = count($this->iPattern); 315 } 316 317 $grad = null; 318 for($i=0; $i < $numbars; ++$i) { 319 320 // If value is NULL, or 0 then don't draw a bar at all 321 if ($this->coords[0][$i] === null || $this->coords[0][$i] === '' ) 322 continue; 323 324 if( $exist_x ) $x=$this->coords[1][$i]; 325 else $x=$i; 326 327 $x=$xscale->Translate($x); 328 329 // Comment Note: This confuses the positioning when using acc together with 330 // grouped bars. Workaround for fixing #191 331 /* 332 if( !$xscale->textscale ) { 333 if($this->align=="center") 334 $x -= $abswidth/2; 335 elseif($this->align=="right") 336 $x -= $abswidth; 337 } 338 */ 339 // Stroke fill color and fill gradient 340 $pts=array( 341 $x,$zp, 342 $x,$yscale->Translate($this->coords[0][$i]), 343 $x+$abswidth,$yscale->Translate($this->coords[0][$i]), 344 $x+$abswidth,$zp); 345 if( $this->grad ) { 346 if( $grad === null ) 347 $grad = new Gradient($img); 348 if( is_array($this->grad_fromcolor) ) { 349 // The first argument (grad_fromcolor) can be either an array or a single color. If it is an array 350 // then we have two choices. It can either a) be a single color specified as an RGB triple or it can be 351 // an array to specify both (from, to style) for each individual bar. The way to know the difference is 352 // to investgate the first element. If this element is an integer [0,255] then we assume it is an RGB 353 // triple. 354 $ng = count($this->grad_fromcolor); 355 if( $ng === 3 ) { 356 if( is_numeric($this->grad_fromcolor[0]) && $this->grad_fromcolor[0] > 0 && $this->grad_fromcolor[0] < 256 ) { 357 // RGB Triple 358 $fromcolor = $this->grad_fromcolor; 359 $tocolor = $this->grad_tocolor; 360 $style = $this->grad_style; 361 } 362 } 363 else { 364 $fromcolor = $this->grad_fromcolor[$i % $ng][0]; 365 $tocolor = $this->grad_fromcolor[$i % $ng][1]; 366 $style = $this->grad_fromcolor[$i % $ng][2]; 367 } 368 $grad->FilledRectangle($pts[2],$pts[3], 369 $pts[6],$pts[7], 370 $fromcolor,$tocolor,$style); 371 } 372 else { 373 $grad->FilledRectangle($pts[2],$pts[3], 374 $pts[6],$pts[7], 375 $this->grad_fromcolor,$this->grad_tocolor,$this->grad_style); 376 } 377 } 378 elseif( !empty($this->fill_color) ) { 379 if(is_array($this->fill_color)) { 380 $img->PushColor($this->fill_color[$i % count($this->fill_color)]); 381 } else { 382 $img->PushColor($this->fill_color); 383 } 384 $img->FilledPolygon($pts); 385 $img->PopColor(); 386 } 387 388 389 // Remember value of this bar 390 $val=$this->coords[0][$i]; 391 392 if( !empty($val) && !is_numeric($val) ) { 393 JpGraphError::RaiseL(2004,$i,$val); 394 //'All values for a barplot must be numeric. You have specified value['.$i.'] == \''.$val.'\''); 395 } 396 397 // Determine the shadow 398 if( $this->bar_shadow && $val != 0) { 399 400 $ssh = $this->bar_shadow_hsize; 401 $ssv = $this->bar_shadow_vsize; 402 // Create points to create a "upper-right" shadow 403 if( $val > 0 ) { 404 $sp[0]=$pts[6]; $sp[1]=$pts[7]; 405 $sp[2]=$pts[4]; $sp[3]=$pts[5]; 406 $sp[4]=$pts[2]; $sp[5]=$pts[3]; 407 $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv; 408 $sp[8]=$pts[4]+$ssh; $sp[9]=$pts[5]-$ssv; 409 $sp[10]=$pts[6]+$ssh; $sp[11]=$pts[7]-$ssv; 410 } 411 elseif( $val < 0 ) { 412 $sp[0]=$pts[4]; $sp[1]=$pts[5]; 413 $sp[2]=$pts[6]; $sp[3]=$pts[7]; 414 $sp[4]=$pts[0]; $sp[5]=$pts[1]; 415 $sp[6]=$pts[0]+$ssh; $sp[7]=$pts[1]-$ssv; 416 $sp[8]=$pts[6]+$ssh; $sp[9]=$pts[7]-$ssv; 417 $sp[10]=$pts[4]+$ssh; $sp[11]=$pts[5]-$ssv; 418 } 419 if( is_array($this->bar_shadow_color) ) { 420 $numcolors = count($this->bar_shadow_color); 421 if( $numcolors == 0 ) { 422 JpGraphError::RaiseL(2005);//('You have specified an empty array for shadow colors in the bar plot.'); 423 } 424 $img->PushColor($this->bar_shadow_color[$i % $numcolors]); 425 } 426 else { 427 $img->PushColor($this->bar_shadow_color); 428 } 429 $img->FilledPolygon($sp); 430 $img->PopColor(); 431 } 432 433 // Stroke the pattern 434 if( is_array($this->iPattern) ) { 435 $f = new RectPatternFactory(); 436 if( is_array($this->iPatternColor) ) { 437 $pcolor = $this->iPatternColor[$i % $np]; 438 } 439 else 440 $pcolor = $this->iPatternColor; 441 $prect = $f->Create($this->iPattern[$i % $np],$pcolor,1); 442 $prect->SetDensity($this->iPatternDensity[$i % $np]); 443 444 if( $val < 0 ) { 445 $rx = $pts[0]; 446 $ry = $pts[1]; 447 } 448 else { 449 $rx = $pts[2]; 450 $ry = $pts[3]; 451 } 452 $width = abs($pts[4]-$pts[0])+1; 453 $height = abs($pts[1]-$pts[3])+1; 454 $prect->SetPos(new Rectangle($rx,$ry,$width,$height)); 455 $prect->Stroke($img); 456 } 457 else { 458 if( $this->iPattern > -1 ) { 459 $f = new RectPatternFactory(); 460 $prect = $f->Create($this->iPattern,$this->iPatternColor,1); 461 $prect->SetDensity($this->iPatternDensity); 462 if( $val < 0 ) { 463 $rx = $pts[0]; 464 $ry = $pts[1]; 465 } 466 else { 467 $rx = $pts[2]; 468 $ry = $pts[3]; 469 } 470 $width = abs($pts[4]-$pts[0])+1; 471 $height = abs($pts[1]-$pts[3])+1; 472 $prect->SetPos(new Rectangle($rx,$ry,$width,$height)); 473 $prect->Stroke($img); 474 } 475 } 476 // Stroke the outline of the bar 477 if( is_array($this->color) ) 478 $img->SetColor($this->color[$i % count($this->color)]); 479 else 480 $img->SetColor($this->color); 481 482 $pts[] = $pts[0]; 483 $pts[] = $pts[1]; 484 485 if( $this->weight > 0 ) { 486 $img->SetLineWeight($this->weight); 487 $img->Polygon($pts); 488 } 489 490 // Determine how to best position the values of the individual bars 491 $x=$pts[2]+($pts[4]-$pts[2])/2; 492 $this->value->SetMargin(5); 493 494 if( $this->valuepos=='top' ) { 495 $y=$pts[3]; 496 if( $img->a === 90 ) { 497 if( $val < 0 ) 498 $this->value->SetAlign('right','center'); 499 else 500 $this->value->SetAlign('left','center'); 501 502 } 503 else { 504 if( $val < 0 ) { 505 $this->value->SetMargin(-5); 506 $y=$pts[1]; 507 $this->value->SetAlign('center','bottom'); 508 } 509 else { 510 $this->value->SetAlign('center','bottom'); 511 } 512 513 } 514 $this->value->Stroke($img,$val,$x,$y); 515 } 516 elseif( $this->valuepos=='max' ) { 517 $y=$pts[3]; 518 if( $img->a === 90 ) { 519 if( $val < 0 ) 520 $this->value->SetAlign('left','center'); 521 else 522 $this->value->SetAlign('right','center'); 523 } 524 else { 525 if( $val < 0 ) { 526 $this->value->SetAlign('center','bottom'); 527 } 528 else { 529 $this->value->SetAlign('center','top'); 530 } 531 } 532 $this->value->SetMargin(-5); 533 $this->value->Stroke($img,$val,$x,$y); 534 } 535 elseif( $this->valuepos=='center' ) { 536 $y = ($pts[3] + $pts[1])/2; 537 $this->value->SetAlign('center','center'); 538 $this->value->SetMargin(0); 539 $this->value->Stroke($img,$val,$x,$y); 540 } 541 elseif( $this->valuepos=='bottom' || $this->valuepos=='min' ) { 542 $y=$pts[1]; 543 if( $img->a === 90 ) { 544 if( $val < 0 ) 545 $this->value->SetAlign('right','center'); 546 else 547 $this->value->SetAlign('left','center'); 548 } 549 $this->value->SetMargin(3); 550 $this->value->Stroke($img,$val,$x,$y); 551 } 552 else { 553 JpGraphError::RaiseL(2006,$this->valuepos); 554 //'Unknown position for values on bars :'.$this->valuepos); 555 } 556 // Create the client side image map 557 $rpts = $img->ArrRotate($pts); 558 $csimcoord=round($rpts[0]).", ".round($rpts[1]); 559 for( $j=1; $j < 4; ++$j){ 560 $csimcoord .= ", ".round($rpts[2*$j]).", ".round($rpts[2*$j+1]); 561 } 562 if( !empty($this->csimtargets[$i]) ) { 563 $this->csimareas .= '<area shape="poly" coords="'.$csimcoord.'" '; 564 $this->csimareas .= " href=\"".htmlentities($this->csimtargets[$i])."\""; 565 566 if( !empty($this->csimwintargets[$i]) ) { 567 $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; 568 } 569 570 $sval=''; 571 if( !empty($this->csimalts[$i]) ) { 572 $sval=sprintf($this->csimalts[$i],$this->coords[0][$i]); 573 $this->csimareas .= " title=\"$sval\" alt=\"$sval\" "; 574 } 575 $this->csimareas .= " />\n"; 576 } 577 } 578 return true; 265 switch( $aPattern ) { 266 case PATTERN_DIAG1: 267 $aPatternValue= 1; 268 $aDensity = 92; 269 break; 270 case PATTERN_DIAG2: 271 $aPatternValue= 1; 272 $aDensity = 78; 273 break; 274 case PATTERN_DIAG3: 275 $aPatternValue= 2; 276 $aDensity = 92; 277 break; 278 case PATTERN_DIAG4: 279 $aPatternValue= 2; 280 $aDensity = 78; 281 break; 282 case PATTERN_CROSS1: 283 $aPatternValue= 8; 284 $aDensity = 90; 285 break; 286 case PATTERN_CROSS2: 287 $aPatternValue= 8; 288 $aDensity = 78; 289 break; 290 case PATTERN_CROSS3: 291 $aPatternValue= 8; 292 $aDensity = 65; 293 break; 294 case PATTERN_CROSS4: 295 $aPatternValue= 7; 296 $aDensity = 90; 297 break; 298 case PATTERN_STRIPE1: 299 $aPatternValue= 5; 300 $aDensity = 94; 301 break; 302 case PATTERN_STRIPE2: 303 $aPatternValue= 5; 304 $aDensity = 85; 305 break; 306 default: 307 JpGraphError::RaiseL(2002); 308 //('Unknown pattern specified in call to BarPlot::SetPattern()'); 309 } 310 } 311 312 function Stroke($img,$xscale,$yscale) { 313 314 $numpoints = count($this->coords[0]); 315 if( isset($this->coords[1]) ) { 316 if( count($this->coords[1])!=$numpoints ) { 317 JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints); 318 //"Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])."Number of Y-points:$numpoints"); 319 } 320 else { 321 $exist_x = true; 322 } 323 } 324 else { 325 $exist_x = false; 326 } 327 328 329 $numbars=count($this->coords[0]); 330 331 // Use GetMinVal() instead of scale[0] directly since in the case 332 // of log scale we get a correct value. Log scales will have negative 333 // values for values < 1 while still not representing negative numbers. 334 if( $yscale->GetMinVal() >= 0 ) 335 $zp=$yscale->scale_abs[0]; 336 else { 337 $zp=$yscale->Translate(0); 338 } 339 340 if( $this->abswidth > -1 ) { 341 $abswidth=$this->abswidth; 342 } 343 else { 344 $abswidth=round($this->width*$xscale->scale_factor,0); 345 } 346 347 // Count pontetial pattern array to avoid doing the count for each iteration 348 if( is_array($this->iPattern) ) { 349 $np = count($this->iPattern); 350 } 351 352 $grad = null; 353 for($i=0; $i < $numbars; ++$i) { 354 355 // If value is NULL, or 0 then don't draw a bar at all 356 if ($this->coords[0][$i] === null || $this->coords[0][$i] === '' ) 357 continue; 358 359 if( $exist_x ) { 360 $x=$this->coords[1][$i]; 361 } 362 else { 363 $x=$i; 364 } 365 366 $x=$xscale->Translate($x); 367 368 // Comment Note: This confuses the positioning when using acc together with 369 // grouped bars. Workaround for fixing #191 370 /* 371 if( !$xscale->textscale ) { 372 if($this->align=="center") 373 $x -= $abswidth/2; 374 elseif($this->align=="right") 375 $x -= $abswidth; 376 } 377 */ 378 // Stroke fill color and fill gradient 379 $pts=array( 380 $x,$zp, 381 $x,$yscale->Translate($this->coords[0][$i]), 382 $x+$abswidth,$yscale->Translate($this->coords[0][$i]), 383 $x+$abswidth,$zp); 384 if( $this->grad ) { 385 if( $grad === null ) { 386 $grad = new Gradient($img); 387 } 388 if( is_array($this->grad_fromcolor) ) { 389 // The first argument (grad_fromcolor) can be either an array or a single color. If it is an array 390 // then we have two choices. It can either a) be a single color specified as an RGB triple or it can be 391 // an array to specify both (from, to style) for each individual bar. The way to know the difference is 392 // to investgate the first element. If this element is an integer [0,255] then we assume it is an RGB 393 // triple. 394 $ng = count($this->grad_fromcolor); 395 if( $ng === 3 ) { 396 if( is_numeric($this->grad_fromcolor[0]) && $this->grad_fromcolor[0] > 0 && $this->grad_fromcolor[0] < 256 ) { 397 // RGB Triple 398 $fromcolor = $this->grad_fromcolor; 399 $tocolor = $this->grad_tocolor; 400 $style = $this->grad_style; 401 } 402 else { 403 $fromcolor = $this->grad_fromcolor[$i % $ng][0]; 404 $tocolor = $this->grad_fromcolor[$i % $ng][1]; 405 $style = $this->grad_fromcolor[$i % $ng][2]; 406 } 407 } 408 else { 409 $fromcolor = $this->grad_fromcolor[$i % $ng][0]; 410 $tocolor = $this->grad_fromcolor[$i % $ng][1]; 411 $style = $this->grad_fromcolor[$i % $ng][2]; 412 } 413 $grad->FilledRectangle($pts[2],$pts[3], 414 $pts[6],$pts[7], 415 $fromcolor,$tocolor,$style); 416 } 417 else { 418 $grad->FilledRectangle($pts[2],$pts[3], 419 $pts[6],$pts[7], 420 $this->grad_fromcolor,$this->grad_tocolor,$this->grad_style); 421 } 422 } 423 elseif( !empty($this->fill_color) ) { 424 if(is_array($this->fill_color)) { 425 $img->PushColor($this->fill_color[$i % count($this->fill_color)]); 426 } else { 427 $img->PushColor($this->fill_color); 428 } 429 $img->FilledPolygon($pts); 430 $img->PopColor(); 431 } 432 433 /////////////////////////kokorahen rectangle polygon////////////////////// 434 435 // Remember value of this bar 436 $val=$this->coords[0][$i]; 437 438 if( !empty($val) && !is_numeric($val) ) { 439 JpGraphError::RaiseL(2004,$i,$val); 440 //'All values for a barplot must be numeric. You have specified value['.$i.'] == \''.$val.'\''); 441 } 442 443 // Determine the shadow 444 if( $this->bar_shadow && $val != 0) { 445 446 $ssh = $this->bar_shadow_hsize; 447 $ssv = $this->bar_shadow_vsize; 448 // Create points to create a "upper-right" shadow 449 if( $val > 0 ) { 450 $sp[0]=$pts[6]; $sp[1]=$pts[7]; 451 $sp[2]=$pts[4]; $sp[3]=$pts[5]; 452 $sp[4]=$pts[2]; $sp[5]=$pts[3]; 453 $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv; 454 $sp[8]=$pts[4]+$ssh; $sp[9]=$pts[5]-$ssv; 455 $sp[10]=$pts[6]+$ssh; $sp[11]=$pts[7]-$ssv; 456 } 457 elseif( $val < 0 ) { 458 $sp[0]=$pts[4]; $sp[1]=$pts[5]; 459 $sp[2]=$pts[6]; $sp[3]=$pts[7]; 460 $sp[4]=$pts[0]; $sp[5]=$pts[1]; 461 $sp[6]=$pts[0]+$ssh; $sp[7]=$pts[1]-$ssv; 462 $sp[8]=$pts[6]+$ssh; $sp[9]=$pts[7]-$ssv; 463 $sp[10]=$pts[4]+$ssh; $sp[11]=$pts[5]-$ssv; 464 } 465 if( is_array($this->bar_shadow_color) ) { 466 $numcolors = count($this->bar_shadow_color); 467 if( $numcolors == 0 ) { 468 JpGraphError::RaiseL(2005);//('You have specified an empty array for shadow colors in the bar plot.'); 469 } 470 $img->PushColor($this->bar_shadow_color[$i % $numcolors]); 471 } 472 else { 473 $img->PushColor($this->bar_shadow_color); 474 } 475 $img->FilledPolygon($sp); 476 $img->PopColor(); 477 478 } elseif( $this->bar_3d && $val != 0) { 479 // Determine the 3D 480 481 $ssh = $this->bar_3d_hsize; 482 $ssv = $this->bar_3d_vsize; 483 484 // Create points to create a "upper-right" shadow 485 if( $val > 0 ) { 486 $sp1[0]=$pts[6]; $sp1[1]=$pts[7]; 487 $sp1[2]=$pts[4]; $sp1[3]=$pts[5]; 488 $sp1[4]=$pts[4]+$ssh; $sp1[5]=$pts[5]-$ssv; 489 $sp1[6]=$pts[6]+$ssh; $sp1[7]=$pts[7]-$ssv; 490 491 $sp2[0]=$pts[4]; $sp2[1]=$pts[5]; 492 $sp2[2]=$pts[2]; $sp2[3]=$pts[3]; 493 $sp2[4]=$pts[2]+$ssh; $sp2[5]=$pts[3]-$ssv; 494 $sp2[6]=$pts[4]+$ssh; $sp2[7]=$pts[5]-$ssv; 495 496 } 497 elseif( $val < 0 ) { 498 $sp1[0]=$pts[4]; $sp1[1]=$pts[5]; 499 $sp1[2]=$pts[6]; $sp1[3]=$pts[7]; 500 $sp1[4]=$pts[6]+$ssh; $sp1[5]=$pts[7]-$ssv; 501 $sp1[6]=$pts[4]+$ssh; $sp1[7]=$pts[5]-$ssv; 502 503 $sp2[0]=$pts[6]; $sp2[1]=$pts[7]; 504 $sp2[2]=$pts[0]; $sp2[3]=$pts[1]; 505 $sp2[4]=$pts[0]+$ssh; $sp2[5]=$pts[1]-$ssv; 506 $sp2[6]=$pts[6]+$ssh; $sp2[7]=$pts[7]-$ssv; 507 } 508 509 $base_color = $this->fill_color; 510 511 $img->PushColor($base_color . ':0.7'); 512 $img->FilledPolygon($sp1); 513 $img->PopColor(); 514 515 $img->PushColor($base_color . ':1.1'); 516 $img->FilledPolygon($sp2); 517 $img->PopColor(); 518 } 519 520 // Stroke the pattern 521 if( is_array($this->iPattern) ) { 522 $f = new RectPatternFactory(); 523 if( is_array($this->iPatternColor) ) { 524 $pcolor = $this->iPatternColor[$i % $np]; 525 } 526 else { 527 $pcolor = $this->iPatternColor; 528 } 529 $prect = $f->Create($this->iPattern[$i % $np],$pcolor,1); 530 $prect->SetDensity($this->iPatternDensity[$i % $np]); 531 532 if( $val < 0 ) { 533 $rx = $pts[0]; 534 $ry = $pts[1]; 535 } 536 else { 537 $rx = $pts[2]; 538 $ry = $pts[3]; 539 } 540 $width = abs($pts[4]-$pts[0])+1; 541 $height = abs($pts[1]-$pts[3])+1; 542 $prect->SetPos(new Rectangle($rx,$ry,$width,$height)); 543 $prect->Stroke($img); 544 } 545 else { 546 if( $this->iPattern > -1 ) { 547 $f = new RectPatternFactory(); 548 $prect = $f->Create($this->iPattern,$this->iPatternColor,1); 549 $prect->SetDensity($this->iPatternDensity); 550 if( $val < 0 ) { 551 $rx = $pts[0]; 552 $ry = $pts[1]; 553 } 554 else { 555 $rx = $pts[2]; 556 $ry = $pts[3]; 557 } 558 $width = abs($pts[4]-$pts[0])+1; 559 $height = abs($pts[1]-$pts[3])+1; 560 $prect->SetPos(new Rectangle($rx,$ry,$width,$height)); 561 $prect->Stroke($img); 562 } 563 } 564 565 // Stroke the outline of the bar 566 if( is_array($this->color) ) { 567 $img->SetColor($this->color[$i % count($this->color)]); 568 } 569 else { 570 $img->SetColor($this->color); 571 } 572 573 $pts[] = $pts[0]; 574 $pts[] = $pts[1]; 575 576 if( $this->weight > 0 ) { 577 $img->SetLineWeight($this->weight); 578 $img->Polygon($pts); 579 } 580 581 // Determine how to best position the values of the individual bars 582 $x=$pts[2]+($pts[4]-$pts[2])/2; 583 $this->value->SetMargin(5); 584 585 if( $this->valuepos=='top' ) { 586 $y=$pts[3]; 587 if( $img->a === 90 ) { 588 if( $val < 0 ) { 589 $this->value->SetAlign('right','center'); 590 } 591 else { 592 $this->value->SetAlign('left','center'); 593 } 594 595 } 596 else { 597 if( $val < 0 ) { 598 $this->value->SetMargin(-5); 599 $y=$pts[1]; 600 $this->value->SetAlign('center','bottom'); 601 } 602 else { 603 $this->value->SetAlign('center','bottom'); 604 } 605 606 } 607 $this->value->Stroke($img,$val,$x,$y); 608 } 609 elseif( $this->valuepos=='max' ) { 610 $y=$pts[3]; 611 if( $img->a === 90 ) { 612 if( $val < 0 ) 613 $this->value->SetAlign('left','center'); 614 else 615 $this->value->SetAlign('right','center'); 616 } 617 else { 618 if( $val < 0 ) { 619 $this->value->SetAlign('center','bottom'); 620 } 621 else { 622 $this->value->SetAlign('center','top'); 623 } 624 } 625 $this->value->SetMargin(-5); 626 $this->value->Stroke($img,$val,$x,$y); 627 } 628 elseif( $this->valuepos=='center' ) { 629 $y = ($pts[3] + $pts[1])/2; 630 $this->value->SetAlign('center','center'); 631 $this->value->SetMargin(0); 632 $this->value->Stroke($img,$val,$x,$y); 633 } 634 elseif( $this->valuepos=='bottom' || $this->valuepos=='min' ) { 635 $y=$pts[1]; 636 if( $img->a === 90 ) { 637 if( $val < 0 ) 638 $this->value->SetAlign('right','center'); 639 else 640 $this->value->SetAlign('left','center'); 641 } 642 $this->value->SetMargin(3); 643 $this->value->Stroke($img,$val,$x,$y); 644 } 645 else { 646 JpGraphError::RaiseL(2006,$this->valuepos); 647 //'Unknown position for values on bars :'.$this->valuepos); 648 } 649 // Create the client side image map 650 $rpts = $img->ArrRotate($pts); 651 $csimcoord=round($rpts[0]).", ".round($rpts[1]); 652 for( $j=1; $j < 4; ++$j){ 653 $csimcoord .= ", ".round($rpts[2*$j]).", ".round($rpts[2*$j+1]); 654 } 655 if( !empty($this->csimtargets[$i]) ) { 656 $this->csimareas .= '<area shape="poly" coords="'.$csimcoord.'" '; 657 $this->csimareas .= " href=\"".htmlentities($this->csimtargets[$i])."\""; 658 659 if( !empty($this->csimwintargets[$i]) ) { 660 $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; 661 } 662 663 $sval=''; 664 if( !empty($this->csimalts[$i]) ) { 665 $sval=sprintf($this->csimalts[$i],$this->coords[0][$i]); 666 $this->csimareas .= " title=\"$sval\" alt=\"$sval\" "; 667 } 668 $this->csimareas .= " />\n"; 669 } 670 } 671 return true; 579 672 } 580 673 } // Class … … 585 678 //=================================================== 586 679 class GroupBarPlot extends BarPlot { 587 private $plots, $nbrplots=0; 588 //--------------- 589 // CONSTRUCTOR 590 function GroupBarPlot($plots) { 591 $this->width=0.7; 592 $this->plots = $plots; 593 $this->nbrplots = count($plots); 594 if( $this->nbrplots < 1 ) { 595 JpGraphError::RaiseL(2007);//('Cannot create GroupBarPlot from empty plot array.'); 596 } 597 for($i=0; $i < $this->nbrplots; ++$i ) { 598 if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) { 599 JpGraphError::RaiseL(2008,$i);//("Group bar plot element nbr $i is undefined or empty."); 600 } 601 } 602 $this->numpoints = $plots[0]->numpoints; 603 $this->width=0.7; 604 } 605 606 //--------------- 607 // PUBLIC METHODS 680 public $plots; 681 private $nbrplots=0; 682 //--------------- 683 // CONSTRUCTOR 684 function __construct($plots) { 685 $this->width=0.7; 686 $this->plots = $plots; 687 $this->nbrplots = count($plots); 688 if( $this->nbrplots < 1 ) { 689 JpGraphError::RaiseL(2007);//('Cannot create GroupBarPlot from empty plot array.'); 690 } 691 for($i=0; $i < $this->nbrplots; ++$i ) { 692 if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) { 693 JpGraphError::RaiseL(2008,$i);//("Group bar plot element nbr $i is undefined or empty."); 694 } 695 } 696 $this->numpoints = $plots[0]->numpoints; 697 $this->width=0.7; 698 } 699 700 //--------------- 701 // PUBLIC METHODS 608 702 function Legend($graph) { 609 610 611 612 613 614 //('One of the objects submitted to GroupBar is not a BarPlot. Make sure that you create the Group Bar plot from an array of BarPlot or AccBarPlot objects. (Class = '.$c.')');615 616 617 618 } 619 703 $n = count($this->plots); 704 for($i=0; $i < $n; ++$i) { 705 $c = get_class($this->plots[$i]); 706 if( !($this->plots[$i] instanceof BarPlot) ) { 707 JpGraphError::RaiseL(2009,$c); 708 //('One of the objects submitted to GroupBar is not a BarPlot. Make sure that you create the Group Bar plot from an array of BarPlot or AccBarPlot objects. (Class = '.$c.')'); 709 } 710 $this->plots[$i]->DoLegend($graph); 711 } 712 } 713 620 714 function Min() { 621 622 623 624 625 626 627 628 return array($xmin,$ymin); 629 } 630 715 list($xmin,$ymin) = $this->plots[0]->Min(); 716 $n = count($this->plots); 717 for($i=0; $i < $n; ++$i) { 718 list($xm,$ym) = $this->plots[$i]->Min(); 719 $xmin = max($xmin,$xm); 720 $ymin = min($ymin,$ym); 721 } 722 return array($xmin,$ymin); 723 } 724 631 725 function Max() { 632 633 634 635 636 637 638 639 640 } 641 726 list($xmax,$ymax) = $this->plots[0]->Max(); 727 $n = count($this->plots); 728 for($i=0; $i < $n; ++$i) { 729 list($xm,$ym) = $this->plots[$i]->Max(); 730 $xmax = max($xmax,$xm); 731 $ymax = max($ymax,$ym); 732 } 733 return array($xmax,$ymax); 734 } 735 642 736 function GetCSIMareas() { 643 644 645 646 647 648 649 } 650 737 $n = count($this->plots); 738 $csimareas=''; 739 for($i=0; $i < $n; ++$i) { 740 $csimareas .= $this->plots[$i]->csimareas; 741 } 742 return $csimareas; 743 } 744 651 745 // Stroke all the bars next to each other 652 function Stroke($img,$xscale,$yscale) { 653 654 655 $subwidth = $this->width/$this->nbrplots ; 656 657 658 659 660 661 662 663 664 665 666 667 668 669 746 function Stroke($img,$xscale,$yscale) { 747 $tmp=$xscale->off; 748 $n = count($this->plots); 749 $subwidth = $this->width/$this->nbrplots ; 750 751 for( $i=0; $i < $n; ++$i ) { 752 $this->plots[$i]->ymin=$this->ybase; 753 $this->plots[$i]->SetWidth($subwidth); 754 755 // If the client have used SetTextTickInterval() then 756 // major_step will be > 1 and the positioning will fail. 757 // If we assume it is always one the positioning will work 758 // fine with a text scale but this will not work with 759 // arbitrary linear scale 760 $xscale->off = $tmp+$i*round($xscale->scale_factor* $subwidth); 761 $this->plots[$i]->Stroke($img,$xscale,$yscale); 762 } 763 $xscale->off=$tmp; 670 764 } 671 765 } // Class … … 676 770 //=================================================== 677 771 class AccBarPlot extends BarPlot { 678 private $plots=null,$nbrplots=0; 679 //--------------- 680 // CONSTRUCTOR 681 function AccBarPlot($plots) { 682 $this->plots = $plots; 683 $this->nbrplots = count($plots); 684 if( $this->nbrplots < 1 ) { 685 JpGraphError::RaiseL(2010);//('Cannot create AccBarPlot from empty plot array.'); 686 } 687 for($i=0; $i < $this->nbrplots; ++$i ) { 688 if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) { 689 JpGraphError::RaiseL(2011,$i);//("Acc bar plot element nbr $i is undefined or empty."); 690 } 691 } 692 693 // We can only allow individual plost which do not have specified X-positions 694 for($i=0; $i < $this->nbrplots; ++$i ) { 695 if( !empty($this->plots[$i]->coords[1]) ) { 696 JpGraphError::RaiseL(2015); 697 //'Individual bar plots in an AccBarPlot or GroupBarPlot can not have specified X-positions.'); 698 } 699 } 700 701 $this->numpoints = $plots[0]->numpoints; 702 $this->value = new DisplayValue(); 703 } 704 705 //--------------- 706 // PUBLIC METHODS 772 public $plots=null; 773 private $nbrplots=0; 774 //--------------- 775 // CONSTRUCTOR 776 function __construct($plots) { 777 $this->plots = $plots; 778 $this->nbrplots = count($plots); 779 if( $this->nbrplots < 1 ) { 780 JpGraphError::RaiseL(2010);//('Cannot create AccBarPlot from empty plot array.'); 781 } 782 for($i=0; $i < $this->nbrplots; ++$i ) { 783 if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) { 784 JpGraphError::RaiseL(2011,$i);//("Acc bar plot element nbr $i is undefined or empty."); 785 } 786 } 787 788 // We can only allow individual plost which do not have specified X-positions 789 for($i=0; $i < $this->nbrplots; ++$i ) { 790 if( !empty($this->plots[$i]->coords[1]) ) { 791 JpGraphError::RaiseL(2015); 792 //'Individual bar plots in an AccBarPlot or GroupBarPlot can not have specified X-positions.'); 793 } 794 } 795 796 // Use 0 weight by default which means that the individual bar 797 // weights will be used per part n the accumulated bar 798 $this->SetWeight(0); 799 800 $this->numpoints = $plots[0]->numpoints; 801 $this->value = new DisplayValue(); 802 } 803 804 //--------------- 805 // PUBLIC METHODS 707 806 function Legend($graph) { 708 709 710 711 712 713 //('One of the objects submitted to AccBar is not a BarPlot. Make sure that you create the AccBar plot from an array of BarPlot objects.(Class='.$c.')');714 } 715 716 807 $n = count($this->plots); 808 for( $i=$n-1; $i >= 0; --$i ) { 809 $c = get_class($this->plots[$i]); 810 if( !($this->plots[$i] instanceof BarPlot) ) { 811 JpGraphError::RaiseL(2012,$c); 812 //('One of the objects submitted to AccBar is not a BarPlot. Make sure that you create the AccBar plot from an array of BarPlot objects.(Class='.$c.')'); 813 } 814 $this->plots[$i]->DoLegend($graph); 815 } 717 816 } 718 817 719 818 function Max() { 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 if( $ymax <= $this->ybase ) 753 754 819 list($xmax) = $this->plots[0]->Max(); 820 $nmax=0; 821 for($i=0; $i < count($this->plots); ++$i) { 822 $n = count($this->plots[$i]->coords[0]); 823 $nmax = max($nmax,$n); 824 list($x) = $this->plots[$i]->Max(); 825 $xmax = max($xmax,$x); 826 } 827 for( $i = 0; $i < $nmax; $i++ ) { 828 // Get y-value for bar $i by adding the 829 // individual bars from all the plots added. 830 // It would be wrong to just add the 831 // individual plots max y-value since that 832 // would in most cases give to large y-value. 833 $y=0; 834 if( !isset($this->plots[0]->coords[0][$i]) ) { 835 JpGraphError::RaiseL(2014); 836 } 837 if( $this->plots[0]->coords[0][$i] > 0 ) 838 $y=$this->plots[0]->coords[0][$i]; 839 for( $j = 1; $j < $this->nbrplots; $j++ ) { 840 if( !isset($this->plots[$j]->coords[0][$i]) ) { 841 JpGraphError::RaiseL(2014); 842 } 843 if( $this->plots[$j]->coords[0][$i] > 0 ) 844 $y += $this->plots[$j]->coords[0][$i]; 845 } 846 $ymax[$i] = $y; 847 } 848 $ymax = max($ymax); 849 850 // Bar always start at baseline 851 if( $ymax <= $this->ybase ) 852 $ymax = $this->ybase; 853 return array($xmax,$ymax); 755 854 } 756 855 757 856 function Min() { 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 857 $nmax=0; 858 list($xmin,$ysetmin) = $this->plots[0]->Min(); 859 for($i=0; $i < count($this->plots); ++$i) { 860 $n = count($this->plots[$i]->coords[0]); 861 $nmax = max($nmax,$n); 862 list($x,$y) = $this->plots[$i]->Min(); 863 $xmin = Min($xmin,$x); 864 $ysetmin = Min($y,$ysetmin); 865 } 866 for( $i = 0; $i < $nmax; $i++ ) { 867 // Get y-value for bar $i by adding the 868 // individual bars from all the plots added. 869 // It would be wrong to just add the 870 // individual plots max y-value since that 871 // would in most cases give to large y-value. 872 $y=0; 873 if( $this->plots[0]->coords[0][$i] < 0 ) 874 $y=$this->plots[0]->coords[0][$i]; 875 for( $j = 1; $j < $this->nbrplots; $j++ ) { 876 if( $this->plots[$j]->coords[0][$i] < 0 ) 877 $y += $this->plots[ $j ]->coords[0][$i]; 878 } 879 $ymin[$i] = $y; 880 } 881 $ymin = Min($ysetmin,Min($ymin)); 882 // Bar always start at baseline 883 if( $ymin >= $this->ybase ) 884 $ymin = $this->ybase; 885 return array($xmin,$ymin); 787 886 } 788 887 789 888 // Stroke acc bar plot 790 889 function Stroke($img,$xscale,$yscale) { 791 $pattern=NULL; 792 $img->SetLineWeight($this->weight); 793 for($i=0; $i < $this->numpoints-1; $i++) { 794 $accy = 0; 795 $accy_neg = 0; 796 for($j=0; $j < $this->nbrplots; ++$j ) { 797 $img->SetColor($this->plots[$j]->color); 798 799 if ( $this->plots[$j]->coords[0][$i] >= 0) { 800 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy); 801 $accyt=$yscale->Translate($accy); 802 $accy+=$this->plots[$j]->coords[0][$i]; 803 } 804 else { 805 //if ( $this->plots[$j]->coords[0][$i] < 0 || $accy_neg < 0 ) { 806 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg); 807 $accyt=$yscale->Translate($accy_neg); 808 $accy_neg+=$this->plots[$j]->coords[0][$i]; 809 } 810 811 $xt=$xscale->Translate($i); 812 813 if( $this->abswidth > -1 ) 814 $abswidth=$this->abswidth; 815 else 816 $abswidth=round($this->width*$xscale->scale_factor,0); 817 818 $pts=array($xt,$accyt,$xt,$yt,$xt+$abswidth,$yt,$xt+$abswidth,$accyt); 819 820 if( $this->bar_shadow ) { 821 $ssh = $this->bar_shadow_hsize; 822 $ssv = $this->bar_shadow_vsize; 823 824 // We must also differ if we are a positive or negative bar. 825 if( $j === 0 ) { 826 // This gets extra complicated since we have to 827 // see all plots to see if we are negative. It could 828 // for example be that all plots are 0 until the very 829 // last one. We therefore need to save the initial setup 830 // for both the negative and positive case 831 832 // In case the final bar is positive 833 $sp[0]=$pts[6]+1; $sp[1]=$pts[7]; 834 $sp[2]=$pts[6]+$ssh; $sp[3]=$pts[7]-$ssv; 835 836 // In case the final bar is negative 837 $nsp[0]=$pts[0]; $nsp[1]=$pts[1]; 838 $nsp[2]=$pts[0]+$ssh; $nsp[3]=$pts[1]-$ssv; 839 $nsp[4]=$pts[6]+$ssh; $nsp[5]=$pts[7]-$ssv; 840 $nsp[10]=$pts[6]+1; $nsp[11]=$pts[7]; 841 } 842 843 if( $j === $this->nbrplots-1 ) { 844 // If this is the last plot of the bar and 845 // the total value is larger than 0 then we 846 // add the shadow. 847 if( is_array($this->bar_shadow_color) ) { 848 $numcolors = count($this->bar_shadow_color); 849 if( $numcolors == 0 ) { 850 JpGraphError::RaiseL(2013);//('You have specified an empty array for shadow colors in the bar plot.'); 851 } 852 $img->PushColor($this->bar_shadow_color[$i % $numcolors]); 853 } 854 else { 855 $img->PushColor($this->bar_shadow_color); 856 } 857 858 if( $accy > 0 ) { 859 $sp[4]=$pts[4]+$ssh; $sp[5]=$pts[5]-$ssv; 860 $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv; 861 $sp[8]=$pts[2]; $sp[9]=$pts[3]-1; 862 $sp[10]=$pts[4]+1; $sp[11]=$pts[5]; 863 $img->FilledPolygon($sp,4); 864 } 865 elseif( $accy_neg < 0 ) { 866 $nsp[6]=$pts[4]+$ssh; $nsp[7]=$pts[5]-$ssv; 867 $nsp[8]=$pts[4]+1; $nsp[9]=$pts[5]; 868 $img->FilledPolygon($nsp,4); 869 } 870 $img->PopColor(); 871 } 872 } 873 874 875 // If value is NULL or 0, then don't draw a bar at all 876 if ($this->plots[$j]->coords[0][$i] == 0 ) continue; 877 878 if( $this->plots[$j]->grad ) { 879 $grad = new Gradient($img); 880 $grad->FilledRectangle( 881 $pts[2],$pts[3], 882 $pts[6],$pts[7], 883 $this->plots[$j]->grad_fromcolor, 884 $this->plots[$j]->grad_tocolor, 885 $this->plots[$j]->grad_style); 886 } else { 887 if (is_array($this->plots[$j]->fill_color) ) { 888 $numcolors = count($this->plots[$j]->fill_color); 889 $fillcolor = $this->plots[$j]->fill_color[$i % $numcolors]; 890 // If the bar is specified to be non filled then the fill color is false 891 if( $fillcolor !== false ) 892 $img->SetColor($this->plots[$j]->fill_color[$i % $numcolors]); 893 } 894 else { 895 $fillcolor = $this->plots[$j]->fill_color; 896 if( $fillcolor !== false ) 897 $img->SetColor($this->plots[$j]->fill_color); 898 } 899 if( $fillcolor !== false ) 900 $img->FilledPolygon($pts); 901 $img->SetColor($this->plots[$j]->color); 902 } 903 904 // Stroke the pattern 905 if( $this->plots[$j]->iPattern > -1 ) { 906 if( $pattern===NULL ) 907 $pattern = new RectPatternFactory(); 908 909 $prect = $pattern->Create($this->plots[$j]->iPattern,$this->plots[$j]->iPatternColor,1); 910 $prect->SetDensity($this->plots[$j]->iPatternDensity); 911 if( $this->plots[$j]->coords[0][$i] < 0 ) { 912 $rx = $pts[0]; 913 $ry = $pts[1]; 914 } 915 else { 916 $rx = $pts[2]; 917 $ry = $pts[3]; 918 } 919 $width = abs($pts[4]-$pts[0])+1; 920 $height = abs($pts[1]-$pts[3])+1; 921 $prect->SetPos(new Rectangle($rx,$ry,$width,$height)); 922 $prect->Stroke($img); 923 } 924 925 926 // CSIM array 927 928 if( $i < count($this->plots[$j]->csimtargets) ) { 929 // Create the client side image map 930 $rpts = $img->ArrRotate($pts); 931 $csimcoord=round($rpts[0]).", ".round($rpts[1]); 932 for( $k=1; $k < 4; ++$k){ 933 $csimcoord .= ", ".round($rpts[2*$k]).", ".round($rpts[2*$k+1]); 934 } 935 if( ! empty($this->plots[$j]->csimtargets[$i]) ) { 936 $this->csimareas.= '<area shape="poly" coords="'.$csimcoord.'" '; 937 $this->csimareas.= " href=\"".$this->plots[$j]->csimtargets[$i]."\" "; 938 939 if( ! empty($this->plots[$j]->csimwintargets[$i]) ) { 940 $this->csimareas.= " target=\"".$this->plots[$j]->csimwintargets[$i]."\" "; 941 } 942 943 $sval=''; 944 if( !empty($this->plots[$j]->csimalts[$i]) ) { 945 $sval=sprintf($this->plots[$j]->csimalts[$i],$this->plots[$j]->coords[0][$i]); 946 $this->csimareas .= " title=\"$sval\" "; 947 } 948 $this->csimareas .= " alt=\"$sval\" />\n"; 949 } 950 } 951 952 $pts[] = $pts[0]; 953 $pts[] = $pts[1]; 954 $img->SetLineWeight($this->plots[$j]->line_weight); 955 $img->Polygon($pts); 956 $img->SetLineWeight(1); 957 } 958 959 // Draw labels for each acc.bar 960 961 $x=$pts[2]+($pts[4]-$pts[2])/2; 962 if($this->bar_shadow) $x += $ssh; 963 964 // First stroke the accumulated value for the entire bar 965 // This value is always placed at the top/bottom of the bars 966 if( $accy_neg < 0 ) { 967 $y=$yscale->Translate($accy_neg); 968 $this->value->Stroke($img,$accy_neg,$x,$y); 969 } 970 else { 971 $y=$yscale->Translate($accy); 972 $this->value->Stroke($img,$accy,$x,$y); 973 } 974 975 $accy = 0; 976 $accy_neg = 0; 977 for($j=0; $j < $this->nbrplots; ++$j ) { 978 979 // We don't print 0 values in an accumulated bar plot 980 if( $this->plots[$j]->coords[0][$i] == 0 ) continue; 981 982 if ($this->plots[$j]->coords[0][$i] > 0) { 983 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy); 984 $accyt=$yscale->Translate($accy); 985 if( $this->plots[$j]->valuepos=='center' ) { 986 $y = $accyt-($accyt-$yt)/2; 987 } 988 elseif( $this->plots[$j]->valuepos=='bottom' ) { 989 $y = $accyt; 990 } 991 else { // top or max 992 $y = $accyt-($accyt-$yt); 993 } 994 $accy+=$this->plots[$j]->coords[0][$i]; 995 if( $this->plots[$j]->valuepos=='center' ) { 996 $this->plots[$j]->value->SetAlign("center","center"); 997 $this->plots[$j]->value->SetMargin(0); 998 } 999 elseif( $this->plots[$j]->valuepos=='bottom' ) { 1000 $this->plots[$j]->value->SetAlign('center','bottom'); 1001 $this->plots[$j]->value->SetMargin(2); 1002 } 1003 else { 1004 $this->plots[$j]->value->SetAlign('center','top'); 1005 $this->plots[$j]->value->SetMargin(1); 1006 } 1007 } else { 1008 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg); 1009 $accyt=$yscale->Translate($accy_neg); 1010 $accy_neg+=$this->plots[$j]->coords[0][$i]; 1011 if( $this->plots[$j]->valuepos=='center' ) { 1012 $y = $accyt-($accyt-$yt)/2; 1013 } 1014 elseif( $this->plots[$j]->valuepos=='bottom' ) { 1015 $y = $accyt; 1016 } 1017 else { 1018 $y = $accyt-($accyt-$yt); 1019 } 1020 if( $this->plots[$j]->valuepos=='center' ) { 1021 $this->plots[$j]->value->SetAlign("center","center"); 1022 $this->plots[$j]->value->SetMargin(0); 1023 } 1024 elseif( $this->plots[$j]->valuepos=='bottom' ) { 1025 $this->plots[$j]->value->SetAlign('center',$j==0 ? 'bottom':'top'); 1026 $this->plots[$j]->value->SetMargin(-2); 1027 } 1028 else { 1029 $this->plots[$j]->value->SetAlign('center','bottom'); 1030 $this->plots[$j]->value->SetMargin(-1); 1031 } 1032 } 1033 $this->plots[$j]->value->Stroke($img,$this->plots[$j]->coords[0][$i],$x,$y); 1034 } 1035 1036 } 1037 return true; 890 $pattern=NULL; 891 $img->SetLineWeight($this->weight); 892 $grad=null; 893 for($i=0; $i < $this->numpoints-1; $i++) { 894 $accy = 0; 895 $accy_neg = 0; 896 for($j=0; $j < $this->nbrplots; ++$j ) { 897 $img->SetColor($this->plots[$j]->color); 898 899 if ( $this->plots[$j]->coords[0][$i] >= 0) { 900 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy); 901 $accyt=$yscale->Translate($accy); 902 $accy+=$this->plots[$j]->coords[0][$i]; 903 } 904 else { 905 //if ( $this->plots[$j]->coords[0][$i] < 0 || $accy_neg < 0 ) { 906 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg); 907 $accyt=$yscale->Translate($accy_neg); 908 $accy_neg+=$this->plots[$j]->coords[0][$i]; 909 } 910 911 $xt=$xscale->Translate($i); 912 913 if( $this->abswidth > -1 ) { 914 $abswidth=$this->abswidth; 915 } 916 else { 917 $abswidth=round($this->width*$xscale->scale_factor,0); 918 } 919 920 $pts=array($xt,$accyt,$xt,$yt,$xt+$abswidth,$yt,$xt+$abswidth,$accyt); 921 922 if( $this->bar_shadow ) { 923 $ssh = $this->bar_shadow_hsize; 924 $ssv = $this->bar_shadow_vsize; 925 926 // We must also differ if we are a positive or negative bar. 927 if( $j === 0 ) { 928 // This gets extra complicated since we have to 929 // see all plots to see if we are negative. It could 930 // for example be that all plots are 0 until the very 931 // last one. We therefore need to save the initial setup 932 // for both the negative and positive case 933 934 // In case the final bar is positive 935 $sp[0]=$pts[6]+1; $sp[1]=$pts[7]; 936 $sp[2]=$pts[6]+$ssh; $sp[3]=$pts[7]-$ssv; 937 938 // In case the final bar is negative 939 $nsp[0]=$pts[0]; $nsp[1]=$pts[1]; 940 $nsp[2]=$pts[0]+$ssh; $nsp[3]=$pts[1]-$ssv; 941 $nsp[4]=$pts[6]+$ssh; $nsp[5]=$pts[7]-$ssv; 942 $nsp[10]=$pts[6]+1; $nsp[11]=$pts[7]; 943 } 944 945 if( $j === $this->nbrplots-1 ) { 946 // If this is the last plot of the bar and 947 // the total value is larger than 0 then we 948 // add the shadow. 949 if( is_array($this->bar_shadow_color) ) { 950 $numcolors = count($this->bar_shadow_color); 951 if( $numcolors == 0 ) { 952 JpGraphError::RaiseL(2013);//('You have specified an empty array for shadow colors in the bar plot.'); 953 } 954 $img->PushColor($this->bar_shadow_color[$i % $numcolors]); 955 } 956 else { 957 $img->PushColor($this->bar_shadow_color); 958 } 959 960 if( $accy > 0 ) { 961 $sp[4]=$pts[4]+$ssh; $sp[5]=$pts[5]-$ssv; 962 $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv; 963 $sp[8]=$pts[2]; $sp[9]=$pts[3]-1; 964 $sp[10]=$pts[4]+1; $sp[11]=$pts[5]; 965 $img->FilledPolygon($sp,4); 966 } 967 elseif( $accy_neg < 0 ) { 968 $nsp[6]=$pts[4]+$ssh; $nsp[7]=$pts[5]-$ssv; 969 $nsp[8]=$pts[4]+1; $nsp[9]=$pts[5]; 970 $img->FilledPolygon($nsp,4); 971 } 972 $img->PopColor(); 973 } 974 } 975 976 977 // If value is NULL or 0, then don't draw a bar at all 978 if ($this->plots[$j]->coords[0][$i] == 0 ) continue; 979 980 if( $this->plots[$j]->grad ) { 981 if( $grad === null ) { 982 $grad = new Gradient($img); 983 } 984 if( is_array($this->plots[$j]->grad_fromcolor) ) { 985 // The first argument (grad_fromcolor) can be either an array or a single color. If it is an array 986 // then we have two choices. It can either a) be a single color specified as an RGB triple or it can be 987 // an array to specify both (from, to style) for each individual bar. The way to know the difference is 988 // to investgate the first element. If this element is an integer [0,255] then we assume it is an RGB 989 // triple. 990 $ng = count($this->plots[$j]->grad_fromcolor); 991 if( $ng === 3 ) { 992 if( is_numeric($this->plots[$j]->grad_fromcolor[0]) && $this->plots[$j]->grad_fromcolor[0] > 0 && 993 $this->plots[$j]->grad_fromcolor[0] < 256 ) { 994 // RGB Triple 995 $fromcolor = $this->plots[$j]->grad_fromcolor; 996 $tocolor = $this->plots[$j]->grad_tocolor; 997 $style = $this->plots[$j]->grad_style; 998 } 999 else { 1000 $fromcolor = $this->plots[$j]->grad_fromcolor[$i % $ng][0]; 1001 $tocolor = $this->plots[$j]->grad_fromcolor[$i % $ng][1]; 1002 $style = $this->plots[$j]->grad_fromcolor[$i % $ng][2]; 1003 } 1004 } 1005 else { 1006 $fromcolor = $this->plots[$j]->grad_fromcolor[$i % $ng][0]; 1007 $tocolor = $this->plots[$j]->grad_fromcolor[$i % $ng][1]; 1008 $style = $this->plots[$j]->grad_fromcolor[$i % $ng][2]; 1009 } 1010 $grad->FilledRectangle($pts[2],$pts[3], 1011 $pts[6],$pts[7], 1012 $fromcolor,$tocolor,$style); 1013 } 1014 else { 1015 $grad->FilledRectangle($pts[2],$pts[3], 1016 $pts[6],$pts[7], 1017 $this->plots[$j]->grad_fromcolor, 1018 $this->plots[$j]->grad_tocolor, 1019 $this->plots[$j]->grad_style); 1020 } 1021 } else { 1022 if (is_array($this->plots[$j]->fill_color) ) { 1023 $numcolors = count($this->plots[$j]->fill_color); 1024 $fillcolor = $this->plots[$j]->fill_color[$i % $numcolors]; 1025 // If the bar is specified to be non filled then the fill color is false 1026 if( $fillcolor !== false ) { 1027 $img->SetColor($this->plots[$j]->fill_color[$i % $numcolors]); 1028 } 1029 } 1030 else { 1031 $fillcolor = $this->plots[$j]->fill_color; 1032 if( $fillcolor !== false ) { 1033 $img->SetColor($this->plots[$j]->fill_color); 1034 } 1035 } 1036 if( $fillcolor !== false ) { 1037 $img->FilledPolygon($pts); 1038 } 1039 } 1040 1041 $img->SetColor($this->plots[$j]->color); 1042 1043 // Stroke the pattern 1044 if( $this->plots[$j]->iPattern > -1 ) { 1045 if( $pattern===NULL ) { 1046 $pattern = new RectPatternFactory(); 1047 } 1048 1049 $prect = $pattern->Create($this->plots[$j]->iPattern,$this->plots[$j]->iPatternColor,1); 1050 $prect->SetDensity($this->plots[$j]->iPatternDensity); 1051 if( $this->plots[$j]->coords[0][$i] < 0 ) { 1052 $rx = $pts[0]; 1053 $ry = $pts[1]; 1054 } 1055 else { 1056 $rx = $pts[2]; 1057 $ry = $pts[3]; 1058 } 1059 $width = abs($pts[4]-$pts[0])+1; 1060 $height = abs($pts[1]-$pts[3])+1; 1061 $prect->SetPos(new Rectangle($rx,$ry,$width,$height)); 1062 $prect->Stroke($img); 1063 } 1064 1065 1066 // CSIM array 1067 1068 if( $i < count($this->plots[$j]->csimtargets) ) { 1069 // Create the client side image map 1070 $rpts = $img->ArrRotate($pts); 1071 $csimcoord=round($rpts[0]).", ".round($rpts[1]); 1072 for( $k=1; $k < 4; ++$k){ 1073 $csimcoord .= ", ".round($rpts[2*$k]).", ".round($rpts[2*$k+1]); 1074 } 1075 if( ! empty($this->plots[$j]->csimtargets[$i]) ) { 1076 $this->csimareas.= '<area shape="poly" coords="'.$csimcoord.'" '; 1077 $this->csimareas.= " href=\"".$this->plots[$j]->csimtargets[$i]."\" "; 1078 1079 if( ! empty($this->plots[$j]->csimwintargets[$i]) ) { 1080 $this->csimareas.= " target=\"".$this->plots[$j]->csimwintargets[$i]."\" "; 1081 } 1082 1083 $sval=''; 1084 if( !empty($this->plots[$j]->csimalts[$i]) ) { 1085 $sval=sprintf($this->plots[$j]->csimalts[$i],$this->plots[$j]->coords[0][$i]); 1086 $this->csimareas .= " title=\"$sval\" "; 1087 } 1088 $this->csimareas .= " alt=\"$sval\" />\n"; 1089 } 1090 } 1091 1092 $pts[] = $pts[0]; 1093 $pts[] = $pts[1]; 1094 $img->SetLineWeight($this->plots[$j]->weight); 1095 $img->Polygon($pts); 1096 $img->SetLineWeight(1); 1097 } 1098 1099 // Daw potential bar around the entire accbar bar 1100 if( $this->weight > 0 ) { 1101 $y=$yscale->Translate(0); 1102 $img->SetColor($this->color); 1103 $img->SetLineWeight($this->weight); 1104 $img->Rectangle($pts[0],$y,$pts[6],$pts[5]); 1105 } 1106 1107 // Draw labels for each acc.bar 1108 1109 $x=$pts[2]+($pts[4]-$pts[2])/2; 1110 if($this->bar_shadow) $x += $ssh; 1111 1112 // First stroke the accumulated value for the entire bar 1113 // This value is always placed at the top/bottom of the bars 1114 if( $accy + $accy_neg < 0 ) { 1115 $y=$yscale->Translate($accy_neg); 1116 } 1117 else { 1118 $y=$yscale->Translate($accy); 1119 } 1120 $this->value->Stroke($img,$accy + $accy_neg,$x,$y); 1121 1122 $accy = 0; 1123 $accy_neg = 0; 1124 for($j=0; $j < $this->nbrplots; ++$j ) { 1125 1126 // We don't print 0 values in an accumulated bar plot 1127 if( $this->plots[$j]->coords[0][$i] == 0 ) continue; 1128 1129 if ($this->plots[$j]->coords[0][$i] > 0) { 1130 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy); 1131 $accyt=$yscale->Translate($accy); 1132 if( $this->plots[$j]->valuepos=='center' ) { 1133 $y = $accyt-($accyt-$yt)/2; 1134 } 1135 elseif( $this->plots[$j]->valuepos=='bottom' ) { 1136 $y = $accyt; 1137 } 1138 else { // top or max 1139 $y = $accyt-($accyt-$yt); 1140 } 1141 $accy+=$this->plots[$j]->coords[0][$i]; 1142 if( $this->plots[$j]->valuepos=='center' ) { 1143 $this->plots[$j]->value->SetAlign("center","center"); 1144 $this->plots[$j]->value->SetMargin(0); 1145 } 1146 elseif( $this->plots[$j]->valuepos=='bottom' ) { 1147 $this->plots[$j]->value->SetAlign('center','bottom'); 1148 $this->plots[$j]->value->SetMargin(2); 1149 } 1150 else { 1151 $this->plots[$j]->value->SetAlign('center','top'); 1152 $this->plots[$j]->value->SetMargin(1); 1153 } 1154 } else { 1155 $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg); 1156 $accyt=$yscale->Translate($accy_neg); 1157 $accy_neg+=$this->plots[$j]->coords[0][$i]; 1158 if( $this->plots[$j]->valuepos=='center' ) { 1159 $y = $accyt-($accyt-$yt)/2; 1160 } 1161 elseif( $this->plots[$j]->valuepos=='bottom' ) { 1162 $y = $accyt; 1163 } 1164 else { 1165 $y = $accyt-($accyt-$yt); 1166 } 1167 if( $this->plots[$j]->valuepos=='center' ) { 1168 $this->plots[$j]->value->SetAlign("center","center"); 1169 $this->plots[$j]->value->SetMargin(0); 1170 } 1171 elseif( $this->plots[$j]->valuepos=='bottom' ) { 1172 $this->plots[$j]->value->SetAlign('center',$j==0 ? 'bottom':'top'); 1173 $this->plots[$j]->value->SetMargin(-2); 1174 } 1175 else { 1176 $this->plots[$j]->value->SetAlign('center','bottom'); 1177 $this->plots[$j]->value->SetMargin(-1); 1178 } 1179 } 1180 $this->plots[$j]->value->Stroke($img,$this->plots[$j]->coords[0][$i],round($x),round($y)); 1181 } 1182 1183 } 1184 return true; 1038 1185 } 1039 1186 } // Class -
trunk/client/modules/Elezioni/grafici/jpgraph_canvas.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_CANVAS.PHP4 // Description:Canvas drawing extension for JpGraph5 // Created:2001-01-086 // Ver: $Id: jpgraph_canvas.php 781 2006-10-08 08:07:47Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */3 // File: JPGRAPH_CANVAS.PHP 4 // Description: Canvas drawing extension for JpGraph 5 // Created: 2001-01-08 6 // Ver: $Id: jpgraph_canvas.php 1923 2010-01-11 13:48:49Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 //=================================================== … … 16 16 // primitives. Useful to auickoly produce some arbitrary 17 17 // graphic which benefits from all the functionality in the 18 // graph liek caching for example. 18 // graph liek caching for example. 19 19 //=================================================== 20 20 class CanvasGraph extends Graph { 21 //---------------22 // CONSTRUCTOR23 function CanvasGraph($aWidth=300,$aHeight=200,$aCachedName="",$timeout=0,$inline=1) {24 $this->Graph($aWidth,$aHeight,$aCachedName,$timeout,$inline);21 //--------------- 22 // CONSTRUCTOR 23 function __construct($aWidth=300,$aHeight=200,$aCachedName="",$timeout=0,$inline=1) { 24 parent::__construct($aWidth,$aHeight,$aCachedName,$timeout,$inline); 25 25 } 26 26 27 //---------------28 // PUBLIC METHODS 27 //--------------- 28 // PUBLIC METHODS 29 29 30 30 function InitFrame() { 31 31 $this->StrokePlotArea(); 32 32 } 33 33 34 34 // Method description 35 35 function Stroke($aStrokeFileName="") { 36 37 38 39 40 } 41 42 43 44 } 45 46 36 if( $this->texts != null ) { 37 for($i=0; $i < count($this->texts); ++$i) { 38 $this->texts[$i]->Stroke($this->img); 39 } 40 } 41 if( $this->iTables !== null ) { 42 for($i=0; $i < count($this->iTables); ++$i) { 43 $this->iTables[$i]->Stroke($this->img); 44 } 45 } 46 $this->StrokeTitles(); 47 47 48 49 50 51 52 53 54 55 48 // If the filename is the predefined value = '_csim_special_' 49 // we assume that the call to stroke only needs to do enough 50 // to correctly generate the CSIM maps. 51 // We use this variable to skip things we don't strictly need 52 // to do to generate the image map to improve performance 53 // a best we can. Therefor you will see a lot of tests !$_csim in the 54 // code below. 55 $_csim = ($aStrokeFileName===_CSIM_SPECIALFILE); 56 56 57 58 59 60 61 57 // We need to know if we have stroked the plot in the 58 // GetCSIMareas. Otherwise the CSIM hasn't been generated 59 // and in the case of GetCSIM called before stroke to generate 60 // CSIM without storing an image to disk GetCSIM must call Stroke. 61 $this->iHasStroked = true; 62 62 63 63 if( !$_csim ) { 64 64 65 // Should we do any final image transformation 66 if( $this->iImgTrans ) { 67 if( !class_exists('ImgTrans') ) { 68 require_once('jpgraph_imgtrans.php'); 69 } 70 71 $tform = new ImgTrans($this->img->img); 72 $this->img->img = $tform->Skew3D($this->iImgTransHorizon,$this->iImgTransSkewDist, 73 $this->iImgTransDirection,$this->iImgTransHighQ, 74 $this->iImgTransMinSize,$this->iImgTransFillColor, 75 $this->iImgTransBorder); 76 } 77 65 // Should we do any final image transformation 66 if( $this->iImgTrans ) { 67 if( !class_exists('ImgTrans',false) ) { 68 require_once('jpgraph_imgtrans.php'); 69 } 78 70 79 // If the filename is given as the special _IMG_HANDLER 80 // then the image handler is returned and the image is NOT 81 // streamed back 82 if( $aStrokeFileName == _IMG_HANDLER ) { 83 return $this->img->img; 84 } 85 else { 86 // Finally stream the generated picture 87 $this->cache->PutAndStream($this->img,$this->cache_name,$this->inline,$aStrokeFileName); 88 return true; 89 } 90 } 71 $tform = new ImgTrans($this->img->img); 72 $this->img->img = $tform->Skew3D($this->iImgTransHorizon,$this->iImgTransSkewDist, 73 $this->iImgTransDirection,$this->iImgTransHighQ, 74 $this->iImgTransMinSize,$this->iImgTransFillColor, 75 $this->iImgTransBorder); 76 } 77 78 79 // If the filename is given as the special _IMG_HANDLER 80 // then the image handler is returned and the image is NOT 81 // streamed back 82 if( $aStrokeFileName == _IMG_HANDLER ) { 83 return $this->img->img; 84 } 85 else { 86 // Finally stream the generated picture 87 $this->cache->PutAndStream($this->img,$this->cache_name,$this->inline,$aStrokeFileName); 88 return true; 89 } 90 } 91 91 } 92 92 } // Class -
trunk/client/modules/Elezioni/grafici/jpgraph_canvtools.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_CANVTOOLS.PHP4 // Description:Some utilities for text and shape drawing on a canvas5 // Created:2002-08-236 // Ver: $Id: jpgraph_canvtools.php 1091 2009-01-18 22:57:40Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */3 // File: JPGRAPH_CANVTOOLS.PHP 4 // Description: Some utilities for text and shape drawing on a canvas 5 // Created: 2002-08-23 6 // Ver: $Id: jpgraph_canvtools.php 1857 2009-09-28 14:38:14Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 define('CORNER_TOPLEFT',0); … … 21 21 // can abstract away with absolute pixels 22 22 //=================================================== 23 23 24 24 class CanvasScale { 25 25 private $g; … … 27 27 private $ixmin=0,$ixmax=10,$iymin=0,$iymax=10; 28 28 29 function CanvasScale($graph,$xmin=0,$xmax=10,$ymin=0,$ymax=10) {30 31 32 33 34 35 36 37 } 38 29 function __construct($graph,$xmin=0,$xmax=10,$ymin=0,$ymax=10) { 30 $this->g = $graph; 31 $this->w = $graph->img->width; 32 $this->h = $graph->img->height; 33 $this->ixmin = $xmin; 34 $this->ixmax = $xmax; 35 $this->iymin = $ymin; 36 $this->iymax = $ymax; 37 } 38 39 39 function Set($xmin=0,$xmax=10,$ymin=0,$ymax=10) { 40 $this->ixmin = $xmin; 41 $this->ixmax = $xmax; 42 $this->iymin = $ymin; 43 $this->iymax = $ymax; 40 $this->ixmin = $xmin; 41 $this->ixmax = $xmax; 42 $this->iymin = $ymin; 43 $this->iymax = $ymax; 44 } 45 46 function Get() { 47 return array($this->ixmin,$this->ixmax,$this->iymin,$this->iymax); 44 48 } 45 49 46 50 function Translate($x,$y) { 47 48 49 51 $xp = round(($x-$this->ixmin)/($this->ixmax - $this->ixmin) * $this->w); 52 $yp = round(($y-$this->iymin)/($this->iymax - $this->iymin) * $this->h); 53 return array($xp,$yp); 50 54 } 51 55 52 56 function TranslateX($x) { 53 54 57 $xp = round(($x-$this->ixmin)/($this->ixmax - $this->ixmin) * $this->w); 58 return $xp; 55 59 } 56 60 57 61 function TranslateY($y) { 58 59 62 $yp = round(($y-$this->iymin)/($this->iymax - $this->iymin) * $this->h); 63 return $yp; 60 64 } 61 65 … … 70 74 private $img,$scale; 71 75 72 function Shape($aGraph,$scale) {73 74 75 76 function __construct($aGraph,$scale) { 77 $this->img = $aGraph->img; 78 $this->img->SetColor('black'); 79 $this->scale = $scale; 76 80 } 77 81 78 82 function SetColor($aColor) { 79 83 $this->img->SetColor($aColor); 80 84 } 81 85 82 86 function Line($x1,$y1,$x2,$y2) { 83 list($x1,$y1) = $this->scale->Translate($x1,$y1); 84 list($x2,$y2) = $this->scale->Translate($x2,$y2); 85 $this->img->Line($x1,$y1,$x2,$y2); 87 list($x1,$y1) = $this->scale->Translate($x1,$y1); 88 list($x2,$y2) = $this->scale->Translate($x2,$y2); 89 $this->img->Line($x1,$y1,$x2,$y2); 90 } 91 92 function SetLineWeight($aWeight) { 93 $this->img->SetLineWeight($aWeight); 86 94 } 87 95 88 96 function Polygon($p,$aClosed=false) { 89 90 91 92 93 94 97 $n=count($p); 98 for($i=0; $i < $n; $i+=2 ) { 99 $p[$i] = $this->scale->TranslateX($p[$i]); 100 $p[$i+1] = $this->scale->TranslateY($p[$i+1]); 101 } 102 $this->img->Polygon($p,$aClosed); 95 103 } 96 104 97 105 function FilledPolygon($p) { 98 99 100 101 102 103 104 } 105 106 $n=count($p); 107 for($i=0; $i < $n; $i+=2 ) { 108 $p[$i] = $this->scale->TranslateX($p[$i]); 109 $p[$i+1] = $this->scale->TranslateY($p[$i+1]); 110 } 111 $this->img->FilledPolygon($p); 112 } 113 106 114 107 115 // Draw a bezier curve with defining points in the $aPnts array … … 112 120 // 6=x3, 7=y3 113 121 function Bezier($p,$aSteps=40) { 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 122 $x0 = $p[0]; 123 $y0 = $p[1]; 124 // Calculate coefficients 125 $cx = 3*($p[2]-$p[0]); 126 $bx = 3*($p[4]-$p[2])-$cx; 127 $ax = $p[6]-$p[0]-$cx-$bx; 128 $cy = 3*($p[3]-$p[1]); 129 $by = 3*($p[5]-$p[3])-$cy; 130 $ay = $p[7]-$p[1]-$cy-$by; 131 132 // Step size 133 $delta = 1.0/$aSteps; 134 135 $x_old = $x0; 136 $y_old = $y0; 137 for($t=$delta; $t<=1.0; $t+=$delta) { 138 $tt = $t*$t; $ttt=$tt*$t; 139 $x = $ax*$ttt + $bx*$tt + $cx*$t + $x0; 140 $y = $ay*$ttt + $by*$tt + $cy*$t + $y0; 141 $this->Line($x_old,$y_old,$x,$y); 142 $x_old = $x; 143 $y_old = $y; 144 } 145 $this->Line($x_old,$y_old,$p[6],$p[7]); 138 146 } 139 147 140 148 function Rectangle($x1,$y1,$x2,$y2) { 141 142 143 149 list($x1,$y1) = $this->scale->Translate($x1,$y1); 150 list($x2,$y2) = $this->scale->Translate($x2,$y2); 151 $this->img->Rectangle($x1,$y1,$x2,$y2); 144 152 } 145 153 146 154 function FilledRectangle($x1,$y1,$x2,$y2) { 147 148 149 150 } 151 155 list($x1,$y1) = $this->scale->Translate($x1,$y1); 156 list($x2,$y2) = $this->scale->Translate($x2,$y2); 157 $this->img->FilledRectangle($x1,$y1,$x2,$y2); 158 } 159 152 160 function Circle($x1,$y1,$r) { 153 154 155 156 157 158 161 list($x1,$y1) = $this->scale->Translate($x1,$y1); 162 if( $r >= 0 ) 163 $r = $this->scale->TranslateX($r); 164 else 165 $r = -$r; 166 $this->img->Circle($x1,$y1,$r); 159 167 } 160 168 161 169 function FilledCircle($x1,$y1,$r) { 162 163 164 165 166 167 168 } 169 170 function RoundedRectangle($x1,$y1,$x2,$y2,$r=null) { 171 172 173 174 175 176 177 178 179 180 181 } 182 183 function FilledRoundedRectangle($x1,$y1,$x2,$y2,$r=null) { 184 185 186 187 188 189 190 191 192 193 $this->img->FilledRoundedRectangle($x1,$y1,$x2,$y2,$r); 170 list($x1,$y1) = $this->scale->Translate($x1,$y1); 171 if( $r >= 0 ) 172 $r = $this->scale->TranslateX($r); 173 else 174 $r = -$r; 175 $this->img->FilledCircle($x1,$y1,$r); 176 } 177 178 function RoundedRectangle($x1,$y1,$x2,$y2,$r=null) { 179 list($x1,$y1) = $this->scale->Translate($x1,$y1); 180 list($x2,$y2) = $this->scale->Translate($x2,$y2); 181 182 if( $r == null ) 183 $r = 5; 184 elseif( $r >= 0 ) 185 $r = $this->scale->TranslateX($r); 186 else 187 $r = -$r; 188 $this->img->RoundedRectangle($x1,$y1,$x2,$y2,$r); 189 } 190 191 function FilledRoundedRectangle($x1,$y1,$x2,$y2,$r=null) { 192 list($x1,$y1) = $this->scale->Translate($x1,$y1); 193 list($x2,$y2) = $this->scale->Translate($x2,$y2); 194 195 if( $r == null ) 196 $r = 5; 197 elseif( $r > 0 ) 198 $r = $this->scale->TranslateX($r); 199 else 200 $r = -$r; 201 $this->img->FilledRoundedRectangle($x1,$y1,$x2,$y2,$r); 194 202 } 195 203 196 204 function ShadowRectangle($x1,$y1,$x2,$y2,$fcolor=false,$shadow_width=null,$shadow_color=array(102,102,102)) { 197 198 199 if( $shadow_width == null ) 200 201 202 203 205 list($x1,$y1) = $this->scale->Translate($x1,$y1); 206 list($x2,$y2) = $this->scale->Translate($x2,$y2); 207 if( $shadow_width == null ) 208 $shadow_width=4; 209 else 210 $shadow_width=$this->scale->TranslateX($shadow_width); 211 $this->img->ShadowRectangle($x1,$y1,$x2,$y2,$fcolor,$shadow_width,$shadow_color); 204 212 } 205 213 206 214 function SetTextAlign($halign,$valign="bottom") { 207 215 $this->img->SetTextAlign($halign,$valign="bottom"); 208 216 } 209 217 210 218 function StrokeText($x1,$y1,$txt,$dir=0,$paragraph_align="left") { 211 212 219 list($x1,$y1) = $this->scale->Translate($x1,$y1); 220 $this->img->StrokeText($x1,$y1,$txt,$dir,$paragraph_align); 213 221 } 214 222 … … 217 225 // 0=Top left, 1=top right, 2=bottom right, 3=bottom left 218 226 function IndentedRectangle($xt,$yt,$w,$h,$iw=0,$ih=0,$aCorner=3,$aFillColor="",$r=4) { 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 227 228 list($xt,$yt) = $this->scale->Translate($xt,$yt); 229 list($w,$h) = $this->scale->Translate($w,$h); 230 list($iw,$ih) = $this->scale->Translate($iw,$ih); 231 232 $xr = $xt + $w - 0; 233 $yl = $yt + $h - 0; 234 235 switch( $aCorner ) { 236 case 0: // Upper left 237 238 // Bottom line, left & right arc 239 $this->img->Line($xt+$r,$yl,$xr-$r,$yl); 240 $this->img->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180); 241 $this->img->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90); 242 243 // Right line, Top right arc 244 $this->img->Line($xr,$yt+$r,$xr,$yl-$r); 245 $this->img->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360); 246 247 // Top line, Top left arc 248 $this->img->Line($xt+$iw+$r,$yt,$xr-$r,$yt); 249 $this->img->Arc($xt+$iw+$r,$yt+$r,$r*2,$r*2,180,270); 250 251 // Left line 252 $this->img->Line($xt,$yt+$ih+$r,$xt,$yl-$r); 253 254 // Indent horizontal, Lower left arc 255 $this->img->Line($xt+$r,$yt+$ih,$xt+$iw-$r,$yt+$ih); 256 $this->img->Arc($xt+$r,$yt+$ih+$r,$r*2,$r*2,180,270); 257 258 // Indent vertical, Indent arc 259 $this->img->Line($xt+$iw,$yt+$r,$xt+$iw,$yt+$ih-$r); 260 $this->img->Arc($xt+$iw-$r,$yt+$ih-$r,$r*2,$r*2,0,90); 261 262 if( $aFillColor != '' ) { 263 $bc = $this->img->current_color_name; 264 $this->img->PushColor($aFillColor); 265 $this->img->FillToBorder($xr-$r,$yl-$r,$bc); 266 $this->img->PopColor(); 267 } 268 269 break; 270 271 case 1: // Upper right 272 273 // Bottom line, left & right arc 274 $this->img->Line($xt+$r,$yl,$xr-$r,$yl); 275 $this->img->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180); 276 $this->img->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90); 277 278 // Left line, Top left arc 279 $this->img->Line($xt,$yt+$r,$xt,$yl-$r); 280 $this->img->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270); 281 282 // Top line, Top right arc 283 $this->img->Line($xt+$r,$yt,$xr-$iw-$r,$yt); 284 $this->img->Arc($xr-$iw-$r,$yt+$r,$r*2,$r*2,270,360); 285 286 // Right line 287 $this->img->Line($xr,$yt+$ih+$r,$xr,$yl-$r); 288 289 // Indent horizontal, Lower right arc 290 $this->img->Line($xr-$iw+$r,$yt+$ih,$xr-$r,$yt+$ih); 291 $this->img->Arc($xr-$r,$yt+$ih+$r,$r*2,$r*2,270,360); 292 293 // Indent vertical, Indent arc 294 $this->img->Line($xr-$iw,$yt+$r,$xr-$iw,$yt+$ih-$r); 295 $this->img->Arc($xr-$iw+$r,$yt+$ih-$r,$r*2,$r*2,90,180); 296 297 if( $aFillColor != '' ) { 298 $bc = $this->img->current_color_name; 299 $this->img->PushColor($aFillColor); 300 $this->img->FillToBorder($xt+$r,$yl-$r,$bc); 301 $this->img->PopColor(); 302 } 303 304 break; 305 306 case 2: // Lower right 307 // Top line, Top left & Top right arc 308 $this->img->Line($xt+$r,$yt,$xr-$r,$yt); 309 $this->img->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270); 310 $this->img->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360); 311 312 // Left line, Bottom left arc 313 $this->img->Line($xt,$yt+$r,$xt,$yl-$r); 314 $this->img->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180); 315 316 // Bottom line, Bottom right arc 317 $this->img->Line($xt+$r,$yl,$xr-$iw-$r,$yl); 318 $this->img->Arc($xr-$iw-$r,$yl-$r,$r*2,$r*2,0,90); 319 320 // Right line 321 $this->img->Line($xr,$yt+$r,$xr,$yl-$ih-$r); 322 323 // Indent horizontal, Lower right arc 324 $this->img->Line($xr-$r,$yl-$ih,$xr-$iw+$r,$yl-$ih); 325 $this->img->Arc($xr-$r,$yl-$ih-$r,$r*2,$r*2,0,90); 326 327 // Indent vertical, Indent arc 328 $this->img->Line($xr-$iw,$yl-$r,$xr-$iw,$yl-$ih+$r); 329 $this->img->Arc($xr-$iw+$r,$yl-$ih+$r,$r*2,$r*2,180,270); 330 331 if( $aFillColor != '' ) { 332 $bc = $this->img->current_color_name; 333 $this->img->PushColor($aFillColor); 334 $this->img->FillToBorder($xt+$r,$yt+$r,$bc); 335 $this->img->PopColor(); 336 } 337 338 break; 339 340 case 3: // Lower left 341 // Top line, Top left & Top right arc 342 $this->img->Line($xt+$r,$yt,$xr-$r,$yt); 343 $this->img->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270); 344 $this->img->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360); 345 346 // Right line, Bottom right arc 347 $this->img->Line($xr,$yt+$r,$xr,$yl-$r); 348 $this->img->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90); 349 350 // Bottom line, Bottom left arc 351 $this->img->Line($xt+$iw+$r,$yl,$xr-$r,$yl); 352 $this->img->Arc($xt+$iw+$r,$yl-$r,$r*2,$r*2,90,180); 353 354 // Left line 355 $this->img->Line($xt,$yt+$r,$xt,$yl-$ih-$r); 356 357 // Indent horizontal, Lower left arc 358 $this->img->Line($xt+$r,$yl-$ih,$xt+$iw-$r,$yl-$ih); 359 $this->img->Arc($xt+$r,$yl-$ih-$r,$r*2,$r*2,90,180); 360 361 // Indent vertical, Indent arc 362 $this->img->Line($xt+$iw,$yl-$ih+$r,$xt+$iw,$yl-$r); 363 $this->img->Arc($xt+$iw-$r,$yl-$ih+$r,$r*2,$r*2,270,360); 364 365 if( $aFillColor != '' ) { 366 $bc = $this->img->current_color_name; 367 $this->img->PushColor($aFillColor); 368 $this->img->FillToBorder($xr-$r,$yt+$r,$bc); 369 $this->img->PopColor(); 370 } 371 372 break; 373 } 366 374 } 367 375 } … … 370 378 //=================================================== 371 379 // CLASS RectangleText 372 // Description: Draws a text paragraph inside a 380 // Description: Draws a text paragraph inside a 373 381 // rounded, possible filled, rectangle. 374 382 //=================================================== … … 380 388 private $iShadowWidth=3,$iShadowColor=''; 381 389 382 function CanvasRectangleText($aTxt='',$xl=0,$yt=0,$w=0,$h=0) {383 384 385 386 387 388 } 389 390 function __construct($aTxt='',$xl=0,$yt=0,$w=0,$h=0) { 391 $this->iTxt = new Text($aTxt); 392 $this->ix = $xl; 393 $this->iy = $yt; 394 $this->iw = $w; 395 $this->ih = $h; 396 } 397 390 398 function SetShadow($aColor='gray',$aWidth=3) { 391 392 399 $this->iShadowColor = $aColor; 400 $this->iShadowWidth = $aWidth; 393 401 } 394 402 395 403 function SetFont($FontFam,$aFontStyle,$aFontSize=12) { 396 404 $this->iTxt->SetFont($FontFam,$aFontStyle,$aFontSize); 397 405 } 398 406 399 407 function SetTxt($aTxt) { 400 408 $this->iTxt->Set($aTxt); 401 409 } 402 410 403 411 function ParagraphAlign($aParaAlign) { 404 412 $this->iParaAlign = $aParaAlign; 405 413 } 406 414 407 415 function SetFillColor($aFillColor) { 408 416 $this->iFillColor = $aFillColor; 409 417 } 410 418 411 419 function SetAutoMargin($aMargin) { 412 420 $this->iAutoBoxMargin=$aMargin; 413 421 } 414 422 415 423 function SetColor($aColor) { 416 424 $this->iColor = $aColor; 417 425 } 418 426 419 427 function SetFontColor($aColor) { 420 428 $this->iFontColor = $aColor; 421 429 } 422 430 423 431 function SetPos($xl=0,$yt=0,$w=0,$h=0) { 424 425 426 427 432 $this->ix = $xl; 433 $this->iy = $yt; 434 $this->iw = $w; 435 $this->ih = $h; 428 436 } 429 437 430 438 function Pos($xl=0,$yt=0,$w=0,$h=0) { 431 432 433 434 439 $this->ix = $xl; 440 $this->iy = $yt; 441 $this->iw = $w; 442 $this->ih = $h; 435 443 } 436 444 437 445 function Set($aTxt,$xl,$yt,$w=0,$h=0) { 438 439 440 441 442 446 $this->iTxt->Set($aTxt); 447 $this->ix = $xl; 448 $this->iy = $yt; 449 $this->iw = $w; 450 $this->ih = $h; 443 451 } 444 452 445 453 function SetCornerRadius($aRad=5) { 446 454 $this->ir = $aRad; 447 455 } 448 456 449 457 function Stroke($aImg,$scale) { 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 if( $this->iw == 0 ) 470 471 472 473 474 475 476 477 478 479 480 481 482 $aImg->PopColor(); 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 458 459 // If coordinates are specifed as negative this means we should 460 // treat them as abolsute (pixels) coordinates 461 if( $this->ix > 0 ) { 462 $this->ix = $scale->TranslateX($this->ix) ; 463 } 464 else { 465 $this->ix = -$this->ix; 466 } 467 468 if( $this->iy > 0 ) { 469 $this->iy = $scale->TranslateY($this->iy) ; 470 } 471 else { 472 $this->iy = -$this->iy; 473 } 474 475 list($this->iw,$this->ih) = $scale->Translate($this->iw,$this->ih) ; 476 477 if( $this->iw == 0 ) 478 $this->iw = round($this->iTxt->GetWidth($aImg) + $this->iAutoBoxMargin); 479 if( $this->ih == 0 ) { 480 $this->ih = round($this->iTxt->GetTextHeight($aImg) + $this->iAutoBoxMargin); 481 } 482 483 if( $this->iShadowColor != '' ) { 484 $aImg->PushColor($this->iShadowColor); 485 $aImg->FilledRoundedRectangle($this->ix+$this->iShadowWidth, 486 $this->iy+$this->iShadowWidth, 487 $this->ix+$this->iw-1+$this->iShadowWidth, 488 $this->iy+$this->ih-1+$this->iShadowWidth, 489 $this->ir); 490 $aImg->PopColor(); 491 } 492 493 if( $this->iFillColor != '' ) { 494 $aImg->PushColor($this->iFillColor); 495 $aImg->FilledRoundedRectangle($this->ix,$this->iy, 496 $this->ix+$this->iw-1, 497 $this->iy+$this->ih-1, 498 $this->ir); 499 $aImg->PopColor(); 500 } 501 502 if( $this->iColor != '' ) { 503 $aImg->PushColor($this->iColor); 504 $aImg->RoundedRectangle($this->ix,$this->iy, 505 $this->ix+$this->iw-1, 506 $this->iy+$this->ih-1, 507 $this->ir); 508 $aImg->PopColor(); 509 } 510 511 $this->iTxt->Align('center','center'); 512 $this->iTxt->ParagraphAlign($this->iParaAlign); 513 $this->iTxt->SetColor($this->iFontColor); 514 $this->iTxt->Stroke($aImg, $this->ix+$this->iw/2, $this->iy+$this->ih/2); 515 516 return array($this->iw, $this->ih); 509 517 510 518 } -
trunk/client/modules/Elezioni/grafici/jpgraph_date.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_DATE.PHP4 // Description:Classes to handle Date scaling5 // Created:2005-05-026 // Ver: $Id: jpgraph_date.php 1091 2009-01-18 22:57:40Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */3 // File: JPGRAPH_DATE.PHP 4 // Description: Classes to handle Date scaling 5 // Created: 2005-05-02 6 // Ver: $Id: jpgraph_date.php 1106 2009-02-22 20:16:35Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 define('HOURADJ_1',0+30); … … 52 52 private $iStartTimeAlign = false, $iEndTimeAlign = false; 53 53 54 //---------------55 // CONSTRUCTOR56 function DateScale($aMin=0,$aMax=0,$aType='x') {57 58 59 60 61 $this->scale=array($aMin,$aMax); 62 $this->world_size=$aMax-$aMin; 63 64 65 } 66 67 68 //------------------------------------------------------------------------------------------69 // Utility Function AdjDate()70 // Description: Will round a given time stamp to an even year, month or day 71 // argument. 72 //------------------------------------------------------------------------------------------54 //--------------- 55 // CONSTRUCTOR 56 function __construct($aMin=0,$aMax=0,$aType='x') { 57 assert($aType=="x"); 58 assert($aMin<=$aMax); 59 60 $this->type=$aType; 61 $this->scale=array($aMin,$aMax); 62 $this->world_size=$aMax-$aMin; 63 $this->ticks = new LinearTicks(); 64 $this->intscale=true; 65 } 66 67 68 //------------------------------------------------------------------------------------------ 69 // Utility Function AdjDate() 70 // Description: Will round a given time stamp to an even year, month or day 71 // argument. 72 //------------------------------------------------------------------------------------------ 73 73 74 74 function AdjDate($aTime,$aRound=0,$aYearType=false,$aMonthType=false,$aDayType=false) { 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 // Adjust to an even week boundary. 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 } 126 127 //------------------------------------------------------------------------------------------128 // Wrapper for AdjDate that will round a timestamp to an even date rounding129 // it downwards.130 //------------------------------------------------------------------------------------------75 $y = (int)date('Y',$aTime); $m = (int)date('m',$aTime); $d = (int)date('d',$aTime); 76 $h=0;$i=0;$s=0; 77 if( $aYearType !== false ) { 78 $yearAdj = array(0=>1, 1=>2, 2=>5); 79 if( $aRound == 0 ) { 80 $y = floor($y/$yearAdj[$aYearType])*$yearAdj[$aYearType]; 81 } 82 else { 83 ++$y; 84 $y = ceil($y/$yearAdj[$aYearType])*$yearAdj[$aYearType]; 85 } 86 $m=1;$d=1; 87 } 88 elseif( $aMonthType !== false ) { 89 $monthAdj = array(0=>1, 1=>6); 90 if( $aRound == 0 ) { 91 $m = floor($m/$monthAdj[$aMonthType])*$monthAdj[$aMonthType]; 92 $d=1; 93 } 94 else { 95 ++$m; 96 $m = ceil($m/$monthAdj[$aMonthType])*$monthAdj[$aMonthType]; 97 $d=1; 98 } 99 } 100 elseif( $aDayType !== false ) { 101 if( $aDayType == 0 ) { 102 if( $aRound == 1 ) { 103 //++$d; 104 $h=23;$i=59;$s=59; 105 } 106 } 107 else { 108 // Adjust to an even week boundary. 109 $w = (int)date('w',$aTime); // Day of week 0=Sun, 6=Sat 110 if( true ) { // Adjust to start on Mon 111 if( $w==0 ) $w=6; 112 else --$w; 113 } 114 if( $aRound == 0 ) { 115 $d -= $w; 116 } 117 else { 118 $d += (7-$w); 119 $h=23;$i=59;$s=59; 120 } 121 } 122 } 123 return mktime($h,$i,$s,$m,$d,$y); 124 125 } 126 127 //------------------------------------------------------------------------------------------ 128 // Wrapper for AdjDate that will round a timestamp to an even date rounding 129 // it downwards. 130 //------------------------------------------------------------------------------------------ 131 131 function AdjStartDate($aTime,$aYearType=false,$aMonthType=false,$aDayType=false) { 132 133 } 134 135 //------------------------------------------------------------------------------------------136 // Wrapper for AdjDate that will round a timestamp to an even date rounding137 // it upwards138 //------------------------------------------------------------------------------------------132 return $this->AdjDate($aTime,0,$aYearType,$aMonthType,$aDayType); 133 } 134 135 //------------------------------------------------------------------------------------------ 136 // Wrapper for AdjDate that will round a timestamp to an even date rounding 137 // it upwards 138 //------------------------------------------------------------------------------------------ 139 139 function AdjEndDate($aTime,$aYearType=false,$aMonthType=false,$aDayType=false) { 140 141 } 142 143 //------------------------------------------------------------------------------------------144 // Utility Function AdjTime()145 // Description: Will round a given time stamp to an even time according to 146 // argument. 147 //------------------------------------------------------------------------------------------140 return $this->AdjDate($aTime,1,$aYearType,$aMonthType,$aDayType); 141 } 142 143 //------------------------------------------------------------------------------------------ 144 // Utility Function AdjTime() 145 // Description: Will round a given time stamp to an even time according to 146 // argument. 147 //------------------------------------------------------------------------------------------ 148 148 149 149 function AdjTime($aTime,$aRound=0,$aHourType=false,$aMinType=false,$aSecType=false) { 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 $h -= 24; 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 $h = (int)date('H',$aTime); $i = (int)date('i',$aTime); 202 203 204 205 206 } 207 208 //------------------------------------------------------------------------------------------209 // Wrapper for AdjTime that will round a timestamp to an even time rounding210 // it downwards.211 // Example: AdjStartTime(mktime(18,27,13,2,22,2005),false,2) => 18:20212 //------------------------------------------------------------------------------------------150 $y = (int)date('Y',$aTime); $m = (int)date('m',$aTime); $d = (int)date('d',$aTime); 151 $h = (int)date('H',$aTime); $i = (int)date('i',$aTime); $s = (int)date('s',$aTime); 152 if( $aHourType !== false ) { 153 $aHourType %= 6; 154 $hourAdj = array(0=>1, 1=>2, 2=>3, 3=>4, 4=>6, 5=>12); 155 if( $aRound == 0 ) 156 $h = floor($h/$hourAdj[$aHourType])*$hourAdj[$aHourType]; 157 else { 158 if( ($h % $hourAdj[$aHourType]==0) && ($i > 0 || $s > 0) ) { 159 $h++; 160 } 161 $h = ceil($h/$hourAdj[$aHourType])*$hourAdj[$aHourType]; 162 if( $h >= 24 ) { 163 $aTime += 86400; 164 $y = (int)date('Y',$aTime); $m = (int)date('m',$aTime); $d = (int)date('d',$aTime); 165 $h -= 24; 166 } 167 } 168 $i=0;$s=0; 169 } 170 elseif( $aMinType !== false ) { 171 $aMinType %= 5; 172 $minAdj = array(0=>1, 1=>5, 2=>10, 3=>15, 4=>30); 173 if( $aRound == 0 ) { 174 $i = floor($i/$minAdj[$aMinType])*$minAdj[$aMinType]; 175 } 176 else { 177 if( ($i % $minAdj[$aMinType]==0) && $s > 0 ) { 178 $i++; 179 } 180 $i = ceil($i/$minAdj[$aMinType])*$minAdj[$aMinType]; 181 if( $i >= 60) { 182 $aTime += 3600; 183 $y = (int)date('Y',$aTime); $m = (int)date('m',$aTime); $d = (int)date('d',$aTime); 184 $h = (int)date('H',$aTime); $i = 0; 185 } 186 } 187 $s=0; 188 } 189 elseif( $aSecType !== false ) { 190 $aSecType %= 5; 191 $secAdj = array(0=>1, 1=>5, 2=>10, 3=>15, 4=>30); 192 if( $aRound == 0 ) { 193 $s = floor($s/$secAdj[$aSecType])*$secAdj[$aSecType]; 194 } 195 else { 196 $s = ceil($s/$secAdj[$aSecType]*1.0)*$secAdj[$aSecType]; 197 if( $s >= 60) { 198 $s=0; 199 $aTime += 60; 200 $y = (int)date('Y',$aTime); $m = (int)date('m',$aTime); $d = (int)date('d',$aTime); 201 $h = (int)date('H',$aTime); $i = (int)date('i',$aTime); 202 } 203 } 204 } 205 return mktime($h,$i,$s,$m,$d,$y); 206 } 207 208 //------------------------------------------------------------------------------------------ 209 // Wrapper for AdjTime that will round a timestamp to an even time rounding 210 // it downwards. 211 // Example: AdjStartTime(mktime(18,27,13,2,22,2005),false,2) => 18:20 212 //------------------------------------------------------------------------------------------ 213 213 function AdjStartTime($aTime,$aHourType=false,$aMinType=false,$aSecType=false) { 214 215 } 216 217 //------------------------------------------------------------------------------------------218 // Wrapper for AdjTime that will round a timestamp to an even time rounding219 // it upwards220 // Example: AdjEndTime(mktime(18,27,13,2,22,2005),false,2) => 18:30221 //------------------------------------------------------------------------------------------214 return $this->AdjTime($aTime,0,$aHourType,$aMinType,$aSecType); 215 } 216 217 //------------------------------------------------------------------------------------------ 218 // Wrapper for AdjTime that will round a timestamp to an even time rounding 219 // it upwards 220 // Example: AdjEndTime(mktime(18,27,13,2,22,2005),false,2) => 18:30 221 //------------------------------------------------------------------------------------------ 222 222 function AdjEndTime($aTime,$aHourType=false,$aMinType=false,$aSecType=false) { 223 224 } 225 226 //------------------------------------------------------------------------------------------227 // DateAutoScale228 // Autoscale a date axis given start and end time229 // Returns an array ($start,$end,$major,$minor,$format)230 //------------------------------------------------------------------------------------------223 return $this->AdjTime($aTime,1,$aHourType,$aMinType,$aSecType); 224 } 225 226 //------------------------------------------------------------------------------------------ 227 // DateAutoScale 228 // Autoscale a date axis given start and end time 229 // Returns an array ($start,$end,$major,$minor,$format) 230 //------------------------------------------------------------------------------------------ 231 231 function DoDateAutoScale($aStartTime,$aEndTime,$aDensity=0,$aAdjust=true) { 232 233 // array ( Decision point, array( array( Major-scale-step-array ), 234 // array( Minor-scale-step-array ), 235 //array( 0=date-adjust, 1=time-adjust, adjustment-alignment) )236 237 $scalePoints = 238 239 240 241 array(SECPERYEAR), 242 243 244 245 SECPERYEAR*2,array(array(SECPERYEAR),array(SECPERYEAR), 246 247 248 249 250 array(SECPERDAY*5,SECPERDAY*7,SECPERDAY,SECPERDAY), 251 252 253 254 255 array(SECPERDAY,SECPERDAY,SECPERDAY,SECPERDAY), 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 if( $scaleSteps[2][$idx] === 0 ) { 320 321 $adj = $scaleSteps[2][$idx+1]; 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 $end++; 337 338 339 340 341 $adj = $scaleSteps[2][$idx+1]; 342 343 344 345 346 347 348 349 350 351 352 $end = $this->AdjEndTime($aEndTime,false,false,$adj); 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 232 // Format of array 233 // array ( Decision point, array( array( Major-scale-step-array ), 234 // array( Minor-scale-step-array ), 235 // array( 0=date-adjust, 1=time-adjust, adjustment-alignment) ) 236 // 237 $scalePoints = 238 array( 239 /* Intervall larger than 10 years */ 240 SECPERYEAR*10,array(array(SECPERYEAR*5,SECPERYEAR*2), 241 array(SECPERYEAR), 242 array(0,YEARADJ_1, 0,YEARADJ_1) ), 243 244 /* Intervall larger than 2 years */ 245 SECPERYEAR*2,array(array(SECPERYEAR),array(SECPERYEAR), 246 array(0,YEARADJ_1) ), 247 248 /* Intervall larger than 90 days (approx 3 month) */ 249 SECPERDAY*90,array(array(SECPERDAY*30,SECPERDAY*14,SECPERDAY*7,SECPERDAY), 250 array(SECPERDAY*5,SECPERDAY*7,SECPERDAY,SECPERDAY), 251 array(0,MONTHADJ_1, 0,DAYADJ_WEEK, 0,DAYADJ_1, 0,DAYADJ_1)), 252 253 /* Intervall larger than 30 days (approx 1 month) */ 254 SECPERDAY*30,array(array(SECPERDAY*14,SECPERDAY*7,SECPERDAY*2, SECPERDAY), 255 array(SECPERDAY,SECPERDAY,SECPERDAY,SECPERDAY), 256 array(0,DAYADJ_WEEK, 0,DAYADJ_1, 0,DAYADJ_1, 0,DAYADJ_1)), 257 258 /* Intervall larger than 7 days */ 259 SECPERDAY*7,array(array(SECPERDAY,SECPERHOUR*12,SECPERHOUR*6,SECPERHOUR*2), 260 array(SECPERHOUR*6,SECPERHOUR*3,SECPERHOUR,SECPERHOUR), 261 array(0,DAYADJ_1, 1,HOURADJ_12, 1,HOURADJ_6, 1,HOURADJ_1)), 262 263 /* Intervall larger than 1 day */ 264 SECPERDAY,array(array(SECPERDAY,SECPERHOUR*12,SECPERHOUR*6,SECPERHOUR*2,SECPERHOUR), 265 array(SECPERHOUR*6,SECPERHOUR*2,SECPERHOUR,SECPERHOUR,SECPERHOUR), 266 array(1,HOURADJ_12, 1,HOURADJ_6, 1,HOURADJ_1, 1,HOURADJ_1)), 267 268 /* Intervall larger than 12 hours */ 269 SECPERHOUR*12,array(array(SECPERHOUR*2,SECPERHOUR,SECPERMIN*30,900,600), 270 array(1800,1800,900,300,300), 271 array(1,HOURADJ_1, 1,MINADJ_30, 1,MINADJ_15, 1,MINADJ_10, 1,MINADJ_5) ), 272 273 /* Intervall larger than 2 hours */ 274 SECPERHOUR*2,array(array(SECPERHOUR,SECPERMIN*30,900,600,300), 275 array(1800,900,300,120,60), 276 array(1,HOURADJ_1, 1,MINADJ_30, 1,MINADJ_15, 1,MINADJ_10, 1,MINADJ_5) ), 277 278 /* Intervall larger than 1 hours */ 279 SECPERHOUR,array(array(SECPERMIN*30,900,600,300),array(900,300,120,60), 280 array(1,MINADJ_30, 1,MINADJ_15, 1,MINADJ_10, 1,MINADJ_5) ), 281 282 /* Intervall larger than 30 min */ 283 SECPERMIN*30,array(array(SECPERMIN*15,SECPERMIN*10,SECPERMIN*5,SECPERMIN), 284 array(300,300,60,10), 285 array(1,MINADJ_15, 1,MINADJ_10, 1,MINADJ_5, 1,MINADJ_1)), 286 287 /* Intervall larger than 1 min */ 288 SECPERMIN,array(array(SECPERMIN,15,10,5), 289 array(15,5,2,1), 290 array(1,MINADJ_1, 1,SECADJ_15, 1,SECADJ_10, 1,SECADJ_5)), 291 292 /* Intervall larger than 10 sec */ 293 10,array(array(5,2), 294 array(1,1), 295 array(1,SECADJ_5, 1,SECADJ_1)), 296 297 /* Intervall larger than 1 sec */ 298 1,array(array(1), 299 array(1), 300 array(1,SECADJ_1)), 301 ); 302 303 $ns = count($scalePoints); 304 // Establish major and minor scale units for the date scale 305 $diff = $aEndTime - $aStartTime; 306 if( $diff < 1 ) return false; 307 $done=false; 308 $i=0; 309 while( ! $done ) { 310 if( $diff > $scalePoints[2*$i] ) { 311 // Get major and minor scale for this intervall 312 $scaleSteps = $scalePoints[2*$i+1]; 313 $major = $scaleSteps[0][min($aDensity,count($scaleSteps[0])-1)]; 314 // Try to find out which minor step looks best 315 $minor = $scaleSteps[1][min($aDensity,count($scaleSteps[1])-1)]; 316 if( $aAdjust ) { 317 // Find out how we should align the start and end timestamps 318 $idx = 2*min($aDensity,floor(count($scaleSteps[2])/2)-1); 319 if( $scaleSteps[2][$idx] === 0 ) { 320 // Use date adjustment 321 $adj = $scaleSteps[2][$idx+1]; 322 if( $adj >= 30 ) { 323 $start = $this->AdjStartDate($aStartTime,$adj-30); 324 $end = $this->AdjEndDate($aEndTime,$adj-30); 325 } 326 elseif( $adj >= 20 ) { 327 $start = $this->AdjStartDate($aStartTime,false,$adj-20); 328 $end = $this->AdjEndDate($aEndTime,false,$adj-20); 329 } 330 else { 331 $start = $this->AdjStartDate($aStartTime,false,false,$adj); 332 $end = $this->AdjEndDate($aEndTime,false,false,$adj); 333 // We add 1 second for date adjustment to make sure we end on 00:00 the following day 334 // This makes the final major tick be srawn when we step day-by-day instead of ending 335 // on xx:59:59 which would not draw the final major tick 336 $end++; 337 } 338 } 339 else { 340 // Use time adjustment 341 $adj = $scaleSteps[2][$idx+1]; 342 if( $adj >= 30 ) { 343 $start = $this->AdjStartTime($aStartTime,$adj-30); 344 $end = $this->AdjEndTime($aEndTime,$adj-30); 345 } 346 elseif( $adj >= 20 ) { 347 $start = $this->AdjStartTime($aStartTime,false,$adj-20); 348 $end = $this->AdjEndTime($aEndTime,false,$adj-20); 349 } 350 else { 351 $start = $this->AdjStartTime($aStartTime,false,false,$adj); 352 $end = $this->AdjEndTime($aEndTime,false,false,$adj); 353 } 354 } 355 } 356 // If the overall date span is larger than 1 day ten we show date 357 $format = ''; 358 if( ($end-$start) > SECPERDAY ) { 359 $format = 'Y-m-d '; 360 } 361 // If the major step is less than 1 day we need to whow hours + min 362 if( $major < SECPERDAY ) { 363 $format .= 'H:i'; 364 } 365 // If the major step is less than 1 min we need to show sec 366 if( $major < 60 ) { 367 $format .= ':s'; 368 } 369 $done=true; 370 } 371 ++$i; 372 } 373 return array($start,$end,$major,$minor,$format); 374 374 } 375 375 376 376 // Overrides the automatic determined date format. Must be a valid date() format string 377 377 function SetDateFormat($aFormat) { 378 379 378 $this->date_format = $aFormat; 379 $this->ticks->SetLabelDateFormat($this->date_format); 380 380 } 381 381 382 382 function AdjustForDST($aFlg=true) { 383 383 $this->ticks->AdjustForDST($aFlg); 384 384 } 385 385 386 386 387 387 function SetDateAlign($aStartAlign,$aEndAlign=false) { 388 389 390 391 392 388 if( $aEndAlign === false ) { 389 $aEndAlign=$aStartAlign; 390 } 391 $this->iStartAlign = $aStartAlign; 392 $this->iEndAlign = $aEndAlign; 393 393 } 394 394 395 395 function SetTimeAlign($aStartAlign,$aEndAlign=false) { 396 397 398 399 400 396 if( $aEndAlign === false ) { 397 $aEndAlign=$aStartAlign; 398 } 399 $this->iStartTimeAlign = $aStartAlign; 400 $this->iEndTimeAlign = $aEndAlign; 401 401 } 402 402 403 403 404 404 function AutoScale($img,$aStartTime,$aEndTime,$aNumSteps,$_adummy=false) { 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 //('It is only possible to use either SetDateAlign() or SetTimeAlign() but not both');439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 if( $this->date_format == '' ) 492 493 else 494 405 // We need to have one dummy argument to make the signature of AutoScale() 406 // identical to LinearScale::AutoScale 407 if( $aStartTime == $aEndTime ) { 408 // Special case when we only have one data point. 409 // Create a small artifical intervall to do the autoscaling 410 $aStartTime -= 10; 411 $aEndTime += 10; 412 } 413 $done=false; 414 $i=0; 415 while( ! $done && $i < 5) { 416 list($adjstart,$adjend,$maj,$min,$format) = $this->DoDateAutoScale($aStartTime,$aEndTime,$i); 417 $n = floor(($adjend-$adjstart)/$maj); 418 if( $n * 1.7 > $aNumSteps ) { 419 $done=true; 420 } 421 $i++; 422 } 423 424 /* 425 if( 0 ) { // DEBUG 426 echo " Start =".date("Y-m-d H:i:s",$aStartTime)."<br>"; 427 echo " End =".date("Y-m-d H:i:s",$aEndTime)."<br>"; 428 echo "Adj Start =".date("Y-m-d H:i:s",$adjstart)."<br>"; 429 echo "Adj End =".date("Y-m-d H:i:s",$adjend)."<p>"; 430 echo "Major = $maj s, ".floor($maj/60)."min, ".floor($maj/3600)."h, ".floor($maj/86400)."day<br>"; 431 echo "Min = $min s, ".floor($min/60)."min, ".floor($min/3600)."h, ".floor($min/86400)."day<br>"; 432 echo "Format=$format<p>"; 433 } 434 */ 435 436 if( $this->iStartTimeAlign !== false && $this->iStartAlign !== false ) { 437 JpGraphError::RaiseL(3001); 438 //('It is only possible to use either SetDateAlign() or SetTimeAlign() but not both'); 439 } 440 441 if( $this->iStartTimeAlign !== false ) { 442 if( $this->iStartTimeAlign >= 30 ) { 443 $adjstart = $this->AdjStartTime($aStartTime,$this->iStartTimeAlign-30); 444 } 445 elseif( $this->iStartTimeAlign >= 20 ) { 446 $adjstart = $this->AdjStartTime($aStartTime,false,$this->iStartTimeAlign-20); 447 } 448 else { 449 $adjstart = $this->AdjStartTime($aStartTime,false,false,$this->iStartTimeAlign); 450 } 451 } 452 if( $this->iEndTimeAlign !== false ) { 453 if( $this->iEndTimeAlign >= 30 ) { 454 $adjend = $this->AdjEndTime($aEndTime,$this->iEndTimeAlign-30); 455 } 456 elseif( $this->iEndTimeAlign >= 20 ) { 457 $adjend = $this->AdjEndTime($aEndTime,false,$this->iEndTimeAlign-20); 458 } 459 else { 460 $adjend = $this->AdjEndTime($aEndTime,false,false,$this->iEndTimeAlign); 461 } 462 } 463 464 465 466 if( $this->iStartAlign !== false ) { 467 if( $this->iStartAlign >= 30 ) { 468 $adjstart = $this->AdjStartDate($aStartTime,$this->iStartAlign-30); 469 } 470 elseif( $this->iStartAlign >= 20 ) { 471 $adjstart = $this->AdjStartDate($aStartTime,false,$this->iStartAlign-20); 472 } 473 else { 474 $adjstart = $this->AdjStartDate($aStartTime,false,false,$this->iStartAlign); 475 } 476 } 477 if( $this->iEndAlign !== false ) { 478 if( $this->iEndAlign >= 30 ) { 479 $adjend = $this->AdjEndDate($aEndTime,$this->iEndAlign-30); 480 } 481 elseif( $this->iEndAlign >= 20 ) { 482 $adjend = $this->AdjEndDate($aEndTime,false,$this->iEndAlign-20); 483 } 484 else { 485 $adjend = $this->AdjEndDate($aEndTime,false,false,$this->iEndAlign); 486 } 487 } 488 $this->Update($img,$adjstart,$adjend); 489 if( ! $this->ticks->IsSpecified() ) 490 $this->ticks->Set($maj,$min); 491 if( $this->date_format == '' ) 492 $this->ticks->SetLabelDateFormat($format); 493 else 494 $this->ticks->SetLabelDateFormat($this->date_format); 495 495 } 496 496 } -
trunk/client/modules/Elezioni/grafici/jpgraph_errhandler.inc.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // 6 // 7 // Created: 8 // Ver: $Id: jpgraph_errhandler.inc.php 973 2008-03-09 15:29:44Z ljp $3 // File: JPGRAPH_ERRHANDLER.PHP 4 // Description: Error handler class together with handling of localized 5 // error messages. All localized error messages are stored 6 // in a separate file under the "lang/" subdirectory. 7 // Created: 2006-09-24 8 // Ver: $Id: jpgraph_errhandler.inc.php 1920 2009-12-08 10:02:26Z ljp $ 9 9 // 10 10 // Copyright 2006 (c) Aditus Consulting. All rights reserved. 11 11 //======================================================================== 12 12 13 if( !defined('DEFAULT_ERR_LOCALE') ) { 14 define('DEFAULT_ERR_LOCALE','en'); 15 } 16 17 if( !defined('USE_IMAGE_ERROR_HANDLER') ) { 18 define('USE_IMAGE_ERROR_HANDLER',true); 19 } 13 20 14 21 GLOBAL $__jpg_err_locale ; … … 17 24 class ErrMsgText { 18 25 private $lt=NULL; 19 function ErrMsgText() {20 21 22 23 24 25 26 27 28 29 30 31 32 33 26 function __construct() { 27 GLOBAL $__jpg_err_locale; 28 $file = 'lang/'.$__jpg_err_locale.'.inc.php'; 29 30 // If the chosen locale doesn't exist try english 31 if( !file_exists(dirname(__FILE__).'/'.$file) ) { 32 $__jpg_err_locale = 'en'; 33 } 34 35 $file = 'lang/'.$__jpg_err_locale.'.inc.php'; 36 if( !file_exists(dirname(__FILE__).'/'.$file) ) { 37 die('Chosen locale file ("'.$file.'") for error messages does not exist or is not readable for the PHP process. Please make sure that the file exists and that the file permissions are such that the PHP process is allowed to read this file.'); 38 } 39 require($file); 40 $this->lt = $_jpg_messages; 34 41 } 35 42 36 43 function Get($errnbr,$a1=null,$a2=null,$a3=null,$a4=null,$a5=null) { 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 $numargs = $j; 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 } 87 } 88 44 GLOBAL $__jpg_err_locale; 45 if( !isset($this->lt[$errnbr]) ) { 46 return 'Internal error: The specified error message ('.$errnbr.') does not exist in the chosen locale ('.$__jpg_err_locale.')'; 47 } 48 $ea = $this->lt[$errnbr]; 49 $j=0; 50 if( $a1 !== null ) { 51 $argv[$j++] = $a1; 52 if( $a2 !== null ) { 53 $argv[$j++] = $a2; 54 if( $a3 !== null ) { 55 $argv[$j++] = $a3; 56 if( $a4 !== null ) { 57 $argv[$j++] = $a4; 58 if( $a5 !== null ) { 59 $argv[$j++] = $a5; 60 } 61 } 62 } 63 } 64 } 65 $numargs = $j; 66 if( $ea[1] != $numargs ) { 67 // Error message argument count do not match. 68 // Just return the error message without arguments. 69 return $ea[0]; 70 } 71 switch( $numargs ) { 72 case 1: 73 $msg = sprintf($ea[0],$argv[0]); 74 break; 75 case 2: 76 $msg = sprintf($ea[0],$argv[0],$argv[1]); 77 break; 78 case 3: 79 $msg = sprintf($ea[0],$argv[0],$argv[1],$argv[2]); 80 break; 81 case 4: 82 $msg = sprintf($ea[0],$argv[0],$argv[1],$argv[2],$argv[3]); 83 break; 84 case 5: 85 $msg = sprintf($ea[0],$argv[0],$argv[1],$argv[2],$argv[3],$argv[4]); 86 break; 87 case 0: 88 default: 89 $msg = sprintf($ea[0]); 90 break; 91 } 92 return $msg; 93 } 94 } 95 89 96 // 90 97 // A wrapper class that is used to access the specified error object … … 93 100 // 94 101 class JpGraphError { 95 private static $__jpg_err; 96 public static function Install($aErrObject) { 97 self::$__jpg_err = new $aErrObject; 98 } 102 private static $__iImgFlg = true; 103 private static $__iLogFile = ''; 104 private static $__iTitle = 'JpGraph Error: '; 99 105 public static function Raise($aMsg,$aHalt=true){ 100 self::$__jpg_err->Raise($aMsg,$aHalt);106 throw new JpGraphException($aMsg); 101 107 } 102 108 public static function SetErrLocale($aLoc) { 103 104 109 GLOBAL $__jpg_err_locale ; 110 $__jpg_err_locale = $aLoc; 105 111 } 106 112 public static function RaiseL($errnbr,$a1=null,$a2=null,$a3=null,$a4=null,$a5=null) { 107 $t = new ErrMsgText(); 108 $msg = $t->Get($errnbr,$a1,$a2,$a3,$a4,$a5); 109 self::$__jpg_err->Raise($msg); 110 } 111 } 113 throw new JpGraphExceptionL($errnbr,$a1,$a2,$a3,$a4,$a5); 114 } 115 public static function SetImageFlag($aFlg=true) { 116 self::$__iImgFlg = $aFlg; 117 } 118 public static function GetImageFlag() { 119 return self::$__iImgFlg; 120 } 121 public static function SetLogFile($aFile) { 122 self::$__iLogFile = $aFile; 123 } 124 public static function GetLogFile() { 125 return self::$__iLogFile; 126 } 127 public static function SetTitle($aTitle) { 128 self::$__iTitle = $aTitle; 129 } 130 public static function GetTitle() { 131 return self::$__iTitle; 132 } 133 } 134 135 class JpGraphException extends Exception { 136 // Redefine the exception so message isn't optional 137 public function __construct($message, $code = 0) { 138 // make sure everything is assigned properly 139 parent::__construct($message, $code); 140 } 141 // custom string representation of object 142 public function _toString() { 143 return __CLASS__ . ": [{$this->code}]: {$this->message} at " . basename($this->getFile()) . ":" . $this->getLine() . "\n" . $this->getTraceAsString() . "\n"; 144 } 145 // custom representation of error as an image 146 public function Stroke() { 147 if( JpGraphError::GetImageFlag() ) { 148 $errobj = new JpGraphErrObjectImg(); 149 $errobj->SetTitle(JpGraphError::GetTitle()); 150 } 151 else { 152 $errobj = new JpGraphErrObject(); 153 $errobj->SetTitle(JpGraphError::GetTitle()); 154 $errobj->SetStrokeDest(JpGraphError::GetLogFile()); 155 } 156 $errobj->Raise($this->getMessage()); 157 } 158 static public function defaultHandler(Exception $exception) { 159 global $__jpg_OldHandler; 160 if( $exception instanceof JpGraphException ) { 161 $exception->Stroke(); 162 } 163 else { 164 // Restore old handler 165 if( $__jpg_OldHandler !== NULL ) { 166 set_exception_handler($__jpg_OldHandler); 167 } 168 throw $exception; 169 } 170 } 171 } 172 173 class JpGraphExceptionL extends JpGraphException { 174 // Redefine the exception so message isn't optional 175 public function __construct($errcode,$a1=null,$a2=null,$a3=null,$a4=null,$a5=null) { 176 // make sure everything is assigned properly 177 $errtxt = new ErrMsgText(); 178 JpGraphError::SetTitle('JpGraph Error: '.$errcode); 179 parent::__construct($errtxt->Get($errcode,$a1,$a2,$a3,$a4,$a5), 0); 180 } 181 } 182 183 // Setup the default handler 184 global $__jpg_OldHandler; 185 $__jpg_OldHandler = set_exception_handler(array('JpGraphException','defaultHandler')); 112 186 113 187 // … … 120 194 class JpGraphErrObject { 121 195 122 protected $iTitle = "JpGraph Error";196 protected $iTitle = "JpGraph error: "; 123 197 protected $iDest = false; 124 198 125 199 126 function JpGraphErrObject() {127 200 function __construct() { 201 // Empty. Reserved for future use 128 202 } 129 203 130 204 function SetTitle($aTitle) { 131 132 } 133 134 function SetStrokeDest($aDest) { 135 $this->iDest = $aDest; 205 $this->iTitle = $aTitle; 206 } 207 208 function SetStrokeDest($aDest) { 209 $this->iDest = $aDest; 136 210 } 137 211 138 212 // If aHalt is true then execution can't continue. Typical used for fatal errors 139 function Raise($aMsg,$aHalt=true) { 140 $aMsg = $this->iTitle.' '.$aMsg; 141 if ($this->iDest) { 142 $f = @fopen($this->iDest,'a'); 143 if( $f ) { 144 @fwrite($f,$aMsg); 145 @fclose($f); 146 } 147 } 148 else { 149 echo $aMsg; 150 } 151 if( $aHalt ) 152 die(); 213 function Raise($aMsg,$aHalt=false) { 214 if( $this->iDest != '' ) { 215 if( $this->iDest == 'syslog' ) { 216 error_log($this->iTitle.$aMsg); 217 } 218 else { 219 $str = '['.date('r').'] '.$this->iTitle.$aMsg."\n"; 220 $f = @fopen($this->iDest,'a'); 221 if( $f ) { 222 @fwrite($f,$str); 223 @fclose($f); 224 } 225 } 226 } 227 else { 228 $aMsg = $this->iTitle.$aMsg; 229 // Check SAPI and if we are called from the command line 230 // send the error to STDERR instead 231 if( PHP_SAPI == 'cli' ) { 232 fwrite(STDERR,$aMsg); 233 } 234 else { 235 echo $aMsg; 236 } 237 } 238 if( $aHalt ) 239 exit(1); 153 240 } 154 241 } … … 158 245 //============================================================== 159 246 class JpGraphErrObjectImg extends JpGraphErrObject { 247 248 function __construct() { 249 parent::__construct(); 250 // Empty. Reserved for future use 251 } 160 252 161 253 function Raise($aMsg,$aHalt=true) { 162 $img_iconerror = 163 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAAAaV'. 164 'BMVEX//////2Xy8mLl5V/Z2VvMzFi/v1WyslKlpU+ZmUyMjEh/'. 165 'f0VyckJlZT9YWDxMTDjAwMDy8sLl5bnY2K/MzKW/v5yyspKlpY'. 166 'iYmH+MjHY/PzV/f2xycmJlZVlZWU9MTEXY2Ms/PzwyMjLFTjea'. 167 'AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACx'. 168 'IAAAsSAdLdfvwAAAAHdElNRQfTBgISOCqusfs5AAABLUlEQVR4'. 169 '2tWV3XKCMBBGWfkranCIVClKLd/7P2Q3QsgCxjDTq+6FE2cPH+'. 170 'xJ0Ogn2lQbsT+Wrs+buAZAV4W5T6Bs0YXBBwpKgEuIu+JERAX6'. 171 'wM2rHjmDdEITmsQEEmWADgZm6rAjhXsoMGY9B/NZBwJzBvn+e3'. 172 'wHntCAJdGu9SviwIwoZVDxPB9+Rc0TSEbQr0j3SA1gwdSn6Db0'. 173 '6Tm1KfV6yzWGQO7zdpvyKLKBDmRFjzeB3LYgK7r6A/noDAfjtS'. 174 'IXaIzbJSv6WgUebTMV4EoRB8a2mQiQjgtF91HdKDKZ1gtFtQjk'. 175 'YcWaR5OKOhkYt+ZsTFdJRfPAApOpQYJTNHvCRSJR6SJngQadfc'. 176 'vd69OLMddVOPCGVnmrFD8bVYd3JXfxXPtLR/+mtv59/ALWiiMx'. 177 'qL72fwAAAABJRU5ErkJggg==' ; 178 179 if( function_exists("imagetypes") ) 180 $supported = imagetypes(); 181 else 182 $supported = 0; 183 184 if( !function_exists('imagecreatefromstring') ) 185 $supported = 0; 186 187 if( ob_get_length() || headers_sent() || !($supported & IMG_PNG) ) { 188 // Special case for headers already sent or that the installation doesn't support 189 // the PNG format (which the error icon is encoded in). 190 // Dont return an image since it can't be displayed 191 die($this->iTitle.' '.$aMsg); 192 } 193 194 $aMsg = wordwrap($aMsg,55); 195 $lines = substr_count($aMsg,"\n"); 196 197 // Create the error icon GD 198 $erricon = Image::CreateFromString(base64_decode($img_iconerror)); 199 200 // Create an image that contains the error text. 201 $w=400; 202 $h=100 + 15*max(0,$lines-3); 203 204 $img = new Image($w,$h); 205 206 207 // Drop shadow 208 $img->SetColor("gray"); 209 $img->FilledRectangle(5,5,$w-1,$h-1,10); 210 $img->SetColor("gray:0.7"); 211 $img->FilledRectangle(5,5,$w-3,$h-3,10); 212 213 // Window background 214 $img->SetColor("lightblue"); 215 $img->FilledRectangle(1,1,$w-5,$h-5); 216 $img->CopyCanvasH($img->img,$erricon,5,30,0,0,40,40); 217 218 // Window border 219 $img->SetColor("black"); 220 $img->Rectangle(1,1,$w-5,$h-5); 221 $img->Rectangle(0,0,$w-4,$h-4); 222 223 // Window top row 224 $img->SetColor("darkred"); 225 for($y=3; $y < 18; $y += 2 ) 226 $img->Line(1,$y,$w-6,$y); 227 228 // "White shadow" 229 $img->SetColor("white"); 230 231 // Left window edge 232 $img->Line(2,2,2,$h-5); 233 $img->Line(2,2,$w-6,2); 234 235 // "Gray button shadow" 236 $img->SetColor("darkgray"); 237 238 // Gray window shadow 239 $img->Line(2,$h-6,$w-5,$h-6); 240 $img->Line(3,$h-7,$w-5,$h-7); 241 242 // Window title 243 $m = floor($w/2-5); 244 $l = 100; 245 $img->SetColor("lightgray:1.3"); 246 $img->FilledRectangle($m-$l,2,$m+$l,16); 247 248 // Stroke text 249 $img->SetColor("darkred"); 250 $img->SetFont(FF_FONT2,FS_BOLD); 251 $img->StrokeText($m-50,15,$this->iTitle); 252 $img->SetColor("black"); 253 $img->SetFont(FF_FONT1,FS_NORMAL); 254 $txt = new Text($aMsg,52,25); 255 $txt->Align("left","top"); 256 $txt->Stroke($img); 257 if ($this->iDest) { 258 $img->Stream($this->iDest); 259 } else { 260 $img->Headers(); 261 $img->Stream(); 262 } 263 if( $aHalt ) 264 die(); 265 } 266 } 267 268 269 // Install the default error handler 270 if( USE_IMAGE_ERROR_HANDLER ) { 271 JpGraphError::Install("JpGraphErrObjectImg"); 272 } 273 else { 274 JpGraphError::Install("JpGraphErrObject"); 275 } 276 277 254 $img_iconerror = 255 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAAAaV'. 256 'BMVEX//////2Xy8mLl5V/Z2VvMzFi/v1WyslKlpU+ZmUyMjEh/'. 257 'f0VyckJlZT9YWDxMTDjAwMDy8sLl5bnY2K/MzKW/v5yyspKlpY'. 258 'iYmH+MjHY/PzV/f2xycmJlZVlZWU9MTEXY2Ms/PzwyMjLFTjea'. 259 'AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACx'. 260 'IAAAsSAdLdfvwAAAAHdElNRQfTBgISOCqusfs5AAABLUlEQVR4'. 261 '2tWV3XKCMBBGWfkranCIVClKLd/7P2Q3QsgCxjDTq+6FE2cPH+'. 262 'xJ0Ogn2lQbsT+Wrs+buAZAV4W5T6Bs0YXBBwpKgEuIu+JERAX6'. 263 'wM2rHjmDdEITmsQEEmWADgZm6rAjhXsoMGY9B/NZBwJzBvn+e3'. 264 'wHntCAJdGu9SviwIwoZVDxPB9+Rc0TSEbQr0j3SA1gwdSn6Db0'. 265 '6Tm1KfV6yzWGQO7zdpvyKLKBDmRFjzeB3LYgK7r6A/noDAfjtS'. 266 'IXaIzbJSv6WgUebTMV4EoRB8a2mQiQjgtF91HdKDKZ1gtFtQjk'. 267 'YcWaR5OKOhkYt+ZsTFdJRfPAApOpQYJTNHvCRSJR6SJngQadfc'. 268 'vd69OLMddVOPCGVnmrFD8bVYd3JXfxXPtLR/+mtv59/ALWiiMx'. 269 'qL72fwAAAABJRU5ErkJggg==' ; 270 271 272 if( function_exists("imagetypes") ) { 273 $supported = imagetypes(); 274 } else { 275 $supported = 0; 276 } 277 278 if( !function_exists('imagecreatefromstring') ) { 279 $supported = 0; 280 } 281 282 if( ob_get_length() || headers_sent() || !($supported & IMG_PNG) ) { 283 // Special case for headers already sent or that the installation doesn't support 284 // the PNG format (which the error icon is encoded in). 285 // Dont return an image since it can't be displayed 286 die($this->iTitle.' '.$aMsg); 287 } 288 289 $aMsg = wordwrap($aMsg,55); 290 $lines = substr_count($aMsg,"\n"); 291 292 // Create the error icon GD 293 $erricon = Image::CreateFromString(base64_decode($img_iconerror)); 294 295 // Create an image that contains the error text. 296 $w=400; 297 $h=100 + 15*max(0,$lines-3); 298 299 $img = new Image($w,$h); 300 301 302 // Drop shadow 303 $img->SetColor("gray"); 304 $img->FilledRectangle(5,5,$w-1,$h-1,10); 305 $img->SetColor("gray:0.7"); 306 $img->FilledRectangle(5,5,$w-3,$h-3,10); 307 308 // Window background 309 $img->SetColor("lightblue"); 310 $img->FilledRectangle(1,1,$w-5,$h-5); 311 $img->CopyCanvasH($img->img,$erricon,5,30,0,0,40,40); 312 313 // Window border 314 $img->SetColor("black"); 315 $img->Rectangle(1,1,$w-5,$h-5); 316 $img->Rectangle(0,0,$w-4,$h-4); 317 318 // Window top row 319 $img->SetColor("darkred"); 320 for($y=3; $y < 18; $y += 2 ) 321 $img->Line(1,$y,$w-6,$y); 322 323 // "White shadow" 324 $img->SetColor("white"); 325 326 // Left window edge 327 $img->Line(2,2,2,$h-5); 328 $img->Line(2,2,$w-6,2); 329 330 // "Gray button shadow" 331 $img->SetColor("darkgray"); 332 333 // Gray window shadow 334 $img->Line(2,$h-6,$w-5,$h-6); 335 $img->Line(3,$h-7,$w-5,$h-7); 336 337 // Window title 338 $m = floor($w/2-5); 339 $l = 110; 340 $img->SetColor("lightgray:1.3"); 341 $img->FilledRectangle($m-$l,2,$m+$l,16); 342 343 // Stroke text 344 $img->SetColor("darkred"); 345 $img->SetFont(FF_FONT2,FS_BOLD); 346 $img->StrokeText($m-90,15,$this->iTitle); 347 $img->SetColor("black"); 348 $img->SetFont(FF_FONT1,FS_NORMAL); 349 $txt = new Text($aMsg,52,25); 350 $txt->SetFont(FF_FONT1); 351 $txt->Align("left","top"); 352 $txt->Stroke($img); 353 if ($this->iDest) { 354 $img->Stream($this->iDest); 355 } else { 356 $img->Headers(); 357 $img->Stream(); 358 } 359 if( $aHalt ) 360 die(); 361 } 362 } 363 364 365 366 if( ! USE_IMAGE_ERROR_HANDLER ) { 367 JpGraphError::SetImageFlag(false); 368 } 278 369 ?> -
trunk/client/modules/Elezioni/grafici/jpgraph_error.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_ERROR.PHP4 // Description:Error plot extension for JpGraph5 // Created:2001-01-086 // Ver: $Id: jpgraph_error.php 781 2006-10-08 08:07:47Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */11 3 // File: JPGRAPH_ERROR.PHP 4 // Description: Error plot extension for JpGraph 5 // Created: 2001-01-08 6 // Ver: $Id: jpgraph_error.php 1106 2009-02-22 20:16:35Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 12 12 //=================================================== 13 13 // CLASS ErrorPlot … … 17 17 class ErrorPlot extends Plot { 18 18 private $errwidth=2; 19 //--------------- 20 // CONSTRUCTOR 21 function ErrorPlot($datay,$datax=false) { 22 $this->Plot($datay,$datax); 23 $this->numpoints /= 2; 19 20 //--------------- 21 // CONSTRUCTOR 22 function __construct($datay,$datax=false) { 23 parent::__construct($datay,$datax); 24 $this->numpoints /= 2; 24 25 } 25 //---------------26 // PUBLIC METHODS27 26 //--------------- 27 // PUBLIC METHODS 28 28 29 // Gets called before any axis are stroked 29 30 function PreStrokeAdjust($graph) { 30 31 32 ++$this->numpoints; 33 34 35 36 37 $graph->SetTextScaleOff($b); 38 31 if( $this->center ) { 32 $a=0.5; $b=0.5; 33 ++$this->numpoints; 34 } else { 35 $a=0; $b=0; 36 } 37 $graph->xaxis->scale->ticks->SetXLabelOffset($a); 38 $graph->SetTextScaleOff($b); 39 //$graph->xaxis->scale->ticks->SupressMinorTickMarks(); 39 40 } 40 41 41 42 // Method description 42 43 function Stroke($img,$xscale,$yscale) { 43 44 45 $img->SetLineWeight($this->weight); 44 $numpoints=count($this->coords[0])/2; 45 $img->SetColor($this->color); 46 $img->SetLineWeight($this->weight); 46 47 47 48 49 50 //("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints");51 52 53 54 else 55 48 if( isset($this->coords[1]) ) { 49 if( count($this->coords[1])!=$numpoints ) 50 JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints); 51 //("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints"); 52 else 53 $exist_x = true; 54 } 55 else 56 $exist_x = false; 56 57 57 58 if( $exist_x ) 59 60 else 61 58 for( $i=0; $i<$numpoints; ++$i) { 59 if( $exist_x ) 60 $x=$this->coords[1][$i]; 61 else 62 $x=$i; 62 63 63 if( !is_numeric($x) || 64 65 66 64 if( !is_numeric($x) || 65 !is_numeric($this->coords[0][$i*2]) || !is_numeric($this->coords[0][$i*2+1]) ) { 66 continue; 67 } 67 68 68 69 70 71 72 73 74 } 75 69 $xt = $xscale->Translate($x); 70 $yt1 = $yscale->Translate($this->coords[0][$i*2]); 71 $yt2 = $yscale->Translate($this->coords[0][$i*2+1]); 72 $img->Line($xt,$yt1,$xt,$yt2); 73 $img->Line($xt-$this->errwidth,$yt1,$xt+$this->errwidth,$yt1); 74 $img->Line($xt-$this->errwidth,$yt2,$xt+$this->errwidth,$yt2); 75 } 76 return true; 76 77 } 77 78 } // Class … … 86 87 class ErrorLinePlot extends ErrorPlot { 87 88 public $line=null; 88 //---------------89 // CONSTRUCTOR90 function ErrorLinePlot($datay,$datax=false) {91 $this->ErrorPlot($datay,$datax);92 93 94 95 96 } 97 89 //--------------- 90 // CONSTRUCTOR 91 function __construct($datay,$datax=false) { 92 parent::__construct($datay,$datax); 93 // Calculate line coordinates as the average of the error limits 94 $n = count($datay); 95 for($i=0; $i < $n; $i+=2 ) { 96 $ly[]=($datay[$i]+$datay[$i+1])/2; 97 } 98 $this->line=new LinePlot($ly,$datax); 98 99 } 99 100 100 //---------------101 // PUBLIC METHODS101 //--------------- 102 // PUBLIC METHODS 102 103 function Legend($graph) { 103 104 105 104 if( $this->legend != "" ) 105 $graph->legend->Add($this->legend,$this->color); 106 $this->line->Legend($graph); 106 107 } 107 108 108 109 function Stroke($img,$xscale,$yscale) { 109 110 110 parent::Stroke($img,$xscale,$yscale); 111 $this->line->Stroke($img,$xscale,$yscale); 111 112 } 112 113 } // Class … … 119 120 class LineErrorPlot extends ErrorPlot { 120 121 public $line=null; 121 //---------------122 // CONSTRUCTOR122 //--------------- 123 // CONSTRUCTOR 123 124 // Data is (val, errdeltamin, errdeltamax) 124 function LineErrorPlot($datay,$datax=false) {125 126 127 128 129 //('Error in input data to LineErrorPlot. Number of data points must be a multiple of 3');130 131 132 133 134 135 } 136 $this->ErrorPlot($ey,$datax);137 125 function __construct($datay,$datax=false) { 126 $ly=array(); $ey=array(); 127 $n = count($datay); 128 if( $n % 3 != 0 ) { 129 JpGraphError::RaiseL(4002); 130 //('Error in input data to LineErrorPlot. Number of data points must be a multiple of 3'); 131 } 132 for($i=0; $i < $n; $i+=3 ) { 133 $ly[]=$datay[$i]; 134 $ey[]=$datay[$i]+$datay[$i+1]; 135 $ey[]=$datay[$i]+$datay[$i+2]; 136 } 137 parent::__construct($ey,$datax); 138 $this->line=new LinePlot($ly,$datax); 138 139 } 139 140 140 //---------------141 // PUBLIC METHODS141 //--------------- 142 // PUBLIC METHODS 142 143 function Legend($graph) { 143 144 145 144 if( $this->legend != "" ) 145 $graph->legend->Add($this->legend,$this->color); 146 $this->line->Legend($graph); 146 147 } 147 148 148 149 function Stroke($img,$xscale,$yscale) { 149 150 150 parent::Stroke($img,$xscale,$yscale); 151 $this->line->Stroke($img,$xscale,$yscale); 151 152 } 152 153 } // Class -
trunk/client/modules/Elezioni/grafici/jpgraph_flags.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph_flags.php 957 2007-12-01 14:00:29Z ljp $3 // File: JPGRAPH_FLAGS.PHP 4 // Description: Class Jpfile. Handles plotmarks 5 // Created: 2003-06-28 6 // Ver: $Id: jpgraph_flags.php 1106 2009-02-22 20:16:35Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 … … 259 259 private $iFlagCount = -1; 260 260 private $iFlagSetMap = array( 261 262 263 264 265 261 FLAGSIZE1 => 'flags_thumb35x35', 262 FLAGSIZE2 => 'flags_thumb60x60', 263 FLAGSIZE3 => 'flags_thumb100x100', 264 FLAGSIZE4 => 'flags' 265 ); 266 266 267 267 private $iFlagData ; 268 268 private $iOrdIdx=array(); 269 269 270 function FlagImages($aSize=FLAGSIZE1) {271 272 273 274 275 276 277 278 279 280 281 282 283 //('Unknown flag size. ('.$aSize.')');284 285 270 function __construct($aSize=FLAGSIZE1) { 271 switch($aSize) { 272 case FLAGSIZE1 : 273 case FLAGSIZE2 : 274 case FLAGSIZE3 : 275 case FLAGSIZE4 : 276 $file = dirname(__FILE__).'/'.$this->iFlagSetMap[$aSize].'.dat'; 277 $fp = fopen($file,'rb'); 278 $rawdata = fread($fp,filesize($file)); 279 $this->iFlagData = unserialize($rawdata); 280 break; 281 default: 282 JpGraphError::RaiseL(5001,$aSize); 283 //('Unknown flag size. ('.$aSize.')'); 284 } 285 $this->iFlagCount = count($this->iCountryNameMap); 286 286 } 287 287 288 288 function GetNum() { 289 289 return $this->iFlagCount; 290 290 } 291 291 292 292 function GetImgByName($aName,&$outFullName) { 293 294 293 $idx = $this->GetIdxByName($aName,$outFullName); 294 return $this->GetImgByIdx($idx); 295 295 } 296 296 297 297 function GetImgByIdx($aIdx) { 298 299 $d = $this->iFlagData[$aIdx][1]; 300 return Image::CreateFromString($d); 301 302 303 304 //("Flag index \"$aIdx\" does not exist.");305 298 if( array_key_exists($aIdx,$this->iFlagData) ) { 299 $d = $this->iFlagData[$aIdx][1]; 300 return Image::CreateFromString($d); 301 } 302 else { 303 JpGraphError::RaiseL(5002,$aIdx); 304 //("Flag index \"ï¿œ$aIdx\" does not exist."); 305 } 306 306 } 307 307 308 308 function GetIdxByOrdinal($aOrd,&$outFullName) { 309 $aOrd--; 310 $n = count($this->iOrdIdx); 311 if( $n == 0 ) { 312 reset($this->iCountryNameMap); 313 $this->iOrdIdx=array(); 314 $i=0; 315 while( list($key,$val) = each($this->iCountryNameMap) ) { 316 $this->iOrdIdx[$i++] = array($val,$key); 317 } 318 $tmp=$this->iOrdIdx[$aOrd]; 319 $outFullName = $tmp[1]; 320 return $tmp[0]; 321 322 } 323 elseif( $aOrd >= 0 && $aOrd < $n ) { 324 $tmp=$this->iOrdIdx[$aOrd]; 325 $outFullName = $tmp[1]; 326 return $tmp[0]; 327 } 328 else { 329 JpGraphError::RaiseL(5003,$aOrd); 330 //('Invalid ordinal number specified for flag index.'); 331 } 309 $aOrd--; 310 $n = count($this->iOrdIdx); 311 if( $n == 0 ) { 312 $this->iOrdIdx=array(); 313 $i=0; 314 foreach( $this->iCountryNameMap as $key => $val ) { 315 $this->iOrdIdx[$i++] = array($val,$key); 316 } 317 $tmp=$this->iOrdIdx[$aOrd]; 318 $outFullName = $tmp[1]; 319 return $tmp[0]; 320 321 } 322 elseif( $aOrd >= 0 && $aOrd < $n ) { 323 $tmp=$this->iOrdIdx[$aOrd]; 324 $outFullName = $tmp[1]; 325 return $tmp[0]; 326 } 327 else { 328 JpGraphError::RaiseL(5003,$aOrd); 329 //('Invalid ordinal number specified for flag index.'); 330 } 332 331 } 333 332 334 333 function GetIdxByName($aName,&$outFullName) { 335 334 336 if( is_integer($aName) ) { 337 $idx = $this->GetIdxByOrdinal($aName,$outFullName); 338 return $idx; 339 } 340 341 $found=false; 342 $aName = strtolower($aName); 343 $nlen = strlen($aName); 344 reset($this->iCountryNameMap); 345 // Start by trying to match exact index name 346 while( list($key,$val) = each($this->iCountryNameMap) ) { 347 if( $nlen == strlen($val) && $val == $aName ) { 348 $found=true; 349 break; 350 } 351 } 352 if( !$found ) { 353 reset($this->iCountryNameMap); 354 // If the exact index doesn't work try a (partial) full name 355 while( list($key,$val) = each($this->iCountryNameMap) ) { 356 if( strpos(strtolower($key), $aName) !== false ) { 357 $found=true; 358 break; 359 } 360 } 361 } 362 if( $found ) { 363 $outFullName = $key; 364 return $val; 365 } 366 else { 367 JpGraphError::RaiseL(5004,$aName); 368 //("The (partial) country name \"$aName\" does not have a cooresponding flag image. The flag may still exist but under another name, e.g. insted of \"usa\" try \"united states\"."); 369 } 335 if( is_integer($aName) ) { 336 $idx = $this->GetIdxByOrdinal($aName,$outFullName); 337 return $idx; 338 } 339 340 $found=false; 341 $aName = strtolower($aName); 342 $nlen = strlen($aName); 343 // Start by trying to match exact index name 344 foreach( $this->iCountryNameMap as $key => $val ) { 345 if( $nlen == strlen($val) && $val == $aName ) { 346 $found=true; 347 break; 348 } 349 } 350 if( !$found ) { 351 // If the exact index doesn't work try a (partial) full name 352 foreach( $this->iCountryNameMap as $key => $val ) { 353 if( strpos(strtolower($key), $aName) !== false ) { 354 $found=true; 355 break; 356 } 357 } 358 } 359 if( $found ) { 360 $outFullName = $key; 361 return $val; 362 } 363 else { 364 JpGraphError::RaiseL(5004,$aName); 365 //("The (partial) country name \"$aName\" does not have a cooresponding flag image. The flag may still exist but under another name, e.g. insted of \"usa\" try \"united states\"."); 366 } 370 367 } 371 368 } -
trunk/client/modules/Elezioni/grafici/jpgraph_gantt.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_GANTT.PHP4 // Description:JpGraph Gantt plot extension5 // Created:2001-11-126 // Ver: $Id: jpgraph_gantt.php 1091 2009-01-18 22:57:40Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */11 12 require_once('jpgraph_plotband.php'); 13 require_once('jpgraph_iconplot.php'); 3 // File: JPGRAPH_GANTT.PHP 4 // Description: JpGraph Gantt plot extension 5 // Created: 2001-11-12 6 // Ver: $Id: jpgraph_gantt.php 1809 2009-09-09 13:07:33Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 12 require_once('jpgraph_plotband.php'); 13 require_once('jpgraph_iconplot.php'); 14 14 require_once('jpgraph_plotmark.inc.php'); 15 15 16 16 // Maximum size for Automatic Gantt chart 17 define('MAX_GANTTIMG_SIZE_W', 4000);17 define('MAX_GANTTIMG_SIZE_W',8000); 18 18 define('MAX_GANTTIMG_SIZE_H',5000); 19 19 … … 27 27 28 28 // Bar patterns 29 define("GANTT_RDIAG",BAND_RDIAG); 29 define("GANTT_RDIAG",BAND_RDIAG); // Right diagonal lines 30 30 define("GANTT_LDIAG",BAND_LDIAG); // Left diagonal lines 31 31 define("GANTT_SOLID",BAND_SOLID); // Solid one color … … 40 40 41 41 // Locales. ONLY KEPT FOR BACKWARDS COMPATIBILITY 42 // You should use the proper locale strings directly 43 // from now on. 42 // You should use the proper locale strings directly 43 // from now on. 44 44 define("LOCALE_EN","en_UK"); 45 45 define("LOCALE_SV","sv_SE"); … … 50 50 51 51 // Style for minute header 52 define("MINUTESTYLE_MM",0); 53 define("MINUTESTYLE_CUSTOM",2); 52 define("MINUTESTYLE_MM",0); // 15 53 define("MINUTESTYLE_CUSTOM",2); // Custom format 54 54 55 55 56 56 // Style for hour header 57 define("HOURSTYLE_HM24",0); 58 define("HOURSTYLE_HMAMPM",1); 59 define("HOURSTYLE_H24",2); 60 define("HOURSTYLE_HAMPM",3); 61 define("HOURSTYLE_CUSTOM",4); 57 define("HOURSTYLE_HM24",0); // 13:10 58 define("HOURSTYLE_HMAMPM",1); // 1:10pm 59 define("HOURSTYLE_H24",2); // 13 60 define("HOURSTYLE_HAMPM",3); // 1pm 61 define("HOURSTYLE_CUSTOM",4); // User defined 62 62 63 63 // Style for day header 64 define("DAYSTYLE_ONELETTER",0); 65 define("DAYSTYLE_LONG",1); 66 define("DAYSTYLE_LONGDAYDATE1",2); 67 define("DAYSTYLE_LONGDAYDATE2",3); 68 define("DAYSTYLE_SHORT",4); 69 define("DAYSTYLE_SHORTDAYDATE1",5); 70 define("DAYSTYLE_SHORTDAYDATE2",6); 71 define("DAYSTYLE_SHORTDAYDATE3",7); 72 define("DAYSTYLE_SHORTDATE1",8); 73 define("DAYSTYLE_SHORTDATE2",9); 74 define("DAYSTYLE_SHORTDATE3",10); 75 define("DAYSTYLE_SHORTDATE4",11); 76 define("DAYSTYLE_CUSTOM",12); 64 define("DAYSTYLE_ONELETTER",0); // "M" 65 define("DAYSTYLE_LONG",1); // "Monday" 66 define("DAYSTYLE_LONGDAYDATE1",2); // "Monday 23 Jun" 67 define("DAYSTYLE_LONGDAYDATE2",3); // "Monday 23 Jun 2003" 68 define("DAYSTYLE_SHORT",4); // "Mon" 69 define("DAYSTYLE_SHORTDAYDATE1",5); // "Mon 23/6" 70 define("DAYSTYLE_SHORTDAYDATE2",6); // "Mon 23 Jun" 71 define("DAYSTYLE_SHORTDAYDATE3",7); // "Mon 23" 72 define("DAYSTYLE_SHORTDATE1",8); // "23/6" 73 define("DAYSTYLE_SHORTDATE2",9); // "23 Jun" 74 define("DAYSTYLE_SHORTDATE3",10); // "Mon 23" 75 define("DAYSTYLE_SHORTDATE4",11); // "23" 76 define("DAYSTYLE_CUSTOM",12); // "M" 77 77 78 78 // Styles for week header … … 128 128 if (!function_exists('array_fill')) { 129 129 function array_fill($iStart, $iLen, $vValue) { 130 131 132 133 134 130 $aResult = array(); 131 for ($iCount = $iStart; $iCount < $iLen + $iStart; $iCount++) { 132 $aResult[$iCount] = $vValue; 133 } 134 return $aResult; 135 135 } 136 136 } … … 138 138 //=================================================== 139 139 // CLASS GanttActivityInfo 140 // Description: 140 // Description: 141 141 //=================================================== 142 142 class GanttActivityInfo { … … 153 153 private $iHeaderAlign='center'; 154 154 155 function GanttActivityInfo() {156 155 function __construct() { 156 $this->vgrid = new LineProperty(); 157 157 } 158 158 159 159 function Hide($aF=true) { 160 160 $this->iShow=!$aF; 161 161 } 162 162 163 163 function Show($aF=true) { 164 164 $this->iShow=$aF; 165 165 } 166 166 167 167 // Specify font 168 168 function SetFont($aFFamily,$aFStyle=FS_NORMAL,$aFSize=10) { 169 170 $this->iFStyle= $aFStyle;171 $this->iFSize= $aFSize;169 $this->iFFamily = $aFFamily; 170 $this->iFStyle = $aFStyle; 171 $this->iFSize = $aFSize; 172 172 } 173 173 174 174 function SetStyle($aStyle) { 175 175 $this->iStyle = $aStyle; 176 176 } 177 177 178 178 function SetColumnMargin($aLeft,$aRight) { 179 180 179 $this->iLeftColMargin = $aLeft; 180 $this->iRightColMargin = $aRight; 181 181 } 182 182 183 183 function SetFontColor($aFontColor) { 184 184 $this->iFontColor = $aFontColor; 185 185 } 186 186 187 187 function SetColor($aColor) { 188 188 $this->iColor = $aColor; 189 189 } 190 190 191 191 function SetBackgroundColor($aColor) { 192 192 $this->iBackgroundColor = $aColor; 193 193 } 194 194 195 195 function SetColTitles($aTitles,$aWidth=null) { 196 197 196 $this->iTitles = $aTitles; 197 $this->iWidth = $aWidth; 198 198 } 199 199 200 200 function SetMinColWidth($aWidths) { 201 202 203 204 205 206 207 208 209 210 211 201 $n = min(count($this->iTitles),count($aWidths)); 202 for($i=0; $i < $n; ++$i ) { 203 if( !empty($aWidths[$i]) ) { 204 if( empty($this->iWidth[$i]) ) { 205 $this->iWidth[$i] = $aWidths[$i]; 206 } 207 else { 208 $this->iWidth[$i] = max($this->iWidth[$i],$aWidths[$i]); 209 } 210 } 211 } 212 212 } 213 213 214 214 function GetWidth($aImg) { 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 215 $txt = new TextProperty(); 216 $txt->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 217 $n = count($this->iTitles) ; 218 $rm=$this->iRightColMargin; 219 $w = 0; 220 for($h=0, $i=0; $i < $n; ++$i ) { 221 $w += $this->iLeftColMargin; 222 $txt->Set($this->iTitles[$i]); 223 if( !empty($this->iWidth[$i]) ) { 224 $w1 = max($txt->GetWidth($aImg)+$rm,$this->iWidth[$i]); 225 } 226 else { 227 $w1 = $txt->GetWidth($aImg)+$rm; 228 } 229 $this->iWidth[$i] = $w1; 230 $w += $w1; 231 $h = max($h,$txt->GetHeight($aImg)); 232 } 233 $this->iHeight = $h+$this->iTopHeaderMargin; 234 234 $txt=''; 235 236 } 237 235 return $w; 236 } 237 238 238 function GetColStart($aImg,&$aStart,$aAddLeftMargin=false) { 239 240 241 242 243 244 245 } 246 239 $n = count($this->iTitles) ; 240 $adj = $aAddLeftMargin ? $this->iLeftColMargin : 0; 241 $aStart=array($aImg->left_margin+$adj); 242 for( $i=1; $i < $n; ++$i ) { 243 $aStart[$i] = $aStart[$i-1]+$this->iLeftColMargin+$this->iWidth[$i-1]; 244 } 245 } 246 247 247 // Adjust headers left, right or centered 248 248 function SetHeaderAlign($aAlign) { 249 249 $this->iHeaderAlign=$aAlign; 250 250 } 251 251 252 252 function Stroke($aImg,$aXLeft,$aYTop,$aXRight,$aYBottom,$aUseTextHeight=false) { 253 253 254 if( !$this->iShow ) return; 255 256 $txt = new TextProperty(); 257 $txt->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 258 $txt->SetColor($this->iFontColor); 259 $txt->SetAlign($this->iHeaderAlign,'top'); 260 $n=count($this->iTitles); 261 262 if( $n == 0 ) 263 return; 264 265 $x = $aXLeft; 266 $h = $this->iHeight; 267 $yTop = $aUseTextHeight ? $aYBottom-$h-$this->iTopColMargin-$this->iBottomColMargin : $aYTop ; 268 269 if( $h < 0 ) { 270 JpGraphError::RaiseL(6001); 271 //('Internal error. Height for ActivityTitles is < 0'); 272 } 273 274 $aImg->SetLineWeight(1); 275 // Set background color 276 $aImg->SetColor($this->iBackgroundColor); 277 $aImg->FilledRectangle($aXLeft,$yTop,$aXRight,$aYBottom-1); 278 279 if( $this->iStyle == 1 ) { 280 // Make a 3D effect 281 $aImg->SetColor('white'); 282 $aImg->Line($aXLeft,$yTop+1, 283 $aXRight,$yTop+1); 284 } 285 286 for($i=0; $i < $n; ++$i ) { 287 if( $this->iStyle == 1 ) { 288 // Make a 3D effect 289 $aImg->SetColor('white'); 290 $aImg->Line($x+1,$yTop,$x+1,$aYBottom); 291 } 292 $x += $this->iLeftColMargin; 293 $txt->Set($this->iTitles[$i]); 294 295 // Adjust the text anchor position according to the choosen alignment 296 $xp = $x; 297 if( $this->iHeaderAlign == 'center' ) { 298 $xp = (($x-$this->iLeftColMargin)+($x+$this->iWidth[$i]))/2; 299 } 300 elseif( $this->iHeaderAlign == 'right' ) { 301 $xp = $x +$this->iWidth[$i]-$this->iRightColMargin; 302 } 303 304 $txt->Stroke($aImg,$xp,$yTop+$this->iTopHeaderMargin); 305 $x += $this->iWidth[$i]; 306 if( $i < $n-1 ) { 307 $aImg->SetColor($this->iColor); 308 $aImg->Line($x,$yTop,$x,$aYBottom); 309 } 310 } 311 312 $aImg->SetColor($this->iColor); 313 $aImg->Line($aXLeft,$yTop, $aXRight,$yTop); 314 315 // Stroke vertical column dividers 316 $cols=array(); 317 $this->GetColStart($aImg,$cols); 318 $n=count($cols); 319 for( $i=1; $i < $n; ++$i ) { 320 $this->vgrid->Stroke($aImg,$cols[$i],$aYBottom,$cols[$i], 321 $aImg->height - $aImg->bottom_margin); 322 } 254 if( !$this->iShow ) return; 255 256 $txt = new TextProperty(); 257 $txt->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 258 $txt->SetColor($this->iFontColor); 259 $txt->SetAlign($this->iHeaderAlign,'top'); 260 $n=count($this->iTitles); 261 262 if( $n == 0 ) 263 return; 264 265 $x = $aXLeft; 266 $h = $this->iHeight; 267 $yTop = $aUseTextHeight ? $aYBottom-$h-$this->iTopColMargin-$this->iBottomColMargin : $aYTop ; 268 269 if( $h < 0 ) { 270 JpGraphError::RaiseL(6001); 271 //('Internal error. Height for ActivityTitles is < 0'); 272 } 273 274 $aImg->SetLineWeight(1); 275 // Set background color 276 $aImg->SetColor($this->iBackgroundColor); 277 $aImg->FilledRectangle($aXLeft,$yTop,$aXRight,$aYBottom-1); 278 279 if( $this->iStyle == 1 ) { 280 // Make a 3D effect 281 $aImg->SetColor('white'); 282 $aImg->Line($aXLeft,$yTop+1,$aXRight,$yTop+1); 283 } 284 285 for($i=0; $i < $n; ++$i ) { 286 if( $this->iStyle == 1 ) { 287 // Make a 3D effect 288 $aImg->SetColor('white'); 289 $aImg->Line($x+1,$yTop,$x+1,$aYBottom); 290 } 291 $x += $this->iLeftColMargin; 292 $txt->Set($this->iTitles[$i]); 293 294 // Adjust the text anchor position according to the choosen alignment 295 $xp = $x; 296 if( $this->iHeaderAlign == 'center' ) { 297 $xp = (($x-$this->iLeftColMargin)+($x+$this->iWidth[$i]))/2; 298 } 299 elseif( $this->iHeaderAlign == 'right' ) { 300 $xp = $x +$this->iWidth[$i]-$this->iRightColMargin; 301 } 302 303 $txt->Stroke($aImg,$xp,$yTop+$this->iTopHeaderMargin); 304 $x += $this->iWidth[$i]; 305 if( $i < $n-1 ) { 306 $aImg->SetColor($this->iColor); 307 $aImg->Line($x,$yTop,$x,$aYBottom); 308 } 309 } 310 311 $aImg->SetColor($this->iColor); 312 $aImg->Line($aXLeft,$yTop, $aXRight,$yTop); 313 314 // Stroke vertical column dividers 315 $cols=array(); 316 $this->GetColStart($aImg,$cols); 317 $n=count($cols); 318 for( $i=1; $i < $n; ++$i ) { 319 $this->vgrid->Stroke($aImg,$cols[$i],$aYBottom,$cols[$i], 320 $aImg->height - $aImg->bottom_margin); 321 } 323 322 } 324 323 } … … 330 329 //=================================================== 331 330 class GanttGraph extends Graph { 332 public $scale; 331 public $scale; // Public accessible 333 332 public $hgrid=null; 334 private $iObj=array(); 335 private $iLabelHMarginFactor=0.2; 336 private $iLabelVMarginFactor=0.4; 337 private $iLayout=GANTT_FROMTOP; 333 private $iObj=array(); // Gantt objects 334 private $iLabelHMarginFactor=0.2; // 10% margin on each side of the labels 335 private $iLabelVMarginFactor=0.4; // 40% margin on top and bottom of label 336 private $iLayout=GANTT_FROMTOP; // Could also be GANTT_EVEN 338 337 private $iSimpleFont = FF_FONT1,$iSimpleFontSize=11; 339 338 private $iSimpleStyle=GANTT_RDIAG,$iSimpleColor='yellow',$iSimpleBkgColor='red'; 340 339 private $iSimpleProgressBkgColor='gray',$iSimpleProgressColor='darkgreen'; 341 340 private $iSimpleProgressStyle=GANTT_SOLID; 342 //--------------- 343 // CONSTRUCTOR 341 private $iZoomFactor = 1.0; 342 //--------------- 343 // CONSTRUCTOR 344 344 // Create a new gantt graph 345 function GanttGraph($aWidth=0,$aHeight=0,$aCachedName="",$aTimeOut=0,$aInline=true) {346 347 348 349 350 351 352 353 //("You can't specify negative sizes for Gantt graph dimensions. Use 0 to indicate that you want the library to automatically determine a dimension.");354 355 Graph::Graph($aWidth,$aHeight,$aCachedName,$aTimeOut,$aInline); 356 357 358 359 360 361 362 363 364 365 } 366 367 //---------------368 // PUBLIC METHODS369 370 // 345 function __construct($aWidth=0,$aHeight=0,$aCachedName="",$aTimeOut=0,$aInline=true) { 346 347 // Backward compatibility 348 if( $aWidth == -1 ) $aWidth=0; 349 if( $aHeight == -1 ) $aHeight=0; 350 351 if( $aWidth< 0 || $aHeight < 0 ) { 352 JpgraphError::RaiseL(6002); 353 //("You can't specify negative sizes for Gantt graph dimensions. Use 0 to indicate that you want the library to automatically determine a dimension."); 354 } 355 parent::__construct($aWidth,$aHeight,$aCachedName,$aTimeOut,$aInline); 356 $this->scale = new GanttScale($this->img); 357 358 // Default margins 359 $this->img->SetMargin(15,17,25,15); 360 361 $this->hgrid = new HorizontalGridLine(); 362 363 $this->scale->ShowHeaders(GANTT_HWEEK|GANTT_HDAY); 364 $this->SetBox(); 365 } 366 367 //--------------- 368 // PUBLIC METHODS 369 370 // 371 371 372 372 function SetSimpleFont($aFont,$aSize) { 373 374 373 $this->iSimpleFont = $aFont; 374 $this->iSimpleFontSize = $aSize; 375 375 } 376 376 377 377 function SetSimpleStyle($aBand,$aColor,$aBkgColor) { 378 379 380 378 $this->iSimpleStyle = $aBand; 379 $this->iSimpleColor = $aColor; 380 $this->iSimpleBkgColor = $aBkgColor; 381 381 } 382 382 383 383 // A utility function to help create basic Gantt charts 384 384 function CreateSimple($data,$constrains=array(),$progress=array()) { 385 $num = count($data); 386 for( $i=0; $i < $num; ++$i) { 387 switch( $data[$i][1] ) { 388 case ACTYPE_GROUP: 389 // Create a slightly smaller height bar since the 390 // "wings" at the end will make it look taller 391 $a = new GanttBar($data[$i][0],$data[$i][2],$data[$i][3],$data[$i][4],'',8); 392 $a->title->SetFont($this->iSimpleFont,FS_BOLD,$this->iSimpleFontSize); 393 $a->rightMark->Show(); 394 $a->rightMark->SetType(MARK_RIGHTTRIANGLE); 395 $a->rightMark->SetWidth(8); 396 $a->rightMark->SetColor('black'); 397 $a->rightMark->SetFillColor('black'); 398 399 $a->leftMark->Show(); 400 $a->leftMark->SetType(MARK_LEFTTRIANGLE); 401 $a->leftMark->SetWidth(8); 402 $a->leftMark->SetColor('black'); 403 $a->leftMark->SetFillColor('black'); 404 405 $a->SetPattern(BAND_SOLID,'black'); 406 $csimpos = 6; 407 break; 408 409 case ACTYPE_NORMAL: 410 $a = new GanttBar($data[$i][0],$data[$i][2],$data[$i][3],$data[$i][4],'',10); 411 $a->title->SetFont($this->iSimpleFont,FS_NORMAL,$this->iSimpleFontSize); 412 $a->SetPattern($this->iSimpleStyle,$this->iSimpleColor); 413 $a->SetFillColor($this->iSimpleBkgColor); 414 // Check if this activity should have a constrain line 415 $n = count($constrains); 416 for( $j=0; $j < $n; ++$j ) { 417 if( empty($constrains[$j]) || (count($constrains[$j]) != 3) ) { 418 JpGraphError::RaiseL(6003,$j); 419 //("Invalid format for Constrain parameter at index=$j in CreateSimple(). Parameter must start with index 0 and contain arrays of (Row,Constrain-To,Constrain-Type)"); 420 } 421 if( $constrains[$j][0]==$data[$i][0] ) { 422 $a->SetConstrain($constrains[$j][1],$constrains[$j][2],'black',ARROW_S2,ARROWT_SOLID); 423 } 424 } 425 426 // Check if this activity have a progress bar 427 $n = count($progress); 428 for( $j=0; $j < $n; ++$j ) { 429 430 if( empty($progress[$j]) || (count($progress[$j]) != 2) ) { 431 JpGraphError::RaiseL(6004,$j); 432 //("Invalid format for Progress parameter at index=$j in CreateSimple(). Parameter must start with index 0 and contain arrays of (Row,Progress)"); 433 } 434 if( $progress[$j][0]==$data[$i][0] ) { 435 $a->progress->Set($progress[$j][1]); 436 $a->progress->SetPattern($this->iSimpleProgressStyle, 437 $this->iSimpleProgressColor); 438 $a->progress->SetFillColor($this->iSimpleProgressBkgColor); 439 //$a->progress->SetPattern($progress[$j][2],$progress[$j][3]); 440 break; 441 } 442 } 443 $csimpos = 6; 444 break; 445 446 case ACTYPE_MILESTONE: 447 $a = new MileStone($data[$i][0],$data[$i][2],$data[$i][3]); 448 $a->title->SetFont($this->iSimpleFont,FS_NORMAL,$this->iSimpleFontSize); 449 $a->caption->SetFont($this->iSimpleFont,FS_NORMAL,$this->iSimpleFontSize); 450 $csimpos = 5; 451 break; 452 default: 453 die('Unknown activity type'); 454 break; 455 } 456 457 // Setup caption 458 $a->caption->Set($data[$i][$csimpos-1]); 459 460 // Check if this activity should have a CSIM target ? 461 if( !empty($data[$i][$csimpos]) ) { 462 $a->SetCSIMTarget($data[$i][$csimpos]); 463 $a->SetCSIMAlt($data[$i][$csimpos+1]); 464 } 465 if( !empty($data[$i][$csimpos+2]) ) { 466 $a->title->SetCSIMTarget($data[$i][$csimpos+2]); 467 $a->title->SetCSIMAlt($data[$i][$csimpos+3]); 468 } 469 470 $this->Add($a); 471 } 472 } 473 474 385 $num = count($data); 386 for( $i=0; $i < $num; ++$i) { 387 switch( $data[$i][1] ) { 388 case ACTYPE_GROUP: 389 // Create a slightly smaller height bar since the 390 // "wings" at the end will make it look taller 391 $a = new GanttBar($data[$i][0],$data[$i][2],$data[$i][3],$data[$i][4],'',8); 392 $a->title->SetFont($this->iSimpleFont,FS_BOLD,$this->iSimpleFontSize); 393 $a->rightMark->Show(); 394 $a->rightMark->SetType(MARK_RIGHTTRIANGLE); 395 $a->rightMark->SetWidth(8); 396 $a->rightMark->SetColor('black'); 397 $a->rightMark->SetFillColor('black'); 398 399 $a->leftMark->Show(); 400 $a->leftMark->SetType(MARK_LEFTTRIANGLE); 401 $a->leftMark->SetWidth(8); 402 $a->leftMark->SetColor('black'); 403 $a->leftMark->SetFillColor('black'); 404 405 $a->SetPattern(BAND_SOLID,'black'); 406 $csimpos = 6; 407 break; 408 409 case ACTYPE_NORMAL: 410 $a = new GanttBar($data[$i][0],$data[$i][2],$data[$i][3],$data[$i][4],'',10); 411 $a->title->SetFont($this->iSimpleFont,FS_NORMAL,$this->iSimpleFontSize); 412 $a->SetPattern($this->iSimpleStyle,$this->iSimpleColor); 413 $a->SetFillColor($this->iSimpleBkgColor); 414 // Check if this activity should have a constrain line 415 $n = count($constrains); 416 for( $j=0; $j < $n; ++$j ) { 417 if( empty($constrains[$j]) || (count($constrains[$j]) != 3) ) { 418 JpGraphError::RaiseL(6003,$j); 419 //("Invalid format for Constrain parameter at index=$j in CreateSimple(). Parameter must start with index 0 and contain arrays of (Row,Constrain-To,Constrain-Type)"); 420 } 421 if( $constrains[$j][0]==$data[$i][0] ) { 422 $a->SetConstrain($constrains[$j][1],$constrains[$j][2],'black',ARROW_S2,ARROWT_SOLID); 423 } 424 } 425 426 // Check if this activity have a progress bar 427 $n = count($progress); 428 for( $j=0; $j < $n; ++$j ) { 429 430 if( empty($progress[$j]) || (count($progress[$j]) != 2) ) { 431 JpGraphError::RaiseL(6004,$j); 432 //("Invalid format for Progress parameter at index=$j in CreateSimple(). Parameter must start with index 0 and contain arrays of (Row,Progress)"); 433 } 434 if( $progress[$j][0]==$data[$i][0] ) { 435 $a->progress->Set($progress[$j][1]); 436 $a->progress->SetPattern($this->iSimpleProgressStyle, 437 $this->iSimpleProgressColor); 438 $a->progress->SetFillColor($this->iSimpleProgressBkgColor); 439 //$a->progress->SetPattern($progress[$j][2],$progress[$j][3]); 440 break; 441 } 442 } 443 $csimpos = 6; 444 break; 445 446 case ACTYPE_MILESTONE: 447 $a = new MileStone($data[$i][0],$data[$i][2],$data[$i][3]); 448 $a->title->SetFont($this->iSimpleFont,FS_NORMAL,$this->iSimpleFontSize); 449 $a->caption->SetFont($this->iSimpleFont,FS_NORMAL,$this->iSimpleFontSize); 450 $csimpos = 5; 451 break; 452 default: 453 die('Unknown activity type'); 454 break; 455 } 456 457 // Setup caption 458 $a->caption->Set($data[$i][$csimpos-1]); 459 460 // Check if this activity should have a CSIM targetï¿œ? 461 if( !empty($data[$i][$csimpos]) ) { 462 $a->SetCSIMTarget($data[$i][$csimpos]); 463 $a->SetCSIMAlt($data[$i][$csimpos+1]); 464 } 465 if( !empty($data[$i][$csimpos+2]) ) { 466 $a->title->SetCSIMTarget($data[$i][$csimpos+2]); 467 $a->title->SetCSIMAlt($data[$i][$csimpos+3]); 468 } 469 470 $this->Add($a); 471 } 472 } 473 474 // Set user specified scale zoom factor when auto sizing is used 475 function SetZoomFactor($aZoom) { 476 $this->iZoomFactor = $aZoom; 477 } 478 479 475 480 // Set what headers should be shown 476 481 function ShowHeaders($aFlg) { 477 478 } 479 480 // Specify the fraction of the font height that should be added 482 $this->scale->ShowHeaders($aFlg); 483 } 484 485 // Specify the fraction of the font height that should be added 481 486 // as vertical margin 482 487 function SetLabelVMarginFactor($aVal) { 483 488 $this->iLabelVMarginFactor = $aVal; 484 489 } 485 490 486 491 // Synonym to the method above 487 492 function SetVMarginFactor($aVal) { 488 489 } 490 491 493 $this->iLabelVMarginFactor = $aVal; 494 } 495 496 492 497 // Add a new Gantt object 493 498 function Add($aObject) { 494 if( is_array($aObject) && count($aObject) > 0 ) { 495 $cl = $aObject[0]; 496 if( class_exists('IconPlot',false) && ($cl instanceof IconPlot) ) { 497 $this->AddIcon($aObject); 498 } 499 else { 500 $n = count($aObject); 501 for($i=0; $i < $n; ++$i) 502 $this->iObj[] = $aObject[$i]; 503 } 499 if( is_array($aObject) && count($aObject) > 0 ) { 500 $cl = $aObject[0]; 501 if( class_exists('IconPlot',false) && ($cl instanceof IconPlot) ) { 502 $this->AddIcon($aObject); 503 } 504 elseif( class_exists('Text',false) && ($cl instanceof Text) ) { 505 $this->AddText($aObject); 506 } 507 else { 508 $n = count($aObject); 509 for($i=0; $i < $n; ++$i) 510 $this->iObj[] = $aObject[$i]; 511 } 512 } 513 else { 514 if( class_exists('IconPlot',false) && ($aObject instanceof IconPlot) ) { 515 $this->AddIcon($aObject); 516 } 517 elseif( class_exists('Text',false) && ($aObject instanceof Text) ) { 518 $this->AddText($aObject); 519 } 520 else { 521 $this->iObj[] = $aObject; 522 } 523 } 524 } 525 526 function StrokeTexts() { 527 // Stroke any user added text objects 528 if( $this->texts != null ) { 529 $n = count($this->texts); 530 for($i=0; $i < $n; ++$i) { 531 if( $this->texts[$i]->iScalePosX !== null && $this->texts[$i]->iScalePosY !== null ) { 532 $x = $this->scale->TranslateDate($this->texts[$i]->iScalePosX); 533 $y = $this->scale->TranslateVertPos($this->texts[$i]->iScalePosY); 534 $y -= $this->scale->GetVertSpacing()/2; 535 } 536 else { 537 $x = $y = null; 538 } 539 $this->texts[$i]->Stroke($this->img,$x,$y); 540 } 541 } 504 542 } 505 else {506 if( class_exists('IconPlot',false) && ($aObject instanceof IconPlot) ) {507 $this->AddIcon($aObject);508 }509 else {510 $this->iObj[] = $aObject;511 }512 }513 }514 543 515 544 // Override inherit method from Graph and give a warning message 516 545 function SetScale($aAxisType,$aYMin=1,$aYMax=1,$aXMin=1,$aXMax=1) { 517 518 //("SetScale() is not meaningfull with Gantt charts.");546 JpGraphError::RaiseL(6005); 547 //("SetScale() is not meaningfull with Gantt charts."); 519 548 } 520 549 … … 522 551 // automtically determined from the input data) 523 552 function SetDateRange($aStart,$aEnd) { 524 525 526 527 528 529 530 531 } 532 553 // Adjust the start and end so that the indicate the 554 // begining and end of respective start and end days 555 if( strpos($aStart,':') === false ) 556 $aStart = date('Y-m-d 00:00',strtotime($aStart)); 557 if( strpos($aEnd,':') === false ) 558 $aEnd = date('Y-m-d 23:59',strtotime($aEnd)); 559 $this->scale->SetRange($aStart,$aEnd); 560 } 561 533 562 // Get the maximum width of the activity titles columns for the bars 534 563 // The name is lightly misleading since we from now on can have … … 536 565 // it only supported a single label, hence the name. 537 566 function GetMaxLabelWidth() { 538 539 540 541 542 543 544 545 546 547 548 else 549 550 551 552 553 554 } 555 567 $m=10; 568 if( $this->iObj != null ) { 569 $marg = $this->scale->actinfo->iLeftColMargin+$this->scale->actinfo->iRightColMargin; 570 $n = count($this->iObj); 571 for($i=0; $i < $n; ++$i) { 572 if( !empty($this->iObj[$i]->title) ) { 573 if( $this->iObj[$i]->title->HasTabs() ) { 574 list($tot,$w) = $this->iObj[$i]->title->GetWidth($this->img,true); 575 $m=max($m,$tot); 576 } 577 else 578 $m=max($m,$this->iObj[$i]->title->GetWidth($this->img)); 579 } 580 } 581 } 582 return $m; 583 } 584 556 585 // Get the maximum height of the titles for the bars 557 586 function GetMaxLabelHeight() { 558 $m=10; 559 if( $this->iObj != null ) { 560 $n = count($this->iObj); 561 for($i=0; $i < $n; ++$i) { 562 if( !empty($this->iObj[$i]->title) ) { 563 $m=max($m,$this->iObj[$i]->title->GetHeight($this->img)); 564 } 565 } 566 } 567 return $m; 587 $m=10; 588 if( $this->iObj != null ) { 589 $n = count($this->iObj); 590 // We can not include the title of GnttVLine since that title is stroked at the bottom 591 // of the Gantt bar and not in the activity title columns 592 for($i=0; $i < $n; ++$i) { 593 if( !empty($this->iObj[$i]->title) && !($this->iObj[$i] instanceof GanttVLine) ) { 594 $m=max($m,$this->iObj[$i]->title->GetHeight($this->img)); 595 } 596 } 597 } 598 return $m; 568 599 } 569 600 570 601 function GetMaxBarAbsHeight() { 571 572 573 574 575 576 577 578 579 return $m; 580 } 581 602 $m=0; 603 if( $this->iObj != null ) { 604 $m = $this->iObj[0]->GetAbsHeight($this->img); 605 $n = count($this->iObj); 606 for($i=1; $i < $n; ++$i) { 607 $m=max($m,$this->iObj[$i]->GetAbsHeight($this->img)); 608 } 609 } 610 return $m; 611 } 612 582 613 // Get the maximum used line number (vertical position) for bars 583 614 function GetBarMaxLineNumber() { 584 585 586 587 588 589 590 591 592 593 } 594 615 $m=1; 616 if( $this->iObj != null ) { 617 $m = $this->iObj[0]->GetLineNbr(); 618 $n = count($this->iObj); 619 for($i=1; $i < $n; ++$i) { 620 $m=max($m,$this->iObj[$i]->GetLineNbr()); 621 } 622 } 623 return $m; 624 } 625 595 626 // Get the minumum and maximum used dates for all bars 596 627 function GetBarMinMax() { 597 598 599 600 601 602 603 //('Cannot autoscale Gantt chart. No dated activities exist. [GetBarMinMax() start >= n]');604 605 606 607 608 609 610 611 if( $rmax != false ) 612 613 614 if( $rmin != false ) 615 616 617 618 619 620 $max = strtotime($maxDate); 621 628 $start = 0 ; 629 $n = count($this->iObj); 630 while( $start < $n && $this->iObj[$start]->GetMaxDate() === false ) 631 ++$start; 632 if( $start >= $n ) { 633 JpgraphError::RaiseL(6006); 634 //('Cannot autoscale Gantt chart. No dated activities exist. [GetBarMinMax() start >= n]'); 635 } 636 637 $max=$this->scale->NormalizeDate($this->iObj[$start]->GetMaxDate()); 638 $min=$this->scale->NormalizeDate($this->iObj[$start]->GetMinDate()); 639 640 for($i=$start+1; $i < $n; ++$i) { 641 $rmax = $this->scale->NormalizeDate($this->iObj[$i]->GetMaxDate()); 642 if( $rmax != false ) 643 $max=Max($max,$rmax); 644 $rmin = $this->scale->NormalizeDate($this->iObj[$i]->GetMinDate()); 645 if( $rmin != false ) 646 $min=Min($min,$rmin); 647 } 648 $minDate = date("Y-m-d",$min); 649 $min = strtotime($minDate); 650 $maxDate = date("Y-m-d 23:59",$max); 651 $max = strtotime($maxDate); 652 return array($min,$max); 622 653 } 623 654 … … 628 659 function AutoSize() { 629 660 630 if( $this->img->img == null ) { 631 // The predefined left, right, top, bottom margins. 632 // Note that the top margin might incease depending on 633 // the title. 634 $lm = $this->img->left_margin; 635 $rm = $this->img->right_margin; 636 $rm += 2 ; 637 $tm = $this->img->top_margin; 638 $bm = $this->img->bottom_margin; 639 $bm += 1; 640 if( BRAND_TIMING ) $bm += 10; 641 642 // First find out the height 643 $n=$this->GetBarMaxLineNumber()+1; 644 $m=max($this->GetMaxLabelHeight(),$this->GetMaxBarAbsHeight()); 645 $height=$n*((1+$this->iLabelVMarginFactor)*$m); 646 647 // Add the height of the scale titles 648 $h=$this->scale->GetHeaderHeight(); 649 $height += $h; 650 651 // Calculate the top margin needed for title and subtitle 652 if( $this->title->t != "" ) { 653 $tm += $this->title->GetFontHeight($this->img); 654 } 655 if( $this->subtitle->t != "" ) { 656 $tm += $this->subtitle->GetFontHeight($this->img); 657 } 658 659 // ...and then take the bottom and top plot margins into account 660 $height += $tm + $bm + $this->scale->iTopPlotMargin + $this->scale->iBottomPlotMargin; 661 // Now find the minimum width for the chart required 662 663 // If day scale or smaller is shown then we use the day font width 664 // as the base size unit. 665 // If only weeks or above is displayed we use a modified unit to 666 // get a smaller image. 667 if( $this->scale->IsDisplayHour() || $this->scale->IsDisplayMinute() ) { 668 // Add 2 pixel margin on each side 669 $fw=$this->scale->day->GetFontWidth($this->img)+4; 670 } 671 elseif( $this->scale->IsDisplayWeek() ) { 672 $fw = 8; 673 } 674 elseif( $this->scale->IsDisplayMonth() ) { 675 $fw = 4; 676 } 677 else { 678 $fw = 2; 679 } 680 681 $nd=$this->scale->GetNumberOfDays(); 682 683 if( $this->scale->IsDisplayDay() ) { 684 // If the days are displayed we also need to figure out 685 // how much space each day's title will require. 686 switch( $this->scale->day->iStyle ) { 687 case DAYSTYLE_LONG : 688 $txt = "Monday"; 689 break; 690 case DAYSTYLE_LONGDAYDATE1 : 691 $txt = "Monday 23 Jun"; 692 break; 693 case DAYSTYLE_LONGDAYDATE2 : 694 $txt = "Monday 23 Jun 2003"; 695 break; 696 case DAYSTYLE_SHORT : 697 $txt = "Mon"; 698 break; 699 case DAYSTYLE_SHORTDAYDATE1 : 661 if( $this->img->img == null ) { 662 // The predefined left, right, top, bottom margins. 663 // Note that the top margin might incease depending on 664 // the title. 665 $hadj = $vadj = 0; 666 if( $this->doshadow ) { 667 $hadj = $this->shadow_width; 668 $vadj = $this->shadow_width+5; 669 } 670 671 $lm = $this->img->left_margin; 672 $rm = $this->img->right_margin +$hadj; 673 $rm += 2 ; 674 $tm = $this->img->top_margin; 675 $bm = $this->img->bottom_margin + $vadj; 676 $bm += 2; 677 678 // If there are any added GanttVLine we must make sure that the 679 // bottom margin is wide enough to hold a title. 680 $n = count($this->iObj); 681 for($i=0; $i < $n; ++$i) { 682 if( $this->iObj[$i] instanceof GanttVLine ) { 683 $bm = max($bm,$this->iObj[$i]->title->GetHeight($this->img)+10); 684 } 685 } 686 687 // First find out the height 688 $n=$this->GetBarMaxLineNumber()+1; 689 $m=max($this->GetMaxLabelHeight(),$this->GetMaxBarAbsHeight()); 690 $height=$n*((1+$this->iLabelVMarginFactor)*$m); 691 692 // Add the height of the scale titles 693 $h=$this->scale->GetHeaderHeight(); 694 $height += $h; 695 696 // Calculate the top margin needed for title and subtitle 697 if( $this->title->t != "" ) { 698 $tm += $this->title->GetFontHeight($this->img); 699 } 700 if( $this->subtitle->t != "" ) { 701 $tm += $this->subtitle->GetFontHeight($this->img); 702 } 703 704 // ...and then take the bottom and top plot margins into account 705 $height += $tm + $bm + $this->scale->iTopPlotMargin + $this->scale->iBottomPlotMargin; 706 // Now find the minimum width for the chart required 707 708 // If day scale or smaller is shown then we use the day font width 709 // as the base size unit. 710 // If only weeks or above is displayed we use a modified unit to 711 // get a smaller image. 712 if( $this->scale->IsDisplayHour() || $this->scale->IsDisplayMinute() ) { 713 // Add 2 pixel margin on each side 714 $fw=$this->scale->day->GetFontWidth($this->img)+4; 715 } 716 elseif( $this->scale->IsDisplayWeek() ) { 717 $fw = 8; 718 } 719 elseif( $this->scale->IsDisplayMonth() ) { 720 $fw = 4; 721 } 722 else { 723 $fw = 2; 724 } 725 726 $nd=$this->scale->GetNumberOfDays(); 727 728 if( $this->scale->IsDisplayDay() ) { 729 // If the days are displayed we also need to figure out 730 // how much space each day's title will require. 731 switch( $this->scale->day->iStyle ) { 732 case DAYSTYLE_LONG : 733 $txt = "Monday"; 734 break; 735 case DAYSTYLE_LONGDAYDATE1 : 736 $txt = "Monday 23 Jun"; 737 break; 738 case DAYSTYLE_LONGDAYDATE2 : 739 $txt = "Monday 23 Jun 2003"; 740 break; 741 case DAYSTYLE_SHORT : 742 $txt = "Mon"; 743 break; 744 case DAYSTYLE_SHORTDAYDATE1 : 700 745 $txt = "Mon 23/6"; 701 702 703 704 705 706 707 708 746 break; 747 case DAYSTYLE_SHORTDAYDATE2 : 748 $txt = "Mon 23 Jun"; 749 break; 750 case DAYSTYLE_SHORTDAYDATE3 : 751 $txt = "Mon 23"; 752 break; 753 case DAYSTYLE_SHORTDATE1 : 709 754 $txt = "23/6"; 710 break; 711 case DAYSTYLE_SHORTDATE2 : 712 $txt = "23 Jun"; 713 break; 714 case DAYSTYLE_SHORTDATE3 : 715 $txt = "Mon 23"; 716 break; 717 case DAYSTYLE_SHORTDATE4 : 718 $txt = "88"; 719 break; 720 case DAYSTYLE_CUSTOM : 721 $txt = date($this->scale->day->iLabelFormStr, 722 strtotime('2003-12-20 18:00')); 723 break; 724 case DAYSTYLE_ONELETTER : 725 default: 726 $txt = "M"; 727 break; 728 } 729 $fw = $this->scale->day->GetStrWidth($this->img,$txt)+6; 730 } 731 732 // If we have hours enabled we must make sure that each day has enough 733 // space to fit the number of hours to be displayed. 734 if( $this->scale->IsDisplayHour() ) { 735 // Depending on what format the user has choose we need different amount 736 // of space. We therefore create a typical string for the choosen format 737 // and determine the length of that string. 738 switch( $this->scale->hour->iStyle ) { 739 case HOURSTYLE_HMAMPM: 740 $txt = '12:00pm'; 741 break; 742 case HOURSTYLE_H24: 743 // 13 744 $txt = '24'; 745 break; 746 case HOURSTYLE_HAMPM: 747 $txt = '12pm'; 748 break; 749 case HOURSTYLE_CUSTOM: 750 $txt = date($this->scale->hour->iLabelFormStr,strtotime('2003-12-20 18:00')); 751 break; 752 case HOURSTYLE_HM24: 753 default: 754 $txt = '24:00'; 755 break; 756 } 757 758 $hfw = $this->scale->hour->GetStrWidth($this->img,$txt)+6; 759 $mw = $hfw; 760 if( $this->scale->IsDisplayMinute() ) { 761 // Depending on what format the user has choose we need different amount 762 // of space. We therefore create a typical string for the choosen format 763 // and determine the length of that string. 764 switch( $this->scale->minute->iStyle ) { 765 case HOURSTYLE_CUSTOM: 766 $txt2 = date($this->scale->minute->iLabelFormStr,strtotime('2005-05-15 18:55')); 767 break; 768 case MINUTESTYLE_MM: 769 default: 770 $txt2 = '15'; 771 break; 772 } 773 774 $mfw = $this->scale->minute->GetStrWidth($this->img,$txt2)+6; 775 $n2 = ceil(60 / $this->scale->minute->GetIntervall() ); 776 $mw = $n2 * $mfw; 777 } 778 $hfw = $hfw < $mw ? $mw : $hfw ; 779 $n = ceil(24*60 / $this->scale->TimeToMinutes($this->scale->hour->GetIntervall()) ); 780 $hw = $n * $hfw; 781 $fw = $fw < $hw ? $hw : $fw ; 782 } 783 784 // We need to repeat this code block here as well. 785 // THIS iS NOT A MISTAKE ! 786 // We really need it since we need to adjust for minutes both in the case 787 // where hour scale is shown and when it is not shown. 788 789 if( $this->scale->IsDisplayMinute() ) { 790 // Depending on what format the user has choose we need different amount 791 // of space. We therefore create a typical string for the choosen format 792 // and determine the length of that string. 793 switch( $this->scale->minute->iStyle ) { 794 case HOURSTYLE_CUSTOM: 795 $txt = date($this->scale->minute->iLabelFormStr,strtotime('2005-05-15 18:55')); 796 break; 797 case MINUTESTYLE_MM: 798 default: 799 $txt = '15'; 800 break; 801 } 802 803 $mfw = $this->scale->minute->GetStrWidth($this->img,$txt)+6; 804 $n = ceil(60 / $this->scale->TimeToMinutes($this->scale->minute->GetIntervall()) ); 805 $mw = $n * $mfw; 806 $fw = $fw < $mw ? $mw : $fw ; 807 } 808 809 // If we display week we must make sure that 7*$fw is enough 810 // to fit up to 10 characters of the week font (if the week is enabled) 811 if( $this->scale->IsDisplayWeek() ) { 812 // Depending on what format the user has choose we need different amount 813 // of space 814 $fsw = strlen($this->scale->week->iLabelFormStr); 815 if( $this->scale->week->iStyle==WEEKSTYLE_FIRSTDAY2WNBR ) { 816 $fsw += 8; 817 } 818 elseif( $this->scale->week->iStyle==WEEKSTYLE_FIRSTDAYWNBR ) { 819 $fsw += 7; 820 } 821 else { 822 $fsw += 4; 823 } 824 825 $ww = $fsw*$this->scale->week->GetFontWidth($this->img); 826 if( 7*$fw < $ww ) { 827 $fw = ceil($ww/7); 828 } 829 } 830 831 if( !$this->scale->IsDisplayDay() && !$this->scale->IsDisplayHour() && 832 !( ($this->scale->week->iStyle==WEEKSTYLE_FIRSTDAYWNBR || 833 $this->scale->week->iStyle==WEEKSTYLE_FIRSTDAY2WNBR) && $this->scale->IsDisplayWeek() ) ) { 834 // If we don't display the individual days we can shrink the 835 // scale a little bit. This is a little bit pragmatic at the 836 // moment and should be re-written to take into account 837 // a) What scales exactly are shown and 838 // b) what format do they use so we know how wide we need to 839 // make each scale text space at minimum. 840 $fw /= 2; 841 if( !$this->scale->IsDisplayWeek() ) { 842 $fw /= 1.8; 843 } 844 } 845 846 $cw = $this->GetMaxActInfoColWidth() ; 847 $this->scale->actinfo->SetMinColWidth($cw); 848 if( $this->img->width <= 0 ) { 849 // Now determine the width for the activity titles column 850 851 // Firdst find out the maximum width of each object column 852 $titlewidth = max(max($this->GetMaxLabelWidth(), 853 $this->scale->tableTitle->GetWidth($this->img)), 854 $this->scale->actinfo->GetWidth($this->img)); 855 856 // Add the width of the vertivcal divider line 857 $titlewidth += $this->scale->divider->iWeight*2; 858 859 860 // Now get the total width taking 861 // titlewidth, left and rigt margin, dayfont size 862 // into account 863 $width = $titlewidth + $nd*$fw + $lm+$rm; 864 } 865 else { 866 $width = $this->img->width; 867 } 868 869 $width = round($width); 870 $height = round($height); 871 // Make a sanity check on image size 872 if( $width > MAX_GANTTIMG_SIZE_W || $height > MAX_GANTTIMG_SIZE_H ) { 873 JpgraphError::RaiseL(6007,$width,$height); 874 //("Sanity check for automatic Gantt chart size failed. Either the width (=$width) or height (=$height) is larger than MAX_GANTTIMG_SIZE. This could potentially be caused by a wrong date in one of the activities."); 875 } 876 $this->img->CreateImgCanvas($width,$height); 877 $this->img->SetMargin($lm,$rm,$tm,$bm); 878 } 755 break; 756 case DAYSTYLE_SHORTDATE2 : 757 $txt = "23 Jun"; 758 break; 759 case DAYSTYLE_SHORTDATE3 : 760 $txt = "Mon 23"; 761 break; 762 case DAYSTYLE_SHORTDATE4 : 763 $txt = "88"; 764 break; 765 case DAYSTYLE_CUSTOM : 766 $txt = date($this->scale->day->iLabelFormStr,strtotime('2003-12-20 18:00')); 767 break; 768 case DAYSTYLE_ONELETTER : 769 default: 770 $txt = "M"; 771 break; 772 } 773 $fw = $this->scale->day->GetStrWidth($this->img,$txt)+6; 774 } 775 776 // If we have hours enabled we must make sure that each day has enough 777 // space to fit the number of hours to be displayed. 778 if( $this->scale->IsDisplayHour() ) { 779 // Depending on what format the user has choose we need different amount 780 // of space. We therefore create a typical string for the choosen format 781 // and determine the length of that string. 782 switch( $this->scale->hour->iStyle ) { 783 case HOURSTYLE_HMAMPM: 784 $txt = '12:00pm'; 785 break; 786 case HOURSTYLE_H24: 787 // 13 788 $txt = '24'; 789 break; 790 case HOURSTYLE_HAMPM: 791 $txt = '12pm'; 792 break; 793 case HOURSTYLE_CUSTOM: 794 $txt = date($this->scale->hour->iLabelFormStr,strtotime('2003-12-20 18:00')); 795 break; 796 case HOURSTYLE_HM24: 797 default: 798 $txt = '24:00'; 799 break; 800 } 801 802 $hfw = $this->scale->hour->GetStrWidth($this->img,$txt)+6; 803 $mw = $hfw; 804 if( $this->scale->IsDisplayMinute() ) { 805 // Depending on what format the user has choose we need different amount 806 // of space. We therefore create a typical string for the choosen format 807 // and determine the length of that string. 808 switch( $this->scale->minute->iStyle ) { 809 case HOURSTYLE_CUSTOM: 810 $txt2 = date($this->scale->minute->iLabelFormStr,strtotime('2005-05-15 18:55')); 811 break; 812 case MINUTESTYLE_MM: 813 default: 814 $txt2 = '15'; 815 break; 816 } 817 818 $mfw = $this->scale->minute->GetStrWidth($this->img,$txt2)+6; 819 $n2 = ceil(60 / $this->scale->minute->GetIntervall() ); 820 $mw = $n2 * $mfw; 821 } 822 $hfw = $hfw < $mw ? $mw : $hfw ; 823 $n = ceil(24*60 / $this->scale->TimeToMinutes($this->scale->hour->GetIntervall()) ); 824 $hw = $n * $hfw; 825 $fw = $fw < $hw ? $hw : $fw ; 826 } 827 828 // We need to repeat this code block here as well. 829 // THIS iS NOT A MISTAKE ! 830 // We really need it since we need to adjust for minutes both in the case 831 // where hour scale is shown and when it is not shown. 832 833 if( $this->scale->IsDisplayMinute() ) { 834 // Depending on what format the user has choose we need different amount 835 // of space. We therefore create a typical string for the choosen format 836 // and determine the length of that string. 837 switch( $this->scale->minute->iStyle ) { 838 case HOURSTYLE_CUSTOM: 839 $txt = date($this->scale->minute->iLabelFormStr,strtotime('2005-05-15 18:55')); 840 break; 841 case MINUTESTYLE_MM: 842 default: 843 $txt = '15'; 844 break; 845 } 846 847 $mfw = $this->scale->minute->GetStrWidth($this->img,$txt)+6; 848 $n = ceil(60 / $this->scale->TimeToMinutes($this->scale->minute->GetIntervall()) ); 849 $mw = $n * $mfw; 850 $fw = $fw < $mw ? $mw : $fw ; 851 } 852 853 // If we display week we must make sure that 7*$fw is enough 854 // to fit up to 10 characters of the week font (if the week is enabled) 855 if( $this->scale->IsDisplayWeek() ) { 856 // Depending on what format the user has choose we need different amount 857 // of space 858 $fsw = strlen($this->scale->week->iLabelFormStr); 859 if( $this->scale->week->iStyle==WEEKSTYLE_FIRSTDAY2WNBR ) { 860 $fsw += 8; 861 } 862 elseif( $this->scale->week->iStyle==WEEKSTYLE_FIRSTDAYWNBR ) { 863 $fsw += 7; 864 } 865 else { 866 $fsw += 4; 867 } 868 869 $ww = $fsw*$this->scale->week->GetFontWidth($this->img); 870 if( 7*$fw < $ww ) { 871 $fw = ceil($ww/7); 872 } 873 } 874 875 if( !$this->scale->IsDisplayDay() && !$this->scale->IsDisplayHour() && 876 !( ($this->scale->week->iStyle==WEEKSTYLE_FIRSTDAYWNBR || 877 $this->scale->week->iStyle==WEEKSTYLE_FIRSTDAY2WNBR) && $this->scale->IsDisplayWeek() ) ) { 878 // If we don't display the individual days we can shrink the 879 // scale a little bit. This is a little bit pragmatic at the 880 // moment and should be re-written to take into account 881 // a) What scales exactly are shown and 882 // b) what format do they use so we know how wide we need to 883 // make each scale text space at minimum. 884 $fw /= 2; 885 if( !$this->scale->IsDisplayWeek() ) { 886 $fw /= 1.8; 887 } 888 } 889 890 $cw = $this->GetMaxActInfoColWidth() ; 891 $this->scale->actinfo->SetMinColWidth($cw); 892 if( $this->img->width <= 0 ) { 893 // Now determine the width for the activity titles column 894 895 // Firdst find out the maximum width of each object column 896 $titlewidth = max(max($this->GetMaxLabelWidth(), 897 $this->scale->tableTitle->GetWidth($this->img)), 898 $this->scale->actinfo->GetWidth($this->img)); 899 900 // Add the width of the vertivcal divider line 901 $titlewidth += $this->scale->divider->iWeight*2; 902 903 // Adjust the width by the user specified zoom factor 904 $fw *= $this->iZoomFactor; 905 906 // Now get the total width taking 907 // titlewidth, left and rigt margin, dayfont size 908 // into account 909 $width = $titlewidth + $nd*$fw + $lm+$rm; 910 } 911 else { 912 $width = $this->img->width; 913 } 914 915 $width = round($width); 916 $height = round($height); 917 // Make a sanity check on image size 918 if( $width > MAX_GANTTIMG_SIZE_W || $height > MAX_GANTTIMG_SIZE_H ) { 919 JpgraphError::RaiseL(6007,$width,$height); 920 //("Sanity check for automatic Gantt chart size failed. Either the width (=$width) or height (=$height) is larger than MAX_GANTTIMG_SIZE. This could potentially be caused by a wrong date in one of the activities."); 921 } 922 $this->img->CreateImgCanvas($width,$height); 923 $this->img->SetMargin($lm,$rm,$tm,$bm); 924 } 879 925 } 880 926 … … 884 930 // must walk through all the objects, sigh... 885 931 function GetMaxActInfoColWidth() { 886 887 888 889 890 891 892 893 894 895 if( empty($w[$j]) ) 896 897 else 898 899 900 901 932 $n = count($this->iObj); 933 if( $n == 0 ) return; 934 $w = array(); 935 $m = $this->scale->actinfo->iLeftColMargin + $this->scale->actinfo->iRightColMargin; 936 937 for( $i=0; $i < $n; ++$i ) { 938 $tmp = $this->iObj[$i]->title->GetColWidth($this->img,$m); 939 $nn = count($tmp); 940 for( $j=0; $j < $nn; ++$j ) { 941 if( empty($w[$j]) ) 942 $w[$j] = $tmp[$j]; 943 else 944 $w[$j] = max($w[$j],$tmp[$j]); 945 } 946 } 947 return $w; 902 948 } 903 949 904 950 // Stroke the gantt chart 905 function Stroke($aStrokeFileName="") { 906 907 // If the filename is the predefined value = '_csim_special_' 908 // we assume that the call to stroke only needs to do enough 909 // to correctly generate the CSIM maps. 910 // We use this variable to skip things we don't strictly need 911 // to do to generate the image map to improve performance 912 // a best we can. Therefor you will see a lot of tests !$_csim in the 913 // code below. 914 $_csim = ($aStrokeFileName===_CSIM_SPECIALFILE); 915 916 // Should we autoscale dates? 917 918 if( !$this->scale->IsRangeSet() ) { 919 list($min,$max) = $this->GetBarMinMax(); 920 $this->scale->SetRange($min,$max); 921 } 922 923 $this->scale->AdjustStartEndDay(); 924 925 // Check if we should autoscale the image 926 $this->AutoSize(); 927 928 // Should we start from the top or just spread the bars out even over the 929 // available height 930 $this->scale->SetVertLayout($this->iLayout); 931 if( $this->iLayout == GANTT_FROMTOP ) { 932 $maxheight=max($this->GetMaxLabelHeight(),$this->GetMaxBarAbsHeight()); 933 $this->scale->SetVertSpacing($maxheight*(1+$this->iLabelVMarginFactor)); 934 } 935 // If it hasn't been set find out the maximum line number 936 if( $this->scale->iVertLines == -1 ) 937 $this->scale->iVertLines = $this->GetBarMaxLineNumber()+1; 938 939 $maxwidth=max($this->scale->actinfo->GetWidth($this->img), 940 max($this->GetMaxLabelWidth(), 941 $this->scale->tableTitle->GetWidth($this->img))); 942 943 $this->scale->SetLabelWidth($maxwidth+$this->scale->divider->iWeight);//*(1+$this->iLabelHMarginFactor)); 944 945 if( !$_csim ) { 946 $this->StrokePlotArea(); 947 if( $this->iIconDepth == DEPTH_BACK ) { 948 $this->StrokeIcons(); 949 } 950 } 951 952 $this->scale->Stroke(); 953 954 if( !$_csim ) { 955 // Due to a minor off by 1 bug we need to temporarily adjust the margin 956 $this->img->right_margin--; 957 $this->StrokePlotBox(); 958 $this->img->right_margin++; 959 } 960 961 // Stroke Grid line 962 $this->hgrid->Stroke($this->img,$this->scale); 963 964 $n = count($this->iObj); 965 for($i=0; $i < $n; ++$i) { 966 //$this->iObj[$i]->SetLabelLeftMargin(round($maxwidth*$this->iLabelHMarginFactor/2)); 967 $this->iObj[$i]->Stroke($this->img,$this->scale); 968 } 969 970 $this->StrokeTitles(); 971 972 if( !$_csim ) { 973 $this->StrokeConstrains(); 974 $this->footer->Stroke($this->img); 975 976 977 if( $this->iIconDepth == DEPTH_FRONT) { 978 $this->StrokeIcons(); 979 } 980 981 // Should we do any final image transformation 982 if( $this->iImgTrans ) { 983 if( !class_exists('ImgTrans',false) ) { 984 require_once('jpgraph_imgtrans.php'); 985 } 986 987 $tform = new ImgTrans($this->img->img); 988 $this->img->img = $tform->Skew3D($this->iImgTransHorizon,$this->iImgTransSkewDist, 989 $this->iImgTransDirection,$this->iImgTransHighQ, 990 $this->iImgTransMinSize,$this->iImgTransFillColor, 991 $this->iImgTransBorder); 992 } 993 994 995 // If the filename is given as the special "__handle" 996 // then the image handler is returned and the image is NOT 997 // streamed back 998 if( $aStrokeFileName == _IMG_HANDLER ) { 999 return $this->img->img; 1000 } 1001 else { 1002 // Finally stream the generated picture 1003 $this->cache->PutAndStream($this->img,$this->cache_name,$this->inline, 1004 $aStrokeFileName); 1005 } 1006 } 951 function Stroke($aStrokeFileName="") { 952 953 // If the filename is the predefined value = '_csim_special_' 954 // we assume that the call to stroke only needs to do enough 955 // to correctly generate the CSIM maps. 956 // We use this variable to skip things we don't strictly need 957 // to do to generate the image map to improve performance 958 // a best we can. Therefor you will see a lot of tests !$_csim in the 959 // code below. 960 $_csim = ($aStrokeFileName===_CSIM_SPECIALFILE); 961 962 // Should we autoscale dates? 963 964 if( !$this->scale->IsRangeSet() ) { 965 list($min,$max) = $this->GetBarMinMax(); 966 $this->scale->SetRange($min,$max); 967 } 968 969 $this->scale->AdjustStartEndDay(); 970 971 // Check if we should autoscale the image 972 $this->AutoSize(); 973 974 // Should we start from the top or just spread the bars out even over the 975 // available height 976 $this->scale->SetVertLayout($this->iLayout); 977 if( $this->iLayout == GANTT_FROMTOP ) { 978 $maxheight=max($this->GetMaxLabelHeight(),$this->GetMaxBarAbsHeight()); 979 $this->scale->SetVertSpacing($maxheight*(1+$this->iLabelVMarginFactor)); 980 } 981 // If it hasn't been set find out the maximum line number 982 if( $this->scale->iVertLines == -1 ) 983 $this->scale->iVertLines = $this->GetBarMaxLineNumber()+1; 984 985 $maxwidth=max($this->scale->actinfo->GetWidth($this->img), 986 max($this->GetMaxLabelWidth(), 987 $this->scale->tableTitle->GetWidth($this->img))); 988 989 $this->scale->SetLabelWidth($maxwidth+$this->scale->divider->iWeight);//*(1+$this->iLabelHMarginFactor)); 990 991 if( !$_csim ) { 992 $this->StrokePlotArea(); 993 if( $this->iIconDepth == DEPTH_BACK ) { 994 $this->StrokeIcons(); 995 } 996 } 997 998 $this->scale->Stroke(); 999 1000 if( !$_csim ) { 1001 // Due to a minor off by 1 bug we need to temporarily adjust the margin 1002 $this->img->right_margin--; 1003 $this->StrokePlotBox(); 1004 $this->img->right_margin++; 1005 } 1006 1007 // Stroke Grid line 1008 $this->hgrid->Stroke($this->img,$this->scale); 1009 1010 $n = count($this->iObj); 1011 for($i=0; $i < $n; ++$i) { 1012 //$this->iObj[$i]->SetLabelLeftMargin(round($maxwidth*$this->iLabelHMarginFactor/2)); 1013 $this->iObj[$i]->Stroke($this->img,$this->scale); 1014 } 1015 1016 $this->StrokeTitles(); 1017 1018 if( !$_csim ) { 1019 $this->StrokeConstrains(); 1020 $this->footer->Stroke($this->img); 1021 1022 1023 if( $this->iIconDepth == DEPTH_FRONT) { 1024 $this->StrokeIcons(); 1025 } 1026 1027 // Stroke all added user texts 1028 $this->StrokeTexts(); 1029 1030 // Should we do any final image transformation 1031 if( $this->iImgTrans ) { 1032 if( !class_exists('ImgTrans',false) ) { 1033 require_once('jpgraph_imgtrans.php'); 1034 } 1035 1036 $tform = new ImgTrans($this->img->img); 1037 $this->img->img = $tform->Skew3D($this->iImgTransHorizon,$this->iImgTransSkewDist, 1038 $this->iImgTransDirection,$this->iImgTransHighQ, 1039 $this->iImgTransMinSize,$this->iImgTransFillColor, 1040 $this->iImgTransBorder); 1041 } 1042 1043 1044 // If the filename is given as the special "__handle" 1045 // then the image handler is returned and the image is NOT 1046 // streamed back 1047 if( $aStrokeFileName == _IMG_HANDLER ) { 1048 return $this->img->img; 1049 } 1050 else { 1051 // Finally stream the generated picture 1052 $this->cache->PutAndStream($this->img,$this->cache_name,$this->inline, 1053 $aStrokeFileName); 1054 } 1055 } 1007 1056 } 1008 1057 1009 1058 function StrokeConstrains() { 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 //('You have specifed a constrain from row='.$this->iObj[$i]->iVPos.' to row='.$vpos.' which does not have any activity.');1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 //('Unknown constrain type specified from row='.$this->iObj[$i]->iVPos.' to row='.$vpos);1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1059 $n = count($this->iObj); 1060 1061 // Stroke all constrains 1062 for($i=0; $i < $n; ++$i) { 1063 1064 // Some gantt objects may not have constraints associated with them 1065 // for example we can add IconPlots which doesn't have this property. 1066 if( empty($this->iObj[$i]->constraints) ) continue; 1067 1068 $numConstrains = count($this->iObj[$i]->constraints); 1069 1070 for( $k = 0; $k < $numConstrains; $k++ ) { 1071 $vpos = $this->iObj[$i]->constraints[$k]->iConstrainRow; 1072 if( $vpos >= 0 ) { 1073 $c1 = $this->iObj[$i]->iConstrainPos; 1074 1075 // Find out which object is on the target row 1076 $targetobj = -1; 1077 for( $j=0; $j < $n && $targetobj == -1; ++$j ) { 1078 if( $this->iObj[$j]->iVPos == $vpos ) { 1079 $targetobj = $j; 1080 } 1081 } 1082 if( $targetobj == -1 ) { 1083 JpGraphError::RaiseL(6008,$this->iObj[$i]->iVPos,$vpos); 1084 //('You have specifed a constrain from row='.$this->iObj[$i]->iVPos.' to row='.$vpos.' which does not have any activity.'); 1085 } 1086 $c2 = $this->iObj[$targetobj]->iConstrainPos; 1087 if( count($c1) == 4 && count($c2 ) == 4) { 1088 switch( $this->iObj[$i]->constraints[$k]->iConstrainType ) { 1089 case CONSTRAIN_ENDSTART: 1090 if( $c1[1] < $c2[1] ) { 1091 $link = new GanttLink($c1[2],$c1[3],$c2[0],$c2[1]); 1092 } 1093 else { 1094 $link = new GanttLink($c1[2],$c1[1],$c2[0],$c2[3]); 1095 } 1096 $link->SetPath(3); 1097 break; 1098 case CONSTRAIN_STARTEND: 1099 if( $c1[1] < $c2[1] ) { 1100 $link = new GanttLink($c1[0],$c1[3],$c2[2],$c2[1]); 1101 } 1102 else { 1103 $link = new GanttLink($c1[0],$c1[1],$c2[2],$c2[3]); 1104 } 1105 $link->SetPath(0); 1106 break; 1107 case CONSTRAIN_ENDEND: 1108 if( $c1[1] < $c2[1] ) { 1109 $link = new GanttLink($c1[2],$c1[3],$c2[2],$c2[1]); 1110 } 1111 else { 1112 $link = new GanttLink($c1[2],$c1[1],$c2[2],$c2[3]); 1113 } 1114 $link->SetPath(1); 1115 break; 1116 case CONSTRAIN_STARTSTART: 1117 if( $c1[1] < $c2[1] ) { 1118 $link = new GanttLink($c1[0],$c1[3],$c2[0],$c2[1]); 1119 } 1120 else { 1121 $link = new GanttLink($c1[0],$c1[1],$c2[0],$c2[3]); 1122 } 1123 $link->SetPath(3); 1124 break; 1125 default: 1126 JpGraphError::RaiseL(6009,$this->iObj[$i]->iVPos,$vpos); 1127 //('Unknown constrain type specified from row='.$this->iObj[$i]->iVPos.' to row='.$vpos); 1128 break; 1129 } 1130 1131 $link->SetColor($this->iObj[$i]->constraints[$k]->iConstrainColor); 1132 $link->SetArrow($this->iObj[$i]->constraints[$k]->iConstrainArrowSize, 1133 $this->iObj[$i]->constraints[$k]->iConstrainArrowType); 1134 1135 $link->Stroke($this->img); 1136 } 1137 } 1138 } 1139 } 1091 1140 } 1092 1141 1093 1142 function GetCSIMAreas() { 1094 1095 1096 1097 1098 1099 1100 1101 1102 for( $i=$n-1; $i >= 0; --$i ) 1103 1104 1143 if( !$this->iHasStroked ) 1144 $this->Stroke(_CSIM_SPECIALFILE); 1145 1146 $csim = $this->title->GetCSIMAreas(); 1147 $csim .= $this->subtitle->GetCSIMAreas(); 1148 $csim .= $this->subsubtitle->GetCSIMAreas(); 1149 1150 $n = count($this->iObj); 1151 for( $i=$n-1; $i >= 0; --$i ) 1152 $csim .= $this->iObj[$i]->GetCSIMArea(); 1153 return $csim; 1105 1154 } 1106 1155 } … … 1128 1177 1129 1178 function GetLen() { 1130 return $this->iLen ; 1179 return $this->iLen ; 1131 1180 } 1132 1181 1133 1182 function GetImg($aIdx) { 1134 1135 1136 //('Illegal icon index for Gantt builtin icon ['.$aIdx.']');1137 1138 return Image::CreateFromString(base64_decode($this->iBuiltinIcon[$aIdx][1])); 1139 } 1140 1141 function PredefIcons() {1142 1143 1144 1145 1146 $this->iBuiltinIcon[0][1]= 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 'uX1gU36dymgqYxJIJJNJT1W9QqHgNwFQBGYqo94OwHZQUuPD7ACglSvc+5n5T9m/wfJJX4U9qzEAAAAASUVORK5CYII=' ; 1161 1162 1163 1164 1165 1166 $this->iBuiltinIcon[1][1]= 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 'EOm71HUINiY7mGb95l/8jZCyQmJjMDGJjUmsdCROtZ0n/P/Z8v4Fs2MTUUf7vYoAAAAASUVORK5CYII=' ; 1180 1181 1182 1183 1184 1185 $this->iBuiltinIcon[2][1]= 1186 1187 1188 1189 1190 1191 1192 1193 1194 'avXYaXXxPwsnt0imdttCocMmZBdK7YU9D8wuNOW0nXc6QWzPsSa5naZ1beb9BbGB6dxGtMnXAAAAAElFTkSuQmCC' ; 1195 1196 1197 1198 1199 1200 $this->iBuiltinIcon[3][1]= 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 'LBbVR8feJDs0Rlv6GFKeXJ21rNRXESxMPR+CBUl0nN7PjtO+dye7Up/8v1I88bf/ixT/AO1/hZsqW+C6AAAAAElFTkSuQmCC' ; 1216 1217 1218 1219 1220 1221 $this->iBuiltinIcon[4][1]= 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 'EVgKVsutKPl0TGWGhwofoquaoKK4apsq/tH/e/kFwBMXLgAEKK4AAAAASUVORK5CYII=' ; 1232 1233 1234 1235 1236 1237 $this->iBuiltinIcon[5][1]= 1238 1239 1240 1241 1242 1243 1244 1245 'rABG1EL/BilZP8DjU2uR4U+2E49P1Z8QJmNXUzl24A9GBT0IruCfi86d9x+D12RGzt+pNAAAAABJRU5ErkJggg==' ; 1246 1247 1248 1249 1250 1251 $this->iBuiltinIcon[6][1]= 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 'p/TXyYkTJ0Xe59jf7QOyAKDWp/QXxcFQ61P4pT3ShBBcvnUHIQTjxmX19/8BCeVg+/GPpskAAAAASUVORK5CYII=' ; 1271 1272 1273 1274 1275 1276 $this->iBuiltinIcon[7][1]= 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 'opHP7/Do90Ua+WWUyezzZHObP/7cfX54/dowE1d66s8TV3oE+Mfn+L/zb4XmHPjRG9YjAAAAAElFTkSuQmCC' ; 1290 1291 1292 1293 1294 1295 $this->iBuiltinIcon[8][1]= 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 'LbQVOIcP+HG2UauH3xgwBqOz9Cc3l1tC24Fz+MvUDroeGNb5if9H/1dM/wLPCYMw9fryKgAAAABJRU5ErkJggg==' ; 1308 1309 1310 1311 1312 1313 $this->iBuiltinIcon[9][1]= 1314 1315 1316 1317 1318 1319 1320 1321 'iOsCHgAAAABJRU5ErkJggg==' ; 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1183 if( $aIdx < 0 || $aIdx >= $this->iLen ) { 1184 JpGraphError::RaiseL(6010,$aIdx); 1185 //('Illegal icon index for Gantt builtin icon ['.$aIdx.']'); 1186 } 1187 return Image::CreateFromString(base64_decode($this->iBuiltinIcon[$aIdx][1])); 1188 } 1189 1190 function __construct() { 1191 //========================================================== 1192 // warning.png 1193 //========================================================== 1194 $this->iBuiltinIcon[0][0]= 1043 ; 1195 $this->iBuiltinIcon[0][1]= 1196 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsSAAALEgHS3X78AAAA'. 1197 'B3RJTUUH0wgKFSgilWPhUQAAA6BJREFUeNrtl91rHFUYh5/3zMx+Z5JNUoOamCZNaqTZ6IWIkqRiQWmi1IDetHfeiCiltgXBP8AL'. 1198 '0SIUxf/AvfRSBS9EKILFFqyIH9CEmFZtPqrBJLs7c+b1YneT3WTTbNsUFPLCcAbmzPt73o9zzgzs2Z793231UOdv3w9k9Z2uzOdA'. 1199 '5+2+79yNeL7Hl7hw7oeixRMZ6PJM26W18DNAm/Vh7lR8fqh97NmMF11es1iFpMATqdirwMNA/J4DpIzkr5YsAF1PO6gIMYHRdPwl'. 1200 'oO2elmB+qH3sm7XozbkgYvy8SzYnZPtcblyM6I+5z3jQ+0vJfgpEu56BfI9vUkbyi2HZd1QJoeWRiAjBd4SDCW8SSAOy6wBHMzF7'. 1201 'YdV2A+ROuvRPLfHoiSU0EMY/cDAIhxJeGngKaN1VgHyPL7NBxI1K9P4QxBzw3K1zJ/zkG8B9uwaQ7/HNsRZv9kohBGD0o7JqMYS/'. 1202 '/ynPidQw/LrBiPBcS/yFCT95DvB2BWAy4575PaQbQKW+tPd3GCItu2odKI++YxiKu0d26oWmAD7paZU/rLz37VqIijD2YbnzNBBE'. 1203 'IBHf8K8qjL7vYhCGErEU8CTg3xXAeMp96GrJEqkyXkm9Bhui1xfsunjdGhcYLq+IzjsGmBt5YH/cmJkFq6gIqlon3u4LxdKGuCIo'. 1204 'Qu41g0E41po+2R33Xt5uz9kRIB2UTle7PnfKrROP1HD4sRjZlq0lzhwoZ6rDNeTi3nEg1si/7FT7kYQbXS6E5E65tA5uRF9tutq0'. 1205 'K/VwAF+/FbIYWt6+tjQM/AqUms7A4Wy6d7YSfSNxgMmzi0ycWWworio4QJvj4LpuL5BqugTnXzzqJsJwurrlNhJXFaavW67NRw3F'. 1206 'q+aJcCQVe9fzvJGmAY7/dPH0gi0f64OveGxa+usCuQMeZ0+kt8BVrX+qPO9Bzx0MgqBvs+a2PfDdYIf+WAjXU1ub4tqNaPPzRs8A'. 1207 'blrli+WVn79cXn0cWKl+tGx7HLc7pu3CSmnfitL+l1UihAhwjFkPQev4K/fSABjBM8JCaFuurJU+rgW41SroA8aNMVNAFtgHJCsn'. 1208 'XGy/58QVxAC9MccJtZ5kIzNlW440WrJ2ea4YPA9cAooA7i0A/gS+iqLoOpB1HOegqrYB3UBmJrAtQAJwpwPr1Ry92wVlgZsiYlW1'. 1209 'uX1gU36dymgqYxJIJJNJT1W9QqHgNwFQBGYqo94OwHZQUuPD7ACglSvc+5n5T9m/wfJJX4U9qzEAAAAASUVORK5CYII=' ; 1210 1211 //========================================================== 1212 // edit.png 1213 //========================================================== 1214 $this->iBuiltinIcon[1][0]= 959 ; 1215 $this->iBuiltinIcon[1][1]= 1216 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAFgAWABY9j+ZuwAAAAlwSFlz'. 1217 'AAALEAAACxABrSO9dQAAAAd0SU1FB9AKDAwbIEXOA6AAAAM8SURBVHicpdRPaBxlHMbx76ZvsmOTmm1dsEqQSIIsEmGVBAQjivEQ'. 1218 'PAUJngpWsAWlBw8egpQepKwplN4ULEG9CjkEyUFKlSJrWTG0IU51pCsdYW2ncUPjdtp9Z+f3vuNhu8nKbmhaf5cZeGc+PO8zf1Lc'. 1219 'm0KhkACICCKCMeaBjiLC0tLSnjNvPmuOHRpH0TZTU1M8zBi9wakzn7OFTs5sw8YYACYmJrre7HkeuVyu69qPF77hlT1XmZ0eQ03O'. 1220 'wOLJTvhBx1rLz18VmJ0eY+jVd2FxDkKXnvYLHgb97OgLzE4ON9Hzc1B1QaQzsed5O0Lta3Ec89OnR5h5McfQ+Mw2qgQUnfBOPbZ3'. 1221 'bK3l+xOvMT0+3ERLp5FNF6UEjcL32+DdVmGt5WLhDYYPZrbRqreFumXwql0S3w9tnDvLWD5PZigPpdOwuYpSCo3C8wU3UHxQdHbf'. 1222 'cZIkNM6dxcnlUM4k1eUFMlUPpUADbpkttFarHe6oYqeOr6yt4RzMQHYUcUsQVtGicHDwKprViuLDkkOtVnsHCHZVRVy/zcj1i5Af'. 1223 'h8AjdIts+hUcGcYPK3iBtKM3gD/uAzf/AdY2mmmVgy6X8YNNKmGIvyloPcB8SUin07RQ4EZHFdsdG0wkJEnEaHAJxvKEpSLeaokV'. 1224 'r4zWmhUZYLlY4b1D03y5eIEWCtS7vsciAgiIxkQRabWOrlQor66y4pUphoJb1jiO4uO5o0S3q6RSqVbiOmC7VCEgAhLSaDQ48dH7'. 1225 'vD46REY0iysegSjKQciRt99ib7qXwX0O+pG4teM6YKHLB9JMq4mTmF9/+AKA4wvLZByH7OgYL7+UY2qvw/7Bfg5kHiXjJFyv3CGO'. 1226 'Y1rof+BW4t/XLiPG0DCGr79d4XzRxRnIMn98huXSTYyJ6et1UNYQhRvcinpJq86H3wGPPPM0iBDd+QffD1g4eZjLvuG7S1Wef26E'. 1227 'J7L7eSx7gAHVg7V3MSbi6m/r93baBd6qQjerAJg/9Ql/XrvG0ON1+vv7GH3qSfY5fahUnSTpwZgIEQesaVXRPbHRG/xyJSAxMYlp'. 1228 'EOm71HUINiY7mGb95l/8jZCyQmJjMDGJjUmsdCROtZ0n/P/Z8v4Fs2MTUUf7vYoAAAAASUVORK5CYII=' ; 1229 1230 //========================================================== 1231 // endconstrain.png 1232 //========================================================== 1233 $this->iBuiltinIcon[2][0]= 666 ; 1234 $this->iBuiltinIcon[2][1]= 1235 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlz'. 1236 'AAALDwAACw8BkvkDpQAAAAd0SU1FB9ALEREILkh0+eQAAAIXSURBVHictZU9aFNRFMd/N81HX77aptJUWmp1LHRpIcWhg5sIDlUQ'. 1237 'LAXB4t7RRUpwEhy7iQ46CCIoSHcl0CFaoVARU2MFMYktadLXJNok7x2HtCExvuYFmnO4w/3gx+Gc/z1HKRTdMEdXqHbB/sgc/sic'. 1238 'nDoYAI8XwDa8o1RMLT+2hAsigtTvbIGVqhX46szUifBGswUeCPgAGB7QeLk0X4Ork+HOxo1VgSqGASjMqkn8W4r4vVtEgI/RRQEL'. 1239 'vaoGD85cl5V3nySR/S1mxWxab7f35PnntNyMJeRr9kCMqiHTy09EoeToLwggx6ymiMOD/VwcD7Oa/MHkcIiQx026WGYto5P/U+ZZ'. 1240 '7gD0QwDuT5z9N3LrVPi0Xs543eQPKkRzaS54eviJIp4tMFQFMllAWN2qcRZHBnixNM8NYD162xq8u7ePSQ+GX2Pjwxc2dB2cLtB8'. 1241 '7GgamCb0anBYBeChMtl8855CarclxU1gvViiUK4w2OMkNDnGeJ8bt9fH90yOnOkCwLFTwhzykhvtYzOWoBBbY//R3dbaNTYhf2RO'. 1242 'QpeuUMzv188MlwuHy0H13HnE48UzMcL0WAtUHX8OxZHoG1URiFw7rnLLCswuSPD1ulze/iWjT2PSf+dBXRFtVVGIvzqph0pQL7VE'. 1243 'avXYaXXxPwsnt0imdttCocMmZBdK7YU9D8wuNOW0nXc6QWzPsSa5naZ1beb9BbGB6dxGtMnXAAAAAElFTkSuQmCC' ; 1244 1245 //========================================================== 1246 // mail.png 1247 //========================================================== 1248 $this->iBuiltinIcon[3][0]= 1122 ; 1249 $this->iBuiltinIcon[3][1]= 1250 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlz'. 1251 'AAALEAAACxABrSO9dQAAAAd0SU1FB9AJHAMfFvL9OU8AAAPfSURBVHictZRdaBRXFMd/987H7tbNx8aYtGCrEexDsOBDaKHFxirb'. 1252 'h0qhsiY0ykppKq1osI99C4H2WSiFFMHWUhXBrjRi0uCmtSEUGgP1QWqhWjGkoW7M1kTX3WRn5p4+TJJNGolQ6IXDnDtz+N0z/3PP'. 1253 'UWBIpdpYa23b9g09PZ2kUrOrvmUyGVKp1Ao/mUyi56YnVgWfO/P1CihAd/dJMpmaNROIRq8BkM1m0bH6TasC3j6QXgFdXI+DR6PR'. 1254 'JX/Pno8B+KLnMKqlpUU8z8MYs2RBEDzWf9J+0RcRbMdxGBsbw/fmCXwPMUEYID4iAVp8wIRmDIHMo4yHSIBSASKC+CWE0C/PF9jU'. 1255 '3B6Cp+4M07C5FUtKGNvGwQJctPgIsgD2wRhEIqAMGB+UQYkHJgYYZD7P1HwVlmWhHcfhyk83KeRGUW4t6CgoG5SNUS4KBWgQDUov'. 1256 '7AGlwYASBVqH0Bk49dXpCviVV3dw/tI1Bvr7kMIIlh0NYUpjlF0BAYvcxSXmEVLKceHSCJm+PnbueBHbtkNwTXUNBzo6aGpq4sSZ'. 1257 'GwT5H7BsF6Wdf1GWHQAoM0upeI9PT1yioS7B7tdaSdSuw7KsUGMAy7HYsmUztTW1nMwM0txssX1rlHjjS5jy/Uq2YkK/eJuLl6/z'. 1258 'x+1xkslW6mrixGIODx8EFSlEBC0+tmXT0NhA2763iEUjnLv4C8XpUbSbAB1mKkGJ3J83Od77HW5EszvZSqK2iljMIeJaRGNuJePF'. 1259 '6mspY7BJ1DXwQnCd2fxGRq5OUCz8xt72dyhMZcn++Cu3xu9SKhdp2b4ZHWnAtTSxmIWlhcIjlksR3lNBYzlxZsb7+f7ne+xtSzOd'. 1260 'u83szH1OnThOPp/n+a0beeP1l4mvq+PU2Qyd+5PY1RuwlAqLYFaBfbTbyPSdfgaH77A//QF4f1O/vpr6RJyq+C5Kc/M8FbFxXItY'. 1261 'xOHDrvfo/fxLDnbsJBp5BowBReVWYAzabeTh5ABDw7cWoNNL3YYYNtSv57lnn6Z+Qx01VeuIuBa2DV1HD3H63BAPZu4u1WGpeLHq'. 1262 'Rh7+NcjA0O+0p4+CNwXigwnbWlQQdpuEpli+n+PIkcOc//YKuckJJFh2K2anrjFw+QZt6S6kPImIF/b+cqAJD1LihWAxC61twBTo'. 1263 'fPcQF/oGsVW5ovHQlavs2/8+uYnRVSOUgHAmmAClBIOBwKC0gPjhIRgEIX2wg7NnwpZW3d3d4vs+vu8TBMGK51rvPM9b8hdteZxd'. 1264 'LBbVR8feJDs0Rlv6GFKeXJ21rNRXESxMPR+CBUl0nN7PjtO+dye7Up/8v1I88bf/ixT/AO1/hZsqW+C6AAAAAElFTkSuQmCC' ; 1265 1266 //========================================================== 1267 // startconstrain.png 1268 //========================================================== 1269 $this->iBuiltinIcon[4][0]= 725 ; 1270 $this->iBuiltinIcon[4][1]= 1271 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlz'. 1272 'AAALDgAACw4BQL7hQQAAAAd0SU1FB9ALEREICJp5fBkAAAJSSURBVHic3dS9a1NRGMfx77kxtS+xqS9FG6p1ER3qVJpBQUUc3CRU'. 1273 'BwURVLB1EAuKIP0THJQiiNRJBK3iJl18AyeltRZa0bbaJMbUNmlNSm5e7s25j0NqpSSmyag/OMM9POdzDuflwn8djz8gClVRrVEV'. 1274 'ur4Bl1FTNSzLrSS6vbml0jUUwSXj8Qfk3PkLtLW2AeBIybmrgz3+gFzpucjlE4f4btuFTuWuCF5XDr3a3UPf6cM8GQvxzbsRAJdh'. 1275 'ScfxSywml5j7mVypN0eGEJ0tebIre+zxB6Tv7jPReS2hREpOvpmUXU+H5eC913JnNCSRVE60pUVbWoZjprR39Yq70bdqj4pW7PEH'. 1276 '5FpvL9e79jOTTHM7ssDL6CJZ08LbvAGnrpZg2mI2Z/MlZfN8IkxuSwu4V9+WIrj7zFlOHfXzKrLIi2SGh5ECKjnNVNxkQEc55vOw'. 1277 'rb6O8JLFdHyJ+ayFElUeHvjwkfteL/V7fKTSkFvIQE4DoLI2Mz/muTkTApcBKIwaN8pwIUrKw+ajWwDknAO0d/r4zFaMuRS63sWm'. 1278 'RoOdm+vRIriUYjKexrQV+t1o0YEVwfZSVJmD/dIABJuO0LG3lRFx0GOfiAELE9OgCrfU0XnIp5FwGLEy5WEAOxlR5uN+ARhP7GN3'. 1279 '5w7Gv4bQI2+xpt4jjv2nWBmIlcExE2vDAHYioszBZXw6CPE4ADoWVHmd/tuwlZR9eXYyoszBfpiNQqaAOU5+TXRN+DeeenADPT9b'. 1280 'EVgKVsutKPl0TGWGhwofoquaoKK4apsq/tH/e/kFwBMXLgAEKK4AAAAASUVORK5CYII=' ; 1281 1282 //========================================================== 1283 // calc.png 1284 //========================================================== 1285 $this->iBuiltinIcon[5][0]= 589 ; 1286 $this->iBuiltinIcon[5][1]= 1287 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAA4AIwBbgMF12wAAAAlwSFlz'. 1288 'AAALEQAACxEBf2RfkQAAAAd0SU1FB9AHBxQeFsqn0wQAAAHKSURBVHicnZWff+RAGIef3U/gcOEgUAgUCgcLhYXCwsHBQeGgUDgs'. 1289 'FgMHB4VA/4Bg4XChWFgIFIqBwkJhsRAYeOGF+TQHmWSTTbKd9pU37/x45jvfTDITXEynAbdWKVQB0NazcVm0alcL4rJaRVzm+w/e'. 1290 '3iwAkzbYRcnnYgI04GCvsxxSPabYaEdt2Ra6D0atcvvvDmyrMWBX1zPq2ircP/Tk98DiJtjV/fim6ziOCL6dDHZNhxQ3arIMsox4'. 1291 'vejleL2Ay9+jaw6A+4OSICG2cacGKhsGxg+CxeqAQS0Y7BYJvowq7iGMOhXHEfzpvpQkA9bLKgOgWKt+4Lo1mM9hs9m17QNsJ70P'. 1292 'Fjc/O52joogoX8MZKiBiAFxd9Z1vcj9wfSpUlDRNMcYQxzFpmnJ0FPH8nDe1MQaWSz9woQpWSZKEojDkeaWoKAyr1tlu+s48wfVx'. 1293 'u7n5i7jthmGIiEGcT+36PP+gFeJrxWLhb0UA/lb4ggGs1T0rZs0zwM/ZjNfilcIY5tutPxgOW3F6dUX464LrKILLiw+A7WErrl+2'. 1294 'rABG1EL/BilZP8DjU2uR4U+2E49P1Z8QJmNXUzl24A9GBT0IruCfi86d9x+D12RGzt+pNAAAAABJRU5ErkJggg==' ; 1295 1296 //========================================================== 1297 // mag.png 1298 //========================================================== 1299 $this->iBuiltinIcon[6][0]= 1415 ; 1300 $this->iBuiltinIcon[6][1]= 1301 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlz'. 1302 'AAALDAAACwwBP0AiyAAAAAd0SU1FB9ALDxEWDY6Ul+UAAAUESURBVHicdZVrbFRFGIafsyyF0nalV1R6WiggaAptlzsr1OgEogmC'. 1303 '0IgoBAsBgkIrBAPEhBj/AP6xRTCUFEwRI4jcgsitXMrFCJptJWvBNpXYbbXtbtttt6e7e86ec/yxadlCfZPJZDIz73zzzjfvR2VL'. 1304 'F7U+hf0HD2JduIzTFy6SlJRkPtkcDgdCCE65OxFC8NPV6wghyM7OptankJ2dzbSC5QghEEIgCSHog9PpNAF27dlN6miZuPgElB4/'. 1305 'nmY3O7ZtByA1NVUCkGWZweD1eklJScESTbqxuIjrd+/x6uIl5M19hSy7nfGOeUxf+g7VjU1sKi7C4/GYsiyz7tAJAD4/cRaA1tZW'. 1306 'AHIPnECUVGD1+/3U19ebG4uLeHf1akamjsIwoVnVCOvQEdLoVILYYmMo3PIxSBJflpSaDX5FAmju1QAYv/8k/s8+wLVxOU0jR2LZ'. 1307 '8sMFAApWrCApbRRDrRZirBYSLBKaoRPQw3SFernf2sav7T0Ubt4KwL4FMwF4Vu8FoHBCKgCzDhwHwLIhZ7y5a89u4m2JhA0wTdDC'. 1308 'OrphEjJMNElCHxKDEjaobmvlfo/Krj27CQQCJsCGJW8C0KXqAMxMiosQA8hZWcTFx9OsaniDKh1qmG7VoFsL0x0K06kbeAMhWpRe'. 1309 '/KpG+gwHAKUnz7Dz3BUMw6DK18nuw99wt0Nh6VdHI8RJicmETQgFg7SFwjSrGv+oKp6ghldV6dZ0ugJBlF6FmCESQ2w2AIqXLsan'. 1310 'BrFYLJTnTCBrdBqveeopWZiPFaBHUegJhegMqGgxEkHDwB/UaQ9rdIV06v0+TD2EEQjQFtAY0dsNgNvt5sialQAIIXh7wQKuVf6J'. 1311 'gTsSccPDWlQstClBGjr9eHpVWvUQncEwdYEedF8noQ4vmYmpZMTH0nTvDn25vLbrNmu7bvfnsYEbAMnhcPDgwQPzUo2LJusw/mhp'. 1312 'QwlHNO0KBAnoIfxtrcQMT2De1Mm891wyUzNlUlJSpIyMDBobGzlzr5rFM/Koq6vrP8ASGxsLwPmKcvIShjPGZiPOakE3VFB8hHwd'. 1313 'vJAxhrk5L7Ly+RQuH/sWgPdXrwFg/6HDFBUsIj09nehfbAWwPWOT9n5RYhqGwarNWxkRM5TRCfF4U1PQsDDJFk9uYhwXvzvKjm3b'. 1314 'KSsro3DJInNW5RXp7u2bAKSlpeH1esnPz6eqqgqLpmmcr3Fht9ulfaV7mZk1Bs+lM6T1djM9fhg5egDPpTNMy5TZsW07kydPYdWM'. 1315 'aXx96ixOp9O8cfUa80srmDpjOgAulytiQqZpMnvObLbt/JTtHxXj9/tRVdU0DGOAufRpevPDTeac0hJyc3NxOOawfv161lVWS6eX'. 1316 'z+9/UOCxu1VWVvaTRGv16NFfjB2bNeAQp9NpTpmSM4DcbrdL0WsGDKLRR+52uwe1yP8jb2lpYfikyY9t80n03UCWZeaXVjw1f+zs'. 1317 'Oen+/d+pqanhzp2fKSsrw+l0mi6XiyPl5ZGITdN8fAVJwjRNJEmi1qfw1kw7siyTnJxMe3s71dXV3GpoZO64DG41NPJylvxU5D/e'. 1318 'qJKsfWQD9IkaZ2RmUvr9aV4aGYcQgjfO3aWoYBF5eXm4ewIsu/CbdPz1aWb0/p1bNoOrQxlUiuiaFo3c3FyEEOx9+C9CCD6paaTW'. 1319 'p/TXyYkTJ0Xe59jf7QOyAKDWp/QXxcFQ61P4pT3ShBBcvnUHIQTjxmX19/8BCeVg+/GPpskAAAAASUVORK5CYII=' ; 1320 1321 //========================================================== 1322 // lock.png 1323 //========================================================== 1324 $this->iBuiltinIcon[7][0]= 963 ; 1325 $this->iBuiltinIcon[7][1]= 1326 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlz'. 1327 'AAALCwAACwsBbQSEtwAAAAd0SU1FB9AKAw0XDmwMOwIAAANASURBVHic7ZXfS1t3GMY/3+PprI7aisvo2YU6h6ATA8JW4rrlsF4U'. 1328 'qiAsF9mhl0N2cYTRy9G/wptAYWPD9iJtRy5asDe7cYFmyjaXOLaMImOrmkRrjL9yTmIS3120JybWQgfb3R74wuc8Lzw858vLOUpE'. 1329 'OK6pqSm2trbY39+nu7tbPHYch7m5OcLhMIA67kWj0aMQEWk6tm17rNm2LSIie3t7ksvlJJ1OSyqVkls3Z8SyLMnlcqTTaVKpFLdu'. 1330 'zmBZVj1HeY2VUti2TSQSQSml2bZdi0QirK2tMT09zerqKtlslqGhISYnJ4nHv2N+foFsNquOe9FotLlxOBwmk8lgWRbhcFgymYxY'. 1331 'liUi0mqaJoAuIi2macrdO7fFsizx3to0Te7euV1vrXtXEgqFmJmZYWVlhXK5LB4/U9kwDL784kYV0A3DYHd3m4sXRymXywKoRi8U'. 1332 'Ch01DgQCJBIJLMsiEAhIIpHw2uLz+eqtYrEYIqKZpimxWEyCwaCMjY01zYPBIJpXqVQqsby8TLVabWKA/v5+RkZGMAyDrq4ulFKH'. 1333 'HsfjcWZnZ+ns7KTRqwcnk0mKxSKFQqGJlVKtruuSTCYB6O3trW9UI/v9/iZPB/j8s2HOnX0FgHfeXpeffnzK+fWf+fijvhLs0PtG'. 1334 'D/n1OJ9+MsrlSwb3733DwMCAt1EyPj6uACYmJp56168NU6nUqFSE9nZdPE7+WqC/r4NKTagcCJVqDaUUB5VDAA4Pa9x7sMLlSwan'. 1335 'WjRmv13D7/erpaWlo604qOp88OF7LC48rPNosMq5Th+Dgxd4/XyA1rbzADi7j8jnf2P++wdcvSr8MJ/i8eomAKlUqn41OsDAQDeD'. 1336 'g++yuPCwzm/2vU8+n2a7sMFfj79mp7BBuVzioFSiXHJx3SKuW2Rzy0Up9dxnQVvODALQerqNRn4ZKe0Mvtc6TpzpmqbxalcY9Ato'. 1337 '2v06t515C73YQftZB9GLnDrt4LoujuPgOA4Ui+C6yOpXJwZrJ7r/gv4P/u+D9W7fLxTz+1ScQxrZ3atRLaVxdjbY2d184R6/sLHe'. 1338 'opHP7/Do90Ua+WWUyezzZHObP/7cfX54/dowE1d66s8TV3oE+Mfn+L/zb4XmHPjRG9YjAAAAAElFTkSuQmCC' ; 1339 1340 //========================================================== 1341 // stop.png 1342 //========================================================== 1343 $this->iBuiltinIcon[8][0]= 889 ; 1344 $this->iBuiltinIcon[8][1]= 1345 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlz'. 1346 'AAALDwAACw8BkvkDpQAAAAd0SU1FB9AJDwEvNyD6M/0AAAL2SURBVHic1ZTLaxVnGIefb2bO5OScHJN4oWrFNqcUJYoUEgU3/Qf6'. 1347 'F7gwCkIrvdBLUtqqiLhSg9bgBduFSHZdiG5ctkJ3xRDbUFwUmghNzBDanPGMkzOX79LFJGPMOSd204U/+Bbzvd/78F4H/ieJdoad'. 1348 'pZKxRFszAI/DcP0HazXY22v+HB01kee1PA/v3zfnjx4xgGnHcNZe7OvuNj+cOEF1ZATv5nUA4jhBSgmADCVWo8Ge2Of9wb18P/G7'. 1349 'oUXmYi30zqlTVEdGWLh1g2D6MYlKkXGE0Vl8aa2GEB149+4xXSzyoOIw/mimiZV/DPb25pFOj13A9gOMEChhUEqhVYqWKUk9QAUp'. 1350 'sT/P4s8PmKlUmNhQaIJbkDVqBbpw6wZ2zUc4Nm+ePku5p4eOrgpueQOFUoVCVxcD4+N07dpF9+5tVJeWGPBjhvr7WF1zC8ASgtcP'. 1351 'H8a7eZ1odh4sh50nzwCw9ZNh3M4Stutiu0X2nB/LyjZ6lcIbVTpdQU/jWVPzLADM8+ZGBRdtC7wrF/O7bR99iu26VL86iU4SAH4b'. 1352 'Po5d6AQhstMSvGyI4wS5FJBKSRwnzF8byx/u+PjzzMF1mfryQ1K/jnCahqp1xEopjFLoNEFJSRJHzF799gWHqa+/QKcSUXBI609f'. 1353 'Al5W4teQSiHDOipNUKnMI13RvnOXAIEKQixvGWya98SC560MFwPiqEG86JM8q79Q06lvhnOndy5/B6GPCUOMUu3BQgg8z0M3GmBZ'. 1354 'iGJn3v2VmsqnfzNx7FDueODuj8ROCFpjtG5TCmOYv32bJ09msP0ISydMfnAUgF8/O45RAA6WTPjlvXcB+Gn7FuRf/zAnNX6x3ARe'. 1355 'PSdmqL+P/YHkwMGDOGWDZTlQcNBRhPEComgB/YeHfq2InF1kLlXUOkpMbio1bd7aATRD/X0M1lPeSlM2vt2X1XBZjZnpLG2tmZO6'. 1356 'LbQVOIcP+HG2UauH3xgwBqOz9Cc3l1tC24Fz+MvUDroeGNb5if9H/1dM/wLPCYMw9fryKgAAAABJRU5ErkJggg==' ; 1357 1358 //========================================================== 1359 // error.png 1360 //========================================================== 1361 $this->iBuiltinIcon[9][0]= 541 ; 1362 $this->iBuiltinIcon[9][1]= 1363 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAAAaVBMVEX//////2Xy8mLl5V/Z2VvMzFi/v1WyslKlpU+ZmUyMjEh/'. 1364 'f0VyckJlZT9YWDxMTDjAwMDy8sLl5bnY2K/MzKW/v5yyspKlpYiYmH+MjHY/PzV/f2xycmJlZVlZWU9MTEXY2Ms/PzwyMjLFTjea'. 1365 'AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTCAkUMSj9wWSOAAABLUlEQVR4'. 1366 '2s2U3ZKCMAxGjfzJanFAXFkUle/9H9JUKA1gKTN7Yy6YMjl+kNPK5rlZVSuxf1ZRnlZxFYAm93NnIKvR+MEHUgqBXx93wZGIUrSe'. 1367 'h+ctEgbpiMo3iQ4kioHCGxir/ZYUbr7AgPXs9bX0BCYM8vN/cPe8oQYzom3tVsSBMVHEoOJ5dm5F1RsIe9CtqGgRacCAkUvRtevT'. 1368 'e2pd6vOWF+gCuc/brcuhyARakBU9FgK5bUBWdHEH8tHpDsZnRTZQGzdLVvQ3CzyYZiTAmSIODEwzFCAdJopuvbpeZDisJ4pKEcjD'. 1369 'ijWPJhU1MjCo9dkYfiUVjQNTDKY6CVbR6A0niUSZjRwFanR0l9i/TyvGnFdqwStq5axMfDbyBksld/FUumvxS/Bd9VyJvQDWiiMx'. 1370 'iOsCHgAAAABJRU5ErkJggg==' ; 1371 1372 //========================================================== 1373 // openfolder.png 1374 //========================================================== 1375 $this->iBuiltinIcon[10][0]= 2040 ; 1376 $this->iBuiltinIcon[10][1]= 1377 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEANAAtwClFht71AAAAAlwSFlz'. 1378 'AAALEAAACxABrSO9dQAAAAd0SU1FB9AKDQ4RIXMeaLcAAAd1SURBVHicxZd7jBXVHcc/58zcvTNzH8vusqw8FsTsKiCUUh5WBZXG'. 1379 'GkOptmqwNWsWLKXFGlEpzZI0AWNKSy0WhDS22gJKtWlTsSRqzYIuLGB2WVvDIwQMZQMsy2OFfdzde+/OnHP6x907vJaFpjb9JZM5'. 1380 'c85Mfp/f9/s7Jxn4P4e41gtSyp78WGvtfdEAcqDFYUOH9HS0NhGk9tPb/ilSyp789UUB2AMuqhQy3Uzm7HGkE6W3dTNZMRI3EcWO'. 1381 'jf9ClLmWBT3dzW8jUsevWHCG3UpWl+IkHSxnbDh/Mcz12NevBcuWXTmf6TjnXvJ88gDmVB3pw3+nt3UzHa1NqMzBS2zqPLGFjtMN'. 1382 'ZNr3XdW+qyqwZcFk76HX/tHWfuQvyO4W7qhaHwL8efkMRlRUpPv7rqD0RrJ+FgAjLy1a20OIxZJEEuNCRfIApj+om4bGM3u2/sYU'. 1383 '9J41d8973f3Dhg1pISTV1dXXBRNJxPGFCzhou+DCQrScZOkktNaeDZjamgeZ9MgiYmVDccvHhjAzJw0NTh8/alyZMaVJicp0iTHj'. 1384 'JpgNv38tjWUhhGROdbUL9W5/MH5XCkjlcibi+KIop5LVHLKEu8A/f4r286doa9pGrGwYAAsfqbbH3b8MgO/Nqgy6WvdbbXHMkEFJ'. 1385 '4xUOMVEvaTZu3BgmvF4Yk4hz9rO/Ulr5cE9owae/rcGxohSOuiWkC2IjcIqKyPZm+OmCH7GhoZEF077EEzVVweAbJ+riEeO0Ey8y'. 1386 'UubqOHn0AOgMwvf59txnBrSp9dgxKmf/+kIP1NY8SFk0jh5ajmNHAWg5b2E5EexojGHjbiVRMoRMNs0LC+Yz46vTuH3enN7BI8fr'. 1387 'qFdo0BoVZNC9aVSQ4fNjBzEmQJiARxb+/AqYPMAVB5FsPU5v37g9OxgLhe14ZM5/ju052E6MNZvf5pmHHuLmmWOkEysxUtpGAtme'. 1388 'dtHTflJkezqQto3jFRnLssyf1jydxiiM7zNnye/c3ZsqLu2BN5fcMfzrv/hby1tPzmRUoihcTJ87CwQI2yLtDcIqsIjYUf51qBlf'. 1389 'OnScOSrdQUOMURkiXsLUzJnvbGhoBGDHH5cGyZLhOpYoNl5hqYnYEXOu5fDl9eYAHntx98n8hFHZcPHUuTSxSASAeK/CGIOxJJ0f'. 1390 'bOGNPU280dgkq6Y2yu8vfjCIlwwzr+/ZQ/PHO0gOLuO5qsftDQ2NbN+4OCgqG6WTxWVaq6zpF+DiSHWnicdylp3r6aZTWthIOrNp'. 1391 'ktHcvBu0sHX1Sm6ozB3B42d90zZA9bQp7PvgPSzXZfnqX/HS4DKKK2+x69Y/HURs26iBAN5ccsfw7774UcumF37C6f07KSt2OHji'. 1392 'DEUJD0tISjyPrrSPlAKvN0JP/U4O1NfjuhG2rvklN1SOpfXwftpbTqAyKRrff5fb7rs9V1R7m4wlz2ihA3HpmXflUWyOH2umpLiY'. 1393 'ui3v8M+6bWzfsRNbSgqkxaCkiy0simMuEWEhpcRzIhQWOIAh6tiAwS4owInFiTou5dOnMnl2NR++ujBwXEc9terD6M43nrj6LgAB'. 1394 'QnDPA9/irtkP8JRS7Hr/3T6YekDQ1pEiEXOwpUVJzCVlZZFS4mZtkpEo9ChAkDp/jtLMBACy6S4RiQghLyv5cgBRPnKUOX6smUGF'. 1395 'hSil0MYw9d77mPy1e5mnFE3batm3czvb6nYgEJztSFGU9LCRlMRdUjIH0+lnEMIwPNXD3NumoVJnrMCJaiciMUZfvQnz4QcBSvV1'. 1396 'vjE5GK358t0zmXDnDB79saLpo20c+aSRD+t25JTp7GZQwsEWFiVxl6hlUf/WO9z32CxmL1rOe6u/I2KuwGhzLQCB7/sYY9Bah3el'. 1397 'FKbvrrVm4vS7GH/7ncx+chEHGz7myCeNbPtoO0JI2jq78WIRLGkzsqs7V5SfFV5EovXACoiqqsfNpk2vo5VCWtYFBfoU0VoTBAFa'. 1398 'a7TRaK2p+MoURk+cxMzq+Rzbv49DDbuo27UTW9h0dedssPxuK+kIfN8XxhgDYPVXf2Fh4XKtFIl4AiklAlBKAYRKKK36wHIweTCt'. 1399 'NfHiEkaOn8j0+7/BmDFjaT30GbHywSxcuZkpFfFg+m1jjZ/NmnVvNfRvwd69e8WBA/uNFAIh4JVXXmHsmDHE4vEQQgjQ2lxQIm9N'. 1400 'nz35q3BEOZOHzaG2thaA4mRU+L29It+IV21CpbRQfeMFC35gRB/M2rVrubnyZmLxWJhECBEmz/eHyo/7lMlH3LFFujsthNFCCGOu'. 1401 '+WNyeUgpjSVzMKtWraKyshLPdcPEeYWCIEBdpIxSivr6eta8vI7d6+cGnhdV06pe1QP+F/QXWmuRL+jZZ58LlVmxYgUVFRV4rhtu'. 1402 '4TzMxXAA6XRaRAtsYUkx8I/JtSJQOlSwpmZpCLN8+fPcdNNoHMfB9/0QJgRoP295TlR7UVv8xxZcHMuWIZ9/Hn35vG3JEGZpzVJG'. 1403 'jx5N1IlitKahsZE1L69j69qHgx+urFX/lQL9JYdLlfnZihUhzOLFi8N3Ml1dthOxVH/f/8/CtqSJ2JaJ2JZ59J7RPsC/AViJsQS/'. 1404 'dBntAAAAAElFTkSuQmCC' ; 1405 1406 //========================================================== 1407 // folder.png 1408 //========================================================== 1360 1409 $this->iBuiltinIcon[11][0]= 1824 ; 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1410 $this->iBuiltinIcon[11][1]= 1411 'iVBORw0KGgoAAAANSUhEUgAAACIAAAAiCAYAAAA6RwvCAAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlz'. 1412 'AAALEAAACxABrSO9dQAAAAd0SU1FB9ECAQgFFyd9cRUAAAadSURBVHiczdhvbBP3Hcfx9/2xfefEOA5JoCNNnIT8AdtZmYBETJsI'. 1413 '6+jQOlQihT1AYgytqzZpD1atfyYqlT1h0lRpT7aRJ4NQpRvZGELVuo5Ua9jEJDIETQsNQyPBsUJMWGPnj//e+e72wNg4xElMR6ed'. 1414 'ZNln3933dZ/f93f6yfB/sgmrHdDV1WXlPg8NDZUDScD8LFFFEZZlWYZhWMFg0Orq6sq/gDJAfFy1iiZy9OjrVnj4JzQ1rMWqfxm/'. 1415 '309jYyNtbW0kEgnu3bvH4cOH88c/jqSKQl4/XGkd+eVtAN46up1LH92ktqYS++ZX8Pv9NDQ0sGnTJlKpFOFwmO7u7vy5IyMjeVRd'. 1416 'XV1+WEOh0IrY4pDnq6wXX/sTiCJaMkFZdRNqxefoe7VtCSqXVDqdZnZ2ltraWkzTpKqqijt3JpFlG7dvj7NzZ1f++qFQyA3EClHL'. 1417 'Ql743nFkhxPDtJAd5eTaYSVUfX09lZWVlJWVIUnSg7sVQMBCUcu4ceMGe/bsIRQK1QAzOcyykIM9P0KyudAyCWyqG8nhwqa4SkLt'. 1418 '3r0bVVVxu924XC40TUOWZUQxe97CwgIdHR2LMHIxSCaVInVvFElxE0vMY1Pd2NUKJMWNTXHlUfF//4vETJCelwbpFm3MjP2dt37x'. 1419 'AlN+PzU1NViWRSwW4+7du3g8HjweD4qi5EFAJzAExIpCANbooxhplfB0FJvTg6xWIqsVRVF6MopkU3FXPcnkJxGU0VEAdF2noqKC'. 1420 'W3/8DpnqLjzep2lubsblcjE8PExHR8fboVDID9xYFpLBDpJF0jDQIncQpWlkm31FlFLtp9PfyuW/vYQj1kPSuRW/38+lj27S2Q7v'. 1421 '/aWXUBVUffVNtm3blivVCEwsC5Eyc5iiApEpDEAXMqQdldhSiWVQHjJagud+8Fuexck/zv+K82dfoSbSCsDe75/km+4GVPd6+l5t'. 1422 '4zJHcqVUYN2yEEtZQDCSJCueRAYsPY49HsFIZVG6p25JUumFafT4DKJN4amtT7Nz38sk5+5A70HMtEYyMkFiZhxzjQ/poXrLQrRU'. 1423 'DFGEeFpAlkQkm4pRiCpIKodKzk0T/2QMh+piPjxKZPwiSkUtu/b9mNnJEWS7E8nhAmvpM60oJDkXJxqNozxRRUxPIesispBBlsXV'. 1424 'UaKEFo8gzoaJhz8s2lOmrpUG+WBhJ9/60g+Z+fDXTAXfxllRjl1VkO0OFATsYhYliiK21ZKKhhHnFveUqSdKgwAEOp7F2v51vvw8'. 1425 'XH7/N1wd/BlTweuUV65BdtgfoLTSkipsdD3tRi0VYpommUwGwzDwdT5HYEc3giAwcvH3jLz3BlPB67jWeZBEKYsSBWwpHZtNKo4q'. 1426 'aHTDsJeeiGEYWJaFZVmYpommaRiGQdPnv0bb1m8gSRL/vPIOV979aR4lmAJ2p4qCgCxksNuKJ6VNpx4NYhgGpmkuQhmGQTqdxjAM'. 1427 'qr2d7HtxEEEQuH1tkKvvvkF44tqDnrIcKJKAPf1g+LAUElq8dIiu60sApmnm93Pfzc7OYhgGrie+wFe++ztcLhcT1wf54PzPCU9c'. 1428 'w7XWjWS3IdsdOAUBWZAxrRJnTQ6SG5bce2FCpmkughmGQSqVYm5uDtnj44sH38TtdhP6+Dwf//V4ttHXrkGURZJaic8RgHQ6jWma'. 1429 'SJKUL5RLKNfIOczDKF3XSSaTRCIRhLJWntp3nGfWrSMxc5OLf3iNP4+68T9Ub9nF76lTpxgfHycajZJKpdA0LZ9GbjYV7hcDWZaF'. 1430 'pmnMz88Ti8UYunSLmu1HFi2aVkxkaGjINTY2ttDb24vX6+XQoUNs3ryZ8vJyIDu1BUFYkkxhgxeiWlpaOHPmDE1NTdTX1xe98eWG'. 1431 'JnF/9dQZCoXUYDA4AOD1ejlw4ACtra2Ul5fniwmCkEcUJiUIAoFAgL6+Pnw+H21tbfT39z8SxCS7hHsfWH9/8dL4MKqnp4eWlhac'. 1432 'TmcekEvMNE2am5s5ceIEgUCA9vZ2Tp48ic/nY3j4UsmQHCYOjJHtpeBKqL1799Lc3IzT6UTXdRobGxkYGKC9vZ3W1tZ8Ko86NJ8a'. 1433 'tXHjRo4dO8bp06fZsmULGzZsoL+/n0AggNfr5ezZs/8VpGTU5OSkc//+/acBfD4f1dXV7Nq1i4aGBs6dO4fP5+Pq1SuPBbIiyjTN'. 1434 'RUnV1dUNXLhwAa/Xy44dO4jFYgBEo9FFF1r134BPuYlk16LrAYXsAlmtq6sbKDwoFAp9m+ykuP5ZQVZF3f8tCdwCov8LyHIoAANI'. 1435 'AXf/A1TI0XCDh7OWAAAAAElFTkSuQmCC' ; 1436 1437 //========================================================== 1438 // file_important.png 1439 //========================================================== 1440 $this->iBuiltinIcon[12][0]= 1785 ; 1441 $this->iBuiltinIcon[12][1]= 1442 'iVBORw0KGgoAAAANSUhEUgAAACIAAAAiCAYAAAA6RwvCAAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlz'. 1443 'AAALDwAACw8BkvkDpQAAAAd0SU1FB9ECDAcjDeD3lKsAAAZ2SURBVHicrZhPaFzHHcc/897s7lutJCsr2VHsOHWMk0MPbsBUrcnF'. 1444 'OFRdSo6FNhdB6SGHlpDmYtJCDyoxyKe6EBxKQkt7KKL0T6ABo0NbciqigtC6PhWKI2NFqqxdSd7V2/dmftPDvPd212t55dCBYfbN'. 1445 'zpvfZ77z+/1mdhUjytWrV93Hf/24eD5z9gwiMlDjOKbb7dLtdhER2u02u7u73Lp1CxEZBw4AeZwdNQqkMd9wbziFGINJUt6rRbz5'. 1446 '1ptUq1XK5TJBEAAUMHt7e+zu7gKwvLzMysoKwAng/uNg9CgQgFKlgg1DUJ67Vqtx6tQpZmdniaIIpRTOOZRSdDoddnZ2aLfbLC8v'. 1447 's7S0xJUrV7ZGwQSj1PhhfRodVdDlMrpc5vup5Z2fvMPdu3fZ29vDWjvwztjYGPV6nVqtRqVS4dKlSywtLQFsAdOH2XwsCEApg3jl'. 1448 'w98Rak2gvYjNZpNms0mSJDjnHgkDMDc3dySYQ0Ea8w139YUX0OUKulzyg7UmCEO+l1huvHuDra0t9vf3h1TJYSqVypFhHquIrlQI'. 1449 'S5qv/uIDAC7/4bcEQYAKvK+0Wq1DVQGIoog7d+4cCeaRII35hrt+8SsEOkRlUaEyR0UpFIrXHxyMVKVUKnHv3r0jwRwaNelBjBjL'. 1450 'Sz/7KYuLiwAsLi7y4z/9kY9e+TpkCuSqjI+Po7XuAWeKXLt2DWNMUZMkwRjDhQsXWFtbK6JpCCT3jfQgxomPtPX19YHWicM5x3c2'. 1451 '73Pj3Ru8/aO3mZqaolKpoHVvyuvXr/Ppnf/Q7uzz380NPtu4y/qnG+ztd1hfX2dtbQ3gIvDnRyqSxl1UoPjyz98D4PTp0wPtq39Z'. 1452 '4fdzLxegrVaLVqvF5OQkYRgWqpRKJZ77wvNsbW1RG5tgfKLOTH2G7Z1twqBQrgrMDvhInjfSOCY5iIv+hYWFgRZArEWsZWF941Bf'. 1453 'SdMUgMnJCWpjVU4cn+HUyePM1Gc4+fRUPkzBI5w1jbukcczLv/5l0XfmzJmBFuCba38r/CRXpT+CrDUoZ0jjB4RYonJAOYRobJKT'. 1454 'z5zgqfqxAbsFSH6mpHFM2qdGXh4VnoViD6mSJF2cTQeqDqBaKVHWmonJCWpZjhkC6anR5WsffTgwaHV1FaUUq6urA/2v3f5k4LnV'. 1455 'arG9tUn3oI2YBCcWHYAxMVYs1qZEZY2SFB2aYZDGfMN9d7uJiWPSeFiNo5Rclc3NTXZbO6RpF7EJVixYA9agwwDnUiqlEPdQ3imi'. 1456 'Jo27BGHIt/7x9yEjc3Nzh27Na7c/4TdffKl4bja3ae5MUIu0T/HOEIaOpJt4gwoSsVTK4SBIY77hFtY3ABBjBiZ90rKwvsH77/+K'. 1457 't37wOhO1iPpTk4SBw1mLsz6CnKQ4l3qV+kE+t9XHlNZOk+bUJLVIE1VCcIJWQmJ6qjj30NbcXLkZMt8YPig+Z3n1G5fZ39/j/vY2'. 1458 '9ckqZT2Ochbn0p4qNkU/dDfUADdXbh4HXgRO4zNdEU0XL1784PLly5w9e7Z4SazFOfGrEotDcOKrcoJPmrYIXf/Zop3QNd1skuGt'. 1459 'cUAb2MgAxvHZTgFUq1Wmp6eZnZ0F8JlTjDduDThBnDeECEoJtbGIp6enqEblzCcEZ1PECU4yVRiOGgd0gc+AB0CZvkv1sWPHOHfu'. 1460 'HOfPn8da41cpkkltEBEPJhYnBkTQJcdYVKGkgRxCfBsq5xXNgAa2Bn+hjTOgHEKBP8pzRUxykIH4ifLJRTJAl+UMBJzPHQ6bfe/f'. 1461 'cWIzPxlUpD+zugzIZtVk1d8znBAqRxgoQuVQgSJQ3h9C5QhDRYgjUILCAzlnEdsHYTKfMTEBcP7F54YUGVmc2GLlIn6ve6v0ahSt'. 1462 '8X25TzjJ+rIx1grKpQPWR4LkGVVsMgghvS0qjPdvm5OeceOTWA5Evo2mFzkjQfL7hZPUy5yvvF/uPFQL3+nbDmsLCEmT3sTmCTNr'. 1463 'rogT6yFsOix3ftw7OwQhkvSU6CuinhCk0+kAkFoBazEEICHaHHiPVmU0gnUp4EAc1mYrF0EBVpwPi34VrBkwPxKk3W5ju/e5/c+d'. 1464 'bGUHIAIuydTIE5zfc5Wr4lJcahHnHTP3CVGm78DrgY38N+DEibp7dmYKdAQmBh1hjEFjis+9CTWYGK21H6PxPyOI0DobYwzZF/z7'. 1465 '7jadTvJtYG0kCD7lfwl49ijgT1gc0AH+dZSJA/xB+Mz/GSIvFoj/B7H1mAd8CO/zAAAAAElFTkSuQmCC' ; 1466 1467 $this->iLen = count($this->iBuiltinIcon); 1419 1468 } 1420 1469 } … … 1427 1476 //=================================================== 1428 1477 // CLASS IconImage 1429 // Description: Holds properties for an icon image 1478 // Description: Holds properties for an icon image 1430 1479 //=================================================== 1431 1480 class IconImage { … … 1435 1484 private $iScale=1.0; 1436 1485 1437 function IconImage($aIcon,$aScale=1) {1438 GLOBAL $_gPredefIcons ; 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 //('Argument to IconImage must be string or integer');1449 1450 1451 1452 1486 function __construct($aIcon,$aScale=1) { 1487 GLOBAL $_gPredefIcons ; 1488 if( is_string($aIcon) ) { 1489 $this->iGDImage = Graph::LoadBkgImage('',$aIcon); 1490 } 1491 elseif( is_integer($aIcon) ) { 1492 // Builtin image 1493 $this->iGDImage = $_gPredefIcons->GetImg($aIcon); 1494 } 1495 else { 1496 JpGraphError::RaiseL(6011); 1497 //('Argument to IconImage must be string or integer'); 1498 } 1499 $this->iScale = $aScale; 1500 $this->iWidth = Image::GetWidth($this->iGDImage); 1501 $this->iHeight = Image::GetHeight($this->iGDImage); 1453 1502 } 1454 1503 1455 1504 function GetWidth() { 1456 1505 return round($this->iScale*$this->iWidth); 1457 1506 } 1458 1507 1459 1508 function GetHeight() { 1460 1509 return round($this->iScale*$this->iHeight); 1461 1510 } 1462 1511 1463 1512 function SetAlign($aX='left',$aY='center') { 1464 1465 $this->ixalign = $aX; 1466 $this->iyalign = $aY; 1467 1513 $this->ixalign = $aX; 1514 $this->iyalign = $aY; 1468 1515 } 1469 1516 1470 1517 function Stroke($aImg,$x,$y) { 1471 1518 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1519 if( $this->ixalign == 'right' ) { 1520 $x -= $this->iWidth; 1521 } 1522 elseif( $this->ixalign == 'center' ) { 1523 $x -= round($this->iWidth/2*$this->iScale); 1524 } 1525 1526 if( $this->iyalign == 'bottom' ) { 1527 $y -= $this->iHeight; 1528 } 1529 elseif( $this->iyalign == 'center' ) { 1530 $y -= round($this->iHeight/2*$this->iScale); 1531 } 1532 1533 $aImg->Copy($this->iGDImage, 1534 $x,$y,0,0, 1535 round($this->iWidth*$this->iScale),round($this->iHeight*$this->iScale), 1536 $this->iWidth,$this->iHeight); 1490 1537 } 1491 1538 } … … 1500 1547 public $csimtarget='',$csimwintarget='',$csimalt=''; 1501 1548 private $iFFamily=FF_FONT1,$iFStyle=FS_NORMAL,$iFSize=10; 1549 private $iFontArray=array(); 1502 1550 private $iColor="black"; 1503 1551 private $iText=""; 1504 1552 private $iHAlign="left",$iVAlign="bottom"; 1505 1506 //---------------1507 // CONSTRUCTOR 1508 function TextProperty($aTxt='') {1509 1510 } 1511 1512 //---------------1513 // PUBLIC METHODS 1553 1554 //--------------- 1555 // CONSTRUCTOR 1556 function __construct($aTxt='') { 1557 $this->iText = $aTxt; 1558 } 1559 1560 //--------------- 1561 // PUBLIC METHODS 1514 1562 function Set($aTxt) { 1515 1563 $this->iText = $aTxt; 1516 1564 } 1517 1565 1518 1566 function SetCSIMTarget($aTarget,$aAltText='',$aWinTarget='') { 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1567 if( is_string($aTarget) ) 1568 $aTarget = array($aTarget); 1569 $this->csimtarget=$aTarget; 1570 1571 if( is_string($aWinTarget) ) 1572 $aWinTarget = array($aWinTarget); 1573 $this->csimwintarget=$aWinTarget; 1574 1575 if( is_string($aAltText) ) 1576 $aAltText = array($aAltText); 1529 1577 $this->csimalt=$aAltText; 1530 1531 } 1532 1578 1579 } 1580 1533 1581 function SetCSIMAlt($aAltText) { 1534 1535 1582 if( is_string($aAltText) ) 1583 $aAltText = array($aAltText); 1536 1584 $this->csimalt=$aAltText; 1537 1585 } … … 1539 1587 // Set text color 1540 1588 function SetColor($aColor) { 1541 1542 } 1543 1589 $this->iColor = $aColor; 1590 } 1591 1544 1592 function HasTabs() { 1545 1546 1547 1548 1549 1550 1551 } 1552 1593 if( is_string($this->iText) ) { 1594 return substr_count($this->iText,"\t") > 0; 1595 } 1596 elseif( is_array($this->iText) ) { 1597 return false; 1598 } 1599 } 1600 1553 1601 // Get number of tabs in string 1554 1602 function GetNbrTabs() { 1555 1556 1557 1558 1559 1560 1561 } 1562 1603 if( is_string($this->iText) ) { 1604 return substr_count($this->iText,"\t") ; 1605 } 1606 else{ 1607 return 0; 1608 } 1609 } 1610 1563 1611 // Set alignment 1564 1612 function Align($aHAlign,$aVAlign="bottom") { 1565 1566 1567 } 1568 1613 $this->iHAlign=$aHAlign; 1614 $this->iVAlign=$aVAlign; 1615 } 1616 1569 1617 // Synonym 1570 1618 function SetAlign($aHAlign,$aVAlign="bottom") { 1571 1572 1573 } 1574 1619 $this->iHAlign=$aHAlign; 1620 $this->iVAlign=$aVAlign; 1621 } 1622 1575 1623 // Specify font 1576 1624 function SetFont($aFFamily,$aFStyle=FS_NORMAL,$aFSize=10) { 1577 $this->iFFamily = $aFFamily; 1578 $this->iFStyle = $aFStyle; 1579 $this->iFSize = $aFSize; 1580 } 1625 $this->iFFamily = $aFFamily; 1626 $this->iFStyle = $aFStyle; 1627 $this->iFSize = $aFSize; 1628 } 1629 1630 function SetColumnFonts($aFontArray) { 1631 if( !is_array($aFontArray) || count($aFontArray[0]) != 3 ) { 1632 JpGraphError::RaiseL(6033); 1633 // 'Array of fonts must contain arrays with 3 elements, i.e. (Family, Style, Size)' 1634 } 1635 $this->iFontArray = $aFontArray; 1636 } 1637 1581 1638 1582 1639 function IsColumns() { 1583 return is_array($this->iText) ; 1584 } 1585 1640 return is_array($this->iText) ; 1641 } 1642 1586 1643 // Get width of text. If text contains several columns separated by 1587 // tabs then return both the total width as well as an array with a 1644 // tabs then return both the total width as well as an array with a 1588 1645 // width for each column. 1589 1646 function GetWidth($aImg,$aUseTabs=false,$aTabExtraMargin=1.1) { 1590 $extra_margin=4; 1591 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1592 if( is_string($this->iText) ) { 1593 if( strlen($this->iText) == 0 ) return 0; 1594 $tmp = split("\t",$this->iText); 1595 if( count($tmp) <= 1 || !$aUseTabs ) { 1596 $w = $aImg->GetTextWidth($this->iText); 1597 return $w + 2*$extra_margin; 1598 } 1599 else { 1600 $tot=0; 1601 $n = count($tmp); 1602 for($i=0; $i < $n; ++$i) { 1603 $res[$i] = $aImg->GetTextWidth($tmp[$i]); 1604 $tot += $res[$i]*$aTabExtraMargin; 1605 } 1606 return array(round($tot),$res); 1607 } 1608 } 1609 elseif( is_object($this->iText) ) { 1610 // A single icon 1611 return $this->iText->GetWidth()+2*$extra_margin; 1612 } 1613 elseif( is_array($this->iText) ) { 1614 // Must be an array of texts. In this case we return the sum of the 1615 // length + a fixed margin of 4 pixels on each text string 1616 $n = count($this->iText); 1617 for( $i=0, $w=0; $i < $n; ++$i ) { 1618 $tmp = $this->iText[$i]; 1619 if( is_string($tmp) ) { 1620 $w += $aImg->GetTextWidth($tmp)+$extra_margin; 1621 } 1622 else { 1623 if( is_object($tmp) === false ) { 1624 JpGraphError::RaiseL(6012); 1625 } 1626 $w += $tmp->GetWidth()+$extra_margin; 1627 } 1628 } 1629 return $w; 1630 } 1631 else { 1632 JpGraphError::RaiseL(6012); 1633 } 1647 $extra_margin=4; 1648 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1649 if( is_string($this->iText) ) { 1650 if( strlen($this->iText) == 0 ) return 0; 1651 $tmp = preg_split('/\t/',$this->iText); 1652 if( count($tmp) <= 1 || !$aUseTabs ) { 1653 $w = $aImg->GetTextWidth($this->iText); 1654 return $w + 2*$extra_margin; 1655 } 1656 else { 1657 $tot=0; 1658 $n = count($tmp); 1659 for($i=0; $i < $n; ++$i) { 1660 $res[$i] = $aImg->GetTextWidth($tmp[$i]); 1661 $tot += $res[$i]*$aTabExtraMargin; 1662 } 1663 return array(round($tot),$res); 1664 } 1665 } 1666 elseif( is_object($this->iText) ) { 1667 // A single icon 1668 return $this->iText->GetWidth()+2*$extra_margin; 1669 } 1670 elseif( is_array($this->iText) ) { 1671 // Must be an array of texts. In this case we return the sum of the 1672 // length + a fixed margin of 4 pixels on each text string 1673 $n = count($this->iText); 1674 $nf = count($this->iFontArray); 1675 for( $i=0, $w=0; $i < $n; ++$i ) { 1676 if( $i < $nf ) { 1677 $aImg->SetFont($this->iFontArray[$i][0],$this->iFontArray[$i][1],$this->iFontArray[$i][2]); 1678 } 1679 else { 1680 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1681 } 1682 $tmp = $this->iText[$i]; 1683 if( is_string($tmp) ) { 1684 $w += $aImg->GetTextWidth($tmp)+$extra_margin; 1685 } 1686 else { 1687 if( is_object($tmp) === false ) { 1688 JpGraphError::RaiseL(6012); 1689 } 1690 $w += $tmp->GetWidth()+$extra_margin; 1691 } 1692 } 1693 return $w; 1694 } 1695 else { 1696 JpGraphError::RaiseL(6012); 1697 } 1634 1698 } 1635 1699 … … 1638 1702 // column as an array of one 1639 1703 function GetColWidth($aImg,$aMargin=0) { 1640 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1641 if( is_array($this->iText) ) { 1642 $n = count($this->iText); 1643 for( $i=0, $w=array(); $i < $n; ++$i ) { 1644 $tmp = $this->iText[$i]; 1645 if( is_string($tmp) ) { 1646 $w[$i] = $aImg->GetTextWidth($this->iText[$i])+$aMargin; 1647 } 1648 else { 1649 if( is_object($tmp) === false ) { 1650 JpGraphError::RaiseL(6012); 1651 } 1652 $w[$i] = $tmp->GetWidth()+$aMargin; 1653 } 1654 } 1655 return $w; 1656 } 1657 else { 1658 return array($this->GetWidth($aImg)); 1659 } 1660 } 1661 1704 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1705 if( is_array($this->iText) ) { 1706 $n = count($this->iText); 1707 $nf = count($this->iFontArray); 1708 for( $i=0, $w=array(); $i < $n; ++$i ) { 1709 $tmp = $this->iText[$i]; 1710 if( is_string($tmp) ) { 1711 if( $i < $nf ) { 1712 $aImg->SetFont($this->iFontArray[$i][0],$this->iFontArray[$i][1],$this->iFontArray[$i][2]); 1713 } 1714 else { 1715 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1716 } 1717 $w[$i] = $aImg->GetTextWidth($tmp)+$aMargin; 1718 } 1719 else { 1720 if( is_object($tmp) === false ) { 1721 JpGraphError::RaiseL(6012); 1722 } 1723 $w[$i] = $tmp->GetWidth()+$aMargin; 1724 } 1725 } 1726 return $w; 1727 } 1728 else { 1729 return array($this->GetWidth($aImg)); 1730 } 1731 } 1732 1662 1733 // Get total height of text 1663 1734 function GetHeight($aImg) { 1664 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1665 return $aImg->GetFontHeight(); 1666 } 1667 1668 // Unhide/hide the text 1735 $nf = count($this->iFontArray); 1736 $maxheight = -1; 1737 1738 if( $nf > 0 ) { 1739 // We have to find out the largest font and take that one as the 1740 // height of the row 1741 for($i=0; $i < $nf; ++$i ) { 1742 $aImg->SetFont($this->iFontArray[$i][0],$this->iFontArray[$i][1],$this->iFontArray[$i][2]); 1743 $height = $aImg->GetFontHeight(); 1744 $maxheight = max($height,$maxheight); 1745 } 1746 } 1747 1748 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1749 $height = $aImg->GetFontHeight(); 1750 $maxheight = max($height,$maxheight); 1751 return $maxheight; 1752 } 1753 1754 // Unhide/hide the text 1669 1755 function Show($aShow=true) { 1670 1671 } 1672 1756 $this->iShow=$aShow; 1757 } 1758 1673 1759 // Stroke text at (x,y) coordinates. If the text contains tabs then the 1674 1760 // x parameter should be an array of positions to be used for each successive 1675 1761 // tab mark. If no array is supplied then the tabs will be ignored. 1676 1762 function Stroke($aImg,$aX,$aY) { 1677 if( $this->iShow ) { 1678 $aImg->SetColor($this->iColor); 1679 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1680 $aImg->SetTextAlign($this->iHAlign,$this->iVAlign); 1681 if( $this->GetNbrTabs() <= 1 ) { 1682 if( is_string($this->iText) ) { 1683 // Get rid of any "\t" characters and stroke string 1684 if( is_array($aX) ) $aX=$aX[0]; 1685 if( is_array($aY) ) $aY=$aY[0]; 1686 $aImg->StrokeText($aX,$aY,str_replace("\t"," ",$this->iText)); 1687 } 1688 elseif( is_array($this->iText) && ($n = count($this->iText)) > 0 ) { 1689 $ax = is_array($aX) ; 1690 $ay = is_array($aY) ; 1691 if( $ax && $ay ) { 1692 // Nothing; both are already arrays 1693 } 1694 elseif( $ax ) { 1695 $aY = array_fill(0,$n,$aY); 1696 } 1697 elseif( $ay ) { 1698 $aX = array_fill(0,$n,$aX); 1699 } 1700 else { 1701 $aX = array_fill(0,$n,$aX); 1702 $aY = array_fill(0,$n,$aY); 1703 } 1704 $n = min($n, count($aX) ) ; 1705 $n = min($n, count($aY) ) ; 1706 for($i=0; $i < $n; ++$i ) { 1707 $tmp = $this->iText[$i]; 1708 if( is_object($tmp) ) { 1709 $tmp->Stroke($aImg,$aX[$i],$aY[$i]); 1710 } 1711 else 1712 $aImg->StrokeText($aX[$i],$aY[$i],str_replace("\t"," ",$tmp)); 1713 } 1714 } 1715 } 1716 else { 1717 $tmp = split("\t",$this->iText); 1718 $n = min(count($tmp),count($aX)); 1719 for($i=0; $i < $n; ++$i) { 1720 $aImg->StrokeText($aX[$i],$aY,$tmp[$i]); 1721 } 1722 } 1723 } 1763 if( $this->iShow ) { 1764 $aImg->SetColor($this->iColor); 1765 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1766 $aImg->SetTextAlign($this->iHAlign,$this->iVAlign); 1767 if( $this->GetNbrTabs() < 1 ) { 1768 if( is_string($this->iText) ) { 1769 if( is_array($aX) ) $aX=$aX[0]; 1770 if( is_array($aY) ) $aY=$aY[0]; 1771 $aImg->StrokeText($aX,$aY,$this->iText); 1772 } 1773 elseif( is_array($this->iText) && ($n = count($this->iText)) > 0 ) { 1774 $ax = is_array($aX) ; 1775 $ay = is_array($aY) ; 1776 if( $ax && $ay ) { 1777 // Nothing; both are already arrays 1778 } 1779 elseif( $ax ) { 1780 $aY = array_fill(0,$n,$aY); 1781 } 1782 elseif( $ay ) { 1783 $aX = array_fill(0,$n,$aX); 1784 } 1785 else { 1786 $aX = array_fill(0,$n,$aX); 1787 $aY = array_fill(0,$n,$aY); 1788 } 1789 $n = min($n, count($aX) ) ; 1790 $n = min($n, count($aY) ) ; 1791 for($i=0; $i < $n; ++$i ) { 1792 $tmp = $this->iText[$i]; 1793 if( is_object($tmp) ) { 1794 $tmp->Stroke($aImg,$aX[$i],$aY[$i]); 1795 } 1796 else { 1797 if( $i < count($this->iFontArray) ) { 1798 $font = $this->iFontArray[$i]; 1799 $aImg->SetFont($font[0],$font[1],$font[2]); 1800 } 1801 else { 1802 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1803 } 1804 $aImg->StrokeText($aX[$i],$aY[$i],str_replace("\t"," ",$tmp)); 1805 } 1806 } 1807 } 1808 } 1809 else { 1810 $tmp = preg_split('/\t/',$this->iText); 1811 $n = min(count($tmp),count($aX)); 1812 for($i=0; $i < $n; ++$i) { 1813 if( $i < count($this->iFontArray) ) { 1814 $font = $this->iFontArray[$i]; 1815 $aImg->SetFont($font[0],$font[1],$font[2]); 1816 } 1817 else { 1818 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1819 } 1820 $aImg->StrokeText($aX[$i],$aY,$tmp[$i]); 1821 } 1822 } 1823 } 1724 1824 } 1725 1825 } … … 1727 1827 //=================================================== 1728 1828 // CLASS HeaderProperty 1729 // Description: Data encapsulating class to hold property 1829 // Description: Data encapsulating class to hold property 1730 1830 // for each type of the scale headers 1731 1831 //=================================================== … … 1742 1842 public $iIntervall = 1; 1743 1843 1744 //---------------1745 // CONSTRUCTOR 1746 function HeaderProperty() {1747 1748 } 1749 1750 //---------------1751 // PUBLIC METHODS 1844 //--------------- 1845 // CONSTRUCTOR 1846 function __construct() { 1847 $this->grid = new LineProperty(); 1848 } 1849 1850 //--------------- 1851 // PUBLIC METHODS 1752 1852 function Show($aShow=true) { 1753 1853 $this->iShowLabels = $aShow; 1754 1854 } 1755 1855 1756 1856 function SetIntervall($aInt) { 1757 $this->iIntervall = $aInt; 1857 $this->iIntervall = $aInt; 1858 } 1859 1860 function SetInterval($aInt) { 1861 $this->iIntervall = $aInt; 1758 1862 } 1759 1863 1760 1864 function GetIntervall() { 1761 1762 } 1763 1865 return $this->iIntervall ; 1866 } 1867 1764 1868 function SetFont($aFFamily,$aFStyle=FS_NORMAL,$aFSize=10) { 1765 1766 $this->iFStyle= $aFStyle;1767 $this->iFSize= $aFSize;1869 $this->iFFamily = $aFFamily; 1870 $this->iFStyle = $aFStyle; 1871 $this->iFSize = $aFSize; 1768 1872 } 1769 1873 1770 1874 function SetFontColor($aColor) { 1771 1772 } 1773 1875 $this->iTextColor = $aColor; 1876 } 1877 1774 1878 function GetFontHeight($aImg) { 1775 1776 1879 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1880 return $aImg->GetFontHeight(); 1777 1881 } 1778 1882 1779 1883 function GetFontWidth($aImg) { 1780 1781 1884 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1885 return $aImg->GetFontWidth(); 1782 1886 } 1783 1887 1784 1888 function GetStrWidth($aImg,$aStr) { 1785 1786 1787 } 1788 1889 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1890 return $aImg->GetTextWidth($aStr); 1891 } 1892 1789 1893 function SetStyle($aStyle) { 1790 1791 } 1792 1894 $this->iStyle = $aStyle; 1895 } 1896 1793 1897 function SetBackgroundColor($aColor) { 1794 1898 $this->iBackgroundColor=$aColor; 1795 1899 } 1796 1900 1797 1901 function SetFrameWeight($aWeight) { 1798 1902 $this->iFrameWeight=$aWeight; 1799 1903 } 1800 1904 1801 1905 function SetFrameColor($aColor) { 1802 1803 } 1804 1906 $this->iFrameColor=$aColor; 1907 } 1908 1805 1909 // Only used by day scale 1806 1910 function SetWeekendColor($aColor) { 1807 1808 } 1809 1911 $this->iWeekendBackgroundColor=$aColor; 1912 } 1913 1810 1914 // Only used by day scale 1811 1915 function SetSundayFontColor($aColor) { 1812 1813 } 1814 1916 $this->iSundayTextColor=$aColor; 1917 } 1918 1815 1919 function SetTitleVertMargin($aMargin) { 1816 1817 } 1818 1920 $this->iTitleVertMargin=$aMargin; 1921 } 1922 1819 1923 function SetLabelFormatString($aStr) { 1820 1924 $this->iLabelFormStr=$aStr; 1821 1925 } 1822 1926 1823 1927 function SetFormatString($aStr) { 1824 1928 $this->SetLabelFormatString($aStr); 1825 1929 } 1826 1930 … … 1844 1948 public $actinfo; 1845 1949 public $iTopPlotMargin=10,$iBottomPlotMargin=15; 1846 public $iVertLines=-1; 1950 public $iVertLines=-1; 1847 1951 public $iVertHeaderSize=-1; 1848 1952 // The width of the labels (defaults to the widest of all labels) 1849 private $iLabelWidth; 1953 private $iLabelWidth; 1850 1954 // Out image to stroke the scale to 1851 private $iImg; 1955 private $iImg; 1852 1956 private $iTableHeaderBackgroundColor="white",$iTableHeaderFrameColor="black"; 1853 1957 private $iTableHeaderFrameWeight=1; … … 1856 1960 private $iVertLayout=GANTT_EVEN; 1857 1961 private $iUsePlotWeekendBackground=true; 1858 private $iWeekStart = 1; 1859 1860 //---------------1861 // CONSTRUCTOR 1862 function GanttScale($aImg) {1863 $this->iImg = $aImg; 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 $this->year->SetFont(FF_FONT1,FS_BOLD); 1892 1893 1894 $this->dividerh=new LineProperty(); 1895 1896 1897 1898 1899 1900 1901 1902 1903 } 1904 1905 //---------------1906 // PUBLIC METHODS 1962 private $iWeekStart = 1; // Default to have weekends start on Monday 1963 1964 //--------------- 1965 // CONSTRUCTOR 1966 function __construct($aImg) { 1967 $this->iImg = $aImg; 1968 $this->iDateLocale = new DateLocale(); 1969 1970 $this->minute = new HeaderProperty(); 1971 $this->minute->SetIntervall(15); 1972 $this->minute->SetLabelFormatString('i'); 1973 $this->minute->SetFont(FF_FONT0); 1974 $this->minute->grid->SetColor("gray"); 1975 1976 $this->hour = new HeaderProperty(); 1977 $this->hour->SetFont(FF_FONT0); 1978 $this->hour->SetIntervall(6); 1979 $this->hour->SetStyle(HOURSTYLE_HM24); 1980 $this->hour->SetLabelFormatString('H:i'); 1981 $this->hour->grid->SetColor("gray"); 1982 1983 $this->day = new HeaderProperty(); 1984 $this->day->grid->SetColor("gray"); 1985 $this->day->SetLabelFormatString('l'); 1986 1987 $this->week = new HeaderProperty(); 1988 $this->week->SetLabelFormatString("w%d"); 1989 $this->week->SetFont(FF_FONT1); 1990 1991 $this->month = new HeaderProperty(); 1992 $this->month->SetFont(FF_FONT1,FS_BOLD); 1993 1994 $this->year = new HeaderProperty(); 1995 $this->year->SetFont(FF_FONT1,FS_BOLD); 1996 1997 $this->divider=new LineProperty(); 1998 $this->dividerh=new LineProperty(); 1999 $this->dividerh->SetWeight(2); 2000 $this->divider->SetWeight(6); 2001 $this->divider->SetColor('gray'); 2002 $this->divider->SetStyle('fancy'); 2003 2004 $this->tableTitle=new TextProperty(); 2005 $this->tableTitle->Show(false); 2006 $this->actinfo = new GanttActivityInfo(); 2007 } 2008 2009 //--------------- 2010 // PUBLIC METHODS 1907 2011 // Specify what headers should be visible 1908 2012 function ShowHeaders($aFlg) { 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 } 1925 2013 $this->day->Show($aFlg & GANTT_HDAY); 2014 $this->week->Show($aFlg & GANTT_HWEEK); 2015 $this->month->Show($aFlg & GANTT_HMONTH); 2016 $this->year->Show($aFlg & GANTT_HYEAR); 2017 $this->hour->Show($aFlg & GANTT_HHOUR); 2018 $this->minute->Show($aFlg & GANTT_HMIN); 2019 2020 // Make some default settings of gridlines whihc makes sense 2021 if( $aFlg & GANTT_HWEEK ) { 2022 $this->month->grid->Show(false); 2023 $this->year->grid->Show(false); 2024 } 2025 if( $aFlg & GANTT_HHOUR ) { 2026 $this->day->grid->SetColor("black"); 2027 } 2028 } 2029 1926 2030 // Should the weekend background stretch all the way down in the plotarea 1927 2031 function UseWeekendBackground($aShow) { 1928 1929 } 1930 2032 $this->iUsePlotWeekendBackground = $aShow; 2033 } 2034 1931 2035 // Have a range been specified? 1932 2036 function IsRangeSet() { 1933 1934 } 1935 2037 return $this->iStartDate!=-1 && $this->iEndDate!=-1; 2038 } 2039 1936 2040 // Should the layout be from top or even? 1937 2041 function SetVertLayout($aLayout) { 1938 1939 } 1940 2042 $this->iVertLayout = $aLayout; 2043 } 2044 1941 2045 // Which locale should be used? 1942 2046 function SetDateLocale($aLocale) { 1943 1944 } 1945 2047 $this->iDateLocale->Set($aLocale); 2048 } 2049 1946 2050 // Number of days we are showing 1947 2051 function GetNumberOfDays() { 1948 1949 } 1950 2052 return round(($this->iEndDate-$this->iStartDate)/SECPERDAY); 2053 } 2054 1951 2055 // The width of the actual plot area 1952 2056 function GetPlotWidth() { 1953 1954 2057 $img=$this->iImg; 2058 return $img->width - $img->left_margin - $img->right_margin; 1955 2059 } 1956 2060 … … 1959 2063 // widest title) 1960 2064 function SetLabelWidth($aLabelWidth) { 1961 1962 } 1963 1964 1965 2065 $this->iLabelWidth=$aLabelWidth; 2066 } 2067 2068 // Which day should the week start? 2069 // 0==Sun, 1==Monday, 2==Tuesday etc 1966 2070 function SetWeekStart($aStartDay) { 1967 1968 1969 1970 2071 $this->iWeekStart = $aStartDay % 7; 2072 2073 //Recalculate the startday since this will change the week start 2074 $this->SetRange($this->iStartDate,$this->iEndDate); 1971 2075 } 1972 2076 1973 2077 // Do we show min scale? 1974 2078 function IsDisplayMinute() { 1975 2079 return $this->minute->iShowLabels; 1976 2080 } 1977 2081 1978 2082 // Do we show day scale? 1979 2083 function IsDisplayHour() { 1980 1981 } 1982 1983 2084 return $this->hour->iShowLabels; 2085 } 2086 2087 1984 2088 // Do we show day scale? 1985 2089 function IsDisplayDay() { 1986 1987 } 1988 2090 return $this->day->iShowLabels; 2091 } 2092 1989 2093 // Do we show week scale? 1990 2094 function IsDisplayWeek() { 1991 1992 } 1993 2095 return $this->week->iShowLabels; 2096 } 2097 1994 2098 // Do we show month scale? 1995 2099 function IsDisplayMonth() { 1996 1997 } 1998 2100 return $this->month->iShowLabels; 2101 } 2102 1999 2103 // Do we show year scale? 2000 2104 function IsDisplayYear() { 2001 2105 return $this->year->iShowLabels; 2002 2106 } 2003 2107 2004 2108 // Specify spacing (in percent of bar height) between activity bars 2005 2109 function SetVertSpacing($aSpacing) { 2006 2110 $this->iVertSpacing = $aSpacing; 2007 2111 } 2008 2112 … … 2010 2114 // Always round to the nearest week boundary 2011 2115 function SetRange($aMin,$aMax) { 2012 2013 $this->iEndDate = $this->NormalizeDate($aMax); 2116 $this->iStartDate = $this->NormalizeDate($aMin); 2117 $this->iEndDate = $this->NormalizeDate($aMax); 2014 2118 } 2015 2119 … … 2019 2123 function AdjustStartEndDay() { 2020 2124 2021 2022 2023 2024 2025 2026 2027 2028 $de=strftime("%w",$this->iEndDate); 2029 2030 2031 // if the startdate is "behind" the day the week start at. 2032 // This way we ensure that the given start date is always included 2033 // in the range. If we don't do this the nearest correct weekday in the week 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 if( $preferredEndDay != $de ) { 2045 2046 2047 2048 $this->iEndDate = $adjdate; 2049 } 2050 } 2051 2052 // Specify background for the table title area (upper left corner of the table) 2125 if( !($this->IsDisplayYear() ||$this->IsDisplayMonth() || $this->IsDisplayWeek()) ) { 2126 // Don't adjust 2127 return; 2128 } 2129 2130 // Get day in week for start and ending date (Sun==0) 2131 $ds=strftime("%w",$this->iStartDate); 2132 $de=strftime("%w",$this->iEndDate); 2133 2134 // We want to start on iWeekStart day. But first we subtract a week 2135 // if the startdate is "behind" the day the week start at. 2136 // This way we ensure that the given start date is always included 2137 // in the range. If we don't do this the nearest correct weekday in the week 2138 // to start at might be later than the start date. 2139 if( $ds < $this->iWeekStart ) 2140 $d = strtotime('-7 day',$this->iStartDate); 2141 else 2142 $d = $this->iStartDate; 2143 $adjdate = strtotime(($this->iWeekStart-$ds).' day',$d /*$this->iStartDate*/ ); 2144 $this->iStartDate = $adjdate; 2145 2146 // We want to end on the last day of the week 2147 $preferredEndDay = ($this->iWeekStart+6)%7; 2148 if( $preferredEndDay != $de ) { 2149 // Solve equivalence eq: $de + x ~ $preferredDay (mod 7) 2150 $adj = (7+($preferredEndDay - $de)) % 7; 2151 $adjdate = strtotime("+$adj day",$this->iEndDate); 2152 $this->iEndDate = $adjdate; 2153 } 2154 } 2155 2156 // Specify background for the table title area (upper left corner of the table) 2053 2157 function SetTableTitleBackground($aColor) { 2054 2055 } 2056 2057 ///////////////////////////////////////2058 // PRIVATE Methods2059 2158 $this->iTableHeaderBackgroundColor = $aColor; 2159 } 2160 2161 /////////////////////////////////////// 2162 // PRIVATE Methods 2163 2060 2164 // Determine the height of all the scale headers combined 2061 2165 function GetHeaderHeight() { 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 } 2090 2166 $img=$this->iImg; 2167 $height=1; 2168 if( $this->minute->iShowLabels ) { 2169 $height += $this->minute->GetFontHeight($img); 2170 $height += $this->minute->iTitleVertMargin; 2171 } 2172 if( $this->hour->iShowLabels ) { 2173 $height += $this->hour->GetFontHeight($img); 2174 $height += $this->hour->iTitleVertMargin; 2175 } 2176 if( $this->day->iShowLabels ) { 2177 $height += $this->day->GetFontHeight($img); 2178 $height += $this->day->iTitleVertMargin; 2179 } 2180 if( $this->week->iShowLabels ) { 2181 $height += $this->week->GetFontHeight($img); 2182 $height += $this->week->iTitleVertMargin; 2183 } 2184 if( $this->month->iShowLabels ) { 2185 $height += $this->month->GetFontHeight($img); 2186 $height += $this->month->iTitleVertMargin; 2187 } 2188 if( $this->year->iShowLabels ) { 2189 $height += $this->year->GetFontHeight($img); 2190 $height += $this->year->iTitleVertMargin; 2191 } 2192 return $height; 2193 } 2194 2091 2195 // Get width (in pixels) for a single day 2092 2196 function GetDayWidth() { 2093 return ($this->GetPlotWidth()-$this->iLabelWidth+1)/$this->GetNumberOfDays(); 2197 return ($this->GetPlotWidth()-$this->iLabelWidth+1)/$this->GetNumberOfDays(); 2094 2198 } 2095 2199 2096 2200 // Get width (in pixels) for a single hour 2097 2201 function GetHourWidth() { 2098 2202 return $this->GetDayWidth() / 24 ; 2099 2203 } 2100 2204 2101 2205 function GetMinuteWidth() { 2102 2206 return $this->GetHourWidth() / 60 ; 2103 2207 } 2104 2208 2105 2209 // Nuber of days in a year 2106 2210 function GetNumDaysInYear($aYear) { 2107 2108 2109 2110 2111 } 2112 2113 // Get week number 2211 if( $this->IsLeap($aYear) ) 2212 return 366; 2213 else 2214 return 365; 2215 } 2216 2217 // Get week number 2114 2218 function GetWeekNbr($aDate,$aSunStart=true) { 2115 2116 2117 2118 2119 2120 2121 2122 2123 // version of Week Nbr calculation. 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 } 2149 2219 // We can't use the internal strftime() since it gets the weeknumber 2220 // wrong since it doesn't follow ISO on all systems since this is 2221 // system linrary dependent. 2222 // Even worse is that this works differently if we are on a Windows 2223 // or UNIX box (it even differs between UNIX boxes how strftime() 2224 // is natively implemented) 2225 // 2226 // Credit to Nicolas Hoizey <nhoizey@phpheaven.net> for this elegant 2227 // version of Week Nbr calculation. 2228 2229 $day = $this->NormalizeDate($aDate); 2230 if( $aSunStart ) 2231 $day += 60*60*24; 2232 2233 /*------------------------------------------------------------------------- 2234 According to ISO-8601 : 2235 "Week 01 of a year is per definition the first week that has the Thursday in this year, 2236 which is equivalent to the week that contains the fourth day of January. 2237 In other words, the first week of a new year is the week that has the majority of its 2238 days in the new year." 2239 2240 Be carefull, with PHP, -3 % 7 = -3, instead of 4 !!! 2241 2242 day of year = date("z", $day) + 1 2243 offset to thursday = 3 - (date("w", $day) + 6) % 7 2244 first thursday of year = 1 + (11 - date("w", mktime(0, 0, 0, 1, 1, date("Y", $day)))) % 7 2245 week number = (thursday's day of year - first thursday's day of year) / 7 + 1 2246 ---------------------------------------------------------------------------*/ 2247 2248 $thursday = $day + 60 * 60 * 24 * (3 - (date("w", $day) + 6) % 7); // take week's thursday 2249 $week = 1 + (date("z", $thursday) - (11 - date("w", mktime(0, 0, 0, 1, 1, date("Y", $thursday)))) % 7) / 7; 2250 2251 return $week; 2252 } 2253 2150 2254 // Is year a leap year? 2151 2255 function IsLeap($aYear) { 2152 2153 2154 2155 2156 2157 2256 // Is the year a leap year? 2257 //$year = 0+date("Y",$aDate); 2258 if( $aYear % 4 == 0) 2259 if( !($aYear % 100 == 0) || ($aYear % 400 == 0) ) 2260 return true; 2261 return false; 2158 2262 } 2159 2263 2160 2264 // Get current year 2161 2265 function GetYear($aDate) { 2162 2163 } 2164 2266 return 0+Date("Y",$aDate); 2267 } 2268 2165 2269 // Return number of days in a year 2166 2270 function GetNumDaysInMonth($aMonth,$aYear) { 2167 2168 2169 2170 2171 2172 2173 } 2174 2271 $days=array(31,28,31,30,31,30,31,31,30,31,30,31); 2272 $daysl=array(31,29,31,30,31,30,31,31,30,31,30,31); 2273 if( $this->IsLeap($aYear)) 2274 return $daysl[$aMonth]; 2275 else 2276 return $days[$aMonth]; 2277 } 2278 2175 2279 // Get day in month 2176 2280 function GetMonthDayNbr($aDate) { 2177 2281 return 0+strftime("%d",$aDate); 2178 2282 } 2179 2283 2180 2284 // Get day in year 2181 2285 function GetYearDayNbr($aDate) { 2182 2183 } 2184 2286 return 0+strftime("%j",$aDate); 2287 } 2288 2185 2289 // Get month number 2186 2290 function GetMonthNbr($aDate) { 2187 2188 } 2189 2190 // Translate a date to screen coordinates 2291 return 0+strftime("%m",$aDate); 2292 } 2293 2294 // Translate a date to screen coordinates (horizontal scale) 2191 2295 function TranslateDate($aDate) { 2192 // 2193 // In order to handle the problem with Daylight savings time 2194 // the scale written with equal number of seconds per day beginning 2195 // with the start date. This means that we "cement" the state of 2196 // DST as it is in the start date. If later the scale includes the 2197 // switchover date (depends on the locale) we need to adjust back 2198 // if the date we try to translate has a different DST status since 2199 // we would otherwise be off by one hour. 2200 $aDate = $this->NormalizeDate($aDate); 2201 $tmp = localtime($aDate); 2202 $cloc = $tmp[8]; 2203 $tmp = localtime($this->iStartDate); 2204 $sloc = $tmp[8]; 2205 $offset = 0; 2206 if( $sloc != $cloc) { 2207 if( $sloc ) 2208 $offset = 3600; 2209 else 2210 $offset = -3600; 2211 } 2212 $img=$this->iImg; 2213 return ($aDate-$this->iStartDate-$offset)/SECPERDAY*$this->GetDayWidth()+$img->left_margin+$this->iLabelWidth;; 2214 } 2215 2216 // Get screen coordinatesz for the vertical position for a bar 2217 function TranslateVertPos($aPos) { 2218 $img=$this->iImg; 2219 $ph=$this->iAvailableHeight; 2220 if( $aPos > $this->iVertLines ) 2221 JpGraphError::RaiseL(6015,$aPos); 2222 // 'Illegal vertical position %d' 2223 if( $this->iVertLayout == GANTT_EVEN ) { 2224 // Position the top bar at 1 vert spacing from the scale 2225 return round($img->top_margin + $this->iVertHeaderSize + ($aPos+1)*$this->iVertSpacing); 2226 } 2227 else { 2228 // position the top bar at 1/2 a vert spacing from the scale 2229 return round($img->top_margin + $this->iVertHeaderSize + $this->iTopPlotMargin + ($aPos+1)*$this->iVertSpacing); 2230 } 2231 } 2232 2296 // 2297 // In order to handle the problem with Daylight savings time 2298 // the scale written with equal number of seconds per day beginning 2299 // with the start date. This means that we "cement" the state of 2300 // DST as it is in the start date. If later the scale includes the 2301 // switchover date (depends on the locale) we need to adjust back 2302 // if the date we try to translate has a different DST status since 2303 // we would otherwise be off by one hour. 2304 $aDate = $this->NormalizeDate($aDate); 2305 $tmp = localtime($aDate); 2306 $cloc = $tmp[8]; 2307 $tmp = localtime($this->iStartDate); 2308 $sloc = $tmp[8]; 2309 $offset = 0; 2310 if( $sloc != $cloc) { 2311 if( $sloc ) 2312 $offset = 3600; 2313 else 2314 $offset = -3600; 2315 } 2316 $img=$this->iImg; 2317 return ($aDate-$this->iStartDate-$offset)/SECPERDAY*$this->GetDayWidth()+$img->left_margin+$this->iLabelWidth;; 2318 } 2319 2320 // Get screen coordinatesz for the vertical position for a bar 2321 function TranslateVertPos($aPos,$atTop=false) { 2322 $img=$this->iImg; 2323 if( $aPos > $this->iVertLines ) 2324 JpGraphError::RaiseL(6015,$aPos); 2325 // 'Illegal vertical position %d' 2326 if( $this->iVertLayout == GANTT_EVEN ) { 2327 // Position the top bar at 1 vert spacing from the scale 2328 $pos = round($img->top_margin + $this->iVertHeaderSize + ($aPos+1)*$this->iVertSpacing); 2329 } 2330 else { 2331 // position the top bar at 1/2 a vert spacing from the scale 2332 $pos = round($img->top_margin + $this->iVertHeaderSize + $this->iTopPlotMargin + ($aPos+1)*$this->iVertSpacing); 2333 } 2334 2335 if( $atTop ) 2336 $pos -= $this->iVertSpacing; 2337 2338 return $pos; 2339 } 2340 2233 2341 // What is the vertical spacing? 2234 2342 function GetVertSpacing() { 2235 2236 } 2237 2343 return $this->iVertSpacing; 2344 } 2345 2238 2346 // Convert a date to timestamp 2239 2347 function NormalizeDate($aDate) { 2240 if( $aDate === false ) return false; 2241 2242 2243 2244 2245 //("Date string ($aDate) specified for Gantt activity can not be interpretated. Please make sure it is a valid time string, e.g. 2005-04-23 13:30");2246 2247 2248 2249 2250 2251 2252 2253 //Unknown date format in GanttScale ($aDate).");2254 } 2255 2256 2348 if( $aDate === false ) return false; 2349 if( is_string($aDate) ) { 2350 $t = strtotime($aDate); 2351 if( $t === FALSE || $t === -1 ) { 2352 JpGraphError::RaiseL(6016,$aDate); 2353 //("Date string ($aDate) specified for Gantt activity can not be interpretated. Please make sure it is a valid time string, e.g. 2005-04-23 13:30"); 2354 } 2355 return $t; 2356 } 2357 elseif( is_int($aDate) || is_float($aDate) ) 2358 return $aDate; 2359 else 2360 JpGraphError::RaiseL(6017,$aDate); 2361 //Unknown date format in GanttScale ($aDate)."); 2362 } 2363 2364 2257 2365 // Convert a time string to minutes 2258 2366 2259 2367 function TimeToMinutes($aTimeString) { 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 } 2274 2275 // Stroke the day scale (including gridlines) 2368 // Split in hours and minutes 2369 $pos=strpos($aTimeString,':'); 2370 $minint=60; 2371 if( $pos === false ) { 2372 $hourint = $aTimeString; 2373 $minint = 0; 2374 } 2375 else { 2376 $hourint = floor(substr($aTimeString,0,$pos)); 2377 $minint = floor(substr($aTimeString,$pos+1)); 2378 } 2379 $minint += 60 * $hourint; 2380 return $minint; 2381 } 2382 2383 // Stroke the day scale (including gridlines) 2276 2384 function StrokeMinutes($aYCoord,$getHeight=false) { 2277 $img=$this->iImg; 2278 2279 $yt=$aYCoord+$img->top_margin; 2280 2281 2282 $yb = $yt + $img->GetFontHeight() + 2283 2284 2285 2286 2287 2288 2289 2290 2291 $x = $xt; 2292 2293 2294 2295 2296 if( 60 % $minint !== 0 ) { 2385 $img=$this->iImg; 2386 $xt=$img->left_margin+$this->iLabelWidth; 2387 $yt=$aYCoord+$img->top_margin; 2388 if( $this->minute->iShowLabels ) { 2389 $img->SetFont($this->minute->iFFamily,$this->minute->iFStyle,$this->minute->iFSize); 2390 $yb = $yt + $img->GetFontHeight() + 2391 $this->minute->iTitleVertMargin + $this->minute->iFrameWeight; 2392 if( $getHeight ) { 2393 return $yb - $img->top_margin; 2394 } 2395 $xb = $img->width-$img->right_margin+1; 2396 $img->SetColor($this->minute->iBackgroundColor); 2397 $img->FilledRectangle($xt,$yt,$xb,$yb); 2398 2399 $x = $xt; 2400 $img->SetTextAlign("center"); 2401 $day = date('w',$this->iStartDate); 2402 $minint = $this->minute->GetIntervall() ; 2403 2404 if( 60 % $minint !== 0 ) { 2297 2405 JpGraphError::RaiseL(6018,$minint); 2298 //'Intervall for minutes must divide the hour evenly, e.g. 1,5,10,12,15,20,30 etc You have specified an intervall of '.$minint.' minutes.'); 2299 } 2300 2301 2302 $n = 60 / $minint; 2303 $datestamp = $this->iStartDate; 2304 $width = $this->GetHourWidth() / $n ; 2305 if( $width < 8 ) { 2306 // TO small width to draw minute scale 2307 JpGraphError::RaiseL(6019,$width); 2308 //('The available width ('.$width.') for minutes are to small for this scale to be displayed. Please use auto-sizing or increase the width of the graph.'); 2309 } 2310 2311 $nh = ceil(24*60 / $this->TimeToMinutes($this->hour->GetIntervall()) ); 2312 $nd = $this->GetNumberOfDays(); 2313 // Convert to intervall to seconds 2314 $minint *= 60; 2315 for($j=0; $j < $nd; ++$j, $day += 1, $day %= 7) { 2316 for( $k=0; $k < $nh; ++$k ) { 2317 for($i=0; $i < $n ;++$i, $x+=$width, $datestamp += $minint ) { 2318 if( $day==6 || $day==0 ) { 2319 2320 $img->PushColor($this->day->iWeekendBackgroundColor); 2321 if( $this->iUsePlotWeekendBackground ) 2322 $img->FilledRectangle($x,$yt+$this->day->iFrameWeight,$x+$width,$img->height-$img->bottom_margin); 2323 else 2324 $img->FilledRectangle($x,$yt+$this->day->iFrameWeight,$x+$width,$yb-$this->day->iFrameWeight); 2325 $img->PopColor(); 2326 2327 } 2328 2329 if( $day==0 ) 2330 $img->SetColor($this->day->iSundayTextColor); 2331 else 2332 $img->SetColor($this->day->iTextColor); 2333 2334 switch( $this->minute->iStyle ) { 2335 case MINUTESTYLE_CUSTOM: 2336 $txt = date($this->minute->iLabelFormStr,$datestamp); 2337 break; 2338 case MINUTESTYLE_MM: 2339 default: 2340 // 15 2341 $txt = date('i',$datestamp); 2342 break; 2343 } 2344 $img->StrokeText(round($x+$width/2),round($yb-$this->minute->iTitleVertMargin),$txt); 2345 2346 // FIXME: The rounding problem needs to be solved properly ... 2347 // 2348 // Fix a rounding problem the wrong way .. 2349 // If we also have hour scale then don't draw the firsta or last 2350 // gridline since that will be overwritten by the hour scale gridline if such exists. 2351 // However, due to the propagation of rounding of the 'x+=width' term in the loop 2352 // this might sometimes be one pixel of so we fix this by not drawing it. 2353 // The proper way to fix it would be to re-calculate the scale for each step and 2354 // not using the additive term. 2355 if( !(($i == $n || $i==0) && $this->hour->iShowLabels && $this->hour->grid->iShow) ) { 2356 $img->SetColor($this->minute->grid->iColor); 2357 $img->SetLineWeight($this->minute->grid->iWeight); 2358 $img->Line($x,$yt,$x,$yb); 2359 $this->minute->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin); 2360 } 2361 } 2362 } 2363 } 2364 $img->SetColor($this->minute->iFrameColor); 2365 $img->SetLineWeight($this->minute->iFrameWeight); 2366 $img->Rectangle($xt,$yt,$xb,$yb); 2367 return $yb - $img->top_margin; 2368 } 2369 return $aYCoord; 2370 } 2371 2372 // Stroke the day scale (including gridlines) 2406 //'Intervall for minutes must divide the hour evenly, e.g. 1,5,10,12,15,20,30 etc You have specified an intervall of '.$minint.' minutes.'); 2407 } 2408 2409 2410 $n = 60 / $minint; 2411 $datestamp = $this->iStartDate; 2412 $width = $this->GetHourWidth() / $n ; 2413 if( $width < 8 ) { 2414 // TO small width to draw minute scale 2415 JpGraphError::RaiseL(6019,$width); 2416 //('The available width ('.$width.') for minutes are to small for this scale to be displayed. Please use auto-sizing or increase the width of the graph.'); 2417 } 2418 2419 $nh = ceil(24*60 / $this->TimeToMinutes($this->hour->GetIntervall()) ); 2420 $nd = $this->GetNumberOfDays(); 2421 // Convert to intervall to seconds 2422 $minint *= 60; 2423 for($j=0; $j < $nd; ++$j, $day += 1, $day %= 7) { 2424 for( $k=0; $k < $nh; ++$k ) { 2425 for($i=0; $i < $n ;++$i, $x+=$width, $datestamp += $minint ) { 2426 if( $day==6 || $day==0 ) { 2427 2428 $img->PushColor($this->day->iWeekendBackgroundColor); 2429 if( $this->iUsePlotWeekendBackground ) 2430 $img->FilledRectangle($x,$yt+$this->day->iFrameWeight,$x+$width,$img->height-$img->bottom_margin); 2431 else 2432 $img->FilledRectangle($x,$yt+$this->day->iFrameWeight,$x+$width,$yb-$this->day->iFrameWeight); 2433 $img->PopColor(); 2434 2435 } 2436 2437 if( $day==0 ) 2438 $img->SetColor($this->day->iSundayTextColor); 2439 else 2440 $img->SetColor($this->day->iTextColor); 2441 2442 switch( $this->minute->iStyle ) { 2443 case MINUTESTYLE_CUSTOM: 2444 $txt = date($this->minute->iLabelFormStr,$datestamp); 2445 break; 2446 case MINUTESTYLE_MM: 2447 default: 2448 // 15 2449 $txt = date('i',$datestamp); 2450 break; 2451 } 2452 $img->StrokeText(round($x+$width/2),round($yb-$this->minute->iTitleVertMargin),$txt); 2453 2454 // Fix a rounding problem the wrong way .. 2455 // If we also have hour scale then don't draw the firsta or last 2456 // gridline since that will be overwritten by the hour scale gridline if such exists. 2457 // However, due to the propagation of rounding of the 'x+=width' term in the loop 2458 // this might sometimes be one pixel of so we fix this by not drawing it. 2459 // The proper way to fix it would be to re-calculate the scale for each step and 2460 // not using the additive term. 2461 if( !(($i == $n || $i==0) && $this->hour->iShowLabels && $this->hour->grid->iShow) ) { 2462 $img->SetColor($this->minute->grid->iColor); 2463 $img->SetLineWeight($this->minute->grid->iWeight); 2464 $img->Line($x,$yt,$x,$yb); 2465 $this->minute->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin); 2466 } 2467 } 2468 } 2469 } 2470 $img->SetColor($this->minute->iFrameColor); 2471 $img->SetLineWeight($this->minute->iFrameWeight); 2472 $img->Rectangle($xt,$yt,$xb,$yb); 2473 return $yb - $img->top_margin; 2474 } 2475 return $aYCoord; 2476 } 2477 2478 // Stroke the day scale (including gridlines) 2373 2479 function StrokeHours($aYCoord,$getHeight=false) { 2374 $img=$this->iImg; 2375 2376 $yt=$aYCoord+$img->top_margin; 2377 2378 2379 $yb = $yt + $img->GetFontHeight() + 2380 2381 2382 2383 2384 2385 2386 2387 2388 $x = $xt; 2389 2390 2391 2392 if( 1440 % $minint !== 0 ) { 2480 $img=$this->iImg; 2481 $xt=$img->left_margin+$this->iLabelWidth; 2482 $yt=$aYCoord+$img->top_margin; 2483 if( $this->hour->iShowLabels ) { 2484 $img->SetFont($this->hour->iFFamily,$this->hour->iFStyle,$this->hour->iFSize); 2485 $yb = $yt + $img->GetFontHeight() + 2486 $this->hour->iTitleVertMargin + $this->hour->iFrameWeight; 2487 if( $getHeight ) { 2488 return $yb - $img->top_margin; 2489 } 2490 $xb = $img->width-$img->right_margin+1; 2491 $img->SetColor($this->hour->iBackgroundColor); 2492 $img->FilledRectangle($xt,$yt,$xb,$yb); 2493 2494 $x = $xt; 2495 $img->SetTextAlign("center"); 2496 $tmp = $this->hour->GetIntervall() ; 2497 $minint = $this->TimeToMinutes($tmp); 2498 if( 1440 % $minint !== 0 ) { 2393 2499 JpGraphError::RaiseL(6020,$tmp); 2394 //('Intervall for hours must divide the day evenly, e.g. 0:30, 1:00, 1:30, 4:00 etc. You have specified an intervall of '.$tmp);2395 } 2396 2397 2398 2399 2400 2401 2402 2403 for($i=0; $i < $n ;++$i, $x+=$width) { 2404 2405 2406 2407 2408 $img->FilledRectangle($x,$yt+$this->day->iFrameWeight,$x+$width,$img->height-$img->bottom_margin); 2409 2410 2411 2412 2413 2414 2415 if( $day==0 ) 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 } 2450 2451 2452 2453 2454 2455 2456 2457 } 2458 2459 2460 // Stroke the day scale (including gridlines) 2500 //('Intervall for hours must divide the day evenly, e.g. 0:30, 1:00, 1:30, 4:00 etc. You have specified an intervall of '.$tmp); 2501 } 2502 2503 $n = ceil(24*60 / $minint ); 2504 $datestamp = $this->iStartDate; 2505 $day = date('w',$this->iStartDate); 2506 $doback = !$this->minute->iShowLabels; 2507 $width = $this->GetDayWidth() / $n ; 2508 for($j=0; $j < $this->GetNumberOfDays(); ++$j, $day += 1,$day %= 7) { 2509 for($i=0; $i < $n ;++$i, $x+=$width) { 2510 if( $day==6 || $day==0 ) { 2511 2512 $img->PushColor($this->day->iWeekendBackgroundColor); 2513 if( $this->iUsePlotWeekendBackground && $doback ) 2514 $img->FilledRectangle($x,$yt+$this->day->iFrameWeight,$x+$width,$img->height-$img->bottom_margin); 2515 else 2516 $img->FilledRectangle($x,$yt+$this->day->iFrameWeight,$x+$width,$yb-$this->day->iFrameWeight); 2517 $img->PopColor(); 2518 2519 } 2520 2521 if( $day==0 ) 2522 $img->SetColor($this->day->iSundayTextColor); 2523 else 2524 $img->SetColor($this->day->iTextColor); 2525 2526 switch( $this->hour->iStyle ) { 2527 case HOURSTYLE_HMAMPM: 2528 // 1:35pm 2529 $txt = date('g:ia',$datestamp); 2530 break; 2531 case HOURSTYLE_H24: 2532 // 13 2533 $txt = date('H',$datestamp); 2534 break; 2535 case HOURSTYLE_HAMPM: 2536 $txt = date('ga',$datestamp); 2537 break; 2538 case HOURSTYLE_CUSTOM: 2539 $txt = date($this->hour->iLabelFormStr,$datestamp); 2540 break; 2541 case HOURSTYLE_HM24: 2542 default: 2543 $txt = date('H:i',$datestamp); 2544 break; 2545 } 2546 $img->StrokeText(round($x+$width/2),round($yb-$this->hour->iTitleVertMargin),$txt); 2547 $img->SetColor($this->hour->grid->iColor); 2548 $img->SetLineWeight($this->hour->grid->iWeight); 2549 $img->Line($x,$yt,$x,$yb); 2550 $this->hour->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin); 2551 //$datestamp += $minint*60 2552 $datestamp = mktime(date('H',$datestamp),date('i',$datestamp)+$minint,0, 2553 date("m",$datestamp),date("d",$datestamp)+1,date("Y",$datestamp)); 2554 2555 } 2556 } 2557 $img->SetColor($this->hour->iFrameColor); 2558 $img->SetLineWeight($this->hour->iFrameWeight); 2559 $img->Rectangle($xt,$yt,$xb,$yb); 2560 return $yb - $img->top_margin; 2561 } 2562 return $aYCoord; 2563 } 2564 2565 2566 // Stroke the day scale (including gridlines) 2461 2567 function StrokeDays($aYCoord,$getHeight=false) { 2462 $img=$this->iImg; 2463 2464 2465 $yt=$aYCoord+$img->top_margin; 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 $x = $xt; 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 $x+$daywidth,$img->height-$img->bottom_margin); 2491 2492 2493 2494 2495 2496 2497 if( $mn[0]=='0' ) 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 break; 2533 2534 2535 2536 break; 2537 2538 2539 2540 break; 2541 2542 2543 2544 break; 2545 2546 2547 2548 break; 2549 2550 2551 2552 2553 2554 2555 2556 2557 if( $day==0 ) 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 } 2571 2572 2573 2574 2575 2576 2577 } 2578 2568 $img=$this->iImg; 2569 $daywidth=$this->GetDayWidth(); 2570 $xt=$img->left_margin+$this->iLabelWidth; 2571 $yt=$aYCoord+$img->top_margin; 2572 if( $this->day->iShowLabels ) { 2573 $img->SetFont($this->day->iFFamily,$this->day->iFStyle,$this->day->iFSize); 2574 $yb=$yt + $img->GetFontHeight() + $this->day->iTitleVertMargin + $this->day->iFrameWeight; 2575 if( $getHeight ) { 2576 return $yb - $img->top_margin; 2577 } 2578 $xb=$img->width-$img->right_margin+1; 2579 $img->SetColor($this->day->iBackgroundColor); 2580 $img->FilledRectangle($xt,$yt,$xb,$yb); 2581 2582 $x = $xt; 2583 $img->SetTextAlign("center"); 2584 $day = date('w',$this->iStartDate); 2585 $datestamp = $this->iStartDate; 2586 2587 $doback = !($this->hour->iShowLabels || $this->minute->iShowLabels); 2588 2589 setlocale(LC_TIME,$this->iDateLocale->iLocale); 2590 2591 for($i=0; $i < $this->GetNumberOfDays(); ++$i, $x+=$daywidth, $day += 1,$day %= 7) { 2592 if( $day==6 || $day==0 ) { 2593 $img->SetColor($this->day->iWeekendBackgroundColor); 2594 if( $this->iUsePlotWeekendBackground && $doback) 2595 $img->FilledRectangle($x,$yt+$this->day->iFrameWeight, 2596 $x+$daywidth,$img->height-$img->bottom_margin); 2597 else 2598 $img->FilledRectangle($x,$yt+$this->day->iFrameWeight, 2599 $x+$daywidth,$yb-$this->day->iFrameWeight); 2600 } 2601 2602 $mn = strftime('%m',$datestamp); 2603 if( $mn[0]=='0' ) 2604 $mn = $mn[1]; 2605 2606 switch( $this->day->iStyle ) { 2607 case DAYSTYLE_LONG: 2608 // "Monday" 2609 $txt = strftime('%A',$datestamp); 2610 break; 2611 case DAYSTYLE_SHORT: 2612 // "Mon" 2613 $txt = strftime('%a',$datestamp); 2614 break; 2615 case DAYSTYLE_SHORTDAYDATE1: 2616 // "Mon 23/6" 2617 $txt = strftime('%a %d/'.$mn,$datestamp); 2618 break; 2619 case DAYSTYLE_SHORTDAYDATE2: 2620 // "Mon 23 Jun" 2621 $txt = strftime('%a %d %b',$datestamp); 2622 break; 2623 case DAYSTYLE_SHORTDAYDATE3: 2624 // "Mon 23 Jun 2003" 2625 $txt = strftime('%a %d %b %Y',$datestamp); 2626 break; 2627 case DAYSTYLE_LONGDAYDATE1: 2628 // "Monday 23 Jun" 2629 $txt = strftime('%A %d %b',$datestamp); 2630 break; 2631 case DAYSTYLE_LONGDAYDATE2: 2632 // "Monday 23 Jun 2003" 2633 $txt = strftime('%A %d %b %Y',$datestamp); 2634 break; 2635 case DAYSTYLE_SHORTDATE1: 2636 // "23/6" 2637 $txt = strftime('%d/'.$mn,$datestamp); 2638 break; 2639 case DAYSTYLE_SHORTDATE2: 2640 // "23 Jun" 2641 $txt = strftime('%d %b',$datestamp); 2642 break; 2643 case DAYSTYLE_SHORTDATE3: 2644 // "Mon 23" 2645 $txt = strftime('%a %d',$datestamp); 2646 break; 2647 case DAYSTYLE_SHORTDATE4: 2648 // "23" 2649 $txt = strftime('%d',$datestamp); 2650 break; 2651 case DAYSTYLE_CUSTOM: 2652 // Custom format 2653 $txt = strftime($this->day->iLabelFormStr,$datestamp); 2654 break; 2655 case DAYSTYLE_ONELETTER: 2656 default: 2657 // "M" 2658 $txt = strftime('%A',$datestamp); 2659 $txt = strtoupper($txt[0]); 2660 break; 2661 } 2662 2663 if( $day==0 ) 2664 $img->SetColor($this->day->iSundayTextColor); 2665 else 2666 $img->SetColor($this->day->iTextColor); 2667 $img->StrokeText(round($x+$daywidth/2+1), 2668 round($yb-$this->day->iTitleVertMargin),$txt); 2669 $img->SetColor($this->day->grid->iColor); 2670 $img->SetLineWeight($this->day->grid->iWeight); 2671 $img->Line($x,$yt,$x,$yb); 2672 $this->day->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin); 2673 $datestamp = mktime(0,0,0,date("m",$datestamp),date("d",$datestamp)+1,date("Y",$datestamp)); 2674 //$datestamp += SECPERDAY; 2675 2676 } 2677 $img->SetColor($this->day->iFrameColor); 2678 $img->SetLineWeight($this->day->iFrameWeight); 2679 $img->Rectangle($xt,$yt,$xb,$yb); 2680 return $yb - $img->top_margin; 2681 } 2682 return $aYCoord; 2683 } 2684 2579 2685 // Stroke week header and grid 2580 2686 function StrokeWeeks($aYCoord,$getHeight=false) { 2581 if( $this->week->iShowLabels ) { 2582 $img=$this->iImg; 2583 $yt=$aYCoord+$img->top_margin; 2584 $img->SetFont($this->week->iFFamily,$this->week->iFStyle,$this->week->iFSize); 2585 $yb=$yt + $img->GetFontHeight() + $this->week->iTitleVertMargin + $this->week->iFrameWeight; 2586 2587 if( $getHeight ) { 2588 return $yb - $img->top_margin; 2589 } 2590 2591 $xt=$img->left_margin+$this->iLabelWidth; 2592 $weekwidth=$this->GetDayWidth()*7; 2593 $wdays=$this->iDateLocale->GetDayAbb(); 2594 $xb=$img->width-$img->right_margin+1; 2595 $week = $this->iStartDate; 2596 $weeknbr=$this->GetWeekNbr($week); 2597 $img->SetColor($this->week->iBackgroundColor); 2598 $img->FilledRectangle($xt,$yt,$xb,$yb); 2599 $img->SetColor($this->week->grid->iColor); 2600 $x = $xt; 2601 if( $this->week->iStyle==WEEKSTYLE_WNBR ) { 2602 $img->SetTextAlign("center"); 2603 $txtOffset = $weekwidth/2+1; 2604 } 2605 elseif( $this->week->iStyle==WEEKSTYLE_FIRSTDAY || 2606 $this->week->iStyle==WEEKSTYLE_FIRSTDAY2 || 2607 $this->week->iStyle==WEEKSTYLE_FIRSTDAYWNBR || 2608 $this->week->iStyle==WEEKSTYLE_FIRSTDAY2WNBR ) { 2609 $img->SetTextAlign("left"); 2610 $txtOffset = 3; 2611 } 2612 else 2613 JpGraphError::RaiseL(6021); 2614 //("Unknown formatting style for week."); 2615 2616 for($i=0; $i<$this->GetNumberOfDays()/7; ++$i, $x+=$weekwidth) { 2617 $img->PushColor($this->week->iTextColor); 2618 2619 if( $this->week->iStyle==WEEKSTYLE_WNBR ) 2620 $txt = sprintf($this->week->iLabelFormStr,$weeknbr); 2621 elseif( $this->week->iStyle==WEEKSTYLE_FIRSTDAY || 2622 $this->week->iStyle==WEEKSTYLE_FIRSTDAYWNBR ) 2623 $txt = date("j/n",$week); 2624 elseif( $this->week->iStyle==WEEKSTYLE_FIRSTDAY2 || 2625 $this->week->iStyle==WEEKSTYLE_FIRSTDAY2WNBR ) { 2626 $monthnbr = date("n",$week)-1; 2627 $shortmonth = $this->iDateLocale->GetShortMonthName($monthnbr); 2628 $txt = Date("j",$week)." ".$shortmonth; 2629 } 2630 2631 if( $this->week->iStyle==WEEKSTYLE_FIRSTDAYWNBR || 2632 $this->week->iStyle==WEEKSTYLE_FIRSTDAY2WNBR ) { 2633 $w = sprintf($this->week->iLabelFormStr,$weeknbr); 2634 $txt .= ' '.$w; 2635 } 2636 2637 $img->StrokeText(round($x+$txtOffset), 2638 round($yb-$this->week->iTitleVertMargin),$txt); 2639 2640 $week = strtotime('+7 day',$week); 2641 $weeknbr = $this->GetWeekNbr($week); 2642 $img->PopColor(); 2643 $img->SetLineWeight($this->week->grid->iWeight); 2644 $img->Line($x,$yt,$x,$yb); 2645 $this->week->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin); 2646 } 2647 $img->SetColor($this->week->iFrameColor); 2648 $img->SetLineWeight($this->week->iFrameWeight); 2649 $img->Rectangle($xt,$yt,$xb,$yb); 2650 return $yb-$img->top_margin; 2651 } 2652 return $aYCoord; 2653 } 2654 2687 if( $this->week->iShowLabels ) { 2688 $img=$this->iImg; 2689 $yt=$aYCoord+$img->top_margin; 2690 $img->SetFont($this->week->iFFamily,$this->week->iFStyle,$this->week->iFSize); 2691 $yb=$yt + $img->GetFontHeight() + $this->week->iTitleVertMargin + $this->week->iFrameWeight; 2692 2693 if( $getHeight ) { 2694 return $yb - $img->top_margin; 2695 } 2696 2697 $xt=$img->left_margin+$this->iLabelWidth; 2698 $weekwidth=$this->GetDayWidth()*7; 2699 $wdays=$this->iDateLocale->GetDayAbb(); 2700 $xb=$img->width-$img->right_margin+1; 2701 $week = $this->iStartDate; 2702 $weeknbr=$this->GetWeekNbr($week); 2703 $img->SetColor($this->week->iBackgroundColor); 2704 $img->FilledRectangle($xt,$yt,$xb,$yb); 2705 $img->SetColor($this->week->grid->iColor); 2706 $x = $xt; 2707 if( $this->week->iStyle==WEEKSTYLE_WNBR ) { 2708 $img->SetTextAlign("center"); 2709 $txtOffset = $weekwidth/2+1; 2710 } 2711 elseif( $this->week->iStyle==WEEKSTYLE_FIRSTDAY || 2712 $this->week->iStyle==WEEKSTYLE_FIRSTDAY2 || 2713 $this->week->iStyle==WEEKSTYLE_FIRSTDAYWNBR || 2714 $this->week->iStyle==WEEKSTYLE_FIRSTDAY2WNBR ) { 2715 $img->SetTextAlign("left"); 2716 $txtOffset = 3; 2717 } 2718 else { 2719 JpGraphError::RaiseL(6021); 2720 //("Unknown formatting style for week."); 2721 } 2722 2723 for($i=0; $i<$this->GetNumberOfDays()/7; ++$i, $x+=$weekwidth) { 2724 $img->PushColor($this->week->iTextColor); 2725 2726 if( $this->week->iStyle==WEEKSTYLE_WNBR ) 2727 $txt = sprintf($this->week->iLabelFormStr,$weeknbr); 2728 elseif( $this->week->iStyle==WEEKSTYLE_FIRSTDAY || 2729 $this->week->iStyle==WEEKSTYLE_FIRSTDAYWNBR ) 2730 $txt = date("j/n",$week); 2731 elseif( $this->week->iStyle==WEEKSTYLE_FIRSTDAY2 || 2732 $this->week->iStyle==WEEKSTYLE_FIRSTDAY2WNBR ) { 2733 $monthnbr = date("n",$week)-1; 2734 $shortmonth = $this->iDateLocale->GetShortMonthName($monthnbr); 2735 $txt = Date("j",$week)." ".$shortmonth; 2736 } 2737 2738 if( $this->week->iStyle==WEEKSTYLE_FIRSTDAYWNBR || 2739 $this->week->iStyle==WEEKSTYLE_FIRSTDAY2WNBR ) { 2740 $w = sprintf($this->week->iLabelFormStr,$weeknbr); 2741 $txt .= ' '.$w; 2742 } 2743 2744 $img->StrokeText(round($x+$txtOffset), 2745 round($yb-$this->week->iTitleVertMargin),$txt); 2746 2747 $week = strtotime('+7 day',$week); 2748 $weeknbr = $this->GetWeekNbr($week); 2749 $img->PopColor(); 2750 $img->SetLineWeight($this->week->grid->iWeight); 2751 $img->Line($x,$yt,$x,$yb); 2752 $this->week->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin); 2753 } 2754 $img->SetColor($this->week->iFrameColor); 2755 $img->SetLineWeight($this->week->iFrameWeight); 2756 $img->Rectangle($xt,$yt,$xb,$yb); 2757 return $yb-$img->top_margin; 2758 } 2759 return $aYCoord; 2760 } 2761 2655 2762 // Format the mont scale header string 2656 2763 function GetMonthLabel($aMonthNbr,$year) { 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 } 2684 2764 $sn = $this->iDateLocale->GetShortMonthName($aMonthNbr); 2765 $ln = $this->iDateLocale->GetLongMonthName($aMonthNbr); 2766 switch($this->month->iStyle) { 2767 case MONTHSTYLE_SHORTNAME: 2768 $m=$sn; 2769 break; 2770 case MONTHSTYLE_LONGNAME: 2771 $m=$ln; 2772 break; 2773 case MONTHSTYLE_SHORTNAMEYEAR2: 2774 $m=$sn." '".substr("".$year,2); 2775 break; 2776 case MONTHSTYLE_SHORTNAMEYEAR4: 2777 $m=$sn." ".$year; 2778 break; 2779 case MONTHSTYLE_LONGNAMEYEAR2: 2780 $m=$ln." '".substr("".$year,2); 2781 break; 2782 case MONTHSTYLE_LONGNAMEYEAR4: 2783 $m=$ln." ".$year; 2784 break; 2785 case MONTHSTYLE_FIRSTLETTER: 2786 $m=$sn[0]; 2787 break; 2788 } 2789 return $m; 2790 } 2791 2685 2792 // Stroke month scale and gridlines 2686 2793 function StrokeMonths($aYCoord,$getHeight=false) { 2687 2688 $img=$this->iImg; 2689 2690 $yt=$aYCoord+$img->top_margin; 2691 2692 2693 return $yb - $img->top_margin; 2694 2695 $monthnbr = $this->GetMonthNbr($this->iStartDate)-1; 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 if( $this->GetMonthNbr($this->iStartDate) == $this->GetMonthNbr($this->iEndDate) 2707 2708 2709 } 2710 2711 2712 2713 2714 2715 2716 $img->SetColor($this->month->iTextColor); 2717 2718 2719 2720 2721 2722 2723 $img->SetColor($this->month->grid->iColor); 2724 2725 2726 2727 2728 2729 2730 2731 2732 $monthwidth=$this->GetDayWidth()*$this->GetNumDaysInMonth($monthnbr,$year); 2733 2734 2735 2736 2737 2738 $img->SetColor($this->month->iTextColor); 2739 2740 2741 2742 2743 } 2744 2745 2746 $img->Rectangle($xt,$yt,$xb,$yb); 2747 2748 2749 2794 if( $this->month->iShowLabels ) { 2795 $img=$this->iImg; 2796 $img->SetFont($this->month->iFFamily,$this->month->iFStyle,$this->month->iFSize); 2797 $yt=$aYCoord+$img->top_margin; 2798 $yb=$yt + $img->GetFontHeight() + $this->month->iTitleVertMargin + $this->month->iFrameWeight; 2799 if( $getHeight ) { 2800 return $yb - $img->top_margin; 2801 } 2802 $monthnbr = $this->GetMonthNbr($this->iStartDate)-1; 2803 $xt=$img->left_margin+$this->iLabelWidth; 2804 $xb=$img->width-$img->right_margin+1; 2805 2806 $img->SetColor($this->month->iBackgroundColor); 2807 $img->FilledRectangle($xt,$yt,$xb,$yb); 2808 2809 $img->SetLineWeight($this->month->grid->iWeight); 2810 $img->SetColor($this->month->iTextColor); 2811 $year = 0+strftime("%Y",$this->iStartDate); 2812 $img->SetTextAlign("center"); 2813 if( $this->GetMonthNbr($this->iStartDate) == $this->GetMonthNbr($this->iEndDate) 2814 && $this->GetYear($this->iStartDate)==$this->GetYear($this->iEndDate) ) { 2815 $monthwidth=$this->GetDayWidth()*($this->GetMonthDayNbr($this->iEndDate) - $this->GetMonthDayNbr($this->iStartDate) + 1); 2816 } 2817 else { 2818 $monthwidth=$this->GetDayWidth()*($this->GetNumDaysInMonth($monthnbr,$year)-$this->GetMonthDayNbr($this->iStartDate)+1); 2819 } 2820 // Is it enough space to stroke the first month? 2821 $monthName = $this->GetMonthLabel($monthnbr,$year); 2822 if( $monthwidth >= 1.2*$img->GetTextWidth($monthName) ) { 2823 $img->SetColor($this->month->iTextColor); 2824 $img->StrokeText(round($xt+$monthwidth/2+1), 2825 round($yb-$this->month->iTitleVertMargin), 2826 $monthName); 2827 } 2828 $x = $xt + $monthwidth; 2829 while( $x < $xb ) { 2830 $img->SetColor($this->month->grid->iColor); 2831 $img->Line($x,$yt,$x,$yb); 2832 $this->month->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin); 2833 $monthnbr++; 2834 if( $monthnbr==12 ) { 2835 $monthnbr=0; 2836 $year++; 2837 } 2838 $monthName = $this->GetMonthLabel($monthnbr,$year); 2839 $monthwidth=$this->GetDayWidth()*$this->GetNumDaysInMonth($monthnbr,$year); 2840 if( $x + $monthwidth < $xb ) 2841 $w = $monthwidth; 2842 else 2843 $w = $xb-$x; 2844 if( $w >= 1.2*$img->GetTextWidth($monthName) ) { 2845 $img->SetColor($this->month->iTextColor); 2846 $img->StrokeText(round($x+$w/2+1), 2847 round($yb-$this->month->iTitleVertMargin),$monthName); 2848 } 2849 $x += $monthwidth; 2850 } 2851 $img->SetColor($this->month->iFrameColor); 2852 $img->SetLineWeight($this->month->iFrameWeight); 2853 $img->Rectangle($xt,$yt,$xb,$yb); 2854 return $yb-$img->top_margin; 2855 } 2856 return $aYCoord; 2750 2857 } 2751 2858 2752 2859 // Stroke year scale and gridlines 2753 2860 function StrokeYears($aYCoord,$getHeight=false) { 2754 2755 $img=$this->iImg; 2756 $yt=$aYCoord+$img->top_margin; 2757 2758 2759 2760 2761 return $yb - $img->top_margin; 2762 2763 2764 2765 2766 $year = $this->GetYear($this->iStartDate); 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 // The space for a year must be at least 20% bigger than the actual text 2777 2778 2779 $img->SetColor($this->year->iTextColor); 2780 2781 2782 2783 2784 2785 2786 $img->SetColor($this->year->grid->iColor); 2787 2788 2789 2790 $yearwidth=$this->GetDayWidth()*$this->GetNumDaysInYear($year); 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 $img->Rectangle($xt,$yt,$xb,$yb); 2806 2807 2808 2809 } 2810 2861 if( $this->year->iShowLabels ) { 2862 $img=$this->iImg; 2863 $yt=$aYCoord+$img->top_margin; 2864 $img->SetFont($this->year->iFFamily,$this->year->iFStyle,$this->year->iFSize); 2865 $yb=$yt + $img->GetFontHeight() + $this->year->iTitleVertMargin + $this->year->iFrameWeight; 2866 2867 if( $getHeight ) { 2868 return $yb - $img->top_margin; 2869 } 2870 2871 $xb=$img->width-$img->right_margin+1; 2872 $xt=$img->left_margin+$this->iLabelWidth; 2873 $year = $this->GetYear($this->iStartDate); 2874 $img->SetColor($this->year->iBackgroundColor); 2875 $img->FilledRectangle($xt,$yt,$xb,$yb); 2876 $img->SetLineWeight($this->year->grid->iWeight); 2877 $img->SetTextAlign("center"); 2878 if( $year == $this->GetYear($this->iEndDate) ) 2879 $yearwidth=$this->GetDayWidth()*($this->GetYearDayNbr($this->iEndDate)-$this->GetYearDayNbr($this->iStartDate)+1); 2880 else 2881 $yearwidth=$this->GetDayWidth()*($this->GetNumDaysInYear($year)-$this->GetYearDayNbr($this->iStartDate)+1); 2882 2883 // The space for a year must be at least 20% bigger than the actual text 2884 // so we allow 10% margin on each side 2885 if( $yearwidth >= 1.20*$img->GetTextWidth("".$year) ) { 2886 $img->SetColor($this->year->iTextColor); 2887 $img->StrokeText(round($xt+$yearwidth/2+1), 2888 round($yb-$this->year->iTitleVertMargin), 2889 $year); 2890 } 2891 $x = $xt + $yearwidth; 2892 while( $x < $xb ) { 2893 $img->SetColor($this->year->grid->iColor); 2894 $img->Line($x,$yt,$x,$yb); 2895 $this->year->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin); 2896 $year += 1; 2897 $yearwidth=$this->GetDayWidth()*$this->GetNumDaysInYear($year); 2898 if( $x + $yearwidth < $xb ) 2899 $w = $yearwidth; 2900 else 2901 $w = $xb-$x; 2902 if( $w >= 1.2*$img->GetTextWidth("".$year) ) { 2903 $img->SetColor($this->year->iTextColor); 2904 $img->StrokeText(round($x+$w/2+1), 2905 round($yb-$this->year->iTitleVertMargin), 2906 $year); 2907 } 2908 $x += $yearwidth; 2909 } 2910 $img->SetColor($this->year->iFrameColor); 2911 $img->SetLineWeight($this->year->iFrameWeight); 2912 $img->Rectangle($xt,$yt,$xb,$yb); 2913 return $yb-$img->top_margin; 2914 } 2915 return $aYCoord; 2916 } 2917 2811 2918 // Stroke table title (upper left corner) 2812 2919 function StrokeTableHeaders($aYBottom) { 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 $this->tableTitle->Stroke($img,$xt+($xb-$xt)/2+1,$yt+2); 2824 2825 2826 2827 2828 2829 2830 2831 2832 // Draw the horizontal dividing line 2833 $this->dividerh->Stroke($img,$xt,$yb,$img->width-$img->right_margin,$yb); 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 $tmp = $this->divider->iWeight; 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2920 $img=$this->iImg; 2921 $xt=$img->left_margin; 2922 $yt=$img->top_margin; 2923 $xb=$xt+$this->iLabelWidth; 2924 $yb=$aYBottom+$img->top_margin; 2925 2926 if( $this->tableTitle->iShow ) { 2927 $img->SetColor($this->iTableHeaderBackgroundColor); 2928 $img->FilledRectangle($xt,$yt,$xb,$yb); 2929 $this->tableTitle->Align("center","top"); 2930 $this->tableTitle->Stroke($img,$xt+($xb-$xt)/2+1,$yt+2); 2931 $img->SetColor($this->iTableHeaderFrameColor); 2932 $img->SetLineWeight($this->iTableHeaderFrameWeight); 2933 $img->Rectangle($xt,$yt,$xb,$yb); 2934 } 2935 2936 $this->actinfo->Stroke($img,$xt,$yt,$xb,$yb,$this->tableTitle->iShow); 2937 2938 2939 // Draw the horizontal dividing line 2940 $this->dividerh->Stroke($img,$xt,$yb,$img->width-$img->right_margin,$yb); 2941 2942 // Draw the vertical dividing line 2943 // We do the width "manually" since we want the line only to grow 2944 // to the left 2945 $fancy = $this->divider->iStyle == 'fancy' ; 2946 if( $fancy ) { 2947 $this->divider->iStyle = 'solid'; 2948 } 2949 2950 $tmp = $this->divider->iWeight; 2951 $this->divider->iWeight=1; 2952 $y = $img->height-$img->bottom_margin; 2953 for($i=0; $i < $tmp; ++$i ) { 2954 $this->divider->Stroke($img,$xb-$i,$yt,$xb-$i,$y); 2955 } 2956 2957 // Should we draw "fancy" divider 2958 if( $fancy ) { 2959 $img->SetLineWeight(1); 2960 $img->SetColor($this->iTableHeaderFrameColor); 2961 $img->Line($xb,$yt,$xb,$y); 2962 $img->Line($xb-$tmp+1,$yt,$xb-$tmp+1,$y); 2963 $img->SetColor('white'); 2964 $img->Line($xb-$tmp+2,$yt,$xb-$tmp+2,$y); 2965 } 2859 2966 } 2860 2967 2861 2968 // Main entry point to stroke scale 2862 2969 function Stroke() { 2863 if( !$this->IsRangeSet() ) 2864 JpGraphError::RaiseL(6022); 2865 //("Gantt scale has not been specified."); 2866 $img=$this->iImg; 2867 2868 // If minutes are displayed then hour interval must be 1 2869 if( $this->IsDisplayMinute() && $this->hour->GetIntervall() > 1 ) { 2870 JpGraphError::RaiseL(6023); 2871 //('If you display both hour and minutes the hour intervall must be 1 (Otherwise it doesn\' make sense to display minutes).'); 2872 } 2873 2874 // Stroke all headers. As argument we supply the offset from the 2875 // top which depends on any previous headers 2876 2877 // First find out the height of each header 2878 $offy=$this->StrokeYears(0,true); 2879 $offm=$this->StrokeMonths($offy,true); 2880 $offw=$this->StrokeWeeks($offm,true); 2881 $offd=$this->StrokeDays($offw,true); 2882 $offh=$this->StrokeHours($offd,true); 2883 $offmin=$this->StrokeMinutes($offh,true); 2884 2885 2886 // ... then we can stroke them in the "backwards order to ensure that 2887 // the larger scale gridlines is stroked over the smaller scale gridline 2888 $this->StrokeMinutes($offh); 2889 $this->StrokeHours($offd); 2890 $this->StrokeDays($offw); 2891 $this->StrokeWeeks($offm); 2892 $this->StrokeMonths($offy); 2893 $this->StrokeYears(0); 2894 2895 // Now when we now the oaverall size of the scale headers 2896 // we can stroke the overall table headers 2897 $this->StrokeTableHeaders($offmin); 2898 2899 // Now we can calculate the correct scaling factor for each vertical position 2900 $this->iAvailableHeight = $img->height - $img->top_margin - $img->bottom_margin - $offd; 2901 $this->iVertHeaderSize = $offmin; 2902 if( $this->iVertSpacing == -1 ) 2903 $this->iVertSpacing = $this->iAvailableHeight / $this->iVertLines; 2904 } 2970 if( !$this->IsRangeSet() ) { 2971 JpGraphError::RaiseL(6022); 2972 //("Gantt scale has not been specified."); 2973 } 2974 $img=$this->iImg; 2975 2976 // If minutes are displayed then hour interval must be 1 2977 if( $this->IsDisplayMinute() && $this->hour->GetIntervall() > 1 ) { 2978 JpGraphError::RaiseL(6023); 2979 //('If you display both hour and minutes the hour intervall must be 1 (Otherwise it doesn\' make sense to display minutes).'); 2980 } 2981 2982 // Stroke all headers. As argument we supply the offset from the 2983 // top which depends on any previous headers 2984 2985 // First find out the height of each header 2986 $offy=$this->StrokeYears(0,true); 2987 $offm=$this->StrokeMonths($offy,true); 2988 $offw=$this->StrokeWeeks($offm,true); 2989 $offd=$this->StrokeDays($offw,true); 2990 $offh=$this->StrokeHours($offd,true); 2991 $offmin=$this->StrokeMinutes($offh,true); 2992 2993 2994 // ... then we can stroke them in the "backwards order to ensure that 2995 // the larger scale gridlines is stroked over the smaller scale gridline 2996 $this->StrokeMinutes($offh); 2997 $this->StrokeHours($offd); 2998 $this->StrokeDays($offw); 2999 $this->StrokeWeeks($offm); 3000 $this->StrokeMonths($offy); 3001 $this->StrokeYears(0); 3002 3003 // Now when we now the oaverall size of the scale headers 3004 // we can stroke the overall table headers 3005 $this->StrokeTableHeaders($offmin); 3006 3007 // Now we can calculate the correct scaling factor for each vertical position 3008 $this->iAvailableHeight = $img->height - $img->top_margin - $img->bottom_margin - $offd; 3009 3010 $this->iVertHeaderSize = $offmin; 3011 if( $this->iVertSpacing == -1 ) 3012 $this->iVertSpacing = $this->iAvailableHeight / $this->iVertLines; 3013 } 2905 3014 } 2906 3015 … … 2917 3026 public $iConstrainArrowType; 2918 3027 2919 //---------------2920 // CONSTRUCTOR2921 function GanttConstraint($aRow,$aType,$aColor,$aArrowSize,$aArrowType){2922 2923 2924 2925 2926 3028 //--------------- 3029 // CONSTRUCTOR 3030 function __construct($aRow,$aType,$aColor,$aArrowSize,$aArrowType){ 3031 $this->iConstrainType = $aType; 3032 $this->iConstrainRow = $aRow; 3033 $this->iConstrainColor=$aColor; 3034 $this->iConstrainArrowSize=$aArrowSize; 3035 $this->iConstrainArrowType=$aArrowType; 2927 3036 } 2928 3037 } … … 2936 3045 public $title,$caption; 2937 3046 public $csimarea='',$csimtarget='',$csimwintarget='',$csimalt=''; 2938 public $constraints = array(); 3047 public $constraints = array(); 2939 3048 public $iCaptionMargin=5; 2940 3049 public $iConstrainPos=array(); 2941 protected $iStart=""; 2942 public $iVPos=0; 2943 protected $iLabelLeftMargin=2; 2944 2945 function GanttPlotObject() {2946 2947 $this->title->Align("left","center");2948 3050 protected $iStart=""; // Start date 3051 public $iVPos=0; // Vertical position 3052 protected $iLabelLeftMargin=2; // Title margin 3053 3054 function __construct() { 3055 $this->title = new TextProperty(); 3056 $this->title->Align('left','center'); 3057 $this->caption = new TextProperty(); 2949 3058 } 2950 3059 2951 3060 function GetCSIMArea() { 2952 3061 return $this->csimarea; 2953 3062 } 2954 3063 2955 3064 function SetCSIMTarget($aTarget,$aAlt='',$aWinTarget='') { 2956 2957 2958 2959 //('CSIM Target must be specified as a string.'."\nStart of target is:\n$tv");2960 2961 2962 2963 2964 //('CSIM Alt text must be specified as a string.'."\nStart of alt text is:\n$tv");2965 3065 if( !is_string($aTarget) ) { 3066 $tv = substr(var_export($aTarget,true),0,40); 3067 JpGraphError::RaiseL(6024,$tv); 3068 //('CSIM Target must be specified as a string.'."\nStart of target is:\n$tv"); 3069 } 3070 if( !is_string($aAlt) ) { 3071 $tv = substr(var_export($aAlt,true),0,40); 3072 JpGraphError::RaiseL(6025,$tv); 3073 //('CSIM Alt text must be specified as a string.'."\nStart of alt text is:\n$tv"); 3074 } 2966 3075 2967 3076 $this->csimtarget=$aTarget; … … 2969 3078 $this->csimalt=$aAlt; 2970 3079 } 2971 3080 2972 3081 function SetCSIMAlt($aAlt) { 2973 2974 2975 2976 //('CSIM Alt text must be specified as a string.'."\nStart of alt text is:\n$tv");2977 3082 if( !is_string($aAlt) ) { 3083 $tv = substr(var_export($aAlt,true),0,40); 3084 JpGraphError::RaiseL(6025,$tv); 3085 //('CSIM Alt text must be specified as a string.'."\nStart of alt text is:\n$tv"); 3086 } 2978 3087 $this->csimalt=$aAlt; 2979 3088 } 2980 3089 2981 3090 function SetConstrain($aRow,$aType,$aColor='black',$aArrowSize=ARROW_S2,$aArrowType=ARROWT_SOLID) { 2982 3091 $this->constraints[] = new GanttConstraint($aRow, $aType, $aColor, $aArrowSize, $aArrowType); 2983 3092 } 2984 3093 2985 3094 function SetConstrainPos($xt,$yt,$xb,$yb) { 2986 $this->iConstrainPos = array($xt,$yt,$xb,$yb); 2987 } 2988 2989 /* 2990 function GetConstrain() { 2991 return array($this->iConstrainRow,$this->iConstrainType); 2992 } 2993 */ 2994 3095 $this->iConstrainPos = array($xt,$yt,$xb,$yb); 3096 } 3097 2995 3098 function GetMinDate() { 2996 3099 return $this->iStart; 2997 3100 } 2998 3101 2999 3102 function GetMaxDate() { 3000 3001 } 3002 3103 return $this->iStart; 3104 } 3105 3003 3106 function SetCaptionMargin($aMarg) { 3004 3107 $this->iCaptionMargin=$aMarg; 3005 3108 } 3006 3109 3007 3110 function GetAbsHeight($aImg) { 3008 return 0; 3009 } 3010 3111 return 0; 3112 } 3113 3011 3114 function GetLineNbr() { 3012 3115 return $this->iVPos; 3013 3116 } 3014 3117 3015 3118 function SetLabelLeftMargin($aOff) { 3016 3017 } 3119 $this->iLabelLeftMargin=$aOff; 3120 } 3018 3121 3019 3122 function StrokeActInfo($aImg,$aScale,$aYPos) { 3020 3021 3022 $this->title->Stroke($aImg,$cols,$aYPos); 3123 $cols=array(); 3124 $aScale->actinfo->GetColStart($aImg,$cols,true); 3125 $this->title->Stroke($aImg,$cols,$aYPos); 3023 3126 } 3024 3127 } … … 3026 3129 //=================================================== 3027 3130 // CLASS Progress 3028 // Holds parameters for the progress indicator 3131 // Holds parameters for the progress indicator 3029 3132 // displyed within a bar 3030 3133 //=================================================== … … 3033 3136 public $iPattern=GANTT_SOLID; 3034 3137 public $iColor="black", $iFillColor='black'; 3035 public $iDensity=98, $iHeight=0.65; 3036 3138 public $iDensity=98, $iHeight=0.65; 3139 3037 3140 function Set($aProg) { 3038 if( $aProg < 0.0 || $aProg > 1.0 ) 3039 JpGraphError::RaiseL(6027); 3040 //("Progress value must in range [0, 1]"); 3041 $this->iProgress = $aProg; 3042 } 3043 3044 function SetPattern($aPattern,$aColor="blue",$aDensity=98) { 3045 $this->iPattern = $aPattern; 3046 $this->iColor = $aColor; 3047 $this->iDensity = $aDensity; 3141 if( $aProg < 0.0 || $aProg > 1.0 ) { 3142 JpGraphError::RaiseL(6027); 3143 //("Progress value must in range [0, 1]"); 3144 } 3145 $this->iProgress = $aProg; 3146 } 3147 3148 function SetPattern($aPattern,$aColor="blue",$aDensity=98) { 3149 $this->iPattern = $aPattern; 3150 $this->iColor = $aColor; 3151 $this->iDensity = $aDensity; 3048 3152 } 3049 3153 3050 3154 function SetFillColor($aColor) { 3051 3052 } 3053 3155 $this->iFillColor = $aColor; 3156 } 3157 3054 3158 function SetHeight($aHeight) { 3055 3159 $this->iHeight = $aHeight; 3056 3160 } 3057 3161 } … … 3071 3175 private $iStart=0; // 0=from left margin, 1=just along header 3072 3176 3073 function HorizontalGridLine() {3074 3075 3076 3077 } 3078 3177 function __construct() { 3178 $this->line = new LineProperty(); 3179 $this->line->SetColor('gray@0.4'); 3180 $this->line->SetStyle('dashed'); 3181 } 3182 3079 3183 function Show($aShow=true) { 3080 3184 $this->iShow = $aShow; 3081 3185 } 3082 3186 3083 3187 function SetRowFillColor($aColor1,$aColor2='') { 3084 3085 3188 $this->iRowColor1 = $aColor1; 3189 $this->iRowColor2 = $aColor2; 3086 3190 } 3087 3191 3088 3192 function SetStart($aStart) { 3089 3193 $this->iStart = $aStart; 3090 3194 } 3091 3195 3092 3196 function Stroke($aImg,$aScale) { 3093 3094 3095 3096 3097 3098 3099 3100 3101 $xb = round($aScale->TranslateDate($limen)); 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 $yb = round($aScale->TranslateVertPos(1)); 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3197 3198 if( ! $this->iShow ) return; 3199 3200 // Get horizontal width of line 3201 /* 3202 $limst = $aScale->iStartDate; 3203 $limen = $aScale->iEndDate; 3204 $xt = round($aScale->TranslateDate($aScale->iStartDate)); 3205 $xb = round($aScale->TranslateDate($limen)); 3206 */ 3207 3208 if( $this->iStart === 0 ) { 3209 $xt = $aImg->left_margin-1; 3210 } 3211 else { 3212 $xt = round($aScale->TranslateDate($aScale->iStartDate))+1; 3213 } 3214 3215 $xb = $aImg->width-$aImg->right_margin; 3216 3217 $yt = round($aScale->TranslateVertPos(0)); 3218 $yb = round($aScale->TranslateVertPos(1)); 3219 $height = $yb - $yt; 3220 3221 // Loop around for all lines in the chart 3222 for($i=0; $i < $aScale->iVertLines; ++$i ) { 3223 $yb = $yt - $height; 3224 $this->line->Stroke($aImg,$xt,$yb,$xb,$yb); 3225 if( $this->iRowColor1 !== '' ) { 3226 if( $i % 2 == 0 ) { 3227 $aImg->PushColor($this->iRowColor1); 3228 $aImg->FilledRectangle($xt,$yt,$xb,$yb); 3229 $aImg->PopColor(); 3230 } 3231 elseif( $this->iRowColor2 !== '' ) { 3232 $aImg->PushColor($this->iRowColor2); 3233 $aImg->FilledRectangle($xt,$yt,$xb,$yb); 3234 $aImg->PopColor(); 3235 } 3236 } 3237 $yt = round($aScale->TranslateVertPos($i+1)); 3238 } 3239 $yb = $yt - $height; 3240 $this->line->Stroke($aImg,$xt,$yb,$xb,$yb); 3137 3241 } 3138 3242 } … … 3151 3255 private $iShadow=false,$iShadowColor="darkgray",$iShadowWidth=1,$iShadowFrame="black"; 3152 3256 private $iPattern=GANTT_RDIAG,$iPatternColor="blue",$iPatternDensity=95; 3153 //--------------- 3154 // CONSTRUCTOR 3155 function GanttBar($aPos,$aLabel,$aStart,$aEnd,$aCaption="",$aHeightFactor=0.6) { 3156 parent::GanttPlotObject(); 3157 $this->iStart = $aStart; 3158 // Is the end date given as a date or as number of days added to start date? 3159 if( is_string($aEnd) ) { 3160 // If end date has been specified without a time we will asssume 3161 // end date is at the end of that date 3162 if( strpos($aEnd,':') === false ) 3163 $this->iEnd = strtotime($aEnd)+SECPERDAY-1; 3164 else 3165 $this->iEnd = $aEnd; 3166 } 3167 elseif(is_int($aEnd) || is_float($aEnd) ) 3168 $this->iEnd = strtotime($aStart)+round($aEnd*SECPERDAY); 3169 $this->iVPos = $aPos; 3170 $this->iHeightFactor = $aHeightFactor; 3171 $this->title->Set($aLabel); 3172 $this->caption = new TextProperty($aCaption); 3173 $this->caption->Align("left","center"); 3174 $this->leftMark =new PlotMark(); 3175 $this->leftMark->Hide(); 3176 $this->rightMark=new PlotMark(); 3177 $this->rightMark->Hide(); 3178 $this->progress = new Progress(); 3179 } 3180 3181 //--------------- 3182 // PUBLIC METHODS 3257 private $iBreakStyle=false, $iBreakLineStyle='dotted',$iBreakLineWeight=1; 3258 //--------------- 3259 // CONSTRUCTOR 3260 function __construct($aPos,$aLabel,$aStart,$aEnd,$aCaption="",$aHeightFactor=0.6) { 3261 parent::__construct(); 3262 $this->iStart = $aStart; 3263 // Is the end date given as a date or as number of days added to start date? 3264 if( is_string($aEnd) ) { 3265 // If end date has been specified without a time we will asssume 3266 // end date is at the end of that date 3267 if( strpos($aEnd,':') === false ) { 3268 $this->iEnd = strtotime($aEnd)+SECPERDAY-1; 3269 } 3270 else { 3271 $this->iEnd = $aEnd; 3272 } 3273 } 3274 elseif(is_int($aEnd) || is_float($aEnd) ) { 3275 $this->iEnd = strtotime($aStart)+round($aEnd*SECPERDAY); 3276 } 3277 $this->iVPos = $aPos; 3278 $this->iHeightFactor = $aHeightFactor; 3279 $this->title->Set($aLabel); 3280 $this->caption = new TextProperty($aCaption); 3281 $this->caption->Align("left","center"); 3282 $this->leftMark =new PlotMark(); 3283 $this->leftMark->Hide(); 3284 $this->rightMark=new PlotMark(); 3285 $this->rightMark->Hide(); 3286 $this->progress = new Progress(); 3287 } 3288 3289 //--------------- 3290 // PUBLIC METHODS 3183 3291 function SetShadow($aShadow=true,$aColor="gray") { 3184 $this->iShadow=$aShadow; 3185 $this->iShadowColor=$aColor; 3186 } 3187 3292 $this->iShadow=$aShadow; 3293 $this->iShadowColor=$aColor; 3294 } 3295 3296 function SetBreakStyle($aFlg=true,$aLineStyle='dotted',$aLineWeight=1) { 3297 $this->iBreakStyle = $aFlg; 3298 $this->iBreakLineStyle = $aLineStyle; 3299 $this->iBreakLineWeight = $aLineWeight; 3300 } 3301 3188 3302 function GetMaxDate() { 3189 3190 } 3191 3303 return $this->iEnd; 3304 } 3305 3192 3306 function SetHeight($aHeight) { 3193 3307 $this->iHeightFactor = $aHeight; 3194 3308 } 3195 3309 3196 3310 function SetColor($aColor) { 3197 3311 $this->iFrameColor = $aColor; 3198 3312 } 3199 3313 3200 3314 function SetFillColor($aColor) { 3201 3315 $this->iFillColor = $aColor; 3202 3316 } 3203 3317 3204 3318 function GetAbsHeight($aImg) { 3205 3206 3207 3208 3209 if( $this->leftMark->show ) 3210 3211 if( $this->rightMark->show ) 3212 3213 3214 3215 3216 3217 } 3218 3219 function SetPattern($aPattern,$aColor="blue",$aDensity=95) { 3220 3221 3222 3319 if( is_int($this->iHeightFactor) || $this->leftMark->show || $this->rightMark->show ) { 3320 $m=-1; 3321 if( is_int($this->iHeightFactor) ) 3322 $m = $this->iHeightFactor; 3323 if( $this->leftMark->show ) 3324 $m = max($m,$this->leftMark->width*2); 3325 if( $this->rightMark->show ) 3326 $m = max($m,$this->rightMark->width*2); 3327 return $m; 3328 } 3329 else 3330 return -1; 3331 } 3332 3333 function SetPattern($aPattern,$aColor="blue",$aDensity=95) { 3334 $this->iPattern = $aPattern; 3335 $this->iPatternColor = $aColor; 3336 $this->iPatternDensity = $aDensity; 3223 3337 } 3224 3338 3225 3339 function Stroke($aImg,$aScale) { 3226 $factory = new RectPatternFactory(); 3227 $prect = $factory->Create($this->iPattern,$this->iPatternColor); 3228 $prect->SetDensity($this->iPatternDensity); 3229 3230 // If height factor is specified as a float between 0,1 then we take it as meaning 3231 // percetage of the scale width between horizontal line. 3232 // If it is an integer > 1 we take it to mean the absolute height in pixels 3233 if( $this->iHeightFactor > -0.0 && $this->iHeightFactor <= 1.1) 3234 $vs = $aScale->GetVertSpacing()*$this->iHeightFactor; 3235 elseif(is_int($this->iHeightFactor) && $this->iHeightFactor>2 && $this->iHeightFactor < 200 ) 3236 $vs = $this->iHeightFactor; 3237 else 3238 JpGraphError::RaiseL(6028,$this->iHeightFactor); 3239 //("Specified height (".$this->iHeightFactor.") for gantt bar is out of range."); 3240 3241 // Clip date to min max dates to show 3242 $st = $aScale->NormalizeDate($this->iStart); 3243 $en = $aScale->NormalizeDate($this->iEnd); 3244 3245 3246 $limst = max($st,$aScale->iStartDate); 3247 $limen = min($en,$aScale->iEndDate); 3248 3249 $xt = round($aScale->TranslateDate($limst)); 3250 $xb = round($aScale->TranslateDate($limen)); 3251 $yt = round($aScale->TranslateVertPos($this->iVPos)-$vs-($aScale->GetVertSpacing()/2-$vs/2)); 3252 $yb = round($aScale->TranslateVertPos($this->iVPos)-($aScale->GetVertSpacing()/2-$vs/2)); 3253 $middle = round($yt+($yb-$yt)/2); 3254 $this->StrokeActInfo($aImg,$aScale,$middle); 3255 3256 // CSIM for title 3257 if( ! empty($this->title->csimtarget) ) { 3258 $colwidth = $this->title->GetColWidth($aImg); 3259 $colstarts=array(); 3260 $aScale->actinfo->GetColStart($aImg,$colstarts,true); 3261 $n = min(count($colwidth),count($this->title->csimtarget)); 3262 for( $i=0; $i < $n; ++$i ) { 3263 $title_xt = $colstarts[$i]; 3264 $title_xb = $title_xt + $colwidth[$i]; 3265 $coords = "$title_xt,$yt,$title_xb,$yt,$title_xb,$yb,$title_xt,$yb"; 3266 3267 if( ! empty($this->title->csimtarget[$i]) ) { 3268 $this->csimarea .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->title->csimtarget[$i]."\""; 3269 3270 if( ! empty($this->title->csimwintarget[$i]) ) { 3271 $this->csimarea .= "target=\"".$this->title->csimwintarget[$i]."\" "; 3272 } 3273 3274 if( ! empty($this->title->csimalt[$i]) ) { 3275 $tmp = $this->title->csimalt[$i]; 3276 $this->csimarea .= " title=\"$tmp\" alt=\"$tmp\" "; 3277 } 3278 $this->csimarea .= " />\n"; 3279 } 3280 } 3281 } 3282 3283 // Check if the bar is totally outside the current scale range 3284 if( $en < $aScale->iStartDate || $st > $aScale->iEndDate ) 3285 return; 3286 3287 3288 // Remember the positions for the bar 3289 $this->SetConstrainPos($xt,$yt,$xb,$yb); 3290 3291 $prect->ShowFrame(false); 3292 $prect->SetBackground($this->iFillColor); 3293 if( $this->iShadow ) { 3294 $aImg->SetColor($this->iFrameColor); 3295 $aImg->ShadowRectangle($xt,$yt,$xb,$yb,$this->iFillColor,$this->iShadowWidth,$this->iShadowColor); 3296 $prect->SetPos(new Rectangle($xt+1,$yt+1,$xb-$xt-$this->iShadowWidth-2,$yb-$yt-$this->iShadowWidth-2)); 3297 $prect->Stroke($aImg); 3298 } 3299 else { 3300 $prect->SetPos(new Rectangle($xt,$yt,$xb-$xt+1,$yb-$yt+1)); 3301 $prect->Stroke($aImg); 3302 $aImg->SetColor($this->iFrameColor); 3303 $aImg->Rectangle($xt,$yt,$xb,$yb); 3304 } 3305 3306 // CSIM for bar 3307 if( ! empty($this->csimtarget) ) { 3308 3309 $coords = "$xt,$yt,$xb,$yt,$xb,$yb,$xt,$yb"; 3310 $this->csimarea .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->csimtarget."\""; 3311 3312 if( !empty($this->csimwintarget) ) { 3313 $this->csimarea .= " target=\"".$this->csimwintarget."\" "; 3314 } 3315 3316 if( $this->csimalt != '' ) { 3317 $tmp = $this->csimalt; 3318 $this->csimarea .= " title=\"$tmp\" alt=\"$tmp\" "; 3319 } 3320 $this->csimarea .= " />\n"; 3321 } 3322 3323 // Draw progress bar inside activity bar 3324 if( $this->progress->iProgress > 0 ) { 3325 3326 $xtp = $aScale->TranslateDate($st); 3327 $xbp = $aScale->TranslateDate($en); 3328 $len = ($xbp-$xtp)*$this->progress->iProgress; 3329 3330 $endpos = $xtp+$len; 3331 if( $endpos > $xt ) { 3332 3333 // Take away the length of the progress that is not visible (before the start date) 3334 $len -= ($xt-$xtp); 3335 3336 // Is the the progress bar visible after the start date? 3337 if( $xtp < $xt ) 3338 $xtp = $xt; 3339 3340 // Make sure that the progess bar doesn't extend over the end date 3341 if( $xtp+$len-1 > $xb ) 3342 $len = $xb - $xtp ; 3343 3344 $prog = $factory->Create($this->progress->iPattern,$this->progress->iColor); 3345 $prog->SetDensity($this->progress->iDensity); 3346 $prog->SetBackground($this->progress->iFillColor); 3347 $barheight = ($yb-$yt+1); 3348 if( $this->iShadow ) 3349 $barheight -= $this->iShadowWidth; 3350 $progressheight = floor($barheight*$this->progress->iHeight); 3351 $marg = ceil(($barheight-$progressheight)/2); 3352 $pos = new Rectangle($xtp,$yt + $marg, $len,$barheight-2*$marg); 3353 $prog->SetPos($pos); 3354 $prog->Stroke($aImg); 3355 } 3356 } 3357 3358 // We don't plot the end mark if the bar has been capped 3359 if( $limst == $st ) { 3360 $y = $middle; 3361 // We treat the RIGHT and LEFT triangle mark a little bi 3362 // special so that these marks are placed right under the 3363 // bar. 3364 if( $this->leftMark->GetType() == MARK_LEFTTRIANGLE ) { 3365 $y = $yb ; 3366 } 3367 $this->leftMark->Stroke($aImg,$xt,$y); 3368 } 3369 if( $limen == $en ) { 3370 $y = $middle; 3371 // We treat the RIGHT and LEFT triangle mark a little bi 3372 // special so that these marks are placed right under the 3373 // bar. 3374 if( $this->rightMark->GetType() == MARK_RIGHTTRIANGLE ) { 3375 $y = $yb ; 3376 } 3377 $this->rightMark->Stroke($aImg,$xb,$y); 3378 3379 $margin = $this->iCaptionMargin; 3380 if( $this->rightMark->show ) 3381 $margin += $this->rightMark->GetWidth(); 3382 $this->caption->Stroke($aImg,$xb+$margin,$middle); 3383 } 3340 $factory = new RectPatternFactory(); 3341 $prect = $factory->Create($this->iPattern,$this->iPatternColor); 3342 $prect->SetDensity($this->iPatternDensity); 3343 3344 // If height factor is specified as a float between 0,1 then we take it as meaning 3345 // percetage of the scale width between horizontal line. 3346 // If it is an integer > 1 we take it to mean the absolute height in pixels 3347 if( $this->iHeightFactor > -0.0 && $this->iHeightFactor <= 1.1) 3348 $vs = $aScale->GetVertSpacing()*$this->iHeightFactor; 3349 elseif(is_int($this->iHeightFactor) && $this->iHeightFactor>2 && $this->iHeightFactor < 200 ) 3350 $vs = $this->iHeightFactor; 3351 else { 3352 JpGraphError::RaiseL(6028,$this->iHeightFactor); 3353 // ("Specified height (".$this->iHeightFactor.") for gantt bar is out of range."); 3354 } 3355 3356 // Clip date to min max dates to show 3357 $st = $aScale->NormalizeDate($this->iStart); 3358 $en = $aScale->NormalizeDate($this->iEnd); 3359 3360 $limst = max($st,$aScale->iStartDate); 3361 $limen = min($en,$aScale->iEndDate); 3362 3363 $xt = round($aScale->TranslateDate($limst)); 3364 $xb = round($aScale->TranslateDate($limen)); 3365 $yt = round($aScale->TranslateVertPos($this->iVPos)-$vs-($aScale->GetVertSpacing()/2-$vs/2)); 3366 $yb = round($aScale->TranslateVertPos($this->iVPos)-($aScale->GetVertSpacing()/2-$vs/2)); 3367 $middle = round($yt+($yb-$yt)/2); 3368 $this->StrokeActInfo($aImg,$aScale,$middle); 3369 3370 // CSIM for title 3371 if( ! empty($this->title->csimtarget) ) { 3372 $colwidth = $this->title->GetColWidth($aImg); 3373 $colstarts=array(); 3374 $aScale->actinfo->GetColStart($aImg,$colstarts,true); 3375 $n = min(count($colwidth),count($this->title->csimtarget)); 3376 for( $i=0; $i < $n; ++$i ) { 3377 $title_xt = $colstarts[$i]; 3378 $title_xb = $title_xt + $colwidth[$i]; 3379 $coords = "$title_xt,$yt,$title_xb,$yt,$title_xb,$yb,$title_xt,$yb"; 3380 3381 if( ! empty($this->title->csimtarget[$i]) ) { 3382 $this->csimarea .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->title->csimtarget[$i]."\""; 3383 3384 if( ! empty($this->title->csimwintarget[$i]) ) { 3385 $this->csimarea .= "target=\"".$this->title->csimwintarget[$i]."\" "; 3386 } 3387 3388 if( ! empty($this->title->csimalt[$i]) ) { 3389 $tmp = $this->title->csimalt[$i]; 3390 $this->csimarea .= " title=\"$tmp\" alt=\"$tmp\" "; 3391 } 3392 $this->csimarea .= " />\n"; 3393 } 3394 } 3395 } 3396 3397 // Check if the bar is totally outside the current scale range 3398 if( $en < $aScale->iStartDate || $st > $aScale->iEndDate ) 3399 return; 3400 3401 3402 // Remember the positions for the bar 3403 $this->SetConstrainPos($xt,$yt,$xb,$yb); 3404 3405 3406 3407 $prect->ShowFrame(false); 3408 $prect->SetBackground($this->iFillColor); 3409 if( $this->iBreakStyle ) { 3410 $aImg->SetColor($this->iFrameColor); 3411 $olds = $aImg->SetLineStyle($this->iBreakLineStyle); 3412 $oldw = $aImg->SetLineWeight($this->iBreakLineWeight); 3413 $aImg->StyleLine($xt,$yt,$xb,$yt); 3414 $aImg->StyleLine($xt,$yb,$xb,$yb); 3415 $aImg->SetLineStyle($olds); 3416 $aImg->SetLineWeight($oldw); 3417 } 3418 else { 3419 if( $this->iShadow ) { 3420 $aImg->SetColor($this->iFrameColor); 3421 $aImg->ShadowRectangle($xt,$yt,$xb,$yb,$this->iFillColor,$this->iShadowWidth,$this->iShadowColor); 3422 $prect->SetPos(new Rectangle($xt+1,$yt+1,$xb-$xt-$this->iShadowWidth-2,$yb-$yt-$this->iShadowWidth-2)); 3423 $prect->Stroke($aImg); 3424 } 3425 else { 3426 $prect->SetPos(new Rectangle($xt,$yt,$xb-$xt+1,$yb-$yt+1)); 3427 $prect->Stroke($aImg); 3428 $aImg->SetColor($this->iFrameColor); 3429 $aImg->Rectangle($xt,$yt,$xb,$yb); 3430 } 3431 } 3432 // CSIM for bar 3433 if( ! empty($this->csimtarget) ) { 3434 3435 $coords = "$xt,$yt,$xb,$yt,$xb,$yb,$xt,$yb"; 3436 $this->csimarea .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->csimtarget."\""; 3437 3438 if( !empty($this->csimwintarget) ) { 3439 $this->csimarea .= " target=\"".$this->csimwintarget."\" "; 3440 } 3441 3442 if( $this->csimalt != '' ) { 3443 $tmp = $this->csimalt; 3444 $this->csimarea .= " title=\"$tmp\" alt=\"$tmp\" "; 3445 } 3446 $this->csimarea .= " />\n"; 3447 } 3448 3449 // Draw progress bar inside activity bar 3450 if( $this->progress->iProgress > 0 ) { 3451 3452 $xtp = $aScale->TranslateDate($st); 3453 $xbp = $aScale->TranslateDate($en); 3454 $len = ($xbp-$xtp)*$this->progress->iProgress; 3455 3456 $endpos = $xtp+$len; 3457 if( $endpos > $xt ) { 3458 3459 // Take away the length of the progress that is not visible (before the start date) 3460 $len -= ($xt-$xtp); 3461 3462 // Is the the progress bar visible after the start date? 3463 if( $xtp < $xt ) 3464 $xtp = $xt; 3465 3466 // Make sure that the progess bar doesn't extend over the end date 3467 if( $xtp+$len-1 > $xb ) 3468 $len = $xb - $xtp ; 3469 3470 $prog = $factory->Create($this->progress->iPattern,$this->progress->iColor); 3471 $prog->SetDensity($this->progress->iDensity); 3472 $prog->SetBackground($this->progress->iFillColor); 3473 $barheight = ($yb-$yt+1); 3474 if( $this->iShadow ) 3475 $barheight -= $this->iShadowWidth; 3476 $progressheight = floor($barheight*$this->progress->iHeight); 3477 $marg = ceil(($barheight-$progressheight)/2); 3478 $pos = new Rectangle($xtp,$yt + $marg, $len,$barheight-2*$marg); 3479 $prog->SetPos($pos); 3480 $prog->Stroke($aImg); 3481 } 3482 } 3483 3484 // We don't plot the end mark if the bar has been capped 3485 if( $limst == $st ) { 3486 $y = $middle; 3487 // We treat the RIGHT and LEFT triangle mark a little bi 3488 // special so that these marks are placed right under the 3489 // bar. 3490 if( $this->leftMark->GetType() == MARK_LEFTTRIANGLE ) { 3491 $y = $yb ; 3492 } 3493 $this->leftMark->Stroke($aImg,$xt,$y); 3494 } 3495 if( $limen == $en ) { 3496 $y = $middle; 3497 // We treat the RIGHT and LEFT triangle mark a little bi 3498 // special so that these marks are placed right under the 3499 // bar. 3500 if( $this->rightMark->GetType() == MARK_RIGHTTRIANGLE ) { 3501 $y = $yb ; 3502 } 3503 $this->rightMark->Stroke($aImg,$xb,$y); 3504 3505 $margin = $this->iCaptionMargin; 3506 if( $this->rightMark->show ) 3507 $margin += $this->rightMark->GetWidth(); 3508 $this->caption->Stroke($aImg,$xb+$margin,$middle); 3509 } 3384 3510 } 3385 3511 } … … 3391 3517 class MileStone extends GanttPlotObject { 3392 3518 public $mark; 3393 3394 //---------------3395 // CONSTRUCTOR 3396 function MileStone($aVPos,$aLabel,$aDate,$aCaption="") {3397 GanttPlotObject::GanttPlotObject();3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 } 3411 3412 //---------------3413 // PUBLIC METHODS 3414 3519 3520 //--------------- 3521 // CONSTRUCTOR 3522 function __construct($aVPos,$aLabel,$aDate,$aCaption="") { 3523 GanttPlotObject::__construct(); 3524 $this->caption->Set($aCaption); 3525 $this->caption->Align("left","center"); 3526 $this->caption->SetFont(FF_FONT1,FS_BOLD); 3527 $this->title->Set($aLabel); 3528 $this->title->SetColor("darkred"); 3529 $this->mark = new PlotMark(); 3530 $this->mark->SetWidth(10); 3531 $this->mark->SetType(MARK_DIAMOND); 3532 $this->mark->SetColor("darkred"); 3533 $this->mark->SetFillColor("darkred"); 3534 $this->iVPos = $aVPos; 3535 $this->iStart = $aDate; 3536 } 3537 3538 //--------------- 3539 // PUBLIC METHODS 3540 3415 3541 function GetAbsHeight($aImg) { 3416 3417 } 3418 3542 return max($this->title->GetHeight($aImg),$this->mark->GetWidth()); 3543 } 3544 3419 3545 function Stroke($aImg,$aScale) { 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 $this->mark->Stroke($aImg,$x,$y); 3474 3475 3476 3546 // Put the mark in the middle at the middle of the day 3547 $d = $aScale->NormalizeDate($this->iStart)+SECPERDAY/2; 3548 $x = $aScale->TranslateDate($d); 3549 $y = $aScale->TranslateVertPos($this->iVPos)-($aScale->GetVertSpacing()/2); 3550 3551 $this->StrokeActInfo($aImg,$aScale,$y); 3552 3553 // CSIM for title 3554 if( ! empty($this->title->csimtarget) ) { 3555 3556 $yt = round($y - $this->title->GetHeight($aImg)/2); 3557 $yb = round($y + $this->title->GetHeight($aImg)/2); 3558 3559 $colwidth = $this->title->GetColWidth($aImg); 3560 $colstarts=array(); 3561 $aScale->actinfo->GetColStart($aImg,$colstarts,true); 3562 $n = min(count($colwidth),count($this->title->csimtarget)); 3563 for( $i=0; $i < $n; ++$i ) { 3564 $title_xt = $colstarts[$i]; 3565 $title_xb = $title_xt + $colwidth[$i]; 3566 $coords = "$title_xt,$yt,$title_xb,$yt,$title_xb,$yb,$title_xt,$yb"; 3567 3568 if( !empty($this->title->csimtarget[$i]) ) { 3569 3570 $this->csimarea .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->title->csimtarget[$i]."\""; 3571 3572 if( !empty($this->title->csimwintarget[$i]) ) { 3573 $this->csimarea .= "target=\"".$this->title->csimwintarget[$i]."\""; 3574 } 3575 3576 if( ! empty($this->title->csimalt[$i]) ) { 3577 $tmp = $this->title->csimalt[$i]; 3578 $this->csimarea .= " title=\"$tmp\" alt=\"$tmp\" "; 3579 } 3580 $this->csimarea .= " />\n"; 3581 } 3582 } 3583 } 3584 3585 if( $d < $aScale->iStartDate || $d > $aScale->iEndDate ) 3586 return; 3587 3588 // Remember the coordinates for any constrains linking to 3589 // this milestone 3590 $w = $this->mark->GetWidth()/2; 3591 $this->SetConstrainPos($x,round($y-$w),$x,round($y+$w)); 3592 3593 // Setup CSIM 3594 if( $this->csimtarget != '' ) { 3595 $this->mark->SetCSIMTarget( $this->csimtarget ); 3596 $this->mark->SetCSIMAlt( $this->csimalt ); 3597 } 3598 3599 $this->mark->Stroke($aImg,$x,$y); 3600 $this->caption->Stroke($aImg,$x+$this->mark->width/2+$this->iCaptionMargin,$y); 3601 3602 $this->csimarea .= $this->mark->GetCSIMAreas(); 3477 3603 } 3478 3604 } … … 3485 3611 3486 3612 class TextPropertyBelow extends TextProperty { 3487 function TextPropertyBelow($aTxt='') {3488 parent::TextProperty($aTxt);3613 function __construct($aTxt='') { 3614 parent::__construct($aTxt); 3489 3615 } 3490 3616 3491 3617 function GetColWidth($aImg,$aMargin=0) { 3492 3493 3494 3618 // Since we are not stroking the title in the columns 3619 // but rather under the graph we want this to return 0. 3620 return array(0); 3495 3621 } 3496 3622 } … … 3498 3624 class GanttVLine extends GanttPlotObject { 3499 3625 3500 private $iLine,$title_margin=3, $iDayOffset=1; 3501 3502 //--------------- 3503 // CONSTRUCTOR 3504 function GanttVLine($aDate,$aTitle="",$aColor="black",$aWeight=3,$aStyle="dashed") { 3505 GanttPlotObject::GanttPlotObject(); 3506 $this->iLine = new LineProperty(); 3507 $this->iLine->SetColor($aColor); 3508 $this->iLine->SetWeight($aWeight); 3509 $this->iLine->SetStyle($aStyle); 3510 $this->iStart = $aDate; 3511 $this->title = new TextPropertyBelow(); 3512 $this->title->Set($aTitle); 3513 } 3514 3515 //--------------- 3516 // PUBLIC METHODS 3626 private $iLine,$title_margin=3, $iDayOffset=0.5; 3627 private $iStartRow = -1, $iEndRow = -1; 3628 3629 //--------------- 3630 // CONSTRUCTOR 3631 function __construct($aDate,$aTitle="",$aColor="darkred",$aWeight=2,$aStyle="solid") { 3632 GanttPlotObject::__construct(); 3633 $this->iLine = new LineProperty(); 3634 $this->iLine->SetColor($aColor); 3635 $this->iLine->SetWeight($aWeight); 3636 $this->iLine->SetStyle($aStyle); 3637 $this->iStart = $aDate; 3638 $this->title = new TextPropertyBelow(); 3639 $this->title->Set($aTitle); 3640 } 3641 3642 //--------------- 3643 // PUBLIC METHODS 3644 3645 // Set start and end rows for the VLine. By default the entire heigh of the 3646 // Gantt chart is used 3647 function SetRowSpan($aStart, $aEnd=-1) { 3648 $this->iStartRow = $aStart; 3649 $this->iEndRow = $aEnd; 3650 } 3517 3651 3518 3652 function SetDayOffset($aOff=0.5) { 3519 if( $aOff < 0.0 || $aOff > 1.0 ) 3520 JpGraphError::RaiseL(6029); 3521 //("Offset for vertical line must be in range [0,1]"); 3522 $this->iDayOffset = $aOff; 3523 } 3524 3653 if( $aOff < 0.0 || $aOff > 1.0 ) { 3654 JpGraphError::RaiseL(6029); 3655 //("Offset for vertical line must be in range [0,1]"); 3656 } 3657 $this->iDayOffset = $aOff; 3658 } 3659 3525 3660 function SetTitleMargin($aMarg) { 3526 $this->title_margin = $aMarg; 3527 } 3528 3661 $this->title_margin = $aMarg; 3662 } 3663 3664 function SetWeight($aWeight) { 3665 $this->iLine->SetWeight($aWeight); 3666 } 3667 3529 3668 function Stroke($aImg,$aScale) { 3530 $d = $aScale->NormalizeDate($this->iStart); 3531 if( $d < $aScale->iStartDate || $d > $aScale->iEndDate ) 3532 return; 3533 if($this->iDayOffset != 0.0) 3534 $d += 24*60*60*$this->iDayOffset; 3535 $x = $aScale->TranslateDate($d); 3536 $y1 = $aScale->iVertHeaderSize+$aImg->top_margin; 3537 $y2 = $aImg->height - $aImg->bottom_margin; 3538 $this->iLine->Stroke($aImg,$x,$y1,$x,$y2); 3539 $this->title->Align("center","top"); 3540 $this->title->Stroke($aImg,$x,$y2+$this->title_margin); 3541 } 3669 $d = $aScale->NormalizeDate($this->iStart); 3670 if( $d < $aScale->iStartDate || $d > $aScale->iEndDate ) 3671 return; 3672 if($this->iDayOffset != 0.0) 3673 $d += 24*60*60*$this->iDayOffset; 3674 $x = $aScale->TranslateDate($d);//d=1006858800, 3675 3676 if( $this->iStartRow > -1 ) { 3677 $y1 = $aScale->TranslateVertPos($this->iStartRow,true) ; 3678 } 3679 else { 3680 $y1 = $aScale->iVertHeaderSize+$aImg->top_margin; 3681 } 3682 3683 if( $this->iEndRow > -1 ) { 3684 $y2 = $aScale->TranslateVertPos($this->iEndRow); 3685 } 3686 else { 3687 $y2 = $aImg->height - $aImg->bottom_margin; 3688 } 3689 3690 $this->iLine->Stroke($aImg,$x,$y1,$x,$y2); 3691 $this->title->Align("center","top"); 3692 $this->title->Stroke($aImg,$x,$y2+$this->title_margin); 3693 } 3542 3694 } 3543 3695 3544 3696 //=================================================== 3545 3697 // CLASS LinkArrow 3546 // Handles the drawing of a an arrow 3698 // Handles the drawing of a an arrow 3547 3699 //=================================================== 3548 3700 class LinkArrow { 3549 3701 private $ix,$iy; 3550 3702 private $isizespec = array( 3551 3703 array(2,3),array(3,5),array(3,8),array(6,15),array(8,22)); 3552 3704 private $iDirection=ARROW_DOWN,$iType=ARROWT_SOLID,$iSize=ARROW_S2; 3553 3705 private $iColor='black'; 3554 3706 3555 function LinkArrow($x,$y,$aDirection,$aType=ARROWT_SOLID,$aSize=ARROW_S2) {3556 3557 3558 3559 3560 3561 } 3562 3707 function __construct($x,$y,$aDirection,$aType=ARROWT_SOLID,$aSize=ARROW_S2) { 3708 $this->iDirection = $aDirection; 3709 $this->iType = $aType; 3710 $this->iSize = $aSize; 3711 $this->ix = $x; 3712 $this->iy = $y; 3713 } 3714 3563 3715 function SetColor($aColor) { 3564 3716 $this->iColor = $aColor; 3565 3717 } 3566 3718 3567 3719 function SetSize($aSize) { 3568 3720 $this->iSize = $aSize; 3569 3721 } 3570 3722 3571 3723 function SetType($aType) { 3572 3724 $this->iType = $aType; 3573 3725 } 3574 3726 3575 3727 function Stroke($aImg) { 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 //('Unknown arrow direction for link.');3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 //('Unknown arrow type for link.');3609 3610 break; 3611 3728 list($dx,$dy) = $this->isizespec[$this->iSize]; 3729 $x = $this->ix; 3730 $y = $this->iy; 3731 switch ( $this->iDirection ) { 3732 case ARROW_DOWN: 3733 $c = array($x,$y,$x-$dx,$y-$dy,$x+$dx,$y-$dy,$x,$y); 3734 break; 3735 case ARROW_UP: 3736 $c = array($x,$y,$x-$dx,$y+$dy,$x+$dx,$y+$dy,$x,$y); 3737 break; 3738 case ARROW_LEFT: 3739 $c = array($x,$y,$x+$dy,$y-$dx,$x+$dy,$y+$dx,$x,$y); 3740 break; 3741 case ARROW_RIGHT: 3742 $c = array($x,$y,$x-$dy,$y-$dx,$x-$dy,$y+$dx,$x,$y); 3743 break; 3744 default: 3745 JpGraphError::RaiseL(6030); 3746 //('Unknown arrow direction for link.'); 3747 die(); 3748 break; 3749 } 3750 $aImg->SetColor($this->iColor); 3751 switch( $this->iType ) { 3752 case ARROWT_SOLID: 3753 $aImg->FilledPolygon($c); 3754 break; 3755 case ARROWT_OPEN: 3756 $aImg->Polygon($c); 3757 break; 3758 default: 3759 JpGraphError::RaiseL(6031); 3760 //('Unknown arrow type for link.'); 3761 die(); 3762 break; 3763 } 3612 3764 } 3613 3765 } … … 3624 3776 private $iArrowSize=ARROW_S2,$iArrowType=ARROWT_SOLID; 3625 3777 3626 function GanttLink($x1=0,$y1=0,$x2=0,$y2=0) {3627 3628 3629 3630 3778 function __construct($x1=0,$y1=0,$x2=0,$y2=0) { 3779 $this->ix1 = $x1; 3780 $this->ix2 = $x2; 3781 $this->iy1 = $y1; 3782 $this->iy2 = $y2; 3631 3783 } 3632 3784 3633 3785 function SetPos($x1,$y1,$x2,$y2) { 3634 3635 3636 3637 3786 $this->ix1 = $x1; 3787 $this->ix2 = $x2; 3788 $this->iy1 = $y1; 3789 $this->iy2 = $y2; 3638 3790 } 3639 3791 3640 3792 function SetPath($aPath) { 3641 3793 $this->iPathType = $aPath; 3642 3794 } 3643 3795 3644 3796 function SetColor($aColor) { 3645 3797 $this->iColor = $aColor; 3646 3798 } 3647 3799 3648 3800 function SetArrow($aSize,$aType=ARROWT_SOLID) { 3649 3650 3651 } 3652 3801 $this->iArrowSize = $aSize; 3802 $this->iArrowType = $aType; 3803 } 3804 3653 3805 function SetWeight($aWeight) { 3654 3806 $this->iWeight = $aWeight; 3655 3807 } 3656 3808 3657 3809 function Stroke($aImg) { 3658 3659 3660 3661 3662 3663 // space between axctivities then no suh detour is made and the 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 //('Internal error: Unknown path type (='.$this->iPathType .') specified for link.');3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 // If we draw a link back in time (end to start) and the bars 3708 // are very close we also change the path so it comes in from 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 //('Internal error: Unknown path type specified for link.');3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 //('Internal error: Unknown path type specified for link.');3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 //('Internal error: Unknown path type specified for link.');3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3810 // The way the path for the arrow is constructed is partly based 3811 // on some heuristics. This is not an exact science but draws the 3812 // path in a way that, for me, makes esthetic sence. For example 3813 // if the start and end activities are very close we make a small 3814 // detour to endter the target horixontally. If there are more 3815 // space between axctivities then no suh detour is made and the 3816 // target is "hit" directly vertical. I have tried to keep this 3817 // simple. no doubt this could become almost infinitive complex 3818 // and have some real AI. Feel free to modify this. 3819 // This will no-doubt be tweaked as times go by. One design aim 3820 // is to avoid having the user choose what types of arrow 3821 // he wants. 3822 3823 // The arrow is drawn between (x1,y1) to (x2,y2) 3824 $x1 = $this->ix1 ; 3825 $x2 = $this->ix2 ; 3826 $y1 = $this->iy1 ; 3827 $y2 = $this->iy2 ; 3828 3829 // Depending on if the target is below or above we have to 3830 // handle thi different. 3831 if( $y2 > $y1 ) { 3832 $arrowtype = ARROW_DOWN; 3833 $midy = round(($y2-$y1)/2+$y1); 3834 if( $x2 > $x1 ) { 3835 switch ( $this->iPathType ) { 3836 case 0: 3837 $c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2); 3838 break; 3839 case 1: 3840 case 2: 3841 case 3: 3842 $c = array($x1,$y1,$x2,$y1,$x2,$y2); 3843 break; 3844 default: 3845 JpGraphError::RaiseL(6032,$this->iPathType); 3846 //('Internal error: Unknown path type (='.$this->iPathType .') specified for link.'); 3847 exit(1); 3848 break; 3849 } 3850 } 3851 else { 3852 switch ( $this->iPathType ) { 3853 case 0: 3854 case 1: 3855 $c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2); 3856 break; 3857 case 2: 3858 // Always extend out horizontally a bit from the first point 3859 // If we draw a link back in time (end to start) and the bars 3860 // are very close we also change the path so it comes in from 3861 // the left on the activity 3862 $c = array($x1,$y1,$x1+$this->iPathExtend,$y1, 3863 $x1+$this->iPathExtend,$midy, 3864 $x2,$midy,$x2,$y2); 3865 break; 3866 case 3: 3867 if( $y2-$midy < 6 ) { 3868 $c = array($x1,$y1,$x1,$midy, 3869 $x2-$this->iPathExtend,$midy, 3870 $x2-$this->iPathExtend,$y2, 3871 $x2,$y2); 3872 $arrowtype = ARROW_RIGHT; 3873 } 3874 else { 3875 $c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2); 3876 } 3877 break; 3878 default: 3879 JpGraphError::RaiseL(6032,$this->iPathType); 3880 //('Internal error: Unknown path type specified for link.'); 3881 exit(1); 3882 break; 3883 } 3884 } 3885 $arrow = new LinkArrow($x2,$y2,$arrowtype); 3886 } 3887 else { 3888 // Y2 < Y1 3889 $arrowtype = ARROW_UP; 3890 $midy = round(($y1-$y2)/2+$y2); 3891 if( $x2 > $x1 ) { 3892 switch ( $this->iPathType ) { 3893 case 0: 3894 case 1: 3895 $c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2); 3896 break; 3897 case 3: 3898 if( $midy-$y2 < 8 ) { 3899 $arrowtype = ARROW_RIGHT; 3900 $c = array($x1,$y1,$x1,$y2,$x2,$y2); 3901 } 3902 else { 3903 $c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2); 3904 } 3905 break; 3906 default: 3907 JpGraphError::RaiseL(6032,$this->iPathType); 3908 //('Internal error: Unknown path type specified for link.'); 3909 break; 3910 } 3911 } 3912 else { 3913 switch ( $this->iPathType ) { 3914 case 0: 3915 case 1: 3916 $c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2); 3917 break; 3918 case 2: 3919 // Always extend out horizontally a bit from the first point 3920 $c = array($x1,$y1,$x1+$this->iPathExtend,$y1, 3921 $x1+$this->iPathExtend,$midy, 3922 $x2,$midy,$x2,$y2); 3923 break; 3924 case 3: 3925 if( $midy-$y2 < 16 ) { 3926 $arrowtype = ARROW_RIGHT; 3927 $c = array($x1,$y1,$x1,$midy,$x2-$this->iPathExtend,$midy, 3928 $x2-$this->iPathExtend,$y2, 3929 $x2,$y2); 3930 } 3931 else { 3932 $c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2); 3933 } 3934 break; 3935 default: 3936 JpGraphError::RaiseL(6032,$this->iPathType); 3937 //('Internal error: Unknown path type specified for link.'); 3938 break; 3939 } 3940 } 3941 $arrow = new LinkArrow($x2,$y2,$arrowtype); 3942 } 3943 $aImg->SetColor($this->iColor); 3944 $aImg->SetLineWeight($this->iWeight); 3945 $aImg->Polygon($c); 3946 $aImg->SetLineWeight(1); 3947 $arrow->SetColor($this->iColor); 3948 $arrow->SetSize($this->iArrowSize); 3949 $arrow->SetType($this->iArrowType); 3950 $arrow->Stroke($aImg); 3799 3951 } 3800 3952 } -
trunk/client/modules/Elezioni/grafici/jpgraph_gb2312.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: PHP4 Graph Plotting library.Chinese font conversions5 // Created: 6 // Ver: $Id: jpgraph_gb2312.php 781 2006-10-08 08:07:47Z ljp $3 // File: JPGRAPH_GB2312.PHP 4 // Description: Chinese font conversions 5 // Created: 2003-05-30 6 // Ver: $Id: jpgraph_gb2312.php 1106 2009-02-22 20:16:35Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 11 11 12 12 class GB2312toUTF8 { 13 // --------------------------------------------------------------------14 // This code table is used to translate GB2312 code (key) to 15 // it's corresponding Unicode value (data)16 // --------------------------------------------------------------------17 private $codetable = array( 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 13140 => 21507, 13141 => 30196, 13142 => 25345, 13143 => 21273, 13144 => 27744,222 13145 => 36831, 13146 => 24347, 13147 => 39536, 13148 => 32827, 13149 => 40831,223 13150 => 20360, 13151 => 23610, 13152 => 36196, 13153 => 32709, 13154 => 26021,224 13155 => 28861, 13156 => 20805, 13157 => 20914, 13158 => 34411, 13159 => 23815,225 13160 => 23456, 13161 => 25277, 13162 => 37228, 13163 => 30068, 13164 => 36364,226 13165 => 31264, 13166 => 24833, 13167 => 31609, 13168 => 20167, 13169 => 32504,227 13170 => 30597, 13171 => 19985, 13172 => 33261, 13173 => 21021, 13174 => 20986,228 13175 => 27249, 13176 => 21416, 13177 => 36487, 13178 => 38148, 13179 => 38607,229 13180 => 28353, 13181 => 38500, 13182 => 26970, 13345 => 30784, 13346 => 20648,230 13347 => 30679, 13348 => 25616, 13349 => 35302, 13350 => 22788, 13351 => 25571,231 13352 => 24029, 13353 => 31359, 13354 => 26941, 13355 => 20256, 13356 => 33337,232 13357 => 21912, 13358 => 20018, 13359 => 30126, 13360 => 31383, 13361 => 24162,233 13362 => 24202, 13363 => 38383, 13364 => 21019, 13365 => 21561, 13366 => 28810,234 13367 => 25462, 13368 => 38180, 13369 => 22402, 13370 => 26149, 13371 => 26943,235 13372 => 37255, 13373 => 21767, 13374 => 28147, 13375 => 32431, 13376 => 34850,236 13377 => 25139, 13378 => 32496, 13379 => 30133, 13380 => 33576, 13381 => 30913,237 13382 => 38604, 13383 => 36766, 13384 => 24904, 13385 => 29943, 13386 => 35789,238 13387 => 27492, 13388 => 21050, 13389 => 36176, 13390 => 27425, 13391 => 32874,239 13392 => 33905, 13393 => 22257, 13394 => 21254, 13395 => 20174, 13396 => 19995,240 13397 => 20945, 13398 => 31895, 13399 => 37259, 13400 => 31751, 13401 => 20419,241 13402 => 36479, 13403 => 31713, 13404 => 31388, 13405 => 25703, 13406 => 23828,242 13407 => 20652, 13408 => 33030, 13409 => 30209, 13410 => 31929, 13411 => 28140,243 13412 => 32736, 13413 => 26449, 13414 => 23384, 13415 => 23544, 13416 => 30923,244 13417 => 25774, 13418 => 25619, 13419 => 25514, 13420 => 25387, 13421 => 38169,245 13422 => 25645, 13423 => 36798, 13424 => 31572, 13425 => 30249, 13426 => 25171,246 13427 => 22823, 13428 => 21574, 13429 => 27513, 13430 => 20643, 13431 => 25140,247 13432 => 24102, 13433 => 27526, 13434 => 20195, 13435 => 36151, 13436 => 34955,248 13437 => 24453, 13438 => 36910, 13601 => 24608, 13602 => 32829, 13603 => 25285,249 13604 => 20025, 13605 => 21333, 13606 => 37112, 13607 => 25528, 13608 => 32966,250 13609 => 26086, 13610 => 27694, 13611 => 20294, 13612 => 24814, 13613 => 28129,251 13614 => 35806, 13615 => 24377, 13616 => 34507, 13617 => 24403, 13618 => 25377,252 13619 => 20826, 13620 => 33633, 13621 => 26723, 13622 => 20992, 13623 => 25443,253 13624 => 36424, 13625 => 20498, 13626 => 23707, 13627 => 31095, 13628 => 23548,254 13629 => 21040, 13630 => 31291, 13631 => 24764, 13632 => 36947, 13633 => 30423,255 13634 => 24503, 13635 => 24471, 13636 => 30340, 13637 => 36460, 13638 => 28783,256 13639 => 30331, 13640 => 31561, 13641 => 30634, 13642 => 20979, 13643 => 37011,257 13644 => 22564, 13645 => 20302, 13646 => 28404, 13647 => 36842, 13648 => 25932,258 13649 => 31515, 13650 => 29380, 13651 => 28068, 13652 => 32735, 13653 => 23265,259 13654 => 25269, 13655 => 24213, 13656 => 22320, 13657 => 33922, 13658 => 31532,260 13659 => 24093, 13660 => 24351, 13661 => 36882, 13662 => 32532, 13663 => 39072,261 13664 => 25474, 13665 => 28359, 13666 => 30872, 13667 => 28857, 13668 => 20856,262 13669 => 38747, 13670 => 22443, 13671 => 30005, 13672 => 20291, 13673 => 30008,263 13674 => 24215, 13675 => 24806, 13676 => 22880, 13677 => 28096, 13678 => 27583,264 13679 => 30857, 13680 => 21500, 13681 => 38613, 13682 => 20939, 13683 => 20993,265 13684 => 25481, 13685 => 21514, 13686 => 38035, 13687 => 35843, 13688 => 36300,266 13689 => 29241, 13690 => 30879, 13691 => 34678, 13692 => 36845, 13693 => 35853,267 13694 => 21472, 13857 => 19969, 13858 => 30447, 13859 => 21486, 13860 => 38025,268 13861 => 39030, 13862 => 40718, 13863 => 38189, 13864 => 23450, 13865 => 35746,269 13866 => 20002, 13867 => 19996, 13868 => 20908, 13869 => 33891, 13870 => 25026,270 13871 => 21160, 13872 => 26635, 13873 => 20375, 13874 => 24683, 13875 => 20923,271 13876 => 27934, 13877 => 20828, 13878 => 25238, 13879 => 26007, 13880 => 38497,272 13881 => 35910, 13882 => 36887, 13883 => 30168, 13884 => 37117, 13885 => 30563,273 13886 => 27602, 13887 => 29322, 13888 => 29420, 13889 => 35835, 13890 => 22581,274 13891 => 30585, 13892 => 36172, 13893 => 26460, 13894 => 38208, 13895 => 32922,275 13896 => 24230, 13897 => 28193, 13898 => 22930, 13899 => 31471, 13900 => 30701,276 13901 => 38203, 13902 => 27573, 13903 => 26029, 13904 => 32526, 13905 => 22534,277 13906 => 20817, 13907 => 38431, 13908 => 23545, 13909 => 22697, 13910 => 21544,278 13911 => 36466, 13912 => 25958, 13913 => 39039, 13914 => 22244, 13915 => 38045,279 13916 => 30462, 13917 => 36929, 13918 => 25479, 13919 => 21702, 13920 => 22810,280 13921 => 22842, 13922 => 22427, 13923 => 36530, 13924 => 26421, 13925 => 36346,281 13926 => 33333, 13927 => 21057, 13928 => 24816, 13929 => 22549, 13930 => 34558,282 13931 => 23784, 13932 => 40517, 13933 => 20420, 13934 => 39069, 13935 => 35769,283 13936 => 23077, 13937 => 24694, 13938 => 21380, 13939 => 25212, 13940 => 36943,284 13941 => 37122, 13942 => 39295, 13943 => 24681, 13944 => 32780, 13945 => 20799,285 13946 => 32819, 13947 => 23572, 13948 => 39285, 13949 => 27953, 13950 => 20108,286 14113 => 36144, 14114 => 21457, 14115 => 32602, 14116 => 31567, 14117 => 20240,287 14118 => 20047, 14119 => 38400, 14120 => 27861, 14121 => 29648, 14122 => 34281,288 14123 => 24070, 14124 => 30058, 14125 => 32763, 14126 => 27146, 14127 => 30718,289 14128 => 38034, 14129 => 32321, 14130 => 20961, 14131 => 28902, 14132 => 21453,290 14133 => 36820, 14134 => 33539, 14135 => 36137, 14136 => 29359, 14137 => 39277,291 14138 => 27867, 14139 => 22346, 14140 => 33459, 14141 => 26041, 14142 => 32938,292 14143 => 25151, 14144 => 38450, 14145 => 22952, 14146 => 20223, 14147 => 35775,293 14148 => 32442, 14149 => 25918, 14150 => 33778, 14151 => 38750, 14152 => 21857,294 14153 => 39134, 14154 => 32933, 14155 => 21290, 14156 => 35837, 14157 => 21536,295 14158 => 32954, 14159 => 24223, 14160 => 27832, 14161 => 36153, 14162 => 33452,296 14163 => 37210, 14164 => 21545, 14165 => 27675, 14166 => 20998, 14167 => 32439,297 14168 => 22367, 14169 => 28954, 14170 => 27774, 14171 => 31881, 14172 => 22859,298 14173 => 20221, 14174 => 24575, 14175 => 24868, 14176 => 31914, 14177 => 20016,299 14178 => 23553, 14179 => 26539, 14180 => 34562, 14181 => 23792, 14182 => 38155,300 14183 => 39118, 14184 => 30127, 14185 => 28925, 14186 => 36898, 14187 => 20911,301 14188 => 32541, 14189 => 35773, 14190 => 22857, 14191 => 20964, 14192 => 20315,302 14193 => 21542, 14194 => 22827, 14195 => 25975, 14196 => 32932, 14197 => 23413,303 14198 => 25206, 14199 => 25282, 14200 => 36752, 14201 => 24133, 14202 => 27679,304 14203 => 31526, 14204 => 20239, 14205 => 20440, 14206 => 26381, 14369 => 28014,305 14370 => 28074, 14371 => 31119, 14372 => 34993, 14373 => 24343, 14374 => 29995,306 14375 => 25242, 14376 => 36741, 14377 => 20463, 14378 => 37340, 14379 => 26023,307 14380 => 33071, 14381 => 33105, 14382 => 24220, 14383 => 33104, 14384 => 36212,308 14385 => 21103, 14386 => 35206, 14387 => 36171, 14388 => 22797, 14389 => 20613,309 14390 => 20184, 14391 => 38428, 14392 => 29238, 14393 => 33145, 14394 => 36127,310 14395 => 23500, 14396 => 35747, 14397 => 38468, 14398 => 22919, 14399 => 32538,311 14400 => 21648, 14401 => 22134, 14402 => 22030, 14403 => 35813, 14404 => 25913,312 14405 => 27010, 14406 => 38041, 14407 => 30422, 14408 => 28297, 14409 => 24178,313 14410 => 29976, 14411 => 26438, 14412 => 26577, 14413 => 31487, 14414 => 32925,314 14415 => 36214, 14416 => 24863, 14417 => 31174, 14418 => 25954, 14419 => 36195,315 14420 => 20872, 14421 => 21018, 14422 => 38050, 14423 => 32568, 14424 => 32923,316 14425 => 32434, 14426 => 23703, 14427 => 28207, 14428 => 26464, 14429 => 31705,317 14430 => 30347, 14431 => 39640, 14432 => 33167, 14433 => 32660, 14434 => 31957,318 14435 => 25630, 14436 => 38224, 14437 => 31295, 14438 => 21578, 14439 => 21733,319 14440 => 27468, 14441 => 25601, 14442 => 25096, 14443 => 40509, 14444 => 33011,320 14445 => 30105, 14446 => 21106, 14447 => 38761, 14448 => 33883, 14449 => 26684,321 14450 => 34532, 14451 => 38401, 14452 => 38548, 14453 => 38124, 14454 => 20010,322 14455 => 21508, 14456 => 32473, 14457 => 26681, 14458 => 36319, 14459 => 32789,323 14460 => 26356, 14461 => 24218, 14462 => 32697, 14625 => 22466, 14626 => 32831,324 14627 => 26775, 14628 => 24037, 14629 => 25915, 14630 => 21151, 14631 => 24685,325 14632 => 40858, 14633 => 20379, 14634 => 36524, 14635 => 20844, 14636 => 23467,326 14637 => 24339, 14638 => 24041, 14639 => 27742, 14640 => 25329, 14641 => 36129,327 14642 => 20849, 14643 => 38057, 14644 => 21246, 14645 => 27807, 14646 => 33503,328 14647 => 29399, 14648 => 22434, 14649 => 26500, 14650 => 36141, 14651 => 22815,329 14652 => 36764, 14653 => 33735, 14654 => 21653, 14655 => 31629, 14656 => 20272,330 14657 => 27837, 14658 => 23396, 14659 => 22993, 14660 => 40723, 14661 => 21476,331 14662 => 34506, 14663 => 39592, 14664 => 35895, 14665 => 32929, 14666 => 25925,332 14667 => 39038, 14668 => 22266, 14669 => 38599, 14670 => 21038, 14671 => 29916,333 14672 => 21072, 14673 => 23521, 14674 => 25346, 14675 => 35074, 14676 => 20054,334 14677 => 25296, 14678 => 24618, 14679 => 26874, 14680 => 20851, 14681 => 23448,335 14682 => 20896, 14683 => 35266, 14684 => 31649, 14685 => 39302, 14686 => 32592,336 14687 => 24815, 14688 => 28748, 14689 => 36143, 14690 => 20809, 14691 => 24191,337 14692 => 36891, 14693 => 29808, 14694 => 35268, 14695 => 22317, 14696 => 30789,338 14697 => 24402, 14698 => 40863, 14699 => 38394, 14700 => 36712, 14701 => 39740,339 14702 => 35809, 14703 => 30328, 14704 => 26690, 14705 => 26588, 14706 => 36330,340 14707 => 36149, 14708 => 21053, 14709 => 36746, 14710 => 28378, 14711 => 26829,341 14712 => 38149, 14713 => 37101, 14714 => 22269, 14715 => 26524, 14716 => 35065,342 14717 => 36807, 14718 => 21704, 14881 => 39608, 14882 => 23401, 14883 => 28023,343 14884 => 27686, 14885 => 20133, 14886 => 23475, 14887 => 39559, 14888 => 37219,344 14889 => 25000, 14890 => 37039, 14891 => 38889, 14892 => 21547, 14893 => 28085,345 14894 => 23506, 14895 => 20989, 14896 => 21898, 14897 => 32597, 14898 => 32752,346 14899 => 25788, 14900 => 25421, 14901 => 26097, 14902 => 25022, 14903 => 24717,347 14904 => 28938, 14905 => 27735, 14906 => 27721, 14907 => 22831, 14908 => 26477,348 14909 => 33322, 14910 => 22741, 14911 => 22158, 14912 => 35946, 14913 => 27627,349 14914 => 37085, 14915 => 22909, 14916 => 32791, 14917 => 21495, 14918 => 28009,350 14919 => 21621, 14920 => 21917, 14921 => 33655, 14922 => 33743, 14923 => 26680,351 14924 => 31166, 14925 => 21644, 14926 => 20309, 14927 => 21512, 14928 => 30418,352 14929 => 35977, 14930 => 38402, 14931 => 27827, 14932 => 28088, 14933 => 36203,353 14934 => 35088, 14935 => 40548, 14936 => 36154, 14937 => 22079, 14938 => 40657,354 14939 => 30165, 14940 => 24456, 14941 => 29408, 14942 => 24680, 14943 => 21756,355 14944 => 20136, 14945 => 27178, 14946 => 34913, 14947 => 24658, 14948 => 36720,356 14949 => 21700, 14950 => 28888, 14951 => 34425, 14952 => 40511, 14953 => 27946,357 14954 => 23439, 14955 => 24344, 14956 => 32418, 14957 => 21897, 14958 => 20399,358 14959 => 29492, 14960 => 21564, 14961 => 21402, 14962 => 20505, 14963 => 21518,359 14964 => 21628, 14965 => 20046, 14966 => 24573, 14967 => 29786, 14968 => 22774,360 14969 => 33899, 14970 => 32993, 14971 => 34676, 14972 => 29392, 14973 => 31946,361 14974 => 28246, 15137 => 24359, 15138 => 34382, 15139 => 21804, 15140 => 25252,362 15141 => 20114, 15142 => 27818, 15143 => 25143, 15144 => 33457, 15145 => 21719,363 15146 => 21326, 15147 => 29502, 15148 => 28369, 15149 => 30011, 15150 => 21010,364 15151 => 21270, 15152 => 35805, 15153 => 27088, 15154 => 24458, 15155 => 24576,365 15156 => 28142, 15157 => 22351, 15158 => 27426, 15159 => 29615, 15160 => 26707,366 15161 => 36824, 15162 => 32531, 15163 => 25442, 15164 => 24739, 15165 => 21796,367 15166 => 30186, 15167 => 35938, 15168 => 28949, 15169 => 28067, 15170 => 23462,368 15171 => 24187, 15172 => 33618, 15173 => 24908, 15174 => 40644, 15175 => 30970,369 15176 => 34647, 15177 => 31783, 15178 => 30343, 15179 => 20976, 15180 => 24822,370 15181 => 29004, 15182 => 26179, 15183 => 24140, 15184 => 24653, 15185 => 35854,371 15186 => 28784, 15187 => 25381, 15188 => 36745, 15189 => 24509, 15190 => 24674,372 15191 => 34516, 15192 => 22238, 15193 => 27585, 15194 => 24724, 15195 => 24935,373 15196 => 21321, 15197 => 24800, 15198 => 26214, 15199 => 36159, 15200 => 31229,374 15201 => 20250, 15202 => 28905, 15203 => 27719, 15204 => 35763, 15205 => 35826,375 15206 => 32472, 15207 => 33636, 15208 => 26127, 15209 => 23130, 15210 => 39746,376 15211 => 27985, 15212 => 28151, 15213 => 35905, 15214 => 27963, 15215 => 20249,377 15216 => 28779, 15217 => 33719, 15218 => 25110, 15219 => 24785, 15220 => 38669,378 15221 => 36135, 15222 => 31096, 15223 => 20987, 15224 => 22334, 15225 => 22522,379 15226 => 26426, 15227 => 30072, 15228 => 31293, 15229 => 31215, 15230 => 31637,380 15393 => 32908, 15394 => 39269, 15395 => 36857, 15396 => 28608, 15397 => 35749,381 15398 => 40481, 15399 => 23020, 15400 => 32489, 15401 => 32521, 15402 => 21513,382 15403 => 26497, 15404 => 26840, 15405 => 36753, 15406 => 31821, 15407 => 38598,383 15408 => 21450, 15409 => 24613, 15410 => 30142, 15411 => 27762, 15412 => 21363,384 15413 => 23241, 15414 => 32423, 15415 => 25380, 15416 => 20960, 15417 => 33034,385 15418 => 24049, 15419 => 34015, 15420 => 25216, 15421 => 20864, 15422 => 23395,386 15423 => 20238, 15424 => 31085, 15425 => 21058, 15426 => 24760, 15427 => 27982,387 15428 => 23492, 15429 => 23490, 15430 => 35745, 15431 => 35760, 15432 => 26082,388 15433 => 24524, 15434 => 38469, 15435 => 22931, 15436 => 32487, 15437 => 32426,389 15438 => 22025, 15439 => 26551, 15440 => 22841, 15441 => 20339, 15442 => 23478,390 15443 => 21152, 15444 => 33626, 15445 => 39050, 15446 => 36158, 15447 => 30002,391 15448 => 38078, 15449 => 20551, 15450 => 31292, 15451 => 20215, 15452 => 26550,392 15453 => 39550, 15454 => 23233, 15455 => 27516, 15456 => 30417, 15457 => 22362,393 15458 => 23574, 15459 => 31546, 15460 => 38388, 15461 => 29006, 15462 => 20860,394 15463 => 32937, 15464 => 33392, 15465 => 22904, 15466 => 32516, 15467 => 33575,395 15468 => 26816, 15469 => 26604, 15470 => 30897, 15471 => 30839, 15472 => 25315,396 15473 => 25441, 15474 => 31616, 15475 => 20461, 15476 => 21098, 15477 => 20943,397 15478 => 33616, 15479 => 27099, 15480 => 37492, 15481 => 36341, 15482 => 36145,398 15483 => 35265, 15484 => 38190, 15485 => 31661, 15486 => 20214, 15649 => 20581,399 15650 => 33328, 15651 => 21073, 15652 => 39279, 15653 => 28176, 15654 => 28293,400 15655 => 28071, 15656 => 24314, 15657 => 20725, 15658 => 23004, 15659 => 23558,401 15660 => 27974, 15661 => 27743, 15662 => 30086, 15663 => 33931, 15664 => 26728,402 15665 => 22870, 15666 => 35762, 15667 => 21280, 15668 => 37233, 15669 => 38477,403 15670 => 34121, 15671 => 26898, 15672 => 30977, 15673 => 28966, 15674 => 33014,404 15675 => 20132, 15676 => 37066, 15677 => 27975, 15678 => 39556, 15679 => 23047,405 15680 => 22204, 15681 => 25605, 15682 => 38128, 15683 => 30699, 15684 => 20389,406 15685 => 33050, 15686 => 29409, 15687 => 35282, 15688 => 39290, 15689 => 32564,407 15690 => 32478, 15691 => 21119, 15692 => 25945, 15693 => 37237, 15694 => 36735,408 15695 => 36739, 15696 => 21483, 15697 => 31382, 15698 => 25581, 15699 => 25509,409 15700 => 30342, 15701 => 31224, 15702 => 34903, 15703 => 38454, 15704 => 25130,410 15705 => 21163, 15706 => 33410, 15707 => 26708, 15708 => 26480, 15709 => 25463,411 15710 => 30571, 15711 => 31469, 15712 => 27905, 15713 => 32467, 15714 => 35299,412 15715 => 22992, 15716 => 25106, 15717 => 34249, 15718 => 33445, 15719 => 30028,413 15720 => 20511, 15721 => 20171, 15722 => 30117, 15723 => 35819, 15724 => 23626,414 15725 => 24062, 15726 => 31563, 15727 => 26020, 15728 => 37329, 15729 => 20170,415 15730 => 27941, 15731 => 35167, 15732 => 32039, 15733 => 38182, 15734 => 20165,416 15735 => 35880, 15736 => 36827, 15737 => 38771, 15738 => 26187, 15739 => 31105,417 15740 => 36817, 15741 => 28908, 15742 => 28024, 15905 => 23613, 15906 => 21170,418 15907 => 33606, 15908 => 20834, 15909 => 33550, 15910 => 30555, 15911 => 26230,419 15912 => 40120, 15913 => 20140, 15914 => 24778, 15915 => 31934, 15916 => 31923,420 15917 => 32463, 15918 => 20117, 15919 => 35686, 15920 => 26223, 15921 => 39048,421 15922 => 38745, 15923 => 22659, 15924 => 25964, 15925 => 38236, 15926 => 24452,422 15927 => 30153, 15928 => 38742, 15929 => 31455, 15930 => 31454, 15931 => 20928,423 15932 => 28847, 15933 => 31384, 15934 => 25578, 15935 => 31350, 15936 => 32416,424 15937 => 29590, 15938 => 38893, 15939 => 20037, 15940 => 28792, 15941 => 20061,425 15942 => 37202, 15943 => 21417, 15944 => 25937, 15945 => 26087, 15946 => 33276,426 15947 => 33285, 15948 => 21646, 15949 => 23601, 15950 => 30106, 15951 => 38816,427 15952 => 25304, 15953 => 29401, 15954 => 30141, 15955 => 23621, 15956 => 39545,428 15957 => 33738, 15958 => 23616, 15959 => 21632, 15960 => 30697, 15961 => 20030,429 15962 => 27822, 15963 => 32858, 15964 => 25298, 15965 => 25454, 15966 => 24040,430 15967 => 20855, 15968 => 36317, 15969 => 36382, 15970 => 38191, 15971 => 20465,431 15972 => 21477, 15973 => 24807, 15974 => 28844, 15975 => 21095, 15976 => 25424,432 15977 => 40515, 15978 => 23071, 15979 => 20518, 15980 => 30519, 15981 => 21367,433 15982 => 32482, 15983 => 25733, 15984 => 25899, 15985 => 25225, 15986 => 25496,434 15987 => 20500, 15988 => 29237, 15989 => 35273, 15990 => 20915, 15991 => 35776,435 15992 => 32477, 15993 => 22343, 15994 => 33740, 15995 => 38055, 15996 => 20891,436 15997 => 21531, 15998 => 23803, 16161 => 20426, 16162 => 31459, 16163 => 27994,437 16164 => 37089, 16165 => 39567, 16166 => 21888, 16167 => 21654, 16168 => 21345,438 16169 => 21679, 16170 => 24320, 16171 => 25577, 16172 => 26999, 16173 => 20975,439 16174 => 24936, 16175 => 21002, 16176 => 22570, 16177 => 21208, 16178 => 22350,440 16179 => 30733, 16180 => 30475, 16181 => 24247, 16182 => 24951, 16183 => 31968,441 16184 => 25179, 16185 => 25239, 16186 => 20130, 16187 => 28821, 16188 => 32771,442 16189 => 25335, 16190 => 28900, 16191 => 38752, 16192 => 22391, 16193 => 33499,443 16194 => 26607, 16195 => 26869, 16196 => 30933, 16197 => 39063, 16198 => 31185,444 16199 => 22771, 16200 => 21683, 16201 => 21487, 16202 => 28212, 16203 => 20811,445 16204 => 21051, 16205 => 23458, 16206 => 35838, 16207 => 32943, 16208 => 21827,446 16209 => 22438, 16210 => 24691, 16211 => 22353, 16212 => 21549, 16213 => 31354,447 16214 => 24656, 16215 => 23380, 16216 => 25511, 16217 => 25248, 16218 => 21475,448 16219 => 25187, 16220 => 23495, 16221 => 26543, 16222 => 21741, 16223 => 31391,449 16224 => 33510, 16225 => 37239, 16226 => 24211, 16227 => 35044, 16228 => 22840,450 16229 => 22446, 16230 => 25358, 16231 => 36328, 16232 => 33007, 16233 => 22359,451 16234 => 31607, 16235 => 20393, 16236 => 24555, 16237 => 23485, 16238 => 27454,452 16239 => 21281, 16240 => 31568, 16241 => 29378, 16242 => 26694, 16243 => 30719,453 16244 => 30518, 16245 => 26103, 16246 => 20917, 16247 => 20111, 16248 => 30420,454 16249 => 23743, 16250 => 31397, 16251 => 33909, 16252 => 22862, 16253 => 39745,455 16254 => 20608, 16417 => 39304, 16418 => 24871, 16419 => 28291, 16420 => 22372,456 16421 => 26118, 16422 => 25414, 16423 => 22256, 16424 => 25324, 16425 => 25193,457 16426 => 24275, 16427 => 38420, 16428 => 22403, 16429 => 25289, 16430 => 21895,458 16431 => 34593, 16432 => 33098, 16433 => 36771, 16434 => 21862, 16435 => 33713,459 16436 => 26469, 16437 => 36182, 16438 => 34013, 16439 => 23146, 16440 => 26639,460 16441 => 25318, 16442 => 31726, 16443 => 38417, 16444 => 20848, 16445 => 28572,461 16446 => 35888, 16447 => 25597, 16448 => 35272, 16449 => 25042, 16450 => 32518,462 16451 => 28866, 16452 => 28389, 16453 => 29701, 16454 => 27028, 16455 => 29436,463 16456 => 24266, 16457 => 37070, 16458 => 26391, 16459 => 28010, 16460 => 25438,464 16461 => 21171, 16462 => 29282, 16463 => 32769, 16464 => 20332, 16465 => 23013,465 16466 => 37226, 16467 => 28889, 16468 => 28061, 16469 => 21202, 16470 => 20048,466 16471 => 38647, 16472 => 38253, 16473 => 34174, 16474 => 30922, 16475 => 32047,467 16476 => 20769, 16477 => 22418, 16478 => 25794, 16479 => 32907, 16480 => 31867,468 16481 => 27882, 16482 => 26865, 16483 => 26974, 16484 => 20919, 16485 => 21400,469 16486 => 26792, 16487 => 29313, 16488 => 40654, 16489 => 31729, 16490 => 29432,470 16491 => 31163, 16492 => 28435, 16493 => 29702, 16494 => 26446, 16495 => 37324,471 16496 => 40100, 16497 => 31036, 16498 => 33673, 16499 => 33620, 16500 => 21519,472 16501 => 26647, 16502 => 20029, 16503 => 21385, 16504 => 21169, 16505 => 30782,473 16506 => 21382, 16507 => 21033, 16508 => 20616, 16509 => 20363, 16510 => 20432,474 16673 => 30178, 16674 => 31435, 16675 => 31890, 16676 => 27813, 16677 => 38582,475 16678 => 21147, 16679 => 29827, 16680 => 21737, 16681 => 20457, 16682 => 32852,476 16683 => 33714, 16684 => 36830, 16685 => 38256, 16686 => 24265, 16687 => 24604,477 16688 => 28063, 16689 => 24088, 16690 => 25947, 16691 => 33080, 16692 => 38142,478 16693 => 24651, 16694 => 28860, 16695 => 32451, 16696 => 31918, 16697 => 20937,479 16698 => 26753, 16699 => 31921, 16700 => 33391, 16701 => 20004, 16702 => 36742,480 16703 => 37327, 16704 => 26238, 16705 => 20142, 16706 => 35845, 16707 => 25769,481 16708 => 32842, 16709 => 20698, 16710 => 30103, 16711 => 29134, 16712 => 23525,482 16713 => 36797, 16714 => 28518, 16715 => 20102, 16716 => 25730, 16717 => 38243,483 16718 => 24278, 16719 => 26009, 16720 => 21015, 16721 => 35010, 16722 => 28872,484 16723 => 21155, 16724 => 29454, 16725 => 29747, 16726 => 26519, 16727 => 30967,485 16728 => 38678, 16729 => 20020, 16730 => 37051, 16731 => 40158, 16732 => 28107,486 16733 => 20955, 16734 => 36161, 16735 => 21533, 16736 => 25294, 16737 => 29618,487 16738 => 33777, 16739 => 38646, 16740 => 40836, 16741 => 38083, 16742 => 20278,488 16743 => 32666, 16744 => 20940, 16745 => 28789, 16746 => 38517, 16747 => 23725,489 16748 => 39046, 16749 => 21478, 16750 => 20196, 16751 => 28316, 16752 => 29705,490 16753 => 27060, 16754 => 30827, 16755 => 39311, 16756 => 30041, 16757 => 21016,491 16758 => 30244, 16759 => 27969, 16760 => 26611, 16761 => 20845, 16762 => 40857,492 16763 => 32843, 16764 => 21657, 16765 => 31548, 16766 => 31423, 16929 => 38534,493 16930 => 22404, 16931 => 25314, 16932 => 38471, 16933 => 27004, 16934 => 23044,494 16935 => 25602, 16936 => 31699, 16937 => 28431, 16938 => 38475, 16939 => 33446,495 16940 => 21346, 16941 => 39045, 16942 => 24208, 16943 => 28809, 16944 => 25523,496 16945 => 21348, 16946 => 34383, 16947 => 40065, 16948 => 40595, 16949 => 30860,497 16950 => 38706, 16951 => 36335, 16952 => 36162, 16953 => 40575, 16954 => 28510,498 16955 => 31108, 16956 => 24405, 16957 => 38470, 16958 => 25134, 16959 => 39540,499 16960 => 21525, 16961 => 38109, 16962 => 20387, 16963 => 26053, 16964 => 23653,500 16965 => 23649, 16966 => 32533, 16967 => 34385, 16968 => 27695, 16969 => 24459,501 16970 => 29575, 16971 => 28388, 16972 => 32511, 16973 => 23782, 16974 => 25371,502 16975 => 23402, 16976 => 28390, 16977 => 21365, 16978 => 20081, 16979 => 25504,503 16980 => 30053, 16981 => 25249, 16982 => 36718, 16983 => 20262, 16984 => 20177,504 16985 => 27814, 16986 => 32438, 16987 => 35770, 16988 => 33821, 16989 => 34746,505 16990 => 32599, 16991 => 36923, 16992 => 38179, 16993 => 31657, 16994 => 39585,506 16995 => 35064, 16996 => 33853, 16997 => 27931, 16998 => 39558, 16999 => 32476,507 17000 => 22920, 17001 => 40635, 17002 => 29595, 17003 => 30721, 17004 => 34434,508 17005 => 39532, 17006 => 39554, 17007 => 22043, 17008 => 21527, 17009 => 22475,509 17010 => 20080, 17011 => 40614, 17012 => 21334, 17013 => 36808, 17014 => 33033,510 17015 => 30610, 17016 => 39314, 17017 => 34542, 17018 => 28385, 17019 => 34067,511 17020 => 26364, 17021 => 24930, 17022 => 28459, 17185 => 35881, 17186 => 33426,512 17187 => 33579, 17188 => 30450, 17189 => 27667, 17190 => 24537, 17191 => 33725,513 17192 => 29483, 17193 => 33541, 17194 => 38170, 17195 => 27611, 17196 => 30683,514 17197 => 38086, 17198 => 21359, 17199 => 33538, 17200 => 20882, 17201 => 24125,515 17202 => 35980, 17203 => 36152, 17204 => 20040, 17205 => 29611, 17206 => 26522,516 17207 => 26757, 17208 => 37238, 17209 => 38665, 17210 => 29028, 17211 => 27809,517 17212 => 30473, 17213 => 23186, 17214 => 38209, 17215 => 27599, 17216 => 32654,518 17217 => 26151, 17218 => 23504, 17219 => 22969, 17220 => 23194, 17221 => 38376,519 17222 => 38391, 17223 => 20204, 17224 => 33804, 17225 => 33945, 17226 => 27308,520 17227 => 30431, 17228 => 38192, 17229 => 29467, 17230 => 26790, 17231 => 23391,521 17232 => 30511, 17233 => 37274, 17234 => 38753, 17235 => 31964, 17236 => 36855,522 17237 => 35868, 17238 => 24357, 17239 => 31859, 17240 => 31192, 17241 => 35269,523 17242 => 27852, 17243 => 34588, 17244 => 23494, 17245 => 24130, 17246 => 26825,524 17247 => 30496, 17248 => 32501, 17249 => 20885, 17250 => 20813, 17251 => 21193,525 17252 => 23081, 17253 => 32517, 17254 => 38754, 17255 => 33495, 17256 => 25551,526 17257 => 30596, 17258 => 34256, 17259 => 31186, 17260 => 28218, 17261 => 24217,527 17262 => 22937, 17263 => 34065, 17264 => 28781, 17265 => 27665, 17266 => 25279,528 17267 => 30399, 17268 => 25935, 17269 => 24751, 17270 => 38397, 17271 => 26126,529 17272 => 34719, 17273 => 40483, 17274 => 38125, 17275 => 21517, 17276 => 21629,530 17277 => 35884, 17278 => 25720, 17441 => 25721, 17442 => 34321, 17443 => 27169,531 17444 => 33180, 17445 => 30952, 17446 => 25705, 17447 => 39764, 17448 => 25273,532 17449 => 26411, 17450 => 33707, 17451 => 22696, 17452 => 40664, 17453 => 27819,533 17454 => 28448, 17455 => 23518, 17456 => 38476, 17457 => 35851, 17458 => 29279,534 17459 => 26576, 17460 => 25287, 17461 => 29281, 17462 => 20137, 17463 => 22982,535 17464 => 27597, 17465 => 22675, 17466 => 26286, 17467 => 24149, 17468 => 21215,536 17469 => 24917, 17470 => 26408, 17471 => 30446, 17472 => 30566, 17473 => 29287,537 17474 => 31302, 17475 => 25343, 17476 => 21738, 17477 => 21584, 17478 => 38048,538 17479 => 37027, 17480 => 23068, 17481 => 32435, 17482 => 27670, 17483 => 20035,539 17484 => 22902, 17485 => 32784, 17486 => 22856, 17487 => 21335, 17488 => 30007,540 17489 => 38590, 17490 => 22218, 17491 => 25376, 17492 => 33041, 17493 => 24700,541 17494 => 38393, 17495 => 28118, 17496 => 21602, 17497 => 39297, 17498 => 20869,542 17499 => 23273, 17500 => 33021, 17501 => 22958, 17502 => 38675, 17503 => 20522,543 17504 => 27877, 17505 => 23612, 17506 => 25311, 17507 => 20320, 17508 => 21311,544 17509 => 33147, 17510 => 36870, 17511 => 28346, 17512 => 34091, 17513 => 25288,545 17514 => 24180, 17515 => 30910, 17516 => 25781, 17517 => 25467, 17518 => 24565,546 17519 => 23064, 17520 => 37247, 17521 => 40479, 17522 => 23615, 17523 => 25423,547 17524 => 32834, 17525 => 23421, 17526 => 21870, 17527 => 38218, 17528 => 38221,548 17529 => 28037, 17530 => 24744, 17531 => 26592, 17532 => 29406, 17533 => 20957,549 17534 => 23425, 17697 => 25319, 17698 => 27870, 17699 => 29275, 17700 => 25197,550 17701 => 38062, 17702 => 32445, 17703 => 33043, 17704 => 27987, 17705 => 20892,551 17706 => 24324, 17707 => 22900, 17708 => 21162, 17709 => 24594, 17710 => 22899,552 17711 => 26262, 17712 => 34384, 17713 => 30111, 17714 => 25386, 17715 => 25062,553 17716 => 31983, 17717 => 35834, 17718 => 21734, 17719 => 27431, 17720 => 40485,554 17721 => 27572, 17722 => 34261, 17723 => 21589, 17724 => 20598, 17725 => 27812,555 17726 => 21866, 17727 => 36276, 17728 => 29228, 17729 => 24085, 17730 => 24597,556 17731 => 29750, 17732 => 25293, 17733 => 25490, 17734 => 29260, 17735 => 24472,557 17736 => 28227, 17737 => 27966, 17738 => 25856, 17739 => 28504, 17740 => 30424,558 17741 => 30928, 17742 => 30460, 17743 => 30036, 17744 => 21028, 17745 => 21467,559 17746 => 20051, 17747 => 24222, 17748 => 26049, 17749 => 32810, 17750 => 32982,560 17751 => 25243, 17752 => 21638, 17753 => 21032, 17754 => 28846, 17755 => 34957,561 17756 => 36305, 17757 => 27873, 17758 => 21624, 17759 => 32986, 17760 => 22521,562 17761 => 35060, 17762 => 36180, 17763 => 38506, 17764 => 37197, 17765 => 20329,563 17766 => 27803, 17767 => 21943, 17768 => 30406, 17769 => 30768, 17770 => 25256,564 17771 => 28921, 17772 => 28558, 17773 => 24429, 17774 => 34028, 17775 => 26842,565 17776 => 30844, 17777 => 31735, 17778 => 33192, 17779 => 26379, 17780 => 40527,566 17781 => 25447, 17782 => 30896, 17783 => 22383, 17784 => 30738, 17785 => 38713,567 17786 => 25209, 17787 => 25259, 17788 => 21128, 17789 => 29749, 17790 => 27607,568 17953 => 21860, 17954 => 33086, 17955 => 30130, 17956 => 30382, 17957 => 21305,569 17958 => 30174, 17959 => 20731, 17960 => 23617, 17961 => 35692, 17962 => 31687,570 17963 => 20559, 17964 => 29255, 17965 => 39575, 17966 => 39128, 17967 => 28418,571 17968 => 29922, 17969 => 31080, 17970 => 25735, 17971 => 30629, 17972 => 25340,572 17973 => 39057, 17974 => 36139, 17975 => 21697, 17976 => 32856, 17977 => 20050,573 17978 => 22378, 17979 => 33529, 17980 => 33805, 17981 => 24179, 17982 => 20973,574 17983 => 29942, 17984 => 35780, 17985 => 23631, 17986 => 22369, 17987 => 27900,575 17988 => 39047, 17989 => 23110, 17990 => 30772, 17991 => 39748, 17992 => 36843,576 17993 => 31893, 17994 => 21078, 17995 => 25169, 17996 => 38138, 17997 => 20166,577 17998 => 33670, 17999 => 33889, 18000 => 33769, 18001 => 33970, 18002 => 22484,578 18003 => 26420, 18004 => 22275, 18005 => 26222, 18006 => 28006, 18007 => 35889,579 18008 => 26333, 18009 => 28689, 18010 => 26399, 18011 => 27450, 18012 => 26646,580 18013 => 25114, 18014 => 22971, 18015 => 19971, 18016 => 20932, 18017 => 28422,581 18018 => 26578, 18019 => 27791, 18020 => 20854, 18021 => 26827, 18022 => 22855,582 18023 => 27495, 18024 => 30054, 18025 => 23822, 18026 => 33040, 18027 => 40784,583 18028 => 26071, 18029 => 31048, 18030 => 31041, 18031 => 39569, 18032 => 36215,584 18033 => 23682, 18034 => 20062, 18035 => 20225, 18036 => 21551, 18037 => 22865,585 18038 => 30732, 18039 => 22120, 18040 => 27668, 18041 => 36804, 18042 => 24323,586 18043 => 27773, 18044 => 27875, 18045 => 35755, 18046 => 25488, 18209 => 24688,587 18210 => 27965, 18211 => 29301, 18212 => 25190, 18213 => 38030, 18214 => 38085,588 18215 => 21315, 18216 => 36801, 18217 => 31614, 18218 => 20191, 18219 => 35878,589 18220 => 20094, 18221 => 40660, 18222 => 38065, 18223 => 38067, 18224 => 21069,590 18225 => 28508, 18226 => 36963, 18227 => 27973, 18228 => 35892, 18229 => 22545,591 18230 => 23884, 18231 => 27424, 18232 => 27465, 18233 => 26538, 18234 => 21595,592 18235 => 33108, 18236 => 32652, 18237 => 22681, 18238 => 34103, 18239 => 24378,593 18240 => 25250, 18241 => 27207, 18242 => 38201, 18243 => 25970, 18244 => 24708,594 18245 => 26725, 18246 => 30631, 18247 => 20052, 18248 => 20392, 18249 => 24039,595 18250 => 38808, 18251 => 25772, 18252 => 32728, 18253 => 23789, 18254 => 20431,596 18255 => 31373, 18256 => 20999, 18257 => 33540, 18258 => 19988, 18259 => 24623,597 18260 => 31363, 18261 => 38054, 18262 => 20405, 18263 => 20146, 18264 => 31206,598 18265 => 29748, 18266 => 21220, 18267 => 33465, 18268 => 25810, 18269 => 31165,599 18270 => 23517, 18271 => 27777, 18272 => 38738, 18273 => 36731, 18274 => 27682,600 18275 => 20542, 18276 => 21375, 18277 => 28165, 18278 => 25806, 18279 => 26228,601 18280 => 27696, 18281 => 24773, 18282 => 39031, 18283 => 35831, 18284 => 24198,602 18285 => 29756, 18286 => 31351, 18287 => 31179, 18288 => 19992, 18289 => 37041,603 18290 => 29699, 18291 => 27714, 18292 => 22234, 18293 => 37195, 18294 => 27845,604 18295 => 36235, 18296 => 21306, 18297 => 34502, 18298 => 26354, 18299 => 36527,605 18300 => 23624, 18301 => 39537, 18302 => 28192, 18465 => 21462, 18466 => 23094,606 18467 => 40843, 18468 => 36259, 18469 => 21435, 18470 => 22280, 18471 => 39079,607 18472 => 26435, 18473 => 37275, 18474 => 27849, 18475 => 20840, 18476 => 30154,608 18477 => 25331, 18478 => 29356, 18479 => 21048, 18480 => 21149, 18481 => 32570,609 18482 => 28820, 18483 => 30264, 18484 => 21364, 18485 => 40522, 18486 => 27063,610 18487 => 30830, 18488 => 38592, 18489 => 35033, 18490 => 32676, 18491 => 28982,611 18492 => 29123, 18493 => 20873, 18494 => 26579, 18495 => 29924, 18496 => 22756,612 18497 => 25880, 18498 => 22199, 18499 => 35753, 18500 => 39286, 18501 => 25200,613 18502 => 32469, 18503 => 24825, 18504 => 28909, 18505 => 22764, 18506 => 20161,614 18507 => 20154, 18508 => 24525, 18509 => 38887, 18510 => 20219, 18511 => 35748,615 18512 => 20995, 18513 => 22922, 18514 => 32427, 18515 => 25172, 18516 => 20173,616 18517 => 26085, 18518 => 25102, 18519 => 33592, 18520 => 33993, 18521 => 33635,617 18522 => 34701, 18523 => 29076, 18524 => 28342, 18525 => 23481, 18526 => 32466,618 18527 => 20887, 18528 => 25545, 18529 => 26580, 18530 => 32905, 18531 => 33593,619 18532 => 34837, 18533 => 20754, 18534 => 23418, 18535 => 22914, 18536 => 36785,620 18537 => 20083, 18538 => 27741, 18539 => 20837, 18540 => 35109, 18541 => 36719,621 18542 => 38446, 18543 => 34122, 18544 => 29790, 18545 => 38160, 18546 => 38384,622 18547 => 28070, 18548 => 33509, 18549 => 24369, 18550 => 25746, 18551 => 27922,623 18552 => 33832, 18553 => 33134, 18554 => 40131, 18555 => 22622, 18556 => 36187,624 18557 => 19977, 18558 => 21441, 18721 => 20254, 18722 => 25955, 18723 => 26705,625 18724 => 21971, 18725 => 20007, 18726 => 25620, 18727 => 39578, 18728 => 25195,626 18729 => 23234, 18730 => 29791, 18731 => 33394, 18732 => 28073, 18733 => 26862,627 18734 => 20711, 18735 => 33678, 18736 => 30722, 18737 => 26432, 18738 => 21049,628 18739 => 27801, 18740 => 32433, 18741 => 20667, 18742 => 21861, 18743 => 29022,629 18744 => 31579, 18745 => 26194, 18746 => 29642, 18747 => 33515, 18748 => 26441,630 18749 => 23665, 18750 => 21024, 18751 => 29053, 18752 => 34923, 18753 => 38378,631 18754 => 38485, 18755 => 25797, 18756 => 36193, 18757 => 33203, 18758 => 21892,632 18759 => 27733, 18760 => 25159, 18761 => 32558, 18762 => 22674, 18763 => 20260,633 18764 => 21830, 18765 => 36175, 18766 => 26188, 18767 => 19978, 18768 => 23578,634 18769 => 35059, 18770 => 26786, 18771 => 25422, 18772 => 31245, 18773 => 28903,635 18774 => 33421, 18775 => 21242, 18776 => 38902, 18777 => 23569, 18778 => 21736,636 18779 => 37045, 18780 => 32461, 18781 => 22882, 18782 => 36170, 18783 => 34503,637 18784 => 33292, 18785 => 33293, 18786 => 36198, 18787 => 25668, 18788 => 23556,638 18789 => 24913, 18790 => 28041, 18791 => 31038, 18792 => 35774, 18793 => 30775,639 18794 => 30003, 18795 => 21627, 18796 => 20280, 18797 => 36523, 18798 => 28145,640 18799 => 23072, 18800 => 32453, 18801 => 31070, 18802 => 27784, 18803 => 23457,641 18804 => 23158, 18805 => 29978, 18806 => 32958, 18807 => 24910, 18808 => 28183,642 18809 => 22768, 18810 => 29983, 18811 => 29989, 18812 => 29298, 18813 => 21319,643 18814 => 32499, 18977 => 30465, 18978 => 30427, 18979 => 21097, 18980 => 32988,644 18981 => 22307, 18982 => 24072, 18983 => 22833, 18984 => 29422, 18985 => 26045,645 18986 => 28287, 18987 => 35799, 18988 => 23608, 18989 => 34417, 18990 => 21313,646 18991 => 30707, 18992 => 25342, 18993 => 26102, 18994 => 20160, 18995 => 39135,647 18996 => 34432, 18997 => 23454, 18998 => 35782, 18999 => 21490, 19000 => 30690,648 19001 => 20351, 19002 => 23630, 19003 => 39542, 19004 => 22987, 19005 => 24335,649 19006 => 31034, 19007 => 22763, 19008 => 19990, 19009 => 26623, 19010 => 20107,650 19011 => 25325, 19012 => 35475, 19013 => 36893, 19014 => 21183, 19015 => 26159,651 19016 => 21980, 19017 => 22124, 19018 => 36866, 19019 => 20181, 19020 => 20365,652 19021 => 37322, 19022 => 39280, 19023 => 27663, 19024 => 24066, 19025 => 24643,653 19026 => 23460, 19027 => 35270, 19028 => 35797, 19029 => 25910, 19030 => 25163,654 19031 => 39318, 19032 => 23432, 19033 => 23551, 19034 => 25480, 19035 => 21806,655 19036 => 21463, 19037 => 30246, 19038 => 20861, 19039 => 34092, 19040 => 26530,656 19041 => 26803, 19042 => 27530, 19043 => 25234, 19044 => 36755, 19045 => 21460,657 19046 => 33298, 19047 => 28113, 19048 => 30095, 19049 => 20070, 19050 => 36174,658 19051 => 23408, 19052 => 29087, 19053 => 34223, 19054 => 26257, 19055 => 26329,659 19056 => 32626, 19057 => 34560, 19058 => 40653, 19059 => 40736, 19060 => 23646,660 19061 => 26415, 19062 => 36848, 19063 => 26641, 19064 => 26463, 19065 => 25101,661 19066 => 31446, 19067 => 22661, 19068 => 24246, 19069 => 25968, 19070 => 28465,662 19233 => 24661, 19234 => 21047, 19235 => 32781, 19236 => 25684, 19237 => 34928,663 19238 => 29993, 19239 => 24069, 19240 => 26643, 19241 => 25332, 19242 => 38684,664 19243 => 21452, 19244 => 29245, 19245 => 35841, 19246 => 27700, 19247 => 30561,665 19248 => 31246, 19249 => 21550, 19250 => 30636, 19251 => 39034, 19252 => 33308,666 19253 => 35828, 19254 => 30805, 19255 => 26388, 19256 => 28865, 19257 => 26031,667 19258 => 25749, 19259 => 22070, 19260 => 24605, 19261 => 31169, 19262 => 21496,668 19263 => 19997, 19264 => 27515, 19265 => 32902, 19266 => 23546, 19267 => 21987,669 19268 => 22235, 19269 => 20282, 19270 => 20284, 19271 => 39282, 19272 => 24051,670 19273 => 26494, 19274 => 32824, 19275 => 24578, 19276 => 39042, 19277 => 36865,671 19278 => 23435, 19279 => 35772, 19280 => 35829, 19281 => 25628, 19282 => 33368,672 19283 => 25822, 19284 => 22013, 19285 => 33487, 19286 => 37221, 19287 => 20439,673 19288 => 32032, 19289 => 36895, 19290 => 31903, 19291 => 20723, 19292 => 22609,674 19293 => 28335, 19294 => 23487, 19295 => 35785, 19296 => 32899, 19297 => 37240,675 19298 => 33948, 19299 => 31639, 19300 => 34429, 19301 => 38539, 19302 => 38543,676 19303 => 32485, 19304 => 39635, 19305 => 30862, 19306 => 23681, 19307 => 31319,677 19308 => 36930, 19309 => 38567, 19310 => 31071, 19311 => 23385, 19312 => 25439,678 19313 => 31499, 19314 => 34001, 19315 => 26797, 19316 => 21766, 19317 => 32553,679 19318 => 29712, 19319 => 32034, 19320 => 38145, 19321 => 25152, 19322 => 22604,680 19323 => 20182, 19324 => 23427, 19325 => 22905, 19326 => 22612, 19489 => 29549,681 19490 => 25374, 19491 => 36427, 19492 => 36367, 19493 => 32974, 19494 => 33492,682 19495 => 25260, 19496 => 21488, 19497 => 27888, 19498 => 37214, 19499 => 22826,683 19500 => 24577, 19501 => 27760, 19502 => 22349, 19503 => 25674, 19504 => 36138,684 19505 => 30251, 19506 => 28393, 19507 => 22363, 19508 => 27264, 19509 => 30192,685 19510 => 28525, 19511 => 35885, 19512 => 35848, 19513 => 22374, 19514 => 27631,686 19515 => 34962, 19516 => 30899, 19517 => 25506, 19518 => 21497, 19519 => 28845,687 19520 => 27748, 19521 => 22616, 19522 => 25642, 19523 => 22530, 19524 => 26848,688 19525 => 33179, 19526 => 21776, 19527 => 31958, 19528 => 20504, 19529 => 36538,689 19530 => 28108, 19531 => 36255, 19532 => 28907, 19533 => 25487, 19534 => 28059,690 19535 => 28372, 19536 => 32486, 19537 => 33796, 19538 => 26691, 19539 => 36867,691 19540 => 28120, 19541 => 38518, 19542 => 35752, 19543 => 22871, 19544 => 29305,692 19545 => 34276, 19546 => 33150, 19547 => 30140, 19548 => 35466, 19549 => 26799,693 19550 => 21076, 19551 => 36386, 19552 => 38161, 19553 => 25552, 19554 => 39064,694 19555 => 36420, 19556 => 21884, 19557 => 20307, 19558 => 26367, 19559 => 22159,695 19560 => 24789, 19561 => 28053, 19562 => 21059, 19563 => 23625, 19564 => 22825,696 19565 => 28155, 19566 => 22635, 19567 => 30000, 19568 => 29980, 19569 => 24684,697 19570 => 33300, 19571 => 33094, 19572 => 25361, 19573 => 26465, 19574 => 36834,698 19575 => 30522, 19576 => 36339, 19577 => 36148, 19578 => 38081, 19579 => 24086,699 19580 => 21381, 19581 => 21548, 19582 => 28867, 19745 => 27712, 19746 => 24311,700 19747 => 20572, 19748 => 20141, 19749 => 24237, 19750 => 25402, 19751 => 33351,701 19752 => 36890, 19753 => 26704, 19754 => 37230, 19755 => 30643, 19756 => 21516,702 19757 => 38108, 19758 => 24420, 19759 => 31461, 19760 => 26742, 19761 => 25413,703 19762 => 31570, 19763 => 32479, 19764 => 30171, 19765 => 20599, 19766 => 25237,704 19767 => 22836, 19768 => 36879, 19769 => 20984, 19770 => 31171, 19771 => 31361,705 19772 => 22270, 19773 => 24466, 19774 => 36884, 19775 => 28034, 19776 => 23648,706 19777 => 22303, 19778 => 21520, 19779 => 20820, 19780 => 28237, 19781 => 22242,707 19782 => 25512, 19783 => 39059, 19784 => 33151, 19785 => 34581, 19786 => 35114,708 19787 => 36864, 19788 => 21534, 19789 => 23663, 19790 => 33216, 19791 => 25302,709 19792 => 25176, 19793 => 33073, 19794 => 40501, 19795 => 38464, 19796 => 39534,710 19797 => 39548, 19798 => 26925, 19799 => 22949, 19800 => 25299, 19801 => 21822,711 19802 => 25366, 19803 => 21703, 19804 => 34521, 19805 => 27964, 19806 => 23043,712 19807 => 29926, 19808 => 34972, 19809 => 27498, 19810 => 22806, 19811 => 35916,713 19812 => 24367, 19813 => 28286, 19814 => 29609, 19815 => 39037, 19816 => 20024,714 19817 => 28919, 19818 => 23436, 19819 => 30871, 19820 => 25405, 19821 => 26202,715 19822 => 30358, 19823 => 24779, 19824 => 23451, 19825 => 23113, 19826 => 19975,716 19827 => 33109, 19828 => 27754, 19829 => 29579, 19830 => 20129, 19831 => 26505,717 19832 => 32593, 19833 => 24448, 19834 => 26106, 19835 => 26395, 19836 => 24536,718 19837 => 22916, 19838 => 23041, 20001 => 24013, 20002 => 24494, 20003 => 21361,719 20004 => 38886, 20005 => 36829, 20006 => 26693, 20007 => 22260, 20008 => 21807,720 20009 => 24799, 20010 => 20026, 20011 => 28493, 20012 => 32500, 20013 => 33479,721 20014 => 33806, 20015 => 22996, 20016 => 20255, 20017 => 20266, 20018 => 23614,722 20019 => 32428, 20020 => 26410, 20021 => 34074, 20022 => 21619, 20023 => 30031,723 20024 => 32963, 20025 => 21890, 20026 => 39759, 20027 => 20301, 20028 => 28205,724 20029 => 35859, 20030 => 23561, 20031 => 24944, 20032 => 21355, 20033 => 30239,725 20034 => 28201, 20035 => 34442, 20036 => 25991, 20037 => 38395, 20038 => 32441,726 20039 => 21563, 20040 => 31283, 20041 => 32010, 20042 => 38382, 20043 => 21985,727 20044 => 32705, 20045 => 29934, 20046 => 25373, 20047 => 34583, 20048 => 28065,728 20049 => 31389, 20050 => 25105, 20051 => 26017, 20052 => 21351, 20053 => 25569,729 20054 => 27779, 20055 => 24043, 20056 => 21596, 20057 => 38056, 20058 => 20044,730 20059 => 27745, 20060 => 35820, 20061 => 23627, 20062 => 26080, 20063 => 33436,731 20064 => 26791, 20065 => 21566, 20066 => 21556, 20067 => 27595, 20068 => 27494,732 20069 => 20116, 20070 => 25410, 20071 => 21320, 20072 => 33310, 20073 => 20237,733 20074 => 20398, 20075 => 22366, 20076 => 25098, 20077 => 38654, 20078 => 26212,734 20079 => 29289, 20080 => 21247, 20081 => 21153, 20082 => 24735, 20083 => 35823,735 20084 => 26132, 20085 => 29081, 20086 => 26512, 20087 => 35199, 20088 => 30802,736 20089 => 30717, 20090 => 26224, 20091 => 22075, 20092 => 21560, 20093 => 38177,737 20094 => 29306, 20257 => 31232, 20258 => 24687, 20259 => 24076, 20260 => 24713,738 20261 => 33181, 20262 => 22805, 20263 => 24796, 20264 => 29060, 20265 => 28911,739 20266 => 28330, 20267 => 27728, 20268 => 29312, 20269 => 27268, 20270 => 34989,740 20271 => 24109, 20272 => 20064, 20273 => 23219, 20274 => 21916, 20275 => 38115,741 20276 => 27927, 20277 => 31995, 20278 => 38553, 20279 => 25103, 20280 => 32454,742 20281 => 30606, 20282 => 34430, 20283 => 21283, 20284 => 38686, 20285 => 36758,743 20286 => 26247, 20287 => 23777, 20288 => 20384, 20289 => 29421, 20290 => 19979,744 20291 => 21414, 20292 => 22799, 20293 => 21523, 20294 => 25472, 20295 => 38184,745 20296 => 20808, 20297 => 20185, 20298 => 40092, 20299 => 32420, 20300 => 21688,746 20301 => 36132, 20302 => 34900, 20303 => 33335, 20304 => 38386, 20305 => 28046,747 20306 => 24358, 20307 => 23244, 20308 => 26174, 20309 => 38505, 20310 => 29616,748 20311 => 29486, 20312 => 21439, 20313 => 33146, 20314 => 39301, 20315 => 32673,749 20316 => 23466, 20317 => 38519, 20318 => 38480, 20319 => 32447, 20320 => 30456,750 20321 => 21410, 20322 => 38262, 20323 => 39321, 20324 => 31665, 20325 => 35140,751 20326 => 28248, 20327 => 20065, 20328 => 32724, 20329 => 31077, 20330 => 35814,752 20331 => 24819, 20332 => 21709, 20333 => 20139, 20334 => 39033, 20335 => 24055,753 20336 => 27233, 20337 => 20687, 20338 => 21521, 20339 => 35937, 20340 => 33831,754 20341 => 30813, 20342 => 38660, 20343 => 21066, 20344 => 21742, 20345 => 22179,755 20346 => 38144, 20347 => 28040, 20348 => 23477, 20349 => 28102, 20350 => 26195,756 20513 => 23567, 20514 => 23389, 20515 => 26657, 20516 => 32918, 20517 => 21880,757 20518 => 31505, 20519 => 25928, 20520 => 26964, 20521 => 20123, 20522 => 27463,758 20523 => 34638, 20524 => 38795, 20525 => 21327, 20526 => 25375, 20527 => 25658,759 20528 => 37034, 20529 => 26012, 20530 => 32961, 20531 => 35856, 20532 => 20889,760 20533 => 26800, 20534 => 21368, 20535 => 34809, 20536 => 25032, 20537 => 27844,761 20538 => 27899, 20539 => 35874, 20540 => 23633, 20541 => 34218, 20542 => 33455,762 20543 => 38156, 20544 => 27427, 20545 => 36763, 20546 => 26032, 20547 => 24571,763 20548 => 24515, 20549 => 20449, 20550 => 34885, 20551 => 26143, 20552 => 33125,764 20553 => 29481, 20554 => 24826, 20555 => 20852, 20556 => 21009, 20557 => 22411,765 20558 => 24418, 20559 => 37026, 20560 => 34892, 20561 => 37266, 20562 => 24184,766 20563 => 26447, 20564 => 24615, 20565 => 22995, 20566 => 20804, 20567 => 20982,767 20568 => 33016, 20569 => 21256, 20570 => 27769, 20571 => 38596, 20572 => 29066,768 20573 => 20241, 20574 => 20462, 20575 => 32670, 20576 => 26429, 20577 => 21957,769 20578 => 38152, 20579 => 31168, 20580 => 34966, 20581 => 32483, 20582 => 22687,770 20583 => 25100, 20584 => 38656, 20585 => 34394, 20586 => 22040, 20587 => 39035,771 20588 => 24464, 20589 => 35768, 20590 => 33988, 20591 => 37207, 20592 => 21465,772 20593 => 26093, 20594 => 24207, 20595 => 30044, 20596 => 24676, 20597 => 32110,773 20598 => 23167, 20599 => 32490, 20600 => 32493, 20601 => 36713, 20602 => 21927,774 20603 => 23459, 20604 => 24748, 20605 => 26059, 20606 => 29572, 20769 => 36873,775 20770 => 30307, 20771 => 30505, 20772 => 32474, 20773 => 38772, 20774 => 34203,776 20775 => 23398, 20776 => 31348, 20777 => 38634, 20778 => 34880, 20779 => 21195,777 20780 => 29071, 20781 => 24490, 20782 => 26092, 20783 => 35810, 20784 => 23547,778 20785 => 39535, 20786 => 24033, 20787 => 27529, 20788 => 27739, 20789 => 35757,779 20790 => 35759, 20791 => 36874, 20792 => 36805, 20793 => 21387, 20794 => 25276,780 20795 => 40486, 20796 => 40493, 20797 => 21568, 20798 => 20011, 20799 => 33469,781 20800 => 29273, 20801 => 34460, 20802 => 23830, 20803 => 34905, 20804 => 28079,782 20805 => 38597, 20806 => 21713, 20807 => 20122, 20808 => 35766, 20809 => 28937,783 20810 => 21693, 20811 => 38409, 20812 => 28895, 20813 => 28153, 20814 => 30416,784 20815 => 20005, 20816 => 30740, 20817 => 34578, 20818 => 23721, 20819 => 24310,785 20820 => 35328, 20821 => 39068, 20822 => 38414, 20823 => 28814, 20824 => 27839,786 20825 => 22852, 20826 => 25513, 20827 => 30524, 20828 => 34893, 20829 => 28436,787 20830 => 33395, 20831 => 22576, 20832 => 29141, 20833 => 21388, 20834 => 30746,788 20835 => 38593, 20836 => 21761, 20837 => 24422, 20838 => 28976, 20839 => 23476,789 20840 => 35866, 20841 => 39564, 20842 => 27523, 20843 => 22830, 20844 => 40495,790 20845 => 31207, 20846 => 26472, 20847 => 25196, 20848 => 20335, 20849 => 30113,791 20850 => 32650, 20851 => 27915, 20852 => 38451, 20853 => 27687, 20854 => 20208,792 20855 => 30162, 20856 => 20859, 20857 => 26679, 20858 => 28478, 20859 => 36992,793 20860 => 33136, 20861 => 22934, 20862 => 29814, 21025 => 25671, 21026 => 23591,794 21027 => 36965, 21028 => 31377, 21029 => 35875, 21030 => 23002, 21031 => 21676,795 21032 => 33280, 21033 => 33647, 21034 => 35201, 21035 => 32768, 21036 => 26928,796 21037 => 22094, 21038 => 32822, 21039 => 29239, 21040 => 37326, 21041 => 20918,797 21042 => 20063, 21043 => 39029, 21044 => 25494, 21045 => 19994, 21046 => 21494,798 21047 => 26355, 21048 => 33099, 21049 => 22812, 21050 => 28082, 21051 => 19968,799 21052 => 22777, 21053 => 21307, 21054 => 25558, 21055 => 38129, 21056 => 20381,800 21057 => 20234, 21058 => 34915, 21059 => 39056, 21060 => 22839, 21061 => 36951,801 21062 => 31227, 21063 => 20202, 21064 => 33008, 21065 => 30097, 21066 => 27778,802 21067 => 23452, 21068 => 23016, 21069 => 24413, 21070 => 26885, 21071 => 34433,803 21072 => 20506, 21073 => 24050, 21074 => 20057, 21075 => 30691, 21076 => 20197,804 21077 => 33402, 21078 => 25233, 21079 => 26131, 21080 => 37009, 21081 => 23673,805 21082 => 20159, 21083 => 24441, 21084 => 33222, 21085 => 36920, 21086 => 32900,806 21087 => 30123, 21088 => 20134, 21089 => 35028, 21090 => 24847, 21091 => 27589,807 21092 => 24518, 21093 => 20041, 21094 => 30410, 21095 => 28322, 21096 => 35811,808 21097 => 35758, 21098 => 35850, 21099 => 35793, 21100 => 24322, 21101 => 32764,809 21102 => 32716, 21103 => 32462, 21104 => 33589, 21105 => 33643, 21106 => 22240,810 21107 => 27575, 21108 => 38899, 21109 => 38452, 21110 => 23035, 21111 => 21535,811 21112 => 38134, 21113 => 28139, 21114 => 23493, 21115 => 39278, 21116 => 23609,812 21117 => 24341, 21118 => 38544, 21281 => 21360, 21282 => 33521, 21283 => 27185,813 21284 => 23156, 21285 => 40560, 21286 => 24212, 21287 => 32552, 21288 => 33721,814 21289 => 33828, 21290 => 33829, 21291 => 33639, 21292 => 34631, 21293 => 36814,815 21294 => 36194, 21295 => 30408, 21296 => 24433, 21297 => 39062, 21298 => 30828,816 21299 => 26144, 21300 => 21727, 21301 => 25317, 21302 => 20323, 21303 => 33219,817 21304 => 30152, 21305 => 24248, 21306 => 38605, 21307 => 36362, 21308 => 34553,818 21309 => 21647, 21310 => 27891, 21311 => 28044, 21312 => 27704, 21313 => 24703,819 21314 => 21191, 21315 => 29992, 21316 => 24189, 21317 => 20248, 21318 => 24736,820 21319 => 24551, 21320 => 23588, 21321 => 30001, 21322 => 37038, 21323 => 38080,821 21324 => 29369, 21325 => 27833, 21326 => 28216, 21327 => 37193, 21328 => 26377,822 21329 => 21451, 21330 => 21491, 21331 => 20305, 21332 => 37321, 21333 => 35825,823 21334 => 21448, 21335 => 24188, 21336 => 36802, 21337 => 28132, 21338 => 20110,824 21339 => 30402, 21340 => 27014, 21341 => 34398, 21342 => 24858, 21343 => 33286,825 21344 => 20313, 21345 => 20446, 21346 => 36926, 21347 => 40060, 21348 => 24841,826 21349 => 28189, 21350 => 28180, 21351 => 38533, 21352 => 20104, 21353 => 23089,827 21354 => 38632, 21355 => 19982, 21356 => 23679, 21357 => 31161, 21358 => 23431,828 21359 => 35821, 21360 => 32701, 21361 => 29577, 21362 => 22495, 21363 => 33419,829 21364 => 37057, 21365 => 21505, 21366 => 36935, 21367 => 21947, 21368 => 23786,830 21369 => 24481, 21370 => 24840, 21371 => 27442, 21372 => 29425, 21373 => 32946,831 21374 => 35465, 21537 => 28020, 21538 => 23507, 21539 => 35029, 21540 => 39044,832 21541 => 35947, 21542 => 39533, 21543 => 40499, 21544 => 28170, 21545 => 20900,833 21546 => 20803, 21547 => 22435, 21548 => 34945, 21549 => 21407, 21550 => 25588,834 21551 => 36757, 21552 => 22253, 21553 => 21592, 21554 => 22278, 21555 => 29503,835 21556 => 28304, 21557 => 32536, 21558 => 36828, 21559 => 33489, 21560 => 24895,836 21561 => 24616, 21562 => 38498, 21563 => 26352, 21564 => 32422, 21565 => 36234,837 21566 => 36291, 21567 => 38053, 21568 => 23731, 21569 => 31908, 21570 => 26376,838 21571 => 24742, 21572 => 38405, 21573 => 32792, 21574 => 20113, 21575 => 37095,839 21576 => 21248, 21577 => 38504, 21578 => 20801, 21579 => 36816, 21580 => 34164,840 21581 => 37213, 21582 => 26197, 21583 => 38901, 21584 => 23381, 21585 => 21277,841 21586 => 30776, 21587 => 26434, 21588 => 26685, 21589 => 21705, 21590 => 28798,842 21591 => 23472, 21592 => 36733, 21593 => 20877, 21594 => 22312, 21595 => 21681,843 21596 => 25874, 21597 => 26242, 21598 => 36190, 21599 => 36163, 21600 => 33039,844 21601 => 33900, 21602 => 36973, 21603 => 31967, 21604 => 20991, 21605 => 34299,845 21606 => 26531, 21607 => 26089, 21608 => 28577, 21609 => 34468, 21610 => 36481,846 21611 => 22122, 21612 => 36896, 21613 => 30338, 21614 => 28790, 21615 => 29157,847 21616 => 36131, 21617 => 25321, 21618 => 21017, 21619 => 27901, 21620 => 36156,848 21621 => 24590, 21622 => 22686, 21623 => 24974, 21624 => 26366, 21625 => 36192,849 21626 => 25166, 21627 => 21939, 21628 => 28195, 21629 => 26413, 21630 => 36711,850 21793 => 38113, 21794 => 38392, 21795 => 30504, 21796 => 26629, 21797 => 27048,851 21798 => 21643, 21799 => 20045, 21800 => 28856, 21801 => 35784, 21802 => 25688,852 21803 => 25995, 21804 => 23429, 21805 => 31364, 21806 => 20538, 21807 => 23528,853 21808 => 30651, 21809 => 27617, 21810 => 35449, 21811 => 31896, 21812 => 27838,854 21813 => 30415, 21814 => 26025, 21815 => 36759, 21816 => 23853, 21817 => 23637,855 21818 => 34360, 21819 => 26632, 21820 => 21344, 21821 => 25112, 21822 => 31449,856 21823 => 28251, 21824 => 32509, 21825 => 27167, 21826 => 31456, 21827 => 24432,857 21828 => 28467, 21829 => 24352, 21830 => 25484, 21831 => 28072, 21832 => 26454,858 21833 => 19976, 21834 => 24080, 21835 => 36134, 21836 => 20183, 21837 => 32960,859 21838 => 30260, 21839 => 38556, 21840 => 25307, 21841 => 26157, 21842 => 25214,860 21843 => 27836, 21844 => 36213, 21845 => 29031, 21846 => 32617, 21847 => 20806,861 21848 => 32903, 21849 => 21484, 21850 => 36974, 21851 => 25240, 21852 => 21746,862 21853 => 34544, 21854 => 36761, 21855 => 32773, 21856 => 38167, 21857 => 34071,863 21858 => 36825, 21859 => 27993, 21860 => 29645, 21861 => 26015, 21862 => 30495,864 21863 => 29956, 21864 => 30759, 21865 => 33275, 21866 => 36126, 21867 => 38024,865 21868 => 20390, 21869 => 26517, 21870 => 30137, 21871 => 35786, 21872 => 38663,866 21873 => 25391, 21874 => 38215, 21875 => 38453, 21876 => 33976, 21877 => 25379,867 21878 => 30529, 21879 => 24449, 21880 => 29424, 21881 => 20105, 21882 => 24596,868 21883 => 25972, 21884 => 25327, 21885 => 27491, 21886 => 25919, 22049 => 24103,869 22050 => 30151, 22051 => 37073, 22052 => 35777, 22053 => 33437, 22054 => 26525,870 22055 => 25903, 22056 => 21553, 22057 => 34584, 22058 => 30693, 22059 => 32930,871 22060 => 33026, 22061 => 27713, 22062 => 20043, 22063 => 32455, 22064 => 32844,872 22065 => 30452, 22066 => 26893, 22067 => 27542, 22068 => 25191, 22069 => 20540,873 22070 => 20356, 22071 => 22336, 22072 => 25351, 22073 => 27490, 22074 => 36286,874 22075 => 21482, 22076 => 26088, 22077 => 32440, 22078 => 24535, 22079 => 25370,875 22080 => 25527, 22081 => 33267, 22082 => 33268, 22083 => 32622, 22084 => 24092,876 22085 => 23769, 22086 => 21046, 22087 => 26234, 22088 => 31209, 22089 => 31258,877 22090 => 36136, 22091 => 28825, 22092 => 30164, 22093 => 28382, 22094 => 27835,878 22095 => 31378, 22096 => 20013, 22097 => 30405, 22098 => 24544, 22099 => 38047,879 22100 => 34935, 22101 => 32456, 22102 => 31181, 22103 => 32959, 22104 => 37325,880 22105 => 20210, 22106 => 20247, 22107 => 33311, 22108 => 21608, 22109 => 24030,881 22110 => 27954, 22111 => 35788, 22112 => 31909, 22113 => 36724, 22114 => 32920,882 22115 => 24090, 22116 => 21650, 22117 => 30385, 22118 => 23449, 22119 => 26172,883 22120 => 39588, 22121 => 29664, 22122 => 26666, 22123 => 34523, 22124 => 26417,884 22125 => 29482, 22126 => 35832, 22127 => 35803, 22128 => 36880, 22129 => 31481,885 22130 => 28891, 22131 => 29038, 22132 => 25284, 22133 => 30633, 22134 => 22065,886 22135 => 20027, 22136 => 33879, 22137 => 26609, 22138 => 21161, 22139 => 34496,887 22140 => 36142, 22141 => 38136, 22142 => 31569, 22305 => 20303, 22306 => 27880,888 22307 => 31069, 22308 => 39547, 22309 => 25235, 22310 => 29226, 22311 => 25341,889 22312 => 19987, 22313 => 30742, 22314 => 36716, 22315 => 25776, 22316 => 36186,890 22317 => 31686, 22318 => 26729, 22319 => 24196, 22320 => 35013, 22321 => 22918,891 22322 => 25758, 22323 => 22766, 22324 => 29366, 22325 => 26894, 22326 => 38181,892 22327 => 36861, 22328 => 36184, 22329 => 22368, 22330 => 32512, 22331 => 35846,893 22332 => 20934, 22333 => 25417, 22334 => 25305, 22335 => 21331, 22336 => 26700,894 22337 => 29730, 22338 => 33537, 22339 => 37196, 22340 => 21828, 22341 => 30528,895 22342 => 28796, 22343 => 27978, 22344 => 20857, 22345 => 21672, 22346 => 36164,896 22347 => 23039, 22348 => 28363, 22349 => 28100, 22350 => 23388, 22351 => 32043,897 22352 => 20180, 22353 => 31869, 22354 => 28371, 22355 => 23376, 22356 => 33258,898 22357 => 28173, 22358 => 23383, 22359 => 39683, 22360 => 26837, 22361 => 36394,899 22362 => 23447, 22363 => 32508, 22364 => 24635, 22365 => 32437, 22366 => 37049,900 22367 => 36208, 22368 => 22863, 22369 => 25549, 22370 => 31199, 22371 => 36275,901 22372 => 21330, 22373 => 26063, 22374 => 31062, 22375 => 35781, 22376 => 38459,902 22377 => 32452, 22378 => 38075, 22379 => 32386, 22380 => 22068, 22381 => 37257,903 22382 => 26368, 22383 => 32618, 22384 => 23562, 22385 => 36981, 22386 => 26152,904 22387 => 24038, 22388 => 20304, 22389 => 26590, 22390 => 20570, 22391 => 20316,905 22392 => 22352, 22393 => 24231, 22561 => 20109, 22562 => 19980, 22563 => 20800,906 22564 => 19984, 22565 => 24319, 22566 => 21317, 22567 => 19989, 22568 => 20120,907 22569 => 19998, 22570 => 39730, 22571 => 23404, 22572 => 22121, 22573 => 20008,908 22574 => 31162, 22575 => 20031, 22576 => 21269, 22577 => 20039, 22578 => 22829,909 22579 => 29243, 22580 => 21358, 22581 => 27664, 22582 => 22239, 22583 => 32996,910 22584 => 39319, 22585 => 27603, 22586 => 30590, 22587 => 40727, 22588 => 20022,911 22589 => 20127, 22590 => 40720, 22591 => 20060, 22592 => 20073, 22593 => 20115,912 22594 => 33416, 22595 => 23387, 22596 => 21868, 22597 => 22031, 22598 => 20164,913 22599 => 21389, 22600 => 21405, 22601 => 21411, 22602 => 21413, 22603 => 21422,914 22604 => 38757, 22605 => 36189, 22606 => 21274, 22607 => 21493, 22608 => 21286,915 22609 => 21294, 22610 => 21310, 22611 => 36188, 22612 => 21350, 22613 => 21347,916 22614 => 20994, 22615 => 21000, 22616 => 21006, 22617 => 21037, 22618 => 21043,917 22619 => 21055, 22620 => 21056, 22621 => 21068, 22622 => 21086, 22623 => 21089,918 22624 => 21084, 22625 => 33967, 22626 => 21117, 22627 => 21122, 22628 => 21121,919 22629 => 21136, 22630 => 21139, 22631 => 20866, 22632 => 32596, 22633 => 20155,920 22634 => 20163, 22635 => 20169, 22636 => 20162, 22637 => 20200, 22638 => 20193,921 22639 => 20203, 22640 => 20190, 22641 => 20251, 22642 => 20211, 22643 => 20258,922 22644 => 20324, 22645 => 20213, 22646 => 20261, 22647 => 20263, 22648 => 20233,923 22649 => 20267, 22650 => 20318, 22651 => 20327, 22652 => 25912, 22653 => 20314,924 22654 => 20317, 22817 => 20319, 22818 => 20311, 22819 => 20274, 22820 => 20285,925 22821 => 20342, 22822 => 20340, 22823 => 20369, 22824 => 20361, 22825 => 20355,926 22826 => 20367, 22827 => 20350, 22828 => 20347, 22829 => 20394, 22830 => 20348,927 22831 => 20396, 22832 => 20372, 22833 => 20454, 22834 => 20456, 22835 => 20458,928 22836 => 20421, 22837 => 20442, 22838 => 20451, 22839 => 20444, 22840 => 20433,929 22841 => 20447, 22842 => 20472, 22843 => 20521, 22844 => 20556, 22845 => 20467,930 22846 => 20524, 22847 => 20495, 22848 => 20526, 22849 => 20525, 22850 => 20478,931 22851 => 20508, 22852 => 20492, 22853 => 20517, 22854 => 20520, 22855 => 20606,932 22856 => 20547, 22857 => 20565, 22858 => 20552, 22859 => 20558, 22860 => 20588,933 22861 => 20603, 22862 => 20645, 22863 => 20647, 22864 => 20649, 22865 => 20666,934 22866 => 20694, 22867 => 20742, 22868 => 20717, 22869 => 20716, 22870 => 20710,935 22871 => 20718, 22872 => 20743, 22873 => 20747, 22874 => 20189, 22875 => 27709,936 22876 => 20312, 22877 => 20325, 22878 => 20430, 22879 => 40864, 22880 => 27718,937 22881 => 31860, 22882 => 20846, 22883 => 24061, 22884 => 40649, 22885 => 39320,938 22886 => 20865, 22887 => 22804, 22888 => 21241, 22889 => 21261, 22890 => 35335,939 22891 => 21264, 22892 => 20971, 22893 => 22809, 22894 => 20821, 22895 => 20128,940 22896 => 20822, 22897 => 20147, 22898 => 34926, 22899 => 34980, 22900 => 20149,941 22901 => 33044, 22902 => 35026, 22903 => 31104, 22904 => 23348, 22905 => 34819,942 22906 => 32696, 22907 => 20907, 22908 => 20913, 22909 => 20925, 22910 => 20924,943 23073 => 20935, 23074 => 20886, 23075 => 20898, 23076 => 20901, 23077 => 35744,944 23078 => 35750, 23079 => 35751, 23080 => 35754, 23081 => 35764, 23082 => 35765,945 23083 => 35767, 23084 => 35778, 23085 => 35779, 23086 => 35787, 23087 => 35791,946 23088 => 35790, 23089 => 35794, 23090 => 35795, 23091 => 35796, 23092 => 35798,947 23093 => 35800, 23094 => 35801, 23095 => 35804, 23096 => 35807, 23097 => 35808,948 23098 => 35812, 23099 => 35816, 23100 => 35817, 23101 => 35822, 23102 => 35824,949 23103 => 35827, 23104 => 35830, 23105 => 35833, 23106 => 35836, 23107 => 35839,950 23108 => 35840, 23109 => 35842, 23110 => 35844, 23111 => 35847, 23112 => 35852,951 23113 => 35855, 23114 => 35857, 23115 => 35858, 23116 => 35860, 23117 => 35861,952 23118 => 35862, 23119 => 35865, 23120 => 35867, 23121 => 35864, 23122 => 35869,953 23123 => 35871, 23124 => 35872, 23125 => 35873, 23126 => 35877, 23127 => 35879,954 23128 => 35882, 23129 => 35883, 23130 => 35886, 23131 => 35887, 23132 => 35890,955 23133 => 35891, 23134 => 35893, 23135 => 35894, 23136 => 21353, 23137 => 21370,956 23138 => 38429, 23139 => 38434, 23140 => 38433, 23141 => 38449, 23142 => 38442,957 23143 => 38461, 23144 => 38460, 23145 => 38466, 23146 => 38473, 23147 => 38484,958 23148 => 38495, 23149 => 38503, 23150 => 38508, 23151 => 38514, 23152 => 38516,959 23153 => 38536, 23154 => 38541, 23155 => 38551, 23156 => 38576, 23157 => 37015,960 23158 => 37019, 23159 => 37021, 23160 => 37017, 23161 => 37036, 23162 => 37025,961 23163 => 37044, 23164 => 37043, 23165 => 37046, 23166 => 37050, 23329 => 37048,962 23330 => 37040, 23331 => 37071, 23332 => 37061, 23333 => 37054, 23334 => 37072,963 23335 => 37060, 23336 => 37063, 23337 => 37075, 23338 => 37094, 23339 => 37090,964 23340 => 37084, 23341 => 37079, 23342 => 37083, 23343 => 37099, 23344 => 37103,965 23345 => 37118, 23346 => 37124, 23347 => 37154, 23348 => 37150, 23349 => 37155,966 23350 => 37169, 23351 => 37167, 23352 => 37177, 23353 => 37187, 23354 => 37190,967 23355 => 21005, 23356 => 22850, 23357 => 21154, 23358 => 21164, 23359 => 21165,968 23360 => 21182, 23361 => 21759, 23362 => 21200, 23363 => 21206, 23364 => 21232,969 23365 => 21471, 23366 => 29166, 23367 => 30669, 23368 => 24308, 23369 => 20981,970 23370 => 20988, 23371 => 39727, 23372 => 21430, 23373 => 24321, 23374 => 30042,971 23375 => 24047, 23376 => 22348, 23377 => 22441, 23378 => 22433, 23379 => 22654,972 23380 => 22716, 23381 => 22725, 23382 => 22737, 23383 => 22313, 23384 => 22316,973 23385 => 22314, 23386 => 22323, 23387 => 22329, 23388 => 22318, 23389 => 22319,974 23390 => 22364, 23391 => 22331, 23392 => 22338, 23393 => 22377, 23394 => 22405,975 23395 => 22379, 23396 => 22406, 23397 => 22396, 23398 => 22395, 23399 => 22376,976 23400 => 22381, 23401 => 22390, 23402 => 22387, 23403 => 22445, 23404 => 22436,977 23405 => 22412, 23406 => 22450, 23407 => 22479, 23408 => 22439, 23409 => 22452,978 23410 => 22419, 23411 => 22432, 23412 => 22485, 23413 => 22488, 23414 => 22490,979 23415 => 22489, 23416 => 22482, 23417 => 22456, 23418 => 22516, 23419 => 22511,980 23420 => 22520, 23421 => 22500, 23422 => 22493, 23585 => 22539, 23586 => 22541,981 23587 => 22525, 23588 => 22509, 23589 => 22528, 23590 => 22558, 23591 => 22553,982 23592 => 22596, 23593 => 22560, 23594 => 22629, 23595 => 22636, 23596 => 22657,983 23597 => 22665, 23598 => 22682, 23599 => 22656, 23600 => 39336, 23601 => 40729,984 23602 => 25087, 23603 => 33401, 23604 => 33405, 23605 => 33407, 23606 => 33423,985 23607 => 33418, 23608 => 33448, 23609 => 33412, 23610 => 33422, 23611 => 33425,986 23612 => 33431, 23613 => 33433, 23614 => 33451, 23615 => 33464, 23616 => 33470,987 23617 => 33456, 23618 => 33480, 23619 => 33482, 23620 => 33507, 23621 => 33432,988 23622 => 33463, 23623 => 33454, 23624 => 33483, 23625 => 33484, 23626 => 33473,989 23627 => 33449, 23628 => 33460, 23629 => 33441, 23630 => 33450, 23631 => 33439,990 23632 => 33476, 23633 => 33486, 23634 => 33444, 23635 => 33505, 23636 => 33545,991 23637 => 33527, 23638 => 33508, 23639 => 33551, 23640 => 33543, 23641 => 33500,992 23642 => 33524, 23643 => 33490, 23644 => 33496, 23645 => 33548, 23646 => 33531,993 23647 => 33491, 23648 => 33553, 23649 => 33562, 23650 => 33542, 23651 => 33556,994 23652 => 33557, 23653 => 33504, 23654 => 33493, 23655 => 33564, 23656 => 33617,995 23657 => 33627, 23658 => 33628, 23659 => 33544, 23660 => 33682, 23661 => 33596,996 23662 => 33588, 23663 => 33585, 23664 => 33691, 23665 => 33630, 23666 => 33583,997 23667 => 33615, 23668 => 33607, 23669 => 33603, 23670 => 33631, 23671 => 33600,998 23672 => 33559, 23673 => 33632, 23674 => 33581, 23675 => 33594, 23676 => 33587,999 23677 => 33638, 23678 => 33637, 23841 => 33640, 23842 => 33563, 23843 => 33641,1000 23844 => 33644, 23845 => 33642, 23846 => 33645, 23847 => 33646, 23848 => 33712,1001 23849 => 33656, 23850 => 33715, 23851 => 33716, 23852 => 33696, 23853 => 33706,1002 23854 => 33683, 23855 => 33692, 23856 => 33669, 23857 => 33660, 23858 => 33718,1003 23859 => 33705, 23860 => 33661, 23861 => 33720, 23862 => 33659, 23863 => 33688,1004 23864 => 33694, 23865 => 33704, 23866 => 33722, 23867 => 33724, 23868 => 33729,1005 23869 => 33793, 23870 => 33765, 23871 => 33752, 23872 => 22535, 23873 => 33816,1006 23874 => 33803, 23875 => 33757, 23876 => 33789, 23877 => 33750, 23878 => 33820,1007 23879 => 33848, 23880 => 33809, 23881 => 33798, 23882 => 33748, 23883 => 33759,1008 23884 => 33807, 23885 => 33795, 23886 => 33784, 23887 => 33785, 23888 => 33770,1009 23889 => 33733, 23890 => 33728, 23891 => 33830, 23892 => 33776, 23893 => 33761,1010 23894 => 33884, 23895 => 33873, 23896 => 33882, 23897 => 33881, 23898 => 33907,1011 23899 => 33927, 23900 => 33928, 23901 => 33914, 23902 => 33929, 23903 => 33912,1012 23904 => 33852, 23905 => 33862, 23906 => 33897, 23907 => 33910, 23908 => 33932,1013 23909 => 33934, 23910 => 33841, 23911 => 33901, 23912 => 33985, 23913 => 33997,1014 23914 => 34000, 23915 => 34022, 23916 => 33981, 23917 => 34003, 23918 => 33994,1015 23919 => 33983, 23920 => 33978, 23921 => 34016, 23922 => 33953, 23923 => 33977,1016 23924 => 33972, 23925 => 33943, 23926 => 34021, 23927 => 34019, 23928 => 34060,1017 23929 => 29965, 23930 => 34104, 23931 => 34032, 23932 => 34105, 23933 => 34079,1018 23934 => 34106, 24097 => 34134, 24098 => 34107, 24099 => 34047, 24100 => 34044,1019 24101 => 34137, 24102 => 34120, 24103 => 34152, 24104 => 34148, 24105 => 34142,1020 24106 => 34170, 24107 => 30626, 24108 => 34115, 24109 => 34162, 24110 => 34171,1021 24111 => 34212, 24112 => 34216, 24113 => 34183, 24114 => 34191, 24115 => 34169,1022 24116 => 34222, 24117 => 34204, 24118 => 34181, 24119 => 34233, 24120 => 34231,1023 24121 => 34224, 24122 => 34259, 24123 => 34241, 24124 => 34268, 24125 => 34303,1024 24126 => 34343, 24127 => 34309, 24128 => 34345, 24129 => 34326, 24130 => 34364,1025 24131 => 24318, 24132 => 24328, 24133 => 22844, 24134 => 22849, 24135 => 32823,1026 24136 => 22869, 24137 => 22874, 24138 => 22872, 24139 => 21263, 24140 => 23586,1027 24141 => 23589, 24142 => 23596, 24143 => 23604, 24144 => 25164, 24145 => 25194,1028 24146 => 25247, 24147 => 25275, 24148 => 25290, 24149 => 25306, 24150 => 25303,1029 24151 => 25326, 24152 => 25378, 24153 => 25334, 24154 => 25401, 24155 => 25419,1030 24156 => 25411, 24157 => 25517, 24158 => 25590, 24159 => 25457, 24160 => 25466,1031 24161 => 25486, 24162 => 25524, 24163 => 25453, 24164 => 25516, 24165 => 25482,1032 24166 => 25449, 24167 => 25518, 24168 => 25532, 24169 => 25586, 24170 => 25592,1033 24171 => 25568, 24172 => 25599, 24173 => 25540, 24174 => 25566, 24175 => 25550,1034 24176 => 25682, 24177 => 25542, 24178 => 25534, 24179 => 25669, 24180 => 25665,1035 24181 => 25611, 24182 => 25627, 24183 => 25632, 24184 => 25612, 24185 => 25638,1036 24186 => 25633, 24187 => 25694, 24188 => 25732, 24189 => 25709, 24190 => 25750,1037 24353 => 25722, 24354 => 25783, 24355 => 25784, 24356 => 25753, 24357 => 25786,1038 24358 => 25792, 24359 => 25808, 24360 => 25815, 24361 => 25828, 24362 => 25826,1039 24363 => 25865, 24364 => 25893, 24365 => 25902, 24366 => 24331, 24367 => 24530,1040 24368 => 29977, 24369 => 24337, 24370 => 21343, 24371 => 21489, 24372 => 21501,1041 24373 => 21481, 24374 => 21480, 24375 => 21499, 24376 => 21522, 24377 => 21526,1042 24378 => 21510, 24379 => 21579, 24380 => 21586, 24381 => 21587, 24382 => 21588,1043 24383 => 21590, 24384 => 21571, 24385 => 21537, 24386 => 21591, 24387 => 21593,1044 24388 => 21539, 24389 => 21554, 24390 => 21634, 24391 => 21652, 24392 => 21623,1045 24393 => 21617, 24394 => 21604, 24395 => 21658, 24396 => 21659, 24397 => 21636,1046 24398 => 21622, 24399 => 21606, 24400 => 21661, 24401 => 21712, 24402 => 21677,1047 24403 => 21698, 24404 => 21684, 24405 => 21714, 24406 => 21671, 24407 => 21670,1048 24408 => 21715, 24409 => 21716, 24410 => 21618, 24411 => 21667, 24412 => 21717,1049 24413 => 21691, 24414 => 21695, 24415 => 21708, 24416 => 21721, 24417 => 21722,1050 24418 => 21724, 24419 => 21673, 24420 => 21674, 24421 => 21668, 24422 => 21725,1051 24423 => 21711, 24424 => 21726, 24425 => 21787, 24426 => 21735, 24427 => 21792,1052 24428 => 21757, 24429 => 21780, 24430 => 21747, 24431 => 21794, 24432 => 21795,1053 24433 => 21775, 24434 => 21777, 24435 => 21799, 24436 => 21802, 24437 => 21863,1054 24438 => 21903, 24439 => 21941, 24440 => 21833, 24441 => 21869, 24442 => 21825,1055 24443 => 21845, 24444 => 21823, 24445 => 21840, 24446 => 21820, 24609 => 21815,1056 24610 => 21846, 24611 => 21877, 24612 => 21878, 24613 => 21879, 24614 => 21811,1057 24615 => 21808, 24616 => 21852, 24617 => 21899, 24618 => 21970, 24619 => 21891,1058 24620 => 21937, 24621 => 21945, 24622 => 21896, 24623 => 21889, 24624 => 21919,1059 24625 => 21886, 24626 => 21974, 24627 => 21905, 24628 => 21883, 24629 => 21983,1060 24630 => 21949, 24631 => 21950, 24632 => 21908, 24633 => 21913, 24634 => 21994,1061 24635 => 22007, 24636 => 21961, 24637 => 22047, 24638 => 21969, 24639 => 21995,1062 24640 => 21996, 24641 => 21972, 24642 => 21990, 24643 => 21981, 24644 => 21956,1063 24645 => 21999, 24646 => 21989, 24647 => 22002, 24648 => 22003, 24649 => 21964,1064 24650 => 21965, 24651 => 21992, 24652 => 22005, 24653 => 21988, 24654 => 36756,1065 24655 => 22046, 24656 => 22024, 24657 => 22028, 24658 => 22017, 24659 => 22052,1066 24660 => 22051, 24661 => 22014, 24662 => 22016, 24663 => 22055, 24664 => 22061,1067 24665 => 22104, 24666 => 22073, 24667 => 22103, 24668 => 22060, 24669 => 22093,1068 24670 => 22114, 24671 => 22105, 24672 => 22108, 24673 => 22092, 24674 => 22100,1069 24675 => 22150, 24676 => 22116, 24677 => 22129, 24678 => 22123, 24679 => 22139,1070 24680 => 22140, 24681 => 22149, 24682 => 22163, 24683 => 22191, 24684 => 22228,1071 24685 => 22231, 24686 => 22237, 24687 => 22241, 24688 => 22261, 24689 => 22251,1072 24690 => 22265, 24691 => 22271, 24692 => 22276, 24693 => 22282, 24694 => 22281,1073 24695 => 22300, 24696 => 24079, 24697 => 24089, 24698 => 24084, 24699 => 24081,1074 24700 => 24113, 24701 => 24123, 24702 => 24124, 24865 => 24119, 24866 => 24132,1075 24867 => 24148, 24868 => 24155, 24869 => 24158, 24870 => 24161, 24871 => 23692,1076 24872 => 23674, 24873 => 23693, 24874 => 23696, 24875 => 23702, 24876 => 23688,1077 24877 => 23704, 24878 => 23705, 24879 => 23697, 24880 => 23706, 24881 => 23708,1078 24882 => 23733, 24883 => 23714, 24884 => 23741, 24885 => 23724, 24886 => 23723,1079 24887 => 23729, 24888 => 23715, 24889 => 23745, 24890 => 23735, 24891 => 23748,1080 24892 => 23762, 24893 => 23780, 24894 => 23755, 24895 => 23781, 24896 => 23810,1081 24897 => 23811, 24898 => 23847, 24899 => 23846, 24900 => 23854, 24901 => 23844,1082 24902 => 23838, 24903 => 23814, 24904 => 23835, 24905 => 23896, 24906 => 23870,1083 24907 => 23860, 24908 => 23869, 24909 => 23916, 24910 => 23899, 24911 => 23919,1084 24912 => 23901, 24913 => 23915, 24914 => 23883, 24915 => 23882, 24916 => 23913,1085 24917 => 23924, 24918 => 23938, 24919 => 23961, 24920 => 23965, 24921 => 35955,1086 24922 => 23991, 24923 => 24005, 24924 => 24435, 24925 => 24439, 24926 => 24450,1087 24927 => 24455, 24928 => 24457, 24929 => 24460, 24930 => 24469, 24931 => 24473,1088 24932 => 24476, 24933 => 24488, 24934 => 24493, 24935 => 24501, 24936 => 24508,1089 24937 => 34914, 24938 => 24417, 24939 => 29357, 24940 => 29360, 24941 => 29364,1090 24942 => 29367, 24943 => 29368, 24944 => 29379, 24945 => 29377, 24946 => 29390,1091 24947 => 29389, 24948 => 29394, 24949 => 29416, 24950 => 29423, 24951 => 29417,1092 24952 => 29426, 24953 => 29428, 24954 => 29431, 24955 => 29441, 24956 => 29427,1093 24957 => 29443, 24958 => 29434, 25121 => 29435, 25122 => 29463, 25123 => 29459,1094 25124 => 29473, 25125 => 29450, 25126 => 29470, 25127 => 29469, 25128 => 29461,1095 25129 => 29474, 25130 => 29497, 25131 => 29477, 25132 => 29484, 25133 => 29496,1096 25134 => 29489, 25135 => 29520, 25136 => 29517, 25137 => 29527, 25138 => 29536,1097 25139 => 29548, 25140 => 29551, 25141 => 29566, 25142 => 33307, 25143 => 22821,1098 25144 => 39143, 25145 => 22820, 25146 => 22786, 25147 => 39267, 25148 => 39271,1099 25149 => 39272, 25150 => 39273, 25151 => 39274, 25152 => 39275, 25153 => 39276,1100 25154 => 39284, 25155 => 39287, 25156 => 39293, 25157 => 39296, 25158 => 39300,1101 25159 => 39303, 25160 => 39306, 25161 => 39309, 25162 => 39312, 25163 => 39313,1102 25164 => 39315, 25165 => 39316, 25166 => 39317, 25167 => 24192, 25168 => 24209,1103 25169 => 24203, 25170 => 24214, 25171 => 24229, 25172 => 24224, 25173 => 24249,1104 25174 => 24245, 25175 => 24254, 25176 => 24243, 25177 => 36179, 25178 => 24274,1105 25179 => 24273, 25180 => 24283, 25181 => 24296, 25182 => 24298, 25183 => 33210,1106 25184 => 24516, 25185 => 24521, 25186 => 24534, 25187 => 24527, 25188 => 24579,1107 25189 => 24558, 25190 => 24580, 25191 => 24545, 25192 => 24548, 25193 => 24574,1108 25194 => 24581, 25195 => 24582, 25196 => 24554, 25197 => 24557, 25198 => 24568,1109 25199 => 24601, 25200 => 24629, 25201 => 24614, 25202 => 24603, 25203 => 24591,1110 25204 => 24589, 25205 => 24617, 25206 => 24619, 25207 => 24586, 25208 => 24639,1111 25209 => 24609, 25210 => 24696, 25211 => 24697, 25212 => 24699, 25213 => 24698,1112 25214 => 24642, 25377 => 24682, 25378 => 24701, 25379 => 24726, 25380 => 24730,1113 25381 => 24749, 25382 => 24733, 25383 => 24707, 25384 => 24722, 25385 => 24716,1114 25386 => 24731, 25387 => 24812, 25388 => 24763, 25389 => 24753, 25390 => 24797,1115 25391 => 24792, 25392 => 24774, 25393 => 24794, 25394 => 24756, 25395 => 24864,1116 25396 => 24870, 25397 => 24853, 25398 => 24867, 25399 => 24820, 25400 => 24832,1117 25401 => 24846, 25402 => 24875, 25403 => 24906, 25404 => 24949, 25405 => 25004,1118 25406 => 24980, 25407 => 24999, 25408 => 25015, 25409 => 25044, 25410 => 25077,1119 25411 => 24541, 25412 => 38579, 25413 => 38377, 25414 => 38379, 25415 => 38385,1120 25416 => 38387, 25417 => 38389, 25418 => 38390, 25419 => 38396, 25420 => 38398,1121 25421 => 38403, 25422 => 38404, 25423 => 38406, 25424 => 38408, 25425 => 38410,1122 25426 => 38411, 25427 => 38412, 25428 => 38413, 25429 => 38415, 25430 => 38418,1123 25431 => 38421, 25432 => 38422, 25433 => 38423, 25434 => 38425, 25435 => 38426,1124 25436 => 20012, 25437 => 29247, 25438 => 25109, 25439 => 27701, 25440 => 27732,1125 25441 => 27740, 25442 => 27722, 25443 => 27811, 25444 => 27781, 25445 => 27792,1126 25446 => 27796, 25447 => 27788, 25448 => 27752, 25449 => 27753, 25450 => 27764,1127 25451 => 27766, 25452 => 27782, 25453 => 27817, 25454 => 27856, 25455 => 27860,1128 25456 => 27821, 25457 => 27895, 25458 => 27896, 25459 => 27889, 25460 => 27863,1129 25461 => 27826, 25462 => 27872, 25463 => 27862, 25464 => 27898, 25465 => 27883,1130 25466 => 27886, 25467 => 27825, 25468 => 27859, 25469 => 27887, 25470 => 27902,1131 25633 => 27961, 25634 => 27943, 25635 => 27916, 25636 => 27971, 25637 => 27976,1132 25638 => 27911, 25639 => 27908, 25640 => 27929, 25641 => 27918, 25642 => 27947,1133 25643 => 27981, 25644 => 27950, 25645 => 27957, 25646 => 27930, 25647 => 27983,1134 25648 => 27986, 25649 => 27988, 25650 => 27955, 25651 => 28049, 25652 => 28015,1135 25653 => 28062, 25654 => 28064, 25655 => 27998, 25656 => 28051, 25657 => 28052,1136 25658 => 27996, 25659 => 28000, 25660 => 28028, 25661 => 28003, 25662 => 28186,1137 25663 => 28103, 25664 => 28101, 25665 => 28126, 25666 => 28174, 25667 => 28095,1138 25668 => 28128, 25669 => 28177, 25670 => 28134, 25671 => 28125, 25672 => 28121,1139 25673 => 28182, 25674 => 28075, 25675 => 28172, 25676 => 28078, 25677 => 28203,1140 25678 => 28270, 25679 => 28238, 25680 => 28267, 25681 => 28338, 25682 => 28255,1141 25683 => 28294, 25684 => 28243, 25685 => 28244, 25686 => 28210, 25687 => 28197,1142 25688 => 28228, 25689 => 28383, 25690 => 28337, 25691 => 28312, 25692 => 28384,1143 25693 => 28461, 25694 => 28386, 25695 => 28325, 25696 => 28327, 25697 => 28349,1144 25698 => 28347, 25699 => 28343, 25700 => 28375, 25701 => 28340, 25702 => 28367,1145 25703 => 28303, 25704 => 28354, 25705 => 28319, 25706 => 28514, 25707 => 28486,1146 25708 => 28487, 25709 => 28452, 25710 => 28437, 25711 => 28409, 25712 => 28463,1147 25713 => 28470, 25714 => 28491, 25715 => 28532, 25716 => 28458, 25717 => 28425,1148 25718 => 28457, 25719 => 28553, 25720 => 28557, 25721 => 28556, 25722 => 28536,1149 25723 => 28530, 25724 => 28540, 25725 => 28538, 25726 => 28625, 25889 => 28617,1150 25890 => 28583, 25891 => 28601, 25892 => 28598, 25893 => 28610, 25894 => 28641,1151 25895 => 28654, 25896 => 28638, 25897 => 28640, 25898 => 28655, 25899 => 28698,1152 25900 => 28707, 25901 => 28699, 25902 => 28729, 25903 => 28725, 25904 => 28751,1153 25905 => 28766, 25906 => 23424, 25907 => 23428, 25908 => 23445, 25909 => 23443,1154 25910 => 23461, 25911 => 23480, 25912 => 29999, 25913 => 39582, 25914 => 25652,1155 25915 => 23524, 25916 => 23534, 25917 => 35120, 25918 => 23536, 25919 => 36423,1156 25920 => 35591, 25921 => 36790, 25922 => 36819, 25923 => 36821, 25924 => 36837,1157 25925 => 36846, 25926 => 36836, 25927 => 36841, 25928 => 36838, 25929 => 36851,1158 25930 => 36840, 25931 => 36869, 25932 => 36868, 25933 => 36875, 25934 => 36902,1159 25935 => 36881, 25936 => 36877, 25937 => 36886, 25938 => 36897, 25939 => 36917,1160 25940 => 36918, 25941 => 36909, 25942 => 36911, 25943 => 36932, 25944 => 36945,1161 25945 => 36946, 25946 => 36944, 25947 => 36968, 25948 => 36952, 25949 => 36962,1162 25950 => 36955, 25951 => 26297, 25952 => 36980, 25953 => 36989, 25954 => 36994,1163 25955 => 37000, 25956 => 36995, 25957 => 37003, 25958 => 24400, 25959 => 24407,1164 25960 => 24406, 25961 => 24408, 25962 => 23611, 25963 => 21675, 25964 => 23632,1165 25965 => 23641, 25966 => 23409, 25967 => 23651, 25968 => 23654, 25969 => 32700,1166 25970 => 24362, 25971 => 24361, 25972 => 24365, 25973 => 33396, 25974 => 24380,1167 25975 => 39739, 25976 => 23662, 25977 => 22913, 25978 => 22915, 25979 => 22925,1168 25980 => 22953, 25981 => 22954, 25982 => 22947, 26145 => 22935, 26146 => 22986,1169 26147 => 22955, 26148 => 22942, 26149 => 22948, 26150 => 22994, 26151 => 22962,1170 26152 => 22959, 26153 => 22999, 26154 => 22974, 26155 => 23045, 26156 => 23046,1171 26157 => 23005, 26158 => 23048, 26159 => 23011, 26160 => 23000, 26161 => 23033,1172 26162 => 23052, 26163 => 23049, 26164 => 23090, 26165 => 23092, 26166 => 23057,1173 26167 => 23075, 26168 => 23059, 26169 => 23104, 26170 => 23143, 26171 => 23114,1174 26172 => 23125, 26173 => 23100, 26174 => 23138, 26175 => 23157, 26176 => 33004,1175 26177 => 23210, 26178 => 23195, 26179 => 23159, 26180 => 23162, 26181 => 23230,1176 26182 => 23275, 26183 => 23218, 26184 => 23250, 26185 => 23252, 26186 => 23224,1177 26187 => 23264, 26188 => 23267, 26189 => 23281, 26190 => 23254, 26191 => 23270,1178 26192 => 23256, 26193 => 23260, 26194 => 23305, 26195 => 23319, 26196 => 23318,1179 26197 => 23346, 26198 => 23351, 26199 => 23360, 26200 => 23573, 26201 => 23580,1180 26202 => 23386, 26203 => 23397, 26204 => 23411, 26205 => 23377, 26206 => 23379,1181 26207 => 23394, 26208 => 39541, 26209 => 39543, 26210 => 39544, 26211 => 39546,1182 26212 => 39551, 26213 => 39549, 26214 => 39552, 26215 => 39553, 26216 => 39557,1183 26217 => 39560, 26218 => 39562, 26219 => 39568, 26220 => 39570, 26221 => 39571,1184 26222 => 39574, 26223 => 39576, 26224 => 39579, 26225 => 39580, 26226 => 39581,1185 26227 => 39583, 26228 => 39584, 26229 => 39586, 26230 => 39587, 26231 => 39589,1186 26232 => 39591, 26233 => 32415, 26234 => 32417, 26235 => 32419, 26236 => 32421,1187 26237 => 32424, 26238 => 32425, 26401 => 32429, 26402 => 32432, 26403 => 32446,1188 26404 => 32448, 26405 => 32449, 26406 => 32450, 26407 => 32457, 26408 => 32459,1189 26409 => 32460, 26410 => 32464, 26411 => 32468, 26412 => 32471, 26413 => 32475,1190 26414 => 32480, 26415 => 32481, 26416 => 32488, 26417 => 32491, 26418 => 32494,1191 26419 => 32495, 26420 => 32497, 26421 => 32498, 26422 => 32525, 26423 => 32502,1192 26424 => 32506, 26425 => 32507, 26426 => 32510, 26427 => 32513, 26428 => 32514,1193 26429 => 32515, 26430 => 32519, 26431 => 32520, 26432 => 32523, 26433 => 32524,1194 26434 => 32527, 26435 => 32529, 26436 => 32530, 26437 => 32535, 26438 => 32537,1195 26439 => 32540, 26440 => 32539, 26441 => 32543, 26442 => 32545, 26443 => 32546,1196 26444 => 32547, 26445 => 32548, 26446 => 32549, 26447 => 32550, 26448 => 32551,1197 26449 => 32554, 26450 => 32555, 26451 => 32556, 26452 => 32557, 26453 => 32559,1198 26454 => 32560, 26455 => 32561, 26456 => 32562, 26457 => 32563, 26458 => 32565,1199 26459 => 24186, 26460 => 30079, 26461 => 24027, 26462 => 30014, 26463 => 37013,1200 26464 => 29582, 26465 => 29585, 26466 => 29614, 26467 => 29602, 26468 => 29599,1201 26469 => 29647, 26470 => 29634, 26471 => 29649, 26472 => 29623, 26473 => 29619,1202 26474 => 29632, 26475 => 29641, 26476 => 29640, 26477 => 29669, 26478 => 29657,1203 26479 => 39036, 26480 => 29706, 26481 => 29673, 26482 => 29671, 26483 => 29662,1204 26484 => 29626, 26485 => 29682, 26486 => 29711, 26487 => 29738, 26488 => 29787,1205 26489 => 29734, 26490 => 29733, 26491 => 29736, 26492 => 29744, 26493 => 29742,1206 26494 => 29740, 26657 => 29723, 26658 => 29722, 26659 => 29761, 26660 => 29788,1207 26661 => 29783, 26662 => 29781, 26663 => 29785, 26664 => 29815, 26665 => 29805,1208 26666 => 29822, 26667 => 29852, 26668 => 29838, 26669 => 29824, 26670 => 29825,1209 26671 => 29831, 26672 => 29835, 26673 => 29854, 26674 => 29864, 26675 => 29865,1210 26676 => 29840, 26677 => 29863, 26678 => 29906, 26679 => 29882, 26680 => 38890,1211 26681 => 38891, 26682 => 38892, 26683 => 26444, 26684 => 26451, 26685 => 26462,1212 26686 => 26440, 26687 => 26473, 26688 => 26533, 26689 => 26503, 26690 => 26474,1213 26691 => 26483, 26692 => 26520, 26693 => 26535, 26694 => 26485, 26695 => 26536,1214 26696 => 26526, 26697 => 26541, 26698 => 26507, 26699 => 26487, 26700 => 26492,1215 26701 => 26608, 26702 => 26633, 26703 => 26584, 26704 => 26634, 26705 => 26601,1216 26706 => 26544, 26707 => 26636, 26708 => 26585, 26709 => 26549, 26710 => 26586,1217 26711 => 26547, 26712 => 26589, 26713 => 26624, 26714 => 26563, 26715 => 26552,1218 26716 => 26594, 26717 => 26638, 26718 => 26561, 26719 => 26621, 26720 => 26674,1219 26721 => 26675, 26722 => 26720, 26723 => 26721, 26724 => 26702, 26725 => 26722,1220 26726 => 26692, 26727 => 26724, 26728 => 26755, 26729 => 26653, 26730 => 26709,1221 26731 => 26726, 26732 => 26689, 26733 => 26727, 26734 => 26688, 26735 => 26686,1222 26736 => 26698, 26737 => 26697, 26738 => 26665, 26739 => 26805, 26740 => 26767,1223 26741 => 26740, 26742 => 26743, 26743 => 26771, 26744 => 26731, 26745 => 26818,1224 26746 => 26990, 26747 => 26876, 26748 => 26911, 26749 => 26912, 26750 => 26873,1225 26913 => 26916, 26914 => 26864, 26915 => 26891, 26916 => 26881, 26917 => 26967,1226 26918 => 26851, 26919 => 26896, 26920 => 26993, 26921 => 26937, 26922 => 26976,1227 26923 => 26946, 26924 => 26973, 26925 => 27012, 26926 => 26987, 26927 => 27008,1228 26928 => 27032, 26929 => 27000, 26930 => 26932, 26931 => 27084, 26932 => 27015,1229 26933 => 27016, 26934 => 27086, 26935 => 27017, 26936 => 26982, 26937 => 26979,1230 26938 => 27001, 26939 => 27035, 26940 => 27047, 26941 => 27067, 26942 => 27051,1231 26943 => 27053, 26944 => 27092, 26945 => 27057, 26946 => 27073, 26947 => 27082,1232 26948 => 27103, 26949 => 27029, 26950 => 27104, 26951 => 27021, 26952 => 27135,1233 26953 => 27183, 26954 => 27117, 26955 => 27159, 26956 => 27160, 26957 => 27237,1234 26958 => 27122, 26959 => 27204, 26960 => 27198, 26961 => 27296, 26962 => 27216,1235 26963 => 27227, 26964 => 27189, 26965 => 27278, 26966 => 27257, 26967 => 27197,1236 26968 => 27176, 26969 => 27224, 26970 => 27260, 26971 => 27281, 26972 => 27280,1237 26973 => 27305, 26974 => 27287, 26975 => 27307, 26976 => 29495, 26977 => 29522,1238 26978 => 27521, 26979 => 27522, 26980 => 27527, 26981 => 27524, 26982 => 27538,1239 26983 => 27539, 26984 => 27533, 26985 => 27546, 26986 => 27547, 26987 => 27553,1240 26988 => 27562, 26989 => 36715, 26990 => 36717, 26991 => 36721, 26992 => 36722,1241 26993 => 36723, 26994 => 36725, 26995 => 36726, 26996 => 36728, 26997 => 36727,1242 26998 => 36729, 26999 => 36730, 27000 => 36732, 27001 => 36734, 27002 => 36737,1243 27003 => 36738, 27004 => 36740, 27005 => 36743, 27006 => 36747, 27169 => 36749,1244 27170 => 36750, 27171 => 36751, 27172 => 36760, 27173 => 36762, 27174 => 36558,1245 27175 => 25099, 27176 => 25111, 27177 => 25115, 27178 => 25119, 27179 => 25122,1246 27180 => 25121, 27181 => 25125, 27182 => 25124, 27183 => 25132, 27184 => 33255,1247 27185 => 29935, 27186 => 29940, 27187 => 29951, 27188 => 29967, 27189 => 29969,1248 27190 => 29971, 27191 => 25908, 27192 => 26094, 27193 => 26095, 27194 => 26096,1249 27195 => 26122, 27196 => 26137, 27197 => 26482, 27198 => 26115, 27199 => 26133,1250 27200 => 26112, 27201 => 28805, 27202 => 26359, 27203 => 26141, 27204 => 26164,1251 27205 => 26161, 27206 => 26166, 27207 => 26165, 27208 => 32774, 27209 => 26207,1252 27210 => 26196, 27211 => 26177, 27212 => 26191, 27213 => 26198, 27214 => 26209,1253 27215 => 26199, 27216 => 26231, 27217 => 26244, 27218 => 26252, 27219 => 26279,1254 27220 => 26269, 27221 => 26302, 27222 => 26331, 27223 => 26332, 27224 => 26342,1255 27225 => 26345, 27226 => 36146, 27227 => 36147, 27228 => 36150, 27229 => 36155,1256 27230 => 36157, 27231 => 36160, 27232 => 36165, 27233 => 36166, 27234 => 36168,1257 27235 => 36169, 27236 => 36167, 27237 => 36173, 27238 => 36181, 27239 => 36185,1258 27240 => 35271, 27241 => 35274, 27242 => 35275, 27243 => 35276, 27244 => 35278,1259 27245 => 35279, 27246 => 35280, 27247 => 35281, 27248 => 29294, 27249 => 29343,1260 27250 => 29277, 27251 => 29286, 27252 => 29295, 27253 => 29310, 27254 => 29311,1261 27255 => 29316, 27256 => 29323, 27257 => 29325, 27258 => 29327, 27259 => 29330,1262 27260 => 25352, 27261 => 25394, 27262 => 25520, 27425 => 25663, 27426 => 25816,1263 27427 => 32772, 27428 => 27626, 27429 => 27635, 27430 => 27645, 27431 => 27637,1264 27432 => 27641, 27433 => 27653, 27434 => 27655, 27435 => 27654, 27436 => 27661,1265 27437 => 27669, 27438 => 27672, 27439 => 27673, 27440 => 27674, 27441 => 27681,1266 27442 => 27689, 27443 => 27684, 27444 => 27690, 27445 => 27698, 27446 => 25909,1267 27447 => 25941, 27448 => 25963, 27449 => 29261, 27450 => 29266, 27451 => 29270,1268 27452 => 29232, 27453 => 34402, 27454 => 21014, 27455 => 32927, 27456 => 32924,1269 27457 => 32915, 27458 => 32956, 27459 => 26378, 27460 => 32957, 27461 => 32945,1270 27462 => 32939, 27463 => 32941, 27464 => 32948, 27465 => 32951, 27466 => 32999,1271 27467 => 33000, 27468 => 33001, 27469 => 33002, 27470 => 32987, 27471 => 32962,1272 27472 => 32964, 27473 => 32985, 27474 => 32973, 27475 => 32983, 27476 => 26384,1273 27477 => 32989, 27478 => 33003, 27479 => 33009, 27480 => 33012, 27481 => 33005,1274 27482 => 33037, 27483 => 33038, 27484 => 33010, 27485 => 33020, 27486 => 26389,1275 27487 => 33042, 27488 => 35930, 27489 => 33078, 27490 => 33054, 27491 => 33068,1276 27492 => 33048, 27493 => 33074, 27494 => 33096, 27495 => 33100, 27496 => 33107,1277 27497 => 33140, 27498 => 33113, 27499 => 33114, 27500 => 33137, 27501 => 33120,1278 27502 => 33129, 27503 => 33148, 27504 => 33149, 27505 => 33133, 27506 => 33127,1279 27507 => 22605, 27508 => 23221, 27509 => 33160, 27510 => 33154, 27511 => 33169,1280 27512 => 28373, 27513 => 33187, 27514 => 33194, 27515 => 33228, 27516 => 26406,1281 27517 => 33226, 27518 => 33211, 27681 => 33217, 27682 => 33190, 27683 => 27428,1282 27684 => 27447, 27685 => 27449, 27686 => 27459, 27687 => 27462, 27688 => 27481,1283 27689 => 39121, 27690 => 39122, 27691 => 39123, 27692 => 39125, 27693 => 39129,1284 27694 => 39130, 27695 => 27571, 27696 => 24384, 27697 => 27586, 27698 => 35315,1285 27699 => 26000, 27700 => 40785, 27701 => 26003, 27702 => 26044, 27703 => 26054,1286 27704 => 26052, 27705 => 26051, 27706 => 26060, 27707 => 26062, 27708 => 26066,1287 27709 => 26070, 27710 => 28800, 27711 => 28828, 27712 => 28822, 27713 => 28829,1288 27714 => 28859, 27715 => 28864, 27716 => 28855, 27717 => 28843, 27718 => 28849,1289 27719 => 28904, 27720 => 28874, 27721 => 28944, 27722 => 28947, 27723 => 28950,1290 27724 => 28975, 27725 => 28977, 27726 => 29043, 27727 => 29020, 27728 => 29032,1291 27729 => 28997, 27730 => 29042, 27731 => 29002, 27732 => 29048, 27733 => 29050,1292 27734 => 29080, 27735 => 29107, 27736 => 29109, 27737 => 29096, 27738 => 29088,1293 27739 => 29152, 27740 => 29140, 27741 => 29159, 27742 => 29177, 27743 => 29213,1294 27744 => 29224, 27745 => 28780, 27746 => 28952, 27747 => 29030, 27748 => 29113,1295 27749 => 25150, 27750 => 25149, 27751 => 25155, 27752 => 25160, 27753 => 25161,1296 27754 => 31035, 27755 => 31040, 27756 => 31046, 27757 => 31049, 27758 => 31067,1297 27759 => 31068, 27760 => 31059, 27761 => 31066, 27762 => 31074, 27763 => 31063,1298 27764 => 31072, 27765 => 31087, 27766 => 31079, 27767 => 31098, 27768 => 31109,1299 27769 => 31114, 27770 => 31130, 27771 => 31143, 27772 => 31155, 27773 => 24529,1300 27774 => 24528, 27937 => 24636, 27938 => 24669, 27939 => 24666, 27940 => 24679,1301 27941 => 24641, 27942 => 24665, 27943 => 24675, 27944 => 24747, 27945 => 24838,1302 27946 => 24845, 27947 => 24925, 27948 => 25001, 27949 => 24989, 27950 => 25035,1303 27951 => 25041, 27952 => 25094, 27953 => 32896, 27954 => 32895, 27955 => 27795,1304 27956 => 27894, 27957 => 28156, 27958 => 30710, 27959 => 30712, 27960 => 30720,1305 27961 => 30729, 27962 => 30743, 27963 => 30744, 27964 => 30737, 27965 => 26027,1306 27966 => 30765, 27967 => 30748, 27968 => 30749, 27969 => 30777, 27970 => 30778,1307 27971 => 30779, 27972 => 30751, 27973 => 30780, 27974 => 30757, 27975 => 30764,1308 27976 => 30755, 27977 => 30761, 27978 => 30798, 27979 => 30829, 27980 => 30806,1309 27981 => 30807, 27982 => 30758, 27983 => 30800, 27984 => 30791, 27985 => 30796,1310 27986 => 30826, 27987 => 30875, 27988 => 30867, 27989 => 30874, 27990 => 30855,1311 27991 => 30876, 27992 => 30881, 27993 => 30883, 27994 => 30898, 27995 => 30905,1312 27996 => 30885, 27997 => 30932, 27998 => 30937, 27999 => 30921, 28000 => 30956,1313 28001 => 30962, 28002 => 30981, 28003 => 30964, 28004 => 30995, 28005 => 31012,1314 28006 => 31006, 28007 => 31028, 28008 => 40859, 28009 => 40697, 28010 => 40699,1315 28011 => 40700, 28012 => 30449, 28013 => 30468, 28014 => 30477, 28015 => 30457,1316 28016 => 30471, 28017 => 30472, 28018 => 30490, 28019 => 30498, 28020 => 30489,1317 28021 => 30509, 28022 => 30502, 28023 => 30517, 28024 => 30520, 28025 => 30544,1318 28026 => 30545, 28027 => 30535, 28028 => 30531, 28029 => 30554, 28030 => 30568,1319 28193 => 30562, 28194 => 30565, 28195 => 30591, 28196 => 30605, 28197 => 30589,1320 28198 => 30592, 28199 => 30604, 28200 => 30609, 28201 => 30623, 28202 => 30624,1321 28203 => 30640, 28204 => 30645, 28205 => 30653, 28206 => 30010, 28207 => 30016,1322 28208 => 30030, 28209 => 30027, 28210 => 30024, 28211 => 30043, 28212 => 30066,1323 28213 => 30073, 28214 => 30083, 28215 => 32600, 28216 => 32609, 28217 => 32607,1324 28218 => 35400, 28219 => 32616, 28220 => 32628, 28221 => 32625, 28222 => 32633,1325 28223 => 32641, 28224 => 32638, 28225 => 30413, 28226 => 30437, 28227 => 34866,1326 28228 => 38021, 28229 => 38022, 28230 => 38023, 28231 => 38027, 28232 => 38026,1327 28233 => 38028, 28234 => 38029, 28235 => 38031, 28236 => 38032, 28237 => 38036,1328 28238 => 38039, 28239 => 38037, 28240 => 38042, 28241 => 38043, 28242 => 38044,1329 28243 => 38051, 28244 => 38052, 28245 => 38059, 28246 => 38058, 28247 => 38061,1330 28248 => 38060, 28249 => 38063, 28250 => 38064, 28251 => 38066, 28252 => 38068,1331 28253 => 38070, 28254 => 38071, 28255 => 38072, 28256 => 38073, 28257 => 38074,1332 28258 => 38076, 28259 => 38077, 28260 => 38079, 28261 => 38084, 28262 => 38088,1333 28263 => 38089, 28264 => 38090, 28265 => 38091, 28266 => 38092, 28267 => 38093,1334 28268 => 38094, 28269 => 38096, 28270 => 38097, 28271 => 38098, 28272 => 38101,1335 28273 => 38102, 28274 => 38103, 28275 => 38105, 28276 => 38104, 28277 => 38107,1336 28278 => 38110, 28279 => 38111, 28280 => 38112, 28281 => 38114, 28282 => 38116,1337 28283 => 38117, 28284 => 38119, 28285 => 38120, 28286 => 38122, 28449 => 38121,1338 28450 => 38123, 28451 => 38126, 28452 => 38127, 28453 => 38131, 28454 => 38132,1339 28455 => 38133, 28456 => 38135, 28457 => 38137, 28458 => 38140, 28459 => 38141,1340 28460 => 38143, 28461 => 38147, 28462 => 38146, 28463 => 38150, 28464 => 38151,1341 28465 => 38153, 28466 => 38154, 28467 => 38157, 28468 => 38158, 28469 => 38159,1342 28470 => 38162, 28471 => 38163, 28472 => 38164, 28473 => 38165, 28474 => 38166,1343 28475 => 38168, 28476 => 38171, 28477 => 38173, 28478 => 38174, 28479 => 38175,1344 28480 => 38178, 28481 => 38186, 28482 => 38187, 28483 => 38185, 28484 => 38188,1345 28485 => 38193, 28486 => 38194, 28487 => 38196, 28488 => 38198, 28489 => 38199,1346 28490 => 38200, 28491 => 38204, 28492 => 38206, 28493 => 38207, 28494 => 38210,1347 28495 => 38197, 28496 => 38212, 28497 => 38213, 28498 => 38214, 28499 => 38217,1348 28500 => 38220, 28501 => 38222, 28502 => 38223, 28503 => 38226, 28504 => 38227,1349 28505 => 38228, 28506 => 38230, 28507 => 38231, 28508 => 38232, 28509 => 38233,1350 28510 => 38235, 28511 => 38238, 28512 => 38239, 28513 => 38237, 28514 => 38241,1351 28515 => 38242, 28516 => 38244, 28517 => 38245, 28518 => 38246, 28519 => 38247,1352 28520 => 38248, 28521 => 38249, 28522 => 38250, 28523 => 38251, 28524 => 38252,1353 28525 => 38255, 28526 => 38257, 28527 => 38258, 28528 => 38259, 28529 => 38202,1354 28530 => 30695, 28531 => 30700, 28532 => 38601, 28533 => 31189, 28534 => 31213,1355 28535 => 31203, 28536 => 31211, 28537 => 31238, 28538 => 23879, 28539 => 31235,1356 28540 => 31234, 28541 => 31262, 28542 => 31252, 28705 => 31289, 28706 => 31287,1357 28707 => 31313, 28708 => 40655, 28709 => 39333, 28710 => 31344, 28711 => 30344,1358 28712 => 30350, 28713 => 30355, 28714 => 30361, 28715 => 30372, 28716 => 29918,1359 28717 => 29920, 28718 => 29996, 28719 => 40480, 28720 => 40482, 28721 => 40488,1360 28722 => 40489, 28723 => 40490, 28724 => 40491, 28725 => 40492, 28726 => 40498,1361 28727 => 40497, 28728 => 40502, 28729 => 40504, 28730 => 40503, 28731 => 40505,1362 28732 => 40506, 28733 => 40510, 28734 => 40513, 28735 => 40514, 28736 => 40516,1363 28737 => 40518, 28738 => 40519, 28739 => 40520, 28740 => 40521, 28741 => 40523,1364 28742 => 40524, 28743 => 40526, 28744 => 40529, 28745 => 40533, 28746 => 40535,1365 28747 => 40538, 28748 => 40539, 28749 => 40540, 28750 => 40542, 28751 => 40547,1366 28752 => 40550, 28753 => 40551, 28754 => 40552, 28755 => 40553, 28756 => 40554,1367 28757 => 40555, 28758 => 40556, 28759 => 40561, 28760 => 40557, 28761 => 40563,1368 28762 => 30098, 28763 => 30100, 28764 => 30102, 28765 => 30112, 28766 => 30109,1369 28767 => 30124, 28768 => 30115, 28769 => 30131, 28770 => 30132, 28771 => 30136,1370 28772 => 30148, 28773 => 30129, 28774 => 30128, 28775 => 30147, 28776 => 30146,1371 28777 => 30166, 28778 => 30157, 28779 => 30179, 28780 => 30184, 28781 => 30182,1372 28782 => 30180, 28783 => 30187, 28784 => 30183, 28785 => 30211, 28786 => 30193,1373 28787 => 30204, 28788 => 30207, 28789 => 30224, 28790 => 30208, 28791 => 30213,1374 28792 => 30220, 28793 => 30231, 28794 => 30218, 28795 => 30245, 28796 => 30232,1375 28797 => 30229, 28798 => 30233, 28961 => 30235, 28962 => 30268, 28963 => 30242,1376 28964 => 30240, 28965 => 30272, 28966 => 30253, 28967 => 30256, 28968 => 30271,1377 28969 => 30261, 28970 => 30275, 28971 => 30270, 28972 => 30259, 28973 => 30285,1378 28974 => 30302, 28975 => 30292, 28976 => 30300, 28977 => 30294, 28978 => 30315,1379 28979 => 30319, 28980 => 32714, 28981 => 31462, 28982 => 31352, 28983 => 31353,1380 28984 => 31360, 28985 => 31366, 28986 => 31368, 28987 => 31381, 28988 => 31398,1381 28989 => 31392, 28990 => 31404, 28991 => 31400, 28992 => 31405, 28993 => 31411,1382 28994 => 34916, 28995 => 34921, 28996 => 34930, 28997 => 34941, 28998 => 34943,1383 28999 => 34946, 29000 => 34978, 29001 => 35014, 29002 => 34999, 29003 => 35004,1384 29004 => 35017, 29005 => 35042, 29006 => 35022, 29007 => 35043, 29008 => 35045,1385 29009 => 35057, 29010 => 35098, 29011 => 35068, 29012 => 35048, 29013 => 35070,1386 29014 => 35056, 29015 => 35105, 29016 => 35097, 29017 => 35091, 29018 => 35099,1387 29019 => 35082, 29020 => 35124, 29021 => 35115, 29022 => 35126, 29023 => 35137,1388 29024 => 35174, 29025 => 35195, 29026 => 30091, 29027 => 32997, 29028 => 30386,1389 29029 => 30388, 29030 => 30684, 29031 => 32786, 29032 => 32788, 29033 => 32790,1390 29034 => 32796, 29035 => 32800, 29036 => 32802, 29037 => 32805, 29038 => 32806,1391 29039 => 32807, 29040 => 32809, 29041 => 32808, 29042 => 32817, 29043 => 32779,1392 29044 => 32821, 29045 => 32835, 29046 => 32838, 29047 => 32845, 29048 => 32850,1393 29049 => 32873, 29050 => 32881, 29051 => 35203, 29052 => 39032, 29053 => 39040,1394 29054 => 39043, 29217 => 39049, 29218 => 39052, 29219 => 39053, 29220 => 39055,1395 29221 => 39060, 29222 => 39066, 29223 => 39067, 29224 => 39070, 29225 => 39071,1396 29226 => 39073, 29227 => 39074, 29228 => 39077, 29229 => 39078, 29230 => 34381,1397 29231 => 34388, 29232 => 34412, 29233 => 34414, 29234 => 34431, 29235 => 34426,1398 29236 => 34428, 29237 => 34427, 29238 => 34472, 29239 => 34445, 29240 => 34443,1399 29241 => 34476, 29242 => 34461, 29243 => 34471, 29244 => 34467, 29245 => 34474,1400 29246 => 34451, 29247 => 34473, 29248 => 34486, 29249 => 34500, 29250 => 34485,1401 29251 => 34510, 29252 => 34480, 29253 => 34490, 29254 => 34481, 29255 => 34479,1402 29256 => 34505, 29257 => 34511, 29258 => 34484, 29259 => 34537, 29260 => 34545,1403 29261 => 34546, 29262 => 34541, 29263 => 34547, 29264 => 34512, 29265 => 34579,1404 29266 => 34526, 29267 => 34548, 29268 => 34527, 29269 => 34520, 29270 => 34513,1405 29271 => 34563, 29272 => 34567, 29273 => 34552, 29274 => 34568, 29275 => 34570,1406 29276 => 34573, 29277 => 34569, 29278 => 34595, 29279 => 34619, 29280 => 34590,1407 29281 => 34597, 29282 => 34606, 29283 => 34586, 29284 => 34622, 29285 => 34632,1408 29286 => 34612, 29287 => 34609, 29288 => 34601, 29289 => 34615, 29290 => 34623,1409 29291 => 34690, 29292 => 34594, 29293 => 34685, 29294 => 34686, 29295 => 34683,1410 29296 => 34656, 29297 => 34672, 29298 => 34636, 29299 => 34670, 29300 => 34699,1411 29301 => 34643, 29302 => 34659, 29303 => 34684, 29304 => 34660, 29305 => 34649,1412 29306 => 34661, 29307 => 34707, 29308 => 34735, 29309 => 34728, 29310 => 34770,1413 29473 => 34758, 29474 => 34696, 29475 => 34693, 29476 => 34733, 29477 => 34711,1414 29478 => 34691, 29479 => 34731, 29480 => 34789, 29481 => 34732, 29482 => 34741,1415 29483 => 34739, 29484 => 34763, 29485 => 34771, 29486 => 34749, 29487 => 34769,1416 29488 => 34752, 29489 => 34762, 29490 => 34779, 29491 => 34794, 29492 => 34784,1417 29493 => 34798, 29494 => 34838, 29495 => 34835, 29496 => 34814, 29497 => 34826,1418 29498 => 34843, 29499 => 34849, 29500 => 34873, 29501 => 34876, 29502 => 32566,1419 29503 => 32578, 29504 => 32580, 29505 => 32581, 29506 => 33296, 29507 => 31482,1420 29508 => 31485, 29509 => 31496, 29510 => 31491, 29511 => 31492, 29512 => 31509,1421 29513 => 31498, 29514 => 31531, 29515 => 31503, 29516 => 31559, 29517 => 31544,1422 29518 => 31530, 29519 => 31513, 29520 => 31534, 29521 => 31537, 29522 => 31520,1423 29523 => 31525, 29524 => 31524, 29525 => 31539, 29526 => 31550, 29527 => 31518,1424 29528 => 31576, 29529 => 31578, 29530 => 31557, 29531 => 31605, 29532 => 31564,1425 29533 => 31581, 29534 => 31584, 29535 => 31598, 29536 => 31611, 29537 => 31586,1426 29538 => 31602, 29539 => 31601, 29540 => 31632, 29541 => 31654, 29542 => 31655,1427 29543 => 31672, 29544 => 31660, 29545 => 31645, 29546 => 31656, 29547 => 31621,1428 29548 => 31658, 29549 => 31644, 29550 => 31650, 29551 => 31659, 29552 => 31668,1429 29553 => 31697, 29554 => 31681, 29555 => 31692, 29556 => 31709, 29557 => 31706,1430 29558 => 31717, 29559 => 31718, 29560 => 31722, 29561 => 31756, 29562 => 31742,1431 29563 => 31740, 29564 => 31759, 29565 => 31766, 29566 => 31755, 29729 => 31775,1432 29730 => 31786, 29731 => 31782, 29732 => 31800, 29733 => 31809, 29734 => 31808,1433 29735 => 33278, 29736 => 33281, 29737 => 33282, 29738 => 33284, 29739 => 33260,1434 29740 => 34884, 29741 => 33313, 29742 => 33314, 29743 => 33315, 29744 => 33325,1435 29745 => 33327, 29746 => 33320, 29747 => 33323, 29748 => 33336, 29749 => 33339,1436 29750 => 33331, 29751 => 33332, 29752 => 33342, 29753 => 33348, 29754 => 33353,1437 29755 => 33355, 29756 => 33359, 29757 => 33370, 29758 => 33375, 29759 => 33384,1438 29760 => 34942, 29761 => 34949, 29762 => 34952, 29763 => 35032, 29764 => 35039,1439 29765 => 35166, 29766 => 32669, 29767 => 32671, 29768 => 32679, 29769 => 32687,1440 29770 => 32688, 29771 => 32690, 29772 => 31868, 29773 => 25929, 29774 => 31889,1441 29775 => 31901, 29776 => 31900, 29777 => 31902, 29778 => 31906, 29779 => 31922,1442 29780 => 31932, 29781 => 31933, 29782 => 31937, 29783 => 31943, 29784 => 31948,1443 29785 => 31949, 29786 => 31944, 29787 => 31941, 29788 => 31959, 29789 => 31976,1444 29790 => 33390, 29791 => 26280, 29792 => 32703, 29793 => 32718, 29794 => 32725,1445 29795 => 32741, 29796 => 32737, 29797 => 32742, 29798 => 32745, 29799 => 32750,1446 29800 => 32755, 29801 => 31992, 29802 => 32119, 29803 => 32166, 29804 => 32174,1447 29805 => 32327, 29806 => 32411, 29807 => 40632, 29808 => 40628, 29809 => 36211,1448 29810 => 36228, 29811 => 36244, 29812 => 36241, 29813 => 36273, 29814 => 36199,1449 29815 => 36205, 29816 => 35911, 29817 => 35913, 29818 => 37194, 29819 => 37200,1450 29820 => 37198, 29821 => 37199, 29822 => 37220, 29985 => 37218, 29986 => 37217,1451 29987 => 37232, 29988 => 37225, 29989 => 37231, 29990 => 37245, 29991 => 37246,1452 29992 => 37234, 29993 => 37236, 29994 => 37241, 29995 => 37260, 29996 => 37253,1453 29997 => 37264, 29998 => 37261, 29999 => 37265, 30000 => 37282, 30001 => 37283,1454 30002 => 37290, 30003 => 37293, 30004 => 37294, 30005 => 37295, 30006 => 37301,1455 30007 => 37300, 30008 => 37306, 30009 => 35925, 30010 => 40574, 30011 => 36280,1456 30012 => 36331, 30013 => 36357, 30014 => 36441, 30015 => 36457, 30016 => 36277,1457 30017 => 36287, 30018 => 36284, 30019 => 36282, 30020 => 36292, 30021 => 36310,1458 30022 => 36311, 30023 => 36314, 30024 => 36318, 30025 => 36302, 30026 => 36303,1459 30027 => 36315, 30028 => 36294, 30029 => 36332, 30030 => 36343, 30031 => 36344,1460 30032 => 36323, 30033 => 36345, 30034 => 36347, 30035 => 36324, 30036 => 36361,1461 30037 => 36349, 30038 => 36372, 30039 => 36381, 30040 => 36383, 30041 => 36396,1462 30042 => 36398, 30043 => 36387, 30044 => 36399, 30045 => 36410, 30046 => 36416,1463 30047 => 36409, 30048 => 36405, 30049 => 36413, 30050 => 36401, 30051 => 36425,1464 30052 => 36417, 30053 => 36418, 30054 => 36433, 30055 => 36434, 30056 => 36426,1465 30057 => 36464, 30058 => 36470, 30059 => 36476, 30060 => 36463, 30061 => 36468,1466 30062 => 36485, 30063 => 36495, 30064 => 36500, 30065 => 36496, 30066 => 36508,1467 30067 => 36510, 30068 => 35960, 30069 => 35970, 30070 => 35978, 30071 => 35973,1468 30072 => 35992, 30073 => 35988, 30074 => 26011, 30075 => 35286, 30076 => 35294,1469 30077 => 35290, 30078 => 35292, 30241 => 35301, 30242 => 35307, 30243 => 35311,1470 30244 => 35390, 30245 => 35622, 30246 => 38739, 30247 => 38633, 30248 => 38643,1471 30249 => 38639, 30250 => 38662, 30251 => 38657, 30252 => 38664, 30253 => 38671,1472 30254 => 38670, 30255 => 38698, 30256 => 38701, 30257 => 38704, 30258 => 38718,1473 30259 => 40832, 30260 => 40835, 30261 => 40837, 30262 => 40838, 30263 => 40839,1474 30264 => 40840, 30265 => 40841, 30266 => 40842, 30267 => 40844, 30268 => 40702,1475 30269 => 40715, 30270 => 40717, 30271 => 38585, 30272 => 38588, 30273 => 38589,1476 30274 => 38606, 30275 => 38610, 30276 => 30655, 30277 => 38624, 30278 => 37518,1477 30279 => 37550, 30280 => 37576, 30281 => 37694, 30282 => 37738, 30283 => 37834,1478 30284 => 37775, 30285 => 37950, 30286 => 37995, 30287 => 40063, 30288 => 40066,1479 30289 => 40069, 30290 => 40070, 30291 => 40071, 30292 => 40072, 30293 => 31267,1480 30294 => 40075, 30295 => 40078, 30296 => 40080, 30297 => 40081, 30298 => 40082,1481 30299 => 40084, 30300 => 40085, 30301 => 40090, 30302 => 40091, 30303 => 40094,1482 30304 => 40095, 30305 => 40096, 30306 => 40097, 30307 => 40098, 30308 => 40099,1483 30309 => 40101, 30310 => 40102, 30311 => 40103, 30312 => 40104, 30313 => 40105,1484 30314 => 40107, 30315 => 40109, 30316 => 40110, 30317 => 40112, 30318 => 40113,1485 30319 => 40114, 30320 => 40115, 30321 => 40116, 30322 => 40117, 30323 => 40118,1486 30324 => 40119, 30325 => 40122, 30326 => 40123, 30327 => 40124, 30328 => 40125,1487 30329 => 40132, 30330 => 40133, 30331 => 40134, 30332 => 40135, 30333 => 40138,1488 30334 => 40139, 30497 => 40140, 30498 => 40141, 30499 => 40142, 30500 => 40143,1489 30501 => 40144, 30502 => 40147, 30503 => 40148, 30504 => 40149, 30505 => 40151,1490 30506 => 40152, 30507 => 40153, 30508 => 40156, 30509 => 40157, 30510 => 40159,1491 30511 => 40162, 30512 => 38780, 30513 => 38789, 30514 => 38801, 30515 => 38802,1492 30516 => 38804, 30517 => 38831, 30518 => 38827, 30519 => 38819, 30520 => 38834,1493 30521 => 38836, 30522 => 39601, 30523 => 39600, 30524 => 39607, 30525 => 40536,1494 30526 => 39606, 30527 => 39610, 30528 => 39612, 30529 => 39617, 30530 => 39616,1495 30531 => 39621, 30532 => 39618, 30533 => 39627, 30534 => 39628, 30535 => 39633,1496 30536 => 39749, 30537 => 39747, 30538 => 39751, 30539 => 39753, 30540 => 39752,1497 30541 => 39757, 30542 => 39761, 30543 => 39144, 30544 => 39181, 30545 => 39214,1498 30546 => 39253, 30547 => 39252, 30548 => 39647, 30549 => 39649, 30550 => 39654,1499 30551 => 39663, 30552 => 39659, 30553 => 39675, 30554 => 39661, 30555 => 39673,1500 30556 => 39688, 30557 => 39695, 30558 => 39699, 30559 => 39711, 30560 => 39715,1501 30561 => 40637, 30562 => 40638, 30563 => 32315, 30564 => 40578, 30565 => 40583,1502 30566 => 40584, 30567 => 40587, 30568 => 40594, 30569 => 37846, 30570 => 40605,1503 30571 => 40607, 30572 => 40667, 30573 => 40668, 30574 => 40669, 30575 => 40672,1504 30576 => 40671, 30577 => 40674, 30578 => 40681, 30579 => 40679, 30580 => 40677,1505 30581 => 40682, 30582 => 40687, 30583 => 40738, 30584 => 40748, 30585 => 40751,1506 30586 => 40761, 30587 => 40759, 30588 => 40765, 30589 => 40766, 30590 => 40772,1507 0 => 0 );13 // -------------------------------------------------------------------- 14 // This code table is used to translate GB2312 code (key) to 15 // it's corresponding Unicode value (data) 16 // -------------------------------------------------------------------- 17 private $codetable = array( 18 8481 => 12288, 8482 => 12289, 8483 => 12290, 8484 => 12539, 8485 => 713, 19 8486 => 711, 8487 => 168, 8488 => 12291, 8489 => 12293, 8490 => 8213, 20 8491 => 65374, 8492 => 8214, 8493 => 8230, 8494 => 8216, 8495 => 8217, 21 8496 => 8220, 8497 => 8221, 8498 => 12308, 8499 => 12309, 8500 => 12296, 22 8501 => 12297, 8502 => 12298, 8503 => 12299, 8504 => 12300, 8505 => 12301, 23 8506 => 12302, 8507 => 12303, 8508 => 12310, 8509 => 12311, 8510 => 12304, 24 8511 => 12305, 8512 => 177, 8513 => 215, 8514 => 247, 8515 => 8758, 25 8516 => 8743, 8517 => 8744, 8518 => 8721, 8519 => 8719, 8520 => 8746, 26 8521 => 8745, 8522 => 8712, 8523 => 8759, 8524 => 8730, 8525 => 8869, 27 8526 => 8741, 8527 => 8736, 8528 => 8978, 8529 => 8857, 8530 => 8747, 28 8531 => 8750, 8532 => 8801, 8533 => 8780, 8534 => 8776, 8535 => 8765, 29 8536 => 8733, 8537 => 8800, 8538 => 8814, 8539 => 8815, 8540 => 8804, 30 8541 => 8805, 8542 => 8734, 8543 => 8757, 8544 => 8756, 8545 => 9794, 31 8546 => 9792, 8547 => 176, 8548 => 8242, 8549 => 8243, 8550 => 8451, 32 8551 => 65284, 8552 => 164, 8553 => 65504, 8554 => 65505, 8555 => 8240, 33 8556 => 167, 8557 => 8470, 8558 => 9734, 8559 => 9733, 8560 => 9675, 34 8561 => 9679, 8562 => 9678, 8563 => 9671, 8564 => 9670, 8565 => 9633, 35 8566 => 9632, 8567 => 9651, 8568 => 9650, 8569 => 8251, 8570 => 8594, 36 8571 => 8592, 8572 => 8593, 8573 => 8595, 8574 => 12307, 8753 => 9352, 37 8754 => 9353, 8755 => 9354, 8756 => 9355, 8757 => 9356, 8758 => 9357, 38 8759 => 9358, 8760 => 9359, 8761 => 9360, 8762 => 9361, 8763 => 9362, 39 8764 => 9363, 8765 => 9364, 8766 => 9365, 8767 => 9366, 8768 => 9367, 40 8769 => 9368, 8770 => 9369, 8771 => 9370, 8772 => 9371, 8773 => 9332, 41 8774 => 9333, 8775 => 9334, 8776 => 9335, 8777 => 9336, 8778 => 9337, 42 8779 => 9338, 8780 => 9339, 8781 => 9340, 8782 => 9341, 8783 => 9342, 43 8784 => 9343, 8785 => 9344, 8786 => 9345, 8787 => 9346, 8788 => 9347, 44 8789 => 9348, 8790 => 9349, 8791 => 9350, 8792 => 9351, 8793 => 9312, 45 8794 => 9313, 8795 => 9314, 8796 => 9315, 8797 => 9316, 8798 => 9317, 46 8799 => 9318, 8800 => 9319, 8801 => 9320, 8802 => 9321, 8805 => 12832, 47 8806 => 12833, 8807 => 12834, 8808 => 12835, 8809 => 12836, 8810 => 12837, 48 8811 => 12838, 8812 => 12839, 8813 => 12840, 8814 => 12841, 8817 => 8544, 49 8818 => 8545, 8819 => 8546, 8820 => 8547, 8821 => 8548, 8822 => 8549, 50 8823 => 8550, 8824 => 8551, 8825 => 8552, 8826 => 8553, 8827 => 8554, 51 8828 => 8555, 8993 => 65281, 8994 => 65282, 8995 => 65283, 8996 => 65509, 52 8997 => 65285, 8998 => 65286, 8999 => 65287, 9000 => 65288, 9001 => 65289, 53 9002 => 65290, 9003 => 65291, 9004 => 65292, 9005 => 65293, 9006 => 65294, 54 9007 => 65295, 9008 => 65296, 9009 => 65297, 9010 => 65298, 9011 => 65299, 55 9012 => 65300, 9013 => 65301, 9014 => 65302, 9015 => 65303, 9016 => 65304, 56 9017 => 65305, 9018 => 65306, 9019 => 65307, 9020 => 65308, 9021 => 65309, 57 9022 => 65310, 9023 => 65311, 9024 => 65312, 9025 => 65313, 9026 => 65314, 58 9027 => 65315, 9028 => 65316, 9029 => 65317, 9030 => 65318, 9031 => 65319, 59 9032 => 65320, 9033 => 65321, 9034 => 65322, 9035 => 65323, 9036 => 65324, 60 9037 => 65325, 9038 => 65326, 9039 => 65327, 9040 => 65328, 9041 => 65329, 61 9042 => 65330, 9043 => 65331, 9044 => 65332, 9045 => 65333, 9046 => 65334, 62 9047 => 65335, 9048 => 65336, 9049 => 65337, 9050 => 65338, 9051 => 65339, 63 9052 => 65340, 9053 => 65341, 9054 => 65342, 9055 => 65343, 9056 => 65344, 64 9057 => 65345, 9058 => 65346, 9059 => 65347, 9060 => 65348, 9061 => 65349, 65 9062 => 65350, 9063 => 65351, 9064 => 65352, 9065 => 65353, 9066 => 65354, 66 9067 => 65355, 9068 => 65356, 9069 => 65357, 9070 => 65358, 9071 => 65359, 67 9072 => 65360, 9073 => 65361, 9074 => 65362, 9075 => 65363, 9076 => 65364, 68 9077 => 65365, 9078 => 65366, 9079 => 65367, 9080 => 65368, 9081 => 65369, 69 9082 => 65370, 9083 => 65371, 9084 => 65372, 9085 => 65373, 9086 => 65507, 70 9249 => 12353, 9250 => 12354, 9251 => 12355, 9252 => 12356, 9253 => 12357, 71 9254 => 12358, 9255 => 12359, 9256 => 12360, 9257 => 12361, 9258 => 12362, 72 9259 => 12363, 9260 => 12364, 9261 => 12365, 9262 => 12366, 9263 => 12367, 73 9264 => 12368, 9265 => 12369, 9266 => 12370, 9267 => 12371, 9268 => 12372, 74 9269 => 12373, 9270 => 12374, 9271 => 12375, 9272 => 12376, 9273 => 12377, 75 9274 => 12378, 9275 => 12379, 9276 => 12380, 9277 => 12381, 9278 => 12382, 76 9279 => 12383, 9280 => 12384, 9281 => 12385, 9282 => 12386, 9283 => 12387, 77 9284 => 12388, 9285 => 12389, 9286 => 12390, 9287 => 12391, 9288 => 12392, 78 9289 => 12393, 9290 => 12394, 9291 => 12395, 9292 => 12396, 9293 => 12397, 79 9294 => 12398, 9295 => 12399, 9296 => 12400, 9297 => 12401, 9298 => 12402, 80 9299 => 12403, 9300 => 12404, 9301 => 12405, 9302 => 12406, 9303 => 12407, 81 9304 => 12408, 9305 => 12409, 9306 => 12410, 9307 => 12411, 9308 => 12412, 82 9309 => 12413, 9310 => 12414, 9311 => 12415, 9312 => 12416, 9313 => 12417, 83 9314 => 12418, 9315 => 12419, 9316 => 12420, 9317 => 12421, 9318 => 12422, 84 9319 => 12423, 9320 => 12424, 9321 => 12425, 9322 => 12426, 9323 => 12427, 85 9324 => 12428, 9325 => 12429, 9326 => 12430, 9327 => 12431, 9328 => 12432, 86 9329 => 12433, 9330 => 12434, 9331 => 12435, 9505 => 12449, 9506 => 12450, 87 9507 => 12451, 9508 => 12452, 9509 => 12453, 9510 => 12454, 9511 => 12455, 88 9512 => 12456, 9513 => 12457, 9514 => 12458, 9515 => 12459, 9516 => 12460, 89 9517 => 12461, 9518 => 12462, 9519 => 12463, 9520 => 12464, 9521 => 12465, 90 9522 => 12466, 9523 => 12467, 9524 => 12468, 9525 => 12469, 9526 => 12470, 91 9527 => 12471, 9528 => 12472, 9529 => 12473, 9530 => 12474, 9531 => 12475, 92 9532 => 12476, 9533 => 12477, 9534 => 12478, 9535 => 12479, 9536 => 12480, 93 9537 => 12481, 9538 => 12482, 9539 => 12483, 9540 => 12484, 9541 => 12485, 94 9542 => 12486, 9543 => 12487, 9544 => 12488, 9545 => 12489, 9546 => 12490, 95 9547 => 12491, 9548 => 12492, 9549 => 12493, 9550 => 12494, 9551 => 12495, 96 9552 => 12496, 9553 => 12497, 9554 => 12498, 9555 => 12499, 9556 => 12500, 97 9557 => 12501, 9558 => 12502, 9559 => 12503, 9560 => 12504, 9561 => 12505, 98 9562 => 12506, 9563 => 12507, 9564 => 12508, 9565 => 12509, 9566 => 12510, 99 9567 => 12511, 9568 => 12512, 9569 => 12513, 9570 => 12514, 9571 => 12515, 100 9572 => 12516, 9573 => 12517, 9574 => 12518, 9575 => 12519, 9576 => 12520, 101 9577 => 12521, 9578 => 12522, 9579 => 12523, 9580 => 12524, 9581 => 12525, 102 9582 => 12526, 9583 => 12527, 9584 => 12528, 9585 => 12529, 9586 => 12530, 103 9587 => 12531, 9588 => 12532, 9589 => 12533, 9590 => 12534, 9761 => 913, 104 9762 => 914, 9763 => 915, 9764 => 916, 9765 => 917, 9766 => 918, 105 9767 => 919, 9768 => 920, 9769 => 921, 9770 => 922, 9771 => 923, 106 9772 => 924, 9773 => 925, 9774 => 926, 9775 => 927, 9776 => 928, 107 9777 => 929, 9778 => 931, 9779 => 932, 9780 => 933, 9781 => 934, 108 9782 => 935, 9783 => 936, 9784 => 937, 9793 => 945, 9794 => 946, 109 9795 => 947, 9796 => 948, 9797 => 949, 9798 => 950, 9799 => 951, 110 9800 => 952, 9801 => 953, 9802 => 954, 9803 => 955, 9804 => 956, 111 9805 => 957, 9806 => 958, 9807 => 959, 9808 => 960, 9809 => 961, 112 9810 => 963, 9811 => 964, 9812 => 965, 9813 => 966, 9814 => 967, 113 9815 => 968, 9816 => 969, 10017 => 1040, 10018 => 1041, 10019 => 1042, 114 10020 => 1043, 10021 => 1044, 10022 => 1045, 10023 => 1025, 10024 => 1046, 115 10025 => 1047, 10026 => 1048, 10027 => 1049, 10028 => 1050, 10029 => 1051, 116 10030 => 1052, 10031 => 1053, 10032 => 1054, 10033 => 1055, 10034 => 1056, 117 10035 => 1057, 10036 => 1058, 10037 => 1059, 10038 => 1060, 10039 => 1061, 118 10040 => 1062, 10041 => 1063, 10042 => 1064, 10043 => 1065, 10044 => 1066, 119 10045 => 1067, 10046 => 1068, 10047 => 1069, 10048 => 1070, 10049 => 1071, 120 10065 => 1072, 10066 => 1073, 10067 => 1074, 10068 => 1075, 10069 => 1076, 121 10070 => 1077, 10071 => 1105, 10072 => 1078, 10073 => 1079, 10074 => 1080, 122 10075 => 1081, 10076 => 1082, 10077 => 1083, 10078 => 1084, 10079 => 1085, 123 10080 => 1086, 10081 => 1087, 10082 => 1088, 10083 => 1089, 10084 => 1090, 124 10085 => 1091, 10086 => 1092, 10087 => 1093, 10088 => 1094, 10089 => 1095, 125 10090 => 1096, 10091 => 1097, 10092 => 1098, 10093 => 1099, 10094 => 1100, 126 10095 => 1101, 10096 => 1102, 10097 => 1103, 10273 => 257, 10274 => 225, 127 10275 => 462, 10276 => 224, 10277 => 275, 10278 => 233, 10279 => 283, 128 10280 => 232, 10281 => 299, 10282 => 237, 10283 => 464, 10284 => 236, 129 10285 => 333, 10286 => 243, 10287 => 466, 10288 => 242, 10289 => 363, 130 10290 => 250, 10291 => 468, 10292 => 249, 10293 => 470, 10294 => 472, 131 10295 => 474, 10296 => 476, 10297 => 252, 10298 => 234, 10309 => 12549, 132 10310 => 12550, 10311 => 12551, 10312 => 12552, 10313 => 12553, 10314 => 12554, 133 10315 => 12555, 10316 => 12556, 10317 => 12557, 10318 => 12558, 10319 => 12559, 134 10320 => 12560, 10321 => 12561, 10322 => 12562, 10323 => 12563, 10324 => 12564, 135 10325 => 12565, 10326 => 12566, 10327 => 12567, 10328 => 12568, 10329 => 12569, 136 10330 => 12570, 10331 => 12571, 10332 => 12572, 10333 => 12573, 10334 => 12574, 137 10335 => 12575, 10336 => 12576, 10337 => 12577, 10338 => 12578, 10339 => 12579, 138 10340 => 12580, 10341 => 12581, 10342 => 12582, 10343 => 12583, 10344 => 12584, 139 10345 => 12585, 10532 => 9472, 10533 => 9473, 10534 => 9474, 10535 => 9475, 140 10536 => 9476, 10537 => 9477, 10538 => 9478, 10539 => 9479, 10540 => 9480, 141 10541 => 9481, 10542 => 9482, 10543 => 9483, 10544 => 9484, 10545 => 9485, 142 10546 => 9486, 10547 => 9487, 10548 => 9488, 10549 => 9489, 10550 => 9490, 143 10551 => 9491, 10552 => 9492, 10553 => 9493, 10554 => 9494, 10555 => 9495, 144 10556 => 9496, 10557 => 9497, 10558 => 9498, 10559 => 9499, 10560 => 9500, 145 10561 => 9501, 10562 => 9502, 10563 => 9503, 10564 => 9504, 10565 => 9505, 146 10566 => 9506, 10567 => 9507, 10568 => 9508, 10569 => 9509, 10570 => 9510, 147 10571 => 9511, 10572 => 9512, 10573 => 9513, 10574 => 9514, 10575 => 9515, 148 10576 => 9516, 10577 => 9517, 10578 => 9518, 10579 => 9519, 10580 => 9520, 149 10581 => 9521, 10582 => 9522, 10583 => 9523, 10584 => 9524, 10585 => 9525, 150 10586 => 9526, 10587 => 9527, 10588 => 9528, 10589 => 9529, 10590 => 9530, 151 10591 => 9531, 10592 => 9532, 10593 => 9533, 10594 => 9534, 10595 => 9535, 152 10596 => 9536, 10597 => 9537, 10598 => 9538, 10599 => 9539, 10600 => 9540, 153 10601 => 9541, 10602 => 9542, 10603 => 9543, 10604 => 9544, 10605 => 9545, 154 10606 => 9546, 10607 => 9547, 12321 => 21834, 12322 => 38463, 12323 => 22467, 155 12324 => 25384, 12325 => 21710, 12326 => 21769, 12327 => 21696, 12328 => 30353, 156 12329 => 30284, 12330 => 34108, 12331 => 30702, 12332 => 33406, 12333 => 30861, 157 12334 => 29233, 12335 => 38552, 12336 => 38797, 12337 => 27688, 12338 => 23433, 158 12339 => 20474, 12340 => 25353, 12341 => 26263, 12342 => 23736, 12343 => 33018, 159 12344 => 26696, 12345 => 32942, 12346 => 26114, 12347 => 30414, 12348 => 20985, 160 12349 => 25942, 12350 => 29100, 12351 => 32753, 12352 => 34948, 12353 => 20658, 161 12354 => 22885, 12355 => 25034, 12356 => 28595, 12357 => 33453, 12358 => 25420, 162 12359 => 25170, 12360 => 21485, 12361 => 21543, 12362 => 31494, 12363 => 20843, 163 12364 => 30116, 12365 => 24052, 12366 => 25300, 12367 => 36299, 12368 => 38774, 164 12369 => 25226, 12370 => 32793, 12371 => 22365, 12372 => 38712, 12373 => 32610, 165 12374 => 29240, 12375 => 30333, 12376 => 26575, 12377 => 30334, 12378 => 25670, 166 12379 => 20336, 12380 => 36133, 12381 => 25308, 12382 => 31255, 12383 => 26001, 167 12384 => 29677, 12385 => 25644, 12386 => 25203, 12387 => 33324, 12388 => 39041, 168 12389 => 26495, 12390 => 29256, 12391 => 25198, 12392 => 25292, 12393 => 20276, 169 12394 => 29923, 12395 => 21322, 12396 => 21150, 12397 => 32458, 12398 => 37030, 170 12399 => 24110, 12400 => 26758, 12401 => 27036, 12402 => 33152, 12403 => 32465, 171 12404 => 26834, 12405 => 30917, 12406 => 34444, 12407 => 38225, 12408 => 20621, 172 12409 => 35876, 12410 => 33502, 12411 => 32990, 12412 => 21253, 12413 => 35090, 173 12414 => 21093, 12577 => 34180, 12578 => 38649, 12579 => 20445, 12580 => 22561, 174 12581 => 39281, 12582 => 23453, 12583 => 25265, 12584 => 25253, 12585 => 26292, 175 12586 => 35961, 12587 => 40077, 12588 => 29190, 12589 => 26479, 12590 => 30865, 176 12591 => 24754, 12592 => 21329, 12593 => 21271, 12594 => 36744, 12595 => 32972, 177 12596 => 36125, 12597 => 38049, 12598 => 20493, 12599 => 29384, 12600 => 22791, 178 12601 => 24811, 12602 => 28953, 12603 => 34987, 12604 => 22868, 12605 => 33519, 179 12606 => 26412, 12607 => 31528, 12608 => 23849, 12609 => 32503, 12610 => 29997, 180 12611 => 27893, 12612 => 36454, 12613 => 36856, 12614 => 36924, 12615 => 40763, 181 12616 => 27604, 12617 => 37145, 12618 => 31508, 12619 => 24444, 12620 => 30887, 182 12621 => 34006, 12622 => 34109, 12623 => 27605, 12624 => 27609, 12625 => 27606, 183 12626 => 24065, 12627 => 24199, 12628 => 30201, 12629 => 38381, 12630 => 25949, 184 12631 => 24330, 12632 => 24517, 12633 => 36767, 12634 => 22721, 12635 => 33218, 185 12636 => 36991, 12637 => 38491, 12638 => 38829, 12639 => 36793, 12640 => 32534, 186 12641 => 36140, 12642 => 25153, 12643 => 20415, 12644 => 21464, 12645 => 21342, 187 12646 => 36776, 12647 => 36777, 12648 => 36779, 12649 => 36941, 12650 => 26631, 188 12651 => 24426, 12652 => 33176, 12653 => 34920, 12654 => 40150, 12655 => 24971, 189 12656 => 21035, 12657 => 30250, 12658 => 24428, 12659 => 25996, 12660 => 28626, 190 12661 => 28392, 12662 => 23486, 12663 => 25672, 12664 => 20853, 12665 => 20912, 191 12666 => 26564, 12667 => 19993, 12668 => 31177, 12669 => 39292, 12670 => 28851, 192 12833 => 30149, 12834 => 24182, 12835 => 29627, 12836 => 33760, 12837 => 25773, 193 12838 => 25320, 12839 => 38069, 12840 => 27874, 12841 => 21338, 12842 => 21187, 194 12843 => 25615, 12844 => 38082, 12845 => 31636, 12846 => 20271, 12847 => 24091, 195 12848 => 33334, 12849 => 33046, 12850 => 33162, 12851 => 28196, 12852 => 27850, 196 12853 => 39539, 12854 => 25429, 12855 => 21340, 12856 => 21754, 12857 => 34917, 197 12858 => 22496, 12859 => 19981, 12860 => 24067, 12861 => 27493, 12862 => 31807, 198 12863 => 37096, 12864 => 24598, 12865 => 25830, 12866 => 29468, 12867 => 35009, 199 12868 => 26448, 12869 => 25165, 12870 => 36130, 12871 => 30572, 12872 => 36393, 200 12873 => 37319, 12874 => 24425, 12875 => 33756, 12876 => 34081, 12877 => 39184, 201 12878 => 21442, 12879 => 34453, 12880 => 27531, 12881 => 24813, 12882 => 24808, 202 12883 => 28799, 12884 => 33485, 12885 => 33329, 12886 => 20179, 12887 => 27815, 203 12888 => 34255, 12889 => 25805, 12890 => 31961, 12891 => 27133, 12892 => 26361, 204 12893 => 33609, 12894 => 21397, 12895 => 31574, 12896 => 20391, 12897 => 20876, 205 12898 => 27979, 12899 => 23618, 12900 => 36461, 12901 => 25554, 12902 => 21449, 206 12903 => 33580, 12904 => 33590, 12905 => 26597, 12906 => 30900, 12907 => 25661, 207 12908 => 23519, 12909 => 23700, 12910 => 24046, 12911 => 35815, 12912 => 25286, 208 12913 => 26612, 12914 => 35962, 12915 => 25600, 12916 => 25530, 12917 => 34633, 209 12918 => 39307, 12919 => 35863, 12920 => 32544, 12921 => 38130, 12922 => 20135, 210 12923 => 38416, 12924 => 39076, 12925 => 26124, 12926 => 29462, 13089 => 22330, 211 13090 => 23581, 13091 => 24120, 13092 => 38271, 13093 => 20607, 13094 => 32928, 212 13095 => 21378, 13096 => 25950, 13097 => 30021, 13098 => 21809, 13099 => 20513, 213 13100 => 36229, 13101 => 25220, 13102 => 38046, 13103 => 26397, 13104 => 22066, 214 13105 => 28526, 13106 => 24034, 13107 => 21557, 13108 => 28818, 13109 => 36710, 215 13110 => 25199, 13111 => 25764, 13112 => 25507, 13113 => 24443, 13114 => 28552, 216 13115 => 37108, 13116 => 33251, 13117 => 36784, 13118 => 23576, 13119 => 26216, 217 13120 => 24561, 13121 => 27785, 13122 => 38472, 13123 => 36225, 13124 => 34924, 218 13125 => 25745, 13126 => 31216, 13127 => 22478, 13128 => 27225, 13129 => 25104, 219 13130 => 21576, 13131 => 20056, 13132 => 31243, 13133 => 24809, 13134 => 28548, 220 13135 => 35802, 13136 => 25215, 13137 => 36894, 13138 => 39563, 13139 => 31204, 221 13140 => 21507, 13141 => 30196, 13142 => 25345, 13143 => 21273, 13144 => 27744, 222 13145 => 36831, 13146 => 24347, 13147 => 39536, 13148 => 32827, 13149 => 40831, 223 13150 => 20360, 13151 => 23610, 13152 => 36196, 13153 => 32709, 13154 => 26021, 224 13155 => 28861, 13156 => 20805, 13157 => 20914, 13158 => 34411, 13159 => 23815, 225 13160 => 23456, 13161 => 25277, 13162 => 37228, 13163 => 30068, 13164 => 36364, 226 13165 => 31264, 13166 => 24833, 13167 => 31609, 13168 => 20167, 13169 => 32504, 227 13170 => 30597, 13171 => 19985, 13172 => 33261, 13173 => 21021, 13174 => 20986, 228 13175 => 27249, 13176 => 21416, 13177 => 36487, 13178 => 38148, 13179 => 38607, 229 13180 => 28353, 13181 => 38500, 13182 => 26970, 13345 => 30784, 13346 => 20648, 230 13347 => 30679, 13348 => 25616, 13349 => 35302, 13350 => 22788, 13351 => 25571, 231 13352 => 24029, 13353 => 31359, 13354 => 26941, 13355 => 20256, 13356 => 33337, 232 13357 => 21912, 13358 => 20018, 13359 => 30126, 13360 => 31383, 13361 => 24162, 233 13362 => 24202, 13363 => 38383, 13364 => 21019, 13365 => 21561, 13366 => 28810, 234 13367 => 25462, 13368 => 38180, 13369 => 22402, 13370 => 26149, 13371 => 26943, 235 13372 => 37255, 13373 => 21767, 13374 => 28147, 13375 => 32431, 13376 => 34850, 236 13377 => 25139, 13378 => 32496, 13379 => 30133, 13380 => 33576, 13381 => 30913, 237 13382 => 38604, 13383 => 36766, 13384 => 24904, 13385 => 29943, 13386 => 35789, 238 13387 => 27492, 13388 => 21050, 13389 => 36176, 13390 => 27425, 13391 => 32874, 239 13392 => 33905, 13393 => 22257, 13394 => 21254, 13395 => 20174, 13396 => 19995, 240 13397 => 20945, 13398 => 31895, 13399 => 37259, 13400 => 31751, 13401 => 20419, 241 13402 => 36479, 13403 => 31713, 13404 => 31388, 13405 => 25703, 13406 => 23828, 242 13407 => 20652, 13408 => 33030, 13409 => 30209, 13410 => 31929, 13411 => 28140, 243 13412 => 32736, 13413 => 26449, 13414 => 23384, 13415 => 23544, 13416 => 30923, 244 13417 => 25774, 13418 => 25619, 13419 => 25514, 13420 => 25387, 13421 => 38169, 245 13422 => 25645, 13423 => 36798, 13424 => 31572, 13425 => 30249, 13426 => 25171, 246 13427 => 22823, 13428 => 21574, 13429 => 27513, 13430 => 20643, 13431 => 25140, 247 13432 => 24102, 13433 => 27526, 13434 => 20195, 13435 => 36151, 13436 => 34955, 248 13437 => 24453, 13438 => 36910, 13601 => 24608, 13602 => 32829, 13603 => 25285, 249 13604 => 20025, 13605 => 21333, 13606 => 37112, 13607 => 25528, 13608 => 32966, 250 13609 => 26086, 13610 => 27694, 13611 => 20294, 13612 => 24814, 13613 => 28129, 251 13614 => 35806, 13615 => 24377, 13616 => 34507, 13617 => 24403, 13618 => 25377, 252 13619 => 20826, 13620 => 33633, 13621 => 26723, 13622 => 20992, 13623 => 25443, 253 13624 => 36424, 13625 => 20498, 13626 => 23707, 13627 => 31095, 13628 => 23548, 254 13629 => 21040, 13630 => 31291, 13631 => 24764, 13632 => 36947, 13633 => 30423, 255 13634 => 24503, 13635 => 24471, 13636 => 30340, 13637 => 36460, 13638 => 28783, 256 13639 => 30331, 13640 => 31561, 13641 => 30634, 13642 => 20979, 13643 => 37011, 257 13644 => 22564, 13645 => 20302, 13646 => 28404, 13647 => 36842, 13648 => 25932, 258 13649 => 31515, 13650 => 29380, 13651 => 28068, 13652 => 32735, 13653 => 23265, 259 13654 => 25269, 13655 => 24213, 13656 => 22320, 13657 => 33922, 13658 => 31532, 260 13659 => 24093, 13660 => 24351, 13661 => 36882, 13662 => 32532, 13663 => 39072, 261 13664 => 25474, 13665 => 28359, 13666 => 30872, 13667 => 28857, 13668 => 20856, 262 13669 => 38747, 13670 => 22443, 13671 => 30005, 13672 => 20291, 13673 => 30008, 263 13674 => 24215, 13675 => 24806, 13676 => 22880, 13677 => 28096, 13678 => 27583, 264 13679 => 30857, 13680 => 21500, 13681 => 38613, 13682 => 20939, 13683 => 20993, 265 13684 => 25481, 13685 => 21514, 13686 => 38035, 13687 => 35843, 13688 => 36300, 266 13689 => 29241, 13690 => 30879, 13691 => 34678, 13692 => 36845, 13693 => 35853, 267 13694 => 21472, 13857 => 19969, 13858 => 30447, 13859 => 21486, 13860 => 38025, 268 13861 => 39030, 13862 => 40718, 13863 => 38189, 13864 => 23450, 13865 => 35746, 269 13866 => 20002, 13867 => 19996, 13868 => 20908, 13869 => 33891, 13870 => 25026, 270 13871 => 21160, 13872 => 26635, 13873 => 20375, 13874 => 24683, 13875 => 20923, 271 13876 => 27934, 13877 => 20828, 13878 => 25238, 13879 => 26007, 13880 => 38497, 272 13881 => 35910, 13882 => 36887, 13883 => 30168, 13884 => 37117, 13885 => 30563, 273 13886 => 27602, 13887 => 29322, 13888 => 29420, 13889 => 35835, 13890 => 22581, 274 13891 => 30585, 13892 => 36172, 13893 => 26460, 13894 => 38208, 13895 => 32922, 275 13896 => 24230, 13897 => 28193, 13898 => 22930, 13899 => 31471, 13900 => 30701, 276 13901 => 38203, 13902 => 27573, 13903 => 26029, 13904 => 32526, 13905 => 22534, 277 13906 => 20817, 13907 => 38431, 13908 => 23545, 13909 => 22697, 13910 => 21544, 278 13911 => 36466, 13912 => 25958, 13913 => 39039, 13914 => 22244, 13915 => 38045, 279 13916 => 30462, 13917 => 36929, 13918 => 25479, 13919 => 21702, 13920 => 22810, 280 13921 => 22842, 13922 => 22427, 13923 => 36530, 13924 => 26421, 13925 => 36346, 281 13926 => 33333, 13927 => 21057, 13928 => 24816, 13929 => 22549, 13930 => 34558, 282 13931 => 23784, 13932 => 40517, 13933 => 20420, 13934 => 39069, 13935 => 35769, 283 13936 => 23077, 13937 => 24694, 13938 => 21380, 13939 => 25212, 13940 => 36943, 284 13941 => 37122, 13942 => 39295, 13943 => 24681, 13944 => 32780, 13945 => 20799, 285 13946 => 32819, 13947 => 23572, 13948 => 39285, 13949 => 27953, 13950 => 20108, 286 14113 => 36144, 14114 => 21457, 14115 => 32602, 14116 => 31567, 14117 => 20240, 287 14118 => 20047, 14119 => 38400, 14120 => 27861, 14121 => 29648, 14122 => 34281, 288 14123 => 24070, 14124 => 30058, 14125 => 32763, 14126 => 27146, 14127 => 30718, 289 14128 => 38034, 14129 => 32321, 14130 => 20961, 14131 => 28902, 14132 => 21453, 290 14133 => 36820, 14134 => 33539, 14135 => 36137, 14136 => 29359, 14137 => 39277, 291 14138 => 27867, 14139 => 22346, 14140 => 33459, 14141 => 26041, 14142 => 32938, 292 14143 => 25151, 14144 => 38450, 14145 => 22952, 14146 => 20223, 14147 => 35775, 293 14148 => 32442, 14149 => 25918, 14150 => 33778, 14151 => 38750, 14152 => 21857, 294 14153 => 39134, 14154 => 32933, 14155 => 21290, 14156 => 35837, 14157 => 21536, 295 14158 => 32954, 14159 => 24223, 14160 => 27832, 14161 => 36153, 14162 => 33452, 296 14163 => 37210, 14164 => 21545, 14165 => 27675, 14166 => 20998, 14167 => 32439, 297 14168 => 22367, 14169 => 28954, 14170 => 27774, 14171 => 31881, 14172 => 22859, 298 14173 => 20221, 14174 => 24575, 14175 => 24868, 14176 => 31914, 14177 => 20016, 299 14178 => 23553, 14179 => 26539, 14180 => 34562, 14181 => 23792, 14182 => 38155, 300 14183 => 39118, 14184 => 30127, 14185 => 28925, 14186 => 36898, 14187 => 20911, 301 14188 => 32541, 14189 => 35773, 14190 => 22857, 14191 => 20964, 14192 => 20315, 302 14193 => 21542, 14194 => 22827, 14195 => 25975, 14196 => 32932, 14197 => 23413, 303 14198 => 25206, 14199 => 25282, 14200 => 36752, 14201 => 24133, 14202 => 27679, 304 14203 => 31526, 14204 => 20239, 14205 => 20440, 14206 => 26381, 14369 => 28014, 305 14370 => 28074, 14371 => 31119, 14372 => 34993, 14373 => 24343, 14374 => 29995, 306 14375 => 25242, 14376 => 36741, 14377 => 20463, 14378 => 37340, 14379 => 26023, 307 14380 => 33071, 14381 => 33105, 14382 => 24220, 14383 => 33104, 14384 => 36212, 308 14385 => 21103, 14386 => 35206, 14387 => 36171, 14388 => 22797, 14389 => 20613, 309 14390 => 20184, 14391 => 38428, 14392 => 29238, 14393 => 33145, 14394 => 36127, 310 14395 => 23500, 14396 => 35747, 14397 => 38468, 14398 => 22919, 14399 => 32538, 311 14400 => 21648, 14401 => 22134, 14402 => 22030, 14403 => 35813, 14404 => 25913, 312 14405 => 27010, 14406 => 38041, 14407 => 30422, 14408 => 28297, 14409 => 24178, 313 14410 => 29976, 14411 => 26438, 14412 => 26577, 14413 => 31487, 14414 => 32925, 314 14415 => 36214, 14416 => 24863, 14417 => 31174, 14418 => 25954, 14419 => 36195, 315 14420 => 20872, 14421 => 21018, 14422 => 38050, 14423 => 32568, 14424 => 32923, 316 14425 => 32434, 14426 => 23703, 14427 => 28207, 14428 => 26464, 14429 => 31705, 317 14430 => 30347, 14431 => 39640, 14432 => 33167, 14433 => 32660, 14434 => 31957, 318 14435 => 25630, 14436 => 38224, 14437 => 31295, 14438 => 21578, 14439 => 21733, 319 14440 => 27468, 14441 => 25601, 14442 => 25096, 14443 => 40509, 14444 => 33011, 320 14445 => 30105, 14446 => 21106, 14447 => 38761, 14448 => 33883, 14449 => 26684, 321 14450 => 34532, 14451 => 38401, 14452 => 38548, 14453 => 38124, 14454 => 20010, 322 14455 => 21508, 14456 => 32473, 14457 => 26681, 14458 => 36319, 14459 => 32789, 323 14460 => 26356, 14461 => 24218, 14462 => 32697, 14625 => 22466, 14626 => 32831, 324 14627 => 26775, 14628 => 24037, 14629 => 25915, 14630 => 21151, 14631 => 24685, 325 14632 => 40858, 14633 => 20379, 14634 => 36524, 14635 => 20844, 14636 => 23467, 326 14637 => 24339, 14638 => 24041, 14639 => 27742, 14640 => 25329, 14641 => 36129, 327 14642 => 20849, 14643 => 38057, 14644 => 21246, 14645 => 27807, 14646 => 33503, 328 14647 => 29399, 14648 => 22434, 14649 => 26500, 14650 => 36141, 14651 => 22815, 329 14652 => 36764, 14653 => 33735, 14654 => 21653, 14655 => 31629, 14656 => 20272, 330 14657 => 27837, 14658 => 23396, 14659 => 22993, 14660 => 40723, 14661 => 21476, 331 14662 => 34506, 14663 => 39592, 14664 => 35895, 14665 => 32929, 14666 => 25925, 332 14667 => 39038, 14668 => 22266, 14669 => 38599, 14670 => 21038, 14671 => 29916, 333 14672 => 21072, 14673 => 23521, 14674 => 25346, 14675 => 35074, 14676 => 20054, 334 14677 => 25296, 14678 => 24618, 14679 => 26874, 14680 => 20851, 14681 => 23448, 335 14682 => 20896, 14683 => 35266, 14684 => 31649, 14685 => 39302, 14686 => 32592, 336 14687 => 24815, 14688 => 28748, 14689 => 36143, 14690 => 20809, 14691 => 24191, 337 14692 => 36891, 14693 => 29808, 14694 => 35268, 14695 => 22317, 14696 => 30789, 338 14697 => 24402, 14698 => 40863, 14699 => 38394, 14700 => 36712, 14701 => 39740, 339 14702 => 35809, 14703 => 30328, 14704 => 26690, 14705 => 26588, 14706 => 36330, 340 14707 => 36149, 14708 => 21053, 14709 => 36746, 14710 => 28378, 14711 => 26829, 341 14712 => 38149, 14713 => 37101, 14714 => 22269, 14715 => 26524, 14716 => 35065, 342 14717 => 36807, 14718 => 21704, 14881 => 39608, 14882 => 23401, 14883 => 28023, 343 14884 => 27686, 14885 => 20133, 14886 => 23475, 14887 => 39559, 14888 => 37219, 344 14889 => 25000, 14890 => 37039, 14891 => 38889, 14892 => 21547, 14893 => 28085, 345 14894 => 23506, 14895 => 20989, 14896 => 21898, 14897 => 32597, 14898 => 32752, 346 14899 => 25788, 14900 => 25421, 14901 => 26097, 14902 => 25022, 14903 => 24717, 347 14904 => 28938, 14905 => 27735, 14906 => 27721, 14907 => 22831, 14908 => 26477, 348 14909 => 33322, 14910 => 22741, 14911 => 22158, 14912 => 35946, 14913 => 27627, 349 14914 => 37085, 14915 => 22909, 14916 => 32791, 14917 => 21495, 14918 => 28009, 350 14919 => 21621, 14920 => 21917, 14921 => 33655, 14922 => 33743, 14923 => 26680, 351 14924 => 31166, 14925 => 21644, 14926 => 20309, 14927 => 21512, 14928 => 30418, 352 14929 => 35977, 14930 => 38402, 14931 => 27827, 14932 => 28088, 14933 => 36203, 353 14934 => 35088, 14935 => 40548, 14936 => 36154, 14937 => 22079, 14938 => 40657, 354 14939 => 30165, 14940 => 24456, 14941 => 29408, 14942 => 24680, 14943 => 21756, 355 14944 => 20136, 14945 => 27178, 14946 => 34913, 14947 => 24658, 14948 => 36720, 356 14949 => 21700, 14950 => 28888, 14951 => 34425, 14952 => 40511, 14953 => 27946, 357 14954 => 23439, 14955 => 24344, 14956 => 32418, 14957 => 21897, 14958 => 20399, 358 14959 => 29492, 14960 => 21564, 14961 => 21402, 14962 => 20505, 14963 => 21518, 359 14964 => 21628, 14965 => 20046, 14966 => 24573, 14967 => 29786, 14968 => 22774, 360 14969 => 33899, 14970 => 32993, 14971 => 34676, 14972 => 29392, 14973 => 31946, 361 14974 => 28246, 15137 => 24359, 15138 => 34382, 15139 => 21804, 15140 => 25252, 362 15141 => 20114, 15142 => 27818, 15143 => 25143, 15144 => 33457, 15145 => 21719, 363 15146 => 21326, 15147 => 29502, 15148 => 28369, 15149 => 30011, 15150 => 21010, 364 15151 => 21270, 15152 => 35805, 15153 => 27088, 15154 => 24458, 15155 => 24576, 365 15156 => 28142, 15157 => 22351, 15158 => 27426, 15159 => 29615, 15160 => 26707, 366 15161 => 36824, 15162 => 32531, 15163 => 25442, 15164 => 24739, 15165 => 21796, 367 15166 => 30186, 15167 => 35938, 15168 => 28949, 15169 => 28067, 15170 => 23462, 368 15171 => 24187, 15172 => 33618, 15173 => 24908, 15174 => 40644, 15175 => 30970, 369 15176 => 34647, 15177 => 31783, 15178 => 30343, 15179 => 20976, 15180 => 24822, 370 15181 => 29004, 15182 => 26179, 15183 => 24140, 15184 => 24653, 15185 => 35854, 371 15186 => 28784, 15187 => 25381, 15188 => 36745, 15189 => 24509, 15190 => 24674, 372 15191 => 34516, 15192 => 22238, 15193 => 27585, 15194 => 24724, 15195 => 24935, 373 15196 => 21321, 15197 => 24800, 15198 => 26214, 15199 => 36159, 15200 => 31229, 374 15201 => 20250, 15202 => 28905, 15203 => 27719, 15204 => 35763, 15205 => 35826, 375 15206 => 32472, 15207 => 33636, 15208 => 26127, 15209 => 23130, 15210 => 39746, 376 15211 => 27985, 15212 => 28151, 15213 => 35905, 15214 => 27963, 15215 => 20249, 377 15216 => 28779, 15217 => 33719, 15218 => 25110, 15219 => 24785, 15220 => 38669, 378 15221 => 36135, 15222 => 31096, 15223 => 20987, 15224 => 22334, 15225 => 22522, 379 15226 => 26426, 15227 => 30072, 15228 => 31293, 15229 => 31215, 15230 => 31637, 380 15393 => 32908, 15394 => 39269, 15395 => 36857, 15396 => 28608, 15397 => 35749, 381 15398 => 40481, 15399 => 23020, 15400 => 32489, 15401 => 32521, 15402 => 21513, 382 15403 => 26497, 15404 => 26840, 15405 => 36753, 15406 => 31821, 15407 => 38598, 383 15408 => 21450, 15409 => 24613, 15410 => 30142, 15411 => 27762, 15412 => 21363, 384 15413 => 23241, 15414 => 32423, 15415 => 25380, 15416 => 20960, 15417 => 33034, 385 15418 => 24049, 15419 => 34015, 15420 => 25216, 15421 => 20864, 15422 => 23395, 386 15423 => 20238, 15424 => 31085, 15425 => 21058, 15426 => 24760, 15427 => 27982, 387 15428 => 23492, 15429 => 23490, 15430 => 35745, 15431 => 35760, 15432 => 26082, 388 15433 => 24524, 15434 => 38469, 15435 => 22931, 15436 => 32487, 15437 => 32426, 389 15438 => 22025, 15439 => 26551, 15440 => 22841, 15441 => 20339, 15442 => 23478, 390 15443 => 21152, 15444 => 33626, 15445 => 39050, 15446 => 36158, 15447 => 30002, 391 15448 => 38078, 15449 => 20551, 15450 => 31292, 15451 => 20215, 15452 => 26550, 392 15453 => 39550, 15454 => 23233, 15455 => 27516, 15456 => 30417, 15457 => 22362, 393 15458 => 23574, 15459 => 31546, 15460 => 38388, 15461 => 29006, 15462 => 20860, 394 15463 => 32937, 15464 => 33392, 15465 => 22904, 15466 => 32516, 15467 => 33575, 395 15468 => 26816, 15469 => 26604, 15470 => 30897, 15471 => 30839, 15472 => 25315, 396 15473 => 25441, 15474 => 31616, 15475 => 20461, 15476 => 21098, 15477 => 20943, 397 15478 => 33616, 15479 => 27099, 15480 => 37492, 15481 => 36341, 15482 => 36145, 398 15483 => 35265, 15484 => 38190, 15485 => 31661, 15486 => 20214, 15649 => 20581, 399 15650 => 33328, 15651 => 21073, 15652 => 39279, 15653 => 28176, 15654 => 28293, 400 15655 => 28071, 15656 => 24314, 15657 => 20725, 15658 => 23004, 15659 => 23558, 401 15660 => 27974, 15661 => 27743, 15662 => 30086, 15663 => 33931, 15664 => 26728, 402 15665 => 22870, 15666 => 35762, 15667 => 21280, 15668 => 37233, 15669 => 38477, 403 15670 => 34121, 15671 => 26898, 15672 => 30977, 15673 => 28966, 15674 => 33014, 404 15675 => 20132, 15676 => 37066, 15677 => 27975, 15678 => 39556, 15679 => 23047, 405 15680 => 22204, 15681 => 25605, 15682 => 38128, 15683 => 30699, 15684 => 20389, 406 15685 => 33050, 15686 => 29409, 15687 => 35282, 15688 => 39290, 15689 => 32564, 407 15690 => 32478, 15691 => 21119, 15692 => 25945, 15693 => 37237, 15694 => 36735, 408 15695 => 36739, 15696 => 21483, 15697 => 31382, 15698 => 25581, 15699 => 25509, 409 15700 => 30342, 15701 => 31224, 15702 => 34903, 15703 => 38454, 15704 => 25130, 410 15705 => 21163, 15706 => 33410, 15707 => 26708, 15708 => 26480, 15709 => 25463, 411 15710 => 30571, 15711 => 31469, 15712 => 27905, 15713 => 32467, 15714 => 35299, 412 15715 => 22992, 15716 => 25106, 15717 => 34249, 15718 => 33445, 15719 => 30028, 413 15720 => 20511, 15721 => 20171, 15722 => 30117, 15723 => 35819, 15724 => 23626, 414 15725 => 24062, 15726 => 31563, 15727 => 26020, 15728 => 37329, 15729 => 20170, 415 15730 => 27941, 15731 => 35167, 15732 => 32039, 15733 => 38182, 15734 => 20165, 416 15735 => 35880, 15736 => 36827, 15737 => 38771, 15738 => 26187, 15739 => 31105, 417 15740 => 36817, 15741 => 28908, 15742 => 28024, 15905 => 23613, 15906 => 21170, 418 15907 => 33606, 15908 => 20834, 15909 => 33550, 15910 => 30555, 15911 => 26230, 419 15912 => 40120, 15913 => 20140, 15914 => 24778, 15915 => 31934, 15916 => 31923, 420 15917 => 32463, 15918 => 20117, 15919 => 35686, 15920 => 26223, 15921 => 39048, 421 15922 => 38745, 15923 => 22659, 15924 => 25964, 15925 => 38236, 15926 => 24452, 422 15927 => 30153, 15928 => 38742, 15929 => 31455, 15930 => 31454, 15931 => 20928, 423 15932 => 28847, 15933 => 31384, 15934 => 25578, 15935 => 31350, 15936 => 32416, 424 15937 => 29590, 15938 => 38893, 15939 => 20037, 15940 => 28792, 15941 => 20061, 425 15942 => 37202, 15943 => 21417, 15944 => 25937, 15945 => 26087, 15946 => 33276, 426 15947 => 33285, 15948 => 21646, 15949 => 23601, 15950 => 30106, 15951 => 38816, 427 15952 => 25304, 15953 => 29401, 15954 => 30141, 15955 => 23621, 15956 => 39545, 428 15957 => 33738, 15958 => 23616, 15959 => 21632, 15960 => 30697, 15961 => 20030, 429 15962 => 27822, 15963 => 32858, 15964 => 25298, 15965 => 25454, 15966 => 24040, 430 15967 => 20855, 15968 => 36317, 15969 => 36382, 15970 => 38191, 15971 => 20465, 431 15972 => 21477, 15973 => 24807, 15974 => 28844, 15975 => 21095, 15976 => 25424, 432 15977 => 40515, 15978 => 23071, 15979 => 20518, 15980 => 30519, 15981 => 21367, 433 15982 => 32482, 15983 => 25733, 15984 => 25899, 15985 => 25225, 15986 => 25496, 434 15987 => 20500, 15988 => 29237, 15989 => 35273, 15990 => 20915, 15991 => 35776, 435 15992 => 32477, 15993 => 22343, 15994 => 33740, 15995 => 38055, 15996 => 20891, 436 15997 => 21531, 15998 => 23803, 16161 => 20426, 16162 => 31459, 16163 => 27994, 437 16164 => 37089, 16165 => 39567, 16166 => 21888, 16167 => 21654, 16168 => 21345, 438 16169 => 21679, 16170 => 24320, 16171 => 25577, 16172 => 26999, 16173 => 20975, 439 16174 => 24936, 16175 => 21002, 16176 => 22570, 16177 => 21208, 16178 => 22350, 440 16179 => 30733, 16180 => 30475, 16181 => 24247, 16182 => 24951, 16183 => 31968, 441 16184 => 25179, 16185 => 25239, 16186 => 20130, 16187 => 28821, 16188 => 32771, 442 16189 => 25335, 16190 => 28900, 16191 => 38752, 16192 => 22391, 16193 => 33499, 443 16194 => 26607, 16195 => 26869, 16196 => 30933, 16197 => 39063, 16198 => 31185, 444 16199 => 22771, 16200 => 21683, 16201 => 21487, 16202 => 28212, 16203 => 20811, 445 16204 => 21051, 16205 => 23458, 16206 => 35838, 16207 => 32943, 16208 => 21827, 446 16209 => 22438, 16210 => 24691, 16211 => 22353, 16212 => 21549, 16213 => 31354, 447 16214 => 24656, 16215 => 23380, 16216 => 25511, 16217 => 25248, 16218 => 21475, 448 16219 => 25187, 16220 => 23495, 16221 => 26543, 16222 => 21741, 16223 => 31391, 449 16224 => 33510, 16225 => 37239, 16226 => 24211, 16227 => 35044, 16228 => 22840, 450 16229 => 22446, 16230 => 25358, 16231 => 36328, 16232 => 33007, 16233 => 22359, 451 16234 => 31607, 16235 => 20393, 16236 => 24555, 16237 => 23485, 16238 => 27454, 452 16239 => 21281, 16240 => 31568, 16241 => 29378, 16242 => 26694, 16243 => 30719, 453 16244 => 30518, 16245 => 26103, 16246 => 20917, 16247 => 20111, 16248 => 30420, 454 16249 => 23743, 16250 => 31397, 16251 => 33909, 16252 => 22862, 16253 => 39745, 455 16254 => 20608, 16417 => 39304, 16418 => 24871, 16419 => 28291, 16420 => 22372, 456 16421 => 26118, 16422 => 25414, 16423 => 22256, 16424 => 25324, 16425 => 25193, 457 16426 => 24275, 16427 => 38420, 16428 => 22403, 16429 => 25289, 16430 => 21895, 458 16431 => 34593, 16432 => 33098, 16433 => 36771, 16434 => 21862, 16435 => 33713, 459 16436 => 26469, 16437 => 36182, 16438 => 34013, 16439 => 23146, 16440 => 26639, 460 16441 => 25318, 16442 => 31726, 16443 => 38417, 16444 => 20848, 16445 => 28572, 461 16446 => 35888, 16447 => 25597, 16448 => 35272, 16449 => 25042, 16450 => 32518, 462 16451 => 28866, 16452 => 28389, 16453 => 29701, 16454 => 27028, 16455 => 29436, 463 16456 => 24266, 16457 => 37070, 16458 => 26391, 16459 => 28010, 16460 => 25438, 464 16461 => 21171, 16462 => 29282, 16463 => 32769, 16464 => 20332, 16465 => 23013, 465 16466 => 37226, 16467 => 28889, 16468 => 28061, 16469 => 21202, 16470 => 20048, 466 16471 => 38647, 16472 => 38253, 16473 => 34174, 16474 => 30922, 16475 => 32047, 467 16476 => 20769, 16477 => 22418, 16478 => 25794, 16479 => 32907, 16480 => 31867, 468 16481 => 27882, 16482 => 26865, 16483 => 26974, 16484 => 20919, 16485 => 21400, 469 16486 => 26792, 16487 => 29313, 16488 => 40654, 16489 => 31729, 16490 => 29432, 470 16491 => 31163, 16492 => 28435, 16493 => 29702, 16494 => 26446, 16495 => 37324, 471 16496 => 40100, 16497 => 31036, 16498 => 33673, 16499 => 33620, 16500 => 21519, 472 16501 => 26647, 16502 => 20029, 16503 => 21385, 16504 => 21169, 16505 => 30782, 473 16506 => 21382, 16507 => 21033, 16508 => 20616, 16509 => 20363, 16510 => 20432, 474 16673 => 30178, 16674 => 31435, 16675 => 31890, 16676 => 27813, 16677 => 38582, 475 16678 => 21147, 16679 => 29827, 16680 => 21737, 16681 => 20457, 16682 => 32852, 476 16683 => 33714, 16684 => 36830, 16685 => 38256, 16686 => 24265, 16687 => 24604, 477 16688 => 28063, 16689 => 24088, 16690 => 25947, 16691 => 33080, 16692 => 38142, 478 16693 => 24651, 16694 => 28860, 16695 => 32451, 16696 => 31918, 16697 => 20937, 479 16698 => 26753, 16699 => 31921, 16700 => 33391, 16701 => 20004, 16702 => 36742, 480 16703 => 37327, 16704 => 26238, 16705 => 20142, 16706 => 35845, 16707 => 25769, 481 16708 => 32842, 16709 => 20698, 16710 => 30103, 16711 => 29134, 16712 => 23525, 482 16713 => 36797, 16714 => 28518, 16715 => 20102, 16716 => 25730, 16717 => 38243, 483 16718 => 24278, 16719 => 26009, 16720 => 21015, 16721 => 35010, 16722 => 28872, 484 16723 => 21155, 16724 => 29454, 16725 => 29747, 16726 => 26519, 16727 => 30967, 485 16728 => 38678, 16729 => 20020, 16730 => 37051, 16731 => 40158, 16732 => 28107, 486 16733 => 20955, 16734 => 36161, 16735 => 21533, 16736 => 25294, 16737 => 29618, 487 16738 => 33777, 16739 => 38646, 16740 => 40836, 16741 => 38083, 16742 => 20278, 488 16743 => 32666, 16744 => 20940, 16745 => 28789, 16746 => 38517, 16747 => 23725, 489 16748 => 39046, 16749 => 21478, 16750 => 20196, 16751 => 28316, 16752 => 29705, 490 16753 => 27060, 16754 => 30827, 16755 => 39311, 16756 => 30041, 16757 => 21016, 491 16758 => 30244, 16759 => 27969, 16760 => 26611, 16761 => 20845, 16762 => 40857, 492 16763 => 32843, 16764 => 21657, 16765 => 31548, 16766 => 31423, 16929 => 38534, 493 16930 => 22404, 16931 => 25314, 16932 => 38471, 16933 => 27004, 16934 => 23044, 494 16935 => 25602, 16936 => 31699, 16937 => 28431, 16938 => 38475, 16939 => 33446, 495 16940 => 21346, 16941 => 39045, 16942 => 24208, 16943 => 28809, 16944 => 25523, 496 16945 => 21348, 16946 => 34383, 16947 => 40065, 16948 => 40595, 16949 => 30860, 497 16950 => 38706, 16951 => 36335, 16952 => 36162, 16953 => 40575, 16954 => 28510, 498 16955 => 31108, 16956 => 24405, 16957 => 38470, 16958 => 25134, 16959 => 39540, 499 16960 => 21525, 16961 => 38109, 16962 => 20387, 16963 => 26053, 16964 => 23653, 500 16965 => 23649, 16966 => 32533, 16967 => 34385, 16968 => 27695, 16969 => 24459, 501 16970 => 29575, 16971 => 28388, 16972 => 32511, 16973 => 23782, 16974 => 25371, 502 16975 => 23402, 16976 => 28390, 16977 => 21365, 16978 => 20081, 16979 => 25504, 503 16980 => 30053, 16981 => 25249, 16982 => 36718, 16983 => 20262, 16984 => 20177, 504 16985 => 27814, 16986 => 32438, 16987 => 35770, 16988 => 33821, 16989 => 34746, 505 16990 => 32599, 16991 => 36923, 16992 => 38179, 16993 => 31657, 16994 => 39585, 506 16995 => 35064, 16996 => 33853, 16997 => 27931, 16998 => 39558, 16999 => 32476, 507 17000 => 22920, 17001 => 40635, 17002 => 29595, 17003 => 30721, 17004 => 34434, 508 17005 => 39532, 17006 => 39554, 17007 => 22043, 17008 => 21527, 17009 => 22475, 509 17010 => 20080, 17011 => 40614, 17012 => 21334, 17013 => 36808, 17014 => 33033, 510 17015 => 30610, 17016 => 39314, 17017 => 34542, 17018 => 28385, 17019 => 34067, 511 17020 => 26364, 17021 => 24930, 17022 => 28459, 17185 => 35881, 17186 => 33426, 512 17187 => 33579, 17188 => 30450, 17189 => 27667, 17190 => 24537, 17191 => 33725, 513 17192 => 29483, 17193 => 33541, 17194 => 38170, 17195 => 27611, 17196 => 30683, 514 17197 => 38086, 17198 => 21359, 17199 => 33538, 17200 => 20882, 17201 => 24125, 515 17202 => 35980, 17203 => 36152, 17204 => 20040, 17205 => 29611, 17206 => 26522, 516 17207 => 26757, 17208 => 37238, 17209 => 38665, 17210 => 29028, 17211 => 27809, 517 17212 => 30473, 17213 => 23186, 17214 => 38209, 17215 => 27599, 17216 => 32654, 518 17217 => 26151, 17218 => 23504, 17219 => 22969, 17220 => 23194, 17221 => 38376, 519 17222 => 38391, 17223 => 20204, 17224 => 33804, 17225 => 33945, 17226 => 27308, 520 17227 => 30431, 17228 => 38192, 17229 => 29467, 17230 => 26790, 17231 => 23391, 521 17232 => 30511, 17233 => 37274, 17234 => 38753, 17235 => 31964, 17236 => 36855, 522 17237 => 35868, 17238 => 24357, 17239 => 31859, 17240 => 31192, 17241 => 35269, 523 17242 => 27852, 17243 => 34588, 17244 => 23494, 17245 => 24130, 17246 => 26825, 524 17247 => 30496, 17248 => 32501, 17249 => 20885, 17250 => 20813, 17251 => 21193, 525 17252 => 23081, 17253 => 32517, 17254 => 38754, 17255 => 33495, 17256 => 25551, 526 17257 => 30596, 17258 => 34256, 17259 => 31186, 17260 => 28218, 17261 => 24217, 527 17262 => 22937, 17263 => 34065, 17264 => 28781, 17265 => 27665, 17266 => 25279, 528 17267 => 30399, 17268 => 25935, 17269 => 24751, 17270 => 38397, 17271 => 26126, 529 17272 => 34719, 17273 => 40483, 17274 => 38125, 17275 => 21517, 17276 => 21629, 530 17277 => 35884, 17278 => 25720, 17441 => 25721, 17442 => 34321, 17443 => 27169, 531 17444 => 33180, 17445 => 30952, 17446 => 25705, 17447 => 39764, 17448 => 25273, 532 17449 => 26411, 17450 => 33707, 17451 => 22696, 17452 => 40664, 17453 => 27819, 533 17454 => 28448, 17455 => 23518, 17456 => 38476, 17457 => 35851, 17458 => 29279, 534 17459 => 26576, 17460 => 25287, 17461 => 29281, 17462 => 20137, 17463 => 22982, 535 17464 => 27597, 17465 => 22675, 17466 => 26286, 17467 => 24149, 17468 => 21215, 536 17469 => 24917, 17470 => 26408, 17471 => 30446, 17472 => 30566, 17473 => 29287, 537 17474 => 31302, 17475 => 25343, 17476 => 21738, 17477 => 21584, 17478 => 38048, 538 17479 => 37027, 17480 => 23068, 17481 => 32435, 17482 => 27670, 17483 => 20035, 539 17484 => 22902, 17485 => 32784, 17486 => 22856, 17487 => 21335, 17488 => 30007, 540 17489 => 38590, 17490 => 22218, 17491 => 25376, 17492 => 33041, 17493 => 24700, 541 17494 => 38393, 17495 => 28118, 17496 => 21602, 17497 => 39297, 17498 => 20869, 542 17499 => 23273, 17500 => 33021, 17501 => 22958, 17502 => 38675, 17503 => 20522, 543 17504 => 27877, 17505 => 23612, 17506 => 25311, 17507 => 20320, 17508 => 21311, 544 17509 => 33147, 17510 => 36870, 17511 => 28346, 17512 => 34091, 17513 => 25288, 545 17514 => 24180, 17515 => 30910, 17516 => 25781, 17517 => 25467, 17518 => 24565, 546 17519 => 23064, 17520 => 37247, 17521 => 40479, 17522 => 23615, 17523 => 25423, 547 17524 => 32834, 17525 => 23421, 17526 => 21870, 17527 => 38218, 17528 => 38221, 548 17529 => 28037, 17530 => 24744, 17531 => 26592, 17532 => 29406, 17533 => 20957, 549 17534 => 23425, 17697 => 25319, 17698 => 27870, 17699 => 29275, 17700 => 25197, 550 17701 => 38062, 17702 => 32445, 17703 => 33043, 17704 => 27987, 17705 => 20892, 551 17706 => 24324, 17707 => 22900, 17708 => 21162, 17709 => 24594, 17710 => 22899, 552 17711 => 26262, 17712 => 34384, 17713 => 30111, 17714 => 25386, 17715 => 25062, 553 17716 => 31983, 17717 => 35834, 17718 => 21734, 17719 => 27431, 17720 => 40485, 554 17721 => 27572, 17722 => 34261, 17723 => 21589, 17724 => 20598, 17725 => 27812, 555 17726 => 21866, 17727 => 36276, 17728 => 29228, 17729 => 24085, 17730 => 24597, 556 17731 => 29750, 17732 => 25293, 17733 => 25490, 17734 => 29260, 17735 => 24472, 557 17736 => 28227, 17737 => 27966, 17738 => 25856, 17739 => 28504, 17740 => 30424, 558 17741 => 30928, 17742 => 30460, 17743 => 30036, 17744 => 21028, 17745 => 21467, 559 17746 => 20051, 17747 => 24222, 17748 => 26049, 17749 => 32810, 17750 => 32982, 560 17751 => 25243, 17752 => 21638, 17753 => 21032, 17754 => 28846, 17755 => 34957, 561 17756 => 36305, 17757 => 27873, 17758 => 21624, 17759 => 32986, 17760 => 22521, 562 17761 => 35060, 17762 => 36180, 17763 => 38506, 17764 => 37197, 17765 => 20329, 563 17766 => 27803, 17767 => 21943, 17768 => 30406, 17769 => 30768, 17770 => 25256, 564 17771 => 28921, 17772 => 28558, 17773 => 24429, 17774 => 34028, 17775 => 26842, 565 17776 => 30844, 17777 => 31735, 17778 => 33192, 17779 => 26379, 17780 => 40527, 566 17781 => 25447, 17782 => 30896, 17783 => 22383, 17784 => 30738, 17785 => 38713, 567 17786 => 25209, 17787 => 25259, 17788 => 21128, 17789 => 29749, 17790 => 27607, 568 17953 => 21860, 17954 => 33086, 17955 => 30130, 17956 => 30382, 17957 => 21305, 569 17958 => 30174, 17959 => 20731, 17960 => 23617, 17961 => 35692, 17962 => 31687, 570 17963 => 20559, 17964 => 29255, 17965 => 39575, 17966 => 39128, 17967 => 28418, 571 17968 => 29922, 17969 => 31080, 17970 => 25735, 17971 => 30629, 17972 => 25340, 572 17973 => 39057, 17974 => 36139, 17975 => 21697, 17976 => 32856, 17977 => 20050, 573 17978 => 22378, 17979 => 33529, 17980 => 33805, 17981 => 24179, 17982 => 20973, 574 17983 => 29942, 17984 => 35780, 17985 => 23631, 17986 => 22369, 17987 => 27900, 575 17988 => 39047, 17989 => 23110, 17990 => 30772, 17991 => 39748, 17992 => 36843, 576 17993 => 31893, 17994 => 21078, 17995 => 25169, 17996 => 38138, 17997 => 20166, 577 17998 => 33670, 17999 => 33889, 18000 => 33769, 18001 => 33970, 18002 => 22484, 578 18003 => 26420, 18004 => 22275, 18005 => 26222, 18006 => 28006, 18007 => 35889, 579 18008 => 26333, 18009 => 28689, 18010 => 26399, 18011 => 27450, 18012 => 26646, 580 18013 => 25114, 18014 => 22971, 18015 => 19971, 18016 => 20932, 18017 => 28422, 581 18018 => 26578, 18019 => 27791, 18020 => 20854, 18021 => 26827, 18022 => 22855, 582 18023 => 27495, 18024 => 30054, 18025 => 23822, 18026 => 33040, 18027 => 40784, 583 18028 => 26071, 18029 => 31048, 18030 => 31041, 18031 => 39569, 18032 => 36215, 584 18033 => 23682, 18034 => 20062, 18035 => 20225, 18036 => 21551, 18037 => 22865, 585 18038 => 30732, 18039 => 22120, 18040 => 27668, 18041 => 36804, 18042 => 24323, 586 18043 => 27773, 18044 => 27875, 18045 => 35755, 18046 => 25488, 18209 => 24688, 587 18210 => 27965, 18211 => 29301, 18212 => 25190, 18213 => 38030, 18214 => 38085, 588 18215 => 21315, 18216 => 36801, 18217 => 31614, 18218 => 20191, 18219 => 35878, 589 18220 => 20094, 18221 => 40660, 18222 => 38065, 18223 => 38067, 18224 => 21069, 590 18225 => 28508, 18226 => 36963, 18227 => 27973, 18228 => 35892, 18229 => 22545, 591 18230 => 23884, 18231 => 27424, 18232 => 27465, 18233 => 26538, 18234 => 21595, 592 18235 => 33108, 18236 => 32652, 18237 => 22681, 18238 => 34103, 18239 => 24378, 593 18240 => 25250, 18241 => 27207, 18242 => 38201, 18243 => 25970, 18244 => 24708, 594 18245 => 26725, 18246 => 30631, 18247 => 20052, 18248 => 20392, 18249 => 24039, 595 18250 => 38808, 18251 => 25772, 18252 => 32728, 18253 => 23789, 18254 => 20431, 596 18255 => 31373, 18256 => 20999, 18257 => 33540, 18258 => 19988, 18259 => 24623, 597 18260 => 31363, 18261 => 38054, 18262 => 20405, 18263 => 20146, 18264 => 31206, 598 18265 => 29748, 18266 => 21220, 18267 => 33465, 18268 => 25810, 18269 => 31165, 599 18270 => 23517, 18271 => 27777, 18272 => 38738, 18273 => 36731, 18274 => 27682, 600 18275 => 20542, 18276 => 21375, 18277 => 28165, 18278 => 25806, 18279 => 26228, 601 18280 => 27696, 18281 => 24773, 18282 => 39031, 18283 => 35831, 18284 => 24198, 602 18285 => 29756, 18286 => 31351, 18287 => 31179, 18288 => 19992, 18289 => 37041, 603 18290 => 29699, 18291 => 27714, 18292 => 22234, 18293 => 37195, 18294 => 27845, 604 18295 => 36235, 18296 => 21306, 18297 => 34502, 18298 => 26354, 18299 => 36527, 605 18300 => 23624, 18301 => 39537, 18302 => 28192, 18465 => 21462, 18466 => 23094, 606 18467 => 40843, 18468 => 36259, 18469 => 21435, 18470 => 22280, 18471 => 39079, 607 18472 => 26435, 18473 => 37275, 18474 => 27849, 18475 => 20840, 18476 => 30154, 608 18477 => 25331, 18478 => 29356, 18479 => 21048, 18480 => 21149, 18481 => 32570, 609 18482 => 28820, 18483 => 30264, 18484 => 21364, 18485 => 40522, 18486 => 27063, 610 18487 => 30830, 18488 => 38592, 18489 => 35033, 18490 => 32676, 18491 => 28982, 611 18492 => 29123, 18493 => 20873, 18494 => 26579, 18495 => 29924, 18496 => 22756, 612 18497 => 25880, 18498 => 22199, 18499 => 35753, 18500 => 39286, 18501 => 25200, 613 18502 => 32469, 18503 => 24825, 18504 => 28909, 18505 => 22764, 18506 => 20161, 614 18507 => 20154, 18508 => 24525, 18509 => 38887, 18510 => 20219, 18511 => 35748, 615 18512 => 20995, 18513 => 22922, 18514 => 32427, 18515 => 25172, 18516 => 20173, 616 18517 => 26085, 18518 => 25102, 18519 => 33592, 18520 => 33993, 18521 => 33635, 617 18522 => 34701, 18523 => 29076, 18524 => 28342, 18525 => 23481, 18526 => 32466, 618 18527 => 20887, 18528 => 25545, 18529 => 26580, 18530 => 32905, 18531 => 33593, 619 18532 => 34837, 18533 => 20754, 18534 => 23418, 18535 => 22914, 18536 => 36785, 620 18537 => 20083, 18538 => 27741, 18539 => 20837, 18540 => 35109, 18541 => 36719, 621 18542 => 38446, 18543 => 34122, 18544 => 29790, 18545 => 38160, 18546 => 38384, 622 18547 => 28070, 18548 => 33509, 18549 => 24369, 18550 => 25746, 18551 => 27922, 623 18552 => 33832, 18553 => 33134, 18554 => 40131, 18555 => 22622, 18556 => 36187, 624 18557 => 19977, 18558 => 21441, 18721 => 20254, 18722 => 25955, 18723 => 26705, 625 18724 => 21971, 18725 => 20007, 18726 => 25620, 18727 => 39578, 18728 => 25195, 626 18729 => 23234, 18730 => 29791, 18731 => 33394, 18732 => 28073, 18733 => 26862, 627 18734 => 20711, 18735 => 33678, 18736 => 30722, 18737 => 26432, 18738 => 21049, 628 18739 => 27801, 18740 => 32433, 18741 => 20667, 18742 => 21861, 18743 => 29022, 629 18744 => 31579, 18745 => 26194, 18746 => 29642, 18747 => 33515, 18748 => 26441, 630 18749 => 23665, 18750 => 21024, 18751 => 29053, 18752 => 34923, 18753 => 38378, 631 18754 => 38485, 18755 => 25797, 18756 => 36193, 18757 => 33203, 18758 => 21892, 632 18759 => 27733, 18760 => 25159, 18761 => 32558, 18762 => 22674, 18763 => 20260, 633 18764 => 21830, 18765 => 36175, 18766 => 26188, 18767 => 19978, 18768 => 23578, 634 18769 => 35059, 18770 => 26786, 18771 => 25422, 18772 => 31245, 18773 => 28903, 635 18774 => 33421, 18775 => 21242, 18776 => 38902, 18777 => 23569, 18778 => 21736, 636 18779 => 37045, 18780 => 32461, 18781 => 22882, 18782 => 36170, 18783 => 34503, 637 18784 => 33292, 18785 => 33293, 18786 => 36198, 18787 => 25668, 18788 => 23556, 638 18789 => 24913, 18790 => 28041, 18791 => 31038, 18792 => 35774, 18793 => 30775, 639 18794 => 30003, 18795 => 21627, 18796 => 20280, 18797 => 36523, 18798 => 28145, 640 18799 => 23072, 18800 => 32453, 18801 => 31070, 18802 => 27784, 18803 => 23457, 641 18804 => 23158, 18805 => 29978, 18806 => 32958, 18807 => 24910, 18808 => 28183, 642 18809 => 22768, 18810 => 29983, 18811 => 29989, 18812 => 29298, 18813 => 21319, 643 18814 => 32499, 18977 => 30465, 18978 => 30427, 18979 => 21097, 18980 => 32988, 644 18981 => 22307, 18982 => 24072, 18983 => 22833, 18984 => 29422, 18985 => 26045, 645 18986 => 28287, 18987 => 35799, 18988 => 23608, 18989 => 34417, 18990 => 21313, 646 18991 => 30707, 18992 => 25342, 18993 => 26102, 18994 => 20160, 18995 => 39135, 647 18996 => 34432, 18997 => 23454, 18998 => 35782, 18999 => 21490, 19000 => 30690, 648 19001 => 20351, 19002 => 23630, 19003 => 39542, 19004 => 22987, 19005 => 24335, 649 19006 => 31034, 19007 => 22763, 19008 => 19990, 19009 => 26623, 19010 => 20107, 650 19011 => 25325, 19012 => 35475, 19013 => 36893, 19014 => 21183, 19015 => 26159, 651 19016 => 21980, 19017 => 22124, 19018 => 36866, 19019 => 20181, 19020 => 20365, 652 19021 => 37322, 19022 => 39280, 19023 => 27663, 19024 => 24066, 19025 => 24643, 653 19026 => 23460, 19027 => 35270, 19028 => 35797, 19029 => 25910, 19030 => 25163, 654 19031 => 39318, 19032 => 23432, 19033 => 23551, 19034 => 25480, 19035 => 21806, 655 19036 => 21463, 19037 => 30246, 19038 => 20861, 19039 => 34092, 19040 => 26530, 656 19041 => 26803, 19042 => 27530, 19043 => 25234, 19044 => 36755, 19045 => 21460, 657 19046 => 33298, 19047 => 28113, 19048 => 30095, 19049 => 20070, 19050 => 36174, 658 19051 => 23408, 19052 => 29087, 19053 => 34223, 19054 => 26257, 19055 => 26329, 659 19056 => 32626, 19057 => 34560, 19058 => 40653, 19059 => 40736, 19060 => 23646, 660 19061 => 26415, 19062 => 36848, 19063 => 26641, 19064 => 26463, 19065 => 25101, 661 19066 => 31446, 19067 => 22661, 19068 => 24246, 19069 => 25968, 19070 => 28465, 662 19233 => 24661, 19234 => 21047, 19235 => 32781, 19236 => 25684, 19237 => 34928, 663 19238 => 29993, 19239 => 24069, 19240 => 26643, 19241 => 25332, 19242 => 38684, 664 19243 => 21452, 19244 => 29245, 19245 => 35841, 19246 => 27700, 19247 => 30561, 665 19248 => 31246, 19249 => 21550, 19250 => 30636, 19251 => 39034, 19252 => 33308, 666 19253 => 35828, 19254 => 30805, 19255 => 26388, 19256 => 28865, 19257 => 26031, 667 19258 => 25749, 19259 => 22070, 19260 => 24605, 19261 => 31169, 19262 => 21496, 668 19263 => 19997, 19264 => 27515, 19265 => 32902, 19266 => 23546, 19267 => 21987, 669 19268 => 22235, 19269 => 20282, 19270 => 20284, 19271 => 39282, 19272 => 24051, 670 19273 => 26494, 19274 => 32824, 19275 => 24578, 19276 => 39042, 19277 => 36865, 671 19278 => 23435, 19279 => 35772, 19280 => 35829, 19281 => 25628, 19282 => 33368, 672 19283 => 25822, 19284 => 22013, 19285 => 33487, 19286 => 37221, 19287 => 20439, 673 19288 => 32032, 19289 => 36895, 19290 => 31903, 19291 => 20723, 19292 => 22609, 674 19293 => 28335, 19294 => 23487, 19295 => 35785, 19296 => 32899, 19297 => 37240, 675 19298 => 33948, 19299 => 31639, 19300 => 34429, 19301 => 38539, 19302 => 38543, 676 19303 => 32485, 19304 => 39635, 19305 => 30862, 19306 => 23681, 19307 => 31319, 677 19308 => 36930, 19309 => 38567, 19310 => 31071, 19311 => 23385, 19312 => 25439, 678 19313 => 31499, 19314 => 34001, 19315 => 26797, 19316 => 21766, 19317 => 32553, 679 19318 => 29712, 19319 => 32034, 19320 => 38145, 19321 => 25152, 19322 => 22604, 680 19323 => 20182, 19324 => 23427, 19325 => 22905, 19326 => 22612, 19489 => 29549, 681 19490 => 25374, 19491 => 36427, 19492 => 36367, 19493 => 32974, 19494 => 33492, 682 19495 => 25260, 19496 => 21488, 19497 => 27888, 19498 => 37214, 19499 => 22826, 683 19500 => 24577, 19501 => 27760, 19502 => 22349, 19503 => 25674, 19504 => 36138, 684 19505 => 30251, 19506 => 28393, 19507 => 22363, 19508 => 27264, 19509 => 30192, 685 19510 => 28525, 19511 => 35885, 19512 => 35848, 19513 => 22374, 19514 => 27631, 686 19515 => 34962, 19516 => 30899, 19517 => 25506, 19518 => 21497, 19519 => 28845, 687 19520 => 27748, 19521 => 22616, 19522 => 25642, 19523 => 22530, 19524 => 26848, 688 19525 => 33179, 19526 => 21776, 19527 => 31958, 19528 => 20504, 19529 => 36538, 689 19530 => 28108, 19531 => 36255, 19532 => 28907, 19533 => 25487, 19534 => 28059, 690 19535 => 28372, 19536 => 32486, 19537 => 33796, 19538 => 26691, 19539 => 36867, 691 19540 => 28120, 19541 => 38518, 19542 => 35752, 19543 => 22871, 19544 => 29305, 692 19545 => 34276, 19546 => 33150, 19547 => 30140, 19548 => 35466, 19549 => 26799, 693 19550 => 21076, 19551 => 36386, 19552 => 38161, 19553 => 25552, 19554 => 39064, 694 19555 => 36420, 19556 => 21884, 19557 => 20307, 19558 => 26367, 19559 => 22159, 695 19560 => 24789, 19561 => 28053, 19562 => 21059, 19563 => 23625, 19564 => 22825, 696 19565 => 28155, 19566 => 22635, 19567 => 30000, 19568 => 29980, 19569 => 24684, 697 19570 => 33300, 19571 => 33094, 19572 => 25361, 19573 => 26465, 19574 => 36834, 698 19575 => 30522, 19576 => 36339, 19577 => 36148, 19578 => 38081, 19579 => 24086, 699 19580 => 21381, 19581 => 21548, 19582 => 28867, 19745 => 27712, 19746 => 24311, 700 19747 => 20572, 19748 => 20141, 19749 => 24237, 19750 => 25402, 19751 => 33351, 701 19752 => 36890, 19753 => 26704, 19754 => 37230, 19755 => 30643, 19756 => 21516, 702 19757 => 38108, 19758 => 24420, 19759 => 31461, 19760 => 26742, 19761 => 25413, 703 19762 => 31570, 19763 => 32479, 19764 => 30171, 19765 => 20599, 19766 => 25237, 704 19767 => 22836, 19768 => 36879, 19769 => 20984, 19770 => 31171, 19771 => 31361, 705 19772 => 22270, 19773 => 24466, 19774 => 36884, 19775 => 28034, 19776 => 23648, 706 19777 => 22303, 19778 => 21520, 19779 => 20820, 19780 => 28237, 19781 => 22242, 707 19782 => 25512, 19783 => 39059, 19784 => 33151, 19785 => 34581, 19786 => 35114, 708 19787 => 36864, 19788 => 21534, 19789 => 23663, 19790 => 33216, 19791 => 25302, 709 19792 => 25176, 19793 => 33073, 19794 => 40501, 19795 => 38464, 19796 => 39534, 710 19797 => 39548, 19798 => 26925, 19799 => 22949, 19800 => 25299, 19801 => 21822, 711 19802 => 25366, 19803 => 21703, 19804 => 34521, 19805 => 27964, 19806 => 23043, 712 19807 => 29926, 19808 => 34972, 19809 => 27498, 19810 => 22806, 19811 => 35916, 713 19812 => 24367, 19813 => 28286, 19814 => 29609, 19815 => 39037, 19816 => 20024, 714 19817 => 28919, 19818 => 23436, 19819 => 30871, 19820 => 25405, 19821 => 26202, 715 19822 => 30358, 19823 => 24779, 19824 => 23451, 19825 => 23113, 19826 => 19975, 716 19827 => 33109, 19828 => 27754, 19829 => 29579, 19830 => 20129, 19831 => 26505, 717 19832 => 32593, 19833 => 24448, 19834 => 26106, 19835 => 26395, 19836 => 24536, 718 19837 => 22916, 19838 => 23041, 20001 => 24013, 20002 => 24494, 20003 => 21361, 719 20004 => 38886, 20005 => 36829, 20006 => 26693, 20007 => 22260, 20008 => 21807, 720 20009 => 24799, 20010 => 20026, 20011 => 28493, 20012 => 32500, 20013 => 33479, 721 20014 => 33806, 20015 => 22996, 20016 => 20255, 20017 => 20266, 20018 => 23614, 722 20019 => 32428, 20020 => 26410, 20021 => 34074, 20022 => 21619, 20023 => 30031, 723 20024 => 32963, 20025 => 21890, 20026 => 39759, 20027 => 20301, 20028 => 28205, 724 20029 => 35859, 20030 => 23561, 20031 => 24944, 20032 => 21355, 20033 => 30239, 725 20034 => 28201, 20035 => 34442, 20036 => 25991, 20037 => 38395, 20038 => 32441, 726 20039 => 21563, 20040 => 31283, 20041 => 32010, 20042 => 38382, 20043 => 21985, 727 20044 => 32705, 20045 => 29934, 20046 => 25373, 20047 => 34583, 20048 => 28065, 728 20049 => 31389, 20050 => 25105, 20051 => 26017, 20052 => 21351, 20053 => 25569, 729 20054 => 27779, 20055 => 24043, 20056 => 21596, 20057 => 38056, 20058 => 20044, 730 20059 => 27745, 20060 => 35820, 20061 => 23627, 20062 => 26080, 20063 => 33436, 731 20064 => 26791, 20065 => 21566, 20066 => 21556, 20067 => 27595, 20068 => 27494, 732 20069 => 20116, 20070 => 25410, 20071 => 21320, 20072 => 33310, 20073 => 20237, 733 20074 => 20398, 20075 => 22366, 20076 => 25098, 20077 => 38654, 20078 => 26212, 734 20079 => 29289, 20080 => 21247, 20081 => 21153, 20082 => 24735, 20083 => 35823, 735 20084 => 26132, 20085 => 29081, 20086 => 26512, 20087 => 35199, 20088 => 30802, 736 20089 => 30717, 20090 => 26224, 20091 => 22075, 20092 => 21560, 20093 => 38177, 737 20094 => 29306, 20257 => 31232, 20258 => 24687, 20259 => 24076, 20260 => 24713, 738 20261 => 33181, 20262 => 22805, 20263 => 24796, 20264 => 29060, 20265 => 28911, 739 20266 => 28330, 20267 => 27728, 20268 => 29312, 20269 => 27268, 20270 => 34989, 740 20271 => 24109, 20272 => 20064, 20273 => 23219, 20274 => 21916, 20275 => 38115, 741 20276 => 27927, 20277 => 31995, 20278 => 38553, 20279 => 25103, 20280 => 32454, 742 20281 => 30606, 20282 => 34430, 20283 => 21283, 20284 => 38686, 20285 => 36758, 743 20286 => 26247, 20287 => 23777, 20288 => 20384, 20289 => 29421, 20290 => 19979, 744 20291 => 21414, 20292 => 22799, 20293 => 21523, 20294 => 25472, 20295 => 38184, 745 20296 => 20808, 20297 => 20185, 20298 => 40092, 20299 => 32420, 20300 => 21688, 746 20301 => 36132, 20302 => 34900, 20303 => 33335, 20304 => 38386, 20305 => 28046, 747 20306 => 24358, 20307 => 23244, 20308 => 26174, 20309 => 38505, 20310 => 29616, 748 20311 => 29486, 20312 => 21439, 20313 => 33146, 20314 => 39301, 20315 => 32673, 749 20316 => 23466, 20317 => 38519, 20318 => 38480, 20319 => 32447, 20320 => 30456, 750 20321 => 21410, 20322 => 38262, 20323 => 39321, 20324 => 31665, 20325 => 35140, 751 20326 => 28248, 20327 => 20065, 20328 => 32724, 20329 => 31077, 20330 => 35814, 752 20331 => 24819, 20332 => 21709, 20333 => 20139, 20334 => 39033, 20335 => 24055, 753 20336 => 27233, 20337 => 20687, 20338 => 21521, 20339 => 35937, 20340 => 33831, 754 20341 => 30813, 20342 => 38660, 20343 => 21066, 20344 => 21742, 20345 => 22179, 755 20346 => 38144, 20347 => 28040, 20348 => 23477, 20349 => 28102, 20350 => 26195, 756 20513 => 23567, 20514 => 23389, 20515 => 26657, 20516 => 32918, 20517 => 21880, 757 20518 => 31505, 20519 => 25928, 20520 => 26964, 20521 => 20123, 20522 => 27463, 758 20523 => 34638, 20524 => 38795, 20525 => 21327, 20526 => 25375, 20527 => 25658, 759 20528 => 37034, 20529 => 26012, 20530 => 32961, 20531 => 35856, 20532 => 20889, 760 20533 => 26800, 20534 => 21368, 20535 => 34809, 20536 => 25032, 20537 => 27844, 761 20538 => 27899, 20539 => 35874, 20540 => 23633, 20541 => 34218, 20542 => 33455, 762 20543 => 38156, 20544 => 27427, 20545 => 36763, 20546 => 26032, 20547 => 24571, 763 20548 => 24515, 20549 => 20449, 20550 => 34885, 20551 => 26143, 20552 => 33125, 764 20553 => 29481, 20554 => 24826, 20555 => 20852, 20556 => 21009, 20557 => 22411, 765 20558 => 24418, 20559 => 37026, 20560 => 34892, 20561 => 37266, 20562 => 24184, 766 20563 => 26447, 20564 => 24615, 20565 => 22995, 20566 => 20804, 20567 => 20982, 767 20568 => 33016, 20569 => 21256, 20570 => 27769, 20571 => 38596, 20572 => 29066, 768 20573 => 20241, 20574 => 20462, 20575 => 32670, 20576 => 26429, 20577 => 21957, 769 20578 => 38152, 20579 => 31168, 20580 => 34966, 20581 => 32483, 20582 => 22687, 770 20583 => 25100, 20584 => 38656, 20585 => 34394, 20586 => 22040, 20587 => 39035, 771 20588 => 24464, 20589 => 35768, 20590 => 33988, 20591 => 37207, 20592 => 21465, 772 20593 => 26093, 20594 => 24207, 20595 => 30044, 20596 => 24676, 20597 => 32110, 773 20598 => 23167, 20599 => 32490, 20600 => 32493, 20601 => 36713, 20602 => 21927, 774 20603 => 23459, 20604 => 24748, 20605 => 26059, 20606 => 29572, 20769 => 36873, 775 20770 => 30307, 20771 => 30505, 20772 => 32474, 20773 => 38772, 20774 => 34203, 776 20775 => 23398, 20776 => 31348, 20777 => 38634, 20778 => 34880, 20779 => 21195, 777 20780 => 29071, 20781 => 24490, 20782 => 26092, 20783 => 35810, 20784 => 23547, 778 20785 => 39535, 20786 => 24033, 20787 => 27529, 20788 => 27739, 20789 => 35757, 779 20790 => 35759, 20791 => 36874, 20792 => 36805, 20793 => 21387, 20794 => 25276, 780 20795 => 40486, 20796 => 40493, 20797 => 21568, 20798 => 20011, 20799 => 33469, 781 20800 => 29273, 20801 => 34460, 20802 => 23830, 20803 => 34905, 20804 => 28079, 782 20805 => 38597, 20806 => 21713, 20807 => 20122, 20808 => 35766, 20809 => 28937, 783 20810 => 21693, 20811 => 38409, 20812 => 28895, 20813 => 28153, 20814 => 30416, 784 20815 => 20005, 20816 => 30740, 20817 => 34578, 20818 => 23721, 20819 => 24310, 785 20820 => 35328, 20821 => 39068, 20822 => 38414, 20823 => 28814, 20824 => 27839, 786 20825 => 22852, 20826 => 25513, 20827 => 30524, 20828 => 34893, 20829 => 28436, 787 20830 => 33395, 20831 => 22576, 20832 => 29141, 20833 => 21388, 20834 => 30746, 788 20835 => 38593, 20836 => 21761, 20837 => 24422, 20838 => 28976, 20839 => 23476, 789 20840 => 35866, 20841 => 39564, 20842 => 27523, 20843 => 22830, 20844 => 40495, 790 20845 => 31207, 20846 => 26472, 20847 => 25196, 20848 => 20335, 20849 => 30113, 791 20850 => 32650, 20851 => 27915, 20852 => 38451, 20853 => 27687, 20854 => 20208, 792 20855 => 30162, 20856 => 20859, 20857 => 26679, 20858 => 28478, 20859 => 36992, 793 20860 => 33136, 20861 => 22934, 20862 => 29814, 21025 => 25671, 21026 => 23591, 794 21027 => 36965, 21028 => 31377, 21029 => 35875, 21030 => 23002, 21031 => 21676, 795 21032 => 33280, 21033 => 33647, 21034 => 35201, 21035 => 32768, 21036 => 26928, 796 21037 => 22094, 21038 => 32822, 21039 => 29239, 21040 => 37326, 21041 => 20918, 797 21042 => 20063, 21043 => 39029, 21044 => 25494, 21045 => 19994, 21046 => 21494, 798 21047 => 26355, 21048 => 33099, 21049 => 22812, 21050 => 28082, 21051 => 19968, 799 21052 => 22777, 21053 => 21307, 21054 => 25558, 21055 => 38129, 21056 => 20381, 800 21057 => 20234, 21058 => 34915, 21059 => 39056, 21060 => 22839, 21061 => 36951, 801 21062 => 31227, 21063 => 20202, 21064 => 33008, 21065 => 30097, 21066 => 27778, 802 21067 => 23452, 21068 => 23016, 21069 => 24413, 21070 => 26885, 21071 => 34433, 803 21072 => 20506, 21073 => 24050, 21074 => 20057, 21075 => 30691, 21076 => 20197, 804 21077 => 33402, 21078 => 25233, 21079 => 26131, 21080 => 37009, 21081 => 23673, 805 21082 => 20159, 21083 => 24441, 21084 => 33222, 21085 => 36920, 21086 => 32900, 806 21087 => 30123, 21088 => 20134, 21089 => 35028, 21090 => 24847, 21091 => 27589, 807 21092 => 24518, 21093 => 20041, 21094 => 30410, 21095 => 28322, 21096 => 35811, 808 21097 => 35758, 21098 => 35850, 21099 => 35793, 21100 => 24322, 21101 => 32764, 809 21102 => 32716, 21103 => 32462, 21104 => 33589, 21105 => 33643, 21106 => 22240, 810 21107 => 27575, 21108 => 38899, 21109 => 38452, 21110 => 23035, 21111 => 21535, 811 21112 => 38134, 21113 => 28139, 21114 => 23493, 21115 => 39278, 21116 => 23609, 812 21117 => 24341, 21118 => 38544, 21281 => 21360, 21282 => 33521, 21283 => 27185, 813 21284 => 23156, 21285 => 40560, 21286 => 24212, 21287 => 32552, 21288 => 33721, 814 21289 => 33828, 21290 => 33829, 21291 => 33639, 21292 => 34631, 21293 => 36814, 815 21294 => 36194, 21295 => 30408, 21296 => 24433, 21297 => 39062, 21298 => 30828, 816 21299 => 26144, 21300 => 21727, 21301 => 25317, 21302 => 20323, 21303 => 33219, 817 21304 => 30152, 21305 => 24248, 21306 => 38605, 21307 => 36362, 21308 => 34553, 818 21309 => 21647, 21310 => 27891, 21311 => 28044, 21312 => 27704, 21313 => 24703, 819 21314 => 21191, 21315 => 29992, 21316 => 24189, 21317 => 20248, 21318 => 24736, 820 21319 => 24551, 21320 => 23588, 21321 => 30001, 21322 => 37038, 21323 => 38080, 821 21324 => 29369, 21325 => 27833, 21326 => 28216, 21327 => 37193, 21328 => 26377, 822 21329 => 21451, 21330 => 21491, 21331 => 20305, 21332 => 37321, 21333 => 35825, 823 21334 => 21448, 21335 => 24188, 21336 => 36802, 21337 => 28132, 21338 => 20110, 824 21339 => 30402, 21340 => 27014, 21341 => 34398, 21342 => 24858, 21343 => 33286, 825 21344 => 20313, 21345 => 20446, 21346 => 36926, 21347 => 40060, 21348 => 24841, 826 21349 => 28189, 21350 => 28180, 21351 => 38533, 21352 => 20104, 21353 => 23089, 827 21354 => 38632, 21355 => 19982, 21356 => 23679, 21357 => 31161, 21358 => 23431, 828 21359 => 35821, 21360 => 32701, 21361 => 29577, 21362 => 22495, 21363 => 33419, 829 21364 => 37057, 21365 => 21505, 21366 => 36935, 21367 => 21947, 21368 => 23786, 830 21369 => 24481, 21370 => 24840, 21371 => 27442, 21372 => 29425, 21373 => 32946, 831 21374 => 35465, 21537 => 28020, 21538 => 23507, 21539 => 35029, 21540 => 39044, 832 21541 => 35947, 21542 => 39533, 21543 => 40499, 21544 => 28170, 21545 => 20900, 833 21546 => 20803, 21547 => 22435, 21548 => 34945, 21549 => 21407, 21550 => 25588, 834 21551 => 36757, 21552 => 22253, 21553 => 21592, 21554 => 22278, 21555 => 29503, 835 21556 => 28304, 21557 => 32536, 21558 => 36828, 21559 => 33489, 21560 => 24895, 836 21561 => 24616, 21562 => 38498, 21563 => 26352, 21564 => 32422, 21565 => 36234, 837 21566 => 36291, 21567 => 38053, 21568 => 23731, 21569 => 31908, 21570 => 26376, 838 21571 => 24742, 21572 => 38405, 21573 => 32792, 21574 => 20113, 21575 => 37095, 839 21576 => 21248, 21577 => 38504, 21578 => 20801, 21579 => 36816, 21580 => 34164, 840 21581 => 37213, 21582 => 26197, 21583 => 38901, 21584 => 23381, 21585 => 21277, 841 21586 => 30776, 21587 => 26434, 21588 => 26685, 21589 => 21705, 21590 => 28798, 842 21591 => 23472, 21592 => 36733, 21593 => 20877, 21594 => 22312, 21595 => 21681, 843 21596 => 25874, 21597 => 26242, 21598 => 36190, 21599 => 36163, 21600 => 33039, 844 21601 => 33900, 21602 => 36973, 21603 => 31967, 21604 => 20991, 21605 => 34299, 845 21606 => 26531, 21607 => 26089, 21608 => 28577, 21609 => 34468, 21610 => 36481, 846 21611 => 22122, 21612 => 36896, 21613 => 30338, 21614 => 28790, 21615 => 29157, 847 21616 => 36131, 21617 => 25321, 21618 => 21017, 21619 => 27901, 21620 => 36156, 848 21621 => 24590, 21622 => 22686, 21623 => 24974, 21624 => 26366, 21625 => 36192, 849 21626 => 25166, 21627 => 21939, 21628 => 28195, 21629 => 26413, 21630 => 36711, 850 21793 => 38113, 21794 => 38392, 21795 => 30504, 21796 => 26629, 21797 => 27048, 851 21798 => 21643, 21799 => 20045, 21800 => 28856, 21801 => 35784, 21802 => 25688, 852 21803 => 25995, 21804 => 23429, 21805 => 31364, 21806 => 20538, 21807 => 23528, 853 21808 => 30651, 21809 => 27617, 21810 => 35449, 21811 => 31896, 21812 => 27838, 854 21813 => 30415, 21814 => 26025, 21815 => 36759, 21816 => 23853, 21817 => 23637, 855 21818 => 34360, 21819 => 26632, 21820 => 21344, 21821 => 25112, 21822 => 31449, 856 21823 => 28251, 21824 => 32509, 21825 => 27167, 21826 => 31456, 21827 => 24432, 857 21828 => 28467, 21829 => 24352, 21830 => 25484, 21831 => 28072, 21832 => 26454, 858 21833 => 19976, 21834 => 24080, 21835 => 36134, 21836 => 20183, 21837 => 32960, 859 21838 => 30260, 21839 => 38556, 21840 => 25307, 21841 => 26157, 21842 => 25214, 860 21843 => 27836, 21844 => 36213, 21845 => 29031, 21846 => 32617, 21847 => 20806, 861 21848 => 32903, 21849 => 21484, 21850 => 36974, 21851 => 25240, 21852 => 21746, 862 21853 => 34544, 21854 => 36761, 21855 => 32773, 21856 => 38167, 21857 => 34071, 863 21858 => 36825, 21859 => 27993, 21860 => 29645, 21861 => 26015, 21862 => 30495, 864 21863 => 29956, 21864 => 30759, 21865 => 33275, 21866 => 36126, 21867 => 38024, 865 21868 => 20390, 21869 => 26517, 21870 => 30137, 21871 => 35786, 21872 => 38663, 866 21873 => 25391, 21874 => 38215, 21875 => 38453, 21876 => 33976, 21877 => 25379, 867 21878 => 30529, 21879 => 24449, 21880 => 29424, 21881 => 20105, 21882 => 24596, 868 21883 => 25972, 21884 => 25327, 21885 => 27491, 21886 => 25919, 22049 => 24103, 869 22050 => 30151, 22051 => 37073, 22052 => 35777, 22053 => 33437, 22054 => 26525, 870 22055 => 25903, 22056 => 21553, 22057 => 34584, 22058 => 30693, 22059 => 32930, 871 22060 => 33026, 22061 => 27713, 22062 => 20043, 22063 => 32455, 22064 => 32844, 872 22065 => 30452, 22066 => 26893, 22067 => 27542, 22068 => 25191, 22069 => 20540, 873 22070 => 20356, 22071 => 22336, 22072 => 25351, 22073 => 27490, 22074 => 36286, 874 22075 => 21482, 22076 => 26088, 22077 => 32440, 22078 => 24535, 22079 => 25370, 875 22080 => 25527, 22081 => 33267, 22082 => 33268, 22083 => 32622, 22084 => 24092, 876 22085 => 23769, 22086 => 21046, 22087 => 26234, 22088 => 31209, 22089 => 31258, 877 22090 => 36136, 22091 => 28825, 22092 => 30164, 22093 => 28382, 22094 => 27835, 878 22095 => 31378, 22096 => 20013, 22097 => 30405, 22098 => 24544, 22099 => 38047, 879 22100 => 34935, 22101 => 32456, 22102 => 31181, 22103 => 32959, 22104 => 37325, 880 22105 => 20210, 22106 => 20247, 22107 => 33311, 22108 => 21608, 22109 => 24030, 881 22110 => 27954, 22111 => 35788, 22112 => 31909, 22113 => 36724, 22114 => 32920, 882 22115 => 24090, 22116 => 21650, 22117 => 30385, 22118 => 23449, 22119 => 26172, 883 22120 => 39588, 22121 => 29664, 22122 => 26666, 22123 => 34523, 22124 => 26417, 884 22125 => 29482, 22126 => 35832, 22127 => 35803, 22128 => 36880, 22129 => 31481, 885 22130 => 28891, 22131 => 29038, 22132 => 25284, 22133 => 30633, 22134 => 22065, 886 22135 => 20027, 22136 => 33879, 22137 => 26609, 22138 => 21161, 22139 => 34496, 887 22140 => 36142, 22141 => 38136, 22142 => 31569, 22305 => 20303, 22306 => 27880, 888 22307 => 31069, 22308 => 39547, 22309 => 25235, 22310 => 29226, 22311 => 25341, 889 22312 => 19987, 22313 => 30742, 22314 => 36716, 22315 => 25776, 22316 => 36186, 890 22317 => 31686, 22318 => 26729, 22319 => 24196, 22320 => 35013, 22321 => 22918, 891 22322 => 25758, 22323 => 22766, 22324 => 29366, 22325 => 26894, 22326 => 38181, 892 22327 => 36861, 22328 => 36184, 22329 => 22368, 22330 => 32512, 22331 => 35846, 893 22332 => 20934, 22333 => 25417, 22334 => 25305, 22335 => 21331, 22336 => 26700, 894 22337 => 29730, 22338 => 33537, 22339 => 37196, 22340 => 21828, 22341 => 30528, 895 22342 => 28796, 22343 => 27978, 22344 => 20857, 22345 => 21672, 22346 => 36164, 896 22347 => 23039, 22348 => 28363, 22349 => 28100, 22350 => 23388, 22351 => 32043, 897 22352 => 20180, 22353 => 31869, 22354 => 28371, 22355 => 23376, 22356 => 33258, 898 22357 => 28173, 22358 => 23383, 22359 => 39683, 22360 => 26837, 22361 => 36394, 899 22362 => 23447, 22363 => 32508, 22364 => 24635, 22365 => 32437, 22366 => 37049, 900 22367 => 36208, 22368 => 22863, 22369 => 25549, 22370 => 31199, 22371 => 36275, 901 22372 => 21330, 22373 => 26063, 22374 => 31062, 22375 => 35781, 22376 => 38459, 902 22377 => 32452, 22378 => 38075, 22379 => 32386, 22380 => 22068, 22381 => 37257, 903 22382 => 26368, 22383 => 32618, 22384 => 23562, 22385 => 36981, 22386 => 26152, 904 22387 => 24038, 22388 => 20304, 22389 => 26590, 22390 => 20570, 22391 => 20316, 905 22392 => 22352, 22393 => 24231, 22561 => 20109, 22562 => 19980, 22563 => 20800, 906 22564 => 19984, 22565 => 24319, 22566 => 21317, 22567 => 19989, 22568 => 20120, 907 22569 => 19998, 22570 => 39730, 22571 => 23404, 22572 => 22121, 22573 => 20008, 908 22574 => 31162, 22575 => 20031, 22576 => 21269, 22577 => 20039, 22578 => 22829, 909 22579 => 29243, 22580 => 21358, 22581 => 27664, 22582 => 22239, 22583 => 32996, 910 22584 => 39319, 22585 => 27603, 22586 => 30590, 22587 => 40727, 22588 => 20022, 911 22589 => 20127, 22590 => 40720, 22591 => 20060, 22592 => 20073, 22593 => 20115, 912 22594 => 33416, 22595 => 23387, 22596 => 21868, 22597 => 22031, 22598 => 20164, 913 22599 => 21389, 22600 => 21405, 22601 => 21411, 22602 => 21413, 22603 => 21422, 914 22604 => 38757, 22605 => 36189, 22606 => 21274, 22607 => 21493, 22608 => 21286, 915 22609 => 21294, 22610 => 21310, 22611 => 36188, 22612 => 21350, 22613 => 21347, 916 22614 => 20994, 22615 => 21000, 22616 => 21006, 22617 => 21037, 22618 => 21043, 917 22619 => 21055, 22620 => 21056, 22621 => 21068, 22622 => 21086, 22623 => 21089, 918 22624 => 21084, 22625 => 33967, 22626 => 21117, 22627 => 21122, 22628 => 21121, 919 22629 => 21136, 22630 => 21139, 22631 => 20866, 22632 => 32596, 22633 => 20155, 920 22634 => 20163, 22635 => 20169, 22636 => 20162, 22637 => 20200, 22638 => 20193, 921 22639 => 20203, 22640 => 20190, 22641 => 20251, 22642 => 20211, 22643 => 20258, 922 22644 => 20324, 22645 => 20213, 22646 => 20261, 22647 => 20263, 22648 => 20233, 923 22649 => 20267, 22650 => 20318, 22651 => 20327, 22652 => 25912, 22653 => 20314, 924 22654 => 20317, 22817 => 20319, 22818 => 20311, 22819 => 20274, 22820 => 20285, 925 22821 => 20342, 22822 => 20340, 22823 => 20369, 22824 => 20361, 22825 => 20355, 926 22826 => 20367, 22827 => 20350, 22828 => 20347, 22829 => 20394, 22830 => 20348, 927 22831 => 20396, 22832 => 20372, 22833 => 20454, 22834 => 20456, 22835 => 20458, 928 22836 => 20421, 22837 => 20442, 22838 => 20451, 22839 => 20444, 22840 => 20433, 929 22841 => 20447, 22842 => 20472, 22843 => 20521, 22844 => 20556, 22845 => 20467, 930 22846 => 20524, 22847 => 20495, 22848 => 20526, 22849 => 20525, 22850 => 20478, 931 22851 => 20508, 22852 => 20492, 22853 => 20517, 22854 => 20520, 22855 => 20606, 932 22856 => 20547, 22857 => 20565, 22858 => 20552, 22859 => 20558, 22860 => 20588, 933 22861 => 20603, 22862 => 20645, 22863 => 20647, 22864 => 20649, 22865 => 20666, 934 22866 => 20694, 22867 => 20742, 22868 => 20717, 22869 => 20716, 22870 => 20710, 935 22871 => 20718, 22872 => 20743, 22873 => 20747, 22874 => 20189, 22875 => 27709, 936 22876 => 20312, 22877 => 20325, 22878 => 20430, 22879 => 40864, 22880 => 27718, 937 22881 => 31860, 22882 => 20846, 22883 => 24061, 22884 => 40649, 22885 => 39320, 938 22886 => 20865, 22887 => 22804, 22888 => 21241, 22889 => 21261, 22890 => 35335, 939 22891 => 21264, 22892 => 20971, 22893 => 22809, 22894 => 20821, 22895 => 20128, 940 22896 => 20822, 22897 => 20147, 22898 => 34926, 22899 => 34980, 22900 => 20149, 941 22901 => 33044, 22902 => 35026, 22903 => 31104, 22904 => 23348, 22905 => 34819, 942 22906 => 32696, 22907 => 20907, 22908 => 20913, 22909 => 20925, 22910 => 20924, 943 23073 => 20935, 23074 => 20886, 23075 => 20898, 23076 => 20901, 23077 => 35744, 944 23078 => 35750, 23079 => 35751, 23080 => 35754, 23081 => 35764, 23082 => 35765, 945 23083 => 35767, 23084 => 35778, 23085 => 35779, 23086 => 35787, 23087 => 35791, 946 23088 => 35790, 23089 => 35794, 23090 => 35795, 23091 => 35796, 23092 => 35798, 947 23093 => 35800, 23094 => 35801, 23095 => 35804, 23096 => 35807, 23097 => 35808, 948 23098 => 35812, 23099 => 35816, 23100 => 35817, 23101 => 35822, 23102 => 35824, 949 23103 => 35827, 23104 => 35830, 23105 => 35833, 23106 => 35836, 23107 => 35839, 950 23108 => 35840, 23109 => 35842, 23110 => 35844, 23111 => 35847, 23112 => 35852, 951 23113 => 35855, 23114 => 35857, 23115 => 35858, 23116 => 35860, 23117 => 35861, 952 23118 => 35862, 23119 => 35865, 23120 => 35867, 23121 => 35864, 23122 => 35869, 953 23123 => 35871, 23124 => 35872, 23125 => 35873, 23126 => 35877, 23127 => 35879, 954 23128 => 35882, 23129 => 35883, 23130 => 35886, 23131 => 35887, 23132 => 35890, 955 23133 => 35891, 23134 => 35893, 23135 => 35894, 23136 => 21353, 23137 => 21370, 956 23138 => 38429, 23139 => 38434, 23140 => 38433, 23141 => 38449, 23142 => 38442, 957 23143 => 38461, 23144 => 38460, 23145 => 38466, 23146 => 38473, 23147 => 38484, 958 23148 => 38495, 23149 => 38503, 23150 => 38508, 23151 => 38514, 23152 => 38516, 959 23153 => 38536, 23154 => 38541, 23155 => 38551, 23156 => 38576, 23157 => 37015, 960 23158 => 37019, 23159 => 37021, 23160 => 37017, 23161 => 37036, 23162 => 37025, 961 23163 => 37044, 23164 => 37043, 23165 => 37046, 23166 => 37050, 23329 => 37048, 962 23330 => 37040, 23331 => 37071, 23332 => 37061, 23333 => 37054, 23334 => 37072, 963 23335 => 37060, 23336 => 37063, 23337 => 37075, 23338 => 37094, 23339 => 37090, 964 23340 => 37084, 23341 => 37079, 23342 => 37083, 23343 => 37099, 23344 => 37103, 965 23345 => 37118, 23346 => 37124, 23347 => 37154, 23348 => 37150, 23349 => 37155, 966 23350 => 37169, 23351 => 37167, 23352 => 37177, 23353 => 37187, 23354 => 37190, 967 23355 => 21005, 23356 => 22850, 23357 => 21154, 23358 => 21164, 23359 => 21165, 968 23360 => 21182, 23361 => 21759, 23362 => 21200, 23363 => 21206, 23364 => 21232, 969 23365 => 21471, 23366 => 29166, 23367 => 30669, 23368 => 24308, 23369 => 20981, 970 23370 => 20988, 23371 => 39727, 23372 => 21430, 23373 => 24321, 23374 => 30042, 971 23375 => 24047, 23376 => 22348, 23377 => 22441, 23378 => 22433, 23379 => 22654, 972 23380 => 22716, 23381 => 22725, 23382 => 22737, 23383 => 22313, 23384 => 22316, 973 23385 => 22314, 23386 => 22323, 23387 => 22329, 23388 => 22318, 23389 => 22319, 974 23390 => 22364, 23391 => 22331, 23392 => 22338, 23393 => 22377, 23394 => 22405, 975 23395 => 22379, 23396 => 22406, 23397 => 22396, 23398 => 22395, 23399 => 22376, 976 23400 => 22381, 23401 => 22390, 23402 => 22387, 23403 => 22445, 23404 => 22436, 977 23405 => 22412, 23406 => 22450, 23407 => 22479, 23408 => 22439, 23409 => 22452, 978 23410 => 22419, 23411 => 22432, 23412 => 22485, 23413 => 22488, 23414 => 22490, 979 23415 => 22489, 23416 => 22482, 23417 => 22456, 23418 => 22516, 23419 => 22511, 980 23420 => 22520, 23421 => 22500, 23422 => 22493, 23585 => 22539, 23586 => 22541, 981 23587 => 22525, 23588 => 22509, 23589 => 22528, 23590 => 22558, 23591 => 22553, 982 23592 => 22596, 23593 => 22560, 23594 => 22629, 23595 => 22636, 23596 => 22657, 983 23597 => 22665, 23598 => 22682, 23599 => 22656, 23600 => 39336, 23601 => 40729, 984 23602 => 25087, 23603 => 33401, 23604 => 33405, 23605 => 33407, 23606 => 33423, 985 23607 => 33418, 23608 => 33448, 23609 => 33412, 23610 => 33422, 23611 => 33425, 986 23612 => 33431, 23613 => 33433, 23614 => 33451, 23615 => 33464, 23616 => 33470, 987 23617 => 33456, 23618 => 33480, 23619 => 33482, 23620 => 33507, 23621 => 33432, 988 23622 => 33463, 23623 => 33454, 23624 => 33483, 23625 => 33484, 23626 => 33473, 989 23627 => 33449, 23628 => 33460, 23629 => 33441, 23630 => 33450, 23631 => 33439, 990 23632 => 33476, 23633 => 33486, 23634 => 33444, 23635 => 33505, 23636 => 33545, 991 23637 => 33527, 23638 => 33508, 23639 => 33551, 23640 => 33543, 23641 => 33500, 992 23642 => 33524, 23643 => 33490, 23644 => 33496, 23645 => 33548, 23646 => 33531, 993 23647 => 33491, 23648 => 33553, 23649 => 33562, 23650 => 33542, 23651 => 33556, 994 23652 => 33557, 23653 => 33504, 23654 => 33493, 23655 => 33564, 23656 => 33617, 995 23657 => 33627, 23658 => 33628, 23659 => 33544, 23660 => 33682, 23661 => 33596, 996 23662 => 33588, 23663 => 33585, 23664 => 33691, 23665 => 33630, 23666 => 33583, 997 23667 => 33615, 23668 => 33607, 23669 => 33603, 23670 => 33631, 23671 => 33600, 998 23672 => 33559, 23673 => 33632, 23674 => 33581, 23675 => 33594, 23676 => 33587, 999 23677 => 33638, 23678 => 33637, 23841 => 33640, 23842 => 33563, 23843 => 33641, 1000 23844 => 33644, 23845 => 33642, 23846 => 33645, 23847 => 33646, 23848 => 33712, 1001 23849 => 33656, 23850 => 33715, 23851 => 33716, 23852 => 33696, 23853 => 33706, 1002 23854 => 33683, 23855 => 33692, 23856 => 33669, 23857 => 33660, 23858 => 33718, 1003 23859 => 33705, 23860 => 33661, 23861 => 33720, 23862 => 33659, 23863 => 33688, 1004 23864 => 33694, 23865 => 33704, 23866 => 33722, 23867 => 33724, 23868 => 33729, 1005 23869 => 33793, 23870 => 33765, 23871 => 33752, 23872 => 22535, 23873 => 33816, 1006 23874 => 33803, 23875 => 33757, 23876 => 33789, 23877 => 33750, 23878 => 33820, 1007 23879 => 33848, 23880 => 33809, 23881 => 33798, 23882 => 33748, 23883 => 33759, 1008 23884 => 33807, 23885 => 33795, 23886 => 33784, 23887 => 33785, 23888 => 33770, 1009 23889 => 33733, 23890 => 33728, 23891 => 33830, 23892 => 33776, 23893 => 33761, 1010 23894 => 33884, 23895 => 33873, 23896 => 33882, 23897 => 33881, 23898 => 33907, 1011 23899 => 33927, 23900 => 33928, 23901 => 33914, 23902 => 33929, 23903 => 33912, 1012 23904 => 33852, 23905 => 33862, 23906 => 33897, 23907 => 33910, 23908 => 33932, 1013 23909 => 33934, 23910 => 33841, 23911 => 33901, 23912 => 33985, 23913 => 33997, 1014 23914 => 34000, 23915 => 34022, 23916 => 33981, 23917 => 34003, 23918 => 33994, 1015 23919 => 33983, 23920 => 33978, 23921 => 34016, 23922 => 33953, 23923 => 33977, 1016 23924 => 33972, 23925 => 33943, 23926 => 34021, 23927 => 34019, 23928 => 34060, 1017 23929 => 29965, 23930 => 34104, 23931 => 34032, 23932 => 34105, 23933 => 34079, 1018 23934 => 34106, 24097 => 34134, 24098 => 34107, 24099 => 34047, 24100 => 34044, 1019 24101 => 34137, 24102 => 34120, 24103 => 34152, 24104 => 34148, 24105 => 34142, 1020 24106 => 34170, 24107 => 30626, 24108 => 34115, 24109 => 34162, 24110 => 34171, 1021 24111 => 34212, 24112 => 34216, 24113 => 34183, 24114 => 34191, 24115 => 34169, 1022 24116 => 34222, 24117 => 34204, 24118 => 34181, 24119 => 34233, 24120 => 34231, 1023 24121 => 34224, 24122 => 34259, 24123 => 34241, 24124 => 34268, 24125 => 34303, 1024 24126 => 34343, 24127 => 34309, 24128 => 34345, 24129 => 34326, 24130 => 34364, 1025 24131 => 24318, 24132 => 24328, 24133 => 22844, 24134 => 22849, 24135 => 32823, 1026 24136 => 22869, 24137 => 22874, 24138 => 22872, 24139 => 21263, 24140 => 23586, 1027 24141 => 23589, 24142 => 23596, 24143 => 23604, 24144 => 25164, 24145 => 25194, 1028 24146 => 25247, 24147 => 25275, 24148 => 25290, 24149 => 25306, 24150 => 25303, 1029 24151 => 25326, 24152 => 25378, 24153 => 25334, 24154 => 25401, 24155 => 25419, 1030 24156 => 25411, 24157 => 25517, 24158 => 25590, 24159 => 25457, 24160 => 25466, 1031 24161 => 25486, 24162 => 25524, 24163 => 25453, 24164 => 25516, 24165 => 25482, 1032 24166 => 25449, 24167 => 25518, 24168 => 25532, 24169 => 25586, 24170 => 25592, 1033 24171 => 25568, 24172 => 25599, 24173 => 25540, 24174 => 25566, 24175 => 25550, 1034 24176 => 25682, 24177 => 25542, 24178 => 25534, 24179 => 25669, 24180 => 25665, 1035 24181 => 25611, 24182 => 25627, 24183 => 25632, 24184 => 25612, 24185 => 25638, 1036 24186 => 25633, 24187 => 25694, 24188 => 25732, 24189 => 25709, 24190 => 25750, 1037 24353 => 25722, 24354 => 25783, 24355 => 25784, 24356 => 25753, 24357 => 25786, 1038 24358 => 25792, 24359 => 25808, 24360 => 25815, 24361 => 25828, 24362 => 25826, 1039 24363 => 25865, 24364 => 25893, 24365 => 25902, 24366 => 24331, 24367 => 24530, 1040 24368 => 29977, 24369 => 24337, 24370 => 21343, 24371 => 21489, 24372 => 21501, 1041 24373 => 21481, 24374 => 21480, 24375 => 21499, 24376 => 21522, 24377 => 21526, 1042 24378 => 21510, 24379 => 21579, 24380 => 21586, 24381 => 21587, 24382 => 21588, 1043 24383 => 21590, 24384 => 21571, 24385 => 21537, 24386 => 21591, 24387 => 21593, 1044 24388 => 21539, 24389 => 21554, 24390 => 21634, 24391 => 21652, 24392 => 21623, 1045 24393 => 21617, 24394 => 21604, 24395 => 21658, 24396 => 21659, 24397 => 21636, 1046 24398 => 21622, 24399 => 21606, 24400 => 21661, 24401 => 21712, 24402 => 21677, 1047 24403 => 21698, 24404 => 21684, 24405 => 21714, 24406 => 21671, 24407 => 21670, 1048 24408 => 21715, 24409 => 21716, 24410 => 21618, 24411 => 21667, 24412 => 21717, 1049 24413 => 21691, 24414 => 21695, 24415 => 21708, 24416 => 21721, 24417 => 21722, 1050 24418 => 21724, 24419 => 21673, 24420 => 21674, 24421 => 21668, 24422 => 21725, 1051 24423 => 21711, 24424 => 21726, 24425 => 21787, 24426 => 21735, 24427 => 21792, 1052 24428 => 21757, 24429 => 21780, 24430 => 21747, 24431 => 21794, 24432 => 21795, 1053 24433 => 21775, 24434 => 21777, 24435 => 21799, 24436 => 21802, 24437 => 21863, 1054 24438 => 21903, 24439 => 21941, 24440 => 21833, 24441 => 21869, 24442 => 21825, 1055 24443 => 21845, 24444 => 21823, 24445 => 21840, 24446 => 21820, 24609 => 21815, 1056 24610 => 21846, 24611 => 21877, 24612 => 21878, 24613 => 21879, 24614 => 21811, 1057 24615 => 21808, 24616 => 21852, 24617 => 21899, 24618 => 21970, 24619 => 21891, 1058 24620 => 21937, 24621 => 21945, 24622 => 21896, 24623 => 21889, 24624 => 21919, 1059 24625 => 21886, 24626 => 21974, 24627 => 21905, 24628 => 21883, 24629 => 21983, 1060 24630 => 21949, 24631 => 21950, 24632 => 21908, 24633 => 21913, 24634 => 21994, 1061 24635 => 22007, 24636 => 21961, 24637 => 22047, 24638 => 21969, 24639 => 21995, 1062 24640 => 21996, 24641 => 21972, 24642 => 21990, 24643 => 21981, 24644 => 21956, 1063 24645 => 21999, 24646 => 21989, 24647 => 22002, 24648 => 22003, 24649 => 21964, 1064 24650 => 21965, 24651 => 21992, 24652 => 22005, 24653 => 21988, 24654 => 36756, 1065 24655 => 22046, 24656 => 22024, 24657 => 22028, 24658 => 22017, 24659 => 22052, 1066 24660 => 22051, 24661 => 22014, 24662 => 22016, 24663 => 22055, 24664 => 22061, 1067 24665 => 22104, 24666 => 22073, 24667 => 22103, 24668 => 22060, 24669 => 22093, 1068 24670 => 22114, 24671 => 22105, 24672 => 22108, 24673 => 22092, 24674 => 22100, 1069 24675 => 22150, 24676 => 22116, 24677 => 22129, 24678 => 22123, 24679 => 22139, 1070 24680 => 22140, 24681 => 22149, 24682 => 22163, 24683 => 22191, 24684 => 22228, 1071 24685 => 22231, 24686 => 22237, 24687 => 22241, 24688 => 22261, 24689 => 22251, 1072 24690 => 22265, 24691 => 22271, 24692 => 22276, 24693 => 22282, 24694 => 22281, 1073 24695 => 22300, 24696 => 24079, 24697 => 24089, 24698 => 24084, 24699 => 24081, 1074 24700 => 24113, 24701 => 24123, 24702 => 24124, 24865 => 24119, 24866 => 24132, 1075 24867 => 24148, 24868 => 24155, 24869 => 24158, 24870 => 24161, 24871 => 23692, 1076 24872 => 23674, 24873 => 23693, 24874 => 23696, 24875 => 23702, 24876 => 23688, 1077 24877 => 23704, 24878 => 23705, 24879 => 23697, 24880 => 23706, 24881 => 23708, 1078 24882 => 23733, 24883 => 23714, 24884 => 23741, 24885 => 23724, 24886 => 23723, 1079 24887 => 23729, 24888 => 23715, 24889 => 23745, 24890 => 23735, 24891 => 23748, 1080 24892 => 23762, 24893 => 23780, 24894 => 23755, 24895 => 23781, 24896 => 23810, 1081 24897 => 23811, 24898 => 23847, 24899 => 23846, 24900 => 23854, 24901 => 23844, 1082 24902 => 23838, 24903 => 23814, 24904 => 23835, 24905 => 23896, 24906 => 23870, 1083 24907 => 23860, 24908 => 23869, 24909 => 23916, 24910 => 23899, 24911 => 23919, 1084 24912 => 23901, 24913 => 23915, 24914 => 23883, 24915 => 23882, 24916 => 23913, 1085 24917 => 23924, 24918 => 23938, 24919 => 23961, 24920 => 23965, 24921 => 35955, 1086 24922 => 23991, 24923 => 24005, 24924 => 24435, 24925 => 24439, 24926 => 24450, 1087 24927 => 24455, 24928 => 24457, 24929 => 24460, 24930 => 24469, 24931 => 24473, 1088 24932 => 24476, 24933 => 24488, 24934 => 24493, 24935 => 24501, 24936 => 24508, 1089 24937 => 34914, 24938 => 24417, 24939 => 29357, 24940 => 29360, 24941 => 29364, 1090 24942 => 29367, 24943 => 29368, 24944 => 29379, 24945 => 29377, 24946 => 29390, 1091 24947 => 29389, 24948 => 29394, 24949 => 29416, 24950 => 29423, 24951 => 29417, 1092 24952 => 29426, 24953 => 29428, 24954 => 29431, 24955 => 29441, 24956 => 29427, 1093 24957 => 29443, 24958 => 29434, 25121 => 29435, 25122 => 29463, 25123 => 29459, 1094 25124 => 29473, 25125 => 29450, 25126 => 29470, 25127 => 29469, 25128 => 29461, 1095 25129 => 29474, 25130 => 29497, 25131 => 29477, 25132 => 29484, 25133 => 29496, 1096 25134 => 29489, 25135 => 29520, 25136 => 29517, 25137 => 29527, 25138 => 29536, 1097 25139 => 29548, 25140 => 29551, 25141 => 29566, 25142 => 33307, 25143 => 22821, 1098 25144 => 39143, 25145 => 22820, 25146 => 22786, 25147 => 39267, 25148 => 39271, 1099 25149 => 39272, 25150 => 39273, 25151 => 39274, 25152 => 39275, 25153 => 39276, 1100 25154 => 39284, 25155 => 39287, 25156 => 39293, 25157 => 39296, 25158 => 39300, 1101 25159 => 39303, 25160 => 39306, 25161 => 39309, 25162 => 39312, 25163 => 39313, 1102 25164 => 39315, 25165 => 39316, 25166 => 39317, 25167 => 24192, 25168 => 24209, 1103 25169 => 24203, 25170 => 24214, 25171 => 24229, 25172 => 24224, 25173 => 24249, 1104 25174 => 24245, 25175 => 24254, 25176 => 24243, 25177 => 36179, 25178 => 24274, 1105 25179 => 24273, 25180 => 24283, 25181 => 24296, 25182 => 24298, 25183 => 33210, 1106 25184 => 24516, 25185 => 24521, 25186 => 24534, 25187 => 24527, 25188 => 24579, 1107 25189 => 24558, 25190 => 24580, 25191 => 24545, 25192 => 24548, 25193 => 24574, 1108 25194 => 24581, 25195 => 24582, 25196 => 24554, 25197 => 24557, 25198 => 24568, 1109 25199 => 24601, 25200 => 24629, 25201 => 24614, 25202 => 24603, 25203 => 24591, 1110 25204 => 24589, 25205 => 24617, 25206 => 24619, 25207 => 24586, 25208 => 24639, 1111 25209 => 24609, 25210 => 24696, 25211 => 24697, 25212 => 24699, 25213 => 24698, 1112 25214 => 24642, 25377 => 24682, 25378 => 24701, 25379 => 24726, 25380 => 24730, 1113 25381 => 24749, 25382 => 24733, 25383 => 24707, 25384 => 24722, 25385 => 24716, 1114 25386 => 24731, 25387 => 24812, 25388 => 24763, 25389 => 24753, 25390 => 24797, 1115 25391 => 24792, 25392 => 24774, 25393 => 24794, 25394 => 24756, 25395 => 24864, 1116 25396 => 24870, 25397 => 24853, 25398 => 24867, 25399 => 24820, 25400 => 24832, 1117 25401 => 24846, 25402 => 24875, 25403 => 24906, 25404 => 24949, 25405 => 25004, 1118 25406 => 24980, 25407 => 24999, 25408 => 25015, 25409 => 25044, 25410 => 25077, 1119 25411 => 24541, 25412 => 38579, 25413 => 38377, 25414 => 38379, 25415 => 38385, 1120 25416 => 38387, 25417 => 38389, 25418 => 38390, 25419 => 38396, 25420 => 38398, 1121 25421 => 38403, 25422 => 38404, 25423 => 38406, 25424 => 38408, 25425 => 38410, 1122 25426 => 38411, 25427 => 38412, 25428 => 38413, 25429 => 38415, 25430 => 38418, 1123 25431 => 38421, 25432 => 38422, 25433 => 38423, 25434 => 38425, 25435 => 38426, 1124 25436 => 20012, 25437 => 29247, 25438 => 25109, 25439 => 27701, 25440 => 27732, 1125 25441 => 27740, 25442 => 27722, 25443 => 27811, 25444 => 27781, 25445 => 27792, 1126 25446 => 27796, 25447 => 27788, 25448 => 27752, 25449 => 27753, 25450 => 27764, 1127 25451 => 27766, 25452 => 27782, 25453 => 27817, 25454 => 27856, 25455 => 27860, 1128 25456 => 27821, 25457 => 27895, 25458 => 27896, 25459 => 27889, 25460 => 27863, 1129 25461 => 27826, 25462 => 27872, 25463 => 27862, 25464 => 27898, 25465 => 27883, 1130 25466 => 27886, 25467 => 27825, 25468 => 27859, 25469 => 27887, 25470 => 27902, 1131 25633 => 27961, 25634 => 27943, 25635 => 27916, 25636 => 27971, 25637 => 27976, 1132 25638 => 27911, 25639 => 27908, 25640 => 27929, 25641 => 27918, 25642 => 27947, 1133 25643 => 27981, 25644 => 27950, 25645 => 27957, 25646 => 27930, 25647 => 27983, 1134 25648 => 27986, 25649 => 27988, 25650 => 27955, 25651 => 28049, 25652 => 28015, 1135 25653 => 28062, 25654 => 28064, 25655 => 27998, 25656 => 28051, 25657 => 28052, 1136 25658 => 27996, 25659 => 28000, 25660 => 28028, 25661 => 28003, 25662 => 28186, 1137 25663 => 28103, 25664 => 28101, 25665 => 28126, 25666 => 28174, 25667 => 28095, 1138 25668 => 28128, 25669 => 28177, 25670 => 28134, 25671 => 28125, 25672 => 28121, 1139 25673 => 28182, 25674 => 28075, 25675 => 28172, 25676 => 28078, 25677 => 28203, 1140 25678 => 28270, 25679 => 28238, 25680 => 28267, 25681 => 28338, 25682 => 28255, 1141 25683 => 28294, 25684 => 28243, 25685 => 28244, 25686 => 28210, 25687 => 28197, 1142 25688 => 28228, 25689 => 28383, 25690 => 28337, 25691 => 28312, 25692 => 28384, 1143 25693 => 28461, 25694 => 28386, 25695 => 28325, 25696 => 28327, 25697 => 28349, 1144 25698 => 28347, 25699 => 28343, 25700 => 28375, 25701 => 28340, 25702 => 28367, 1145 25703 => 28303, 25704 => 28354, 25705 => 28319, 25706 => 28514, 25707 => 28486, 1146 25708 => 28487, 25709 => 28452, 25710 => 28437, 25711 => 28409, 25712 => 28463, 1147 25713 => 28470, 25714 => 28491, 25715 => 28532, 25716 => 28458, 25717 => 28425, 1148 25718 => 28457, 25719 => 28553, 25720 => 28557, 25721 => 28556, 25722 => 28536, 1149 25723 => 28530, 25724 => 28540, 25725 => 28538, 25726 => 28625, 25889 => 28617, 1150 25890 => 28583, 25891 => 28601, 25892 => 28598, 25893 => 28610, 25894 => 28641, 1151 25895 => 28654, 25896 => 28638, 25897 => 28640, 25898 => 28655, 25899 => 28698, 1152 25900 => 28707, 25901 => 28699, 25902 => 28729, 25903 => 28725, 25904 => 28751, 1153 25905 => 28766, 25906 => 23424, 25907 => 23428, 25908 => 23445, 25909 => 23443, 1154 25910 => 23461, 25911 => 23480, 25912 => 29999, 25913 => 39582, 25914 => 25652, 1155 25915 => 23524, 25916 => 23534, 25917 => 35120, 25918 => 23536, 25919 => 36423, 1156 25920 => 35591, 25921 => 36790, 25922 => 36819, 25923 => 36821, 25924 => 36837, 1157 25925 => 36846, 25926 => 36836, 25927 => 36841, 25928 => 36838, 25929 => 36851, 1158 25930 => 36840, 25931 => 36869, 25932 => 36868, 25933 => 36875, 25934 => 36902, 1159 25935 => 36881, 25936 => 36877, 25937 => 36886, 25938 => 36897, 25939 => 36917, 1160 25940 => 36918, 25941 => 36909, 25942 => 36911, 25943 => 36932, 25944 => 36945, 1161 25945 => 36946, 25946 => 36944, 25947 => 36968, 25948 => 36952, 25949 => 36962, 1162 25950 => 36955, 25951 => 26297, 25952 => 36980, 25953 => 36989, 25954 => 36994, 1163 25955 => 37000, 25956 => 36995, 25957 => 37003, 25958 => 24400, 25959 => 24407, 1164 25960 => 24406, 25961 => 24408, 25962 => 23611, 25963 => 21675, 25964 => 23632, 1165 25965 => 23641, 25966 => 23409, 25967 => 23651, 25968 => 23654, 25969 => 32700, 1166 25970 => 24362, 25971 => 24361, 25972 => 24365, 25973 => 33396, 25974 => 24380, 1167 25975 => 39739, 25976 => 23662, 25977 => 22913, 25978 => 22915, 25979 => 22925, 1168 25980 => 22953, 25981 => 22954, 25982 => 22947, 26145 => 22935, 26146 => 22986, 1169 26147 => 22955, 26148 => 22942, 26149 => 22948, 26150 => 22994, 26151 => 22962, 1170 26152 => 22959, 26153 => 22999, 26154 => 22974, 26155 => 23045, 26156 => 23046, 1171 26157 => 23005, 26158 => 23048, 26159 => 23011, 26160 => 23000, 26161 => 23033, 1172 26162 => 23052, 26163 => 23049, 26164 => 23090, 26165 => 23092, 26166 => 23057, 1173 26167 => 23075, 26168 => 23059, 26169 => 23104, 26170 => 23143, 26171 => 23114, 1174 26172 => 23125, 26173 => 23100, 26174 => 23138, 26175 => 23157, 26176 => 33004, 1175 26177 => 23210, 26178 => 23195, 26179 => 23159, 26180 => 23162, 26181 => 23230, 1176 26182 => 23275, 26183 => 23218, 26184 => 23250, 26185 => 23252, 26186 => 23224, 1177 26187 => 23264, 26188 => 23267, 26189 => 23281, 26190 => 23254, 26191 => 23270, 1178 26192 => 23256, 26193 => 23260, 26194 => 23305, 26195 => 23319, 26196 => 23318, 1179 26197 => 23346, 26198 => 23351, 26199 => 23360, 26200 => 23573, 26201 => 23580, 1180 26202 => 23386, 26203 => 23397, 26204 => 23411, 26205 => 23377, 26206 => 23379, 1181 26207 => 23394, 26208 => 39541, 26209 => 39543, 26210 => 39544, 26211 => 39546, 1182 26212 => 39551, 26213 => 39549, 26214 => 39552, 26215 => 39553, 26216 => 39557, 1183 26217 => 39560, 26218 => 39562, 26219 => 39568, 26220 => 39570, 26221 => 39571, 1184 26222 => 39574, 26223 => 39576, 26224 => 39579, 26225 => 39580, 26226 => 39581, 1185 26227 => 39583, 26228 => 39584, 26229 => 39586, 26230 => 39587, 26231 => 39589, 1186 26232 => 39591, 26233 => 32415, 26234 => 32417, 26235 => 32419, 26236 => 32421, 1187 26237 => 32424, 26238 => 32425, 26401 => 32429, 26402 => 32432, 26403 => 32446, 1188 26404 => 32448, 26405 => 32449, 26406 => 32450, 26407 => 32457, 26408 => 32459, 1189 26409 => 32460, 26410 => 32464, 26411 => 32468, 26412 => 32471, 26413 => 32475, 1190 26414 => 32480, 26415 => 32481, 26416 => 32488, 26417 => 32491, 26418 => 32494, 1191 26419 => 32495, 26420 => 32497, 26421 => 32498, 26422 => 32525, 26423 => 32502, 1192 26424 => 32506, 26425 => 32507, 26426 => 32510, 26427 => 32513, 26428 => 32514, 1193 26429 => 32515, 26430 => 32519, 26431 => 32520, 26432 => 32523, 26433 => 32524, 1194 26434 => 32527, 26435 => 32529, 26436 => 32530, 26437 => 32535, 26438 => 32537, 1195 26439 => 32540, 26440 => 32539, 26441 => 32543, 26442 => 32545, 26443 => 32546, 1196 26444 => 32547, 26445 => 32548, 26446 => 32549, 26447 => 32550, 26448 => 32551, 1197 26449 => 32554, 26450 => 32555, 26451 => 32556, 26452 => 32557, 26453 => 32559, 1198 26454 => 32560, 26455 => 32561, 26456 => 32562, 26457 => 32563, 26458 => 32565, 1199 26459 => 24186, 26460 => 30079, 26461 => 24027, 26462 => 30014, 26463 => 37013, 1200 26464 => 29582, 26465 => 29585, 26466 => 29614, 26467 => 29602, 26468 => 29599, 1201 26469 => 29647, 26470 => 29634, 26471 => 29649, 26472 => 29623, 26473 => 29619, 1202 26474 => 29632, 26475 => 29641, 26476 => 29640, 26477 => 29669, 26478 => 29657, 1203 26479 => 39036, 26480 => 29706, 26481 => 29673, 26482 => 29671, 26483 => 29662, 1204 26484 => 29626, 26485 => 29682, 26486 => 29711, 26487 => 29738, 26488 => 29787, 1205 26489 => 29734, 26490 => 29733, 26491 => 29736, 26492 => 29744, 26493 => 29742, 1206 26494 => 29740, 26657 => 29723, 26658 => 29722, 26659 => 29761, 26660 => 29788, 1207 26661 => 29783, 26662 => 29781, 26663 => 29785, 26664 => 29815, 26665 => 29805, 1208 26666 => 29822, 26667 => 29852, 26668 => 29838, 26669 => 29824, 26670 => 29825, 1209 26671 => 29831, 26672 => 29835, 26673 => 29854, 26674 => 29864, 26675 => 29865, 1210 26676 => 29840, 26677 => 29863, 26678 => 29906, 26679 => 29882, 26680 => 38890, 1211 26681 => 38891, 26682 => 38892, 26683 => 26444, 26684 => 26451, 26685 => 26462, 1212 26686 => 26440, 26687 => 26473, 26688 => 26533, 26689 => 26503, 26690 => 26474, 1213 26691 => 26483, 26692 => 26520, 26693 => 26535, 26694 => 26485, 26695 => 26536, 1214 26696 => 26526, 26697 => 26541, 26698 => 26507, 26699 => 26487, 26700 => 26492, 1215 26701 => 26608, 26702 => 26633, 26703 => 26584, 26704 => 26634, 26705 => 26601, 1216 26706 => 26544, 26707 => 26636, 26708 => 26585, 26709 => 26549, 26710 => 26586, 1217 26711 => 26547, 26712 => 26589, 26713 => 26624, 26714 => 26563, 26715 => 26552, 1218 26716 => 26594, 26717 => 26638, 26718 => 26561, 26719 => 26621, 26720 => 26674, 1219 26721 => 26675, 26722 => 26720, 26723 => 26721, 26724 => 26702, 26725 => 26722, 1220 26726 => 26692, 26727 => 26724, 26728 => 26755, 26729 => 26653, 26730 => 26709, 1221 26731 => 26726, 26732 => 26689, 26733 => 26727, 26734 => 26688, 26735 => 26686, 1222 26736 => 26698, 26737 => 26697, 26738 => 26665, 26739 => 26805, 26740 => 26767, 1223 26741 => 26740, 26742 => 26743, 26743 => 26771, 26744 => 26731, 26745 => 26818, 1224 26746 => 26990, 26747 => 26876, 26748 => 26911, 26749 => 26912, 26750 => 26873, 1225 26913 => 26916, 26914 => 26864, 26915 => 26891, 26916 => 26881, 26917 => 26967, 1226 26918 => 26851, 26919 => 26896, 26920 => 26993, 26921 => 26937, 26922 => 26976, 1227 26923 => 26946, 26924 => 26973, 26925 => 27012, 26926 => 26987, 26927 => 27008, 1228 26928 => 27032, 26929 => 27000, 26930 => 26932, 26931 => 27084, 26932 => 27015, 1229 26933 => 27016, 26934 => 27086, 26935 => 27017, 26936 => 26982, 26937 => 26979, 1230 26938 => 27001, 26939 => 27035, 26940 => 27047, 26941 => 27067, 26942 => 27051, 1231 26943 => 27053, 26944 => 27092, 26945 => 27057, 26946 => 27073, 26947 => 27082, 1232 26948 => 27103, 26949 => 27029, 26950 => 27104, 26951 => 27021, 26952 => 27135, 1233 26953 => 27183, 26954 => 27117, 26955 => 27159, 26956 => 27160, 26957 => 27237, 1234 26958 => 27122, 26959 => 27204, 26960 => 27198, 26961 => 27296, 26962 => 27216, 1235 26963 => 27227, 26964 => 27189, 26965 => 27278, 26966 => 27257, 26967 => 27197, 1236 26968 => 27176, 26969 => 27224, 26970 => 27260, 26971 => 27281, 26972 => 27280, 1237 26973 => 27305, 26974 => 27287, 26975 => 27307, 26976 => 29495, 26977 => 29522, 1238 26978 => 27521, 26979 => 27522, 26980 => 27527, 26981 => 27524, 26982 => 27538, 1239 26983 => 27539, 26984 => 27533, 26985 => 27546, 26986 => 27547, 26987 => 27553, 1240 26988 => 27562, 26989 => 36715, 26990 => 36717, 26991 => 36721, 26992 => 36722, 1241 26993 => 36723, 26994 => 36725, 26995 => 36726, 26996 => 36728, 26997 => 36727, 1242 26998 => 36729, 26999 => 36730, 27000 => 36732, 27001 => 36734, 27002 => 36737, 1243 27003 => 36738, 27004 => 36740, 27005 => 36743, 27006 => 36747, 27169 => 36749, 1244 27170 => 36750, 27171 => 36751, 27172 => 36760, 27173 => 36762, 27174 => 36558, 1245 27175 => 25099, 27176 => 25111, 27177 => 25115, 27178 => 25119, 27179 => 25122, 1246 27180 => 25121, 27181 => 25125, 27182 => 25124, 27183 => 25132, 27184 => 33255, 1247 27185 => 29935, 27186 => 29940, 27187 => 29951, 27188 => 29967, 27189 => 29969, 1248 27190 => 29971, 27191 => 25908, 27192 => 26094, 27193 => 26095, 27194 => 26096, 1249 27195 => 26122, 27196 => 26137, 27197 => 26482, 27198 => 26115, 27199 => 26133, 1250 27200 => 26112, 27201 => 28805, 27202 => 26359, 27203 => 26141, 27204 => 26164, 1251 27205 => 26161, 27206 => 26166, 27207 => 26165, 27208 => 32774, 27209 => 26207, 1252 27210 => 26196, 27211 => 26177, 27212 => 26191, 27213 => 26198, 27214 => 26209, 1253 27215 => 26199, 27216 => 26231, 27217 => 26244, 27218 => 26252, 27219 => 26279, 1254 27220 => 26269, 27221 => 26302, 27222 => 26331, 27223 => 26332, 27224 => 26342, 1255 27225 => 26345, 27226 => 36146, 27227 => 36147, 27228 => 36150, 27229 => 36155, 1256 27230 => 36157, 27231 => 36160, 27232 => 36165, 27233 => 36166, 27234 => 36168, 1257 27235 => 36169, 27236 => 36167, 27237 => 36173, 27238 => 36181, 27239 => 36185, 1258 27240 => 35271, 27241 => 35274, 27242 => 35275, 27243 => 35276, 27244 => 35278, 1259 27245 => 35279, 27246 => 35280, 27247 => 35281, 27248 => 29294, 27249 => 29343, 1260 27250 => 29277, 27251 => 29286, 27252 => 29295, 27253 => 29310, 27254 => 29311, 1261 27255 => 29316, 27256 => 29323, 27257 => 29325, 27258 => 29327, 27259 => 29330, 1262 27260 => 25352, 27261 => 25394, 27262 => 25520, 27425 => 25663, 27426 => 25816, 1263 27427 => 32772, 27428 => 27626, 27429 => 27635, 27430 => 27645, 27431 => 27637, 1264 27432 => 27641, 27433 => 27653, 27434 => 27655, 27435 => 27654, 27436 => 27661, 1265 27437 => 27669, 27438 => 27672, 27439 => 27673, 27440 => 27674, 27441 => 27681, 1266 27442 => 27689, 27443 => 27684, 27444 => 27690, 27445 => 27698, 27446 => 25909, 1267 27447 => 25941, 27448 => 25963, 27449 => 29261, 27450 => 29266, 27451 => 29270, 1268 27452 => 29232, 27453 => 34402, 27454 => 21014, 27455 => 32927, 27456 => 32924, 1269 27457 => 32915, 27458 => 32956, 27459 => 26378, 27460 => 32957, 27461 => 32945, 1270 27462 => 32939, 27463 => 32941, 27464 => 32948, 27465 => 32951, 27466 => 32999, 1271 27467 => 33000, 27468 => 33001, 27469 => 33002, 27470 => 32987, 27471 => 32962, 1272 27472 => 32964, 27473 => 32985, 27474 => 32973, 27475 => 32983, 27476 => 26384, 1273 27477 => 32989, 27478 => 33003, 27479 => 33009, 27480 => 33012, 27481 => 33005, 1274 27482 => 33037, 27483 => 33038, 27484 => 33010, 27485 => 33020, 27486 => 26389, 1275 27487 => 33042, 27488 => 35930, 27489 => 33078, 27490 => 33054, 27491 => 33068, 1276 27492 => 33048, 27493 => 33074, 27494 => 33096, 27495 => 33100, 27496 => 33107, 1277 27497 => 33140, 27498 => 33113, 27499 => 33114, 27500 => 33137, 27501 => 33120, 1278 27502 => 33129, 27503 => 33148, 27504 => 33149, 27505 => 33133, 27506 => 33127, 1279 27507 => 22605, 27508 => 23221, 27509 => 33160, 27510 => 33154, 27511 => 33169, 1280 27512 => 28373, 27513 => 33187, 27514 => 33194, 27515 => 33228, 27516 => 26406, 1281 27517 => 33226, 27518 => 33211, 27681 => 33217, 27682 => 33190, 27683 => 27428, 1282 27684 => 27447, 27685 => 27449, 27686 => 27459, 27687 => 27462, 27688 => 27481, 1283 27689 => 39121, 27690 => 39122, 27691 => 39123, 27692 => 39125, 27693 => 39129, 1284 27694 => 39130, 27695 => 27571, 27696 => 24384, 27697 => 27586, 27698 => 35315, 1285 27699 => 26000, 27700 => 40785, 27701 => 26003, 27702 => 26044, 27703 => 26054, 1286 27704 => 26052, 27705 => 26051, 27706 => 26060, 27707 => 26062, 27708 => 26066, 1287 27709 => 26070, 27710 => 28800, 27711 => 28828, 27712 => 28822, 27713 => 28829, 1288 27714 => 28859, 27715 => 28864, 27716 => 28855, 27717 => 28843, 27718 => 28849, 1289 27719 => 28904, 27720 => 28874, 27721 => 28944, 27722 => 28947, 27723 => 28950, 1290 27724 => 28975, 27725 => 28977, 27726 => 29043, 27727 => 29020, 27728 => 29032, 1291 27729 => 28997, 27730 => 29042, 27731 => 29002, 27732 => 29048, 27733 => 29050, 1292 27734 => 29080, 27735 => 29107, 27736 => 29109, 27737 => 29096, 27738 => 29088, 1293 27739 => 29152, 27740 => 29140, 27741 => 29159, 27742 => 29177, 27743 => 29213, 1294 27744 => 29224, 27745 => 28780, 27746 => 28952, 27747 => 29030, 27748 => 29113, 1295 27749 => 25150, 27750 => 25149, 27751 => 25155, 27752 => 25160, 27753 => 25161, 1296 27754 => 31035, 27755 => 31040, 27756 => 31046, 27757 => 31049, 27758 => 31067, 1297 27759 => 31068, 27760 => 31059, 27761 => 31066, 27762 => 31074, 27763 => 31063, 1298 27764 => 31072, 27765 => 31087, 27766 => 31079, 27767 => 31098, 27768 => 31109, 1299 27769 => 31114, 27770 => 31130, 27771 => 31143, 27772 => 31155, 27773 => 24529, 1300 27774 => 24528, 27937 => 24636, 27938 => 24669, 27939 => 24666, 27940 => 24679, 1301 27941 => 24641, 27942 => 24665, 27943 => 24675, 27944 => 24747, 27945 => 24838, 1302 27946 => 24845, 27947 => 24925, 27948 => 25001, 27949 => 24989, 27950 => 25035, 1303 27951 => 25041, 27952 => 25094, 27953 => 32896, 27954 => 32895, 27955 => 27795, 1304 27956 => 27894, 27957 => 28156, 27958 => 30710, 27959 => 30712, 27960 => 30720, 1305 27961 => 30729, 27962 => 30743, 27963 => 30744, 27964 => 30737, 27965 => 26027, 1306 27966 => 30765, 27967 => 30748, 27968 => 30749, 27969 => 30777, 27970 => 30778, 1307 27971 => 30779, 27972 => 30751, 27973 => 30780, 27974 => 30757, 27975 => 30764, 1308 27976 => 30755, 27977 => 30761, 27978 => 30798, 27979 => 30829, 27980 => 30806, 1309 27981 => 30807, 27982 => 30758, 27983 => 30800, 27984 => 30791, 27985 => 30796, 1310 27986 => 30826, 27987 => 30875, 27988 => 30867, 27989 => 30874, 27990 => 30855, 1311 27991 => 30876, 27992 => 30881, 27993 => 30883, 27994 => 30898, 27995 => 30905, 1312 27996 => 30885, 27997 => 30932, 27998 => 30937, 27999 => 30921, 28000 => 30956, 1313 28001 => 30962, 28002 => 30981, 28003 => 30964, 28004 => 30995, 28005 => 31012, 1314 28006 => 31006, 28007 => 31028, 28008 => 40859, 28009 => 40697, 28010 => 40699, 1315 28011 => 40700, 28012 => 30449, 28013 => 30468, 28014 => 30477, 28015 => 30457, 1316 28016 => 30471, 28017 => 30472, 28018 => 30490, 28019 => 30498, 28020 => 30489, 1317 28021 => 30509, 28022 => 30502, 28023 => 30517, 28024 => 30520, 28025 => 30544, 1318 28026 => 30545, 28027 => 30535, 28028 => 30531, 28029 => 30554, 28030 => 30568, 1319 28193 => 30562, 28194 => 30565, 28195 => 30591, 28196 => 30605, 28197 => 30589, 1320 28198 => 30592, 28199 => 30604, 28200 => 30609, 28201 => 30623, 28202 => 30624, 1321 28203 => 30640, 28204 => 30645, 28205 => 30653, 28206 => 30010, 28207 => 30016, 1322 28208 => 30030, 28209 => 30027, 28210 => 30024, 28211 => 30043, 28212 => 30066, 1323 28213 => 30073, 28214 => 30083, 28215 => 32600, 28216 => 32609, 28217 => 32607, 1324 28218 => 35400, 28219 => 32616, 28220 => 32628, 28221 => 32625, 28222 => 32633, 1325 28223 => 32641, 28224 => 32638, 28225 => 30413, 28226 => 30437, 28227 => 34866, 1326 28228 => 38021, 28229 => 38022, 28230 => 38023, 28231 => 38027, 28232 => 38026, 1327 28233 => 38028, 28234 => 38029, 28235 => 38031, 28236 => 38032, 28237 => 38036, 1328 28238 => 38039, 28239 => 38037, 28240 => 38042, 28241 => 38043, 28242 => 38044, 1329 28243 => 38051, 28244 => 38052, 28245 => 38059, 28246 => 38058, 28247 => 38061, 1330 28248 => 38060, 28249 => 38063, 28250 => 38064, 28251 => 38066, 28252 => 38068, 1331 28253 => 38070, 28254 => 38071, 28255 => 38072, 28256 => 38073, 28257 => 38074, 1332 28258 => 38076, 28259 => 38077, 28260 => 38079, 28261 => 38084, 28262 => 38088, 1333 28263 => 38089, 28264 => 38090, 28265 => 38091, 28266 => 38092, 28267 => 38093, 1334 28268 => 38094, 28269 => 38096, 28270 => 38097, 28271 => 38098, 28272 => 38101, 1335 28273 => 38102, 28274 => 38103, 28275 => 38105, 28276 => 38104, 28277 => 38107, 1336 28278 => 38110, 28279 => 38111, 28280 => 38112, 28281 => 38114, 28282 => 38116, 1337 28283 => 38117, 28284 => 38119, 28285 => 38120, 28286 => 38122, 28449 => 38121, 1338 28450 => 38123, 28451 => 38126, 28452 => 38127, 28453 => 38131, 28454 => 38132, 1339 28455 => 38133, 28456 => 38135, 28457 => 38137, 28458 => 38140, 28459 => 38141, 1340 28460 => 38143, 28461 => 38147, 28462 => 38146, 28463 => 38150, 28464 => 38151, 1341 28465 => 38153, 28466 => 38154, 28467 => 38157, 28468 => 38158, 28469 => 38159, 1342 28470 => 38162, 28471 => 38163, 28472 => 38164, 28473 => 38165, 28474 => 38166, 1343 28475 => 38168, 28476 => 38171, 28477 => 38173, 28478 => 38174, 28479 => 38175, 1344 28480 => 38178, 28481 => 38186, 28482 => 38187, 28483 => 38185, 28484 => 38188, 1345 28485 => 38193, 28486 => 38194, 28487 => 38196, 28488 => 38198, 28489 => 38199, 1346 28490 => 38200, 28491 => 38204, 28492 => 38206, 28493 => 38207, 28494 => 38210, 1347 28495 => 38197, 28496 => 38212, 28497 => 38213, 28498 => 38214, 28499 => 38217, 1348 28500 => 38220, 28501 => 38222, 28502 => 38223, 28503 => 38226, 28504 => 38227, 1349 28505 => 38228, 28506 => 38230, 28507 => 38231, 28508 => 38232, 28509 => 38233, 1350 28510 => 38235, 28511 => 38238, 28512 => 38239, 28513 => 38237, 28514 => 38241, 1351 28515 => 38242, 28516 => 38244, 28517 => 38245, 28518 => 38246, 28519 => 38247, 1352 28520 => 38248, 28521 => 38249, 28522 => 38250, 28523 => 38251, 28524 => 38252, 1353 28525 => 38255, 28526 => 38257, 28527 => 38258, 28528 => 38259, 28529 => 38202, 1354 28530 => 30695, 28531 => 30700, 28532 => 38601, 28533 => 31189, 28534 => 31213, 1355 28535 => 31203, 28536 => 31211, 28537 => 31238, 28538 => 23879, 28539 => 31235, 1356 28540 => 31234, 28541 => 31262, 28542 => 31252, 28705 => 31289, 28706 => 31287, 1357 28707 => 31313, 28708 => 40655, 28709 => 39333, 28710 => 31344, 28711 => 30344, 1358 28712 => 30350, 28713 => 30355, 28714 => 30361, 28715 => 30372, 28716 => 29918, 1359 28717 => 29920, 28718 => 29996, 28719 => 40480, 28720 => 40482, 28721 => 40488, 1360 28722 => 40489, 28723 => 40490, 28724 => 40491, 28725 => 40492, 28726 => 40498, 1361 28727 => 40497, 28728 => 40502, 28729 => 40504, 28730 => 40503, 28731 => 40505, 1362 28732 => 40506, 28733 => 40510, 28734 => 40513, 28735 => 40514, 28736 => 40516, 1363 28737 => 40518, 28738 => 40519, 28739 => 40520, 28740 => 40521, 28741 => 40523, 1364 28742 => 40524, 28743 => 40526, 28744 => 40529, 28745 => 40533, 28746 => 40535, 1365 28747 => 40538, 28748 => 40539, 28749 => 40540, 28750 => 40542, 28751 => 40547, 1366 28752 => 40550, 28753 => 40551, 28754 => 40552, 28755 => 40553, 28756 => 40554, 1367 28757 => 40555, 28758 => 40556, 28759 => 40561, 28760 => 40557, 28761 => 40563, 1368 28762 => 30098, 28763 => 30100, 28764 => 30102, 28765 => 30112, 28766 => 30109, 1369 28767 => 30124, 28768 => 30115, 28769 => 30131, 28770 => 30132, 28771 => 30136, 1370 28772 => 30148, 28773 => 30129, 28774 => 30128, 28775 => 30147, 28776 => 30146, 1371 28777 => 30166, 28778 => 30157, 28779 => 30179, 28780 => 30184, 28781 => 30182, 1372 28782 => 30180, 28783 => 30187, 28784 => 30183, 28785 => 30211, 28786 => 30193, 1373 28787 => 30204, 28788 => 30207, 28789 => 30224, 28790 => 30208, 28791 => 30213, 1374 28792 => 30220, 28793 => 30231, 28794 => 30218, 28795 => 30245, 28796 => 30232, 1375 28797 => 30229, 28798 => 30233, 28961 => 30235, 28962 => 30268, 28963 => 30242, 1376 28964 => 30240, 28965 => 30272, 28966 => 30253, 28967 => 30256, 28968 => 30271, 1377 28969 => 30261, 28970 => 30275, 28971 => 30270, 28972 => 30259, 28973 => 30285, 1378 28974 => 30302, 28975 => 30292, 28976 => 30300, 28977 => 30294, 28978 => 30315, 1379 28979 => 30319, 28980 => 32714, 28981 => 31462, 28982 => 31352, 28983 => 31353, 1380 28984 => 31360, 28985 => 31366, 28986 => 31368, 28987 => 31381, 28988 => 31398, 1381 28989 => 31392, 28990 => 31404, 28991 => 31400, 28992 => 31405, 28993 => 31411, 1382 28994 => 34916, 28995 => 34921, 28996 => 34930, 28997 => 34941, 28998 => 34943, 1383 28999 => 34946, 29000 => 34978, 29001 => 35014, 29002 => 34999, 29003 => 35004, 1384 29004 => 35017, 29005 => 35042, 29006 => 35022, 29007 => 35043, 29008 => 35045, 1385 29009 => 35057, 29010 => 35098, 29011 => 35068, 29012 => 35048, 29013 => 35070, 1386 29014 => 35056, 29015 => 35105, 29016 => 35097, 29017 => 35091, 29018 => 35099, 1387 29019 => 35082, 29020 => 35124, 29021 => 35115, 29022 => 35126, 29023 => 35137, 1388 29024 => 35174, 29025 => 35195, 29026 => 30091, 29027 => 32997, 29028 => 30386, 1389 29029 => 30388, 29030 => 30684, 29031 => 32786, 29032 => 32788, 29033 => 32790, 1390 29034 => 32796, 29035 => 32800, 29036 => 32802, 29037 => 32805, 29038 => 32806, 1391 29039 => 32807, 29040 => 32809, 29041 => 32808, 29042 => 32817, 29043 => 32779, 1392 29044 => 32821, 29045 => 32835, 29046 => 32838, 29047 => 32845, 29048 => 32850, 1393 29049 => 32873, 29050 => 32881, 29051 => 35203, 29052 => 39032, 29053 => 39040, 1394 29054 => 39043, 29217 => 39049, 29218 => 39052, 29219 => 39053, 29220 => 39055, 1395 29221 => 39060, 29222 => 39066, 29223 => 39067, 29224 => 39070, 29225 => 39071, 1396 29226 => 39073, 29227 => 39074, 29228 => 39077, 29229 => 39078, 29230 => 34381, 1397 29231 => 34388, 29232 => 34412, 29233 => 34414, 29234 => 34431, 29235 => 34426, 1398 29236 => 34428, 29237 => 34427, 29238 => 34472, 29239 => 34445, 29240 => 34443, 1399 29241 => 34476, 29242 => 34461, 29243 => 34471, 29244 => 34467, 29245 => 34474, 1400 29246 => 34451, 29247 => 34473, 29248 => 34486, 29249 => 34500, 29250 => 34485, 1401 29251 => 34510, 29252 => 34480, 29253 => 34490, 29254 => 34481, 29255 => 34479, 1402 29256 => 34505, 29257 => 34511, 29258 => 34484, 29259 => 34537, 29260 => 34545, 1403 29261 => 34546, 29262 => 34541, 29263 => 34547, 29264 => 34512, 29265 => 34579, 1404 29266 => 34526, 29267 => 34548, 29268 => 34527, 29269 => 34520, 29270 => 34513, 1405 29271 => 34563, 29272 => 34567, 29273 => 34552, 29274 => 34568, 29275 => 34570, 1406 29276 => 34573, 29277 => 34569, 29278 => 34595, 29279 => 34619, 29280 => 34590, 1407 29281 => 34597, 29282 => 34606, 29283 => 34586, 29284 => 34622, 29285 => 34632, 1408 29286 => 34612, 29287 => 34609, 29288 => 34601, 29289 => 34615, 29290 => 34623, 1409 29291 => 34690, 29292 => 34594, 29293 => 34685, 29294 => 34686, 29295 => 34683, 1410 29296 => 34656, 29297 => 34672, 29298 => 34636, 29299 => 34670, 29300 => 34699, 1411 29301 => 34643, 29302 => 34659, 29303 => 34684, 29304 => 34660, 29305 => 34649, 1412 29306 => 34661, 29307 => 34707, 29308 => 34735, 29309 => 34728, 29310 => 34770, 1413 29473 => 34758, 29474 => 34696, 29475 => 34693, 29476 => 34733, 29477 => 34711, 1414 29478 => 34691, 29479 => 34731, 29480 => 34789, 29481 => 34732, 29482 => 34741, 1415 29483 => 34739, 29484 => 34763, 29485 => 34771, 29486 => 34749, 29487 => 34769, 1416 29488 => 34752, 29489 => 34762, 29490 => 34779, 29491 => 34794, 29492 => 34784, 1417 29493 => 34798, 29494 => 34838, 29495 => 34835, 29496 => 34814, 29497 => 34826, 1418 29498 => 34843, 29499 => 34849, 29500 => 34873, 29501 => 34876, 29502 => 32566, 1419 29503 => 32578, 29504 => 32580, 29505 => 32581, 29506 => 33296, 29507 => 31482, 1420 29508 => 31485, 29509 => 31496, 29510 => 31491, 29511 => 31492, 29512 => 31509, 1421 29513 => 31498, 29514 => 31531, 29515 => 31503, 29516 => 31559, 29517 => 31544, 1422 29518 => 31530, 29519 => 31513, 29520 => 31534, 29521 => 31537, 29522 => 31520, 1423 29523 => 31525, 29524 => 31524, 29525 => 31539, 29526 => 31550, 29527 => 31518, 1424 29528 => 31576, 29529 => 31578, 29530 => 31557, 29531 => 31605, 29532 => 31564, 1425 29533 => 31581, 29534 => 31584, 29535 => 31598, 29536 => 31611, 29537 => 31586, 1426 29538 => 31602, 29539 => 31601, 29540 => 31632, 29541 => 31654, 29542 => 31655, 1427 29543 => 31672, 29544 => 31660, 29545 => 31645, 29546 => 31656, 29547 => 31621, 1428 29548 => 31658, 29549 => 31644, 29550 => 31650, 29551 => 31659, 29552 => 31668, 1429 29553 => 31697, 29554 => 31681, 29555 => 31692, 29556 => 31709, 29557 => 31706, 1430 29558 => 31717, 29559 => 31718, 29560 => 31722, 29561 => 31756, 29562 => 31742, 1431 29563 => 31740, 29564 => 31759, 29565 => 31766, 29566 => 31755, 29729 => 31775, 1432 29730 => 31786, 29731 => 31782, 29732 => 31800, 29733 => 31809, 29734 => 31808, 1433 29735 => 33278, 29736 => 33281, 29737 => 33282, 29738 => 33284, 29739 => 33260, 1434 29740 => 34884, 29741 => 33313, 29742 => 33314, 29743 => 33315, 29744 => 33325, 1435 29745 => 33327, 29746 => 33320, 29747 => 33323, 29748 => 33336, 29749 => 33339, 1436 29750 => 33331, 29751 => 33332, 29752 => 33342, 29753 => 33348, 29754 => 33353, 1437 29755 => 33355, 29756 => 33359, 29757 => 33370, 29758 => 33375, 29759 => 33384, 1438 29760 => 34942, 29761 => 34949, 29762 => 34952, 29763 => 35032, 29764 => 35039, 1439 29765 => 35166, 29766 => 32669, 29767 => 32671, 29768 => 32679, 29769 => 32687, 1440 29770 => 32688, 29771 => 32690, 29772 => 31868, 29773 => 25929, 29774 => 31889, 1441 29775 => 31901, 29776 => 31900, 29777 => 31902, 29778 => 31906, 29779 => 31922, 1442 29780 => 31932, 29781 => 31933, 29782 => 31937, 29783 => 31943, 29784 => 31948, 1443 29785 => 31949, 29786 => 31944, 29787 => 31941, 29788 => 31959, 29789 => 31976, 1444 29790 => 33390, 29791 => 26280, 29792 => 32703, 29793 => 32718, 29794 => 32725, 1445 29795 => 32741, 29796 => 32737, 29797 => 32742, 29798 => 32745, 29799 => 32750, 1446 29800 => 32755, 29801 => 31992, 29802 => 32119, 29803 => 32166, 29804 => 32174, 1447 29805 => 32327, 29806 => 32411, 29807 => 40632, 29808 => 40628, 29809 => 36211, 1448 29810 => 36228, 29811 => 36244, 29812 => 36241, 29813 => 36273, 29814 => 36199, 1449 29815 => 36205, 29816 => 35911, 29817 => 35913, 29818 => 37194, 29819 => 37200, 1450 29820 => 37198, 29821 => 37199, 29822 => 37220, 29985 => 37218, 29986 => 37217, 1451 29987 => 37232, 29988 => 37225, 29989 => 37231, 29990 => 37245, 29991 => 37246, 1452 29992 => 37234, 29993 => 37236, 29994 => 37241, 29995 => 37260, 29996 => 37253, 1453 29997 => 37264, 29998 => 37261, 29999 => 37265, 30000 => 37282, 30001 => 37283, 1454 30002 => 37290, 30003 => 37293, 30004 => 37294, 30005 => 37295, 30006 => 37301, 1455 30007 => 37300, 30008 => 37306, 30009 => 35925, 30010 => 40574, 30011 => 36280, 1456 30012 => 36331, 30013 => 36357, 30014 => 36441, 30015 => 36457, 30016 => 36277, 1457 30017 => 36287, 30018 => 36284, 30019 => 36282, 30020 => 36292, 30021 => 36310, 1458 30022 => 36311, 30023 => 36314, 30024 => 36318, 30025 => 36302, 30026 => 36303, 1459 30027 => 36315, 30028 => 36294, 30029 => 36332, 30030 => 36343, 30031 => 36344, 1460 30032 => 36323, 30033 => 36345, 30034 => 36347, 30035 => 36324, 30036 => 36361, 1461 30037 => 36349, 30038 => 36372, 30039 => 36381, 30040 => 36383, 30041 => 36396, 1462 30042 => 36398, 30043 => 36387, 30044 => 36399, 30045 => 36410, 30046 => 36416, 1463 30047 => 36409, 30048 => 36405, 30049 => 36413, 30050 => 36401, 30051 => 36425, 1464 30052 => 36417, 30053 => 36418, 30054 => 36433, 30055 => 36434, 30056 => 36426, 1465 30057 => 36464, 30058 => 36470, 30059 => 36476, 30060 => 36463, 30061 => 36468, 1466 30062 => 36485, 30063 => 36495, 30064 => 36500, 30065 => 36496, 30066 => 36508, 1467 30067 => 36510, 30068 => 35960, 30069 => 35970, 30070 => 35978, 30071 => 35973, 1468 30072 => 35992, 30073 => 35988, 30074 => 26011, 30075 => 35286, 30076 => 35294, 1469 30077 => 35290, 30078 => 35292, 30241 => 35301, 30242 => 35307, 30243 => 35311, 1470 30244 => 35390, 30245 => 35622, 30246 => 38739, 30247 => 38633, 30248 => 38643, 1471 30249 => 38639, 30250 => 38662, 30251 => 38657, 30252 => 38664, 30253 => 38671, 1472 30254 => 38670, 30255 => 38698, 30256 => 38701, 30257 => 38704, 30258 => 38718, 1473 30259 => 40832, 30260 => 40835, 30261 => 40837, 30262 => 40838, 30263 => 40839, 1474 30264 => 40840, 30265 => 40841, 30266 => 40842, 30267 => 40844, 30268 => 40702, 1475 30269 => 40715, 30270 => 40717, 30271 => 38585, 30272 => 38588, 30273 => 38589, 1476 30274 => 38606, 30275 => 38610, 30276 => 30655, 30277 => 38624, 30278 => 37518, 1477 30279 => 37550, 30280 => 37576, 30281 => 37694, 30282 => 37738, 30283 => 37834, 1478 30284 => 37775, 30285 => 37950, 30286 => 37995, 30287 => 40063, 30288 => 40066, 1479 30289 => 40069, 30290 => 40070, 30291 => 40071, 30292 => 40072, 30293 => 31267, 1480 30294 => 40075, 30295 => 40078, 30296 => 40080, 30297 => 40081, 30298 => 40082, 1481 30299 => 40084, 30300 => 40085, 30301 => 40090, 30302 => 40091, 30303 => 40094, 1482 30304 => 40095, 30305 => 40096, 30306 => 40097, 30307 => 40098, 30308 => 40099, 1483 30309 => 40101, 30310 => 40102, 30311 => 40103, 30312 => 40104, 30313 => 40105, 1484 30314 => 40107, 30315 => 40109, 30316 => 40110, 30317 => 40112, 30318 => 40113, 1485 30319 => 40114, 30320 => 40115, 30321 => 40116, 30322 => 40117, 30323 => 40118, 1486 30324 => 40119, 30325 => 40122, 30326 => 40123, 30327 => 40124, 30328 => 40125, 1487 30329 => 40132, 30330 => 40133, 30331 => 40134, 30332 => 40135, 30333 => 40138, 1488 30334 => 40139, 30497 => 40140, 30498 => 40141, 30499 => 40142, 30500 => 40143, 1489 30501 => 40144, 30502 => 40147, 30503 => 40148, 30504 => 40149, 30505 => 40151, 1490 30506 => 40152, 30507 => 40153, 30508 => 40156, 30509 => 40157, 30510 => 40159, 1491 30511 => 40162, 30512 => 38780, 30513 => 38789, 30514 => 38801, 30515 => 38802, 1492 30516 => 38804, 30517 => 38831, 30518 => 38827, 30519 => 38819, 30520 => 38834, 1493 30521 => 38836, 30522 => 39601, 30523 => 39600, 30524 => 39607, 30525 => 40536, 1494 30526 => 39606, 30527 => 39610, 30528 => 39612, 30529 => 39617, 30530 => 39616, 1495 30531 => 39621, 30532 => 39618, 30533 => 39627, 30534 => 39628, 30535 => 39633, 1496 30536 => 39749, 30537 => 39747, 30538 => 39751, 30539 => 39753, 30540 => 39752, 1497 30541 => 39757, 30542 => 39761, 30543 => 39144, 30544 => 39181, 30545 => 39214, 1498 30546 => 39253, 30547 => 39252, 30548 => 39647, 30549 => 39649, 30550 => 39654, 1499 30551 => 39663, 30552 => 39659, 30553 => 39675, 30554 => 39661, 30555 => 39673, 1500 30556 => 39688, 30557 => 39695, 30558 => 39699, 30559 => 39711, 30560 => 39715, 1501 30561 => 40637, 30562 => 40638, 30563 => 32315, 30564 => 40578, 30565 => 40583, 1502 30566 => 40584, 30567 => 40587, 30568 => 40594, 30569 => 37846, 30570 => 40605, 1503 30571 => 40607, 30572 => 40667, 30573 => 40668, 30574 => 40669, 30575 => 40672, 1504 30576 => 40671, 30577 => 40674, 30578 => 40681, 30579 => 40679, 30580 => 40677, 1505 30581 => 40682, 30582 => 40687, 30583 => 40738, 30584 => 40748, 30585 => 40751, 1506 30586 => 40761, 30587 => 40759, 30588 => 40765, 30589 => 40766, 30590 => 40772, 1507 0 => 0 ); 1508 1508 1509 1509 function gb2utf8($gb) { 1510 if( !trim($gb) ) return $gb; 1511 $utf8=''; 1512 while($gb) { 1513 if( ord(substr($gb,0,1)) > 127 ) { 1514 $t=substr($gb,0,2); 1515 $gb=substr($gb,2); 1516 $utf8 .= $this->u2utf8($this->codetable[hexdec(bin2hex($t))-0x8080]); 1517 } 1518 else { 1519 $t=substr($gb,0,1); 1520 $gb=substr($gb,1); 1521 $utf8 .= $this->u2utf8($t); 1522 } 1523 } 1524 return $utf8; 1525 } 1526 1527 function u2utf8($c) { 1528 $str=''; 1529 if ($c < 0x80) { 1530 $str.=$c; 1531 } 1532 else if ($c < 0x800) { 1533 $str.=chr(0xC0 | $c>>6); 1534 $str.=chr(0x80 | $c & 0x3F); 1535 } 1536 else if ($c < 0x10000) { 1537 $str.=chr(0xE0 | $c>>12); 1538 $str.=chr(0x80 | $c>>6 & 0x3F); 1539 $str.=chr(0x80 | $c & 0x3F); 1540 } 1541 else if ($c < 0x200000) { 1542 $str.=chr(0xF0 | $c>>18); 1543 $str.=chr(0x80 | $c>>12 & 0x3F); 1544 $str.=chr(0x80 | $c>>6 & 0x3F); 1545 $str.=chr(0x80 | $c & 0x3F); 1546 } 1547 return $str; 1510 if( !trim($gb) ) return $gb; 1511 $utf8=''; 1512 while($gb) { 1513 if( ord(substr($gb,0,1)) > 127 ) { 1514 $t=substr($gb,0,2); 1515 $gb=substr($gb,2); 1516 $utf8 .= $this->u2utf8($this->codetable[hexdec(bin2hex($t))-0x8080]); 1517 } 1518 else { 1519 $t=substr($gb,0,1); 1520 $gb=substr($gb,1); 1521 $utf8 .= $this->u2utf8($t); 1522 } 1523 } 1524 return $utf8; 1548 1525 } 1549 1526 1550 } // END Class 1527 function u2utf8($c) { 1528 $str=''; 1529 if ($c < 0x80) { 1530 $str.=$c; 1531 } 1532 else if ($c < 0x800) { 1533 $str.=chr(0xC0 | $c>>6); 1534 $str.=chr(0x80 | $c & 0x3F); 1535 } 1536 else if ($c < 0x10000) { 1537 $str.=chr(0xE0 | $c>>12); 1538 $str.=chr(0x80 | $c>>6 & 0x3F); 1539 $str.=chr(0x80 | $c & 0x3F); 1540 } 1541 else if ($c < 0x200000) { 1542 $str.=chr(0xF0 | $c>>18); 1543 $str.=chr(0x80 | $c>>12 & 0x3F); 1544 $str.=chr(0x80 | $c>>6 & 0x3F); 1545 $str.=chr(0x80 | $c & 0x3F); 1546 } 1547 return $str; 1548 } 1549 1550 } // END Class 1551 1551 1552 1552 ?> -
trunk/client/modules/Elezioni/grafici/jpgraph_gradient.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_GRADIENT.PHP4 // Description:Create a color gradient5 // Created:2003-02-016 // Ver: $Id: jpgraph_gradient.php 1091 2009-01-18 22:57:40Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */3 // File: JPGRAPH_GRADIENT.PHP 4 // Description: Create a color gradient 5 // Created: 2003-02-01 6 // Ver: $Id: jpgraph_gradient.php 1761 2009-08-01 08:31:28Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 // Styles for gradient color fill … … 23 23 define("GRAD_RAISED_PANEL",10); 24 24 define("GRAD_DIAGONAL",11); 25 25 26 26 //=================================================== 27 27 // CLASS Gradient … … 31 31 class Gradient { 32 32 private $img=null, $numcolors=100; 33 //---------------34 // CONSTRUCTOR35 function Gradient(&$img) {36 33 //--------------- 34 // CONSTRUCTOR 35 function __construct(&$img) { 36 $this->img = $img; 37 37 } 38 38 39 39 40 40 function SetNumColors($aNum) { 41 41 $this->numcolors=$aNum; 42 42 } 43 //---------------44 // PUBLIC METHODS 43 //--------------- 44 // PUBLIC METHODS 45 45 // Produce a gradient filled rectangle with a smooth transition between 46 46 // two colors. 47 // ($xl,$yt) 48 // ($xr,$yb) 49 // $from_color 50 // $to_color 51 // $style 47 // ($xl,$yt) Top left corner 48 // ($xr,$yb) Bottom right 49 // $from_color Starting color in gradient 50 // $to_color End color in the gradient 51 // $style Which way is the gradient oriented? 52 52 function FilledRectangle($xl,$yt,$xr,$yb,$from_color,$to_color,$style=1) { 53 switch( $style ) { 54 case GRAD_VER: 55 $steps = ceil(abs($xr-$xl)); 56 $delta = $xr>=$xl ? 1 : -1; 57 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); 58 for( $i=0, $x=$xl; $i < $steps; ++$i ) { 59 $this->img->current_color = $colors[$i]; 60 $this->img->Line($x,$yt,$x,$yb); 61 $x += $delta; 62 } 63 break; 64 65 case GRAD_HOR: 66 $steps = ceil(abs($yb-$yt)); 67 $delta = $yb>=$yt ? 1 : -1; 68 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); 69 for($i=0,$y=$yt; $i < $steps; ++$i) { 70 $this->img->current_color = $colors[$i]; 71 $this->img->Line($xl,$y,$xr,$y); 72 $y += $delta; 73 } 74 break; 75 76 case GRAD_MIDHOR: 77 $steps = ceil(abs($yb-$yt)/2); 78 $delta = $yb >= $yt ? 1 : -1; 79 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); 80 for($y=$yt, $i=0; $i < $steps; ++$i) { 81 $this->img->current_color = $colors[$i]; 82 $this->img->Line($xl,$y,$xr,$y); 83 $y += $delta; 84 } 85 --$i; 86 if( abs($yb-$yt) % 2 == 1 ) --$steps; 87 for($j=0; $j < $steps; ++$j, --$i) { 88 $this->img->current_color = $colors[$i]; 89 $this->img->Line($xl,$y,$xr,$y); 90 $y += $delta; 91 } 92 $this->img->Line($xl,$y,$xr,$y); 93 break; 94 95 case GRAD_MIDVER: 96 $steps = ceil(abs($xr-$xl)/2); 97 $delta = $xr>=$xl ? 1 : -1; 98 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); 99 for($x=$xl, $i=0; $i < $steps; ++$i) { 100 $this->img->current_color = $colors[$i]; 101 $this->img->Line($x,$yb,$x,$yt); 102 $x += $delta; 103 } 104 --$i; 105 if( abs($xr-$xl) % 2 == 1 ) --$steps; 106 for($j=0; $j < $steps; ++$j, --$i) { 107 $this->img->current_color = $colors[$i]; 108 $this->img->Line($x,$yb,$x,$yt); 109 $x += $delta; 110 } 111 $this->img->Line($x,$yb,$x,$yt); 112 break; 113 114 case GRAD_WIDE_MIDVER: 115 $diff = ceil(abs($xr-$xl)); 116 $steps = floor(abs($diff)/3); 117 $firststep = $diff - 2*$steps ; 118 $delta = $xr >= $xl ? 1 : -1; 119 $this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors); 120 for($x=$xl, $i=0; $i < $firststep; ++$i) { 121 $this->img->current_color = $colors[$i]; 122 $this->img->Line($x,$yb,$x,$yt); 123 $x += $delta; 124 } 125 --$i; 126 $this->img->current_color = $colors[$i]; 127 for($j=0; $j< $steps; ++$j) { 128 $this->img->Line($x,$yb,$x,$yt); 129 $x += $delta; 130 } 131 132 for($j=0; $j < $steps; ++$j, --$i) { 133 $this->img->current_color = $colors[$i]; 134 $this->img->Line($x,$yb,$x,$yt); 135 $x += $delta; 136 } 137 break; 138 139 case GRAD_WIDE_MIDHOR: 140 $diff = ceil(abs($yb-$yt)); 141 $steps = floor(abs($diff)/3); 142 $firststep = $diff - 2*$steps ; 143 $delta = $yb >= $yt? 1 : -1; 144 $this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors); 145 for($y=$yt, $i=0; $i < $firststep; ++$i) { 146 $this->img->current_color = $colors[$i]; 147 $this->img->Line($xl,$y,$xr,$y); 148 $y += $delta; 149 } 150 --$i; 151 $this->img->current_color = $colors[$i]; 152 for($j=0; $j < $steps; ++$j) { 153 $this->img->Line($xl,$y,$xr,$y); 154 $y += $delta; 155 } 156 for($j=0; $j < $steps; ++$j, --$i) { 157 $this->img->current_color = $colors[$i]; 158 $this->img->Line($xl,$y,$xr,$y); 159 $y += $delta; 160 } 161 break; 162 163 case GRAD_LEFT_REFLECTION: 164 $steps1 = ceil(0.3*abs($xr-$xl)); 165 $delta = $xr>=$xl ? 1 : -1; 166 167 $from_color = $this->img->rgb->Color($from_color); 168 $adj = 1.4; 169 $m = ($adj-1.0)*(255-min(255,min($from_color[0],min($from_color[1],$from_color[2])))); 170 $from_color2 = array(min(255,$from_color[0]+$m), 171 min(255,$from_color[1]+$m), min(255,$from_color[2]+$m)); 172 173 $this->GetColArray($from_color2,$to_color,$steps1,$colors,$this->numcolors); 174 $n = count($colors); 175 for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) { 176 $this->img->current_color = $colors[$i]; 177 $this->img->Line($x,$yb,$x,$yt); 178 $x += $delta; 179 } 180 $steps2 = max(1,ceil(0.08*abs($xr-$xl))); 181 $this->img->SetColor($to_color); 182 for($j=0; $j< $steps2; ++$j) { 183 $this->img->Line($x,$yb,$x,$yt); 184 $x += $delta; 185 } 186 $steps = abs($xr-$xl)-$steps1-$steps2; 187 $this->GetColArray($to_color,$from_color,$steps,$colors,$this->numcolors); 188 $n = count($colors); 189 for($i=0; $i < $steps && $i < $n; ++$i) { 190 $this->img->current_color = $colors[$i]; 191 $this->img->Line($x,$yb,$x,$yt); 192 $x += $delta; 193 } 194 break; 195 196 case GRAD_RIGHT_REFLECTION: 197 $steps1 = ceil(0.7*abs($xr-$xl)); 198 $delta = $xr>=$xl ? 1 : -1; 199 200 $this->GetColArray($from_color,$to_color,$steps1,$colors,$this->numcolors); 201 $n = count($colors); 202 for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) { 203 $this->img->current_color = $colors[$i]; 204 $this->img->Line($x,$yb,$x,$yt); 205 $x += $delta; 206 } 207 $steps2 = max(1,ceil(0.08*abs($xr-$xl))); 208 $this->img->SetColor($to_color); 209 for($j=0; $j< $steps2; ++$j) { 210 $this->img->Line($x,$yb,$x,$yt); 211 $x += $delta; 212 } 213 214 $from_color = $this->img->rgb->Color($from_color); 215 $adj = 1.4; 216 $m = ($adj-1.0)*(255-min(255,min($from_color[0],min($from_color[1],$from_color[2])))); 217 $from_color = array(min(255,$from_color[0]+$m), 218 min(255,$from_color[1]+$m), min(255,$from_color[2]+$m)); 219 220 $steps = abs($xr-$xl)-$steps1-$steps2; 221 $this->GetColArray($to_color,$from_color,$steps,$colors,$this->numcolors); 222 $n = count($colors); 223 for($i=0; $i < $steps && $i < $n; ++$i) { 224 $this->img->current_color = $colors[$i]; 225 $this->img->Line($x,$yb,$x,$yt); 226 $x += $delta; 227 } 228 break; 229 230 case GRAD_CENTER: 231 $steps = ceil(min(($yb-$yt)+1,($xr-$xl)+1)/2); 232 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); 233 $dx = ($xr-$xl)/2; 234 $dy = ($yb-$yt)/2; 235 $x=$xl;$y=$yt;$x2=$xr;$y2=$yb; 236 $n = count($colors); 237 for($x=$xl, $i=0; $x < $xl+$dx && $y < $yt+$dy && $i < $n; ++$x, ++$y, --$x2, --$y2, ++$i) { 238 $this->img->current_color = $colors[$i]; 239 $this->img->Rectangle($x,$y,$x2,$y2); 240 } 241 $this->img->Line($x,$y,$x2,$y2); 242 break; 243 244 case GRAD_RAISED_PANEL: 245 // right to left 246 $steps1 = $xr-$xl; 247 $delta = $xr>=$xl ? 1 : -1; 248 $this->GetColArray($to_color,$from_color,$steps1,$colors,$this->numcolors); 249 $n = count($colors); 250 for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) { 251 $this->img->current_color = $colors[$i]; 252 $this->img->Line($x,$yb,$x,$yt); 253 $x += $delta; 254 } 255 256 // left to right 257 $xr -= 3; 258 $xl += 3; 259 $yb -= 3; 260 $yt += 3; 261 $steps2 = $xr-$xl; 262 $delta = $xr>=$xl ? 1 : -1; 263 for($x=$xl, $j=$steps2; $j >= 0; --$j) { 264 $this->img->current_color = $colors[$j]; 265 $this->img->Line($x,$yb,$x,$yt); 266 $x += $delta; 267 } 268 break; 269 270 case GRAD_DIAGONAL: 271 // use the longer dimension to determine the required number of steps. 272 // first loop draws from one corner to the mid-diagonal and the second 273 // loop draws from the mid-diagonal to the opposing corner. 274 if($xr-$xl > $yb - $yt) { 275 // width is greater than height -> use x-dimension for steps 276 $steps = $xr-$xl; 277 $delta = $xr>=$xl ? 1 : -1; 278 $this->GetColArray($from_color,$to_color,$steps*2,$colors,$this->numcolors); 279 $n = count($colors); 280 281 for($x=$xl, $i=0; $i < $steps && $i < $n; ++$i) { 282 $this->img->current_color = $colors[$i]; 283 $y = $yt+($i/$steps)*($yb-$yt)*$delta; 284 $this->img->Line($x,$yt,$xl,$y); 285 $x += $delta; 286 } 287 288 for($x=$xl, $i = 0; $i < $steps && $i < $n; ++$i) { 289 $this->img->current_color = $colors[$steps+$i]; 290 $y = $yt+($i/$steps)*($yb-$yt)*$delta; 291 $this->img->Line($x,$yb,$xr,$y); 292 $x += $delta; 293 } 294 } else { 295 // height is greater than width -> use y-dimension for steps 296 $steps = $yb-$yt; 297 $delta = $yb>=$yt ? 1 : -1; 298 $this->GetColArray($from_color,$to_color,$steps*2,$colors,$this->numcolors); 299 $n = count($colors); 300 301 for($y=$yt, $i=0; $i < $steps && $i < $n; ++$i) { 302 $this->img->current_color = $colors[$i]; 303 $x = $xl+($i/$steps)*($xr-$xl)*$delta; 304 $this->img->Line($x,$yt,$xl,$y); 305 $y += $delta; 306 } 307 308 for($y=$yt, $i = 0; $i < $steps && $i < $n; ++$i) { 309 $this->img->current_color = $colors[$steps+$i]; 310 $x = $xl+($i/$steps)*($xr-$xl)*$delta; 311 $this->img->Line($x,$yb,$xr,$y); 312 $x += $delta; 313 } 314 315 } 316 break; 317 318 default: 319 JpGraphError::RaiseL(7001,$style); 320 //("Unknown gradient style (=$style)."); 321 break; 322 } 53 $this->img->SetLineWeight(1); 54 switch( $style ) { 55 case GRAD_VER: 56 $steps = ceil(abs($xr-$xl)+1); 57 $delta = $xr>=$xl ? 1 : -1; 58 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); 59 for( $i=0, $x=$xl; $i < $steps; ++$i ) { 60 $this->img->current_color = $colors[$i]; 61 $this->img->Line($x,$yt,$x,$yb); 62 $x += $delta; 63 } 64 break; 65 66 case GRAD_HOR: 67 $steps = ceil(abs($yb-$yt)+1); 68 $delta = $yb >= $yt ? 1 : -1; 69 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); 70 for($i=0,$y=$yt; $i < $steps; ++$i) { 71 $this->img->current_color = $colors[$i]; 72 $this->img->Line($xl,$y,$xr,$y); 73 $y += $delta; 74 } 75 break; 76 77 case GRAD_MIDHOR: 78 $steps = ceil(abs($yb-$yt)/2); 79 $delta = $yb >= $yt ? 1 : -1; 80 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); 81 for($y=$yt, $i=0; $i < $steps; ++$i) { 82 $this->img->current_color = $colors[$i]; 83 $this->img->Line($xl,$y,$xr,$y); 84 $y += $delta; 85 } 86 --$i; 87 if( abs($yb-$yt) % 2 == 1 ) { 88 --$steps; 89 } 90 for($j=0; $j < $steps; ++$j, --$i) { 91 $this->img->current_color = $colors[$i]; 92 $this->img->Line($xl,$y,$xr,$y); 93 $y += $delta; 94 } 95 $this->img->Line($xl,$y,$xr,$y); 96 break; 97 98 case GRAD_MIDVER: 99 $steps = ceil(abs($xr-$xl)/2); 100 $delta = $xr>=$xl ? 1 : -1; 101 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); 102 for($x=$xl, $i=0; $i < $steps; ++$i) { 103 $this->img->current_color = $colors[$i]; 104 $this->img->Line($x,$yb,$x,$yt); 105 $x += $delta; 106 } 107 --$i; 108 if( abs($xr-$xl) % 2 == 1 ) { 109 --$steps; 110 } 111 for($j=0; $j < $steps; ++$j, --$i) { 112 $this->img->current_color = $colors[$i]; 113 $this->img->Line($x,$yb,$x,$yt); 114 $x += $delta; 115 } 116 $this->img->Line($x,$yb,$x,$yt); 117 break; 118 119 case GRAD_WIDE_MIDVER: 120 $diff = ceil(abs($xr-$xl)); 121 $steps = floor(abs($diff)/3); 122 $firststep = $diff - 2*$steps ; 123 $delta = $xr >= $xl ? 1 : -1; 124 $this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors); 125 for($x=$xl, $i=0; $i < $firststep; ++$i) { 126 $this->img->current_color = $colors[$i]; 127 $this->img->Line($x,$yb,$x,$yt); 128 $x += $delta; 129 } 130 --$i; 131 $this->img->current_color = $colors[$i]; 132 for($j=0; $j< $steps; ++$j) { 133 $this->img->Line($x,$yb,$x,$yt); 134 $x += $delta; 135 } 136 137 for($j=0; $j < $steps; ++$j, --$i) { 138 $this->img->current_color = $colors[$i]; 139 $this->img->Line($x,$yb,$x,$yt); 140 $x += $delta; 141 } 142 break; 143 144 case GRAD_WIDE_MIDHOR: 145 $diff = ceil(abs($yb-$yt)); 146 $steps = floor(abs($diff)/3); 147 $firststep = $diff - 2*$steps ; 148 $delta = $yb >= $yt? 1 : -1; 149 $this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors); 150 for($y=$yt, $i=0; $i < $firststep; ++$i) { 151 $this->img->current_color = $colors[$i]; 152 $this->img->Line($xl,$y,$xr,$y); 153 $y += $delta; 154 } 155 --$i; 156 $this->img->current_color = $colors[$i]; 157 for($j=0; $j < $steps; ++$j) { 158 $this->img->Line($xl,$y,$xr,$y); 159 $y += $delta; 160 } 161 for($j=0; $j < $steps; ++$j, --$i) { 162 $this->img->current_color = $colors[$i]; 163 $this->img->Line($xl,$y,$xr,$y); 164 $y += $delta; 165 } 166 break; 167 168 case GRAD_LEFT_REFLECTION: 169 $steps1 = ceil(0.3*abs($xr-$xl)); 170 $delta = $xr>=$xl ? 1 : -1; 171 172 $from_color = $this->img->rgb->Color($from_color); 173 $adj = 1.4; 174 $m = ($adj-1.0)*(255-min(255,min($from_color[0],min($from_color[1],$from_color[2])))); 175 $from_color2 = array(min(255,$from_color[0]+$m), 176 min(255,$from_color[1]+$m), min(255,$from_color[2]+$m)); 177 178 $this->GetColArray($from_color2,$to_color,$steps1,$colors,$this->numcolors); 179 $n = count($colors); 180 for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) { 181 $this->img->current_color = $colors[$i]; 182 $this->img->Line($x,$yb,$x,$yt); 183 $x += $delta; 184 } 185 $steps2 = max(1,ceil(0.08*abs($xr-$xl))); 186 $this->img->SetColor($to_color); 187 for($j=0; $j< $steps2; ++$j) { 188 $this->img->Line($x,$yb,$x,$yt); 189 $x += $delta; 190 } 191 $steps = abs($xr-$xl)-$steps1-$steps2; 192 $this->GetColArray($to_color,$from_color,$steps,$colors,$this->numcolors); 193 $n = count($colors); 194 for($i=0; $i < $steps && $i < $n; ++$i) { 195 $this->img->current_color = $colors[$i]; 196 $this->img->Line($x,$yb,$x,$yt); 197 $x += $delta; 198 } 199 break; 200 201 case GRAD_RIGHT_REFLECTION: 202 $steps1 = ceil(0.7*abs($xr-$xl)); 203 $delta = $xr>=$xl ? 1 : -1; 204 205 $this->GetColArray($from_color,$to_color,$steps1,$colors,$this->numcolors); 206 $n = count($colors); 207 for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) { 208 $this->img->current_color = $colors[$i]; 209 $this->img->Line($x,$yb,$x,$yt); 210 $x += $delta; 211 } 212 $steps2 = max(1,ceil(0.08*abs($xr-$xl))); 213 $this->img->SetColor($to_color); 214 for($j=0; $j< $steps2; ++$j) { 215 $this->img->Line($x,$yb,$x,$yt); 216 $x += $delta; 217 } 218 219 $from_color = $this->img->rgb->Color($from_color); 220 $adj = 1.4; 221 $m = ($adj-1.0)*(255-min(255,min($from_color[0],min($from_color[1],$from_color[2])))); 222 $from_color = array(min(255,$from_color[0]+$m), 223 min(255,$from_color[1]+$m), min(255,$from_color[2]+$m)); 224 225 $steps = abs($xr-$xl)-$steps1-$steps2; 226 $this->GetColArray($to_color,$from_color,$steps,$colors,$this->numcolors); 227 $n = count($colors); 228 for($i=0; $i < $steps && $i < $n; ++$i) { 229 $this->img->current_color = $colors[$i]; 230 $this->img->Line($x,$yb,$x,$yt); 231 $x += $delta; 232 } 233 break; 234 235 case GRAD_CENTER: 236 $steps = ceil(min(($yb-$yt)+1,($xr-$xl)+1)/2); 237 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); 238 $dx = ($xr-$xl)/2; 239 $dy = ($yb-$yt)/2; 240 $x=$xl;$y=$yt;$x2=$xr;$y2=$yb; 241 $n = count($colors); 242 for($x=$xl, $i=0; $x < $xl+$dx && $y < $yt+$dy && $i < $n; ++$x, ++$y, --$x2, --$y2, ++$i) { 243 $this->img->current_color = $colors[$i]; 244 $this->img->Rectangle($x,$y,$x2,$y2); 245 } 246 $this->img->Line($x,$y,$x2,$y2); 247 break; 248 249 case GRAD_RAISED_PANEL: 250 // right to left 251 $steps1 = $xr-$xl; 252 $delta = $xr>=$xl ? 1 : -1; 253 $this->GetColArray($to_color,$from_color,$steps1,$colors,$this->numcolors); 254 $n = count($colors); 255 for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) { 256 $this->img->current_color = $colors[$i]; 257 $this->img->Line($x,$yb,$x,$yt); 258 $x += $delta; 259 } 260 261 // left to right 262 $xr -= 3; 263 $xl += 3; 264 $yb -= 3; 265 $yt += 3; 266 $steps2 = $xr-$xl; 267 $delta = $xr>=$xl ? 1 : -1; 268 for($x=$xl, $j=$steps2; $j >= 0; --$j) { 269 $this->img->current_color = $colors[$j]; 270 $this->img->Line($x,$yb,$x,$yt); 271 $x += $delta; 272 } 273 break; 274 275 case GRAD_DIAGONAL: 276 // use the longer dimension to determine the required number of steps. 277 // first loop draws from one corner to the mid-diagonal and the second 278 // loop draws from the mid-diagonal to the opposing corner. 279 if($xr-$xl > $yb - $yt) { 280 // width is greater than height -> use x-dimension for steps 281 $steps = $xr-$xl; 282 $delta = $xr>=$xl ? 1 : -1; 283 $this->GetColArray($from_color,$to_color,$steps*2,$colors,$this->numcolors); 284 $n = count($colors); 285 286 for($x=$xl, $i=0; $i < $steps && $i < $n; ++$i) { 287 $this->img->current_color = $colors[$i]; 288 $y = $yt+($i/$steps)*($yb-$yt)*$delta; 289 $this->img->Line($x,$yt,$xl,$y); 290 $x += $delta; 291 } 292 293 for($x=$xl, $i = 0; $i < $steps && $i < $n; ++$i) { 294 $this->img->current_color = $colors[$steps+$i]; 295 $y = $yt+($i/$steps)*($yb-$yt)*$delta; 296 $this->img->Line($x,$yb,$xr,$y); 297 $x += $delta; 298 } 299 } else { 300 // height is greater than width -> use y-dimension for steps 301 $steps = $yb-$yt; 302 $delta = $yb>=$yt ? 1 : -1; 303 $this->GetColArray($from_color,$to_color,$steps*2,$colors,$this->numcolors); 304 $n = count($colors); 305 306 for($y=$yt, $i=0; $i < $steps && $i < $n; ++$i) { 307 $this->img->current_color = $colors[$i]; 308 $x = $xl+($i/$steps)*($xr-$xl)*$delta; 309 $this->img->Line($x,$yt,$xl,$y); 310 $y += $delta; 311 } 312 313 for($y=$yt, $i = 0; $i < $steps && $i < $n; ++$i) { 314 $this->img->current_color = $colors[$steps+$i]; 315 $x = $xl+($i/$steps)*($xr-$xl)*$delta; 316 $this->img->Line($x,$yb,$xr,$y); 317 $x += $delta; 318 } 319 320 } 321 break; 322 323 default: 324 JpGraphError::RaiseL(7001,$style); 325 //("Unknown gradient style (=$style)."); 326 break; 327 } 323 328 } 324 329 … … 329 334 // of a mountain) 330 335 function FilledFlatPolygon($pts,$from_color,$to_color) { 331 if( count($pts) == 0 ) return; 332 333 $maxy=$pts[1]; 334 $miny=$pts[1]; 335 $n = count($pts) ; 336 for( $i=0, $idx=0; $i < $n; $i += 2) { 337 $x = round($pts[$i]); 338 $y = round($pts[$i+1]); 339 $miny = min($miny,$y); 340 $maxy = max($maxy,$y); 341 } 342 343 $colors = array(); 344 $this->GetColArray($from_color,$to_color,abs($maxy-$miny)+1,$colors,$this->numcolors); 345 for($i=$miny, $idx=0; $i <= $maxy; ++$i ) { 346 $colmap[$i] = $colors[$idx++]; 347 } 348 349 $n = count($pts)/2 ; 350 $idx = 0 ; 351 while( $idx < $n-1 ) { 352 $p1 = array(round($pts[$idx*2]),round($pts[$idx*2+1])); 353 $p2 = array(round($pts[++$idx*2]),round($pts[$idx*2+1])); 354 355 // Find the largest rectangle we can fill 356 $y = max($p1[1],$p2[1]) ; 357 for($yy=$maxy; $yy > $y; --$yy) { 358 $this->img->current_color = $colmap[$yy]; 359 $this->img->Line($p1[0],$yy,$p2[0]-1,$yy); 360 } 361 362 if( $p1[1] == $p2[1] ) continue; 363 364 // Fill the rest using lines (slow...) 365 $slope = ($p2[0]-$p1[0])/($p1[1]-$p2[1]); 366 $x1 = $p1[0]; 367 $x2 = $p2[0]-1; 368 $start = $y; 369 if( $p1[1] > $p2[1] ) { 370 while( $y >= $p2[1] ) { 371 $x1=$slope*($start-$y)+$p1[0]; 372 $this->img->current_color = $colmap[$y]; 373 $this->img->Line($x1,$y,$x2,$y); 374 --$y; 375 } 376 } 377 else { 378 while( $y >= $p1[1] ) { 379 $x2=$p2[0]+$slope*($start-$y); 380 $this->img->current_color = $colmap[$y]; 381 $this->img->Line($x1,$y,$x2,$y); 382 --$y; 383 } 384 } 385 } 336 if( count($pts) == 0 ) return; 337 338 $maxy=$pts[1]; 339 $miny=$pts[1]; 340 $n = count($pts) ; 341 for( $i=0, $idx=0; $i < $n; $i += 2) { 342 $x = round($pts[$i]); 343 $y = round($pts[$i+1]); 344 $miny = min($miny,$y); 345 $maxy = max($maxy,$y); 346 } 347 348 $colors = array(); 349 $this->GetColArray($from_color,$to_color,abs($maxy-$miny)+1,$colors,$this->numcolors); 350 for($i=$miny, $idx=0; $i <= $maxy; ++$i ) { 351 $colmap[$i] = $colors[$idx++]; 352 } 353 354 $n = count($pts)/2 ; 355 $idx = 0 ; 356 while( $idx < $n-1 ) { 357 $p1 = array(round($pts[$idx*2]),round($pts[$idx*2+1])); 358 $p2 = array(round($pts[++$idx*2]),round($pts[$idx*2+1])); 359 360 // Find the largest rectangle we can fill 361 $y = max($p1[1],$p2[1]) ; 362 for($yy=$maxy; $yy > $y; --$yy) { 363 $this->img->current_color = $colmap[$yy]; 364 $this->img->Line($p1[0],$yy,$p2[0]-1,$yy); 365 } 366 367 if( $p1[1] == $p2[1] ) { 368 continue; 369 } 370 371 // Fill the rest using lines (slow...) 372 $slope = ($p2[0]-$p1[0])/($p1[1]-$p2[1]); 373 $x1 = $p1[0]; 374 $x2 = $p2[0]-1; 375 $start = $y; 376 if( $p1[1] > $p2[1] ) { 377 while( $y >= $p2[1] ) { 378 $x1=$slope*($start-$y)+$p1[0]; 379 $this->img->current_color = $colmap[$y]; 380 $this->img->Line($x1,$y,$x2,$y); 381 --$y; 382 } 383 } 384 else { 385 while( $y >= $p1[1] ) { 386 $x2=$p2[0]+$slope*($start-$y); 387 $this->img->current_color = $colmap[$y]; 388 $this->img->Line($x1,$y,$x2,$y); 389 --$y; 390 } 391 } 392 } 386 393 } 387 394 388 //---------------389 // PRIVATE METHODS 395 //--------------- 396 // PRIVATE METHODS 390 397 // Add to the image color map the necessary colors to do the transition 391 398 // between the two colors using $numcolors intermediate colors 392 399 function GetColArray($from_color,$to_color,$arr_size,&$colors,$numcols=100) { 393 if( $arr_size==0 ) return; 394 // If color is given as text get it's corresponding r,g,b values 395 $from_color = $this->img->rgb->Color($from_color); 396 $to_color = $this->img->rgb->Color($to_color); 397 398 $rdelta=($to_color[0]-$from_color[0])/$numcols; 399 $gdelta=($to_color[1]-$from_color[1])/$numcols; 400 $bdelta=($to_color[2]-$from_color[2])/$numcols; 401 $colorsperstep = $numcols/$arr_size; 402 $prevcolnum = -1; 403 $from_alpha = $from_color[3]; 404 $to_alpha = $to_color[3]; 405 $adelta = ( $to_alpha - $from_alpha ) / $numcols ; 406 for ($i=0; $i < $arr_size; ++$i) { 407 $colnum = floor($colorsperstep*$i); 408 if ( $colnum == $prevcolnum ) 409 $colors[$i] = $colidx; 410 else { 411 $r = floor($from_color[0] + $colnum*$rdelta); 412 $g = floor($from_color[1] + $colnum*$gdelta); 413 $b = floor($from_color[2] + $colnum*$bdelta); 414 $alpha = $from_alpha + $colnum*$adelta; 415 $colidx = $this->img->rgb->Allocate(sprintf("#%02x%02x%02x",$r,$g,$b),$alpha); 416 $colors[$i] = $colidx; 417 } 418 $prevcolnum = $colnum; 419 } 420 } 400 if( $arr_size==0 ) { 401 return; 402 } 403 404 // If color is given as text get it's corresponding r,g,b values 405 $from_color = $this->img->rgb->Color($from_color); 406 $to_color = $this->img->rgb->Color($to_color); 407 408 $rdelta=($to_color[0]-$from_color[0])/$numcols; 409 $gdelta=($to_color[1]-$from_color[1])/$numcols; 410 $bdelta=($to_color[2]-$from_color[2])/$numcols; 411 $colorsperstep = $numcols/$arr_size; 412 $prevcolnum = -1; 413 $from_alpha = floatval($from_color[3]); 414 $to_alpha = floatval($to_color[3]); 415 $adelta = ( $to_alpha - $from_alpha ) / $numcols ; 416 for ($i=0; $i < $arr_size; ++$i) { 417 $colnum = floor($colorsperstep*$i); 418 if ( $colnum == $prevcolnum ) { 419 $colors[$i] = $colidx; 420 } 421 else { 422 $r = floor($from_color[0] + $colnum*$rdelta); 423 $g = floor($from_color[1] + $colnum*$gdelta); 424 $b = floor($from_color[2] + $colnum*$bdelta); 425 $alpha = $from_alpha + $colnum*$adelta; 426 $colidx = $this->img->rgb->Allocate(sprintf("#%02x%02x%02x",$r,$g,$b),$alpha); 427 $colors[$i] = $colidx; 428 } 429 $prevcolnum = $colnum; 430 } 431 } 421 432 } // Class 422 433 -
trunk/client/modules/Elezioni/grafici/jpgraph_iconplot.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: PHP4 Graph Plotting library. Extension module.5 // Created: 6 // Ver: $Id: jpgraph_iconplot.php 781 2006-10-08 08:07:47Z ljp $3 // File: JPGRAPH_ICONPLOT.PHP 4 // Description: Extension module to add icons to plots 5 // Created: 2004-02-18 6 // Ver: $Id: jpgraph_iconplot.php 1404 2009-06-28 15:25:41Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 … … 25 25 26 26 27 function IconPlot($aFile="",$aX=0,$aY=0,$aScale=1.0,$aMix=100) {28 29 30 31 32 33 34 35 27 function __construct($aFile="",$aX=0,$aY=0,$aScale=1.0,$aMix=100) { 28 $this->iFile = $aFile; 29 $this->iX=$aX; 30 $this->iY=$aY; 31 $this->iScale= $aScale; 32 if( $aMix < 0 || $aMix > 100 ) { 33 JpGraphError::RaiseL(8001); //('Mix value for icon must be between 0 and 100.'); 34 } 35 $this->iMix = $aMix ; 36 36 } 37 37 38 38 function SetCountryFlag($aFlag,$aX=0,$aY=0,$aScale=1.0,$aMix=100,$aStdSize=3) { 39 40 41 42 43 44 45 46 47 39 $this->iCountryFlag = $aFlag; 40 $this->iX=$aX; 41 $this->iY=$aY; 42 $this->iScale= $aScale; 43 if( $aMix < 0 || $aMix > 100 ) { 44 JpGraphError::RaiseL(8001);//'Mix value for icon must be between 0 and 100.'); 45 } 46 $this->iMix = $aMix; 47 $this->iCountryStdSize = $aStdSize; 48 48 } 49 49 50 50 function SetPos($aX,$aY) { 51 52 51 $this->iX=$aX; 52 $this->iY=$aY; 53 53 } 54 54 55 55 function CreateFromString($aStr) { 56 56 $this->iImgString = $aStr; 57 57 } 58 58 59 59 function SetScalePos($aX,$aY) { 60 61 60 $this->iScalePosX = $aX; 61 $this->iScalePosY = $aY; 62 62 } 63 63 64 64 function SetScale($aScale) { 65 65 $this->iScale = $aScale; 66 66 } 67 67 68 68 function SetMix($aMix) { 69 70 71 72 69 if( $aMix < 0 || $aMix > 100 ) { 70 JpGraphError::RaiseL(8001);//('Mix value for icon must be between 0 and 100.'); 71 } 72 $this->iMix = $aMix ; 73 73 } 74 74 75 75 function SetAnchor($aXAnchor='left',$aYAnchor='center') { 76 77 78 79 80 81 76 if( !in_array($aXAnchor,$this->iAnchors) || 77 !in_array($aYAnchor,$this->iAnchors) ) { 78 JpGraphError::RaiseL(8002);//("Anchor position for icons must be one of 'top', 'bottom', 'left', 'right' or 'center'"); 79 } 80 $this->iHorAnchor=$aXAnchor; 81 $this->iVertAnchor=$aYAnchor; 82 82 } 83 83 84 84 function PreStrokeAdjust($aGraph) { 85 85 // Nothing to do ... 86 86 } 87 87 88 88 function DoLegend($aGraph) { 89 89 // Nothing to do ... 90 90 } 91 91 92 92 function Max() { 93 93 return array(false,false); 94 94 } 95 95 … … 105 105 106 106 function Min() { 107 107 return array(false,false); 108 108 } 109 109 110 110 function StrokeMargin(&$aImg) { 111 111 return true; 112 112 } 113 113 114 function Stroke($aImg,$axscale ,$ayscale) {115 114 function Stroke($aImg,$axscale=null,$ayscale=null) { 115 $this->StrokeWithScale($aImg,$axscale,$ayscale); 116 116 } 117 117 118 118 function StrokeWithScale($aImg,$axscale,$ayscale) { 119 if( $this->iScalePosX=== null ||120 $this->iScalePosY=== null ) {121 122 123 124 125 126 127 119 if( $this->iScalePosX === null || $this->iScalePosY === null || 120 $axscale === null || $ayscale === null ) { 121 $this->_Stroke($aImg); 122 } 123 else { 124 $this->_Stroke($aImg, 125 round($axscale->Translate($this->iScalePosX)), 126 round($ayscale->Translate($this->iScalePosY))); 127 } 128 128 } 129 129 130 130 function GetWidthHeight() { 131 132 131 $dummy=0; 132 return $this->_Stroke($dummy,null,null,true); 133 133 } 134 134 135 135 function _Stroke($aImg,$x=null,$y=null,$aReturnWidthHeight=false) { 136 137 JpGraphError::RaiseL(8003);//('It is not possible to specify both an image file and a country flag for the same icon.'); 138 139 140 141 142 143 144 136 if( $this->iFile != '' && $this->iCountryFlag != '' ) { 137 JpGraphError::RaiseL(8003);//('It is not possible to specify both an image file and a country flag for the same icon.'); 138 } 139 if( $this->iFile != '' ) { 140 $gdimg = Graph::LoadBkgImage('',$this->iFile); 141 } 142 elseif( $this->iImgString != '') { 143 $gdimg = Image::CreateFromString($this->iImgString); 144 } 145 145 146 147 148 149 150 151 152 153 146 else { 147 if( ! class_exists('FlagImages',false) ) { 148 JpGraphError::RaiseL(8004);//('In order to use Country flags as icons you must include the "jpgraph_flags.php" file.'); 149 } 150 $fobj = new FlagImages($this->iCountryStdSize); 151 $dummy=''; 152 $gdimg = $fobj->GetImgByName($this->iCountryFlag,$dummy); 153 } 154 154 155 $iconw = imagesx($gdimg); 156 $iconh = imagesy($gdimg); 157 158 if( $aReturnWidthHeight ) { 159 return array(round($iconw*$this->iScale),round($iconh*$this->iScale)); 160 } 155 $iconw = imagesx($gdimg); 156 $iconh = imagesy($gdimg); 161 157 162 if( $x !== null && $y !== null ) { 163 $this->iX = $x; $this->iY = $y; 164 } 165 if( $this->iX >= 0 && $this->iX <= 1.0 ) { 166 $w = imagesx($aImg->img); 167 $this->iX = round($w*$this->iX); 168 } 169 if( $this->iY >= 0 && $this->iY <= 1.0 ) { 170 $h = imagesy($aImg->img); 171 $this->iY = round($h*$this->iY); 172 } 158 if( $aReturnWidthHeight ) { 159 return array(round($iconw*$this->iScale),round($iconh*$this->iScale)); 160 } 173 161 174 if( $this->iHorAnchor == 'center' ) 175 $this->iX -= round($iconw*$this->iScale/2); 176 if( $this->iHorAnchor == 'right' ) 177 $this->iX -= round($iconw*$this->iScale); 178 if( $this->iVertAnchor == 'center' ) 179 $this->iY -= round($iconh*$this->iScale/2); 180 if( $this->iVertAnchor == 'bottom' ) 181 $this->iY -= round($iconh*$this->iScale); 162 if( $x !== null && $y !== null ) { 163 $this->iX = $x; $this->iY = $y; 164 } 165 if( $this->iX >= 0 && $this->iX <= 1.0 ) { 166 $w = imagesx($aImg->img); 167 $this->iX = round($w*$this->iX); 168 } 169 if( $this->iY >= 0 && $this->iY <= 1.0 ) { 170 $h = imagesy($aImg->img); 171 $this->iY = round($h*$this->iY); 172 } 182 173 183 $aImg->CopyMerge($gdimg,$this->iX,$this->iY,0,0, 184 round($iconw*$this->iScale),round($iconh*$this->iScale), 185 $iconw,$iconh, 186 $this->iMix); 174 if( $this->iHorAnchor == 'center' ) 175 $this->iX -= round($iconw*$this->iScale/2); 176 if( $this->iHorAnchor == 'right' ) 177 $this->iX -= round($iconw*$this->iScale); 178 if( $this->iVertAnchor == 'center' ) 179 $this->iY -= round($iconh*$this->iScale/2); 180 if( $this->iVertAnchor == 'bottom' ) 181 $this->iY -= round($iconh*$this->iScale); 182 183 $aImg->CopyMerge($gdimg,$this->iX,$this->iY,0,0, 184 round($iconw*$this->iScale),round($iconh*$this->iScale), 185 $iconw,$iconh, 186 $this->iMix); 187 187 } 188 188 } -
trunk/client/modules/Elezioni/grafici/jpgraph_imgtrans.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph_imgtrans.php 781 2006-10-08 08:07:47Z ljp $3 // File: JPGRAPH_IMGTRANS.PHP 4 // Description: Extension for JpGraph to do some simple img transformations 5 // Created: 2003-09-06 6 // Ver: $Id: jpgraph_imgtrans.php 1106 2009-02-22 20:16:35Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 11 11 //------------------------------------------------------------------------ 12 12 // Class ImgTrans 13 // Perform some simple image transformations. 13 // Perform some simple image transformations. 14 14 //------------------------------------------------------------------------ 15 15 class ImgTrans { 16 16 private $gdImg=null; 17 17 18 function ImgTrans($aGdImg) {19 20 21 } 22 23 // -------------------------------------------------------------------- 24 // _TransVert3D() and _TransHor3D() are helper methods to 25 // Skew3D(). 18 function __construct($aGdImg) { 19 // Constructor 20 $this->gdImg = $aGdImg; 21 } 22 23 // -------------------------------------------------------------------- 24 // _TransVert3D() and _TransHor3D() are helper methods to 25 // Skew3D(). 26 26 // -------------------------------------------------------------------- 27 27 function _TransVert3D($aGdImg,$aHorizon=100,$aSkewDist=120,$aDir=SKEW3D_DOWN,$aMinSize=true,$aFillColor='#FFFFFF',$aQuality=false,$aBorder=false,$aHorizonPos=0.5) { 28 28 29 29 30 31 32 33 //("Value for image transformation out of bounds.\nVanishing point on horizon must be specified as a value between 0 and 1.");34 35 36 37 38 39 40 41 if( $aMinSize ) 42 43 else 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 for($y=0; $y < $h; ++$y) { 60 61 62 $yt = floor($yp * $aHorizon / ($aSkewDist + $yp)); 63 64 65 66 67 68 69 for($x=0; $x < $w; ++$x) { 70 71 if( $aDir == SKEW3D_UP ) 72 73 74 75 76 77 $b = $rgb & 0xFF; 78 $colidx = imagecolorallocate($newgdh,$r,$g,$b); 79 80 81 82 83 84 85 86 87 88 89 90 91 $nb = $nrgb & 0xFF; 92 93 floor(($g+$ng)/2),floor(($b+$nb)/2)); 94 } 95 96 imagesetpixel($newgdh,$xt,$syt,$colidx); 97 98 99 $set[$yt] = true; 100 101 102 103 } 104 105 // -------------------------------------------------------------------- 106 // _TransVert3D() and _TransHor3D() are helper methods to 107 // Skew3D(). 30 // Parameter check 31 if( $aHorizonPos < 0 || $aHorizonPos > 1.0 ) { 32 JpGraphError::RaiseL(9001); 33 //("Value for image transformation out of bounds.\nVanishing point on horizon must be specified as a value between 0 and 1."); 34 } 35 36 $w = imagesx($aGdImg); 37 $h = imagesy($aGdImg); 38 39 // Create new image 40 $ww = $w; 41 if( $aMinSize ) 42 $hh = ceil($h * $aHorizon / ($aSkewDist+$h)); 43 else 44 $hh = $h; 45 46 $newgdh = imagecreatetruecolor($ww,$hh); 47 $crgb = new RGB( $newgdh ); 48 $fillColor = $crgb->Allocate($aFillColor); 49 imagefilledrectangle($newgdh,0,0,$ww-1,$hh-1,$fillColor); 50 51 if( $aBorder ) { 52 $colidx = $crgb->Allocate($aBorder); 53 imagerectangle($newgdh,0,0,$ww-1,$hh-1,$colidx); 54 } 55 56 $mid = round($w * $aHorizonPos); 57 58 $last=$h; 59 for($y=0; $y < $h; ++$y) { 60 61 $yp = $h-$y-1; 62 $yt = floor($yp * $aHorizon / ($aSkewDist + $yp)); 63 64 if( !$aQuality ) { 65 if( $last <= $yt ) continue ; 66 $last = $yt; 67 } 68 69 for($x=0; $x < $w; ++$x) { 70 $xt = ($x-$mid) * $aSkewDist / ($aSkewDist + $yp); 71 if( $aDir == SKEW3D_UP ) 72 $rgb = imagecolorat($aGdImg,$x,$h-$y-1); 73 else 74 $rgb = imagecolorat($aGdImg,$x,$y); 75 $r = ($rgb >> 16) & 0xFF; 76 $g = ($rgb >> 8) & 0xFF; 77 $b = $rgb & 0xFF; 78 $colidx = imagecolorallocate($newgdh,$r,$g,$b); 79 $xt = round($xt+$mid); 80 if( $aDir == SKEW3D_UP ) { 81 $syt = $yt; 82 } 83 else { 84 $syt = $hh-$yt-1; 85 } 86 87 if( !empty($set[$yt]) ) { 88 $nrgb = imagecolorat($newgdh,$xt,$syt); 89 $nr = ($nrgb >> 16) & 0xFF; 90 $ng = ($nrgb >> 8) & 0xFF; 91 $nb = $nrgb & 0xFF; 92 $colidx = imagecolorallocate($newgdh,floor(($r+$nr)/2), 93 floor(($g+$ng)/2),floor(($b+$nb)/2)); 94 } 95 96 imagesetpixel($newgdh,$xt,$syt,$colidx); 97 } 98 99 $set[$yt] = true; 100 } 101 102 return $newgdh; 103 } 104 105 // -------------------------------------------------------------------- 106 // _TransVert3D() and _TransHor3D() are helper methods to 107 // Skew3D(). 108 108 // -------------------------------------------------------------------- 109 109 function _TransHor3D($aGdImg,$aHorizon=100,$aSkewDist=120,$aDir=SKEW3D_LEFT,$aMinSize=true,$aFillColor='#FFFFFF',$aQuality=false,$aBorder=false,$aHorizonPos=0.5) { 110 110 111 112 113 114 115 116 if( $aMinSize ) 117 118 else 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 $last = -1; 134 for($x=0; $x < $w-1; ++$x) { 135 136 137 138 139 140 141 for($y=0; $y < $h; ++$y) { 142 143 144 145 if( $aDir == SKEW3D_RIGHT ) 146 147 148 149 150 151 $b = $rgb & 0xFF; 152 $colidx = imagecolorallocate($newgdh,$r,$g,$b); 153 154 155 156 157 158 159 160 161 162 163 164 $nb = $nrgb & 0xFF; 165 166 floor(($g+$ng)/2),floor(($b+$nb)/2)); 167 168 imagesetpixel($newgdh,$sxt,$yt,$colidx); 169 170 171 172 173 174 111 $w = imagesx($aGdImg); 112 $h = imagesy($aGdImg); 113 114 // Create new image 115 $hh = $h; 116 if( $aMinSize ) 117 $ww = ceil($w * $aHorizon / ($aSkewDist+$w)); 118 else 119 $ww = $w; 120 121 $newgdh = imagecreatetruecolor($ww,$hh); 122 $crgb = new RGB( $newgdh ); 123 $fillColor = $crgb->Allocate($aFillColor); 124 imagefilledrectangle($newgdh,0,0,$ww-1,$hh-1,$fillColor); 125 126 if( $aBorder ) { 127 $colidx = $crgb->Allocate($aBorder); 128 imagerectangle($newgdh,0,0,$ww-1,$hh-1,$colidx); 129 } 130 131 $mid = round($h * $aHorizonPos); 132 133 $last = -1; 134 for($x=0; $x < $w-1; ++$x) { 135 $xt = floor($x * $aHorizon / ($aSkewDist + $x)); 136 if( !$aQuality ) { 137 if( $last >= $xt ) continue ; 138 $last = $xt; 139 } 140 141 for($y=0; $y < $h; ++$y) { 142 $yp = $h-$y-1; 143 $yt = ($yp-$mid) * $aSkewDist / ($aSkewDist + $x); 144 145 if( $aDir == SKEW3D_RIGHT ) 146 $rgb = imagecolorat($aGdImg,$w-$x-1,$y); 147 else 148 $rgb = imagecolorat($aGdImg,$x,$y); 149 $r = ($rgb >> 16) & 0xFF; 150 $g = ($rgb >> 8) & 0xFF; 151 $b = $rgb & 0xFF; 152 $colidx = imagecolorallocate($newgdh,$r,$g,$b); 153 $yt = floor($hh-$yt-$mid-1); 154 if( $aDir == SKEW3D_RIGHT ) { 155 $sxt = $ww-$xt-1; 156 } 157 else 158 $sxt = $xt ; 159 160 if( !empty($set[$xt]) ) { 161 $nrgb = imagecolorat($newgdh,$sxt,$yt); 162 $nr = ($nrgb >> 16) & 0xFF; 163 $ng = ($nrgb >> 8) & 0xFF; 164 $nb = $nrgb & 0xFF; 165 $colidx = imagecolorallocate($newgdh,floor(($r+$nr)/2), 166 floor(($g+$ng)/2),floor(($b+$nb)/2)); 167 } 168 imagesetpixel($newgdh,$sxt,$yt,$colidx); 169 } 170 171 $set[$xt] = true; 172 } 173 174 return $newgdh; 175 175 } 176 176 … … 180 180 // of the image. The transformation is specified by giving the height 181 181 // of the artificial horizon and specifying a "skew" factor which 182 // is the distance on the horizon line between the point of 182 // is the distance on the horizon line between the point of 183 183 // convergence and perspective line. 184 184 // … … 188 188 // Parameters: 189 189 // * $aGdImg, GD handle to the image to be transformed 190 // * $aHorizon, Distance to the horizon 190 // * $aHorizon, Distance to the horizon 191 191 // * $aSkewDist, Distance from the horizon point of convergence 192 // on the horizon line to the perspective points. A larger 192 // on the horizon line to the perspective points. A larger 193 193 // value will fore-shorten the image more 194 // * $aDir, parameter specifies type of convergence. This of this 194 // * $aDir, parameter specifies type of convergence. This of this 195 195 // as the walls in a room you are looking at. This specifies if the 196 196 // image should be applied on the left,right,top or bottom walls. … … 202 202 // high quality will have a dramatic effect on the time it takes 203 203 // to transform an image. 204 // * $aBorder, if set to anything besides false this will draw a 204 // * $aBorder, if set to anything besides false this will draw a 205 205 // a border of the speciied color around the image 206 206 // -------------------------------------------------------------------- 207 207 function Skew3D($aHorizon=120,$aSkewDist=150,$aDir=SKEW3D_DOWN,$aHiQuality=false,$aMinSize=true,$aFillColor='#FFFFFF',$aBorder=false) { 208 209 208 return $this->_Skew3D($this->gdImg,$aHorizon,$aSkewDist,$aDir,$aHiQuality, 209 $aMinSize,$aFillColor,$aBorder); 210 210 } 211 211 212 212 function _Skew3D($aGdImg,$aHorizon=120,$aSkewDist=150,$aDir=SKEW3D_DOWN,$aHiQuality=false,$aMinSize=true,$aFillColor='#FFFFFF',$aBorder=false) { 213 214 215 216 217 218 } 219 213 if( $aDir == SKEW3D_DOWN || $aDir == SKEW3D_UP ) 214 return $this->_TransVert3D($aGdImg,$aHorizon,$aSkewDist,$aDir,$aMinSize,$aFillColor,$aHiQuality,$aBorder); 215 else 216 return $this->_TransHor3D($aGdImg,$aHorizon,$aSkewDist,$aDir,$aMinSize,$aFillColor,$aHiQuality,$aBorder); 217 218 } 219 220 220 } 221 221 -
trunk/client/modules/Elezioni/grafici/jpgraph_led.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph_led.php 1091 2009-01-18 22:57:40Z ljp $3 // File: JPGRAPH_LED.PHP 4 // Description: Module to generate Dotted LED-like digits 5 // Created: 2006-11-26 6 // Ver: $Id: jpgraph_led.php 1674 2009-07-22 19:42:23Z ljp $ 7 7 // 8 // Copyright 2006 (c) A ditus Consulting. All rights reserved.8 // Copyright 2006 (c) Asial Corporation. All rights reserved. 9 9 // 10 10 // Changed: 2007-08-06 by Alexander Kurochkin (inspector@list.ru) 11 // Added: Decipher 4-bit mask.12 // Added: Chars Latin > 'L', Cyrilic, other symbols and special symbols for13 // simulation some latin and cyrilic chars.14 // Added: New Color schemas.15 // Deleted: Some minor bugs (StrokeNumber first parameter may be eq empty string,16 // false or null - added check see line 294;17 // change color schema check for easy maintenance: 291;18 // change check on key exist in chars array: moved from StrokeNumber19 // function to _GetLED: 251;20 //21 11 //======================================================================== 22 12 23 // Samples for troubled chars: "Ô¡ Ø\r Ù\r Û| ÞÎ Ì\r >\n< W\r" 24 // Ô Ø Ù Û Þ Ì Æ W 25 26 //---------------------------------------------------------------------------- 27 // Each character is encoded line by line with the "On"-LEDs corresponding to 28 // a '1' in the bianry mask of 4 bits. 29 // 30 // 4-bit mask: 31 // 32 // 0 ____ 33 // 1 ___x 34 // 2 __x_ 35 // 3 __xx 36 // 4 _x__ 37 // 5 _x_x 38 // 6 _xx_ 39 // 7 _xxx 40 // 8 x___ 41 // 9 x__x 42 // 10 x_x_ 43 // 11 x_xx 44 // 12 xx__ 45 // 13 xx_x 46 // 14 xxx_ 47 // 15 xxxx 48 //---------------------------------------------------------------------------- 49 50 // Constants for color schema. See definition of iColorSchema below 51 define('LEDC_RED', 0); 52 define('LEDC_GREEN', 1); 53 define('LEDC_BLUE', 2); 54 define('LEDC_YELLOW', 3); 55 define('LEDC_GRAY', 4); 56 define('LEDC_CHOCOLATE', 5); 57 define('LEDC_PERU', 6); 58 define('LEDC_GOLDENROD', 7); 59 define('LEDC_KHAKI', 8); 60 define('LEDC_OLIVE', 9); 61 define('LEDC_LIMEGREEN', 10); 62 define('LEDC_FORESTGREEN', 11); 63 define('LEDC_TEAL', 12); 64 define('LEDC_STEELBLUE', 13); 65 define('LEDC_NAVY', 14); 66 define('LEDC_INVERTGRAY', 15); 67 // ! It correlate with two-dimensional array $iColorSchema 13 // Constants for color schema 14 DEFINE('LEDC_RED', 0); 15 DEFINE('LEDC_GREEN', 1); 16 DEFINE('LEDC_BLUE', 2); 17 DEFINE('LEDC_YELLOW', 3); 18 DEFINE('LEDC_GRAY', 4); 19 DEFINE('LEDC_CHOCOLATE', 5); 20 DEFINE('LEDC_PERU', 6); 21 DEFINE('LEDC_GOLDENROD', 7); 22 DEFINE('LEDC_KHAKI', 8); 23 DEFINE('LEDC_OLIVE', 9); 24 DEFINE('LEDC_LIMEGREEN', 10); 25 DEFINE('LEDC_FORESTGREEN', 11); 26 DEFINE('LEDC_TEAL', 12); 27 DEFINE('LEDC_STEELBLUE', 13); 28 DEFINE('LEDC_NAVY', 14); 29 DEFINE('LEDC_INVERTGRAY', 15); 30 31 // Check that mb_strlen() is available 32 if( ! function_exists('mb_strlen') ) { 33 JpGraphError::RaiseL(25500); 34 //'Multibyte strings must be enabled in the PHP installation in order to run the LED module 35 // so that the function mb_strlen() is available. See PHP documentation for more information.' 36 } 68 37 69 38 //======================================================================== 70 39 // CLASS DigitalLED74 71 // Description: 40 // Description: 72 41 // Construct a number as an image that looks like LED numbers in a 73 42 // 7x4 digital matrix … … 77 46 private $iLED_X = 4, $iLED_Y=7, 78 47 79 // fg-up, fg-down, bg 80 $iColorSchema = array( 81 LEDC_RED => array('red','darkred:0.9','red:0.3'),// 0 82 LEDC_GREEN => array('green','darkgreen','green:0.3'),// 1 83 LEDC_BLUE => array('lightblue:0.9','darkblue:0.85','darkblue:0.7'),// 2 84 LEDC_YELLOW => array('yellow','yellow:0.4','yellow:0.3'),// 3 85 LEDC_GRAY => array('gray:1.4','darkgray:0.85','darkgray:0.7'), 86 LEDC_CHOCOLATE => array('chocolate','chocolate:0.7','chocolate:0.5'), 87 LEDC_PERU => array('peru:0.95','peru:0.6','peru:0.5'), 88 LEDC_GOLDENROD => array('goldenrod','goldenrod:0.6','goldenrod:0.5'), 89 LEDC_KHAKI => array('khaki:0.7','khaki:0.4','khaki:0.3'), 90 LEDC_OLIVE => array('#808000','#808000:0.7','#808000:0.6'), 91 LEDC_LIMEGREEN => array('limegreen:0.9','limegreen:0.5','limegreen:0.4'), 92 LEDC_FORESTGREEN => array('forestgreen','forestgreen:0.7','forestgreen:0.5'), 93 LEDC_TEAL => array('teal','teal:0.7','teal:0.5'), 94 LEDC_STEELBLUE => array('steelblue','steelblue:0.65','steelblue:0.5'), 95 LEDC_NAVY => array('navy:1.3','navy:0.95','navy:0.8'),//14 96 LEDC_INVERTGRAY => array('darkgray','lightgray:1.5','white')//15 97 ), 98 99 $iLEDSpec = array( 100 0 => array(6,9,11,15,13,9,6), 101 //0 => array(6,9,9,9,9,9,6), 102 //0 => array(15,9,9,9,9,9,15), 103 1 => array(2,6,10,2,2,2,2), 104 2 => array(6,9,1,2,4,8,15), 105 3 => array(6,9,1,6,1,9,6), 106 4 => array(1,3,5,9,15,1,1), 107 5 => array(15,8,8,14,1,9,6), 108 6 => array(6,8,8,14,9,9,6), 109 7 => array(15,1,1,2,4,4,4), 110 8 => array(6,9,9,6,9,9,6), 111 9 => array(6,9,9,7,1,1,6), 112 '!' => array(4,4,4,4,4,0,4), 113 '?' => array(6,9,1,2,2,0,2), 114 '#' => array(0,9,15,9,15,9,0), 115 '@' => array(6,9,11,11,10,9,6), 116 '-' => array(0,0,0,15,0,0,0), 117 '_' => array(0,0,0,0,0,0,15), 118 '=' => array(0,0,15,0,15,0,0), 119 '+' => array(0,0,4,14,4,0,0), 120 '|' => array(4,4,4,4,4,4,4), //vertical line, used for simulate rus 'Û' 121 ',' => array(0,0,0,0,0,12,4), 122 '.' => array(0,0,0,0,0,12,12), 123 ':' => array(12,12,0,0,0,12,12), 124 ';' => array(12,12,0,0,0,12,4), 125 '[' => array(3,2,2,2,2,2,3), 126 ']' => array(12,4,4,4,4,4,12), 127 '(' => array(1,2,2,2,2,2,1), 128 ')' => array(8,4,4,4,4,4,8), 129 '{' => array(3,2,2,6,2,2,3), 130 '}' => array(12,4,4,6,4,4,12), 131 '<' => array(1,2,4,8,4,2,1), 132 '>' => array(8,4,2,1,2,4,8), 133 '*' => array(9,6,15,6,9,0,0), 134 '"' => array(10,10,0,0,0,0,0), 135 '\'' => array(4,4,0,0,0,0,0), 136 '`' => array(4,2,0,0,0,0,0), 137 '~' => array(13,11,0,0,0,0,0), 138 '^' => array(4,10,0,0,0,0,0), 139 '\\' => array(8,8,4,6,2,1,1), 140 '/' => array(1,1,2,6,4,8,8), 141 '%' => array(1,9,2,6,4,9,8), 142 '&' => array(0,4,10,4,11,10,5), 143 '$' => array(2,7,8,6,1,14,4), 144 ' ' => array(0,0,0,0,0,0,0), 145 '' => array(0,0,6,6,0,0,0), //149 146 '°' => array(14,10,14,0,0,0,0), //176 147 '' => array(4,4,14,4,4,4,4), //134 148 '' => array(4,4,14,4,14,4,4), //135 149 '±' => array(0,4,14,4,0,14,0), //177 150 '' => array(0,4,2,15,2,4,0), //137 show right arrow 151 '' => array(0,2,4,15,4,2,0), //156 show left arrow 152 '¡' => array(0,0,8,8,0,0,0), //159 show small hi-stick - that need for simulate rus 'Ô' 153 "\t" => array(8,8,8,0,0,0,0), //show hi-stick - that need for simulate rus 'Ó' 154 "\r" => array(8,8,8,8,8,8,8), //vertical line - that need for simulate 'M', 'W' and rus 'Ì','Ø' ,'Ù' 155 "\n" => array(15,15,15,15,15,15,15), //fill up - that need for simulate rus 'Æ' 156 "¥" => array(10,5,10,5,10,5,10), //chess 157 "µ" => array(15,0,15,0,15,0,15), //4 horizontal lines 158 // latin 159 'A' => array(6,9,9,15,9,9,9), 160 'B' => array(14,9,9,14,9,9,14), 161 'C' => array(6,9,8,8,8,9,6), 162 'D' => array(14,9,9,9,9,9,14), 163 'E' => array(15,8,8,14,8,8,15), 164 'F' => array(15,8,8,14,8,8,8), 165 'G' => array(6,9,8,8,11,9,6), 166 'H' => array(9,9,9,15,9,9,9), 167 'I' => array(14,4,4,4,4,4,14), 168 'J' => array(15,1,1,1,1,9,6), 169 'K' => array(8,9,10,12,12,10,9), 170 'L' => array(8,8,8,8,8,8,15), 171 'M' => array(8,13,10,8,8,8,8),// need to add \r 172 'N' => array(9,9,13,11,9,9,9), 173 //'O' => array(0,6,9,9,9,9,6), 174 'O' => array(6,9,9,9,9,9,6), 175 'P' => array(14,9,9,14,8,8,8), 176 'Q' => array(6,9,9,9,13,11,6), 177 'R' => array(14,9,9,14,12,10,9), 178 'S' => array(6,9,8,6,1,9,6), 179 'T' => array(14,4,4,4,4,4,4), 180 'U' => array(9,9,9,9,9,9,6), 181 'V' => array(0,0,0,10,10,10,4), 182 'W' => array(8,8,8,8,10,13,8),// need to add \r 183 'X' => array(9,9,6,6,6,9,9), 184 //'Y' => array(9,9,9,9,6,6,6), 185 'Y' => array(10,10,10,10,4,4,4), 186 'Z' => array(15,1,2,6,4,8,15), 187 // russian cp1251 188 'À' => array(6,9,9,15,9,9,9), 189 'Á' => array(14,8,8,14,9,9,14), 190 'Â' => array(14,9,9,14,9,9,14), 191 'Ã' => array(15,8,8,8,8,8,8), 192 'Ä' => array(14,9,9,9,9,9,14), 193 'Å' => array(15,8,8,14,8,8,15), 194 'š' => array(6,15,8,14,8,8,15), 195 //Æ is combine: >\n< 196 'Ç' => array(6,9,1,2,1,9,6), 197 'È' => array(9,9,9,11,13,9,9), 198 'É' => array(13,9,9,11,13,9,9), 199 'Ê' => array(9,10,12,10,9,9,9), 200 'Ë' => array(7,9,9,9,9,9,9), 201 'Ì' => array(8,13,10,8,8,8,8),// need to add \r 202 'Í' => array(9,9,9,15,9,9,9), 203 'Î' => array(6,9,9,9,9,9,6), 204 'Ï' => array(15,9,9,9,9,9,9), 205 'Ð' => array(14,9,9,14,8,8,8), 206 'Ñ' => array(6,9,8,8,8,9,6), 207 'Ò' => array(14,4,4,4,4,4,4), 208 'Ó' => array(9,9,9,7,1,9,6), 209 'Ô' => array(2,7,10,10,7,2,2),// need to add ¡ 210 'Õ' => array(9,9,6,6,6,9,9), 211 'Ö' => array(10,10,10,10,10,15,1), 212 '×' => array(9,9,9,7,1,1,1), 213 'Ø' => array(10,10,10,10,10,10,15),// \r 214 'Ù' => array(10,10,10,10,10,15,0),// need to add \r 215 'Ú' => array(12,4,4,6,5,5,6), 216 'Û' => array(8,8,8,14,9,9,14),// need to add | 217 'Ü' => array(8,8,8,14,9,9,14), 218 'Ý' => array(6,9,1,7,1,9,6), 219 'Þ' => array(2,2,2,3,2,2,2),// need to add O 220 'ß' => array(7,9,9,7,3,5,9) 221 ), 222 223 $iSuperSampling = 3, $iMarg = 1, $iRad = 4; 224 225 function DigitalLED74($aRadius = 2, $aMargin= 0.6) { 226 $this->iRad = $aRadius; 227 $this->iMarg = $aMargin; 228 } 229 230 function SetSupersampling($aSuperSampling = 2) { 231 $this->iSuperSampling = $aSuperSampling; 232 } 233 234 function _GetLED($aLedIdx, $aColor = 0) { 235 $width= $this->iLED_X*$this->iRad*2 + ($this->iLED_X+1)*$this->iMarg + $this->iRad ; 236 $height= $this->iLED_Y*$this->iRad*2 + ($this->iLED_Y)*$this->iMarg + $this->iRad * 2; 237 238 // Adjust radious for supersampling 239 $rad = $this->iRad * $this->iSuperSampling; 240 241 // Margin in between "Led" dots 242 $marg = $this->iMarg * $this->iSuperSampling; 243 244 $swidth = $width*$this->iSuperSampling; 245 $sheight = $height*$this->iSuperSampling; 246 247 $simg = new RotImage($swidth, $sheight, 0, DEFAULT_GFORMAT, false); 248 $simg->SetColor($this->iColorSchema[$aColor][2]); 249 $simg->FilledRectangle(0, 0, $swidth-1, $sheight-1); 250 251 if(array_key_exists($aLedIdx, $this->iLEDSpec)) { 252 $d = $this->iLEDSpec[$aLedIdx]; 253 } 254 else { 255 $d = array(0,0,0,0,0,0,0); 256 } 257 258 for($r = 0; $r < 7; ++$r) { 259 $dr = $d[$r]; 260 for($c = 0; $c < 4; ++$c) { 261 if( ($dr & pow(2,3-$c)) !== 0 ) { 262 $color = $this->iColorSchema[$aColor][0]; 263 } 264 else { 265 $color = $this->iColorSchema[$aColor][1]; 266 } 267 268 $x = 2*$rad*$c+$rad + ($c+1)*$marg + $rad ; 269 $y = 2*$rad*$r+$rad + ($r+1)*$marg + $rad ; 270 271 $simg->SetColor($color); 272 $simg->FilledCircle($x,$y,$rad); 273 } 274 } 275 276 $img = new Image($width, $height, DEFAULT_GFORMAT, false); 277 $img->Copy($simg->img, 0, 0, 0, 0, $width, $height, $swidth, $sheight); 278 $simg->Destroy(); 279 unset($simg); 280 return $img; 281 } 48 // fg-up, fg-down, bg 49 $iColorSchema = array( 50 LEDC_RED => array('red','darkred:0.9','red:0.3'),// 0 51 LEDC_GREEN => array('green','darkgreen','green:0.3'),// 1 52 LEDC_BLUE => array('lightblue:0.9','darkblue:0.85','darkblue:0.7'),// 2 53 LEDC_YELLOW => array('yellow','yellow:0.4','yellow:0.3'),// 3 54 LEDC_GRAY => array('gray:1.4','darkgray:0.85','darkgray:0.7'), 55 LEDC_CHOCOLATE => array('chocolate','chocolate:0.7','chocolate:0.5'), 56 LEDC_PERU => array('peru:0.95','peru:0.6','peru:0.5'), 57 LEDC_GOLDENROD => array('goldenrod','goldenrod:0.6','goldenrod:0.5'), 58 LEDC_KHAKI => array('khaki:0.7','khaki:0.4','khaki:0.3'), 59 LEDC_OLIVE => array('#808000','#808000:0.7','#808000:0.6'), 60 LEDC_LIMEGREEN => array('limegreen:0.9','limegreen:0.5','limegreen:0.4'), 61 LEDC_FORESTGREEN => array('forestgreen','forestgreen:0.7','forestgreen:0.5'), 62 LEDC_TEAL => array('teal','teal:0.7','teal:0.5'), 63 LEDC_STEELBLUE => array('steelblue','steelblue:0.65','steelblue:0.5'), 64 LEDC_NAVY => array('navy:1.3','navy:0.95','navy:0.8'),//14 65 LEDC_INVERTGRAY => array('darkgray','lightgray:1.5','white')//15 66 ), 67 68 /* Each line of the character is encoded as a 4 bit value 69 0 ____ 70 1 ___x 71 2 __x_ 72 3 __xx 73 4 _x__ 74 5 _x_x 75 6 _xx_ 76 7 _xxx 77 8 x___ 78 9 x__x 79 10 x_x_ 80 11 x_xx 81 12 xx__ 82 13 xx_x 83 14 xxx_ 84 15 xxxx 85 */ 86 87 $iLEDSpec = array( 88 0 => array(6,9,11,15,13,9,6), 89 1 => array(2,6,10,2,2,2,2), 90 2 => array(6,9,1,2,4,8,15), 91 3 => array(6,9,1,6,1,9,6), 92 4 => array(1,3,5,9,15,1,1), 93 5 => array(15,8,8,14,1,9,6), 94 6 => array(6,8,8,14,9,9,6), 95 7 => array(15,1,1,2,4,4,4), 96 8 => array(6,9,9,6,9,9,6), 97 9 => array(6,9,9,7,1,1,6), 98 '!' => array(4,4,4,4,4,0,4), 99 '?' => array(6,9,1,2,2,0,2), 100 '#' => array(0,9,15,9,15,9,0), 101 '@' => array(6,9,11,11,10,9,6), 102 '-' => array(0,0,0,15,0,0,0), 103 '_' => array(0,0,0,0,0,0,15), 104 '=' => array(0,0,15,0,15,0,0), 105 '+' => array(0,0,4,14,4,0,0), 106 '|' => array(4,4,4,4,4,4,4), //vertical line, used for simulate rus 'Ы' 107 ',' => array(0,0,0,0,0,12,4), 108 '.' => array(0,0,0,0,0,12,12), 109 ':' => array(12,12,0,0,0,12,12), 110 ';' => array(12,12,0,0,0,12,4), 111 '[' => array(3,2,2,2,2,2,3), 112 ']' => array(12,4,4,4,4,4,12), 113 '(' => array(1,2,2,2,2,2,1), 114 ')' => array(8,4,4,4,4,4,8), 115 '{' => array(3,2,2,6,2,2,3), 116 '}' => array(12,4,4,6,4,4,12), 117 '<' => array(1,2,4,8,4,2,1), 118 '>' => array(8,4,2,1,2,4,8), 119 '*' => array(9,6,15,6,9,0,0), 120 '"' => array(10,10,0,0,0,0,0), 121 '\'' => array(4,4,0,0,0,0,0), 122 '`' => array(4,2,0,0,0,0,0), 123 '~' => array(13,11,0,0,0,0,0), 124 '^' => array(4,10,0,0,0,0,0), 125 '\\' => array(8,8,4,6,2,1,1), 126 '/' => array(1,1,2,6,4,8,8), 127 '%' => array(1,9,2,6,4,9,8), 128 '&' => array(0,4,10,4,11,10,5), 129 '$' => array(2,7,8,6,1,14,4), 130 ' ' => array(0,0,0,0,0,0,0), 131 'â¢' => array(0,0,6,6,0,0,0), //149 132 '°' => array(14,10,14,0,0,0,0), //176 133 'â ' => array(4,4,14,4,4,4,4), //134 134 'â¡' => array(4,4,14,4,14,4,4), //135 135 '±' => array(0,4,14,4,0,14,0), //177 136 'â°' => array(0,4,2,15,2,4,0), //137 show right arrow 137 'â¢' => array(0,2,4,15,4,2,0), //156 show left arrow 138 'Ð' => array(0,0,8,8,0,0,0), //159 show small hi-stick - that need for simulate rus 'Ѐ' 139 "\t" => array(8,8,8,0,0,0,0), //show hi-stick - that need for simulate rus 'У' 140 "\r" => array(8,8,8,8,8,8,8), //vertical line - that need for simulate 'M', 'W' and rus 'Ð','К' ,'Щ' 141 "\n" => array(15,15,15,15,15,15,15), //fill up - that need for simulate rus 'Ð' 142 "Ò" => array(10,5,10,5,10,5,10), //chess 143 "µ" => array(15,0,15,0,15,0,15), //4 horizontal lines 144 // latin 145 'A' => array(6,9,9,15,9,9,9), 146 'B' => array(14,9,9,14,9,9,14), 147 'C' => array(6,9,8,8,8,9,6), 148 'D' => array(14,9,9,9,9,9,14), 149 'E' => array(15,8,8,14,8,8,15), 150 'F' => array(15,8,8,14,8,8,8), 151 'G' => array(6,9,8,8,11,9,6), 152 'H' => array(9,9,9,15,9,9,9), 153 'I' => array(14,4,4,4,4,4,14), 154 'J' => array(15,1,1,1,1,9,6), 155 'K' => array(8,9,10,12,12,10,9), 156 'L' => array(8,8,8,8,8,8,15), 157 'M' => array(8,13,10,8,8,8,8),// need to add \r 158 'N' => array(9,9,13,11,9,9,9), 159 'O' => array(6,9,9,9,9,9,6), 160 'P' => array(14,9,9,14,8,8,8), 161 'Q' => array(6,9,9,9,13,11,6), 162 'R' => array(14,9,9,14,12,10,9), 163 'S' => array(6,9,8,6,1,9,6), 164 'T' => array(14,4,4,4,4,4,4), 165 'U' => array(9,9,9,9,9,9,6), 166 'V' => array(0,0,0,10,10,10,4), 167 'W' => array(8,8,8,8,10,13,8),// need to add \r 168 'X' => array(9,9,6,6,6,9,9), 169 'Y' => array(10,10,10,10,4,4,4), 170 'Z' => array(15,1,2,6,4,8,15), 171 // russian utf-8 172 'Ð' => array(6,9,9,15,9,9,9), 173 'Ð' => array(14,8,8,14,9,9,14), 174 'Ð' => array(14,9,9,14,9,9,14), 175 'Ð' => array(15,8,8,8,8,8,8), 176 'Ð' => array(14,9,9,9,9,9,14), 177 'Ð' => array(15,8,8,14,8,8,15), 178 'Ð' => array(6,15,8,14,8,8,15), 179 //Ð is combine: >\n< 180 'Ð' => array(6,9,1,2,1,9,6), 181 'Ð' => array(9,9,9,11,13,9,9), 182 'Ð' => array(13,9,9,11,13,9,9), 183 'Ð' => array(9,10,12,10,9,9,9), 184 'Ð' => array(7,9,9,9,9,9,9), 185 'Ð' => array(8,13,10,8,8,8,8),// need to add \r 186 'Ð' => array(9,9,9,15,9,9,9), 187 'Ð' => array(6,9,9,9,9,9,6), 188 'Ð' => array(15,9,9,9,9,9,9), 189 'Ð ' => array(14,9,9,14,8,8,8), 190 'С' => array(6,9,8,8,8,9,6), 191 'Т' => array(14,4,4,4,4,4,4), 192 'У' => array(9,9,9,7,1,9,6), 193 'Ѐ' => array(2,7,10,10,7,2,2),// need to add Ð 194 'Ð¥' => array(9,9,6,6,6,9,9), 195 'Њ' => array(10,10,10,10,10,15,1), 196 'Ч' => array(9,9,9,7,1,1,1), 197 'К' => array(10,10,10,10,10,10,15),// \r 198 'Щ' => array(10,10,10,10,10,15,0),// need to add \r 199 'Ъ' => array(12,4,4,6,5,5,6), 200 'Ы' => array(8,8,8,14,9,9,14),// need to add | 201 'Ь' => array(8,8,8,14,9,9,14), 202 'Ð' => array(6,9,1,7,1,9,6), 203 'Ю' => array(2,2,2,3,2,2,2),// need to add O 204 'Я' => array(7,9,9,7,3,5,9) 205 ), 206 207 $iSuperSampling = 3, $iMarg = 1, $iRad = 4; 208 209 function __construct($aRadius = 2, $aMargin= 0.6) { 210 $this->iRad = $aRadius; 211 $this->iMarg = $aMargin; 212 } 213 214 function SetSupersampling($aSuperSampling = 2) { 215 $this->iSuperSampling = $aSuperSampling; 216 } 217 218 function _GetLED($aLedIdx, $aColor = 0) { 219 $width= $this->iLED_X*$this->iRad*2 + ($this->iLED_X+1)*$this->iMarg + $this->iRad ; 220 $height= $this->iLED_Y*$this->iRad*2 + ($this->iLED_Y)*$this->iMarg + $this->iRad * 2; 221 222 // Adjust radious for supersampling 223 $rad = $this->iRad * $this->iSuperSampling; 224 225 // Margin in between "Led" dots 226 $marg = $this->iMarg * $this->iSuperSampling; 227 228 $swidth = $width*$this->iSuperSampling; 229 $sheight = $height*$this->iSuperSampling; 230 231 $simg = new RotImage($swidth, $sheight, 0, DEFAULT_GFORMAT, false); 232 $simg->SetColor($this->iColorSchema[$aColor][2]); 233 $simg->FilledRectangle(0, 0, $swidth-1, $sheight-1); 234 235 if( array_key_exists($aLedIdx, $this->iLEDSpec) ) { 236 $d = $this->iLEDSpec[$aLedIdx]; 237 } 238 else { 239 $d = array(0,0,0,0,0,0,0); 240 } 241 242 for($r = 0; $r < 7; ++$r) { 243 $dr = $d[$r]; 244 for($c = 0; $c < 4; ++$c) { 245 if( ($dr & pow(2,3-$c)) !== 0 ) { 246 $color = $this->iColorSchema[$aColor][0]; 247 } 248 else { 249 $color = $this->iColorSchema[$aColor][1]; 250 } 251 252 $x = 2*$rad*$c+$rad + ($c+1)*$marg + $rad ; 253 $y = 2*$rad*$r+$rad + ($r+1)*$marg + $rad ; 254 255 $simg->SetColor($color); 256 $simg->FilledCircle($x,$y,$rad); 257 } 258 } 259 260 $img = new Image($width, $height, DEFAULT_GFORMAT, false); 261 $img->Copy($simg->img, 0, 0, 0, 0, $width, $height, $swidth, $sheight); 262 $simg->Destroy(); 263 unset($simg); 264 return $img; 265 } 266 267 268 function Stroke($aValStr, $aColor = 0, $aFileName = '') { 269 $this->StrokeNumber($aValStr, $aColor, $aFileName); 270 } 271 282 272 283 273 function StrokeNumber($aValStr, $aColor = 0, $aFileName = '') { 284 if($aColor < 0 || $aColor >= sizeof($this->iColorSchema)) 285 $aColor = 0; 286 287 if(($n = strlen($aValStr)) == 0) { 288 $aValStr = ' '; 289 $n = 1; 290 } 291 292 for($i = 0; $i < $n; ++$i) { 293 $d = substr($aValStr, $i, 1); 294 if( $d >= '0' && $d <= '9' ) { 295 $d = (int)$d; 296 } 297 else { 298 $d = strtoupper($d); 299 } 300 $digit_img[$i] = $this->_GetLED($d, $aColor); 301 } 302 303 $w = imagesx($digit_img[0]->img); 304 $h = imagesy($digit_img[0]->img); 305 306 $number_img = new Image($w*$n, $h, DEFAULT_GFORMAT, false); 307 308 for($i = 0; $i < $n; ++$i) { 309 $number_img->Copy($digit_img[$i]->img, $i*$w, 0, 0, 0, $w, $h, $w, $h); 310 } 311 312 if( $aFileName != '' ) { 313 $number_img->Stream($aFileName); 314 } else { 315 $number_img->Headers(); 316 $number_img->Stream(); 317 } 274 if( $aColor < 0 || $aColor >= sizeof($this->iColorSchema) ) { 275 $aColor = 0; 276 } 277 278 if(($n = mb_strlen($aValStr,'utf8')) == 0) { 279 $aValStr = ' '; 280 $n = 1; 281 } 282 283 for($i = 0; $i < $n; ++$i) { 284 $d = mb_substr($aValStr, $i, 1, 'utf8'); 285 if( ctype_digit($d) ) { 286 $d = (int)$d; 287 } 288 else { 289 $d = strtoupper($d); 290 } 291 $digit_img[$i] = $this->_GetLED($d, $aColor); 292 } 293 294 $w = imagesx($digit_img[0]->img); 295 $h = imagesy($digit_img[0]->img); 296 297 $number_img = new Image($w*$n, $h, DEFAULT_GFORMAT, false); 298 299 for($i = 0; $i < $n; ++$i) { 300 $number_img->Copy($digit_img[$i]->img, $i*$w, 0, 0, 0, $w, $h, $w, $h); 301 } 302 303 if( $aFileName != '' ) { 304 $number_img->Stream($aFileName); 305 } else { 306 $number_img->Headers(); 307 $number_img->Stream(); 308 } 318 309 } 319 310 } -
trunk/client/modules/Elezioni/grafici/jpgraph_legend.inc.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // 6 // 7 // Created: 8 // Ver: $Id: jpgraph_legend.inc.php 1048 2008-08-01 19:56:46Z ljp $3 // File: JPGRAPH_LEGEND.INC.PHP 4 // Description: Class to handle the legend box in the graph that gives 5 // names on the data series. The number of rows and columns 6 // in the legend are user specifyable. 7 // Created: 2001-01-08 (Refactored to separate file 2008-08-01) 8 // Ver: $Id: jpgraph_legend.inc.php 1926 2010-01-11 16:33:07Z ljp $ 9 9 // 10 // Copyright (c) A ditus Consulting. All rights reserved.10 // Copyright (c) Asial Corporation. All rights reserved. 11 11 //======================================================================== 12 12 13 13 DEFINE('_DEFAULT_LPM_SIZE',8); // Default Legend Plot Mark size 14 14 15 15 16 16 //=================================================== 17 17 // CLASS Legend … … 22 22 class Legend { 23 23 public $txtcol=array(); 24 private $color=array(0,0,0); // Default fram color 25 private $fill_color=array(235,235,235); // Default fill color 26 private $shadow=true; // Shadow around legend "box" 27 private $shadow_color='darkgray@0.5'; 24 public $font_family=FF_DEFAULT,$font_style=FS_NORMAL,$font_size=8; // old. 12 25 private $color=array(120,120,120); // Default frame color 26 private $fill_color=array(245,245,245); // Default fill color 27 private $shadow=false; // Shadow around legend "box" 28 private $shadow_color='darkgray'; 28 29 private $mark_abs_hsize=_DEFAULT_LPM_SIZE,$mark_abs_vsize=_DEFAULT_LPM_SIZE; 29 private $xmargin=10,$ymargin=3,$shadow_width=2; 30 private $xlmargin=2, $ylmargin=''; 30 private $xmargin=10,$ymargin=0,$shadow_width=2; 31 private $xlmargin=4; 32 private $ylinespacing=5; 33 34 // We need a separate margin since the baseline of the last text would coincide with the bottom otherwise 35 private $ybottom_margin = 8; 36 31 37 private $xpos=0.05, $ypos=0.15, $xabspos=-1, $yabspos=-1; 32 38 private $halign="right", $valign="top"; 33 private $font_family=FF_FONT1,$font_style=FS_NORMAL,$font_size=12;34 39 private $font_color='black'; 35 40 private $hide=false,$layout_n=1; … … 37 42 private $csimareas=''; 38 43 private $reverse = false ; 39 40 //--------------- 41 // CONSTRUCTOR 42 function Legend() { 43 // Empty 44 } 45 //--------------- 46 // PUBLIC METHODS 44 private $bkg_gradtype=-1, $bkg_gradfrom='lightgray', $bkg_gradto='gray'; 45 46 //--------------- 47 // CONSTRUCTOR 48 function __construct() { 49 // Empty 50 } 51 //--------------- 52 // PUBLIC METHODS 47 53 function Hide($aHide=true) { 48 49 } 50 54 $this->hide=$aHide; 55 } 56 51 57 function SetHColMargin($aXMarg) { 52 58 $this->xmargin = $aXMarg; 53 59 } 54 60 55 61 function SetVColMargin($aSpacing) { 56 $this->ymargin= $aSpacing ;62 $this->ylinespacing = $aSpacing ; 57 63 } 58 64 59 65 function SetLeftMargin($aXMarg) { 60 66 $this->xlmargin = $aXMarg; 61 67 } 62 68 63 69 // Synonym 64 70 function SetLineSpacing($aSpacing) { 65 $this->ymargin = $aSpacing ; 66 } 67 68 function SetShadow($aShow='gray',$aWidth=2) { 69 if( is_string($aShow) ) { 70 $this->shadow_color = $aShow; 71 $this->shadow=true; 72 } 73 else 74 $this->shadow=$aShow; 75 $this->shadow_width=$aWidth; 71 $this->ylinespacing = $aSpacing ; 72 } 73 74 function SetShadow($aShow='gray',$aWidth=4) { 75 if( is_string($aShow) ) { 76 $this->shadow_color = $aShow; 77 $this->shadow=true; 78 } 79 else { 80 $this->shadow = $aShow; 81 } 82 $this->shadow_width = $aWidth; 76 83 } 77 84 78 85 function SetMarkAbsSize($aSize) { 79 80 86 $this->mark_abs_vsize = $aSize ; 87 $this->mark_abs_hsize = $aSize ; 81 88 } 82 89 83 90 function SetMarkAbsVSize($aSize) { 84 91 $this->mark_abs_vsize = $aSize ; 85 92 } 86 93 87 94 function SetMarkAbsHSize($aSize) { 88 95 $this->mark_abs_hsize = $aSize ; 89 96 } 90 97 91 98 function SetLineWeight($aWeight) { 92 99 $this->weight = $aWeight; 93 100 } 94 101 95 102 function SetFrameWeight($aWeight) { 96 97 } 98 103 $this->frameweight = $aWeight; 104 } 105 99 106 function SetLayout($aDirection=LEGEND_VERT) { 100 101 } 102 107 $this->layout_n = $aDirection==LEGEND_VERT ? 1 : 99 ; 108 } 109 103 110 function SetColumns($aCols) { 104 111 $this->layout_n = $aCols ; 105 112 } 106 113 107 114 function SetReverse($f=true) { 108 115 $this->reverse = $f ; 109 116 } 110 117 111 118 // Set color on frame around box 112 119 function SetColor($aFontColor,$aColor='black') { 113 114 115 } 116 120 $this->font_color=$aFontColor; 121 $this->color=$aColor; 122 } 123 117 124 function SetFont($aFamily,$aStyle=FS_NORMAL,$aSize=10) { 118 119 120 121 } 122 123 function SetPos($aX,$aY,$aHAlign= "right",$aVAlign="top") {124 125 } 126 127 function SetAbsPos($aX,$aY,$aHAlign= "right",$aVAlign="top") {128 129 130 131 132 } 133 134 135 function Pos($aX,$aY,$aHAlign="right",$aVAlign="top") {136 if( !($aX<1 && $aY<1) ) 137 JpGraphError::RaiseL(25120);//(" Position for legend must be given as percentage in range 0-1"); 138 139 140 141 125 $this->font_family = $aFamily; 126 $this->font_style = $aStyle; 127 $this->font_size = $aSize; 128 } 129 130 function SetPos($aX,$aY,$aHAlign='right',$aVAlign='top') { 131 $this->Pos($aX,$aY,$aHAlign,$aVAlign); 132 } 133 134 function SetAbsPos($aX,$aY,$aHAlign='right',$aVAlign='top') { 135 $this->xabspos=$aX; 136 $this->yabspos=$aY; 137 $this->halign=$aHAlign; 138 $this->valign=$aVAlign; 139 } 140 141 function Pos($aX,$aY,$aHAlign='right',$aVAlign='top') { 142 if( !($aX<1 && $aY<1) ) { 143 JpGraphError::RaiseL(25120);//(" Position for legend must be given as percentage in range 0-1"); 144 } 145 $this->xpos=$aX; 146 $this->ypos=$aY; 147 $this->halign=$aHAlign; 148 $this->valign=$aVAlign; 142 149 } 143 150 144 151 function SetFillColor($aColor) { 145 $this->fill_color=$aColor; 146 } 147 152 $this->fill_color=$aColor; 153 } 154 155 function Clear() { 156 $this->txtcol = array(); 157 } 158 148 159 function Add($aTxt,$aColor,$aPlotmark='',$aLinestyle=0,$csimtarget='',$csimalt='',$csimwintarget='') { 149 160 $this->txtcol[]=array($aTxt,$aColor,$aPlotmark,$aLinestyle,$csimtarget,$csimalt,$csimwintarget); 150 161 } 151 162 152 163 function GetCSIMAreas() { 153 return $this->csimareas; 154 } 155 156 function Stroke(&$aImg) { 157 // Constant 158 $fillBoxFrameWeight=1; 159 160 if( $this->hide ) return; 161 162 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 163 164 if( $this->reverse ) { 165 $this->txtcol = array_reverse($this->txtcol); 166 } 167 168 $n=count($this->txtcol); 169 if( $n == 0 ) return; 170 171 // Find out the max width and height of each column to be able 164 return $this->csimareas; 165 } 166 167 function SetBackgroundGradient($aFrom='navy',$aTo='silver',$aGradType=2) { 168 $this->bkg_gradtype=$aGradType; 169 $this->bkg_gradfrom = $aFrom; 170 $this->bkg_gradto = $aTo; 171 } 172 173 function HasItems() { 174 return (boolean)(count($this->txtcol)); 175 } 176 177 function Stroke($aImg) { 178 // Constant 179 $fillBoxFrameWeight=1; 180 181 if( $this->hide ) return; 182 183 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 184 185 if( $this->reverse ) { 186 $this->txtcol = array_reverse($this->txtcol); 187 } 188 189 $n=count($this->txtcol); 190 if( $n == 0 ) return; 191 192 // Find out the max width and height of each column to be able 172 193 // to size the legend box. 173 $numcolumns = ($n > $this->layout_n ? $this->layout_n : $n); 174 for( $i=0; $i < $numcolumns; ++$i ) { 175 $colwidth[$i] = $aImg->GetTextWidth($this->txtcol[$i][0]) + 176 2*$this->xmargin + 2*$this->mark_abs_hsize; 177 $colheight[$i] = 0; 178 } 179 180 // Find our maximum height in each row 181 $rows = 0 ; $rowheight[0] = 0; 182 for( $i=0; $i < $n; ++$i ) { 183 $h = max($this->mark_abs_vsize,$aImg->GetTextHeight($this->txtcol[$i][0]))+$this->ymargin; 184 if( $i % $numcolumns == 0 ) { 185 $rows++; 186 $rowheight[$rows-1] = 0; 187 } 188 $rowheight[$rows-1] = max($rowheight[$rows-1],$h); 189 } 190 191 $abs_height = 0; 192 for( $i=0; $i < $rows; ++$i ) { 193 $abs_height += $rowheight[$i] ; 194 } 195 196 // Make sure that the height is at least as high as mark size + ymargin 197 $abs_height = max($abs_height,$this->mark_abs_vsize); 198 199 // We add 3 extra pixels height to compensate for the difficult in 200 // calculating font height 201 $abs_height += $this->ymargin+3; 202 203 // Find out the maximum width in each column 204 for( $i=$numcolumns; $i < $n; ++$i ) { 205 $colwidth[$i % $numcolumns] = max( 206 $aImg->GetTextWidth($this->txtcol[$i][0])+2*$this->xmargin+2*$this->mark_abs_hsize,$colwidth[$i % $numcolumns]); 207 } 208 209 // Get the total width 210 $mtw = 0; 211 for( $i=0; $i < $numcolumns; ++$i ) { 212 $mtw += $colwidth[$i] ; 213 } 214 215 // Find out maximum width we need for legend box 216 $abs_width = $mtw+$this->xlmargin; 217 218 if( $this->xabspos === -1 && $this->yabspos === -1 ) { 219 $this->xabspos = $this->xpos*$aImg->width ; 220 $this->yabspos = $this->ypos*$aImg->height ; 221 } 222 223 // Positioning of the legend box 224 if( $this->halign == 'left' ) 225 $xp = $this->xabspos; 226 elseif( $this->halign == 'center' ) 227 $xp = $this->xabspos - $abs_width/2; 228 else 229 $xp = $aImg->width - $this->xabspos - $abs_width; 230 231 $yp=$this->yabspos; 232 if( $this->valign == 'center' ) 233 $yp-=$abs_height/2; 234 elseif( $this->valign == 'bottom' ) 235 $yp-=$abs_height; 236 237 // Stroke legend box 238 $aImg->SetColor($this->color); 239 $aImg->SetLineWeight($this->frameweight); 240 $aImg->SetLineStyle('solid'); 241 242 if( $this->shadow ) 243 $aImg->ShadowRectangle($xp,$yp,$xp+$abs_width+$this->shadow_width, 244 $yp+$abs_height+$this->shadow_width, 245 $this->fill_color,$this->shadow_width,$this->shadow_color); 246 else { 247 $aImg->SetColor($this->fill_color); 248 $aImg->FilledRectangle($xp,$yp,$xp+$abs_width,$yp+$abs_height); 249 $aImg->SetColor($this->color); 250 $aImg->Rectangle($xp,$yp,$xp+$abs_width,$yp+$abs_height); 251 } 252 253 // x1,y1 is the position for the legend mark 254 $x1=$xp+$this->mark_abs_hsize+$this->xlmargin; 255 $y1=$yp + $this->ymargin; 256 257 $f2 = round($aImg->GetTextHeight('X')/2); 258 259 $grad = new Gradient($aImg); 260 $patternFactory = null; 261 262 // Now stroke each legend in turn 263 // Each plot has added the following information to the legend 264 // p[0] = Legend text 265 // p[1] = Color, 266 // p[2] = For markers a reference to the PlotMark object 267 // p[3] = For lines the line style, for gradient the negative gradient style 268 // p[4] = CSIM target 269 // p[5] = CSIM Alt text 270 $i = 1 ; $row = 0; 271 foreach($this->txtcol as $p) { 272 273 // STROKE DEBUG BOX 274 if( _JPG_DEBUG ) { 275 $aImg->SetLineWeight(1); 276 $aImg->SetColor('red'); 277 $aImg->SetLineStyle('solid'); 278 $aImg->Rectangle($xp,$y1,$xp+$abs_width,$y1+$rowheight[$row]); 279 } 280 281 $aImg->SetLineWeight($this->weight); 282 $x1 = round($x1); $y1=round($y1); 283 if ( !empty($p[2]) && $p[2]->GetType() > -1 ) { 284 // Make a plot mark legend 285 $aImg->SetColor($p[1]); 286 if( is_string($p[3]) || $p[3]>0 ) { 287 $aImg->SetLineStyle($p[3]); 288 $aImg->StyleLine($x1-$this->mark_abs_hsize,$y1+$f2,$x1+$this->mark_abs_hsize,$y1+$f2); 289 } 290 // Stroke a mark with the standard size 291 // (As long as it is not an image mark ) 292 if( $p[2]->GetType() != MARK_IMG ) { 293 294 // Clear any user callbacks since we ont want them called for 295 // the legend marks 296 $p[2]->iFormatCallback = ''; 297 $p[2]->iFormatCallback2 = ''; 298 299 // Since size for circles is specified as the radius 300 // this means that we must half the size to make the total 301 // width behave as the other marks 302 if( $p[2]->GetType() == MARK_FILLEDCIRCLE || $p[2]->GetType() == MARK_CIRCLE ) { 303 $p[2]->SetSize(min($this->mark_abs_vsize,$this->mark_abs_hsize)/2); 304 $p[2]->Stroke($aImg,$x1,$y1+$f2); 305 } 306 else { 307 $p[2]->SetSize(min($this->mark_abs_vsize,$this->mark_abs_hsize)); 308 $p[2]->Stroke($aImg,$x1,$y1+$f2); 309 } 310 } 311 } 312 elseif ( !empty($p[2]) && (is_string($p[3]) || $p[3]>0 ) ) { 313 // Draw a styled line 314 $aImg->SetColor($p[1]); 315 $aImg->SetLineStyle($p[3]); 316 $aImg->StyleLine($x1-1,$y1+$f2,$x1+$this->mark_abs_hsize,$y1+$f2); 317 $aImg->StyleLine($x1-1,$y1+$f2+1,$x1+$this->mark_abs_hsize,$y1+$f2+1); 318 } 319 else { 320 // Draw a colored box 321 $color = $p[1] ; 322 // We make boxes slightly larger to better show 323 $boxsize = min($this->mark_abs_vsize,$this->mark_abs_hsize) + 2 ; 324 $ym = round($y1 + $f2 - $boxsize/2); 325 // We either need to plot a gradient or a 326 // pattern. To differentiate we use a kludge. 327 // Patterns have a p[3] value of < -100 328 if( $p[3] < -100 ) { 329 // p[1][0] == iPattern, p[1][1] == iPatternColor, p[1][2] == iPatternDensity 330 if( $patternFactory == null ) { 331 $patternFactory = new RectPatternFactory(); 332 } 333 $prect = $patternFactory->Create($p[1][0],$p[1][1],1); 334 $prect->SetBackground($p[1][3]); 335 $prect->SetDensity($p[1][2]+1); 336 $prect->SetPos(new Rectangle($x1,$ym,$boxsize,$boxsize)); 337 $prect->Stroke($aImg); 338 $prect=null; 339 } 340 else { 341 if( is_array($color) && count($color)==2 ) { 342 // The client want a gradient color 343 $grad->FilledRectangle($x1,$ym, 344 $x1+$boxsize,$ym+$boxsize, 345 $color[0],$color[1],-$p[3]); 346 } 347 else { 348 $aImg->SetColor($p[1]); 349 $aImg->FilledRectangle($x1,$ym,$x1+$boxsize,$ym+$boxsize); 350 } 351 $aImg->SetColor($this->color); 352 $aImg->SetLineWeight($fillBoxFrameWeight); 353 $aImg->Rectangle($x1,$ym,$x1+$boxsize,$ym+$boxsize); 354 } 355 } 356 $aImg->SetColor($this->font_color); 357 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 358 $aImg->SetTextAlign("left","top"); 359 $aImg->StrokeText(round($x1+$this->mark_abs_hsize+$this->xmargin),$y1,$p[0]); 360 361 // Add CSIM for Legend if defined 362 if( !empty($p[4]) ) { 363 364 $xe = $x1 + $this->xmargin+$this->mark_abs_hsize+$aImg->GetTextWidth($p[0]); 365 $ye = $y1 + max($this->mark_abs_vsize,$aImg->GetTextHeight($p[0])); 366 $coords = "$x1,$y1,$xe,$y1,$xe,$ye,$x1,$ye"; 367 if( ! empty($p[4]) ) { 368 $this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".htmlentities($p[4])."\""; 369 370 if( !empty($p[6]) ) { 371 $this->csimareas .= " target=\"".$p[6]."\""; 372 } 373 374 if( !empty($p[5]) ) { 375 $tmp=sprintf($p[5],$p[0]); 376 $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" "; 377 } 378 $this->csimareas .= " />\n"; 379 } 380 } 381 if( $i >= $this->layout_n ) { 382 $x1 = $xp+$this->mark_abs_hsize+$this->xlmargin; 383 $y1 += $rowheight[$row++]; 384 $i = 1; 385 } 386 else { 387 $x1 += $colwidth[($i-1) % $numcolumns] ; 388 ++$i; 389 } 390 } 194 $numcolumns = ($n > $this->layout_n ? $this->layout_n : $n); 195 for( $i=0; $i < $numcolumns; ++$i ) { 196 $colwidth[$i] = $aImg->GetTextWidth($this->txtcol[$i][0]) + 197 2*$this->xmargin + 2*$this->mark_abs_hsize; 198 $colheight[$i] = 0; 199 200 } 201 202 // Find our maximum height in each row 203 $rows = 0 ; $rowheight[0] = 0; 204 for( $i=0; $i < $n; ++$i ) { 205 $h = max($this->mark_abs_vsize,$aImg->GetTextHeight($this->txtcol[$i][0]))+$this->ylinespacing; 206 207 // Makes sure we always have a minimum of 1/4 (1/2 on each side) of the mark as space 208 // between two vertical legend entries 209 //$h = round(max($h,$this->mark_abs_vsize+$this->ymargin)); 210 //echo "Textheight #$i: tetxheight=".$aImg->GetTextHeight($this->txtcol[$i][0]).', '; 211 //echo "h=$h ({$this->mark_abs_vsize},{$this->ymargin})<br>"; 212 if( $i % $numcolumns == 0 ) { 213 $rows++; 214 $rowheight[$rows-1] = 0; 215 } 216 $rowheight[$rows-1] = max($rowheight[$rows-1],$h)+1; 217 } 218 219 $abs_height = 0; 220 for( $i=0; $i < $rows; ++$i ) { 221 $abs_height += $rowheight[$i] ; 222 } 223 224 // Make sure that the height is at least as high as mark size + ymargin 225 $abs_height = max($abs_height,$this->mark_abs_vsize); 226 $abs_height += $this->ybottom_margin; 227 228 // Find out the maximum width in each column 229 for( $i=$numcolumns; $i < $n; ++$i ) { 230 $colwidth[$i % $numcolumns] = max( 231 $aImg->GetTextWidth($this->txtcol[$i][0])+2*$this->xmargin+2*$this->mark_abs_hsize, 232 $colwidth[$i % $numcolumns]); 233 } 234 235 // Get the total width 236 $mtw = 0; 237 for( $i=0; $i < $numcolumns; ++$i ) { 238 $mtw += $colwidth[$i] ; 239 } 240 241 // remove the last rows interpace margin (since there is no next row) 242 $abs_height -= $this->ylinespacing; 243 244 245 // Find out maximum width we need for legend box 246 $abs_width = $mtw+$this->xlmargin+($numcolumns-1)*$this->mark_abs_hsize; 247 248 if( $this->xabspos === -1 && $this->yabspos === -1 ) { 249 $this->xabspos = $this->xpos*$aImg->width ; 250 $this->yabspos = $this->ypos*$aImg->height ; 251 } 252 253 // Positioning of the legend box 254 if( $this->halign == 'left' ) { 255 $xp = $this->xabspos; 256 } 257 elseif( $this->halign == 'center' ) { 258 $xp = $this->xabspos - $abs_width/2; 259 } 260 else { 261 $xp = $aImg->width - $this->xabspos - $abs_width; 262 } 263 264 $yp=$this->yabspos; 265 if( $this->valign == 'center' ) { 266 $yp-=$abs_height/2; 267 } 268 elseif( $this->valign == 'bottom' ) { 269 $yp-=$abs_height; 270 } 271 272 // Stroke legend box 273 $aImg->SetColor($this->color); 274 $aImg->SetLineWeight($this->frameweight); 275 $aImg->SetLineStyle('solid'); 276 277 if( $this->shadow ) { 278 $aImg->ShadowRectangle($xp,$yp, 279 $xp+$abs_width+$this->shadow_width+2, 280 $yp+$abs_height+$this->shadow_width+2, 281 $this->fill_color,$this->shadow_width+2,$this->shadow_color); 282 } 283 else { 284 $aImg->SetColor($this->fill_color); 285 $aImg->FilledRectangle($xp,$yp,$xp+$abs_width,$yp+$abs_height); 286 $aImg->SetColor($this->color); 287 $aImg->Rectangle($xp,$yp,$xp+$abs_width,$yp+$abs_height); 288 } 289 290 if( $this->bkg_gradtype >= 0 ) { 291 $grad = new Gradient($aImg); 292 $grad->FilledRectangle($xp+1, $yp+1, 293 $xp+$abs_width-3, $yp+$abs_height-3, 294 $this->bkg_gradfrom, $this->bkg_gradto, 295 $this->bkg_gradtype); 296 } 297 298 // x1,y1 is the position for the legend marker + text 299 // The vertical position is the baseline position for the text 300 // and every marker is adjusted acording to that. 301 302 // For multiline texts this get more complicated. 303 304 $x1 = $xp + $this->xlmargin; 305 $y1 = $yp + $rowheight[0] - $this->ylinespacing + 2 ; // The ymargin is included in rowheight 306 307 // Now, y1 is the bottom vertical position of the first legend, i.e if 308 // the legend has multiple lines it is the bottom line. 309 310 $grad = new Gradient($aImg); 311 $patternFactory = null; 312 313 // Now stroke each legend in turn 314 // Each plot has added the following information to the legend 315 // p[0] = Legend text 316 // p[1] = Color, 317 // p[2] = For markers a reference to the PlotMark object 318 // p[3] = For lines the line style, for gradient the negative gradient style 319 // p[4] = CSIM target 320 // p[5] = CSIM Alt text 321 $i = 1 ; $row = 0; 322 foreach($this->txtcol as $p) { 323 324 // STROKE DEBUG BOX 325 if( _JPG_DEBUG ) { 326 $aImg->SetLineWeight(1); 327 $aImg->SetColor('red'); 328 $aImg->SetLineStyle('solid'); 329 $aImg->Rectangle($x1,$y1,$xp+$abs_width-1,$y1-$rowheight[$row]); 330 } 331 332 $aImg->SetLineWeight($this->weight); 333 $x1 = round($x1)+1; // We add one to not collide with the border 334 $y1=round($y1); 335 336 // This is the center offset up from the baseline which is 337 // considered the "center" of the marks. This gets slightly complicated since 338 // we need to consider if the text is a multiline paragraph or if it is only 339 // a single line. The reason is that for single line the y1 corresponds to the baseline 340 // and that is fine. However for a multiline paragraph there is no single baseline 341 // and in that case the y1 corresponds to the lowest y for the bounding box. In that 342 // case we center the mark in the middle of the paragraph 343 if( !preg_match('/\n/',$p[0]) ) { 344 // Single line 345 $marky = ceil($y1-$this->mark_abs_vsize/2)-1; 346 } else { 347 // Paragraph 348 $marky = $y1 - $aImg->GetTextHeight($p[0])/2; 349 350 // echo "y1=$y1, p[o]={$p[0]}, marky=$marky<br>"; 351 } 352 353 //echo "<br>Mark #$i: marky=$marky<br>"; 354 355 $x1 += $this->mark_abs_hsize; 356 357 if ( !empty($p[2]) && $p[2]->GetType() > -1 ) { 358 359 360 // Make a plot mark legend. This is constructed with a mark which 361 // is run through with a line 362 363 // First construct a bit of the line that looks exactly like the 364 // line in the plot 365 $aImg->SetColor($p[1]); 366 if( is_string($p[3]) || $p[3]>0 ) { 367 $aImg->SetLineStyle($p[3]); 368 $aImg->StyleLine($x1-$this->mark_abs_hsize,$marky,$x1+$this->mark_abs_hsize,$marky); 369 } 370 371 // Stroke a mark using image 372 if( $p[2]->GetType() == MARK_IMG ) { 373 $p[2]->Stroke($aImg,$x1,$marky); 374 } 375 376 // Stroke a mark with the standard size 377 // (As long as it is not an image mark ) 378 if( $p[2]->GetType() != MARK_IMG ) { 379 380 // Clear any user callbacks since we ont want them called for 381 // the legend marks 382 $p[2]->iFormatCallback = ''; 383 $p[2]->iFormatCallback2 = ''; 384 385 // Since size for circles is specified as the radius 386 // this means that we must half the size to make the total 387 // width behave as the other marks 388 if( $p[2]->GetType() == MARK_FILLEDCIRCLE || $p[2]->GetType() == MARK_CIRCLE ) { 389 $p[2]->SetSize(min($this->mark_abs_vsize,$this->mark_abs_hsize)/2); 390 $p[2]->Stroke($aImg,$x1,$marky); 391 } 392 else { 393 $p[2]->SetSize(min($this->mark_abs_vsize,$this->mark_abs_hsize)); 394 $p[2]->Stroke($aImg,$x1,$marky); 395 } 396 } 397 } 398 elseif ( !empty($p[2]) && (is_string($p[3]) || $p[3]>0 ) ) { 399 // Draw a styled line 400 $aImg->SetColor($p[1]); 401 $aImg->SetLineStyle($p[3]); 402 $aImg->StyleLine($x1-$this->mark_abs_hsize,$marky,$x1+$this->mark_abs_hsize,$marky); 403 $aImg->StyleLine($x1-$this->mark_abs_hsize,$marky+1,$x1+$this->mark_abs_hsize,$marky+1); 404 } 405 else { 406 // Draw a colored box 407 $color = $p[1] ; 408 409 // We make boxes slightly larger to better show 410 $boxsize = max($this->mark_abs_vsize,$this->mark_abs_hsize) + 2 ; 411 412 $ym = $marky-ceil($boxsize/2) ; // Marker y-coordinate 413 414 // We either need to plot a gradient or a 415 // pattern. To differentiate we use a kludge. 416 // Patterns have a p[3] value of < -100 417 if( $p[3] < -100 ) { 418 // p[1][0] == iPattern, p[1][1] == iPatternColor, p[1][2] == iPatternDensity 419 if( $patternFactory == null ) { 420 $patternFactory = new RectPatternFactory(); 421 } 422 $prect = $patternFactory->Create($p[1][0],$p[1][1],1); 423 $prect->SetBackground($p[1][3]); 424 $prect->SetDensity($p[1][2]+1); 425 $prect->SetPos(new Rectangle($x1,$ym,$boxsize,$boxsize)); 426 $prect->Stroke($aImg); 427 $prect=null; 428 } 429 else { 430 if( is_array($color) && count($color)==2 ) { 431 // The client want a gradient color 432 $grad->FilledRectangle($x1-$boxsize/2,$ym, 433 $x1+$boxsize/2,$ym+$boxsize, 434 $color[0],$color[1],-$p[3]); 435 } 436 else { 437 $aImg->SetColor($p[1]); 438 $aImg->FilledRectangle($x1-$boxsize/2,$ym, $x1+$boxsize/2,$ym+$boxsize); 439 } 440 441 // Draw a plot frame line 442 $aImg->SetColor($this->color); 443 $aImg->SetLineWeight($fillBoxFrameWeight); 444 $aImg->Rectangle($x1-$boxsize/2,$ym, 445 $x1+$boxsize/2,$ym+$boxsize); 446 } 447 } 448 $aImg->SetColor($this->font_color); 449 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 450 $aImg->SetTextAlign('left','baseline'); 451 452 $debug=false; 453 $aImg->StrokeText($x1+$this->mark_abs_hsize+$this->xmargin,$y1,$p[0], 454 0,'left',$debug); 455 456 // Add CSIM for Legend if defined 457 if( !empty($p[4]) ) { 458 459 $xs = $x1 - $this->mark_abs_hsize ; 460 $ys = $y1 + 1 ; 461 $xe = $x1 + $aImg->GetTextWidth($p[0]) + $this->mark_abs_hsize + $this->xmargin ; 462 $ye = $y1-$rowheight[$row]+1; 463 $coords = "$xs,$ys,$xe,$y1,$xe,$ye,$xs,$ye"; 464 if( ! empty($p[4]) ) { 465 $this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".htmlentities($p[4])."\""; 466 467 if( !empty($p[6]) ) { 468 $this->csimareas .= " target=\"".$p[6]."\""; 469 } 470 471 if( !empty($p[5]) ) { 472 $tmp=sprintf($p[5],$p[0]); 473 $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" "; 474 } 475 $this->csimareas .= " />\n"; 476 } 477 } 478 479 if( $i >= $this->layout_n ) { 480 $x1 = $xp+$this->xlmargin; 481 $row++; 482 if( !empty($rowheight[$row]) ) 483 $y1 += $rowheight[$row]; 484 $i = 1; 485 } 486 else { 487 $x1 += $colwidth[($i-1) % $numcolumns] ; 488 ++$i; 489 } 490 } 391 491 } 392 492 } // Class 393 493 394 494 ?> -
trunk/client/modules/Elezioni/grafici/jpgraph_line.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_LINE.PHP4 // Description:Line plot extension for JpGraph5 // Created:2001-01-086 // Ver: $Id: jpgraph_line.php 981 2008-03-24 11:51:12Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */3 // File: JPGRAPH_LINE.PHP 4 // Description: Line plot extension for JpGraph 5 // Created: 2001-01-08 6 // Ver: $Id: jpgraph_line.php 1921 2009-12-11 11:46:39Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 require_once ('jpgraph_plotmark.inc.php'); … … 20 20 //=================================================== 21 21 // CLASS LinePlot 22 // Description: 22 // Description: 23 23 //=================================================== 24 24 class LinePlot extends Plot{ … … 27 27 protected $fill_color='blue'; 28 28 protected $step_style=false, $center=false; 29 protected $line_style=1; 29 protected $line_style=1; // Default to solid 30 30 protected $filledAreas = array(); // array of arrays(with min,max,col,filled in them) 31 31 public $barcenter=false; // When we mix line and bar. Should we center the line in the bar. 32 protected $fillFromMin = false 32 protected $fillFromMin = false, $fillFromMax = false; 33 33 protected $fillgrad=false,$fillgrad_fromcolor='navy',$fillgrad_tocolor='silver',$fillgrad_numcolors=100; 34 34 protected $iFastStroke=false; 35 35 36 //--------------- 37 // CONSTRUCTOR 38 function LinePlot($datay,$datax=false) { 39 $this->Plot($datay,$datax); 40 $this->mark = new PlotMark() ; 41 } 42 //--------------- 43 // PUBLIC METHODS 44 45 // Set style, filled or open 46 function SetFilled($aFlag=true) { 47 JpGraphError::RaiseL(10001);//('LinePlot::SetFilled() is deprecated. Use SetFillColor()'); 48 } 49 36 //--------------- 37 // CONSTRUCTOR 38 function __construct($datay,$datax=false) { 39 parent::__construct($datay,$datax); 40 $this->mark = new PlotMark() ; 41 $this->color = ColorFactory::getColor(); 42 $this->fill_color = $this->color; 43 } 44 //--------------- 45 // PUBLIC METHODS 46 47 function SetFilled($aFlg=true) { 48 $this->filled = $aFlg; 49 } 50 50 51 function SetBarCenter($aFlag=true) { 51 52 $this->barcenter=$aFlag; 52 53 } 53 54 54 55 function SetStyle($aStyle) { 55 56 } 57 56 $this->line_style=$aStyle; 57 } 58 58 59 function SetStepStyle($aFlag=true) { 59 60 } 61 60 $this->step_style = $aFlag; 61 } 62 62 63 function SetColor($aColor) { 63 64 } 65 64 parent::SetColor($aColor); 65 } 66 66 67 function SetFillFromYMin($f=true) { 67 $this->fillFromMin = $f ; 68 } 69 68 $this->fillFromMin = $f ; 69 } 70 71 function SetFillFromYMax($f=true) { 72 $this->fillFromMax = $f ; 73 } 74 70 75 function SetFillColor($aColor,$aFilled=true) { 71 $this->fill_color=$aColor; 72 $this->filled=$aFilled; 76 //$this->color = $aColor; 77 $this->fill_color=$aColor; 78 $this->filled=$aFilled; 73 79 } 74 80 75 81 function SetFillGradient($aFromColor,$aToColor,$aNumColors=100,$aFilled=true) { 76 77 78 79 80 81 } 82 82 $this->fillgrad_fromcolor = $aFromColor; 83 $this->fillgrad_tocolor = $aToColor; 84 $this->fillgrad_numcolors = $aNumColors; 85 $this->filled = $aFilled; 86 $this->fillgrad = true; 87 } 88 83 89 function Legend($graph) { 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 } 90 if( $this->legend!="" ) { 91 if( $this->filled && !$this->fillgrad ) { 92 $graph->legend->Add($this->legend, 93 $this->fill_color,$this->mark,0, 94 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 95 } 96 elseif( $this->fillgrad ) { 97 $color=array($this->fillgrad_fromcolor,$this->fillgrad_tocolor); 98 // In order to differentiate between gradients and cooors specified as an RGB triple 99 $graph->legend->Add($this->legend,$color,"",-2 /* -GRAD_HOR */, 100 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 101 } else { 102 $graph->legend->Add($this->legend, 103 $this->color,$this->mark,$this->line_style, 104 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 105 } 106 } 101 107 } 102 108 103 109 function AddArea($aMin=0,$aMax=0,$aFilled=LP_AREA_NOT_FILLED,$aColor="gray9",$aBorder=LP_AREA_BORDER) { 104 105 106 107 108 109 } 110 111 } 112 110 if($aMin > $aMax) { 111 // swap 112 $tmp = $aMin; 113 $aMin = $aMax; 114 $aMax = $tmp; 115 } 116 $this->filledAreas[] = array($aMin,$aMax,$aColor,$aFilled,$aBorder); 117 } 118 113 119 // Gets called before any axis are stroked 114 120 function PreStrokeAdjust($graph) { 115 121 116 // If another plot type have already adjusted the 117 // offset we don't touch it. 118 // (We check for empty in case the scale is a log scale 119 // and hence doesn't contain any xlabel_offset) 120 if( empty($graph->xaxis->scale->ticks->xlabel_offset) || 121 $graph->xaxis->scale->ticks->xlabel_offset == 0 ) { 122 if( $this->center ) { 123 ++$this->numpoints; 124 $a=0.5; $b=0.5; 125 } else { 126 $a=0; $b=0; 127 } 128 $graph->xaxis->scale->ticks->SetXLabelOffset($a); 129 $graph->SetTextScaleOff($b); 130 //$graph->xaxis->scale->ticks->SupressMinorTickMarks(); 131 } 132 } 133 122 // If another plot type have already adjusted the 123 // offset we don't touch it. 124 // (We check for empty in case the scale is a log scale 125 // and hence doesn't contain any xlabel_offset) 126 if( empty($graph->xaxis->scale->ticks->xlabel_offset) || $graph->xaxis->scale->ticks->xlabel_offset == 0 ) { 127 if( $this->center ) { 128 ++$this->numpoints; 129 $a=0.5; $b=0.5; 130 } else { 131 $a=0; $b=0; 132 } 133 $graph->xaxis->scale->ticks->SetXLabelOffset($a); 134 $graph->SetTextScaleOff($b); 135 //$graph->xaxis->scale->ticks->SupressMinorTickMarks(); 136 } 137 } 138 134 139 function SetFastStroke($aFlg=true) { 135 140 $this->iFastStroke = $aFlg; 136 141 } 137 142 138 143 function FastStroke($img,$xscale,$yscale,$aStartPoint=0,$exist_x=true) { 139 // An optimized stroke for many data points with no extra 140 // features but 60% faster. You can't have values or line styles, or null 141 // values in plots. 142 $numpoints=count($this->coords[0]); 143 if( $this->barcenter ) 144 $textadj = 0.5-$xscale->text_scale_off; 145 else 146 $textadj = 0; 147 148 $img->SetColor($this->color); 149 $img->SetLineWeight($this->weight); 150 $pnts=$aStartPoint; 151 while( $pnts < $numpoints ) { 152 if( $exist_x ) $x=$this->coords[1][$pnts]; 153 else $x=$pnts+$textadj; 154 $xt = $xscale->Translate($x); 155 $y=$this->coords[0][$pnts]; 156 $yt = $yscale->Translate($y); 157 if( is_numeric($y) ) { 158 $cord[] = $xt; 159 $cord[] = $yt; 160 } 161 elseif( $y == '-' && $pnts > 0 ) { 162 // Just ignore 163 } 164 else { 165 JpGraphError::RaiseL(10002);//('Plot too complicated for fast line Stroke. Use standard Stroke()'); 166 } 167 ++$pnts; 168 } // WHILE 169 170 $img->Polygon($cord,false,true); 171 } 172 144 // An optimized stroke for many data points with no extra 145 // features but 60% faster. You can't have values or line styles, or null 146 // values in plots. 147 $numpoints=count($this->coords[0]); 148 if( $this->barcenter ) { 149 $textadj = 0.5-$xscale->text_scale_off; 150 } 151 else { 152 $textadj = 0; 153 } 154 155 $img->SetColor($this->color); 156 $img->SetLineWeight($this->weight); 157 $pnts=$aStartPoint; 158 while( $pnts < $numpoints ) { 159 if( $exist_x ) { 160 $x=$this->coords[1][$pnts]; 161 } 162 else { 163 $x=$pnts+$textadj; 164 } 165 $xt = $xscale->Translate($x); 166 $y=$this->coords[0][$pnts]; 167 $yt = $yscale->Translate($y); 168 if( is_numeric($y) ) { 169 $cord[] = $xt; 170 $cord[] = $yt; 171 } 172 elseif( $y == '-' && $pnts > 0 ) { 173 // Just ignore 174 } 175 else { 176 JpGraphError::RaiseL(10002);//('Plot too complicated for fast line Stroke. Use standard Stroke()'); 177 } 178 ++$pnts; 179 } // WHILE 180 181 $img->Polygon($cord,false,true); 182 } 183 173 184 function Stroke($img,$xscale,$yscale) { 174 $idx=0; 175 $numpoints=count($this->coords[0]); 176 if( isset($this->coords[1]) ) { 177 if( count($this->coords[1])!=$numpoints ) 178 JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints); 179 //("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints"); 180 else 181 $exist_x = true; 182 } 183 else 184 $exist_x = false; 185 186 if( $this->barcenter ) 187 $textadj = 0.5-$xscale->text_scale_off; 188 else 189 $textadj = 0; 190 191 // Find the first numeric data point 192 $startpoint=0; 193 while( $startpoint < $numpoints && !is_numeric($this->coords[0][$startpoint]) ) 194 ++$startpoint; 195 196 // Bail out if no data points 197 if( $startpoint == $numpoints ) 198 return; 199 200 if( $this->iFastStroke ) { 201 $this->FastStroke($img,$xscale,$yscale,$startpoint,$exist_x); 202 return; 203 } 204 205 if( $exist_x ) 206 $xs=$this->coords[1][$startpoint]; 207 else 208 $xs= $textadj+$startpoint; 209 210 $img->SetStartPoint($xscale->Translate($xs), 211 $yscale->Translate($this->coords[0][$startpoint])); 212 213 214 if( $this->filled ) { 215 $min = $yscale->GetMinVal(); 216 if( $min > 0 || $this->fillFromMin ) 217 $fillmin = $yscale->scale_abs[0];//Translate($min); 218 else 219 $fillmin = $yscale->Translate(0); 220 221 $cord[$idx++] = $xscale->Translate($xs); 222 $cord[$idx++] = $fillmin; 223 } 224 $xt = $xscale->Translate($xs); 225 $yt = $yscale->Translate($this->coords[0][$startpoint]); 226 $cord[$idx++] = $xt; 227 $cord[$idx++] = $yt; 228 $yt_old = $yt; 229 $xt_old = $xt; 230 $y_old = $this->coords[0][$startpoint]; 231 232 $this->value->Stroke($img,$this->coords[0][$startpoint],$xt,$yt); 233 234 $img->SetColor($this->color); 235 $img->SetLineWeight($this->weight); 236 $img->SetLineStyle($this->line_style); 237 $pnts=$startpoint+1; 238 $firstnonumeric = false; 239 240 241 while( $pnts < $numpoints ) { 242 243 if( $exist_x ) $x=$this->coords[1][$pnts]; 244 else $x=$pnts+$textadj; 245 $xt = $xscale->Translate($x); 246 $yt = $yscale->Translate($this->coords[0][$pnts]); 247 248 $y=$this->coords[0][$pnts]; 249 if( $this->step_style ) { 250 // To handle null values within step style we need to record the 251 // first non numeric value so we know from where to start if the 252 // non value is '-'. 253 if( is_numeric($y) ) { 254 $firstnonumeric = false; 255 if( is_numeric($y_old) ) { 256 $img->StyleLine($xt_old,$yt_old,$xt,$yt_old); 257 $img->StyleLine($xt,$yt_old,$xt,$yt); 258 } 259 elseif( $y_old == '-' ) { 260 $img->StyleLine($xt_first,$yt_first,$xt,$yt_first); 261 $img->StyleLine($xt,$yt_first,$xt,$yt); 262 } 263 else { 264 $yt_old = $yt; 265 $xt_old = $xt; 266 } 267 $cord[$idx++] = $xt; 268 $cord[$idx++] = $yt_old; 269 $cord[$idx++] = $xt; 270 $cord[$idx++] = $yt; 271 } 272 elseif( $firstnonumeric==false ) { 273 $firstnonumeric = true; 274 $yt_first = $yt_old; 275 $xt_first = $xt_old; 276 } 277 } 278 else { 279 $tmp1=$y; 280 $prev=$this->coords[0][$pnts-1]; 281 if( $tmp1==='' || $tmp1===NULL || $tmp1==='X' ) $tmp1 = 'x'; 282 if( $prev==='' || $prev===null || $prev==='X' ) $prev = 'x'; 283 284 if( is_numeric($y) || (is_string($y) && $y != '-') ) { 285 if( is_numeric($y) && (is_numeric($prev) || $prev === '-' ) ) { 286 $img->StyleLineTo($xt,$yt); 287 } 288 else { 289 $img->SetStartPoint($xt,$yt); 290 } 291 } 292 if( $this->filled && $tmp1 !== '-' ) { 293 if( $tmp1 === 'x' ) { 294 $cord[$idx++] = $cord[$idx-3]; 295 $cord[$idx++] = $fillmin; 296 } 297 elseif( $prev === 'x' ) { 298 $cord[$idx++] = $xt; 299 $cord[$idx++] = $fillmin; 300 $cord[$idx++] = $xt; 301 $cord[$idx++] = $yt; 302 } 303 else { 304 $cord[$idx++] = $xt; 305 $cord[$idx++] = $yt; 306 } 307 } 308 else { 309 if( is_numeric($tmp1) && (is_numeric($prev) || $prev === '-' ) ) { 310 $cord[$idx++] = $xt; 311 $cord[$idx++] = $yt; 312 } 313 } 314 } 315 $yt_old = $yt; 316 $xt_old = $xt; 317 $y_old = $y; 318 319 $this->StrokeDataValue($img,$this->coords[0][$pnts],$xt,$yt); 320 321 ++$pnts; 322 } 323 324 if( $this->filled ) { 325 $cord[$idx++] = $xt; 326 if( $min > 0 || $this->fillFromMin ) 327 $cord[$idx++] = $yscale->Translate($min); 328 else 329 $cord[$idx++] = $yscale->Translate(0); 330 if( $this->fillgrad ) { 331 $img->SetLineWeight(1); 332 $grad = new Gradient($img); 333 $grad->SetNumColors($this->fillgrad_numcolors); 334 $grad->FilledFlatPolygon($cord,$this->fillgrad_fromcolor,$this->fillgrad_tocolor); 335 $img->SetLineWeight($this->weight); 336 } 337 else { 338 $img->SetColor($this->fill_color); 339 $img->FilledPolygon($cord); 340 } 341 if( $this->line_weight > 0 ) { 342 $img->SetColor($this->color); 343 $img->Polygon($cord); 344 } 345 } 346 347 if(!empty($this->filledAreas)) { 348 349 $minY = $yscale->Translate($yscale->GetMinVal()); 350 $factor = ($this->step_style ? 4 : 2); 351 352 for($i = 0; $i < sizeof($this->filledAreas); ++$i) { 353 // go through all filled area elements ordered by insertion 354 // fill polygon array 355 $areaCoords[] = $cord[$this->filledAreas[$i][0] * $factor]; 356 $areaCoords[] = $minY; 357 358 $areaCoords = 359 array_merge($areaCoords, 360 array_slice($cord, 361 $this->filledAreas[$i][0] * $factor, 362 ($this->filledAreas[$i][1] - $this->filledAreas[$i][0] + ($this->step_style ? 0 : 1)) * $factor)); 363 $areaCoords[] = $areaCoords[sizeof($areaCoords)-2]; // last x 364 $areaCoords[] = $minY; // last y 365 366 if($this->filledAreas[$i][3]) { 367 $img->SetColor($this->filledAreas[$i][2]); 368 $img->FilledPolygon($areaCoords); 369 $img->SetColor($this->color); 370 } 371 // Check if we should draw the frame. 372 // If not we still re-draw the line since it might have been 373 // partially overwritten by the filled area and it doesn't look 374 // very good. 375 // TODO: The behaviour is undefined if the line does not have 376 // any line at the position of the area. 377 if( $this->filledAreas[$i][4] ) 378 $img->Polygon($areaCoords); 379 else 380 $img->Polygon($cord); 381 382 $areaCoords = array(); 383 } 384 } 385 386 if( $this->mark->type == -1 || $this->mark->show == false ) 387 return; 388 389 for( $pnts=0; $pnts<$numpoints; ++$pnts) { 390 391 if( $exist_x ) $x=$this->coords[1][$pnts]; 392 else $x=$pnts+$textadj; 393 $xt = $xscale->Translate($x); 394 $yt = $yscale->Translate($this->coords[0][$pnts]); 395 396 if( is_numeric($this->coords[0][$pnts]) ) { 397 if( !empty($this->csimtargets[$pnts]) ) { 398 if( !empty($this->csimwintargets[$pnts]) ) { 399 $this->mark->SetCSIMTarget($this->csimtargets[$pnts],$this->csimwintargets[$pnts]); 400 } 401 else { 402 $this->mark->SetCSIMTarget($this->csimtargets[$pnts]); 403 } 404 $this->mark->SetCSIMAlt($this->csimalts[$pnts]); 405 } 406 if( $exist_x ) 407 $x=$this->coords[1][$pnts]; 408 else 409 $x=$pnts; 410 $this->mark->SetCSIMAltVal($this->coords[0][$pnts],$x); 411 $this->mark->Stroke($img,$xt,$yt); 412 $this->csimareas .= $this->mark->GetCSIMAreas(); 413 } 414 } 185 $idx=0; 186 $numpoints=count($this->coords[0]); 187 if( isset($this->coords[1]) ) { 188 if( count($this->coords[1])!=$numpoints ) { 189 JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints); 190 //("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints"); 191 } 192 else { 193 $exist_x = true; 194 } 195 } 196 else { 197 $exist_x = false; 198 } 199 200 if( $this->barcenter ) { 201 $textadj = 0.5-$xscale->text_scale_off; 202 } 203 else { 204 $textadj = 0; 205 } 206 207 // Find the first numeric data point 208 $startpoint=0; 209 while( $startpoint < $numpoints && !is_numeric($this->coords[0][$startpoint]) ) { 210 ++$startpoint; 211 } 212 213 // Bail out if no data points 214 if( $startpoint == $numpoints ) return; 215 216 if( $this->iFastStroke ) { 217 $this->FastStroke($img,$xscale,$yscale,$startpoint,$exist_x); 218 return; 219 } 220 221 if( $exist_x ) { 222 $xs=$this->coords[1][$startpoint]; 223 } 224 else { 225 $xs= $textadj+$startpoint; 226 } 227 228 $img->SetStartPoint($xscale->Translate($xs), 229 $yscale->Translate($this->coords[0][$startpoint])); 230 231 if( $this->filled ) { 232 if( $this->fillFromMax ) { 233 //$max = $yscale->GetMaxVal(); 234 $cord[$idx++] = $xscale->Translate($xs); 235 $cord[$idx++] = $yscale->scale_abs[1]; 236 } 237 else { 238 $min = $yscale->GetMinVal(); 239 if( $min > 0 || $this->fillFromMin ) { 240 $fillmin = $yscale->scale_abs[0];//Translate($min); 241 } 242 else { 243 $fillmin = $yscale->Translate(0); 244 } 245 246 $cord[$idx++] = $xscale->Translate($xs); 247 $cord[$idx++] = $fillmin; 248 } 249 } 250 $xt = $xscale->Translate($xs); 251 $yt = $yscale->Translate($this->coords[0][$startpoint]); 252 $cord[$idx++] = $xt; 253 $cord[$idx++] = $yt; 254 $yt_old = $yt; 255 $xt_old = $xt; 256 $y_old = $this->coords[0][$startpoint]; 257 258 $this->value->Stroke($img,$this->coords[0][$startpoint],$xt,$yt); 259 260 $img->SetColor($this->color); 261 $img->SetLineWeight($this->weight); 262 $img->SetLineStyle($this->line_style); 263 $pnts=$startpoint+1; 264 $firstnonumeric = false; 265 266 267 while( $pnts < $numpoints ) { 268 269 if( $exist_x ) { 270 $x=$this->coords[1][$pnts]; 271 } 272 else { 273 $x=$pnts+$textadj; 274 } 275 $xt = $xscale->Translate($x); 276 $yt = $yscale->Translate($this->coords[0][$pnts]); 277 278 $y=$this->coords[0][$pnts]; 279 if( $this->step_style ) { 280 // To handle null values within step style we need to record the 281 // first non numeric value so we know from where to start if the 282 // non value is '-'. 283 if( is_numeric($y) ) { 284 $firstnonumeric = false; 285 if( is_numeric($y_old) ) { 286 $img->StyleLine($xt_old,$yt_old,$xt,$yt_old); 287 $img->StyleLine($xt,$yt_old,$xt,$yt); 288 } 289 elseif( $y_old == '-' ) { 290 $img->StyleLine($xt_first,$yt_first,$xt,$yt_first); 291 $img->StyleLine($xt,$yt_first,$xt,$yt); 292 } 293 else { 294 $yt_old = $yt; 295 $xt_old = $xt; 296 } 297 $cord[$idx++] = $xt; 298 $cord[$idx++] = $yt_old; 299 $cord[$idx++] = $xt; 300 $cord[$idx++] = $yt; 301 } 302 elseif( $firstnonumeric==false ) { 303 $firstnonumeric = true; 304 $yt_first = $yt_old; 305 $xt_first = $xt_old; 306 } 307 } 308 else { 309 $tmp1=$y; 310 $prev=$this->coords[0][$pnts-1]; 311 if( $tmp1==='' || $tmp1===NULL || $tmp1==='X' ) $tmp1 = 'x'; 312 if( $prev==='' || $prev===null || $prev==='X' ) $prev = 'x'; 313 314 if( is_numeric($y) || (is_string($y) && $y != '-') ) { 315 if( is_numeric($y) && (is_numeric($prev) || $prev === '-' ) ) { 316 $img->StyleLineTo($xt,$yt); 317 } 318 else { 319 $img->SetStartPoint($xt,$yt); 320 } 321 } 322 if( $this->filled && $tmp1 !== '-' ) { 323 if( $tmp1 === 'x' ) { 324 $cord[$idx++] = $cord[$idx-3]; 325 $cord[$idx++] = $fillmin; 326 } 327 elseif( $prev === 'x' ) { 328 $cord[$idx++] = $xt; 329 $cord[$idx++] = $fillmin; 330 $cord[$idx++] = $xt; 331 $cord[$idx++] = $yt; 332 } 333 else { 334 $cord[$idx++] = $xt; 335 $cord[$idx++] = $yt; 336 } 337 } 338 else { 339 if( is_numeric($tmp1) && (is_numeric($prev) || $prev === '-' ) ) { 340 $cord[$idx++] = $xt; 341 $cord[$idx++] = $yt; 342 } 343 } 344 } 345 $yt_old = $yt; 346 $xt_old = $xt; 347 $y_old = $y; 348 349 $this->StrokeDataValue($img,$this->coords[0][$pnts],$xt,$yt); 350 351 ++$pnts; 352 } 353 354 if( $this->filled ) { 355 $cord[$idx++] = $xt; 356 if( $this->fillFromMax ) { 357 $cord[$idx++] = $yscale->scale_abs[1]; 358 } 359 else { 360 if( $min > 0 || $this->fillFromMin ) { 361 $cord[$idx++] = $yscale->Translate($min); 362 } 363 else { 364 $cord[$idx++] = $yscale->Translate(0); 365 } 366 } 367 if( $this->fillgrad ) { 368 $img->SetLineWeight(1); 369 $grad = new Gradient($img); 370 $grad->SetNumColors($this->fillgrad_numcolors); 371 $grad->FilledFlatPolygon($cord,$this->fillgrad_fromcolor,$this->fillgrad_tocolor); 372 $img->SetLineWeight($this->weight); 373 } 374 else { 375 $img->SetColor($this->fill_color); 376 $img->FilledPolygon($cord); 377 } 378 if( $this->weight > 0 ) { 379 $img->SetLineWeight($this->weight); 380 $img->SetColor($this->color); 381 // Remove first and last coordinate before drawing the line 382 // sine we otherwise get the vertical start and end lines which 383 // doesn't look appropriate 384 $img->Polygon(array_slice($cord,2,count($cord)-4)); 385 } 386 } 387 388 if(!empty($this->filledAreas)) { 389 390 $minY = $yscale->Translate($yscale->GetMinVal()); 391 $factor = ($this->step_style ? 4 : 2); 392 393 for($i = 0; $i < sizeof($this->filledAreas); ++$i) { 394 // go through all filled area elements ordered by insertion 395 // fill polygon array 396 $areaCoords[] = $cord[$this->filledAreas[$i][0] * $factor]; 397 $areaCoords[] = $minY; 398 399 $areaCoords = 400 array_merge($areaCoords, 401 array_slice($cord, 402 $this->filledAreas[$i][0] * $factor, 403 ($this->filledAreas[$i][1] - $this->filledAreas[$i][0] + ($this->step_style ? 0 : 1)) * $factor)); 404 $areaCoords[] = $areaCoords[sizeof($areaCoords)-2]; // last x 405 $areaCoords[] = $minY; // last y 406 407 if($this->filledAreas[$i][3]) { 408 $img->SetColor($this->filledAreas[$i][2]); 409 $img->FilledPolygon($areaCoords); 410 $img->SetColor($this->color); 411 } 412 // Check if we should draw the frame. 413 // If not we still re-draw the line since it might have been 414 // partially overwritten by the filled area and it doesn't look 415 // very good. 416 if( $this->filledAreas[$i][4] ) { 417 $img->Polygon($areaCoords); 418 } 419 else { 420 $img->Polygon($cord); 421 } 422 423 $areaCoords = array(); 424 } 425 } 426 427 if( $this->mark->type == -1 || $this->mark->show == false ) 428 return; 429 430 for( $pnts=0; $pnts<$numpoints; ++$pnts) { 431 432 if( $exist_x ) { 433 $x=$this->coords[1][$pnts]; 434 } 435 else { 436 $x=$pnts+$textadj; 437 } 438 $xt = $xscale->Translate($x); 439 $yt = $yscale->Translate($this->coords[0][$pnts]); 440 441 if( is_numeric($this->coords[0][$pnts]) ) { 442 if( !empty($this->csimtargets[$pnts]) ) { 443 if( !empty($this->csimwintargets[$pnts]) ) { 444 $this->mark->SetCSIMTarget($this->csimtargets[$pnts],$this->csimwintargets[$pnts]); 445 } 446 else { 447 $this->mark->SetCSIMTarget($this->csimtargets[$pnts]); 448 } 449 $this->mark->SetCSIMAlt($this->csimalts[$pnts]); 450 } 451 if( $exist_x ) { 452 $x=$this->coords[1][$pnts]; 453 } 454 else { 455 $x=$pnts; 456 } 457 $this->mark->SetCSIMAltVal($this->coords[0][$pnts],$x); 458 $this->mark->Stroke($img,$xt,$yt); 459 $this->csimareas .= $this->mark->GetCSIMAreas(); 460 } 461 } 415 462 } 416 463 } // Class … … 419 466 //=================================================== 420 467 // CLASS AccLinePlot 421 // Description: 468 // Description: 422 469 //=================================================== 423 470 class AccLinePlot extends Plot { 424 471 protected $plots=null,$nbrplots=0; 425 472 private $iStartEndZero=true; 426 //---------------427 // CONSTRUCTOR428 function AccLinePlot($plots) {473 //--------------- 474 // CONSTRUCTOR 475 function __construct($plots) { 429 476 $this->plots = $plots; 430 431 432 433 434 435 436 437 438 } 439 440 441 442 } 443 } 444 445 //---------------446 // PUBLIC METHODS 477 $this->nbrplots = count($plots); 478 $this->numpoints = $plots[0]->numpoints; 479 480 // Verify that all plots have the same number of data points 481 for( $i=1; $i < $this->nbrplots; ++$i ) { 482 if( $plots[$i]->numpoints != $this->numpoints ) { 483 JpGraphError::RaiseL(10003);//('Each plot in an accumulated lineplot must have the same number of data points',0) 484 } 485 } 486 487 for($i=0; $i < $this->nbrplots; ++$i ) { 488 $this->LineInterpolate($this->plots[$i]->coords[0]); 489 } 490 } 491 492 //--------------- 493 // PUBLIC METHODS 447 494 function Legend($graph) { 448 foreach( $this->plots as $p ) 449 $p->DoLegend($graph); 450 } 451 495 foreach( $this->plots as $p ) { 496 $p->DoLegend($graph); 497 } 498 } 499 452 500 function Max() { 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 } 501 list($xmax) = $this->plots[0]->Max(); 502 $nmax=0; 503 $n = count($this->plots); 504 for($i=0; $i < $n; ++$i) { 505 $nc = count($this->plots[$i]->coords[0]); 506 $nmax = max($nmax,$nc); 507 list($x) = $this->plots[$i]->Max(); 508 $xmax = Max($xmax,$x); 509 } 510 for( $i = 0; $i < $nmax; $i++ ) { 511 // Get y-value for line $i by adding the 512 // individual bars from all the plots added. 513 // It would be wrong to just add the 514 // individual plots max y-value since that 515 // would in most cases give to large y-value. 516 $y=$this->plots[0]->coords[0][$i]; 517 for( $j = 1; $j < $this->nbrplots; $j++ ) { 518 $y += $this->plots[ $j ]->coords[0][$i]; 519 } 520 $ymax[$i] = $y; 521 } 522 $ymax = max($ymax); 523 return array($xmax,$ymax); 524 } 477 525 478 526 function Min() { 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 527 $nmax=0; 528 list($xmin,$ysetmin) = $this->plots[0]->Min(); 529 $n = count($this->plots); 530 for($i=0; $i < $n; ++$i) { 531 $nc = count($this->plots[$i]->coords[0]); 532 $nmax = max($nmax,$nc); 533 list($x,$y) = $this->plots[$i]->Min(); 534 $xmin = Min($xmin,$x); 535 $ysetmin = Min($y,$ysetmin); 536 } 537 for( $i = 0; $i < $nmax; $i++ ) { 538 // Get y-value for line $i by adding the 539 // individual bars from all the plots added. 540 // It would be wrong to just add the 541 // individual plots min y-value since that 542 // would in most cases give to small y-value. 543 $y=$this->plots[0]->coords[0][$i]; 544 for( $j = 1; $j < $this->nbrplots; $j++ ) { 545 $y += $this->plots[ $j ]->coords[0][$i]; 546 } 547 $ymin[$i] = $y; 548 } 549 $ymin = Min($ysetmin,Min($ymin)); 550 return array($xmin,$ymin); 503 551 } 504 552 … … 506 554 function PreStrokeAdjust($graph) { 507 555 508 509 510 // (We check for empty in case the scale is a log scale 511 512 513 514 515 516 517 518 519 520 521 522 $graph->SetTextScaleOff($b); 523 524 525 556 // If another plot type have already adjusted the 557 // offset we don't touch it. 558 // (We check for empty in case the scale is a log scale 559 // and hence doesn't contain any xlabel_offset) 560 561 if( empty($graph->xaxis->scale->ticks->xlabel_offset) || 562 $graph->xaxis->scale->ticks->xlabel_offset == 0 ) { 563 if( $this->center ) { 564 ++$this->numpoints; 565 $a=0.5; $b=0.5; 566 } else { 567 $a=0; $b=0; 568 } 569 $graph->xaxis->scale->ticks->SetXLabelOffset($a); 570 $graph->SetTextScaleOff($b); 571 $graph->xaxis->scale->ticks->SupressMinorTickMarks(); 572 } 573 526 574 } 527 575 528 576 function SetInterpolateMode($aIntMode) { 529 577 $this->iStartEndZero=$aIntMode; 530 578 } 531 579 … … 535 583 function LineInterpolate(&$aData) { 536 584 537 $n=count($aData); 538 $i=0; 539 540 // If first point is undefined we will set it to the same as the first 541 // valid data 542 if( $aData[$i]==='-' ) { 543 // Find the first valid data 544 while( $i < $n && $aData[$i]==='-' ) { 545 ++$i; 546 } 547 if( $i < $n ) { 548 for($j=0; $j < $i; ++$j ) { 549 if( $this->iStartEndZero ) 550 $aData[$i] = 0; 551 else 552 $aData[$j] = $aData[$i]; 553 } 554 } 555 else { 556 // All '-' => Error 557 return false; 558 } 559 } 560 561 while($i < $n) { 562 while( $i < $n && $aData[$i] !== '-' ) { 563 ++$i; 564 } 565 if( $i < $n ) { 566 $pstart=$i-1; 567 568 // Now see how long this segment of '-' are 569 while( $i < $n && $aData[$i] === '-' ) 570 ++$i; 571 if( $i < $n ) { 572 $pend=$i; 573 $size=$pend-$pstart; 574 $k=($aData[$pend]-$aData[$pstart])/$size; 575 // Replace the segment of '-' with a linear interpolated value. 576 for($j=1; $j < $size; ++$j ) { 577 $aData[$pstart+$j] = $aData[$pstart] + $j*$k ; 578 } 579 } 580 else { 581 // There are no valid end point. The '-' goes all the way to the end 582 // In that case we just set all the remaining values the the same as the 583 // last valid data point. 584 for( $j=$pstart+1; $j < $n; ++$j ) 585 if( $this->iStartEndZero ) 586 $aData[$j] = 0; 587 else 588 $aData[$j] = $aData[$pstart] ; 589 } 590 } 591 } 592 return true; 593 } 594 595 585 $n=count($aData); 586 $i=0; 587 588 // If first point is undefined we will set it to the same as the first 589 // valid data 590 if( $aData[$i]==='-' ) { 591 // Find the first valid data 592 while( $i < $n && $aData[$i]==='-' ) { 593 ++$i; 594 } 595 if( $i < $n ) { 596 for($j=0; $j < $i; ++$j ) { 597 if( $this->iStartEndZero ) 598 $aData[$i] = 0; 599 else 600 $aData[$j] = $aData[$i]; 601 } 602 } 603 else { 604 // All '-' => Error 605 return false; 606 } 607 } 608 609 while($i < $n) { 610 while( $i < $n && $aData[$i] !== '-' ) { 611 ++$i; 612 } 613 if( $i < $n ) { 614 $pstart=$i-1; 615 616 // Now see how long this segment of '-' are 617 while( $i < $n && $aData[$i] === '-' ) { 618 ++$i; 619 } 620 if( $i < $n ) { 621 $pend=$i; 622 $size=$pend-$pstart; 623 $k=($aData[$pend]-$aData[$pstart])/$size; 624 // Replace the segment of '-' with a linear interpolated value. 625 for($j=1; $j < $size; ++$j ) { 626 $aData[$pstart+$j] = $aData[$pstart] + $j*$k ; 627 } 628 } 629 else { 630 // There are no valid end point. The '-' goes all the way to the end 631 // In that case we just set all the remaining values the the same as the 632 // last valid data point. 633 for( $j=$pstart+1; $j < $n; ++$j ) 634 if( $this->iStartEndZero ) { 635 $aData[$j] = 0; 636 } 637 else { 638 $aData[$j] = $aData[$pstart] ; 639 } 640 } 641 } 642 } 643 return true; 644 } 596 645 597 646 // To avoid duplicate of line drawing code here we just … … 602 651 // since this method would have a side effect. 603 652 function Stroke($img,$xscale,$yscale) { 604 $img->SetLineWeight($this->weight); 605 $this->numpoints = count($this->plots[0]->coords[0]); 606 // Allocate array 607 $coords[$this->nbrplots][$this->numpoints]=0; 608 for($i=0; $i<$this->numpoints; $i++) { 609 $coords[0][$i]=$this->plots[0]->coords[0][$i]; 610 $accy=$coords[0][$i]; 611 for($j=1; $j<$this->nbrplots; ++$j ) { 612 $coords[$j][$i] = $this->plots[$j]->coords[0][$i]+$accy; 613 $accy = $coords[$j][$i]; 614 } 615 } 616 for($j=$this->nbrplots-1; $j>=0; --$j) { 617 $p=$this->plots[$j]; 618 for( $i=0; $i<$this->numpoints; ++$i) { 619 $tmp[$i]=$p->coords[0][$i]; 620 $p->coords[0][$i]=$coords[$j][$i]; 621 } 622 $p->Stroke($img,$xscale,$yscale); 623 for( $i=0; $i<$this->numpoints; ++$i) 624 $p->coords[0][$i]=$tmp[$i]; 625 $p->coords[0][]=$tmp; 626 } 653 $img->SetLineWeight($this->weight); 654 $this->numpoints = count($this->plots[0]->coords[0]); 655 // Allocate array 656 $coords[$this->nbrplots][$this->numpoints]=0; 657 for($i=0; $i<$this->numpoints; $i++) { 658 $coords[0][$i]=$this->plots[0]->coords[0][$i]; 659 $accy=$coords[0][$i]; 660 for($j=1; $j<$this->nbrplots; ++$j ) { 661 $coords[$j][$i] = $this->plots[$j]->coords[0][$i]+$accy; 662 $accy = $coords[$j][$i]; 663 } 664 } 665 for($j=$this->nbrplots-1; $j>=0; --$j) { 666 $p=$this->plots[$j]; 667 for( $i=0; $i<$this->numpoints; ++$i) { 668 $tmp[$i]=$p->coords[0][$i]; 669 $p->coords[0][$i]=$coords[$j][$i]; 670 } 671 $p->Stroke($img,$xscale,$yscale); 672 for( $i=0; $i<$this->numpoints; ++$i) { 673 $p->coords[0][$i]=$tmp[$i]; 674 } 675 $p->coords[0][]=$tmp; 676 } 627 677 } 628 678 } // Class -
trunk/client/modules/Elezioni/grafici/jpgraph_log.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_LOG.PHP4 // Description:Log scale plot extension for JpGraph5 // Created:2001-01-086 // Ver: $Id: jpgraph_log.php 957 2007-12-01 14:00:29Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */3 // File: JPGRAPH_LOG.PHP 4 // Description: Log scale plot extension for JpGraph 5 // Created: 2001-01-08 6 // Ver: $Id: jpgraph_log.php 1106 2009-02-22 20:16:35Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 DEFINE('LOGLABELS_PLAIN',0); … … 18 18 //=================================================== 19 19 class LogScale extends LinearScale { 20 //---------------21 // CONSTRUCTOR20 //--------------- 21 // CONSTRUCTOR 22 22 23 23 // Log scale is specified using the log of min and max 24 function LogScale($min,$max,$type="y") {25 $this->LinearScale($min,$max,$type);26 27 28 } 29 30 //----------------31 // PUBLIC METHODS 24 function __construct($min,$max,$type="y") { 25 parent::__construct($min,$max,$type); 26 $this->ticks = new LogTicks(); 27 $this->name = 'log'; 28 } 29 30 //---------------- 31 // PUBLIC METHODS 32 32 33 33 // Translate between world and screen 34 34 function Translate($a) { 35 if( !is_numeric($a) ) { 36 if( $a != '' && $a != '-' && $a != 'x' ) 37 JpGraphError::RaiseL(11001); 38 //('Your data contains non-numeric values.'); 39 return 1; 40 } 41 if( $a < 0 ) { 42 JpGraphError::RaiseL(11002); 43 //("Negative data values can not be used in a log scale."); 44 exit(1); 45 } 46 if( $a==0 ) $a=1; 47 $a=log10($a); 48 return ceil($this->off + ($a*1.0 - $this->scale[0]) * $this->scale_factor); 35 if( !is_numeric($a) ) { 36 if( $a != '' && $a != '-' && $a != 'x' ) { 37 JpGraphError::RaiseL(11001); 38 // ('Your data contains non-numeric values.'); 39 } 40 return 1; 41 } 42 if( $a < 0 ) { 43 JpGraphError::RaiseL(11002); 44 //("Negative data values can not be used in a log scale."); 45 exit(1); 46 } 47 if( $a==0 ) $a=1; 48 $a=log10($a); 49 return ceil($this->off + ($a*1.0 - $this->scale[0]) * $this->scale_factor); 49 50 } 50 51 51 52 // Relative translate (don't include offset) usefull when we just want 52 // to know the relative position (in pixels) on the axis 53 // to know the relative position (in pixels) on the axis 53 54 function RelTranslate($a) { 54 if( !is_numeric($a) ) { 55 if( $a != '' && $a != '-' && $a != 'x' ) 56 JpGraphError::RaiseL(11001); 57 //('Your data contains non-numeric values.'); 58 return 1; 59 } 60 if( $a==0 ) $a=1; 61 $a=log10($a); 62 return round(($a*1.0 - $this->scale[0]) * $this->scale_factor); 63 } 64 55 if( !is_numeric($a) ) { 56 if( $a != '' && $a != '-' && $a != 'x' ) { 57 JpGraphError::RaiseL(11001); 58 //('Your data contains non-numeric values.'); 59 } 60 return 1; 61 } 62 if( $a==0 ) { 63 $a=1; 64 } 65 $a=log10($a); 66 return round(($a*1.0 - $this->scale[0]) * $this->scale_factor); 67 } 68 65 69 // Use bcpow() for increased precision 66 70 function GetMinVal() { 67 if( function_exists("bcpow") ) 68 return round(bcpow(10,$this->scale[0],15),14); 69 else 70 return round(pow(10,$this->scale[0]),14); 71 } 72 71 if( function_exists("bcpow") ) { 72 return round(bcpow(10,$this->scale[0],15),14); 73 } 74 else { 75 return round(pow(10,$this->scale[0]),14); 76 } 77 } 78 73 79 function GetMaxVal() { 74 if( function_exists("bcpow") ) 75 return round(bcpow(10,$this->scale[1],15),14); 76 else 77 return round(pow(10,$this->scale[1]),14); 78 } 79 80 if( function_exists("bcpow") ) { 81 return round(bcpow(10,$this->scale[1],15),14); 82 } 83 else { 84 return round(pow(10,$this->scale[1]),14); 85 } 86 } 87 80 88 // Logarithmic autoscaling is much simplier since we just 81 89 // set the min and max to logs of the min and max values. … … 84 92 // signature as the linear counterpart. 85 93 function AutoScale($img,$min,$max,$maxsteps,$majend=true) { 86 87 88 89 90 //('Scale error for logarithmic scale. You have a problem with your data values. The max value must be greater than 0. It is mathematically impossible to have 0 in a logarithmic scale.');91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 $this->Update($img,$smin,$smax); 112 } 113 //---------------114 // PRIVATE METHODS 94 if( $min==0 ) $min=1; 95 96 if( $max <= 0 ) { 97 JpGraphError::RaiseL(11004); 98 //('Scale error for logarithmic scale. You have a problem with your data values. The max value must be greater than 0. It is mathematically impossible to have 0 in a logarithmic scale.'); 99 } 100 if( is_numeric($this->autoscale_min) ) { 101 $smin = round($this->autoscale_min); 102 $smax = ceil(log10($max)); 103 if( $min >= $max ) { 104 JpGraphError::RaiseL(25071);//('You have specified a min value with SetAutoMin() which is larger than the maximum value used for the scale. This is not possible.'); 105 } 106 } 107 else { 108 $smin = floor(log10($min)); 109 if( is_numeric($this->autoscale_max) ) { 110 $smax = round($this->autoscale_max); 111 if( $smin >= $smax ) { 112 JpGraphError::RaiseL(25072);//('You have specified a max value with SetAutoMax() which is smaller than the miminum value used for the scale. This is not possible.'); 113 } 114 } 115 else 116 $smax = ceil(log10($max)); 117 } 118 119 $this->Update($img,$smin,$smax); 120 } 121 //--------------- 122 // PRIVATE METHODS 115 123 } // Class 116 124 117 125 //=================================================== 118 126 // CLASS LogTicks 119 // Description: 127 // Description: 120 128 //=================================================== 121 129 class LogTicks extends Ticks{ 122 130 private $label_logtype=LOGLABELS_MAGNITUDE; 123 131 private $ticklabels_pos = array(); 124 //---------------125 // CONSTRUCTOR126 function LogTicks() {127 } 128 //---------------129 // PUBLIC METHODS 132 //--------------- 133 // CONSTRUCTOR 134 function __construct() { 135 } 136 //--------------- 137 // PUBLIC METHODS 130 138 function IsSpecified() { 131 139 return true; 132 140 } 133 141 134 142 function SetLabelLogType($aType) { 135 136 } 137 143 $this->label_logtype = $aType; 144 } 145 138 146 // For log scale it's meaningless to speak about a major step 139 147 // We just return -1 to make the framework happy (specifically 140 148 // StrokeLabels() ) 141 149 function GetMajor() { 142 150 return -1; 143 151 } 144 152 145 153 function SetTextLabelStart($aStart) { 146 147 //('Specifying tick interval for a logarithmic scale is undefined. Remove any calls to SetTextLabelStart() or SetTextTickInterval() on the logarithmic scale.');154 JpGraphError::RaiseL(11005); 155 //('Specifying tick interval for a logarithmic scale is undefined. Remove any calls to SetTextLabelStart() or SetTextTickInterval() on the logarithmic scale.'); 148 156 } 149 157 150 158 function SetXLabelOffset($dummy) { 151 159 // For log scales we dont care about XLabel offset 152 160 } 153 161 … … 157 165 // absolute x-position. 158 166 function Stroke($img,$scale,$pos) { 159 $start = $scale->GetMinVal(); 160 $limit = $scale->GetMaxVal(); 161 $nextMajor = 10*$start; 162 $step = $nextMajor / 10.0; 163 164 165 $img->SetLineWeight($this->weight); 166 167 if( $scale->type == "y" ) { 168 // member direction specified if the ticks should be on 169 // left or right side. 170 $a=$pos + $this->direction*$this->GetMinTickAbsSize(); 171 $a2=$pos + $this->direction*$this->GetMajTickAbsSize(); 172 173 $count=1; 174 $this->maj_ticks_pos[0]=$scale->Translate($start); 175 $this->maj_ticklabels_pos[0]=$scale->Translate($start); 176 if( $this->supress_first ) 177 $this->maj_ticks_label[0]=""; 178 else { 179 if( $this->label_formfunc != '' ) { 180 $f = $this->label_formfunc; 181 $this->maj_ticks_label[0]=call_user_func($f,$start); 182 } 183 elseif( $this->label_logtype == LOGLABELS_PLAIN ) 184 $this->maj_ticks_label[0]=$start; 185 else 186 $this->maj_ticks_label[0]='10^'.round(log10($start)); 187 } 188 $i=1; 189 for($y=$start; $y<=$limit; $y+=$step,++$count ) { 190 $ys=$scale->Translate($y); 191 $this->ticks_pos[]=$ys; 192 $this->ticklabels_pos[]=$ys; 193 if( $count % 10 == 0 ) { 194 if( !$this->supress_tickmarks ) { 195 if( $this->majcolor!="" ) { 196 $img->PushColor($this->majcolor); 197 $img->Line($pos,$ys,$a2,$ys); 198 $img->PopColor(); 199 } 200 else 201 $img->Line($pos,$ys,$a2,$ys); 202 } 203 204 $this->maj_ticks_pos[$i]=$ys; 205 $this->maj_ticklabels_pos[$i]=$ys; 206 207 if( $this->label_formfunc != '' ) { 208 $f = $this->label_formfunc; 209 $this->maj_ticks_label[$i]=call_user_func($f,$nextMajor); 210 } 211 elseif( $this->label_logtype == 0 ) 212 $this->maj_ticks_label[$i]=$nextMajor; 213 else 214 $this->maj_ticks_label[$i]='10^'.round(log10($nextMajor)); 215 ++$i; 216 $nextMajor *= 10; 217 $step *= 10; 218 $count=1; 219 } 220 else { 221 if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) { 222 if( $this->mincolor!="" ) $img->PushColor($this->mincolor); 223 $img->Line($pos,$ys,$a,$ys); 224 if( $this->mincolor!="" ) $img->PopColor(); 225 } 226 } 227 } 228 } 229 else { 230 $a=$pos - $this->direction*$this->GetMinTickAbsSize(); 231 $a2=$pos - $this->direction*$this->GetMajTickAbsSize(); 232 $count=1; 233 $this->maj_ticks_pos[0]=$scale->Translate($start); 234 $this->maj_ticklabels_pos[0]=$scale->Translate($start); 235 if( $this->supress_first ) 236 $this->maj_ticks_label[0]=""; 237 else { 238 if( $this->label_formfunc != '' ) { 239 $f = $this->label_formfunc; 240 $this->maj_ticks_label[0]=call_user_func($f,$start); 241 } 242 elseif( $this->label_logtype == 0 ) 243 $this->maj_ticks_label[0]=$start; 244 else 245 $this->maj_ticks_label[0]='10^'.round(log10($start)); 246 } 247 $i=1; 248 for($x=$start; $x<=$limit; $x+=$step,++$count ) { 249 $xs=$scale->Translate($x); 250 $this->ticks_pos[]=$xs; 251 $this->ticklabels_pos[]=$xs; 252 if( $count % 10 == 0 ) { 253 if( !$this->supress_tickmarks ) { 254 $img->Line($xs,$pos,$xs,$a2); 255 } 256 $this->maj_ticks_pos[$i]=$xs; 257 $this->maj_ticklabels_pos[$i]=$xs; 258 259 if( $this->label_formfunc != '' ) { 260 $f = $this->label_formfunc; 261 $this->maj_ticks_label[$i]=call_user_func($f,$nextMajor); 262 } 263 elseif( $this->label_logtype == 0 ) 264 $this->maj_ticks_label[$i]=$nextMajor; 265 else 266 $this->maj_ticks_label[$i]='10^'.round(log10($nextMajor)); 267 ++$i; 268 $nextMajor *= 10; 269 $step *= 10; 270 $count=1; 271 } 272 else { 273 if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) { 274 $img->Line($xs,$pos,$xs,$a); 275 } 276 } 277 } 278 } 279 return true; 167 $start = $scale->GetMinVal(); 168 $limit = $scale->GetMaxVal(); 169 $nextMajor = 10*$start; 170 $step = $nextMajor / 10.0; 171 172 173 $img->SetLineWeight($this->weight); 174 175 if( $scale->type == "y" ) { 176 // member direction specified if the ticks should be on 177 // left or right side. 178 $a=$pos + $this->direction*$this->GetMinTickAbsSize(); 179 $a2=$pos + $this->direction*$this->GetMajTickAbsSize(); 180 181 $count=1; 182 $this->maj_ticks_pos[0]=$scale->Translate($start); 183 $this->maj_ticklabels_pos[0]=$scale->Translate($start); 184 if( $this->supress_first ) 185 $this->maj_ticks_label[0]=""; 186 else { 187 if( $this->label_formfunc != '' ) { 188 $f = $this->label_formfunc; 189 $this->maj_ticks_label[0]=call_user_func($f,$start); 190 } 191 elseif( $this->label_logtype == LOGLABELS_PLAIN ) { 192 $this->maj_ticks_label[0]=$start; 193 } 194 else { 195 $this->maj_ticks_label[0]='10^'.round(log10($start)); 196 } 197 } 198 $i=1; 199 for($y=$start; $y<=$limit; $y+=$step,++$count ) { 200 $ys=$scale->Translate($y); 201 $this->ticks_pos[]=$ys; 202 $this->ticklabels_pos[]=$ys; 203 if( $count % 10 == 0 ) { 204 if( !$this->supress_tickmarks ) { 205 if( $this->majcolor!="" ) { 206 $img->PushColor($this->majcolor); 207 $img->Line($pos,$ys,$a2,$ys); 208 $img->PopColor(); 209 } 210 else { 211 $img->Line($pos,$ys,$a2,$ys); 212 } 213 } 214 215 $this->maj_ticks_pos[$i]=$ys; 216 $this->maj_ticklabels_pos[$i]=$ys; 217 218 if( $this->label_formfunc != '' ) { 219 $f = $this->label_formfunc; 220 $this->maj_ticks_label[$i]=call_user_func($f,$nextMajor); 221 } 222 elseif( $this->label_logtype == 0 ) { 223 $this->maj_ticks_label[$i]=$nextMajor; 224 } 225 else { 226 $this->maj_ticks_label[$i]='10^'.round(log10($nextMajor)); 227 } 228 ++$i; 229 $nextMajor *= 10; 230 $step *= 10; 231 $count=1; 232 } 233 else { 234 if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) { 235 if( $this->mincolor!="" ) { 236 $img->PushColor($this->mincolor); 237 } 238 $img->Line($pos,$ys,$a,$ys); 239 if( $this->mincolor!="" ) { 240 $img->PopColor(); 241 } 242 } 243 } 244 } 245 } 246 else { 247 $a=$pos - $this->direction*$this->GetMinTickAbsSize(); 248 $a2=$pos - $this->direction*$this->GetMajTickAbsSize(); 249 $count=1; 250 $this->maj_ticks_pos[0]=$scale->Translate($start); 251 $this->maj_ticklabels_pos[0]=$scale->Translate($start); 252 if( $this->supress_first ) { 253 $this->maj_ticks_label[0]=""; 254 } 255 else { 256 if( $this->label_formfunc != '' ) { 257 $f = $this->label_formfunc; 258 $this->maj_ticks_label[0]=call_user_func($f,$start); 259 } 260 elseif( $this->label_logtype == 0 ) { 261 $this->maj_ticks_label[0]=$start; 262 } 263 else { 264 $this->maj_ticks_label[0]='10^'.round(log10($start)); 265 } 266 } 267 $i=1; 268 for($x=$start; $x<=$limit; $x+=$step,++$count ) { 269 $xs=$scale->Translate($x); 270 $this->ticks_pos[]=$xs; 271 $this->ticklabels_pos[]=$xs; 272 if( $count % 10 == 0 ) { 273 if( !$this->supress_tickmarks ) { 274 $img->Line($xs,$pos,$xs,$a2); 275 } 276 $this->maj_ticks_pos[$i]=$xs; 277 $this->maj_ticklabels_pos[$i]=$xs; 278 279 if( $this->label_formfunc != '' ) { 280 $f = $this->label_formfunc; 281 $this->maj_ticks_label[$i]=call_user_func($f,$nextMajor); 282 } 283 elseif( $this->label_logtype == 0 ) { 284 $this->maj_ticks_label[$i]=$nextMajor; 285 } 286 else { 287 $this->maj_ticks_label[$i]='10^'.round(log10($nextMajor)); 288 } 289 ++$i; 290 $nextMajor *= 10; 291 $step *= 10; 292 $count=1; 293 } 294 else { 295 if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) { 296 $img->Line($xs,$pos,$xs,$a); 297 } 298 } 299 } 300 } 301 return true; 280 302 } 281 303 } // Class -
trunk/client/modules/Elezioni/grafici/jpgraph_mgraph.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_MGRAPH.PHP4 // Description: Class to handle multiple graphs in the same image5 // Created:2006-01-156 // Ver: $Id: jpgraph_mgraph.php 1012 2008-06-23 15:02:15Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */3 // File: JPGRAPH_MGRAPH.PHP 4 // Description: Class to handle multiple graphs in the same image 5 // Created: 2006-01-15 6 // Ver: $Id: jpgraph_mgraph.php 1770 2009-08-17 06:10:22Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 //============================================================================= 13 13 // CLASS MGraph 14 // Description: Create a container image that can hold several graph 14 // Description: Create a container image that can hold several graph 15 15 //============================================================================= 16 16 class MGraph { 17 18 public $title = null, $subtitle = null, $subsubtitle = null; 17 19 18 20 protected $img=NULL; 19 21 protected $iCnt=0,$iGraphs = array(); // image_handle, x, y, fx, fy, sizex, sizey 20 22 protected $iFillColor='white', $iCurrentColor=0; 21 protected $lm= 0,$rm=0,$tm=0,$bm=0;23 protected $lm=4,$rm=4,$tm=4,$bm=4; 22 24 protected $iDoFrame = FALSE, $iFrameColor = 'black', $iFrameWeight = 1; 23 25 protected $iLineWeight = 1; 24 26 protected $expired=false; 25 protected $img_format='png',$image_quality=75; 27 protected $cache=null,$cache_name = '',$inline=true; 28 protected $image_format='png',$image_quality=75; 26 29 protected $iWidth=NULL,$iHeight=NULL; 27 30 protected $background_image='',$background_image_center=true, 28 $backround_image_format='',$background_image_mix=100, 29 $background_image_y=NULL, $background_image_x=NULL; 31 $backround_image_format='',$background_image_mix=100, 32 $background_image_y=NULL, $background_image_x=NULL; 33 private $doshadow=false, $shadow_width=4, $shadow_color='gray@0.5'; 34 public $footer; 35 30 36 31 37 // Create a new instane of the combined graph 32 function MGraph($aWidth=NULL,$aHeight=NULL) { 33 $this->iWidth = $aWidth; 34 $this->iHeight = $aHeight; 38 function __construct($aWidth=NULL,$aHeight=NULL,$aCachedName='',$aTimeOut=0,$aInline=true) { 39 $this->iWidth = $aWidth; 40 $this->iHeight = $aHeight; 41 42 // If the cached version exist just read it directly from the 43 // cache, stream it back to browser and exit 44 if( $aCachedName!='' && READ_CACHE && $aInline ) { 45 $this->cache = new ImgStreamCache(); 46 $this->cache->SetTimeOut($aTimeOut); 47 $image = new Image(); 48 if( $this->cache->GetAndStream($image,$aCachedName) ) { 49 exit(); 50 } 51 } 52 $this->inline = $aInline; 53 $this->cache_name = $aCachedName; 54 55 $this->title = new Text(); 56 $this->title->ParagraphAlign('center'); 57 $this->title->SetFont(FF_FONT2,FS_BOLD); 58 $this->title->SetMargin(3); 59 $this->title->SetAlign('center'); 60 61 $this->subtitle = new Text(); 62 $this->subtitle->ParagraphAlign('center'); 63 $this->subtitle->SetFont(FF_FONT1,FS_BOLD); 64 $this->subtitle->SetMargin(3); 65 $this->subtitle->SetAlign('center'); 66 67 $this->subsubtitle = new Text(); 68 $this->subsubtitle->ParagraphAlign('center'); 69 $this->subsubtitle->SetFont(FF_FONT1,FS_NORMAL); 70 $this->subsubtitle->SetMargin(3); 71 $this->subsubtitle->SetAlign('center'); 72 73 $this->footer = new Footer(); 74 35 75 } 36 76 37 77 // Specify background fill color for the combined graph 38 78 function SetFillColor($aColor) { 39 79 $this->iFillColor = $aColor; 40 80 } 41 81 42 82 // Add a frame around the combined graph 43 83 function SetFrame($aFlg,$aColor='black',$aWeight=1) { 44 45 46 47 } 48 49 // Specify a background image blend 84 $this->iDoFrame = $aFlg; 85 $this->iFrameColor = $aColor; 86 $this->iFrameWeight = $aWeight; 87 } 88 89 // Specify a background image blend 50 90 function SetBackgroundImageMix($aMix) { 51 91 $this->background_image_mix = $aMix ; 52 92 } 53 93 54 94 // Specify a background image 55 95 function SetBackgroundImage($aFileName,$aCenter_aX=NULL,$aY=NULL) { 56 // Second argument can be either a boolean value or 57 // a numeric 58 $aCenter=TRUE; 59 $aX=NULL; 60 61 if( $GLOBALS['gd2'] && !USE_TRUECOLOR ) { 62 JpGraphError::RaiseL(12001); 63 //("You are using GD 2.x and are trying to use a background images on a non truecolor image. To use background images with GD 2.x you <b>must</b> enable truecolor by setting the USE_TRUECOLOR constant to TRUE. Due to a bug in GD 2.0.1 using any truetype fonts with truecolor images will result in very poor quality fonts."); 64 } 65 if( is_numeric($aCenter_aX) ) { 66 $aX=$aCenter_aX; 67 } 68 69 // Get extension to determine image type 70 $e = explode('.',$aFileName); 71 if( !$e ) { 72 JpGraphError::RaiseL(12002,$aFileName); 73 //('Incorrect file name for MGraph::SetBackgroundImage() : '.$aFileName.' Must have a valid image extension (jpg,gif,png) when using autodetection of image type'); 74 } 75 76 $valid_formats = array('png', 'jpg', 'gif'); 77 $aImgFormat = strtolower($e[count($e)-1]); 78 if ($aImgFormat == 'jpeg') { 79 $aImgFormat = 'jpg'; 80 } 81 elseif (!in_array($aImgFormat, $valid_formats) ) { 82 JpGraphError::RaiseL(12003,$aImgFormat,$aFileName); 83 //('Unknown file extension ($aImgFormat) in MGraph::SetBackgroundImage() for filename: '.$aFileName); 84 } 85 86 $this->background_image = $aFileName; 87 $this->background_image_center=$aCenter; 88 $this->background_image_format=$aImgFormat; 89 $this->background_image_x = $aX; 90 $this->background_image_y = $aY; 91 } 92 93 94 // Private helper function for backgound image 95 function _loadBkgImage($aFile='') { 96 if( $aFile == '' ) 97 $aFile = $this->background_image; 98 99 // Remove case sensitivity and setup appropriate function to create image 100 // Get file extension. This should be the LAST '.' separated part of the filename 101 $e = explode('.',$aFile); 102 $ext = strtolower($e[count($e)-1]); 103 if ($ext == "jpeg") { 104 $ext = "jpg"; 105 } 106 107 if( trim($ext) == '' ) 108 $ext = 'png'; // Assume PNG if no extension specified 109 110 $supported = imagetypes(); 111 if( ( $ext == 'jpg' && !($supported & IMG_JPG) ) || 112 ( $ext == 'gif' && !($supported & IMG_GIF) ) || 113 ( $ext == 'png' && !($supported & IMG_PNG) ) ) { 114 JpGraphError::RaiseL(12004,$aFile);//('The image format of your background image ('.$aFile.') is not supported in your system configuration. '); 115 } 116 117 if( $ext == "jpg" || $ext == "jpeg") { 118 $f = "imagecreatefromjpeg"; 119 $ext = "jpg"; 120 } 121 else { 122 $f = "imagecreatefrom".$ext; 123 } 124 125 $img = @$f($aFile); 126 if( !$img ) { 127 JpGraphError::RaiseL(12005,$aFile); 128 //(" Can't read background image: '".$aFile."'"); 129 } 130 return $img; 131 } 96 // Second argument can be either a boolean value or 97 // a numeric 98 $aCenter=TRUE; 99 $aX=NULL; 100 101 if( is_numeric($aCenter_aX) ) { 102 $aX=$aCenter_aX; 103 } 104 105 // Get extension to determine image type 106 $e = explode('.',$aFileName); 107 if( !$e ) { 108 JpGraphError::RaiseL(12002,$aFileName); 109 //('Incorrect file name for MGraph::SetBackgroundImage() : '.$aFileName.' Must have a valid image extension (jpg,gif,png) when using autodetection of image type'); 110 } 111 112 $valid_formats = array('png', 'jpg', 'gif'); 113 $aImgFormat = strtolower($e[count($e)-1]); 114 if ($aImgFormat == 'jpeg') { 115 $aImgFormat = 'jpg'; 116 } 117 elseif (!in_array($aImgFormat, $valid_formats) ) { 118 JpGraphError::RaiseL(12003,$aImgFormat,$aFileName); 119 //('Unknown file extension ($aImgFormat) in MGraph::SetBackgroundImage() for filename: '.$aFileName); 120 } 121 122 $this->background_image = $aFileName; 123 $this->background_image_center=$aCenter; 124 $this->background_image_format=$aImgFormat; 125 $this->background_image_x = $aX; 126 $this->background_image_y = $aY; 127 } 132 128 133 129 function _strokeBackgroundImage() { 134 if( $this->background_image == '' ) 135 return; 136 137 $bkgimg = $this->_loadBkgImage(); 138 // Background width & Heoght 139 $bw = imagesx($bkgimg); 140 $bh = imagesy($bkgimg); 141 // Canvas width and height 142 $cw = imagesx($this->img); 143 $ch = imagesy($this->img); 144 145 if( $this->background_image_x === NULL || $this->background_image_y === NULL ) { 146 if( $this->background_image_center ) { 147 // Center original image in the plot area 148 $x = round($cw/2-$bw/2); $y = round($ch/2-$bh/2); 149 } 150 else { 151 // Just copy the image from left corner, no resizing 152 $x=0; $y=0; 153 } 154 } 155 else { 156 $x = $this->background_image_x; 157 $y = $this->background_image_y; 158 } 159 $this->_imageCp($bkgimg,$x,$y,0,0,$bw,$bh,$this->background_image_mix); 160 } 161 162 function _imageCp($aSrcImg,$x,$y,$fx,$fy,$w,$h,$mix=100) { 163 imagecopymerge($this->img,$aSrcImg,$x,$y,$fx,$fy,$w,$h,$mix); 164 } 165 166 function _imageCreate($aWidth,$aHeight) { 167 if( $aWidth <= 1 || $aHeight <= 1 ) { 168 JpGraphError::RaiseL(12006,$aWidth,$aHeight); 169 //("Illegal sizes specified for width or height when creating an image, (width=$aWidth, height=$aHeight)"); 170 } 171 if( @$GLOBALS['gd2']==true && USE_TRUECOLOR ) { 172 $this->img = @imagecreatetruecolor($aWidth, $aHeight); 173 if( $this->img < 1 ) { 174 JpGraphError::RaiseL(12011); 175 // die("<b>JpGraph Error:</b> Can't create truecolor image. Check that you really have GD2 library installed."); 176 } 177 ImageAlphaBlending($this->img,true); 178 } else { 179 $this->img = @imagecreate($aWidth, $aHeight); 180 if( $this->img < 1 ) { 181 JpGraphError::RaiseL(12012); 182 // die("<b>JpGraph Error:</b> Can't create image. Check that you really have the GD library installed."); 183 } 184 } 185 } 186 187 function _polygon($p,$closed=FALSE) { 188 if( $this->iLineWeight==0 ) return; 189 $n=count($p); 190 $oldx = $p[0]; 191 $oldy = $p[1]; 192 for( $i=2; $i < $n; $i+=2 ) { 193 imageline($this->img,$oldx,$oldy,$p[$i],$p[$i+1],$this->iCurrentColor); 194 $oldx = $p[$i]; 195 $oldy = $p[$i+1]; 196 } 197 if( $closed ) { 198 imageline($this->img,$p[$n*2-2],$p[$n*2-1],$p[0],$p[1],$this->iCurrentColor); 199 } 200 } 201 202 function _filledPolygon($pts) { 203 $n=count($pts); 204 for($i=0; $i < $n; ++$i) 205 $pts[$i] = round($pts[$i]); 206 imagefilledpolygon($this->img,$pts,count($pts)/2,$this->iCurrentColor); 207 } 208 209 function _rectangle($xl,$yu,$xr,$yl) { 210 for($i=0; $i < $this->iLineWeight; ++$i ) 211 $this->_polygon(array($xl+$i,$yu+$i,$xr-$i,$yu+$i, 212 $xr-$i,$yl-$i,$xl+$i,$yl-$i, 213 $xl+$i,$yu+$i)); 214 } 215 216 function _filledRectangle($xl,$yu,$xr,$yl) { 217 $this->_filledPolygon(array($xl,$yu,$xr,$yu,$xr,$yl,$xl,$yl)); 218 } 219 220 function _setColor($aColor) { 221 $this->iCurrentColor = $this->iRGB->Allocate($aColor); 130 if( $this->background_image == '' ) return; 131 132 $bkgimg = Graph::LoadBkgImage('',$this->background_image); 133 134 // Background width & Heoght 135 $bw = imagesx($bkgimg); 136 $bh = imagesy($bkgimg); 137 138 // Canvas width and height 139 $cw = imagesx($this->img); 140 $ch = imagesy($this->img); 141 142 if( $this->doshadow ) { 143 $cw -= $this->shadow_width; 144 $ch -= $this->shadow_width; 145 } 146 147 if( $this->background_image_x === NULL || $this->background_image_y === NULL ) { 148 if( $this->background_image_center ) { 149 // Center original image in the plot area 150 $x = round($cw/2-$bw/2); $y = round($ch/2-$bh/2); 151 } 152 else { 153 // Just copy the image from left corner, no resizing 154 $x=0; $y=0; 155 } 156 } 157 else { 158 $x = $this->background_image_x; 159 $y = $this->background_image_y; 160 } 161 imagecopymerge($this->img,$bkgimg,$x,$y,0,0,$bw,$bh,$this->background_image_mix); 222 162 } 223 163 224 164 function AddMix($aGraph,$x=0,$y=0,$mix=100,$fx=0,$fy=0,$w=0,$h=0) { 225 226 } 227 165 $this->_gdImgHandle($aGraph->Stroke( _IMG_HANDLER),$x,$y,$fx=0,$fy=0,$w,$h,$mix); 166 } 167 228 168 function Add($aGraph,$x=0,$y=0,$fx=0,$fy=0,$w=0,$h=0) { 229 169 $this->_gdImgHandle($aGraph->Stroke( _IMG_HANDLER),$x,$y,$fx=0,$fy=0,$w,$h); 230 170 } 231 171 232 172 function _gdImgHandle($agdCanvas,$x,$y,$fx=0,$fy=0,$w=0,$h=0,$mix=100) { 233 if( $w == 0 ) $w = @imagesx($agdCanvas); 234 if( $w === NULL ) { 235 JpGraphError::RaiseL(12007); 236 //('Argument to MGraph::Add() is not a valid GD image handle.'); 237 return; 238 } 239 if( $h == 0 ) $h = @imagesy($agdCanvas); 240 $this->iGraphs[$this->iCnt++] = array($agdCanvas,$x,$y,$fx,$fy,$w,$h,$mix); 173 if( $w == 0 ) { 174 $w = @imagesx($agdCanvas); 175 } 176 if( $w === NULL ) { 177 JpGraphError::RaiseL(12007); 178 //('Argument to MGraph::Add() is not a valid GD image handle.'); 179 return; 180 } 181 if( $h == 0 ) { 182 $h = @imagesy($agdCanvas); 183 } 184 $this->iGraphs[$this->iCnt++] = array($agdCanvas,$x,$y,$fx,$fy,$w,$h,$mix); 241 185 } 242 186 243 187 function SetMargin($lm,$rm,$tm,$bm) { 244 245 246 247 188 $this->lm = $lm; 189 $this->rm = $rm; 190 $this->tm = $tm; 191 $this->bm = $bm; 248 192 } 249 193 250 194 function SetExpired($aFlg=true) { 251 $this->expired = $aFlg; 252 } 253 254 // Generate image header 255 function Headers() { 256 257 // In case we are running from the command line with the client version of 258 // PHP we can't send any headers. 259 $sapi = php_sapi_name(); 260 if( $sapi == 'cli' ) 261 return; 262 263 if( headers_sent() ) { 264 265 echo "<table border=1><tr><td><font color=darkred size=4><b>JpGraph Error:</b> 266 HTTP headers have already been sent.</font></td></tr><tr><td><b>Explanation:</b><br>HTTP headers have already been sent back to the browser indicating the data as text before the library got a chance to send it's image HTTP header to this browser. This makes it impossible for the library to send back image data to the browser (since that would be interpretated as text by the browser and show up as junk text).<p>Most likely you have some text in your script before the call to <i>Graph::Stroke()</i>. If this texts gets sent back to the browser the browser will assume that all data is plain text. Look for any text, even spaces and newlines, that might have been sent back to the browser. <p>For example it is a common mistake to leave a blank line before the opening \"<b><?php</b>\".</td></tr></table>"; 267 268 die(); 269 270 } 271 272 if ($this->expired) { 273 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); 274 header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT"); 275 header("Cache-Control: no-cache, must-revalidate"); 276 header("Pragma: no-cache"); 277 } 278 header("Content-type: image/$this->img_format"); 195 $this->expired = $aFlg; 279 196 } 280 197 281 198 function SetImgFormat($aFormat,$aQuality=75) { 282 $this->image_quality = $aQuality; 283 $aFormat = strtolower($aFormat); 284 $tst = true; 285 $supported = imagetypes(); 286 if( $aFormat=="auto" ) { 287 if( $supported & IMG_PNG ) 288 $this->img_format="png"; 289 elseif( $supported & IMG_JPG ) 290 $this->img_format="jpeg"; 291 elseif( $supported & IMG_GIF ) 292 $this->img_format="gif"; 293 else 294 JpGraphError::RaiseL(12008); 295 //(" Your PHP (and GD-lib) installation does not appear to support any known graphic formats.". 296 return true; 297 } 298 else { 299 if( $aFormat=="jpeg" || $aFormat=="png" || $aFormat=="gif" ) { 300 if( $aFormat=="jpeg" && !($supported & IMG_JPG) ) 301 $tst=false; 302 elseif( $aFormat=="png" && !($supported & IMG_PNG) ) 303 $tst=false; 304 elseif( $aFormat=="gif" && !($supported & IMG_GIF) ) 305 $tst=false; 306 else { 307 $this->img_format=$aFormat; 308 return true; 309 } 310 } 311 else 312 $tst=false; 313 if( !$tst ) 314 JpGraphError::RaiseL(12009,$aFormat); 315 //(" Your PHP installation does not support the chosen graphic format: $aFormat"); 316 } 317 } 318 319 // Stream image to browser or to file 320 function Stream($aFile="") { 321 $func="image".$this->img_format; 322 if( $this->img_format=="jpeg" && $this->image_quality != null ) { 323 $res = @$func($this->img,$aFile,$this->image_quality); 324 } 325 else { 326 if( $aFile != "" ) { 327 $res = @$func($this->img,$aFile); 328 } 329 else 330 $res = @$func($this->img); 331 } 332 if( !$res ) 333 JpGraphError::RaiseL(12010,$aFile); 334 //("Can't create or stream image to file $aFile Check that PHP has enough permission to write a file to the current directory."); 199 $this->image_format = $aFormat; 200 $this->image_quality = $aQuality; 201 } 202 203 // Set the shadow around the whole image 204 function SetShadow($aShowShadow=true,$aShadowWidth=4,$aShadowColor='gray@0.3') { 205 $this->doshadow = $aShowShadow; 206 $this->shadow_color = $aShadowColor; 207 $this->shadow_width = $aShadowWidth; 208 $this->footer->iBottomMargin += $aShadowWidth; 209 $this->footer->iRightMargin += $aShadowWidth; 210 } 211 212 function StrokeTitle($image,$w,$h) { 213 // Stroke title 214 if( $this->title->t !== '' ) { 215 216 $margin = 3; 217 218 $y = $this->title->margin; 219 if( $this->title->halign == 'center' ) { 220 $this->title->Center(0,$w,$y); 221 } 222 elseif( $this->title->halign == 'left' ) { 223 $this->title->SetPos($this->title->margin+2,$y); 224 } 225 elseif( $this->title->halign == 'right' ) { 226 $indent = 0; 227 if( $this->doshadow ) { 228 $indent = $this->shadow_width+2; 229 } 230 $this->title->SetPos($w-$this->title->margin-$indent,$y,'right'); 231 } 232 $this->title->Stroke($image); 233 234 // ... and subtitle 235 $y += $this->title->GetTextHeight($image) + $margin + $this->subtitle->margin; 236 if( $this->subtitle->halign == 'center' ) { 237 $this->subtitle->Center(0,$w,$y); 238 } 239 elseif( $this->subtitle->halign == 'left' ) { 240 $this->subtitle->SetPos($this->subtitle->margin+2,$y); 241 } 242 elseif( $this->subtitle->halign == 'right' ) { 243 $indent = 0; 244 if( $this->doshadow ) { 245 $indent = $this->shadow_width+2; 246 } 247 $this->subtitle->SetPos($this->img->width-$this->subtitle->margin-$indent,$y,'right'); 248 } 249 $this->subtitle->Stroke($image); 250 251 // ... and subsubtitle 252 $y += $this->subtitle->GetTextHeight($image) + $margin + $this->subsubtitle->margin; 253 if( $this->subsubtitle->halign == 'center' ) { 254 $this->subsubtitle->Center(0,$w,$y); 255 } 256 elseif( $this->subsubtitle->halign == 'left' ) { 257 $this->subsubtitle->SetPos($this->subsubtitle->margin+2,$y); 258 } 259 elseif( $this->subsubtitle->halign == 'right' ) { 260 $indent = 0; 261 if( $this->doshadow ) { 262 $indent = $this->shadow_width+2; 263 } 264 $this->subsubtitle->SetPos($w-$this->subsubtitle->margin-$indent,$y,'right'); 265 } 266 $this->subsubtitle->Stroke($image); 267 268 } 335 269 } 336 270 337 271 function Stroke($aFileName='') { 338 // Find out the necessary size for the container image 339 $w=0; $h=0; 340 for($i=0; $i < $this->iCnt; ++$i ) { 341 $maxw = $this->iGraphs[$i][1]+$this->iGraphs[$i][5]; 342 $maxh = $this->iGraphs[$i][2]+$this->iGraphs[$i][6]; 343 $w = max( $w, $maxw ); 344 $h = max( $h, $maxh ); 345 } 346 $w += $this->lm+$this->rm; 347 $h += $this->tm+$this->bm; 348 349 // User specified width,height overrides 350 if( $this->iWidth !== NULL ) $w = $this->iWidth; 351 if( $this->iHeight!== NULL ) $h = $this->iHeight; 352 353 $this->_imageCreate($w,$h); 354 $this->iRGB = new RGB($this->img); 355 356 $this->_setcolor($this->iFillColor); 357 $this->_filledRectangle(0,0,$w-1,$h-1); 358 359 $this->_strokeBackgroundImage(); 360 361 if( $this->iDoFrame ) { 362 $this->_setColor($this->iFrameColor); 363 $this->iLineWeight=$this->iFrameWeight; 364 $this->_rectangle(0,0,$w-1,$h-1); 365 } 366 367 // Copy all sub graphs to the container 368 for($i=0; $i < $this->iCnt; ++$i ) { 369 $this->_imageCp($this->iGraphs[$i][0], 370 $this->iGraphs[$i][1]+$this->lm,$this->iGraphs[$i][2]+$this->tm, 371 $this->iGraphs[$i][3],$this->iGraphs[$i][4], 372 $this->iGraphs[$i][5],$this->iGraphs[$i][6], 373 $this->iGraphs[$i][7]); 374 } 375 376 // Output image 377 if( $aFileName == _IMG_HANDLER ) { 378 return $this->img; 379 } 380 else { 381 if( $aFileName != '' ) { 382 $this->Stream($aFileName); 383 } 384 else { 385 $this->Headers(); 386 $this->Stream(); 387 } 388 } 272 // Find out the necessary size for the container image 273 $w=0; $h=0; 274 for($i=0; $i < $this->iCnt; ++$i ) { 275 $maxw = $this->iGraphs[$i][1]+$this->iGraphs[$i][5]; 276 $maxh = $this->iGraphs[$i][2]+$this->iGraphs[$i][6]; 277 $w = max( $w, $maxw ); 278 $h = max( $h, $maxh ); 279 } 280 $w += $this->lm+$this->rm; 281 $h += $this->tm+$this->bm; 282 283 // User specified width,height overrides 284 if( $this->iWidth !== NULL && $this->iWidth !== 0 ) $w = $this->iWidth; 285 if( $this->iHeight!== NULL && $this->iHeight !== 0) $h = $this->iHeight; 286 287 if( $this->doshadow ) { 288 $w += $this->shadow_width; 289 $h += $this->shadow_width; 290 } 291 292 $image = new Image($w,$h); 293 $image->SetImgFormat( $this->image_format,$this->image_quality); 294 295 if( $this->doshadow ) { 296 $image->SetColor($this->iFrameColor); 297 $image->ShadowRectangle(0,0,$w-1,$h-1,$this->iFillColor,$this->shadow_width,$this->shadow_color); 298 $w -= $this->shadow_width; 299 $h -= $this->shadow_width; 300 } 301 else { 302 $image->SetColor($this->iFillColor); 303 $image->FilledRectangle(0,0,$w-1,$h-1); 304 } 305 $image->SetExpired($this->expired); 306 307 $this->img = $image->img; 308 $this->_strokeBackgroundImage(); 309 310 if( $this->iDoFrame && ! $this->doshadow ) { 311 $image->SetColor($this->iFrameColor); 312 $image->SetLineWeight($this->iFrameWeight); 313 $image->Rectangle(0,0,$w-1,$h-1); 314 } 315 316 // Copy all sub graphs to the container 317 for($i=0; $i < $this->iCnt; ++$i ) { 318 $image->CopyMerge($this->iGraphs[$i][0], 319 $this->iGraphs[$i][1]+$this->lm,$this->iGraphs[$i][2]+$this->tm, 320 $this->iGraphs[$i][3],$this->iGraphs[$i][4], 321 $this->iGraphs[$i][5],$this->iGraphs[$i][6], 322 -1,-1, /* Full from width and height */ 323 $this->iGraphs[$i][7]); 324 325 326 } 327 328 $this->StrokeTitle($image,$w,$h); 329 $this->footer->Stroke($image); 330 331 // Output image 332 if( $aFileName == _IMG_HANDLER ) { 333 return $image->img; 334 } 335 else { 336 //Finally stream the generated picture 337 $this->cache = new ImgStreamCache(); 338 $this->cache->PutAndStream($image,$this->cache_name,$this->inline,$aFileName); 339 } 389 340 } 390 341 } 391 342 343 // EOF 344 392 345 ?> -
trunk/client/modules/Elezioni/grafici/jpgraph_pie.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_PIE.PHP4 // Description:Pie plot extension for JpGraph5 // Created:2001-02-146 // Ver: $Id: jpgraph_pie.php 1091 2009-01-18 22:57:40Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */3 // File: JPGRAPH_PIE.PHP 4 // Description: Pie plot extension for JpGraph 5 // Created: 2001-02-14 6 // Ver: $Id: jpgraph_pie.php 1926 2010-01-11 16:33:07Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 … … 24 24 class PiePlot { 25 25 public $posx=0.5,$posy=0.5; 26 public $is_using_plot_theme = false; 27 public $theme="earth"; 28 protected $use_plot_theme_colors = false; 26 29 protected $radius=0.3; 27 30 protected $explode_radius=array(),$explode_all=false,$explode_r=20; 28 31 protected $labels=null, $legends=null; 29 32 protected $csimtargets=null,$csimwintargets=null; // Array of targets for CSIM 30 protected $csimareas=''; // Generated CSIM text31 protected $csimalts=null; 33 protected $csimareas=''; // Generated CSIM text 34 protected $csimalts=null; // ALT tags for corresponding target 32 35 protected $data=null; 33 36 public $title; … … 36 39 protected $legend_margin=6,$show_labels=true; 37 40 protected $themearr = array( 38 "earth" => array(136,34,40,45,46,62,63,134,74,10,120,136,141,168,180,77,209,218,346,395,89,430), 39 "pastel" => array(27,415,128,59,66,79,105,110,42,147,152,230,236,240,331,337,405,38), 40 "water" => array(8,370,24,40,335,56,213,237,268,14,326,387,10,388), 41 "sand" => array(27,168,34,170,19,50,65,72,131,209,46,393)); 42 protected $theme="earth"; 41 "earth" => array(136,34,40,45,46,62,63,134,74,10,120,136,141,168,180,77,209,218,346,395,89,430), 42 "pastel" => array(27,415,128,59,66,79,105,110,42,147,152,230,236,240,331,337,405,38), 43 "water" => array(8,370,24,40,335,56,213,237,268,14,326,387,10,388), 44 "sand" => array(27,168,34,170,19,50,65,72,131,209,46,393)); 43 45 protected $setslicecolors=array(); 44 46 protected $labeltype=0; // Default to percentage … … 54 56 protected $iGuideLineCurve = false,$iGuideVFactor=1.4,$iGuideLineRFactor=0.8; 55 57 protected $la = array(); // Holds the exact angle for each label 56 57 //---------------58 // CONSTRUCTOR59 function PiePlot($data) {60 61 62 $this->title->SetFont(FF_FONT1,FS_BOLD);63 64 65 66 67 } 68 69 //---------------70 // PUBLIC METHODS 58 59 //--------------- 60 // CONSTRUCTOR 61 function __construct($data) { 62 $this->data = array_reverse($data); 63 $this->title = new Text(""); 64 $this->title->SetFont(FF_DEFAULT,FS_BOLD); 65 $this->value = new DisplayValue(); 66 $this->value->Show(); 67 $this->value->SetFormat('%.1f%%'); 68 $this->guideline = new LineProperty(); 69 } 70 71 //--------------- 72 // PUBLIC METHODS 71 73 function SetCenter($x,$y=0.5) { 72 73 74 $this->posx = $x; 75 $this->posy = $y; 74 76 } 75 77 76 78 // Enable guideline and set drwaing policy 77 79 function SetGuideLines($aFlg=true,$aCurved=true,$aAlways=false) { 78 79 80 80 $this->guideline->Show($aFlg); 81 $this->iShowGuideLineForSingle = $aAlways; 82 $this->iGuideLineCurve = $aCurved; 81 83 } 82 84 83 85 // Adjuste the distance between labels and labels and pie 84 86 function SetGuideLinesAdjust($aVFactor,$aRFactor=0.8) { 85 86 87 $this->iGuideVFactor=$aVFactor; 88 $this->iGuideLineRFactor=$aRFactor; 87 89 } 88 90 89 91 function SetColor($aColor) { 90 91 } 92 92 $this->color = $aColor; 93 } 94 93 95 function SetSliceColors($aColors) { 94 95 } 96 96 $this->setslicecolors = $aColors; 97 } 98 97 99 function SetShadow($aColor='darkgray',$aDropWidth=4) { 98 99 100 $this->ishadowcolor = $aColor; 101 $this->ishadowdrop = $aDropWidth; 100 102 } 101 103 102 104 function SetCSIMTargets($aTargets,$aAlts='',$aWinTargets='') { 103 104 105 106 107 108 } 109 105 $this->csimtargets=array_reverse($aTargets); 106 if( is_array($aWinTargets) ) 107 $this->csimwintargets=array_reverse($aWinTargets); 108 if( is_array($aAlts) ) 109 $this->csimalts=array_reverse($aAlts); 110 } 111 110 112 function GetCSIMareas() { 111 112 } 113 114 function AddSliceToCSIM($i,$xc,$yc,$radius,$sa,$ea) { 113 return $this->csimareas; 114 } 115 116 function AddSliceToCSIM($i,$xc,$yc,$radius,$sa,$ea) { 115 117 //Slice number, ellipse centre (x,y), height, width, start angle, end angle 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; 169 170 171 172 173 174 175 176 } 177 178 118 while( $sa > 2*M_PI ) $sa = $sa - 2*M_PI; 119 while( $ea > 2*M_PI ) $ea = $ea - 2*M_PI; 120 121 $sa = 2*M_PI - $sa; 122 $ea = 2*M_PI - $ea; 123 124 // Special case when we have only one slice since then both start and end 125 // angle will be == 0 126 if( abs($sa - $ea) < 0.0001 ) { 127 $sa=2*M_PI; $ea=0; 128 } 129 130 //add coordinates of the centre to the map 131 $xc = floor($xc);$yc=floor($yc); 132 $coords = "$xc, $yc"; 133 134 //add coordinates of the first point on the arc to the map 135 $xp = floor(($radius*cos($ea))+$xc); 136 $yp = floor($yc-$radius*sin($ea)); 137 $coords.= ", $xp, $yp"; 138 139 //add coordinates every 0.2 radians 140 $a=$ea+0.2; 141 142 // If we cross the 360-limit with a slice we need to handle 143 // the fact that end angle is smaller than start 144 if( $sa < $ea ) { 145 while ($a <= 2*M_PI) { 146 $xp = floor($radius*cos($a)+$xc); 147 $yp = floor($yc-$radius*sin($a)); 148 $coords.= ", $xp, $yp"; 149 $a += 0.2; 150 } 151 $a -= 2*M_PI; 152 } 153 154 155 while ($a < $sa) { 156 $xp = floor($radius*cos($a)+$xc); 157 $yp = floor($yc-$radius*sin($a)); 158 $coords.= ", $xp, $yp"; 159 $a += 0.2; 160 } 161 162 //Add the last point on the arc 163 $xp = floor($radius*cos($sa)+$xc); 164 $yp = floor($yc-$radius*sin($sa)); 165 $coords.= ", $xp, $yp"; 166 if( !empty($this->csimtargets[$i]) ) { 167 $this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->csimtargets[$i]."\""; 168 $tmp=""; 169 if( !empty($this->csimwintargets[$i]) ) { 170 $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; 171 } 172 if( !empty($this->csimalts[$i]) ) { 173 $tmp=sprintf($this->csimalts[$i],$this->data[$i]); 174 $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" "; 175 } 176 $this->csimareas .= " />\n"; 177 } 178 } 179 180 179 181 function SetTheme($aTheme) { 180 if( in_array($aTheme,array_keys($this->themearr)) ) 181 $this->theme = $aTheme; 182 else 183 JpGraphError::RaiseL(15001,$aTheme);//("PiePLot::SetTheme() Unknown theme: $aTheme"); 184 } 185 182 // JpGraphError::RaiseL(15012,$aTheme); 183 // return; 184 185 if( in_array($aTheme,array_keys($this->themearr)) ) { 186 $this->theme = $aTheme; 187 $this->is_using_plot_theme = true; 188 } else { 189 JpGraphError::RaiseL(15001,$aTheme);//("PiePLot::SetTheme() Unknown theme: $aTheme"); 190 } 191 } 192 186 193 function ExplodeSlice($e,$radius=20) { 187 if( ! is_integer($e) ) 188 189 194 if( ! is_integer($e) ) 195 JpGraphError::RaiseL(15002);//('Argument to PiePlot::ExplodeSlice() must be an integer'); 196 $this->explode_radius[$e]=$radius; 190 197 } 191 198 192 199 function ExplodeAll($radius=20) { 193 194 200 $this->explode_all=true; 201 $this->explode_r = $radius; 195 202 } 196 203 197 204 function Explode($aExplodeArr) { 198 199 200 //("Argument to PiePlot::Explode() must be an array with integer distances.");201 202 205 if( !is_array($aExplodeArr) ) { 206 JpGraphError::RaiseL(15003); 207 //("Argument to PiePlot::Explode() must be an array with integer distances."); 208 } 209 $this->explode_radius = $aExplodeArr; 203 210 } 204 211 205 212 function SetStartAngle($aStart) { 206 if( $aStart < 0 || $aStart > 360 ) { 207 JpGraphError::RaiseL(15004);//('Slice start angle must be between 0 and 360 degrees.'); 208 } 209 $this->startangle = 360-$aStart; 210 $this->startangle *= M_PI/180; 211 } 212 213 function SetFont($family,$style=FS_NORMAL,$size=10) { 214 JpGraphError::RaiseL(15005);//('PiePlot::SetFont() is deprecated. Use PiePlot->value->SetFont() instead.'); 215 } 216 213 if( $aStart < 0 || $aStart > 360 ) { 214 JpGraphError::RaiseL(15004);//('Slice start angle must be between 0 and 360 degrees.'); 215 } 216 if( $aStart == 0 ) { 217 $this->startangle = 0; 218 } 219 else { 220 $this->startangle = 360-$aStart; 221 $this->startangle *= M_PI/180; 222 } 223 } 224 217 225 // Size in percentage 218 226 function SetSize($aSize) { 219 if( ($aSize>0 && $aSize<=0.5) || ($aSize>10 && $aSize<1000) ) 220 $this->radius = $aSize; 221 else 222 JpGraphError::RaiseL(15006); 223 //("PiePlot::SetSize() Radius for pie must either be specified as a fraction [0, 0.5] of the size of the image or as an absolute size in pixels in the range [10, 1000]"); 224 } 225 226 function SetFontColor($aColor) { 227 JpGraphError::RaiseL(15007); 228 //('PiePlot::SetFontColor() is deprecated. Use PiePlot->value->SetColor() instead.'); 229 } 230 227 if( ($aSize>0 && $aSize<=0.5) || ($aSize>10 && $aSize<1000) ) 228 $this->radius = $aSize; 229 else 230 JpGraphError::RaiseL(15006); 231 //("PiePlot::SetSize() Radius for pie must either be specified as a fraction [0, 0.5] of the size of the image or as an absolute size in pixels in the range [10, 1000]"); 232 } 233 231 234 // Set label arrays 232 235 function SetLegends($aLegend) { 233 234 } 235 236 // Set text labels for slices 236 $this->legends = $aLegend; 237 } 238 239 // Set text labels for slices 237 240 function SetLabels($aLabels,$aLblPosAdj="auto") { 238 239 241 $this->labels = array_reverse($aLabels); 242 $this->ilabelposadj=$aLblPosAdj; 240 243 } 241 244 242 245 function SetLabelPos($aLblPosAdj) { 243 244 } 245 246 $this->ilabelposadj=$aLblPosAdj; 247 } 248 246 249 // Should we display actual value or percentage? 247 function SetLabelType($ t) {248 if( $t < 0 || $t > 2 ) 249 JpGraphError::RaiseL(15008,$t);250 //("PiePlot::SetLabelType() Type for pie plots must be 0 or 1 (not $t).");251 $this->labeltype=$t;252 } 253 254 // Deprecated. 250 function SetLabelType($aType) { 251 if( $aType < 0 || $aType > 2 ) 252 JpGraphError::RaiseL(15008,$aType); 253 //("PiePlot::SetLabelType() Type for pie plots must be 0 or 1 (not $t)."); 254 $this->labeltype = $aType; 255 } 256 257 // Deprecated. 255 258 function SetValueType($aType) { 256 259 $this->SetLabelType($aType); 257 260 } 258 261 259 262 // Should the circle around a pie plot be displayed 260 263 function ShowBorder($exterior=true,$interior=true) { 261 262 263 } 264 264 $this->pie_border = $exterior; 265 $this->pie_interior_border = $interior; 266 } 267 265 268 // Setup the legends 266 269 function Legend($graph) { 267 $colors = array_keys($graph->img->rgb->rgb_table); 268 sort($colors); 269 $ta=$this->themearr[$this->theme]; 270 $n = count($this->data); 271 272 if( $this->setslicecolors==null ) { 273 $numcolors=count($ta); 274 if( class_exists('PiePlot3D',false) && ($this instanceof PiePlot3D) ) { 275 $ta = array_reverse(array_slice($ta,0,$n)); 276 } 277 } 278 else { 279 $this->setslicecolors = array_slice($this->setslicecolors,0,$n); 280 $numcolors=count($this->setslicecolors); 281 if( $graph->pieaa && !($this instanceof PiePlot3D) ) { 282 $this->setslicecolors = array_reverse($this->setslicecolors); 283 } 284 } 285 286 $sum=0; 287 for($i=0; $i < $n; ++$i) 288 $sum += $this->data[$i]; 289 290 // Bail out with error if the sum is 0 291 if( $sum==0 ) 292 JpGraphError::RaiseL(15009);//("Illegal pie plot. Sum of all data is zero for Pie!"); 293 294 // Make sure we don't plot more values than data points 295 // (in case the user added more legends than data points) 296 $n = min(count($this->legends),count($this->data)); 297 if( $this->legends != "" ) { 298 $this->legends = array_reverse(array_slice($this->legends,0,$n)); 299 } 300 for( $i=$n-1; $i >= 0; --$i ) { 301 $l = $this->legends[$i]; 302 // Replace possible format with actual values 303 if( count($this->csimalts) > $i ) { 304 $fmt = $this->csimalts[$i]; 305 } 306 else { 307 $fmt = "%d"; // Deafult Alt if no other has been specified 308 } 309 if( $this->labeltype==0 ) { 310 $l = sprintf($l,100*$this->data[$i]/$sum); 311 $alt = sprintf($fmt,$this->data[$i]); 312 313 } 314 elseif( $this->labeltype == 1) { 315 $l = sprintf($l,$this->data[$i]); 316 $alt = sprintf($fmt,$this->data[$i]); 317 318 } 319 else { 320 $l = sprintf($l,$this->adjusted_data[$i]); 321 $alt = sprintf($fmt,$this->adjusted_data[$i]); 322 } 323 324 if( empty($this->csimwintargets[$i]) ) { 325 $wintarg = ''; 326 } 327 else { 328 $wintarg = $this->csimwintargets[$i]; 329 } 330 331 if( $this->setslicecolors==null ) { 332 $graph->legend->Add($l,$colors[$ta[$i%$numcolors]],"",0,$this->csimtargets[$i],$alt,$wintarg); 333 } 334 else { 335 $graph->legend->Add($l,$this->setslicecolors[$i%$numcolors],"",0,$this->csimtargets[$i],$alt,$wintarg); 336 } 337 } 338 } 339 270 $colors = array_keys($graph->img->rgb->rgb_table); 271 sort($colors); 272 $ta=$this->themearr[$this->theme]; 273 $n = count($this->data); 274 275 if( $this->setslicecolors==null ) { 276 $numcolors=count($ta); 277 if( class_exists('PiePlot3D',false) && ($this instanceof PiePlot3D) ) { 278 $ta = array_reverse(array_slice($ta,0,$n)); 279 } 280 } 281 else { 282 $this->setslicecolors = array_slice($this->setslicecolors,0,$n); 283 $numcolors=count($this->setslicecolors); 284 if( $graph->pieaa && !($this instanceof PiePlot3D) ) { 285 $this->setslicecolors = array_reverse($this->setslicecolors); 286 } 287 } 288 289 $sum=0; 290 for($i=0; $i < $n; ++$i) 291 $sum += $this->data[$i]; 292 293 // Bail out with error if the sum is 0 294 if( $sum==0 ) 295 JpGraphError::RaiseL(15009);//("Illegal pie plot. Sum of all data is zero for Pie!"); 296 297 // Make sure we don't plot more values than data points 298 // (in case the user added more legends than data points) 299 $legendsCount = is_array($this->legends) ? count($this->legends) : 0; 300 $n = min($legendsCount,count($this->data)); 301 if( $this->legends != "" ) { 302 $this->legends = array_reverse(array_slice($this->legends,0,$n)); 303 } 304 for( $i=$n-1; $i >= 0; --$i ) { 305 $l = $this->legends[$i]; 306 // Replace possible format with actual values 307 $count = is_array($this->csimalts) ? count($this->csimalts) : 0; 308 if( $count > $i ) { 309 $fmt = $this->csimalts[$i]; 310 } 311 else { 312 $fmt = "%d"; // Deafult Alt if no other has been specified 313 } 314 if( $this->labeltype==0 ) { 315 $l = sprintf($l,100*$this->data[$i]/$sum); 316 $alt = sprintf($fmt,$this->data[$i]); 317 318 } 319 elseif( $this->labeltype == 1) { 320 $l = sprintf($l,$this->data[$i]); 321 $alt = sprintf($fmt,$this->data[$i]); 322 323 } 324 else { 325 $l = sprintf($l,$this->adjusted_data[$i]); 326 $alt = sprintf($fmt,$this->adjusted_data[$i]); 327 } 328 329 if( empty($this->csimwintargets[$i]) ) { 330 $wintarg = ''; 331 } 332 else { 333 $wintarg = $this->csimwintargets[$i]; 334 } 335 336 if( $this->setslicecolors==null ) { 337 $graph->legend->Add($l,$colors[$ta[$i%$numcolors]],"",0,$this->csimtargets[$i],$alt,$wintarg); 338 } 339 else { 340 $graph->legend->Add($l,$this->setslicecolors[$i%$numcolors],"",0,$this->csimtargets[$i],$alt,$wintarg); 341 } 342 } 343 } 344 340 345 // Adjust the rounded percetage value so that the sum of 341 346 // of the pie slices are always 100% 342 347 // Using the Hare/Niemeyer method 343 348 function AdjPercentage($aData,$aPrec=0) { 344 345 346 if( $aPrec == 1 ) 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 349 $mul=100; 350 if( $aPrec > 0 && $aPrec < 3 ) { 351 if( $aPrec == 1 ) 352 $mul=1000; 353 else 354 $mul=10000; 355 } 356 357 $tmp = array(); 358 $result = array(); 359 $quote_sum=0; 360 $n = count($aData) ; 361 for( $i=0, $sum=0; $i < $n; ++$i ) 362 $sum+=$aData[$i]; 363 foreach($aData as $index => $value) { 364 $tmp_percentage=$value/$sum*$mul; 365 $result[$index]=floor($tmp_percentage); 366 $tmp[$index]=$tmp_percentage-$result[$index]; 367 $quote_sum+=$result[$index]; 368 } 369 if( $quote_sum == $mul) { 370 if( $mul > 100 ) { 371 $tmp = $mul / 100; 372 for( $i=0; $i < $n; ++$i ) { 373 $result[$i] /= $tmp ; 374 } 375 } 376 return $result; 377 } 378 arsort($tmp,SORT_NUMERIC); 379 reset($tmp); 380 for($i=0; $i < $mul-$quote_sum; $i++) 381 { 382 $result[key($tmp)]++; 383 next($tmp); 384 } 385 if( $mul > 100 ) { 386 $tmp = $mul / 100; 387 for( $i=0; $i < $n; ++$i ) { 388 $result[$i] /= $tmp ; 389 } 390 } 391 return $result; 387 392 } 388 393 389 394 390 395 function Stroke($img,$aaoption=0) { 391 // aaoption is used to handle antialias 392 // aaoption == 0 a normal pie 393 // aaoption == 1 just the body 394 // aaoption == 2 just the values 395 396 // Explode scaling. If anti anti alias we scale the image 397 // twice and we also need to scale the exploding distance 398 $expscale = $aaoption === 1 ? 2 : 1; 399 400 if( $this->labeltype == 2 ) { 401 // Adjust the data so that it will add up to 100% 402 $this->adjusted_data = $this->AdjPercentage($this->data); 403 } 404 405 $colors = array_keys($img->rgb->rgb_table); 406 sort($colors); 407 $ta=$this->themearr[$this->theme]; 408 $n = count($this->data); 409 410 if( $this->setslicecolors==null ) { 411 $numcolors=count($ta); 412 } 413 else { 414 // We need to create an array of colors as long as the data 415 // since we need to reverse it to get the colors in the right order 416 $numcolors=count($this->setslicecolors); 417 $i = 2*$numcolors; 418 while( $n > $i ) { 419 $this->setslicecolors = array_merge($this->setslicecolors,$this->setslicecolors); 420 $i += $n; 421 } 422 $tt = array_slice($this->setslicecolors,0,$n % $numcolors); 423 $this->setslicecolors = array_merge($this->setslicecolors,$tt); 424 $this->setslicecolors = array_reverse($this->setslicecolors); 425 } 426 427 // Draw the slices 428 $sum=0; 429 for($i=0; $i < $n; ++$i) 430 $sum += $this->data[$i]; 431 432 // Bail out with error if the sum is 0 433 if( $sum==0 ) 434 JpGraphError::RaiseL(15009);//("Sum of all data is 0 for Pie."); 435 436 // Set up the pie-circle 437 if( $this->radius <= 1 ) 438 $radius = floor($this->radius*min($img->width,$img->height)); 439 else { 440 $radius = $aaoption === 1 ? $this->radius*2 : $this->radius; 441 } 442 443 if( $this->posx <= 1 && $this->posx > 0 ) 444 $xc = round($this->posx*$img->width); 445 else 446 $xc = $this->posx ; 447 448 if( $this->posy <= 1 && $this->posy > 0 ) 449 $yc = round($this->posy*$img->height); 450 else 451 $yc = $this->posy ; 452 453 $n = count($this->data); 454 455 if( $this->explode_all ) 456 for($i=0; $i < $n; ++$i) 457 $this->explode_radius[$i]=$this->explode_r; 458 459 // If we have a shadow and not just drawing the labels 460 if( $this->ishadowcolor != "" && $aaoption !== 2) { 461 $accsum=0; 462 $angle2 = $this->startangle; 463 $img->SetColor($this->ishadowcolor); 464 for($i=0; $sum > 0 && $i < $n; ++$i) { 465 $j = $n-$i-1; 466 $d = $this->data[$i]; 467 $angle1 = $angle2; 468 $accsum += $d; 469 $angle2 = $this->startangle+2*M_PI*$accsum/$sum; 470 if( empty($this->explode_radius[$j]) ) 471 $this->explode_radius[$j]=0; 472 473 if( $d < 0.00001 ) continue; 474 475 $la = 2*M_PI - (abs($angle2-$angle1)/2.0+$angle1); 476 477 $xcm = $xc + $this->explode_radius[$j]*cos($la)*$expscale; 478 $ycm = $yc - $this->explode_radius[$j]*sin($la)*$expscale; 479 480 $xcm += $this->ishadowdrop*$expscale; 481 $ycm += $this->ishadowdrop*$expscale; 482 483 $_sa = round($angle1*180/M_PI); 484 $_ea = round($angle2*180/M_PI); 485 486 // The CakeSlice method draws a full circle in case of start angle = end angle 487 // for pie slices we don't want this behaviour unless we only have one 488 // slice in the pie in case it is the wanted behaviour 489 if( $_ea-$_sa > 0.1 || $n==1 ) { 490 $img->CakeSlice($xcm,$ycm,$radius-1,$radius-1, 491 $angle1*180/M_PI,$angle2*180/M_PI,$this->ishadowcolor); 492 } 493 } 494 } 495 496 //-------------------------------------------------------------------------------- 497 // This is the main loop to draw each cake slice 498 //-------------------------------------------------------------------------------- 499 500 // Set up the accumulated sum, start angle for first slice and border color 501 $accsum=0; 502 $angle2 = $this->startangle; 503 $img->SetColor($this->color); 504 505 // Loop though all the slices if there is a pie to draw (sum>0) 506 // There are n slices in total 507 for($i=0; $sum>0 && $i < $n; ++$i) { 508 509 // $j is the actual index used for the slice 510 $j = $n-$i-1; 511 512 // Make sure we havea valid distance to explode the slice 513 if( empty($this->explode_radius[$j]) ) 514 $this->explode_radius[$j]=0; 515 516 // The actual numeric value for the slice 517 $d = $this->data[$i]; 518 519 $angle1 = $angle2; 520 521 // Accumlate the sum 522 $accsum += $d; 523 524 // The new angle when we add the "size" of this slice 525 // angle1 is then the start and angle2 the end of this slice 526 $angle2 = $this->NormAngle($this->startangle+2*M_PI*$accsum/$sum); 527 528 // We avoid some trouble by not allowing end angle to be 0, in that case 529 // we translate to 360 530 531 532 // la is used to hold the label angle, which is centered on the slice 533 if( $angle2 < 0.0001 && $angle1 > 0.0001 ) { 534 $this->la[$i] = 2*M_PI - (abs(2*M_PI-$angle1)/2.0+$angle1); 535 } 536 elseif( $angle1 > $angle2 ) { 537 // The case where the slice crosses the 3 a'clock line 538 // Remember that the slices are counted clockwise and 539 // labels are counted counter clockwise so we need to revert with 2 PI 540 $this->la[$i] = 2*M_PI-$this->NormAngle($angle1 + ((2*M_PI - $angle1)+$angle2)/2); 541 } 542 else { 543 $this->la[$i] = 2*M_PI - (abs($angle2-$angle1)/2.0+$angle1); 544 } 545 546 // Too avoid rounding problems we skip the slice if it is too small 547 if( $d < 0.00001 ) continue; 548 549 // If the user has specified an array of colors for each slice then use 550 // that a color otherwise use the theme array (ta) of colors 551 if( $this->setslicecolors==null ) 552 $slicecolor=$colors[$ta[$i%$numcolors]]; 553 else 554 $slicecolor=$this->setslicecolors[$i%$numcolors]; 555 556 557 558 //$_sa = round($angle1*180/M_PI); 559 //$_ea = round($angle2*180/M_PI); 560 //$_la = round($this->la[$i]*180/M_PI); 561 //echo "ang1=$_sa , ang2=$_ea, la=$_la, color=$slicecolor<br>"; 562 563 564 // If we have enabled antialias then we don't draw any border so 565 // make the bordedr color the same as the slice color 566 if( $this->pie_interior_border && $aaoption===0 ) 567 $img->SetColor($this->color); 568 else 569 $img->SetColor($slicecolor); 570 $arccolor = $this->pie_border && $aaoption===0 ? $this->color : ""; 571 572 // Calculate the x,y coordinates for the base of this slice taking 573 // the exploded distance into account. Here we use the mid angle as the 574 // ray of extension and we have the mid angle handy as it is also the 575 // label angle 576 $xcm = $xc + $this->explode_radius[$j]*cos($this->la[$i])*$expscale; 577 $ycm = $yc - $this->explode_radius[$j]*sin($this->la[$i])*$expscale; 578 579 // If we are not just drawing the labels then draw this cake slice 580 if( $aaoption !== 2 ) { 581 582 583 $_sa = round($angle1*180/M_PI); 584 $_ea = round($angle2*180/M_PI); 585 $_la = round($this->la[$i]*180/M_PI); 586 //echo "[$i] sa=$_sa, ea=$_ea, la[$i]=$_la, (color=$slicecolor)<br>"; 587 588 589 // The CakeSlice method draws a full circle in case of start angle = end angle 590 // for pie slices we don't want this behaviour unless we only have one 591 // slice in the pie in case it is the wanted behaviour 592 if( abs($_ea-$_sa) > 0.1 || $n==1 ) { 593 $img->CakeSlice($xcm,$ycm,$radius-1,$radius-1,$_sa,$_ea,$slicecolor,$arccolor); 594 } 595 } 596 597 // If the CSIM is used then make sure we register a CSIM area for this slice as well 598 if( $this->csimtargets && $aaoption !== 1 ) { 599 $this->AddSliceToCSIM($i,$xcm,$ycm,$radius,$angle1,$angle2); 600 } 601 } 602 603 // Format the titles for each slice 604 if( $aaoption !== 2 ) { 605 for( $i=0; $i < $n; ++$i) { 606 if( $this->labeltype==0 ) { 607 if( $sum != 0 ) 608 $l = 100.0*$this->data[$i]/$sum; 609 else 610 $l = 0.0; 611 } 612 elseif( $this->labeltype==1 ) { 613 $l = $this->data[$i]*1.0; 614 } 615 else { 616 $l = $this->adjusted_data[$i]; 617 } 618 if( isset($this->labels[$i]) && is_string($this->labels[$i]) ) 619 $this->labels[$i]=sprintf($this->labels[$i],$l); 620 else 621 $this->labels[$i]=$l; 622 } 623 } 624 625 if( $this->value->show && $aaoption !== 1 ) { 626 $this->StrokeAllLabels($img,$xc,$yc,$radius); 627 } 628 629 // Adjust title position 630 if( $aaoption !== 1 ) { 631 $this->title->SetPos($xc, 632 $yc-$this->title->GetFontHeight($img)-$radius-$this->title->margin, 633 "center","bottom"); 634 $this->title->Stroke($img); 635 } 636 637 } 638 639 //--------------- 640 // PRIVATE METHODS 396 // aaoption is used to handle antialias 397 // aaoption == 0 a normal pie 398 // aaoption == 1 just the body 399 // aaoption == 2 just the values 400 401 // Explode scaling. If anti alias we scale the image 402 // twice and we also need to scale the exploding distance 403 $expscale = $aaoption === 1 ? 2 : 1; 404 405 if( $this->labeltype == 2 ) { 406 // Adjust the data so that it will add up to 100% 407 $this->adjusted_data = $this->AdjPercentage($this->data); 408 } 409 410 if ($this->use_plot_theme_colors) { 411 $this->setslicecolors = null; 412 } 413 414 $colors = array_keys($img->rgb->rgb_table); 415 sort($colors); 416 $ta=$this->themearr[$this->theme]; 417 $n = count($this->data); 418 419 if( $this->setslicecolors==null ) { 420 $numcolors=count($ta); 421 } 422 else { 423 // We need to create an array of colors as long as the data 424 // since we need to reverse it to get the colors in the right order 425 $numcolors=count($this->setslicecolors); 426 $i = 2*$numcolors; 427 while( $n > $i ) { 428 $this->setslicecolors = array_merge($this->setslicecolors,$this->setslicecolors); 429 $i += $n; 430 } 431 $tt = array_slice($this->setslicecolors,0,$n % $numcolors); 432 $this->setslicecolors = array_merge($this->setslicecolors,$tt); 433 $this->setslicecolors = array_reverse($this->setslicecolors); 434 } 435 436 // Draw the slices 437 $sum=0; 438 for($i=0; $i < $n; ++$i) 439 $sum += $this->data[$i]; 440 441 // Bail out with error if the sum is 0 442 if( $sum==0 ) { 443 JpGraphError::RaiseL(15009);//("Sum of all data is 0 for Pie."); 444 } 445 446 // Set up the pie-circle 447 if( $this->radius <= 1 ) { 448 $radius = floor($this->radius*min($img->width,$img->height)); 449 } 450 else { 451 $radius = $aaoption === 1 ? $this->radius*2 : $this->radius; 452 } 453 454 if( $this->posx <= 1 && $this->posx > 0 ) { 455 $xc = round($this->posx*$img->width); 456 } 457 else { 458 $xc = $this->posx ; 459 } 460 461 if( $this->posy <= 1 && $this->posy > 0 ) { 462 $yc = round($this->posy*$img->height); 463 } 464 else { 465 $yc = $this->posy ; 466 } 467 468 $n = count($this->data); 469 470 if( $this->explode_all ) { 471 for($i=0; $i < $n; ++$i) { 472 $this->explode_radius[$i]=$this->explode_r; 473 } 474 } 475 476 // If we have a shadow and not just drawing the labels 477 if( $this->ishadowcolor != "" && $aaoption !== 2) { 478 $accsum=0; 479 $angle2 = $this->startangle; 480 $img->SetColor($this->ishadowcolor); 481 for($i=0; $sum > 0 && $i < $n; ++$i) { 482 $j = $n-$i-1; 483 $d = $this->data[$i]; 484 $angle1 = $angle2; 485 $accsum += $d; 486 $angle2 = $this->startangle+2*M_PI*$accsum/$sum; 487 if( empty($this->explode_radius[$j]) ) { 488 $this->explode_radius[$j]=0; 489 } 490 491 if( $d < 0.00001 ) continue; 492 493 $la = 2*M_PI - (abs($angle2-$angle1)/2.0+$angle1); 494 495 $xcm = $xc + $this->explode_radius[$j]*cos($la)*$expscale; 496 $ycm = $yc - $this->explode_radius[$j]*sin($la)*$expscale; 497 498 $xcm += $this->ishadowdrop*$expscale; 499 $ycm += $this->ishadowdrop*$expscale; 500 501 $_sa = round($angle1*180/M_PI); 502 $_ea = round($angle2*180/M_PI); 503 504 // The CakeSlice method draws a full circle in case of start angle = end angle 505 // for pie slices we don't want this behaviour unless we only have one 506 // slice in the pie in case it is the wanted behaviour 507 if( $_ea-$_sa > 0.1 || $n==1 ) { 508 $img->CakeSlice($xcm,$ycm,$radius-1,$radius-1, 509 $angle1*180/M_PI,$angle2*180/M_PI,$this->ishadowcolor); 510 } 511 } 512 } 513 514 //-------------------------------------------------------------------------------- 515 // This is the main loop to draw each cake slice 516 //-------------------------------------------------------------------------------- 517 518 // Set up the accumulated sum, start angle for first slice and border color 519 $accsum=0; 520 $angle2 = $this->startangle; 521 $img->SetColor($this->color); 522 523 // Loop though all the slices if there is a pie to draw (sum>0) 524 // There are n slices in total 525 for($i=0; $sum>0 && $i < $n; ++$i) { 526 527 // $j is the actual index used for the slice 528 $j = $n-$i-1; 529 530 // Make sure we havea valid distance to explode the slice 531 if( empty($this->explode_radius[$j]) ) { 532 $this->explode_radius[$j]=0; 533 } 534 535 // The actual numeric value for the slice 536 $d = $this->data[$i]; 537 538 $angle1 = $angle2; 539 540 // Accumlate the sum 541 $accsum += $d; 542 543 // The new angle when we add the "size" of this slice 544 // angle1 is then the start and angle2 the end of this slice 545 $angle2 = $this->NormAngle($this->startangle+2*M_PI*$accsum/$sum); 546 547 // We avoid some trouble by not allowing end angle to be 0, in that case 548 // we translate to 360 549 550 // la is used to hold the label angle, which is centered on the slice 551 if( $angle2 < 0.0001 && $angle1 > 0.0001 ) { 552 $this->la[$i] = 2*M_PI - (abs(2*M_PI-$angle1)/2.0+$angle1); 553 } 554 elseif( $angle1 > $angle2 ) { 555 // The case where the slice crosses the 3 a'clock line 556 // Remember that the slices are counted clockwise and 557 // labels are counted counter clockwise so we need to revert with 2 PI 558 $this->la[$i] = 2*M_PI-$this->NormAngle($angle1 + ((2*M_PI - $angle1)+$angle2)/2); 559 } 560 else { 561 $this->la[$i] = 2*M_PI - (abs($angle2-$angle1)/2.0+$angle1); 562 } 563 564 // Too avoid rounding problems we skip the slice if it is too small 565 if( $d < 0.00001 ) continue; 566 567 // If the user has specified an array of colors for each slice then use 568 // that a color otherwise use the theme array (ta) of colors 569 if( $this->setslicecolors==null ) { 570 $slicecolor=$colors[$ta[$i%$numcolors]]; 571 } 572 else { 573 $slicecolor=$this->setslicecolors[$i%$numcolors]; 574 } 575 576 // $_sa = round($angle1*180/M_PI); 577 // $_ea = round($angle2*180/M_PI); 578 // $_la = round($this->la[$i]*180/M_PI); 579 // echo "Slice#$i: ang1=$_sa , ang2=$_ea, la=$_la, color=$slicecolor<br>"; 580 581 582 // If we have enabled antialias then we don't draw any border so 583 // make the bordedr color the same as the slice color 584 if( $this->pie_interior_border && $aaoption===0 ) { 585 $img->SetColor($this->color); 586 } 587 else { 588 $img->SetColor($slicecolor); 589 } 590 $arccolor = $this->pie_border && $aaoption===0 ? $this->color : ""; 591 592 // Calculate the x,y coordinates for the base of this slice taking 593 // the exploded distance into account. Here we use the mid angle as the 594 // ray of extension and we have the mid angle handy as it is also the 595 // label angle 596 $xcm = $xc + $this->explode_radius[$j]*cos($this->la[$i])*$expscale; 597 $ycm = $yc - $this->explode_radius[$j]*sin($this->la[$i])*$expscale; 598 599 // If we are not just drawing the labels then draw this cake slice 600 if( $aaoption !== 2 ) { 601 602 $_sa = round($angle1*180/M_PI); 603 $_ea = round($angle2*180/M_PI); 604 $_la = round($this->la[$i]*180/M_PI); 605 //echo "[$i] sa=$_sa, ea=$_ea, la[$i]=$_la, (color=$slicecolor)<br>"; 606 607 // The CakeSlice method draws a full circle in case of start angle = end angle 608 // for pie slices we want this in case the slice have a value larger than 99% of the 609 // total sum 610 if( abs($_ea-$_sa) >= 1 || $d == $sum ) { 611 $img->CakeSlice($xcm,$ycm,$radius-1,$radius-1,$_sa,$_ea,$slicecolor,$arccolor); 612 } 613 } 614 615 // If the CSIM is used then make sure we register a CSIM area for this slice as well 616 if( $this->csimtargets && $aaoption !== 1 ) { 617 $this->AddSliceToCSIM($i,$xcm,$ycm,$radius,$angle1,$angle2); 618 } 619 } 620 621 // Format the titles for each slice 622 if( $aaoption !== 2 ) { 623 for( $i=0; $i < $n; ++$i) { 624 if( $this->labeltype==0 ) { 625 if( $sum != 0 ) 626 $l = 100.0*$this->data[$i]/$sum; 627 else 628 $l = 0.0; 629 } 630 elseif( $this->labeltype==1 ) { 631 $l = $this->data[$i]*1.0; 632 } 633 else { 634 $l = $this->adjusted_data[$i]; 635 } 636 if( isset($this->labels[$i]) && is_string($this->labels[$i]) ) 637 $this->labels[$i]=sprintf($this->labels[$i],$l); 638 else 639 $this->labels[$i]=$l; 640 } 641 } 642 643 if( $this->value->show && $aaoption !== 1 ) { 644 $this->StrokeAllLabels($img,$xc,$yc,$radius); 645 } 646 647 // Adjust title position 648 if( $aaoption !== 1 ) { 649 $this->title->SetPos($xc, 650 $yc-$this->title->GetFontHeight($img)-$radius-$this->title->margin, 651 "center","bottom"); 652 $this->title->Stroke($img); 653 } 654 655 } 656 657 //--------------- 658 // PRIVATE METHODS 641 659 642 660 function NormAngle($a) { 643 644 645 661 while( $a < 0 ) $a += 2*M_PI; 662 while( $a > 2*M_PI ) $a -= 2*M_PI; 663 return $a; 646 664 } 647 665 648 666 function Quadrant($a) { 649 650 651 652 653 654 655 656 657 667 $a=$this->NormAngle($a); 668 if( $a > 0 && $a <= M_PI/2 ) 669 return 0; 670 if( $a > M_PI/2 && $a <= M_PI ) 671 return 1; 672 if( $a > M_PI && $a <= 1.5*M_PI ) 673 return 2; 674 if( $a > 1.5*M_PI ) 675 return 3; 658 676 } 659 677 660 678 function StrokeGuideLabels($img,$xc,$yc,$radius) { 661 662 663 664 665 666 667 668 669 $incluster=false;// flag if we are currently in a cluster or not670 $clusters = array();// array of clusters671 $cidx=-1;// running cluster index672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 // If we cross a quadrant boundary we normally start a 688 689 690 691 // the cluster for q=1 is close to 12'a clock and the 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 $i++; 720 721 722 723 724 725 726 727 728 729 730 731 if( $q1 == 0 && $cidx > -1 && 732 $clusters[$cidx][1] == 1 && 733 734 735 736 737 738 739 740 741 742 else { 743 744 745 746 747 $clusters[$cidx][1] = 1; 748 749 750 751 752 753 754 755 756 757 758 759 $clusters[$cidx][1] = 1; 760 761 762 763 764 765 766 767 768 769 770 $clusters[$cidx][1] = 1; 771 772 773 774 if( true ) { 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 for($j=0; $j < $csize; ++$j) { 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 // in quadrant 1 or 3 very close to the "equator" (< 20 degrees) 855 // and the previous clusters last slice is within the tolerance. 856 // In that case we add a font height to this labels Y-position 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 $this->StrokeLabel($label,$img,$xc,$yc,$a,$r); 899 if( $this->iShowGuideLineForSingle ) 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 679 $n = count($this->labels); 680 681 //----------------------------------------------------------------------- 682 // Step 1 of the algorithm is to construct a number of clusters 683 // a cluster is defined as all slices within the same quadrant (almost) 684 // that has an angular distance less than the treshold 685 //----------------------------------------------------------------------- 686 $tresh_hold=25 * M_PI/180; // 25 degrees difference to be in a cluster 687 $incluster=false; // flag if we are currently in a cluster or not 688 $clusters = array(); // array of clusters 689 $cidx=-1; // running cluster index 690 691 // Go through all the labels and construct a number of clusters 692 for($i=0; $i < $n-1; ++$i) { 693 // Calc the angle distance between two consecutive slices 694 $a1=$this->la[$i]; 695 $a2=$this->la[$i+1]; 696 $q1 = $this->Quadrant($a1); 697 $q2 = $this->Quadrant($a2); 698 $diff = abs($a1-$a2); 699 if( $diff < $tresh_hold ) { 700 if( $incluster ) { 701 $clusters[$cidx][1]++; 702 // Each cluster can only cover one quadrant 703 // Do we cross a quadrant ( and must break the cluster) 704 if( $q1 != $q2 ) { 705 // If we cross a quadrant boundary we normally start a 706 // new cluster. However we need to take the 12'a clock 707 // and 6'a clock positions into a special consideration. 708 // Case 1: WE go from q=1 to q=2 if the last slice on 709 // the cluster for q=1 is close to 12'a clock and the 710 // first slice in q=0 is small we extend the previous 711 // cluster 712 if( $q1 == 1 && $q2 == 0 && $a2 > (90-15)*M_PI/180 ) { 713 if( $i < $n-2 ) { 714 $a3 = $this->la[$i+2]; 715 // If there isn't a cluster coming up with the next-next slice 716 // we extend the previous cluster to cover this slice as well 717 if( abs($a3-$a2) >= $tresh_hold ) { 718 $clusters[$cidx][1]++; 719 $i++; 720 } 721 } 722 } 723 elseif( $q1 == 3 && $q2 == 2 && $a2 > (270-15)*M_PI/180 ) { 724 if( $i < $n-2 ) { 725 $a3 = $this->la[$i+2]; 726 // If there isn't a cluster coming up with the next-next slice 727 // we extend the previous cluster to cover this slice as well 728 if( abs($a3-$a2) >= $tresh_hold ) { 729 $clusters[$cidx][1]++; 730 $i++; 731 } 732 } 733 } 734 735 if( $q1==2 && $q2==1 && $a2 > (180-15)*M_PI/180 ) { 736 $clusters[$cidx][1]++; 737 $i++; 738 } 739 740 $incluster = false; 741 } 742 } 743 elseif( $q1 == $q2) { 744 $incluster = true; 745 // Now we have a special case for quadrant 0. If we previously 746 // have a cluster of one in quadrant 0 we just extend that 747 // cluster. If we don't do this then we risk that the label 748 // for the cluster of one will cross the guide-line 749 if( $q1 == 0 && $cidx > -1 && 750 $clusters[$cidx][1] == 1 && 751 $this->Quadrant($this->la[$clusters[$cidx][0]]) == 0 ) { 752 $clusters[$cidx][1]++; 753 } 754 else { 755 $cidx++; 756 $clusters[$cidx][0] = $i; 757 $clusters[$cidx][1] = 1; 758 } 759 } 760 else { 761 // Create a "cluster" of one since we are just crossing 762 // a quadrant 763 $cidx++; 764 $clusters[$cidx][0] = $i; 765 $clusters[$cidx][1] = 1; 766 } 767 } 768 else { 769 if( $incluster ) { 770 // Add the last slice 771 $clusters[$cidx][1]++; 772 $incluster = false; 773 } 774 else { // Create a "cluster" of one 775 $cidx++; 776 $clusters[$cidx][0] = $i; 777 $clusters[$cidx][1] = 1; 778 } 779 } 780 } 781 // Handle the very last slice 782 if( $incluster ) { 783 $clusters[$cidx][1]++; 784 } 785 else { // Create a "cluster" of one 786 $cidx++; 787 $clusters[$cidx][0] = $i; 788 $clusters[$cidx][1] = 1; 789 } 790 791 /* 792 if( true ) { 793 // Debug printout in labels 794 for( $i=0; $i <= $cidx; ++$i ) { 795 for( $j=0; $j < $clusters[$i][1]; ++$j ) { 796 $a = $this->la[$clusters[$i][0]+$j]; 797 $aa = round($a*180/M_PI); 798 $q = $this->Quadrant($a); 799 $this->labels[$clusters[$i][0]+$j]="[$q:$aa] $i:$j"; 800 } 801 } 802 } 803 */ 804 805 //----------------------------------------------------------------------- 806 // Step 2 of the algorithm is use the clusters and draw the labels 807 // and guidelines 808 //----------------------------------------------------------------------- 809 810 // We use the font height as the base factor for how far we need to 811 // spread the labels in the Y-direction. 812 $this->value->ApplyFont($img); 813 $fh = $img->GetFontHeight(); 814 $origvstep=$fh*$this->iGuideVFactor; 815 $this->value->SetMargin(0); 816 817 // Number of clusters found 818 $nc = count($clusters); 819 820 // Walk through all the clusters 821 for($i=0; $i < $nc; ++$i) { 822 823 // Start angle and number of slices in this cluster 824 $csize = $clusters[$i][1]; 825 $a = $this->la[$clusters[$i][0]]; 826 $q = $this->Quadrant($a); 827 828 // Now set up the start and end conditions to make sure that 829 // in each cluster we walk through the all the slices starting with the slice 830 // closest to the equator. Since all slices are numbered clockwise from "3'a clock" 831 // we have different conditions depending on in which quadrant the slice lies within. 832 if( $q == 0 ) { 833 $start = $csize-1; $idx = $start; $step = -1; $vstep = -$origvstep; 834 } 835 elseif( $q == 1 ) { 836 $start = 0; $idx = $start; $step = 1; $vstep = -$origvstep; 837 } 838 elseif( $q == 2 ) { 839 $start = $csize-1; $idx = $start; $step = -1; $vstep = $origvstep; 840 } 841 elseif( $q == 3 ) { 842 $start = 0; $idx = $start; $step = 1; $vstep = $origvstep; 843 } 844 845 // Walk through all slices within this cluster 846 for($j=0; $j < $csize; ++$j) { 847 // Now adjust the position of the labels in each cluster starting 848 // with the slice that is closest to the equator of the pie 849 $a = $this->la[$clusters[$i][0]+$idx]; 850 851 // Guide line start in the center of the arc of the slice 852 $r = $radius+$this->explode_radius[$n-1-($clusters[$i][0]+$idx)]; 853 $x = round($r*cos($a)+$xc); 854 $y = round($yc-$r*sin($a)); 855 856 // The distance from the arc depends on chosen font and the "R-Factor" 857 $r += $fh*$this->iGuideLineRFactor; 858 859 // Should the labels be placed curved along the pie or in straight columns 860 // outside the pie? 861 if( $this->iGuideLineCurve ) 862 $xt=round($r*cos($a)+$xc); 863 864 // If this is the first slice in the cluster we need some first time 865 // proessing 866 if( $idx == $start ) { 867 if( ! $this->iGuideLineCurve ) 868 $xt=round($r*cos($a)+$xc); 869 $yt=round($yc-$r*sin($a)); 870 871 // Some special consideration in case this cluster starts 872 // in quadrant 1 or 3 very close to the "equator" (< 20 degrees) 873 // and the previous clusters last slice is within the tolerance. 874 // In that case we add a font height to this labels Y-position 875 // so it doesn't collide with 876 // the slice in the previous cluster 877 $prevcluster = ($i + ($nc-1) ) % $nc; 878 $previdx=$clusters[$prevcluster][0]+$clusters[$prevcluster][1]-1; 879 if( $q == 1 && $a > 160*M_PI/180 ) { 880 // Get the angle for the previous clusters last slice 881 $diff = abs($a-$this->la[$previdx]); 882 if( $diff < $tresh_hold ) { 883 $yt -= $fh; 884 } 885 } 886 elseif( $q == 3 && $a > 340*M_PI/180 ) { 887 // We need to subtract 360 to compare angle distance between 888 // q=0 and q=3 889 $diff = abs($a-$this->la[$previdx]-360*M_PI/180); 890 if( $diff < $tresh_hold ) { 891 $yt += $fh; 892 } 893 } 894 895 } 896 else { 897 // The step is at minimum $vstep but if the slices are relatively large 898 // we make sure that we add at least a step that corresponds to the vertical 899 // distance between the centers at the arc on the slice 900 $prev_a = $this->la[$clusters[$i][0]+($idx-$step)]; 901 $dy = abs($radius*(sin($a)-sin($prev_a))*1.2); 902 if( $vstep > 0 ) 903 $yt += max($vstep,$dy); 904 else 905 $yt += min($vstep,-$dy); 906 } 907 908 $label = $this->labels[$clusters[$i][0]+$idx]; 909 910 if( $csize == 1 ) { 911 // A "meta" cluster with only one slice 912 $r = $radius+$this->explode_radius[$n-1-($clusters[$i][0]+$idx)]; 913 $rr = $r+$img->GetFontHeight()/2; 914 $xt=round($rr*cos($a)+$xc); 915 $yt=round($yc-$rr*sin($a)); 916 $this->StrokeLabel($label,$img,$xc,$yc,$a,$r); 917 if( $this->iShowGuideLineForSingle ) 918 $this->guideline->Stroke($img,$x,$y,$xt,$yt); 919 } 920 else { 921 $this->guideline->Stroke($img,$x,$y,$xt,$yt); 922 if( $q==1 || $q==2 ) { 923 // Left side of Pie 924 $this->guideline->Stroke($img,$xt,$yt,$xt-$this->guidelinemargin,$yt); 925 $lbladj = -$this->guidelinemargin-5; 926 $this->value->halign = "right"; 927 $this->value->valign = "center"; 928 } 929 else { 930 // Right side of pie 931 $this->guideline->Stroke($img,$xt,$yt,$xt+$this->guidelinemargin,$yt); 932 $lbladj = $this->guidelinemargin+5; 933 $this->value->halign = "left"; 934 $this->value->valign = "center"; 935 } 936 $this->value->Stroke($img,$label,$xt+$lbladj,$yt); 937 } 938 939 // Udate idx to point to next slice in the cluster to process 940 $idx += $step; 941 } 942 } 925 943 } 926 944 927 945 function StrokeAllLabels($img,$xc,$yc,$radius) { 928 929 930 931 932 933 934 935 936 937 938 939 940 941 $radius + $this->explode_radius[$n-1-$i]); 942 943 946 // First normalize all angles for labels 947 $n = count($this->la); 948 for($i=0; $i < $n; ++$i) { 949 $this->la[$i] = $this->NormAngle($this->la[$i]); 950 } 951 if( $this->guideline->iShow ) { 952 $this->StrokeGuideLabels($img,$xc,$yc,$radius); 953 } 954 else { 955 $n = count($this->labels); 956 for($i=0; $i < $n; ++$i) { 957 $this->StrokeLabel($this->labels[$i],$img,$xc,$yc, 958 $this->la[$i], 959 $radius + $this->explode_radius[$n-1-$i]); 960 } 961 } 944 962 } 945 963 … … 947 965 function StrokeLabel($label,$img,$xc,$yc,$a,$r) { 948 966 949 // Default value 950 if( $this->ilabelposadj === 'auto' ) 951 $this->ilabelposadj = 0.65; 952 953 // We position the values diferently depending on if they are inside 954 // or outside the pie 955 if( $this->ilabelposadj < 1.0 ) { 956 957 $this->value->SetAlign('center','center'); 958 $this->value->margin = 0; 959 960 $xt=round($this->ilabelposadj*$r*cos($a)+$xc); 961 $yt=round($yc-$this->ilabelposadj*$r*sin($a)); 962 963 $this->value->Stroke($img,$label,$xt,$yt); 964 } 965 else { 966 967 $this->value->halign = "left"; 968 $this->value->valign = "top"; 969 $this->value->margin = 0; 970 971 // Position the axis title. 972 // dx, dy is the offset from the top left corner of the bounding box that sorrounds the text 973 // that intersects with the extension of the corresponding axis. The code looks a little 974 // bit messy but this is really the only way of having a reasonable position of the 975 // axis titles. 976 $this->value->ApplyFont($img); 977 $h=$img->GetTextHeight($label); 978 // For numeric values the format of the display value 979 // must be taken into account 980 if( is_numeric($label) ) { 981 if( $label > 0 ) 982 $w=$img->GetTextWidth(sprintf($this->value->format,$label)); 983 else 984 $w=$img->GetTextWidth(sprintf($this->value->negformat,$label)); 985 } 986 else 987 $w=$img->GetTextWidth($label); 988 989 if( $this->ilabelposadj > 1.0 && $this->ilabelposadj < 5.0) { 990 $r *= $this->ilabelposadj; 991 } 992 993 $r += $img->GetFontHeight()/1.5; 994 995 $xt=round($r*cos($a)+$xc); 996 $yt=round($yc-$r*sin($a)); 997 998 // Normalize angle 999 while( $a < 0 ) $a += 2*M_PI; 1000 while( $a > 2*M_PI ) $a -= 2*M_PI; 1001 1002 if( $a>=7*M_PI/4 || $a <= M_PI/4 ) $dx=0; 1003 if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dx=($a-M_PI/4)*2/M_PI; 1004 if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dx=1; 1005 if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dx=(1-($a-M_PI*5/4)*2/M_PI); 1006 1007 if( $a>=7*M_PI/4 ) $dy=(($a-M_PI)-3*M_PI/4)*2/M_PI; 1008 if( $a<=M_PI/4 ) $dy=(1-$a*2/M_PI); 1009 if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dy=1; 1010 if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dy=(1-($a-3*M_PI/4)*2/M_PI); 1011 if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dy=0; 1012 1013 $this->value->Stroke($img,$label,$xt-$dx*$w,$yt-$dy*$h); 1014 } 1015 } 967 // Default value 968 if( $this->ilabelposadj === 'auto' ) 969 $this->ilabelposadj = 0.65; 970 971 // We position the values diferently depending on if they are inside 972 // or outside the pie 973 if( $this->ilabelposadj < 1.0 ) { 974 975 $this->value->SetAlign('center','center'); 976 $this->value->margin = 0; 977 978 $xt=round($this->ilabelposadj*$r*cos($a)+$xc); 979 $yt=round($yc-$this->ilabelposadj*$r*sin($a)); 980 981 $this->value->Stroke($img,$label,$xt,$yt); 982 } 983 else { 984 985 $this->value->halign = "left"; 986 $this->value->valign = "top"; 987 $this->value->margin = 0; 988 989 // Position the axis title. 990 // dx, dy is the offset from the top left corner of the bounding box that sorrounds the text 991 // that intersects with the extension of the corresponding axis. The code looks a little 992 // bit messy but this is really the only way of having a reasonable position of the 993 // axis titles. 994 $this->value->ApplyFont($img); 995 $h=$img->GetTextHeight($label); 996 // For numeric values the format of the display value 997 // must be taken into account 998 if( is_numeric($label) ) { 999 if( $label > 0 ) 1000 $w=$img->GetTextWidth(sprintf($this->value->format,$label)); 1001 else 1002 $w=$img->GetTextWidth(sprintf($this->value->negformat,$label)); 1003 } 1004 else 1005 $w=$img->GetTextWidth($label); 1006 1007 if( $this->ilabelposadj > 1.0 && $this->ilabelposadj < 5.0) { 1008 $r *= $this->ilabelposadj; 1009 } 1010 1011 $r += $img->GetFontHeight()/1.5; 1012 1013 $xt=round($r*cos($a)+$xc); 1014 $yt=round($yc-$r*sin($a)); 1015 1016 // Normalize angle 1017 while( $a < 0 ) $a += 2*M_PI; 1018 while( $a > 2*M_PI ) $a -= 2*M_PI; 1019 1020 if( $a>=7*M_PI/4 || $a <= M_PI/4 ) $dx=0; 1021 if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dx=($a-M_PI/4)*2/M_PI; 1022 if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dx=1; 1023 if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dx=(1-($a-M_PI*5/4)*2/M_PI); 1024 1025 if( $a>=7*M_PI/4 ) $dy=(($a-M_PI)-3*M_PI/4)*2/M_PI; 1026 if( $a<=M_PI/4 ) $dy=(1-$a*2/M_PI); 1027 if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dy=1; 1028 if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dy=(1-($a-3*M_PI/4)*2/M_PI); 1029 if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dy=0; 1030 1031 $this->value->Stroke($img,$label,$xt-$dx*$w,$yt-$dy*$h); 1032 } 1033 } 1034 1035 function UsePlotThemeColors($flag = true) { 1036 $this->use_plot_theme_colors = $flag; 1037 } 1016 1038 } // Class 1017 1039 … … 1019 1041 //=================================================== 1020 1042 // CLASS PiePlotC 1021 // Description: Same as a normal pie plot but with a 1043 // Description: Same as a normal pie plot but with a 1022 1044 // filled circle in the center 1023 1045 //=================================================== 1024 1046 class PiePlotC extends PiePlot { 1025 private $imidsize=0.5; 1047 private $imidsize=0.5; // Fraction of total width 1026 1048 private $imidcolor='white'; 1027 1049 public $midtitle=''; 1028 1050 private $middlecsimtarget='',$middlecsimwintarget='',$middlecsimalt=''; 1029 1051 1030 function PiePlotC($data,$aCenterTitle='') {1031 parent::PiePlot($data);1032 1033 1052 function __construct($data,$aCenterTitle='') { 1053 parent::__construct($data); 1054 $this->midtitle = new Text(); 1055 $this->midtitle->ParagraphAlign('center'); 1034 1056 } 1035 1057 1036 1058 function SetMid($aTitle,$aColor='white',$aSize=0.5) { 1037 1038 1039 $this->imidsize = $aSize ; 1040 $this->imidcolor = $aColor ; 1059 $this->midtitle->Set($aTitle); 1060 1061 $this->imidsize = $aSize ; 1062 $this->imidcolor = $aColor ; 1041 1063 } 1042 1064 1043 1065 function SetMidTitle($aTitle) { 1044 1066 $this->midtitle->Set($aTitle); 1045 1067 } 1046 1068 1047 1069 function SetMidSize($aSize) { 1048 $this->imidsize = $aSize ; 1070 $this->imidsize = $aSize ; 1049 1071 } 1050 1072 1051 1073 function SetMidColor($aColor) { 1052 $this->imidcolor = $aColor ; 1074 $this->imidcolor = $aColor ; 1053 1075 } 1054 1076 1055 1077 function SetMidCSIM($aTarget,$aAlt='',$aWinTarget='') { 1056 1057 1058 1059 } 1060 1061 function AddSliceToCSIM($i,$xc,$yc,$radius,$sa,$ea) { 1078 $this->middlecsimtarget = $aTarget; 1079 $this->middlecsimwintarget = $aWinTarget; 1080 $this->middlecsimalt = $aAlt; 1081 } 1082 1083 function AddSliceToCSIM($i,$xc,$yc,$radius,$sa,$ea) { 1062 1084 //Slice number, ellipse centre (x,y), radius, start angle, end angle 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 $coords.= ", $xp, $yp"; 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1085 while( $sa > 2*M_PI ) $sa = $sa - 2*M_PI; 1086 while( $ea > 2*M_PI ) $ea = $ea - 2*M_PI; 1087 1088 $sa = 2*M_PI - $sa; 1089 $ea = 2*M_PI - $ea; 1090 1091 // Special case when we have only one slice since then both start and end 1092 // angle will be == 0 1093 if( abs($sa - $ea) < 0.0001 ) { 1094 $sa=2*M_PI; $ea=0; 1095 } 1096 1097 // Add inner circle first point 1098 $xp = floor(($this->imidsize*$radius*cos($ea))+$xc); 1099 $yp = floor($yc-($this->imidsize*$radius*sin($ea))); 1100 $coords = "$xp, $yp"; 1101 1102 //add coordinates every 0.25 radians 1103 $a=$ea+0.25; 1104 1105 // If we cross the 360-limit with a slice we need to handle 1106 // the fact that end angle is smaller than start 1107 if( $sa < $ea ) { 1108 while ($a <= 2*M_PI) { 1109 $xp = floor($radius*cos($a)+$xc); 1110 $yp = floor($yc-$radius*sin($a)); 1111 $coords.= ", $xp, $yp"; 1112 $a += 0.25; 1113 } 1114 $a -= 2*M_PI; 1115 } 1116 1117 while ($a < $sa) { 1118 $xp = floor(($this->imidsize*$radius*cos($a)+$xc)); 1119 $yp = floor($yc-($this->imidsize*$radius*sin($a))); 1120 $coords.= ", $xp, $yp"; 1121 $a += 0.25; 1122 } 1123 1124 // Make sure we end at the last point 1125 $xp = floor(($this->imidsize*$radius*cos($sa)+$xc)); 1126 $yp = floor($yc-($this->imidsize*$radius*sin($sa))); 1127 $coords.= ", $xp, $yp"; 1128 1129 // Straight line to outer circle 1130 $xp = floor($radius*cos($sa)+$xc); 1131 $yp = floor($yc-$radius*sin($sa)); 1132 $coords.= ", $xp, $yp"; 1133 1134 //add coordinates every 0.25 radians 1135 $a=$sa - 0.25; 1136 while ($a > $ea) { 1137 $xp = floor($radius*cos($a)+$xc); 1138 $yp = floor($yc-$radius*sin($a)); 1139 $coords.= ", $xp, $yp"; 1140 $a -= 0.25; 1141 } 1142 1143 //Add the last point on the arc 1144 $xp = floor($radius*cos($ea)+$xc); 1145 $yp = floor($yc-$radius*sin($ea)); 1146 $coords.= ", $xp, $yp"; 1147 1148 // Close the arc 1149 $xp = floor(($this->imidsize*$radius*cos($ea))+$xc); 1150 $yp = floor($yc-($this->imidsize*$radius*sin($ea))); 1151 $coords .= ", $xp, $yp"; 1152 1153 if( !empty($this->csimtargets[$i]) ) { 1154 $this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"". 1155 $this->csimtargets[$i]."\""; 1156 if( !empty($this->csimwintargets[$i]) ) { 1157 $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; 1158 } 1159 if( !empty($this->csimalts[$i]) ) { 1160 $tmp=sprintf($this->csimalts[$i],$this->data[$i]); 1161 $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" "; 1162 } 1163 $this->csimareas .= " />\n"; 1164 } 1143 1165 } 1144 1166 … … 1146 1168 function Stroke($img,$aaoption=0) { 1147 1169 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1170 // Stroke the pie but don't stroke values 1171 $tmp = $this->value->show; 1172 $this->value->show = false; 1173 parent::Stroke($img,$aaoption); 1174 $this->value->show = $tmp; 1175 1176 $xc = round($this->posx*$img->width); 1177 $yc = round($this->posy*$img->height); 1178 1179 $radius = floor($this->radius * min($img->width,$img->height)) ; 1180 1181 1182 if( $this->imidsize > 0 && $aaoption !== 2 ) { 1183 1184 if( $this->ishadowcolor != "" ) { 1185 $img->SetColor($this->ishadowcolor); 1186 $img->FilledCircle($xc+$this->ishadowdrop,$yc+$this->ishadowdrop, 1187 round($radius*$this->imidsize)); 1188 } 1189 1190 $img->SetColor($this->imidcolor); 1191 $img->FilledCircle($xc,$yc,round($radius*$this->imidsize)); 1192 1193 if( $this->pie_border && $aaoption === 0 ) { 1194 $img->SetColor($this->color); 1195 $img->Circle($xc,$yc,round($radius*$this->imidsize)); 1196 } 1197 1198 if( !empty($this->middlecsimtarget) ) 1199 $this->AddMiddleCSIM($xc,$yc,round($radius*$this->imidsize)); 1200 1201 } 1202 1203 if( $this->value->show && $aaoption !== 1) { 1204 $this->StrokeAllLabels($img,$xc,$yc,$radius); 1205 $this->midtitle->SetPos($xc,$yc,'center','center'); 1206 $this->midtitle->Stroke($img); 1207 } 1186 1208 1187 1209 } 1188 1210 1189 1211 function AddMiddleCSIM($xc,$yc,$r) { 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1212 $xc=round($xc);$yc=round($yc);$r=round($r); 1213 $this->csimareas .= "<area shape=\"circle\" coords=\"$xc,$yc,$r\" href=\"". 1214 $this->middlecsimtarget."\""; 1215 if( !empty($this->middlecsimwintarget) ) { 1216 $this->csimareas .= " target=\"".$this->middlecsimwintarget."\""; 1217 } 1218 if( !empty($this->middlecsimalt) ) { 1219 $tmp = $this->middlecsimalt; 1220 $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" "; 1221 } 1222 $this->csimareas .= " />\n"; 1201 1223 } 1202 1224 1203 1225 function StrokeLabel($label,$img,$xc,$yc,$a,$r) { 1204 1226 1205 1206 1207 1208 1227 if( $this->ilabelposadj === 'auto' ) 1228 $this->ilabelposadj = (1-$this->imidsize)/2+$this->imidsize; 1229 1230 parent::StrokeLabel($label,$img,$xc,$yc,$a,$r); 1209 1231 1210 1232 } … … 1215 1237 //=================================================== 1216 1238 // CLASS PieGraph 1217 // Description: 1239 // Description: 1218 1240 //=================================================== 1219 1241 class PieGraph extends Graph { 1220 private $posx, $posy, $radius; 1221 private $legends=array(); 1242 private $posx, $posy, $radius; 1243 private $legends=array(); 1222 1244 public $plots=array(); 1223 1245 public $pieaa = false ; 1224 //--------------- 1225 // CONSTRUCTOR 1226 function PieGraph($width=300,$height=200,$cachedName="",$timeout=0,$inline=1) { 1227 $this->Graph($width,$height,$cachedName,$timeout,$inline); 1228 $this->posx=$width/2; 1229 $this->posy=$height/2; 1230 $this->SetColor(array(255,255,255)); 1231 } 1232 1233 //--------------- 1234 // PUBLIC METHODS 1246 //--------------- 1247 // CONSTRUCTOR 1248 function __construct($width=300,$height=200,$cachedName="",$timeout=0,$inline=1) { 1249 parent::__construct($width,$height,$cachedName,$timeout,$inline); 1250 $this->posx=$width/2; 1251 $this->posy=$height/2; 1252 $this->SetColor(array(255,255,255)); 1253 1254 if ($this->graph_theme) { 1255 $this->graph_theme->ApplyGraph($this); 1256 } 1257 } 1258 1259 //--------------- 1260 // PUBLIC METHODS 1235 1261 function Add($aObj) { 1236 1262 1237 if( is_array($aObj) && count($aObj) > 0 ) 1238 $cl = $aObj[0]; 1239 else 1240 $cl = $aObj; 1241 1242 if( $cl instanceof Text ) 1243 $this->AddText($aObj); 1244 elseif( class_exists('IconPlot',false) && ($cl instanceof IconPlot) ) 1245 $this->AddIcon($aObj); 1246 else { 1247 if( is_array($aObj) ) { 1248 $n = count($aObj); 1249 for($i=0; $i < $n; ++$i ) { 1250 $this->plots[] = $aObj[$i]; 1251 } 1252 } 1253 else { 1254 $this->plots[] = $aObj; 1255 } 1256 } 1263 if( is_array($aObj) && count($aObj) > 0 ) 1264 $cl = $aObj[0]; 1265 else 1266 $cl = $aObj; 1267 1268 if( $cl instanceof Text ) 1269 $this->AddText($aObj); 1270 elseif( class_exists('IconPlot',false) && ($cl instanceof IconPlot) ) 1271 $this->AddIcon($aObj); 1272 else { 1273 if( is_array($aObj) ) { 1274 $n = count($aObj); 1275 for($i=0; $i < $n; ++$i ) { 1276 //if ($aObj[$i]->theme) { 1277 // $this->ClearTheme(); 1278 //} 1279 $this->plots[] = $aObj[$i]; 1280 } 1281 } 1282 else { 1283 //if ($aObj->theme) { 1284 // $this->ClearTheme(); 1285 //} 1286 $this->plots[] = $aObj; 1287 } 1288 } 1289 1290 if ($this->graph_theme) { 1291 $this->graph_theme->SetupPlot($aObj); 1292 if ($aObj->is_using_plot_theme) { 1293 $aObj->UsePlotThemeColors(); 1294 } 1295 } 1257 1296 } 1258 1297 1259 1298 function SetAntiAliasing($aFlg=true) { 1260 1261 } 1262 1299 $this->pieaa = $aFlg; 1300 } 1301 1263 1302 function SetColor($c) { 1264 1303 $this->SetMarginColor($c); 1265 1304 } 1266 1305 1267 1306 1268 1307 function DisplayCSIMAreas() { 1269 $csim=""; 1270 foreach($this->plots as $p ) { 1271 $csim .= $p->GetCSIMareas(); 1272 } 1273 //$csim.= $this->legend->GetCSIMareas(); 1274 if (preg_match_all("/area shape=\"(\w+)\" coords=\"([0-9\, ]+)\"/", $csim, $coords)) { 1275 $this->img->SetColor($this->csimcolor); 1276 $n = count($coords[0]); 1277 for ($i=0; $i < $n; $i++) { 1278 if ($coords[1][$i]=="poly") { 1279 preg_match_all('/\s*([0-9]+)\s*,\s*([0-9]+)\s*,*/',$coords[2][$i],$pts); 1280 $this->img->SetStartPoint($pts[1][count($pts[0])-1],$pts[2][count($pts[0])-1]); 1281 $m = count($pts[0]); 1282 for ($j=0; $j < $m; $j++) { 1283 $this->img->LineTo($pts[1][$j],$pts[2][$j]); 1284 } 1285 } else if ($coords[1][$i]=="rect") { 1286 $pts = preg_split('/,/', $coords[2][$i]); 1287 $this->img->SetStartPoint($pts[0],$pts[1]); 1288 $this->img->LineTo($pts[2],$pts[1]); 1289 $this->img->LineTo($pts[2],$pts[3]); 1290 $this->img->LineTo($pts[0],$pts[3]); 1291 $this->img->LineTo($pts[0],$pts[1]); 1292 1293 } 1294 } 1295 } 1308 $csim=""; 1309 foreach($this->plots as $p ) { 1310 $csim .= $p->GetCSIMareas(); 1311 } 1312 1313 $csim.= $this->legend->GetCSIMareas(); 1314 if (preg_match_all("/area shape=\"(\w+)\" coords=\"([0-9\, ]+)\"/", $csim, $coords)) { 1315 $this->img->SetColor($this->csimcolor); 1316 $n = count($coords[0]); 1317 for ($i=0; $i < $n; $i++) { 1318 if ($coords[1][$i]=="poly") { 1319 preg_match_all('/\s*([0-9]+)\s*,\s*([0-9]+)\s*,*/',$coords[2][$i],$pts); 1320 $this->img->SetStartPoint($pts[1][count($pts[0])-1],$pts[2][count($pts[0])-1]); 1321 $m = count($pts[0]); 1322 for ($j=0; $j < $m; $j++) { 1323 $this->img->LineTo($pts[1][$j],$pts[2][$j]); 1324 } 1325 } else if ($coords[1][$i]=="rect") { 1326 $pts = preg_split('/,/', $coords[2][$i]); 1327 $this->img->SetStartPoint($pts[0],$pts[1]); 1328 $this->img->LineTo($pts[2],$pts[1]); 1329 $this->img->LineTo($pts[2],$pts[3]); 1330 $this->img->LineTo($pts[0],$pts[3]); 1331 $this->img->LineTo($pts[0],$pts[1]); 1332 1333 } 1334 } 1335 } 1296 1336 } 1297 1337 1298 1338 // Method description 1299 1339 function Stroke($aStrokeFileName="") { 1300 // If the filename is the predefined value = '_csim_special_' 1301 // we assume that the call to stroke only needs to do enough 1302 // to correctly generate the CSIM maps. 1303 // We use this variable to skip things we don't strictly need 1304 // to do to generate the image map to improve performance 1305 // a best we can. Therefor you will see a lot of tests !$_csim in the 1306 // code below. 1307 $_csim = ($aStrokeFileName===_CSIM_SPECIALFILE); 1308 1309 // We need to know if we have stroked the plot in the 1310 // GetCSIMareas. Otherwise the CSIM hasn't been generated 1311 // and in the case of GetCSIM called before stroke to generate 1312 // CSIM without storing an image to disk GetCSIM must call Stroke. 1313 $this->iHasStroked = true; 1314 1315 $n = count($this->plots); 1316 1317 if( $this->pieaa ) { 1318 1319 if( !$_csim ) { 1320 if( $this->background_image != "" ) { 1321 $this->StrokeFrameBackground(); 1322 } 1323 else { 1324 $this->StrokeFrame(); 1325 $this->StrokeBackgroundGrad(); 1326 } 1327 } 1328 1329 1330 $w = $this->img->width; 1331 $h = $this->img->height; 1332 $oldimg = $this->img->img; 1333 1334 $this->img->CreateImgCanvas(2*$w,2*$h); 1335 1336 $this->img->SetColor( $this->margin_color ); 1337 $this->img->FilledRectangle(0,0,2*$w-1,2*$h-1); 1338 1339 // Make all icons *2 i size since we will be scaling down the 1340 // imahe to do the anti aliasing 1341 $ni = count($this->iIcons); 1342 for($i=0; $i < $ni; ++$i) { 1343 $this->iIcons[$i]->iScale *= 2 ; 1344 if( $this->iIcons[$i]->iX > 1 ) 1345 $this->iIcons[$i]->iX *= 2 ; 1346 if( $this->iIcons[$i]->iY > 1 ) 1347 $this->iIcons[$i]->iY *= 2 ; 1348 } 1349 1350 $this->StrokeIcons(); 1351 1352 for($i=0; $i < $n; ++$i) { 1353 if( $this->plots[$i]->posx > 1 ) 1354 $this->plots[$i]->posx *= 2 ; 1355 if( $this->plots[$i]->posy > 1 ) 1356 $this->plots[$i]->posy *= 2 ; 1357 1358 $this->plots[$i]->Stroke($this->img,1); 1359 1360 if( $this->plots[$i]->posx > 1 ) 1361 $this->plots[$i]->posx /= 2 ; 1362 if( $this->plots[$i]->posy > 1 ) 1363 $this->plots[$i]->posy /= 2 ; 1364 } 1365 1366 $indent = $this->doframe ? ($this->frame_weight + ($this->doshadow ? $this->shadow_width : 0 )) : 0 ; 1367 $indent += $this->framebevel ? $this->framebeveldepth + 1 : 0 ; 1368 $this->img->CopyCanvasH($oldimg,$this->img->img,$indent,$indent,$indent,$indent, 1369 $w-2*$indent,$h-2*$indent,2*($w-$indent),2*($h-$indent)); 1370 1371 $this->img->img = $oldimg ; 1372 $this->img->width = $w ; 1373 $this->img->height = $h ; 1374 1375 for($i=0; $i < $n; ++$i) { 1376 $this->plots[$i]->Stroke($this->img,2); // Stroke labels 1377 $this->plots[$i]->Legend($this); 1378 } 1379 1380 } 1381 else { 1382 1383 if( !$_csim ) { 1384 if( $this->background_image != "" ) { 1385 $this->StrokeFrameBackground(); 1386 } 1387 else { 1388 $this->StrokeFrame(); 1389 } 1390 } 1391 1392 $this->StrokeIcons(); 1393 1394 for($i=0; $i < $n; ++$i) { 1395 $this->plots[$i]->Stroke($this->img); 1396 $this->plots[$i]->Legend($this); 1397 } 1398 } 1399 1400 $this->legend->Stroke($this->img); 1401 $this->footer->Stroke($this->img); 1402 $this->StrokeTitles(); 1403 1404 if( !$_csim ) { 1405 1406 // Stroke texts 1407 if( $this->texts != null ) { 1408 $n = count($this->texts); 1409 for($i=0; $i < $n; ++$i ) { 1410 $this->texts[$i]->Stroke($this->img); 1411 } 1412 } 1413 1414 if( _JPG_DEBUG ) { 1415 $this->DisplayCSIMAreas(); 1416 } 1417 1418 // Should we do any final image transformation 1419 if( $this->iImgTrans ) { 1420 if( !class_exists('ImgTrans',false) ) { 1421 require_once('jpgraph_imgtrans.php'); 1422 //JpGraphError::Raise('In order to use image transformation you must include the file jpgraph_imgtrans.php in your script.'); 1423 } 1424 1425 $tform = new ImgTrans($this->img->img); 1426 $this->img->img = $tform->Skew3D($this->iImgTransHorizon,$this->iImgTransSkewDist, 1427 $this->iImgTransDirection,$this->iImgTransHighQ, 1428 $this->iImgTransMinSize,$this->iImgTransFillColor, 1429 $this->iImgTransBorder); 1430 } 1431 1432 1433 // If the filename is given as the special "__handle" 1434 // then the image handler is returned and the image is NOT 1435 // streamed back 1436 if( $aStrokeFileName == _IMG_HANDLER ) { 1437 return $this->img->img; 1438 } 1439 else { 1440 // Finally stream the generated picture 1441 $this->cache->PutAndStream($this->img,$this->cache_name,$this->inline, 1442 $aStrokeFileName); 1443 } 1444 } 1340 1341 // If the filename is the predefined value = '_csim_special_' 1342 // we assume that the call to stroke only needs to do enough 1343 // to correctly generate the CSIM maps. 1344 // We use this variable to skip things we don't strictly need 1345 // to do to generate the image map to improve performance 1346 // a best we can. Therefor you will see a lot of tests !$_csim in the 1347 // code below. 1348 $_csim = ($aStrokeFileName===_CSIM_SPECIALFILE); 1349 1350 // If we are called the second time (perhaps the user has called GetHTMLImageMap() 1351 // himself then the legends have alsready been populated once in order to get the 1352 // CSIM coordinats. Since we do not want the legends to be populated a second time 1353 // we clear the legends 1354 $this->legend->Clear(); 1355 1356 // We need to know if we have stroked the plot in the 1357 // GetCSIMareas. Otherwise the CSIM hasn't been generated 1358 // and in the case of GetCSIM called before stroke to generate 1359 // CSIM without storing an image to disk GetCSIM must call Stroke. 1360 $this->iHasStroked = true; 1361 1362 $n = count($this->plots); 1363 1364 if( $this->pieaa ) { 1365 1366 if( !$_csim ) { 1367 if( $this->background_image != "" ) { 1368 $this->StrokeFrameBackground(); 1369 } 1370 else { 1371 $this->StrokeFrame(); 1372 $this->StrokeBackgroundGrad(); 1373 } 1374 } 1375 1376 1377 $w = $this->img->width; 1378 $h = $this->img->height; 1379 $oldimg = $this->img->img; 1380 1381 $this->img->CreateImgCanvas(2*$w,2*$h); 1382 1383 $this->img->SetColor( $this->margin_color ); 1384 $this->img->FilledRectangle(0,0,2*$w-1,2*$h-1); 1385 1386 // Make all icons *2 i size since we will be scaling down the 1387 // imahe to do the anti aliasing 1388 $ni = count($this->iIcons); 1389 for($i=0; $i < $ni; ++$i) { 1390 $this->iIcons[$i]->iScale *= 2 ; 1391 if( $this->iIcons[$i]->iX > 1 ) 1392 $this->iIcons[$i]->iX *= 2 ; 1393 if( $this->iIcons[$i]->iY > 1 ) 1394 $this->iIcons[$i]->iY *= 2 ; 1395 } 1396 1397 $this->StrokeIcons(); 1398 1399 for($i=0; $i < $n; ++$i) { 1400 if( $this->plots[$i]->posx > 1 ) 1401 $this->plots[$i]->posx *= 2 ; 1402 if( $this->plots[$i]->posy > 1 ) 1403 $this->plots[$i]->posy *= 2 ; 1404 1405 $this->plots[$i]->Stroke($this->img,1); 1406 1407 if( $this->plots[$i]->posx > 1 ) 1408 $this->plots[$i]->posx /= 2 ; 1409 if( $this->plots[$i]->posy > 1 ) 1410 $this->plots[$i]->posy /= 2 ; 1411 } 1412 1413 $indent = $this->doframe ? ($this->frame_weight + ($this->doshadow ? $this->shadow_width : 0 )) : 0 ; 1414 $indent += $this->framebevel ? $this->framebeveldepth + 1 : 0 ; 1415 $this->img->CopyCanvasH($oldimg,$this->img->img,$indent,$indent,$indent,$indent, 1416 $w-2*$indent,$h-2*$indent,2*($w-$indent),2*($h-$indent)); 1417 1418 $this->img->img = $oldimg ; 1419 $this->img->width = $w ; 1420 $this->img->height = $h ; 1421 1422 for($i=0; $i < $n; ++$i) { 1423 $this->plots[$i]->Stroke($this->img,2); // Stroke labels 1424 $this->plots[$i]->Legend($this); 1425 } 1426 1427 } 1428 else { 1429 1430 if( !$_csim ) { 1431 if( $this->background_image != "" ) { 1432 $this->StrokeFrameBackground(); 1433 } 1434 else { 1435 $this->StrokeFrame(); 1436 $this->StrokeBackgroundGrad(); 1437 } 1438 } 1439 1440 $this->StrokeIcons(); 1441 1442 for($i=0; $i < $n; ++$i) { 1443 $this->plots[$i]->Stroke($this->img); 1444 $this->plots[$i]->Legend($this); 1445 } 1446 } 1447 1448 $this->legend->Stroke($this->img); 1449 $this->footer->Stroke($this->img); 1450 $this->StrokeTitles(); 1451 1452 if( !$_csim ) { 1453 1454 // Stroke texts 1455 if( $this->texts != null ) { 1456 $n = count($this->texts); 1457 for($i=0; $i < $n; ++$i ) { 1458 $this->texts[$i]->Stroke($this->img); 1459 } 1460 } 1461 1462 if( _JPG_DEBUG ) { 1463 $this->DisplayCSIMAreas(); 1464 } 1465 1466 // Should we do any final image transformation 1467 if( $this->iImgTrans ) { 1468 if( !class_exists('ImgTrans',false) ) { 1469 require_once('jpgraph_imgtrans.php'); 1470 //JpGraphError::Raise('In order to use image transformation you must include the file jpgraph_imgtrans.php in your script.'); 1471 } 1472 1473 $tform = new ImgTrans($this->img->img); 1474 $this->img->img = $tform->Skew3D($this->iImgTransHorizon,$this->iImgTransSkewDist, 1475 $this->iImgTransDirection,$this->iImgTransHighQ, 1476 $this->iImgTransMinSize,$this->iImgTransFillColor, 1477 $this->iImgTransBorder); 1478 } 1479 1480 1481 // If the filename is given as the special "__handle" 1482 // then the image handler is returned and the image is NOT 1483 // streamed back 1484 if( $aStrokeFileName == _IMG_HANDLER ) { 1485 return $this->img->img; 1486 } 1487 else { 1488 // Finally stream the generated picture 1489 $this->cache->PutAndStream($this->img,$this->cache_name,$this->inline, 1490 $aStrokeFileName); 1491 } 1492 } 1445 1493 } 1446 1494 } // Class -
trunk/client/modules/Elezioni/grafici/jpgraph_pie3d.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_PIE3D.PHP4 // Description: 3D Pie plot extension for JpGraph5 // Created:2001-03-246 // Ver: $Id: jpgraph_pie3d.php 956 2007-11-17 13:19:20Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */3 // File: JPGRAPH_PIE3D.PHP 4 // Description: 3D Pie plot extension for JpGraph 5 // Created: 2001-03-24 6 // Ver: $Id: jpgraph_pie3d.php 1329 2009-06-20 19:23:30Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 //=================================================== 13 13 // CLASS PiePlot3D 14 // Description: Plots a 3D pie with a specified projection 14 // Description: Plots a 3D pie with a specified projection 15 15 // angle between 20 and 70 degrees. 16 16 //=================================================== 17 17 class PiePlot3D extends PiePlot { 18 18 private $labelhintcolor="red",$showlabelhint=true; 19 private $angle=50; 19 private $angle=50; 20 20 private $edgecolor="", $edgeweight=1; 21 21 private $iThickness=false; 22 23 //---------------24 // CONSTRUCTOR25 function PiePlot3d($data) {26 27 28 29 30 31 32 33 } 34 35 //---------------36 // PUBLIC METHODS 37 22 23 //--------------- 24 // CONSTRUCTOR 25 function __construct($data) { 26 $this->radius = 0.5; 27 $this->data = $data; 28 $this->title = new Text(""); 29 $this->title->SetFont(FF_FONT1,FS_BOLD); 30 $this->value = new DisplayValue(); 31 $this->value->Show(); 32 $this->value->SetFormat('%.0f%%'); 33 } 34 35 //--------------- 36 // PUBLIC METHODS 37 38 38 // Set label arrays 39 39 function SetLegends($aLegend) { 40 40 $this->legends = array_reverse(array_slice($aLegend,0,count($this->data))); 41 41 } 42 42 43 43 function SetSliceColors($aColors) { 44 44 $this->setslicecolors = $aColors; 45 45 } 46 46 47 47 function Legend($aGraph) { 48 49 48 parent::Legend($aGraph); 49 $aGraph->legend->txtcol = array_reverse($aGraph->legend->txtcol); 50 50 } 51 51 52 52 function SetCSIMTargets($aTargets,$aAlts='',$aWinTargets='') { 53 54 55 53 $this->csimtargets = $aTargets; 54 $this->csimwintargets = $aWinTargets; 55 $this->csimalts = $aAlts; 56 56 } 57 57 … … 59 59 // will be used to separate pie slices. 60 60 function SetEdge($aColor='black',$aWeight=1) { 61 $this->edgecolor = $aColor; 62 $this->edgeweight = $aWeight; 63 } 64 65 // Dummy function to make Pie3D behave in a similair way to 2D 66 function ShowBorder($exterior=true,$interior=true) { 67 JpGraphError::RaiseL(14001); 68 //('Pie3D::ShowBorder() . Deprecated function. Use Pie3D::SetEdge() to control the edges around slices.'); 61 $this->edgecolor = $aColor; 62 $this->edgeweight = $aWeight; 69 63 } 70 64 … … 72 66 // Must be between 20 and 70 degrees 73 67 function SetAngle($a) { 74 if( $a<5 || $a>90 ) 75 JpGraphError::RaiseL(14002); 76 //("PiePlot3D::SetAngle() 3D Pie projection angle must be between 5 and 85 degrees."); 77 else 78 $this->angle = $a; 68 if( $a<5 || $a>90 ) { 69 JpGraphError::RaiseL(14002); 70 //("PiePlot3D::SetAngle() 3D Pie projection angle must be between 5 and 85 degrees."); 71 } 72 else { 73 $this->angle = $a; 74 } 79 75 } 80 76 81 77 function Add3DSliceToCSIM($i,$xc,$yc,$height,$width,$thick,$sa,$ea) { //Slice number, ellipse centre (x,y), height, width, start angle, end angle 82 78 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; 129 130 131 if( !empty($this->csimalts[$i]) ) { 132 133 134 135 136 79 $sa *= M_PI/180; 80 $ea *= M_PI/180; 81 82 //add coordinates of the centre to the map 83 $coords = "$xc, $yc"; 84 85 //add coordinates of the first point on the arc to the map 86 $xp = floor($width*cos($sa)/2+$xc); 87 $yp = floor($yc-$height*sin($sa)/2); 88 $coords.= ", $xp, $yp"; 89 90 //If on the front half, add the thickness offset 91 if ($sa >= M_PI && $sa <= 2*M_PI*1.01) { 92 $yp = floor($yp+$thick); 93 $coords.= ", $xp, $yp"; 94 } 95 96 //add coordinates every 0.2 radians 97 $a=$sa+0.2; 98 while ($a<$ea) { 99 $xp = floor($width*cos($a)/2+$xc); 100 if ($a >= M_PI && $a <= 2*M_PI*1.01) { 101 $yp = floor($yc-($height*sin($a)/2)+$thick); 102 } else { 103 $yp = floor($yc-$height*sin($a)/2); 104 } 105 $coords.= ", $xp, $yp"; 106 $a += 0.2; 107 } 108 109 //Add the last point on the arc 110 $xp = floor($width*cos($ea)/2+$xc); 111 $yp = floor($yc-$height*sin($ea)/2); 112 113 114 if ($ea >= M_PI && $ea <= 2*M_PI*1.01) { 115 $coords.= ", $xp, ".floor($yp+$thick); 116 } 117 $coords.= ", $xp, $yp"; 118 $alt=''; 119 120 if( !empty($this->csimtargets[$i]) ) { 121 $this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->csimtargets[$i]."\""; 122 123 if( !empty($this->csimwintargets[$i]) ) { 124 $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; 125 } 126 127 if( !empty($this->csimalts[$i]) ) { 128 $tmp=sprintf($this->csimalts[$i],$this->data[$i]); 129 $this->csimareas .= "alt=\"$tmp\" title=\"$tmp\" "; 130 } 131 $this->csimareas .= " />\n"; 132 } 137 133 138 134 } 139 135 140 136 function SetLabels($aLabels,$aLblPosAdj="auto") { 141 142 143 } 144 145 137 $this->labels = $aLabels; 138 $this->ilabelposadj=$aLblPosAdj; 139 } 140 141 146 142 // Distance from the pie to the labels 147 143 function SetLabelMargin($m) { 148 149 } 150 144 $this->value->SetMargin($m); 145 } 146 151 147 // Show a thin line from the pie to the label for a specific slice 152 148 function ShowLabelHint($f=true) { 153 154 } 155 149 $this->showlabelhint=$f; 150 } 151 156 152 // Set color of hint line to label for each slice 157 153 function SetLabelHintColor($c) { 158 154 $this->labelhintcolor=$c; 159 155 } 160 156 161 157 function SetHeight($aHeight) { 162 $this->iThickness = $aHeight;163 } 164 165 166 // Normalize Angle between 0-360158 $this->iThickness = $aHeight; 159 } 160 161 162 // Normalize Angle between 0-360 167 163 function NormAngle($a) { 168 169 // 170 171 172 173 174 175 176 177 178 179 180 181 } 182 183 184 185 // Draw one 3D pie slice at position ($xc,$yc) with height $z164 // Normalize anle to 0 to 2M_PI 165 // 166 if( $a > 0 ) { 167 while($a > 360) $a -= 360; 168 } 169 else { 170 while($a < 0) $a += 360; 171 } 172 if( $a < 0 ) 173 $a = 360 + $a; 174 175 if( $a == 360 ) $a=0; 176 return $a; 177 } 178 179 180 181 // Draw one 3D pie slice at position ($xc,$yc) with height $z 186 182 function Pie3DSlice($img,$xc,$yc,$w,$h,$sa,$ea,$z,$fillcolor,$shadow=0.65) { 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 $rsa = $sa/180*M_PI;// to Rad202 $rea = $ea/180*M_PI;// to Rad203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 $tsa = sin($a); 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 183 184 // Due to the way the 3D Pie algorithm works we are 185 // guaranteed that any slice we get into this method 186 // belongs to either the left or right side of the 187 // pie ellipse. Hence, no slice will cross 90 or 270 188 // point. 189 if( ($sa < 90 && $ea > 90) || ( ($sa > 90 && $sa < 270) && $ea > 270) ) { 190 JpGraphError::RaiseL(14003);//('Internal assertion failed. Pie3D::Pie3DSlice'); 191 exit(1); 192 } 193 194 $p[] = array(); 195 196 // Setup pre-calculated values 197 $rsa = $sa/180*M_PI; // to Rad 198 $rea = $ea/180*M_PI; // to Rad 199 $sinsa = sin($rsa); 200 $cossa = cos($rsa); 201 $sinea = sin($rea); 202 $cosea = cos($rea); 203 204 // p[] is the points for the overall slice and 205 // pt[] is the points for the top pie 206 207 // Angular step when approximating the arc with a polygon train. 208 $step = 0.05; 209 210 if( $sa >= 270 ) { 211 if( $ea > 360 || ($ea > 0 && $ea <= 90) ) { 212 if( $ea > 0 && $ea <= 90 ) { 213 // Adjust angle to simplify conditions in loops 214 $rea += 2*M_PI; 215 } 216 217 $p = array($xc,$yc,$xc,$yc+$z, 218 $xc+$w*$cossa,$z+$yc-$h*$sinsa); 219 $pt = array($xc,$yc,$xc+$w*$cossa,$yc-$h*$sinsa); 220 221 for( $a=$rsa; $a < 2*M_PI; $a += $step ) { 222 $tca = cos($a); 223 $tsa = sin($a); 224 $p[] = $xc+$w*$tca; 225 $p[] = $z+$yc-$h*$tsa; 226 $pt[] = $xc+$w*$tca; 227 $pt[] = $yc-$h*$tsa; 228 } 229 230 $pt[] = $xc+$w; 231 $pt[] = $yc; 232 233 $p[] = $xc+$w; 234 $p[] = $z+$yc; 235 $p[] = $xc+$w; 236 $p[] = $yc; 237 $p[] = $xc; 238 $p[] = $yc; 239 240 for( $a=2*M_PI+$step; $a < $rea; $a += $step ) { 241 $pt[] = $xc + $w*cos($a); 242 $pt[] = $yc - $h*sin($a); 243 } 244 245 $pt[] = $xc+$w*$cosea; 246 $pt[] = $yc-$h*$sinea; 247 $pt[] = $xc; 248 $pt[] = $yc; 249 250 } 251 else { 252 $p = array($xc,$yc,$xc,$yc+$z, 253 $xc+$w*$cossa,$z+$yc-$h*$sinsa); 254 $pt = array($xc,$yc,$xc+$w*$cossa,$yc-$h*$sinsa); 255 256 $rea = $rea == 0.0 ? 2*M_PI : $rea; 257 for( $a=$rsa; $a < $rea; $a += $step ) { 258 $tca = cos($a); 259 $tsa = sin($a); 260 $p[] = $xc+$w*$tca; 261 $p[] = $z+$yc-$h*$tsa; 262 $pt[] = $xc+$w*$tca; 263 $pt[] = $yc-$h*$tsa; 264 } 265 266 $pt[] = $xc+$w*$cosea; 267 $pt[] = $yc-$h*$sinea; 268 $pt[] = $xc; 269 $pt[] = $yc; 270 271 $p[] = $xc+$w*$cosea; 272 $p[] = $z+$yc-$h*$sinea; 273 $p[] = $xc+$w*$cosea; 274 $p[] = $yc-$h*$sinea; 275 $p[] = $xc; 276 $p[] = $yc; 277 } 278 } 279 elseif( $sa >= 180 ) { 280 $p = array($xc,$yc,$xc,$yc+$z,$xc+$w*$cosea,$z+$yc-$h*$sinea); 281 $pt = array($xc,$yc,$xc+$w*$cosea,$yc-$h*$sinea); 282 283 for( $a=$rea; $a>$rsa; $a -= $step ) { 284 $tca = cos($a); 285 $tsa = sin($a); 286 $p[] = $xc+$w*$tca; 287 $p[] = $z+$yc-$h*$tsa; 288 $pt[] = $xc+$w*$tca; 289 $pt[] = $yc-$h*$tsa; 290 } 291 292 $pt[] = $xc+$w*$cossa; 293 $pt[] = $yc-$h*$sinsa; 294 $pt[] = $xc; 295 $pt[] = $yc; 296 297 $p[] = $xc+$w*$cossa; 298 $p[] = $z+$yc-$h*$sinsa; 299 $p[] = $xc+$w*$cossa; 300 $p[] = $yc-$h*$sinsa; 301 $p[] = $xc; 302 $p[] = $yc; 303 304 } 305 elseif( $sa >= 90 ) { 306 if( $ea > 180 ) { 307 $p = array($xc,$yc,$xc,$yc+$z,$xc+$w*$cosea,$z+$yc-$h*$sinea); 308 $pt = array($xc,$yc,$xc+$w*$cosea,$yc-$h*$sinea); 309 310 for( $a=$rea; $a > M_PI; $a -= $step ) { 311 $tca = cos($a); 312 $tsa = sin($a); 313 $p[] = $xc+$w*$tca; 314 $p[] = $z + $yc - $h*$tsa; 315 $pt[] = $xc+$w*$tca; 316 $pt[] = $yc-$h*$tsa; 317 } 318 319 $p[] = $xc-$w; 320 $p[] = $z+$yc; 321 $p[] = $xc-$w; 322 $p[] = $yc; 323 $p[] = $xc; 324 $p[] = $yc; 325 326 $pt[] = $xc-$w; 327 $pt[] = $z+$yc; 328 $pt[] = $xc-$w; 329 $pt[] = $yc; 330 331 for( $a=M_PI-$step; $a > $rsa; $a -= $step ) { 332 $pt[] = $xc + $w*cos($a); 333 $pt[] = $yc - $h*sin($a); 334 } 335 336 $pt[] = $xc+$w*$cossa; 337 $pt[] = $yc-$h*$sinsa; 338 $pt[] = $xc; 339 $pt[] = $yc; 340 341 } 342 else { // $sa >= 90 && $ea <= 180 343 $p = array($xc,$yc,$xc,$yc+$z, 344 $xc+$w*$cosea,$z+$yc-$h*$sinea, 345 $xc+$w*$cosea,$yc-$h*$sinea, 346 $xc,$yc); 347 348 $pt = array($xc,$yc,$xc+$w*$cosea,$yc-$h*$sinea); 349 350 for( $a=$rea; $a>$rsa; $a -= $step ) { 351 $pt[] = $xc + $w*cos($a); 352 $pt[] = $yc - $h*sin($a); 353 } 354 355 $pt[] = $xc+$w*$cossa; 356 $pt[] = $yc-$h*$sinsa; 357 $pt[] = $xc; 358 $pt[] = $yc; 359 360 } 361 } 362 else { // sa > 0 && ea < 90 363 364 $p = array($xc,$yc,$xc,$yc+$z, 365 $xc+$w*$cossa,$z+$yc-$h*$sinsa, 366 $xc+$w*$cossa,$yc-$h*$sinsa, 367 $xc,$yc); 368 369 $pt = array($xc,$yc,$xc+$w*$cossa,$yc-$h*$sinsa); 370 371 for( $a=$rsa; $a < $rea; $a += $step ) { 372 $pt[] = $xc + $w*cos($a); 373 $pt[] = $yc - $h*sin($a); 374 } 375 376 $pt[] = $xc+$w*$cosea; 377 $pt[] = $yc-$h*$sinea; 378 $pt[] = $xc; 379 $pt[] = $yc; 380 } 381 382 $img->PushColor($fillcolor.":".$shadow); 383 $img->FilledPolygon($p); 384 $img->PopColor(); 385 386 $img->PushColor($fillcolor); 387 $img->FilledPolygon($pt); 388 $img->PopColor(); 393 389 } 394 390 395 391 function SetStartAngle($aStart) { 396 397 398 399 400 } 401 402 // Draw a 3D Pie392 if( $aStart < 0 || $aStart > 360 ) { 393 JpGraphError::RaiseL(14004);//('Slice start angle must be between 0 and 360 degrees.'); 394 } 395 $this->startangle = $aStart; 396 } 397 398 // Draw a 3D Pie 403 399 function Pie3D($aaoption,$img,$data,$colors,$xc,$yc,$d,$angle,$z, 404 $shadow=0.65,$startangle=0,$edgecolor="",$edgeweight=1) { 405 406 //--------------------------------------------------------------------------- 407 // As usual the algorithm get more complicated than I originally 408 // envisioned. I believe that this is as simple as it is possible 409 // to do it with the features I want. It's a good exercise to start 410 // thinking on how to do this to convince your self that all this 411 // is really needed for the general case. 412 // 413 // The algorithm two draw 3D pies without "real 3D" is done in 414 // two steps. 415 // First imagine the pie cut in half through a thought line between 416 // 12'a clock and 6'a clock. It now easy to imagine that we can plot 417 // the individual slices for each half by starting with the topmost 418 // pie slice and continue down to 6'a clock. 419 // 420 // In the algortithm this is done in three principal steps 421 // Step 1. Do the knife cut to ensure by splitting slices that extends 422 // over the cut line. This is done by splitting the original slices into 423 // upto 3 subslices. 424 // Step 2. Find the top slice for each half 425 // Step 3. Draw the slices from top to bottom 426 // 427 // The thing that slightly complicates this scheme with all the 428 // angle comparisons below is that we can have an arbitrary start 429 // angle so we must take into account the different equivalence classes. 430 // For the same reason we must walk through the angle array in a 431 // modulo fashion. 432 // 433 // Limitations of algorithm: 434 // * A small exploded slice which crosses the 270 degree point 435 // will get slightly nagged close to the center due to the fact that 436 // we print the slices in Z-order and that the slice left part 437 // get printed first and might get slightly nagged by a larger 438 // slice on the right side just before the right part of the small 439 // slice. Not a major problem though. 440 //--------------------------------------------------------------------------- 441 442 443 // Determine the height of the ellippse which gives an 444 // indication of the inclination angle 445 $h = ($angle/90.0)*$d; 446 $sum = 0; 447 for($i=0; $i<count($data); ++$i ) { 448 $sum += $data[$i]; 449 } 450 451 // Special optimization 452 if( $sum==0 ) return; 453 454 if( $this->labeltype == 2 ) { 455 $this->adjusted_data = $this->AdjPercentage($data); 456 } 457 458 // Setup the start 459 $accsum = 0; 460 $a = $startangle; 461 $a = $this->NormAngle($a); 462 463 // 464 // Step 1 . Split all slices that crosses 90 or 270 465 // 466 $idx=0; 467 $adjexplode=array(); 468 $numcolors = count($colors); 469 for($i=0; $i<count($data); ++$i, ++$idx ) { 470 $da = $data[$i]/$sum * 360; 471 472 if( empty($this->explode_radius[$i]) ) 473 $this->explode_radius[$i]=0; 474 475 $expscale=1; 476 if( $aaoption == 1 ) 477 $expscale=2; 478 479 $la = $a + $da/2; 480 $explode = array( $xc + $this->explode_radius[$i]*cos($la*M_PI/180)*$expscale, 481 $yc - $this->explode_radius[$i]*sin($la*M_PI/180) * ($h/$d) *$expscale ); 482 $adjexplode[$idx] = $explode; 483 $labeldata[$i] = array($la,$explode[0],$explode[1]); 484 $originalangles[$i] = array($a,$a+$da); 485 486 $ne = $this->NormAngle($a+$da); 487 if( $da <= 180 ) { 488 // If the slice size is <= 90 it can at maximum cut across 489 // one boundary (either 90 or 270) where it needs to be split 490 $split=-1; // no split 491 if( ($da<=90 && ($a <= 90 && $ne > 90)) || 492 (($da <= 180 && $da >90) && (($a < 90 || $a >= 270) && $ne > 90)) ) { 493 $split = 90; 494 } 495 elseif( ($da<=90 && ($a <= 270 && $ne > 270)) || 496 (($da<=180 && $da>90) && ($a >= 90 && $a < 270 && ($a+$da) > 270 )) ) { 497 $split = 270; 498 } 499 if( $split > 0 ) { // split in two 500 $angles[$idx] = array($a,$split); 501 $adjcolors[$idx] = $colors[$i % $numcolors]; 502 $adjexplode[$idx] = $explode; 503 $angles[++$idx] = array($split,$ne); 504 $adjcolors[$idx] = $colors[$i % $numcolors]; 505 $adjexplode[$idx] = $explode; 506 } 507 else { // no split 508 $angles[$idx] = array($a,$ne); 509 $adjcolors[$idx] = $colors[$i % $numcolors]; 510 $adjexplode[$idx] = $explode; 511 } 512 } 513 else { 514 // da>180 515 // Slice may, depending on position, cross one or two 516 // bonudaries 517 518 if( $a < 90 ) 519 $split = 90; 520 elseif( $a <= 270 ) 521 $split = 270; 522 else 523 $split = 90; 524 525 $angles[$idx] = array($a,$split); 526 $adjcolors[$idx] = $colors[$i % $numcolors]; 527 $adjexplode[$idx] = $explode; 528 //if( $a+$da > 360-$split ) { 529 // For slices larger than 270 degrees we might cross 530 // another boundary as well. This means that we must 531 // split the slice further. The comparison gets a little 532 // bit complicated since we must take into accound that 533 // a pie might have a startangle >0 and hence a slice might 534 // wrap around the 0 angle. 535 // Three cases: 536 // a) Slice starts before 90 and hence gets a split=90, but 537 // we must also check if we need to split at 270 538 // b) Slice starts after 90 but before 270 and slices 539 // crosses 90 (after a wrap around of 0) 540 // c) If start is > 270 (hence the firstr split is at 90) 541 // and the slice is so large that it goes all the way 542 // around 270. 543 if( ($a < 90 && ($a+$da > 270)) || 544 ($a > 90 && $a<=270 && ($a+$da>360+90) ) || 545 ($a > 270 && $this->NormAngle($a+$da)>270) ) { 546 $angles[++$idx] = array($split,360-$split); 547 $adjcolors[$idx] = $colors[$i % $numcolors]; 548 $adjexplode[$idx] = $explode; 549 $angles[++$idx] = array(360-$split,$ne); 550 $adjcolors[$idx] = $colors[$i % $numcolors]; 551 $adjexplode[$idx] = $explode; 552 } 553 else { 554 // Just a simple split to the previous decided 555 // angle. 556 $angles[++$idx] = array($split,$ne); 557 $adjcolors[$idx] = $colors[$i % $numcolors]; 558 $adjexplode[$idx] = $explode; 559 } 560 } 561 $a += $da; 562 $a = $this->NormAngle($a); 563 } 564 565 // Total number of slices 566 $n = count($angles); 567 568 for($i=0; $i<$n; ++$i) { 569 list($dbgs,$dbge) = $angles[$i]; 570 } 571 572 // 573 // Step 2. Find start index (first pie that starts in upper left quadrant) 574 // 575 $minval = $angles[0][0]; 576 $min = 0; 577 for( $i=0; $i<$n; ++$i ) { 578 if( $angles[$i][0] < $minval ) { 579 $minval = $angles[$i][0]; 580 $min = $i; 581 } 582 } 583 $j = $min; 584 $cnt = 0; 585 while( $angles[$j][1] <= 90 ) { 586 $j++; 587 if( $j>=$n) { 588 $j=0; 589 } 590 if( $cnt > $n ) { 591 JpGraphError::RaiseL(14005); 592 //("Pie3D Internal error (#1). Trying to wrap twice when looking for start index"); 593 } 594 ++$cnt; 595 } 596 $start = $j; 597 598 // 599 // Step 3. Print slices in z-order 600 // 601 $cnt = 0; 602 603 // First stroke all the slices between 90 and 270 (left half circle) 604 // counterclockwise 605 606 while( $angles[$j][0] < 270 && $aaoption !== 2 ) { 607 608 list($x,$y) = $adjexplode[$j]; 609 610 $this->Pie3DSlice($img,$x,$y,$d,$h,$angles[$j][0],$angles[$j][1], 611 $z,$adjcolors[$j],$shadow); 612 613 $last = array($x,$y,$j); 614 615 $j++; 616 if( $j >= $n ) $j=0; 617 if( $cnt > $n ) { 618 JpGraphError::RaiseL(14006); 619 //("Pie3D Internal Error: Z-Sorting algorithm for 3D Pies is not working properly (2). Trying to wrap twice while stroking."); 620 } 621 ++$cnt; 622 } 623 624 $slice_left = $n-$cnt; 625 $j=$start-1; 626 if($j<0) $j=$n-1; 627 $cnt = 0; 628 629 // The stroke all slices from 90 to -90 (right half circle) 630 // clockwise 631 while( $cnt < $slice_left && $aaoption !== 2 ) { 632 633 list($x,$y) = $adjexplode[$j]; 634 635 $this->Pie3DSlice($img,$x,$y,$d,$h,$angles[$j][0],$angles[$j][1], 636 $z,$adjcolors[$j],$shadow); 637 $j--; 638 if( $cnt > $n ) { 639 JpGraphError::RaiseL(14006); 640 //("Pie3D Internal Error: Z-Sorting algorithm for 3D Pies is not working properly (2). Trying to wrap twice while stroking."); 641 } 642 if($j<0) $j=$n-1; 643 $cnt++; 644 } 645 646 // Now do a special thing. Stroke the last slice on the left 647 // halfcircle one more time. This is needed in the case where 648 // the slice close to 270 have been exploded. In that case the 649 // part of the slice close to the center of the pie might be 650 // slightly nagged. 651 if( $aaoption !== 2 ) 652 $this->Pie3DSlice($img,$last[0],$last[1],$d,$h,$angles[$last[2]][0], 653 $angles[$last[2]][1],$z,$adjcolors[$last[2]],$shadow); 654 655 656 if( $aaoption !== 1 ) { 657 // Now print possible labels and add csim 658 $this->value->ApplyFont($img); 659 $margin = $img->GetFontHeight()/2 + $this->value->margin ; 660 for($i=0; $i < count($data); ++$i ) { 661 $la = $labeldata[$i][0]; 662 $x = $labeldata[$i][1] + cos($la*M_PI/180)*($d+$margin)*$this->ilabelposadj; 663 $y = $labeldata[$i][2] - sin($la*M_PI/180)*($h+$margin)*$this->ilabelposadj; 664 if( $this->ilabelposadj >= 1.0 ) { 665 if( $la > 180 && $la < 360 ) $y += $z; 666 } 667 if( $this->labeltype == 0 ) { 668 if( $sum > 0 ) 669 $l = 100*$data[$i]/$sum; 670 else 671 $l = 0; 672 } 673 elseif( $this->labeltype == 1 ) { 674 $l = $data[$i]; 675 } 676 else { 677 $l = $this->adjusted_data[$i]; 678 } 679 if( isset($this->labels[$i]) && is_string($this->labels[$i]) ) 680 $l=sprintf($this->labels[$i],$l); 681 682 $this->StrokeLabels($l,$img,$labeldata[$i][0]*M_PI/180,$x,$y,$z); 683 684 $this->Add3DSliceToCSIM($i,$labeldata[$i][1],$labeldata[$i][2],$h*2,$d*2,$z, 685 $originalangles[$i][0],$originalangles[$i][1]); 686 } 687 } 688 689 // 690 // Finally add potential lines in pie 691 // 692 693 if( $edgecolor=="" || $aaoption !== 0 ) return; 694 695 $accsum = 0; 696 $a = $startangle; 697 $a = $this->NormAngle($a); 698 699 $a *= M_PI/180.0; 700 701 $idx=0; 702 $img->PushColor($edgecolor); 703 $img->SetLineWeight($edgeweight); 704 705 $fulledge = true; 706 for($i=0; $i < count($data) && $fulledge; ++$i ) { 707 if( empty($this->explode_radius[$i]) ) 708 $this->explode_radius[$i]=0; 709 if( $this->explode_radius[$i] > 0 ) { 710 $fulledge = false; 711 } 712 } 713 714 715 for($i=0; $i < count($data); ++$i, ++$idx ) { 716 717 $da = $data[$i]/$sum * 2*M_PI; 718 $this->StrokeFullSliceFrame($img,$xc,$yc,$a,$a+$da,$d,$h,$z,$edgecolor, 719 $this->explode_radius[$i],$fulledge); 720 $a += $da; 721 } 722 $img->PopColor(); 400 $shadow=0.65,$startangle=0,$edgecolor="",$edgeweight=1) { 401 402 //--------------------------------------------------------------------------- 403 // As usual the algorithm get more complicated than I originally 404 // envisioned. I believe that this is as simple as it is possible 405 // to do it with the features I want. It's a good exercise to start 406 // thinking on how to do this to convince your self that all this 407 // is really needed for the general case. 408 // 409 // The algorithm two draw 3D pies without "real 3D" is done in 410 // two steps. 411 // First imagine the pie cut in half through a thought line between 412 // 12'a clock and 6'a clock. It now easy to imagine that we can plot 413 // the individual slices for each half by starting with the topmost 414 // pie slice and continue down to 6'a clock. 415 // 416 // In the algortithm this is done in three principal steps 417 // Step 1. Do the knife cut to ensure by splitting slices that extends 418 // over the cut line. This is done by splitting the original slices into 419 // upto 3 subslices. 420 // Step 2. Find the top slice for each half 421 // Step 3. Draw the slices from top to bottom 422 // 423 // The thing that slightly complicates this scheme with all the 424 // angle comparisons below is that we can have an arbitrary start 425 // angle so we must take into account the different equivalence classes. 426 // For the same reason we must walk through the angle array in a 427 // modulo fashion. 428 // 429 // Limitations of algorithm: 430 // * A small exploded slice which crosses the 270 degree point 431 // will get slightly nagged close to the center due to the fact that 432 // we print the slices in Z-order and that the slice left part 433 // get printed first and might get slightly nagged by a larger 434 // slice on the right side just before the right part of the small 435 // slice. Not a major problem though. 436 //--------------------------------------------------------------------------- 437 438 439 // Determine the height of the ellippse which gives an 440 // indication of the inclination angle 441 $h = ($angle/90.0)*$d; 442 $sum = 0; 443 for($i=0; $i<count($data); ++$i ) { 444 $sum += $data[$i]; 445 } 446 447 // Special optimization 448 if( $sum==0 ) return; 449 450 if( $this->labeltype == 2 ) { 451 $this->adjusted_data = $this->AdjPercentage($data); 452 } 453 454 // Setup the start 455 $accsum = 0; 456 $a = $startangle; 457 $a = $this->NormAngle($a); 458 459 // 460 // Step 1 . Split all slices that crosses 90 or 270 461 // 462 $idx=0; 463 $adjexplode=array(); 464 $numcolors = count($colors); 465 for($i=0; $i<count($data); ++$i, ++$idx ) { 466 $da = $data[$i]/$sum * 360; 467 468 if( empty($this->explode_radius[$i]) ) { 469 $this->explode_radius[$i]=0; 470 } 471 472 $expscale=1; 473 if( $aaoption == 1 ) { 474 $expscale=2; 475 } 476 477 $la = $a + $da/2; 478 $explode = array( $xc + $this->explode_radius[$i]*cos($la*M_PI/180)*$expscale, 479 $yc - $this->explode_radius[$i]*sin($la*M_PI/180) * ($h/$d) *$expscale ); 480 $adjexplode[$idx] = $explode; 481 $labeldata[$i] = array($la,$explode[0],$explode[1]); 482 $originalangles[$i] = array($a,$a+$da); 483 484 $ne = $this->NormAngle($a+$da); 485 if( $da <= 180 ) { 486 // If the slice size is <= 90 it can at maximum cut across 487 // one boundary (either 90 or 270) where it needs to be split 488 $split=-1; // no split 489 if( ($da<=90 && ($a <= 90 && $ne > 90)) || 490 (($da <= 180 && $da >90) && (($a < 90 || $a >= 270) && $ne > 90)) ) { 491 $split = 90; 492 } 493 elseif( ($da<=90 && ($a <= 270 && $ne > 270)) || 494 (($da<=180 && $da>90) && ($a >= 90 && $a < 270 && ($a+$da) > 270 )) ) { 495 $split = 270; 496 } 497 if( $split > 0 ) { // split in two 498 $angles[$idx] = array($a,$split); 499 $adjcolors[$idx] = $colors[$i % $numcolors]; 500 $adjexplode[$idx] = $explode; 501 $angles[++$idx] = array($split,$ne); 502 $adjcolors[$idx] = $colors[$i % $numcolors]; 503 $adjexplode[$idx] = $explode; 504 } 505 else { // no split 506 $angles[$idx] = array($a,$ne); 507 $adjcolors[$idx] = $colors[$i % $numcolors]; 508 $adjexplode[$idx] = $explode; 509 } 510 } 511 else { 512 // da>180 513 // Slice may, depending on position, cross one or two 514 // bonudaries 515 516 if( $a < 90 ) $split = 90; 517 elseif( $a <= 270 ) $split = 270; 518 else $split = 90; 519 520 $angles[$idx] = array($a,$split); 521 $adjcolors[$idx] = $colors[$i % $numcolors]; 522 $adjexplode[$idx] = $explode; 523 //if( $a+$da > 360-$split ) { 524 // For slices larger than 270 degrees we might cross 525 // another boundary as well. This means that we must 526 // split the slice further. The comparison gets a little 527 // bit complicated since we must take into accound that 528 // a pie might have a startangle >0 and hence a slice might 529 // wrap around the 0 angle. 530 // Three cases: 531 // a) Slice starts before 90 and hence gets a split=90, but 532 // we must also check if we need to split at 270 533 // b) Slice starts after 90 but before 270 and slices 534 // crosses 90 (after a wrap around of 0) 535 // c) If start is > 270 (hence the firstr split is at 90) 536 // and the slice is so large that it goes all the way 537 // around 270. 538 if( ($a < 90 && ($a+$da > 270)) || ($a > 90 && $a<=270 && ($a+$da>360+90) ) || ($a > 270 && $this->NormAngle($a+$da)>270) ) { 539 $angles[++$idx] = array($split,360-$split); 540 $adjcolors[$idx] = $colors[$i % $numcolors]; 541 $adjexplode[$idx] = $explode; 542 $angles[++$idx] = array(360-$split,$ne); 543 $adjcolors[$idx] = $colors[$i % $numcolors]; 544 $adjexplode[$idx] = $explode; 545 } 546 else { 547 // Just a simple split to the previous decided 548 // angle. 549 $angles[++$idx] = array($split,$ne); 550 $adjcolors[$idx] = $colors[$i % $numcolors]; 551 $adjexplode[$idx] = $explode; 552 } 553 } 554 $a += $da; 555 $a = $this->NormAngle($a); 556 } 557 558 // Total number of slices 559 $n = count($angles); 560 561 for($i=0; $i<$n; ++$i) { 562 list($dbgs,$dbge) = $angles[$i]; 563 } 564 565 // 566 // Step 2. Find start index (first pie that starts in upper left quadrant) 567 // 568 $minval = $angles[0][0]; 569 $min = 0; 570 for( $i=0; $i<$n; ++$i ) { 571 if( $angles[$i][0] < $minval ) { 572 $minval = $angles[$i][0]; 573 $min = $i; 574 } 575 } 576 $j = $min; 577 $cnt = 0; 578 while( $angles[$j][1] <= 90 ) { 579 $j++; 580 if( $j>=$n) { 581 $j=0; 582 } 583 if( $cnt > $n ) { 584 JpGraphError::RaiseL(14005); 585 //("Pie3D Internal error (#1). Trying to wrap twice when looking for start index"); 586 } 587 ++$cnt; 588 } 589 $start = $j; 590 591 // 592 // Step 3. Print slices in z-order 593 // 594 $cnt = 0; 595 596 // First stroke all the slices between 90 and 270 (left half circle) 597 // counterclockwise 598 599 while( $angles[$j][0] < 270 && $aaoption !== 2 ) { 600 601 list($x,$y) = $adjexplode[$j]; 602 603 $this->Pie3DSlice($img,$x,$y,$d,$h,$angles[$j][0],$angles[$j][1], 604 $z,$adjcolors[$j],$shadow); 605 606 $last = array($x,$y,$j); 607 608 $j++; 609 if( $j >= $n ) $j=0; 610 if( $cnt > $n ) { 611 JpGraphError::RaiseL(14006); 612 //("Pie3D Internal Error: Z-Sorting algorithm for 3D Pies is not working properly (2). Trying to wrap twice while stroking."); 613 } 614 ++$cnt; 615 } 616 617 $slice_left = $n-$cnt; 618 $j=$start-1; 619 if($j<0) $j=$n-1; 620 $cnt = 0; 621 622 // The stroke all slices from 90 to -90 (right half circle) 623 // clockwise 624 while( $cnt < $slice_left && $aaoption !== 2 ) { 625 626 list($x,$y) = $adjexplode[$j]; 627 628 $this->Pie3DSlice($img,$x,$y,$d,$h,$angles[$j][0],$angles[$j][1], 629 $z,$adjcolors[$j],$shadow); 630 $j--; 631 if( $cnt > $n ) { 632 JpGraphError::RaiseL(14006); 633 //("Pie3D Internal Error: Z-Sorting algorithm for 3D Pies is not working properly (2). Trying to wrap twice while stroking."); 634 } 635 if($j<0) $j=$n-1; 636 $cnt++; 637 } 638 639 // Now do a special thing. Stroke the last slice on the left 640 // halfcircle one more time. This is needed in the case where 641 // the slice close to 270 have been exploded. In that case the 642 // part of the slice close to the center of the pie might be 643 // slightly nagged. 644 if( $aaoption !== 2 ) 645 $this->Pie3DSlice($img,$last[0],$last[1],$d,$h,$angles[$last[2]][0], 646 $angles[$last[2]][1],$z,$adjcolors[$last[2]],$shadow); 647 648 649 if( $aaoption !== 1 ) { 650 // Now print possible labels and add csim 651 $this->value->ApplyFont($img); 652 $margin = $img->GetFontHeight()/2 + $this->value->margin ; 653 for($i=0; $i < count($data); ++$i ) { 654 $la = $labeldata[$i][0]; 655 $x = $labeldata[$i][1] + cos($la*M_PI/180)*($d+$margin)*$this->ilabelposadj; 656 $y = $labeldata[$i][2] - sin($la*M_PI/180)*($h+$margin)*$this->ilabelposadj; 657 if( $this->ilabelposadj >= 1.0 ) { 658 if( $la > 180 && $la < 360 ) $y += $z; 659 } 660 if( $this->labeltype == 0 ) { 661 if( $sum > 0 ) $l = 100*$data[$i]/$sum; 662 else $l = 0; 663 } 664 elseif( $this->labeltype == 1 ) { 665 $l = $data[$i]; 666 } 667 else { 668 $l = $this->adjusted_data[$i]; 669 } 670 if( isset($this->labels[$i]) && is_string($this->labels[$i]) ) { 671 $l=sprintf($this->labels[$i],$l); 672 } 673 674 $this->StrokeLabels($l,$img,$labeldata[$i][0]*M_PI/180,$x,$y,$z); 675 676 $this->Add3DSliceToCSIM($i,$labeldata[$i][1],$labeldata[$i][2],$h*2,$d*2,$z, 677 $originalangles[$i][0],$originalangles[$i][1]); 678 } 679 } 680 681 // 682 // Finally add potential lines in pie 683 // 684 685 if( $edgecolor=="" || $aaoption !== 0 ) return; 686 687 $accsum = 0; 688 $a = $startangle; 689 $a = $this->NormAngle($a); 690 691 $a *= M_PI/180.0; 692 693 $idx=0; 694 $img->PushColor($edgecolor); 695 $img->SetLineWeight($edgeweight); 696 697 $fulledge = true; 698 for($i=0; $i < count($data) && $fulledge; ++$i ) { 699 if( empty($this->explode_radius[$i]) ) { 700 $this->explode_radius[$i]=0; 701 } 702 if( $this->explode_radius[$i] > 0 ) { 703 $fulledge = false; 704 } 705 } 706 707 708 for($i=0; $i < count($data); ++$i, ++$idx ) { 709 710 $da = $data[$i]/$sum * 2*M_PI; 711 $this->StrokeFullSliceFrame($img,$xc,$yc,$a,$a+$da,$d,$h,$z,$edgecolor, 712 $this->explode_radius[$i],$fulledge); 713 $a += $da; 714 } 715 $img->PopColor(); 723 716 } 724 717 725 718 function StrokeFullSliceFrame($img,$xc,$yc,$sa,$ea,$w,$h,$z,$edgecolor,$exploderadius,$fulledge) { 726 $step = 0.02; 727 728 if( $exploderadius > 0 ) { 729 $la = ($sa+$ea)/2; 730 $xc += $exploderadius*cos($la); 731 $yc -= $exploderadius*sin($la) * ($h/$w) ; 732 733 } 734 735 $p = array($xc,$yc,$xc+$w*cos($sa),$yc-$h*sin($sa)); 736 737 for($a=$sa; $a < $ea; $a += $step ) { 738 $p[] = $xc + $w*cos($a); 739 $p[] = $yc - $h*sin($a); 740 } 741 742 $p[] = $xc+$w*cos($ea); 743 $p[] = $yc-$h*sin($ea); 744 $p[] = $xc; 745 $p[] = $yc; 746 747 $img->SetColor($edgecolor); 748 $img->Polygon($p); 749 750 // Unfortunately we can't really draw the full edge around the whole of 751 // of the slice if any of the slices are exploded. The reason is that 752 // this algorithm is to simply. There are cases where the edges will 753 // "overwrite" other slices when they have been exploded. 754 // Doing the full, proper 3D hidden lines stiff is actually quite 755 // tricky. So for exploded pies we only draw the top edge. Not perfect 756 // but the "real" solution is much more complicated. 757 if( $fulledge && !( $sa > 0 && $sa < M_PI && $ea < M_PI) ) { 758 759 if($sa < M_PI && $ea > M_PI) 760 $sa = M_PI; 761 762 if($sa < 2*M_PI && (($ea >= 2*M_PI) || ($ea > 0 && $ea < $sa ) ) ) 763 $ea = 2*M_PI; 764 765 if( $sa >= M_PI && $ea <= 2*M_PI ) { 766 $p = array($xc + $w*cos($sa),$yc - $h*sin($sa), 767 $xc + $w*cos($sa),$z + $yc - $h*sin($sa)); 768 769 for($a=$sa+$step; $a < $ea; $a += $step ) { 770 $p[] = $xc + $w*cos($a); 771 $p[] = $z + $yc - $h*sin($a); 772 } 773 $p[] = $xc + $w*cos($ea); 774 $p[] = $z + $yc - $h*sin($ea); 775 $p[] = $xc + $w*cos($ea); 776 $p[] = $yc - $h*sin($ea); 777 $img->SetColor($edgecolor); 778 $img->Polygon($p); 779 } 780 } 719 $step = 0.02; 720 721 if( $exploderadius > 0 ) { 722 $la = ($sa+$ea)/2; 723 $xc += $exploderadius*cos($la); 724 $yc -= $exploderadius*sin($la) * ($h/$w) ; 725 726 } 727 728 $p = array($xc,$yc,$xc+$w*cos($sa),$yc-$h*sin($sa)); 729 730 for($a=$sa; $a < $ea; $a += $step ) { 731 $p[] = $xc + $w*cos($a); 732 $p[] = $yc - $h*sin($a); 733 } 734 735 $p[] = $xc+$w*cos($ea); 736 $p[] = $yc-$h*sin($ea); 737 $p[] = $xc; 738 $p[] = $yc; 739 740 $img->SetColor($edgecolor); 741 $img->Polygon($p); 742 743 // Unfortunately we can't really draw the full edge around the whole of 744 // of the slice if any of the slices are exploded. The reason is that 745 // this algorithm is to simply. There are cases where the edges will 746 // "overwrite" other slices when they have been exploded. 747 // Doing the full, proper 3D hidden lines stiff is actually quite 748 // tricky. So for exploded pies we only draw the top edge. Not perfect 749 // but the "real" solution is much more complicated. 750 if( $fulledge && !( $sa > 0 && $sa < M_PI && $ea < M_PI) ) { 751 752 if($sa < M_PI && $ea > M_PI) { 753 $sa = M_PI; 754 } 755 756 if($sa < 2*M_PI && (($ea >= 2*M_PI) || ($ea > 0 && $ea < $sa ) ) ) { 757 $ea = 2*M_PI; 758 } 759 760 if( $sa >= M_PI && $ea <= 2*M_PI ) { 761 $p = array($xc + $w*cos($sa),$yc - $h*sin($sa), 762 $xc + $w*cos($sa),$z + $yc - $h*sin($sa)); 763 764 for($a=$sa+$step; $a < $ea; $a += $step ) { 765 $p[] = $xc + $w*cos($a); 766 $p[] = $z + $yc - $h*sin($a); 767 } 768 $p[] = $xc + $w*cos($ea); 769 $p[] = $z + $yc - $h*sin($ea); 770 $p[] = $xc + $w*cos($ea); 771 $p[] = $yc - $h*sin($ea); 772 $img->SetColor($edgecolor); 773 $img->Polygon($p); 774 } 775 } 781 776 } 782 777 783 778 function Stroke($img,$aaoption=0) { 784 $n = count($this->data); 785 786 // If user hasn't set the colors use the theme array 787 if( $this->setslicecolors==null ) { 788 $colors = array_keys($img->rgb->rgb_table); 789 sort($colors); 790 $idx_a=$this->themearr[$this->theme]; 791 $ca = array(); 792 $m = count($idx_a); 793 for($i=0; $i < $m; ++$i) 794 $ca[$i] = $colors[$idx_a[$i]]; 795 $ca = array_reverse(array_slice($ca,0,$n)); 796 } 797 else { 798 $ca = $this->setslicecolors; 799 } 800 801 802 if( $this->posx <= 1 && $this->posx > 0 ) 803 $xc = round($this->posx*$img->width); 804 else 805 $xc = $this->posx ; 806 807 if( $this->posy <= 1 && $this->posy > 0 ) 808 $yc = round($this->posy*$img->height); 809 else 810 $yc = $this->posy ; 811 812 if( $this->radius <= 1 ) { 813 $width = floor($this->radius*min($img->width,$img->height)); 814 // Make sure that the pie doesn't overflow the image border 815 // The 0.9 factor is simply an extra margin to leave some space 816 // between the pie an the border of the image. 817 $width = min($width,min($xc*0.9,($yc*90/$this->angle-$width/4)*0.9)); 818 } 819 else { 820 $width = $this->radius * ($aaoption === 1 ? 2 : 1 ) ; 821 } 822 823 // Add a sanity check for width 824 if( $width < 1 ) { 825 JpGraphError::RaiseL(14007);//("Width for 3D Pie is 0. Specify a size > 0"); 826 } 827 828 // Establish a thickness. By default the thickness is a fifth of the 829 // pie slice width (=pie radius) but since the perspective depends 830 // on the inclination angle we use some heuristics to make the edge 831 // slightly thicker the less the angle. 832 833 // Has user specified an absolute thickness? In that case use 834 // that instead 835 836 if( $this->iThickness ) { 837 $thick = $this->iThickness; 838 $thick *= ($aaoption === 1 ? 2 : 1 ); 839 } 840 else 841 $thick = $width/12; 842 $a = $this->angle; 843 if( $a <= 30 ) $thick *= 1.6; 844 elseif( $a <= 40 ) $thick *= 1.4; 845 elseif( $a <= 50 ) $thick *= 1.2; 846 elseif( $a <= 60 ) $thick *= 1.0; 847 elseif( $a <= 70 ) $thick *= 0.8; 848 elseif( $a <= 80 ) $thick *= 0.7; 849 else $thick *= 0.6; 850 851 $thick = floor($thick); 852 853 if( $this->explode_all ) 854 for($i=0; $i < $n; ++$i) 855 $this->explode_radius[$i]=$this->explode_r; 856 857 $this->Pie3D($aaoption,$img,$this->data, $ca, $xc, $yc, $width, $this->angle, 858 $thick, 0.65, $this->startangle, $this->edgecolor, $this->edgeweight); 859 860 // Adjust title position 861 if( $aaoption != 1 ) { 862 $this->title->SetPos($xc,$yc-$this->title->GetFontHeight($img)-$width/2-$this->title->margin, "center","bottom"); 863 $this->title->Stroke($img); 864 } 865 } 866 867 //--------------- 868 // PRIVATE METHODS 779 $n = count($this->data); 780 781 // If user hasn't set the colors use the theme array 782 if( $this->setslicecolors==null ) { 783 $colors = array_keys($img->rgb->rgb_table); 784 sort($colors); 785 $idx_a=$this->themearr[$this->theme]; 786 $ca = array(); 787 $m = count($idx_a); 788 for($i=0; $i < $m; ++$i) { 789 $ca[$i] = $colors[$idx_a[$i]]; 790 } 791 $ca = array_reverse(array_slice($ca,0,$n)); 792 } 793 else { 794 $ca = $this->setslicecolors; 795 } 796 797 798 if( $this->posx <= 1 && $this->posx > 0 ) { 799 $xc = round($this->posx*$img->width); 800 } 801 else { 802 $xc = $this->posx ; 803 } 804 805 if( $this->posy <= 1 && $this->posy > 0 ) { 806 $yc = round($this->posy*$img->height); 807 } 808 else { 809 $yc = $this->posy ; 810 } 811 812 if( $this->radius <= 1 ) { 813 $width = floor($this->radius*min($img->width,$img->height)); 814 // Make sure that the pie doesn't overflow the image border 815 // The 0.9 factor is simply an extra margin to leave some space 816 // between the pie an the border of the image. 817 $width = min($width,min($xc*0.9,($yc*90/$this->angle-$width/4)*0.9)); 818 } 819 else { 820 $width = $this->radius * ($aaoption === 1 ? 2 : 1 ) ; 821 } 822 823 // Add a sanity check for width 824 if( $width < 1 ) { 825 JpGraphError::RaiseL(14007);//("Width for 3D Pie is 0. Specify a size > 0"); 826 } 827 828 // Establish a thickness. By default the thickness is a fifth of the 829 // pie slice width (=pie radius) but since the perspective depends 830 // on the inclination angle we use some heuristics to make the edge 831 // slightly thicker the less the angle. 832 833 // Has user specified an absolute thickness? In that case use 834 // that instead 835 836 if( $this->iThickness ) { 837 $thick = $this->iThickness; 838 $thick *= ($aaoption === 1 ? 2 : 1 ); 839 } 840 else { 841 $thick = $width/12; 842 } 843 $a = $this->angle; 844 845 if( $a <= 30 ) $thick *= 1.6; 846 elseif( $a <= 40 ) $thick *= 1.4; 847 elseif( $a <= 50 ) $thick *= 1.2; 848 elseif( $a <= 60 ) $thick *= 1.0; 849 elseif( $a <= 70 ) $thick *= 0.8; 850 elseif( $a <= 80 ) $thick *= 0.7; 851 else $thick *= 0.6; 852 853 $thick = floor($thick); 854 855 if( $this->explode_all ) { 856 for($i=0; $i < $n; ++$i) 857 $this->explode_radius[$i]=$this->explode_r; 858 } 859 860 $this->Pie3D($aaoption,$img,$this->data, $ca, $xc, $yc, $width, $this->angle, 861 $thick, 0.65, $this->startangle, $this->edgecolor, $this->edgeweight); 862 863 // Adjust title position 864 if( $aaoption != 1 ) { 865 $this->title->SetPos($xc,$yc-$this->title->GetFontHeight($img)-$width/2-$this->title->margin, "center","bottom"); 866 $this->title->Stroke($img); 867 } 868 } 869 870 //--------------- 871 // PRIVATE METHODS 869 872 870 873 // Position the labels of each slice 871 874 function StrokeLabels($label,$img,$a,$xp,$yp,$z) { 872 $this->value->halign="left"; 873 $this->value->valign="top"; 874 875 // Position the axis title. 876 // dx, dy is the offset from the top left corner of the bounding box that sorrounds the text 877 // that intersects with the extension of the corresponding axis. The code looks a little 878 // bit messy but this is really the only way of having a reasonable position of the 879 // axis titles. 880 $this->value->ApplyFont($img); 881 $h=$img->GetTextHeight($label); 882 // For numeric values the format of the display value 883 // must be taken into account 884 if( is_numeric($label) ) { 885 if( $label >= 0 ) 886 $w=$img->GetTextWidth(sprintf($this->value->format,$label)); 887 else 888 $w=$img->GetTextWidth(sprintf($this->value->negformat,$label)); 889 } 890 else 891 $w=$img->GetTextWidth($label); 892 while( $a > 2*M_PI ) $a -= 2*M_PI; 893 if( $a>=7*M_PI/4 || $a <= M_PI/4 ) $dx=0; 894 if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dx=($a-M_PI/4)*2/M_PI; 895 if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dx=1; 896 if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dx=(1-($a-M_PI*5/4)*2/M_PI); 897 898 if( $a>=7*M_PI/4 ) $dy=(($a-M_PI)-3*M_PI/4)*2/M_PI; 899 if( $a<=M_PI/4 ) $dy=(1-$a*2/M_PI); 900 if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dy=1; 901 if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dy=(1-($a-3*M_PI/4)*2/M_PI); 902 if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dy=0; 903 904 $x = round($xp-$dx*$w); 905 $y = round($yp-$dy*$h); 906 907 908 // Mark anchor point for debugging 909 /* 910 $img->SetColor('red'); 911 $img->Line($xp-10,$yp,$xp+10,$yp); 912 $img->Line($xp,$yp-10,$xp,$yp+10); 913 */ 914 $oldmargin = $this->value->margin; 915 $this->value->margin=0; 916 $this->value->Stroke($img,$label,$x,$y); 917 $this->value->margin=$oldmargin; 918 919 } 875 $this->value->halign="left"; 876 $this->value->valign="top"; 877 878 // Position the axis title. 879 // dx, dy is the offset from the top left corner of the bounding box that sorrounds the text 880 // that intersects with the extension of the corresponding axis. The code looks a little 881 // bit messy but this is really the only way of having a reasonable position of the 882 // axis titles. 883 $this->value->ApplyFont($img); 884 $h=$img->GetTextHeight($label); 885 // For numeric values the format of the display value 886 // must be taken into account 887 if( is_numeric($label) ) { 888 if( $label >= 0 ) { 889 $w=$img->GetTextWidth(sprintf($this->value->format,$label)); 890 } 891 else { 892 $w=$img->GetTextWidth(sprintf($this->value->negformat,$label)); 893 } 894 } 895 else { 896 $w=$img->GetTextWidth($label); 897 } 898 899 while( $a > 2*M_PI ) { 900 $a -= 2*M_PI; 901 } 902 903 if( $a>=7*M_PI/4 || $a <= M_PI/4 ) $dx=0; 904 if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dx=($a-M_PI/4)*2/M_PI; 905 if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dx=1; 906 if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dx=(1-($a-M_PI*5/4)*2/M_PI); 907 908 if( $a>=7*M_PI/4 ) $dy=(($a-M_PI)-3*M_PI/4)*2/M_PI; 909 if( $a<=M_PI/4 ) $dy=(1-$a*2/M_PI); 910 if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dy=1; 911 if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dy=(1-($a-3*M_PI/4)*2/M_PI); 912 if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dy=0; 913 914 $x = round($xp-$dx*$w); 915 $y = round($yp-$dy*$h); 916 917 // Mark anchor point for debugging 918 /* 919 $img->SetColor('red'); 920 $img->Line($xp-10,$yp,$xp+10,$yp); 921 $img->Line($xp,$yp-10,$xp,$yp+10); 922 */ 923 924 $oldmargin = $this->value->margin; 925 $this->value->margin=0; 926 $this->value->Stroke($img,$label,$x,$y); 927 $this->value->margin=$oldmargin; 928 929 } 920 930 } // Class 921 931 -
trunk/client/modules/Elezioni/grafici/jpgraph_plotband.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph_plotband.php 1091 2009-01-18 22:57:40Z ljp $3 // File: JPGRAPH_PLOTBAND.PHP 4 // Description: PHP4 Graph Plotting library. Extension module. 5 // Created: 2004-02-18 6 // Ver: $Id: jpgraph_plotband.php 1106 2009-02-22 20:16:35Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 11 11 // Constants for types of static bands in plot area 12 define("BAND_RDIAG",1); 12 define("BAND_RDIAG",1); // Right diagonal lines 13 13 define("BAND_LDIAG",2); // Left diagonal lines 14 14 define("BAND_SOLID",3); // Solid one color … … 24 24 public $x,$y,$w,$h; 25 25 public $xe, $ye; 26 function Rectangle($aX,$aY,$aWidth,$aHeight) {27 28 29 30 31 32 26 function __construct($aX,$aY,$aWidth,$aHeight) { 27 $this->x=$aX; 28 $this->y=$aY; 29 $this->w=$aWidth; 30 $this->h=$aHeight; 31 $this->xe=$aX+$aWidth-1; 32 $this->ye=$aY+$aHeight-1; 33 33 } 34 34 } … … 46 46 protected $rect=null; 47 47 protected $doframe=true; 48 protected $linespacing; 48 protected $linespacing; // Line spacing in pixels 49 49 protected $iBackgroundColor=-1; // Default is no background fill 50 51 function RectPattern($aColor,$aWeight=1) {52 53 $this->weight = $aWeight; 50 51 function __construct($aColor,$aWeight=1) { 52 $this->color = $aColor; 53 $this->weight = $aWeight; 54 54 } 55 55 56 56 function SetBackground($aBackgroundColor) { 57 57 $this->iBackgroundColor=$aBackgroundColor; 58 58 } 59 59 60 60 function SetPos($aRect) { 61 62 } 63 61 $this->rect = $aRect; 62 } 63 64 64 function ShowFrame($aShow=true) { 65 65 $this->doframe=$aShow; 66 66 } 67 67 68 68 function SetDensity($aDens) { 69 70 71 //(" Desity for pattern must be between 1 and 100. (You tried $aDens)");72 73 74 69 if( $aDens < 1 || $aDens > 100 ) 70 JpGraphError::RaiseL(16001,$aDens); 71 //(" Desity for pattern must be between 1 and 100. (You tried $aDens)"); 72 // 1% corresponds to linespacing=50 73 // 100 % corresponds to linespacing 1 74 $this->linespacing = floor(((100-$aDens)/100.0)*50)+1; 75 75 76 76 } 77 77 78 78 function Stroke($aImg) { 79 80 81 //(" No positions specified for pattern.");82 83 84 85 $aImg->FilledRectangle($this->rect->x,$this->rect->y,$this->rect->xe,$this->rect->ye); 86 87 88 89 90 91 92 93 94 95 if( $this->doframe ) 96 79 if( $this->rect == null ) 80 JpGraphError::RaiseL(16002); 81 //(" No positions specified for pattern."); 82 83 if( !(is_numeric($this->iBackgroundColor) && $this->iBackgroundColor==-1) ) { 84 $aImg->SetColor($this->iBackgroundColor); 85 $aImg->FilledRectangle($this->rect->x,$this->rect->y,$this->rect->xe,$this->rect->ye); 86 } 87 88 $aImg->SetColor($this->color); 89 $aImg->SetLineWeight($this->weight); 90 91 // Virtual function implemented by subclass 92 $this->DoPattern($aImg); 93 94 // Frame around the pattern area 95 if( $this->doframe ) 96 $aImg->Rectangle($this->rect->x,$this->rect->y,$this->rect->xe,$this->rect->ye); 97 97 } 98 98 … … 106 106 class RectPatternSolid extends RectPattern { 107 107 108 function RectPatternSolid($aColor="black",$aWeight=1) {109 parent::RectPattern($aColor,$aWeight);110 } 111 112 function DoPattern($aImg) { 113 114 115 108 function __construct($aColor="black",$aWeight=1) { 109 parent::__construct($aColor,$aWeight); 110 } 111 112 function DoPattern($aImg) { 113 $aImg->SetColor($this->color); 114 $aImg->FilledRectangle($this->rect->x,$this->rect->y, 115 $this->rect->xe,$this->rect->ye); 116 116 } 117 117 } … … 122 122 //===================================================================== 123 123 class RectPatternHor extends RectPattern { 124 125 function RectPatternHor($aColor="black",$aWeight=1,$aLineSpacing=7) {126 parent::RectPattern($aColor,$aWeight);127 128 } 129 130 function DoPattern($aImg) { 131 $x0 = $this->rect->x; 132 133 134 135 136 137 124 125 function __construct($aColor="black",$aWeight=1,$aLineSpacing=7) { 126 parent::__construct($aColor,$aWeight); 127 $this->linespacing = $aLineSpacing; 128 } 129 130 function DoPattern($aImg) { 131 $x0 = $this->rect->x; 132 $x1 = $this->rect->xe; 133 $y = $this->rect->y; 134 while( $y < $this->rect->ye ) { 135 $aImg->Line($x0,$y,$x1,$y); 136 $y += $this->linespacing; 137 } 138 138 } 139 139 } … … 144 144 //===================================================================== 145 145 class RectPatternVert extends RectPattern { 146 147 function RectPatternVert($aColor="black",$aWeight=1,$aLineSpacing=7) {148 parent::RectPattern($aColor,$aWeight);149 146 147 function __construct($aColor="black",$aWeight=1,$aLineSpacing=7) { 148 parent::__construct($aColor,$aWeight); 149 $this->linespacing = $aLineSpacing; 150 150 } 151 151 … … 154 154 // 155 155 function DoPattern($aImg) { 156 $x = $this->rect->x; 157 158 159 160 161 162 156 $x = $this->rect->x; 157 $y0 = $this->rect->y; 158 $y1 = $this->rect->ye; 159 while( $x < $this->rect->xe ) { 160 $aImg->Line($x,$y0,$x,$y1); 161 $x += $this->linespacing; 162 } 163 163 } 164 164 } … … 170 170 //===================================================================== 171 171 class RectPatternRDiag extends RectPattern { 172 173 function RectPatternRDiag($aColor="black",$aWeight=1,$aLineSpacing=12) {174 parent::RectPattern($aColor,$aWeight);175 176 } 177 178 function DoPattern($aImg) { 179 180 181 182 183 184 185 186 $x0 = $this->rect->x + round($this->linespacing/2); 187 188 $x1 = $this->rect->x; 189 190 191 192 193 194 195 196 197 if( $xe-$x1 > $ye-$y0 ) { 198 199 200 $y1 = $ye; 201 $y0 = $this->rect->y; 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 $y0 += $this->linespacing; 231 232 233 } 234 } 235 172 173 function __construct($aColor="black",$aWeight=1,$aLineSpacing=12) { 174 parent::__construct($aColor,$aWeight); 175 $this->linespacing = $aLineSpacing; 176 } 177 178 function DoPattern($aImg) { 179 // -------------------- 180 // | / / / / /| 181 // |/ / / / / | 182 // | / / / / | 183 // -------------------- 184 $xe = $this->rect->xe; 185 $ye = $this->rect->ye; 186 $x0 = $this->rect->x + round($this->linespacing/2); 187 $y0 = $this->rect->y; 188 $x1 = $this->rect->x; 189 $y1 = $this->rect->y + round($this->linespacing/2); 190 191 while($x0<=$xe && $y1<=$ye) { 192 $aImg->Line($x0,$y0,$x1,$y1); 193 $x0 += $this->linespacing; 194 $y1 += $this->linespacing; 195 } 196 197 if( $xe-$x1 > $ye-$y0 ) { 198 // Width larger than height 199 $x1 = $this->rect->x + ($y1-$ye); 200 $y1 = $ye; 201 $y0 = $this->rect->y; 202 while( $x0 <= $xe ) { 203 $aImg->Line($x0,$y0,$x1,$y1); 204 $x0 += $this->linespacing; 205 $x1 += $this->linespacing; 206 } 207 208 $y0=$this->rect->y + ($x0-$xe); 209 $x0=$xe; 210 } 211 else { 212 // Height larger than width 213 $diff = $x0-$xe; 214 $y0 = $diff+$this->rect->y; 215 $x0 = $xe; 216 $x1 = $this->rect->x; 217 while( $y1 <= $ye ) { 218 $aImg->Line($x0,$y0,$x1,$y1); 219 $y1 += $this->linespacing; 220 $y0 += $this->linespacing; 221 } 222 223 $diff = $y1-$ye; 224 $y1 = $ye; 225 $x1 = $diff + $this->rect->x; 226 } 227 228 while( $y0 <= $ye ) { 229 $aImg->Line($x0,$y0,$x1,$y1); 230 $y0 += $this->linespacing; 231 $x1 += $this->linespacing; 232 } 233 } 234 } 235 236 236 //===================================================================== 237 237 // Class RectPatternLDiag … … 239 239 //===================================================================== 240 240 class RectPatternLDiag extends RectPattern { 241 242 function RectPatternLDiag($aColor="black",$aWeight=1,$aLineSpacing=12) {243 244 parent::RectPattern($aColor,$aWeight);245 } 246 247 function DoPattern($aImg) { 248 249 250 251 252 253 254 255 $x0 = $this->rect->x + round($this->linespacing/2); 256 257 $x1 = $this->rect->x; 258 259 260 261 262 263 264 265 if( $xe-$x1 > $ye-$this->rect->y ) { 266 267 268 $y0=$ye; $y1=$this->rect->y; 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 } 288 289 290 291 292 293 294 295 296 241 242 function __construct($aColor="black",$aWeight=1,$aLineSpacing=12) { 243 $this->linespacing = $aLineSpacing; 244 parent::__construct($aColor,$aWeight); 245 } 246 247 function DoPattern($aImg) { 248 // -------------------- 249 // |\ \ \ \ \ | 250 // | \ \ \ \ \| 251 // | \ \ \ \ | 252 // |------------------| 253 $xe = $this->rect->xe; 254 $ye = $this->rect->ye; 255 $x0 = $this->rect->x + round($this->linespacing/2); 256 $y0 = $this->rect->ye; 257 $x1 = $this->rect->x; 258 $y1 = $this->rect->ye - round($this->linespacing/2); 259 260 while($x0<=$xe && $y1>=$this->rect->y) { 261 $aImg->Line($x0,$y0,$x1,$y1); 262 $x0 += $this->linespacing; 263 $y1 -= $this->linespacing; 264 } 265 if( $xe-$x1 > $ye-$this->rect->y ) { 266 // Width larger than height 267 $x1 = $this->rect->x + ($this->rect->y-$y1); 268 $y0=$ye; $y1=$this->rect->y; 269 while( $x0 <= $xe ) { 270 $aImg->Line($x0,$y0,$x1,$y1); 271 $x0 += $this->linespacing; 272 $x1 += $this->linespacing; 273 } 274 275 $y0=$this->rect->ye - ($x0-$xe); 276 $x0=$xe; 277 } 278 else { 279 // Height larger than width 280 $diff = $x0-$xe; 281 $y0 = $ye-$diff; 282 $x0 = $xe; 283 while( $y1 >= $this->rect->y ) { 284 $aImg->Line($x0,$y0,$x1,$y1); 285 $y0 -= $this->linespacing; 286 $y1 -= $this->linespacing; 287 } 288 $diff = $this->rect->y - $y1; 289 $x1 = $this->rect->x + $diff; 290 $y1 = $this->rect->y; 291 } 292 while( $y0 >= $this->rect->y ) { 293 $aImg->Line($x0,$y0,$x1,$y1); 294 $y0 -= $this->linespacing; 295 $x1 += $this->linespacing; 296 } 297 297 } 298 298 } … … 308 308 // converge. 309 309 310 function RectPattern3DPlane($aColor="black",$aWeight=1) {311 parent::RectPattern($aColor,$aWeight);312 310 function __construct($aColor="black",$aWeight=1) { 311 parent::__construct($aColor,$aWeight); 312 $this->SetDensity(10); // Slightly larger default 313 313 } 314 314 315 315 function SetHorizon($aHorizon) { 316 317 } 318 319 function DoPattern($aImg) { 320 // "Fake" a nice 3D grid-effect. 321 322 323 324 325 326 327 328 329 330 // geometric to get the 3D perspective right. 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 $dist += $this->linespacing; 362 363 364 $x0_right = $middle + $dist * $factor; 365 366 } 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 $y -= $vls; 405 406 407 408 409 410 411 412 413 316 $this->alpha=$aHorizon; 317 } 318 319 function DoPattern($aImg) { 320 // "Fake" a nice 3D grid-effect. 321 $x0 = $this->rect->x + $this->rect->w/2; 322 $y0 = $this->rect->y; 323 $x1 = $x0; 324 $y1 = $this->rect->ye; 325 $x0_right = $x0; 326 $x1_right = $x1; 327 328 // BTW "apa" means monkey in Swedish but is really a shortform for 329 // "alpha+a" which was the labels I used on paper when I derived the 330 // geometric to get the 3D perspective right. 331 // $apa is the height of the bounding rectangle plus the distance to the 332 // artifical horizon (alpha) 333 $apa = $this->rect->h + $this->alpha; 334 335 // Three cases and three loops 336 // 1) The endpoint of the line ends on the bottom line 337 // 2) The endpoint ends on the side 338 // 3) Horizontal lines 339 340 // Endpoint falls on bottom line 341 $middle=$this->rect->x + $this->rect->w/2; 342 $dist=$this->linespacing; 343 $factor=$this->alpha /($apa); 344 while($x1>$this->rect->x) { 345 $aImg->Line($x0,$y0,$x1,$y1); 346 $aImg->Line($x0_right,$y0,$x1_right,$y1); 347 $x1 = $middle - $dist; 348 $x0 = $middle - $dist * $factor; 349 $x1_right = $middle + $dist; 350 $x0_right = $middle + $dist * $factor; 351 $dist += $this->linespacing; 352 } 353 354 // Endpoint falls on sides 355 $dist -= $this->linespacing; 356 $d=$this->rect->w/2; 357 $c = $apa - $d*$apa/$dist; 358 while( $x0>$this->rect->x ) { 359 $aImg->Line($x0,$y0,$this->rect->x,$this->rect->ye-$c); 360 $aImg->Line($x0_right,$y0,$this->rect->xe,$this->rect->ye-$c); 361 $dist += $this->linespacing; 362 $x0 = $middle - $dist * $factor; 363 $x1 = $middle - $dist; 364 $x0_right = $middle + $dist * $factor; 365 $c = $apa - $d*$apa/$dist; 366 } 367 368 // Horizontal lines 369 // They need some serious consideration since they are a function 370 // of perspective depth (alpha) and density (linespacing) 371 $x0=$this->rect->x; 372 $x1=$this->rect->xe; 373 $y=$this->rect->ye; 374 375 // The first line is drawn directly. Makes the loop below slightly 376 // more readable. 377 $aImg->Line($x0,$y,$x1,$y); 378 $hls = $this->linespacing; 379 380 // A correction factor for vertical "brick" line spacing to account for 381 // a) the difference in number of pixels hor vs vert 382 // b) visual apperance to make the first layer of "bricks" look more 383 // square. 384 $vls = $this->linespacing*0.6; 385 386 $ds = $hls*($apa-$vls)/$apa; 387 // Get the slope for the "perspective line" going from bottom right 388 // corner to top left corner of the "first" brick. 389 390 // Uncomment the following lines if you want to get a visual understanding 391 // of what this helpline does. BTW this mimics the way you would get the 392 // perspective right when drawing on paper. 393 /* 394 $x0 = $middle; 395 $y0 = $this->rect->ye; 396 $len=floor(($this->rect->ye-$this->rect->y)/$vls); 397 $x1 = $middle+round($len*$ds); 398 $y1 = $this->rect->ye-$len*$vls; 399 $aImg->PushColor("red"); 400 $aImg->Line($x0,$y0,$x1,$y1); 401 $aImg->PopColor(); 402 */ 403 404 $y -= $vls; 405 $k=($this->rect->ye-($this->rect->ye-$vls))/($middle-($middle-$ds)); 406 $dist = $hls; 407 while( $y>$this->rect->y ) { 408 $aImg->Line($this->rect->x,$y,$this->rect->xe,$y); 409 $adj = $k*$dist/(1+$dist*$k/$apa); 410 if( $adj < 2 ) $adj=1; 411 $y = $this->rect->ye - round($adj); 412 $dist += $hls; 413 } 414 414 } 415 415 } … … 422 422 private $vert=null; 423 423 private $hor=null; 424 function RectPatternCross($aColor="black",$aWeight=1) {425 parent::RectPattern($aColor,$aWeight);426 427 424 function __construct($aColor="black",$aWeight=1) { 425 parent::__construct($aColor,$aWeight); 426 $this->vert = new RectPatternVert($aColor,$aWeight); 427 $this->hor = new RectPatternHor($aColor,$aWeight); 428 428 } 429 429 430 430 function SetOrder($aDepth) { 431 432 431 $this->vert->SetOrder($aDepth); 432 $this->hor->SetOrder($aDepth); 433 433 } 434 434 435 435 function SetPos($aRect) { 436 437 438 436 parent::SetPos($aRect); 437 $this->vert->SetPos($aRect); 438 $this->hor->SetPos($aRect); 439 439 } 440 440 441 441 function SetDensity($aDens) { 442 443 444 } 445 446 function DoPattern($aImg) { 447 448 442 $this->vert->SetDensity($aDens); 443 $this->hor->SetDensity($aDens); 444 } 445 446 function DoPattern($aImg) { 447 $this->vert->DoPattern($aImg); 448 $this->hor->DoPattern($aImg); 449 449 } 450 450 } … … 458 458 private $left=null; 459 459 private $right=null; 460 function RectPatternDiagCross($aColor="black",$aWeight=1) {461 parent::RectPattern($aColor,$aWeight);462 463 460 function __construct($aColor="black",$aWeight=1) { 461 parent::__construct($aColor,$aWeight); 462 $this->right = new RectPatternRDiag($aColor,$aWeight); 463 $this->left = new RectPatternLDiag($aColor,$aWeight); 464 464 } 465 465 466 466 function SetOrder($aDepth) { 467 468 467 $this->left->SetOrder($aDepth); 468 $this->right->SetOrder($aDepth); 469 469 } 470 470 471 471 function SetPos($aRect) { 472 473 474 472 parent::SetPos($aRect); 473 $this->left->SetPos($aRect); 474 $this->right->SetPos($aRect); 475 475 } 476 476 477 477 function SetDensity($aDens) { 478 479 480 } 481 482 function DoPattern($aImg) { 483 484 478 $this->left->SetDensity($aDens); 479 $this->right->SetDensity($aDens); 480 } 481 482 function DoPattern($aImg) { 483 $this->left->DoPattern($aImg); 484 $this->right->DoPattern($aImg); 485 485 } 486 486 … … 489 489 //===================================================================== 490 490 // Class RectPatternFactory 491 // Factory class for rectangular pattern 491 // Factory class for rectangular pattern 492 492 //===================================================================== 493 493 class RectPatternFactory { 494 function RectPatternFactory() {495 494 function __construct() { 495 // Empty 496 496 } 497 497 function Create($aPattern,$aColor,$aWeight=1) { 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 //(" Unknown pattern specification ($aPattern)");526 527 498 switch($aPattern) { 499 case BAND_RDIAG: 500 $obj = new RectPatternRDiag($aColor,$aWeight); 501 break; 502 case BAND_LDIAG: 503 $obj = new RectPatternLDiag($aColor,$aWeight); 504 break; 505 case BAND_SOLID: 506 $obj = new RectPatternSolid($aColor,$aWeight); 507 break; 508 case BAND_VLINE: 509 $obj = new RectPatternVert($aColor,$aWeight); 510 break; 511 case BAND_HLINE: 512 $obj = new RectPatternHor($aColor,$aWeight); 513 break; 514 case BAND_3DPLANE: 515 $obj = new RectPattern3DPlane($aColor,$aWeight); 516 break; 517 case BAND_HVCROSS: 518 $obj = new RectPatternCross($aColor,$aWeight); 519 break; 520 case BAND_DIAGCROSS: 521 $obj = new RectPatternDiagCross($aColor,$aWeight); 522 break; 523 default: 524 JpGraphError::RaiseL(16003,$aPattern); 525 //(" Unknown pattern specification ($aPattern)"); 526 } 527 return $obj; 528 528 } 529 529 } … … 541 541 private $dir, $min, $max; 542 542 543 function PlotBand($aDir,$aPattern,$aMin,$aMax,$aColor="black",$aWeight=1,$aDepth=DEPTH_BACK) {544 545 546 if( is_numeric($aMin) && is_numeric($aMax) && ($aMin > $aMax) ) 547 548 //('Min value for plotband is larger than specified max value. Please correct.');549 550 551 552 553 } 554 543 function __construct($aDir,$aPattern,$aMin,$aMax,$aColor="black",$aWeight=1,$aDepth=DEPTH_BACK) { 544 $f = new RectPatternFactory(); 545 $this->prect = $f->Create($aPattern,$aColor,$aWeight); 546 if( is_numeric($aMin) && is_numeric($aMax) && ($aMin > $aMax) ) 547 JpGraphError::RaiseL(16004); 548 //('Min value for plotband is larger than specified max value. Please correct.'); 549 $this->dir = $aDir; 550 $this->min = $aMin; 551 $this->max = $aMax; 552 $this->depth=$aDepth; 553 } 554 555 555 // Set position. aRect contains absolute image coordinates 556 556 function SetPos($aRect) { 557 558 559 } 560 557 assert( $this->prect != null ) ; 558 $this->prect->SetPos($aRect); 559 } 560 561 561 function ShowFrame($aFlag=true) { 562 562 $this->prect->ShowFrame($aFlag); 563 563 } 564 564 565 565 // Set z-order. In front of pplot or in the back 566 566 function SetOrder($aDepth) { 567 568 } 569 567 $this->depth=$aDepth; 568 } 569 570 570 function SetDensity($aDens) { 571 572 } 573 571 $this->prect->SetDensity($aDens); 572 } 573 574 574 function GetDir() { 575 576 } 577 575 return $this->dir; 576 } 577 578 578 function GetMin() { 579 580 } 581 579 return $this->min; 580 } 581 582 582 function GetMax() { 583 583 return $this->max; 584 584 } 585 585 586 586 function PreStrokeAdjust($aGraph) { 587 588 } 589 587 // Nothing to do 588 } 589 590 590 // Display band 591 591 function Stroke($aImg,$aXScale,$aYScale) { 592 593 594 595 592 assert( $this->prect != null ) ; 593 if( $this->dir == HORIZONTAL ) { 594 if( $this->min === 'min' ) $this->min = $aYScale->GetMinVal(); 595 if( $this->max === 'max' ) $this->max = $aYScale->GetMaxVal(); 596 596 597 597 // Only draw the bar if it actually appears in the range 598 598 if ($this->min < $aYScale->GetMaxVal() && $this->max > $aYScale->GetMinVal()) { 599 600 601 602 603 604 605 606 607 608 609 599 600 // Trucate to limit of axis 601 $this->min = max($this->min, $aYScale->GetMinVal()); 602 $this->max = min($this->max, $aYScale->GetMaxVal()); 603 604 $x=$aXScale->scale_abs[0]; 605 $y=$aYScale->Translate($this->max); 606 $width=$aXScale->scale_abs[1]-$aXScale->scale_abs[0]+1; 607 $height=abs($y-$aYScale->Translate($this->min))+1; 608 $this->prect->SetPos(new Rectangle($x,$y,$width,$height)); 609 $this->prect->Stroke($aImg); 610 610 } 611 612 else {// VERTICAL613 614 615 611 } 612 else { // VERTICAL 613 if( $this->min === 'min' ) $this->min = $aXScale->GetMinVal(); 614 if( $this->max === 'max' ) $this->max = $aXScale->GetMaxVal(); 615 616 616 // Only draw the bar if it actually appears in the range 617 618 619 620 621 622 623 624 625 626 627 628 617 if ($this->min < $aXScale->GetMaxVal() && $this->max > $aXScale->GetMinVal()) { 618 619 // Trucate to limit of axis 620 $this->min = max($this->min, $aXScale->GetMinVal()); 621 $this->max = min($this->max, $aXScale->GetMaxVal()); 622 623 $y=$aYScale->scale_abs[1]; 624 $x=$aXScale->Translate($this->min); 625 $height=abs($aYScale->scale_abs[1]-$aYScale->scale_abs[0]); 626 $width=abs($x-$aXScale->Translate($this->max)); 627 $this->prect->SetPos(new Rectangle($x,$y,$width,$height)); 628 $this->prect->Stroke($aImg); 629 629 } 630 630 } 631 631 } 632 632 } -
trunk/client/modules/Elezioni/grafici/jpgraph_plotmark.inc.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph_plotmark.inc.php 956 2007-11-17 13:19:20Z ljp $3 // File: JPGRAPH_PLOTMARK.PHP 4 // Description: Class file. Handles plotmarks 5 // Created: 2003-03-21 6 // Ver: $Id: jpgraph_plotmark.inc.php 1106 2009-02-22 20:16:35Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 … … 31 31 private $imgdata_pushpins = null; 32 32 33 //--------------34 // CONSTRUCTOR35 function PlotMark() {36 37 38 39 40 } 41 //---------------42 // PUBLIC METHODS 33 //-------------- 34 // CONSTRUCTOR 35 function __construct() { 36 $this->title = new Text(); 37 $this->title->Hide(); 38 $this->csimareas = ''; 39 $this->type=-1; 40 } 41 //--------------- 42 // PUBLIC METHODS 43 43 function SetType($aType,$aFileName='',$aScale=1.0) { 44 45 46 47 48 49 50 } 51 44 $this->type = $aType; 45 if( $aType == MARK_IMG && $aFileName=='' ) { 46 JpGraphError::RaiseL(23003);//('A filename must be specified if you set the mark type to MARK_IMG.'); 47 } 48 $this->iFileName = $aFileName; 49 $this->iScale = $aScale; 50 } 51 52 52 function SetCallback($aFunc) { 53 53 $this->iFormatCallback = $aFunc; 54 54 } 55 55 56 56 function SetCallbackYX($aFunc) { 57 58 } 59 57 $this->iFormatCallback2 = $aFunc; 58 } 59 60 60 function GetType() { 61 62 } 63 61 return $this->type; 62 } 63 64 64 function SetColor($aColor) { 65 66 } 67 65 $this->color=$aColor; 66 } 67 68 68 function SetFillColor($aFillColor) { 69 69 $this->fill_color = $aFillColor; 70 70 } 71 71 72 72 function SetWeight($aWeight) { 73 73 $this->weight = $aWeight; 74 74 } 75 75 76 76 // Synonym for SetWidth() 77 77 function SetSize($aWidth) { 78 79 } 80 78 $this->width=$aWidth; 79 } 80 81 81 function SetWidth($aWidth) { 82 82 $this->width=$aWidth; 83 83 } 84 84 85 85 function SetDefaultWidth() { 86 87 case MARK_CIRCLE: 88 case MARK_FILLEDCIRCLE: 89 90 91 92 93 94 } 95 86 switch( $this->type ) { 87 case MARK_CIRCLE: 88 case MARK_FILLEDCIRCLE: 89 $this->width=4; 90 break; 91 default: 92 $this->width=7; 93 } 94 } 95 96 96 function GetWidth() { 97 98 } 99 97 return $this->width; 98 } 99 100 100 function Hide($aHide=true) { 101 102 } 103 101 $this->show = !$aHide; 102 } 103 104 104 function Show($aShow=true) { 105 105 $this->show = $aShow; 106 106 } 107 107 108 108 function SetCSIMAltVal($aY,$aX='') { 109 $this->yvalue=$aY; 110 $this->xvalue=$aX; 111 } 112 109 $this->yvalue=$aY; 110 $this->xvalue=$aX; 111 } 112 113 113 function SetCSIMTarget($aTarget,$aWinTarget='') { 114 114 $this->csimtarget=$aTarget; 115 115 $this->csimwintarget=$aWinTarget; 116 116 } 117 117 118 118 function SetCSIMAlt($aAlt) { 119 119 $this->csimalt=$aAlt; 120 120 } 121 121 122 122 function GetCSIMAreas(){ 123 123 return $this->csimareas; 124 124 } 125 125 126 126 function AddCSIMPoly($aPts) { 127 127 $coords = round($aPts[0]).", ".round($aPts[1]); … … 130 130 $coords .= ", ".round($aPts[2*$i]).", ".round($aPts[2*$i+1]); 131 131 } 132 $this->csimareas=""; 132 $this->csimareas=""; 133 133 if( !empty($this->csimtarget) ) { 134 135 136 137 138 139 140 if( !empty($this->csimalt) ) { 141 142 143 144 145 146 } 147 134 $this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".htmlentities($this->csimtarget)."\""; 135 136 if( !empty($this->csimwintarget) ) { 137 $this->csimareas .= " target=\"".$this->csimwintarget."\" "; 138 } 139 140 if( !empty($this->csimalt) ) { 141 $tmp=sprintf($this->csimalt,$this->yvalue,$this->xvalue); 142 $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\""; 143 } 144 $this->csimareas .= " />\n"; 145 } 146 } 147 148 148 function AddCSIMCircle($x,$y,$r) { 149 150 $this->csimareas=""; 149 $x = round($x); $y=round($y); $r=round($r); 150 $this->csimareas=""; 151 151 if( !empty($this->csimtarget) ) { 152 153 154 155 156 157 158 if( !empty($this->csimalt) ) {159 160 161 162 163 } 164 } 165 152 $this->csimareas .= "<area shape=\"circle\" coords=\"$x,$y,$r\" href=\"".htmlentities($this->csimtarget)."\""; 153 154 if( !empty($this->csimwintarget) ) { 155 $this->csimareas .= " target=\"".$this->csimwintarget."\" "; 156 } 157 158 if( !empty($this->csimalt) ) { 159 $tmp=sprintf($this->csimalt,$this->yvalue,$this->xvalue); 160 $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" "; 161 } 162 $this->csimareas .= " />\n"; 163 } 164 } 165 166 166 function Stroke($img,$x,$y) { 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 $anchor_y = 0.5; 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 case MARK_IMG_BALL: 271 case MARK_IMG_SBALL: 272 case MARK_IMG_MBALL: 273 case MARK_IMG_LBALL: 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 $this->title->Stroke($img,$x,$y+round($dh/2)); 317 318 319 320 321 322 323 $pts=0; 324 325 326 327 328 329 330 331 332 333 334 335 336 $c[]=$x-$dx;$c[]=$y+0.87*$dy;// tan(60)/2*$dx337 338 339 $c[]=$x-$dx;$c[]=$y+0.87*$dy;// tan(60)/2*$dx340 341 342 343 ++$dx;++$dy; 344 $c[]=$x;$c[]=$y+0.87*$dy;// tan(60)/2*$dx345 346 347 $c[]=$x;$c[]=$y+0.87*$dy;// tan(60)/2*$dx348 349 break; 350 351 352 353 354 355 356 357 break; 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 $img->SetColor($color); 380 381 382 383 384 385 386 387 388 389 $img->SetColor($fcolor); 390 391 $img->SetColor($color); 392 393 394 395 396 $img->SetColor($color); 397 398 399 400 401 $img->SetColor($fcolor); 402 403 $img->SetColor($color); 404 405 406 407 408 409 410 411 412 413 $this->AddCSIMCircle($x,$y,$dx); 414 415 416 417 418 419 $img->Line($x-$dx,$y+$dy,$x+$dx,$y-$dy); 420 $this->AddCSIMCircle($x,$y,$dx+$dy); 421 } 422 423 424 425 426 427 // Oversize by a pixel to match the X 428 429 430 $this->AddCSIMCircle($x,$y,$dx+$dy); 431 432 433 434 435 $this->title->Stroke($img,$x,$y); 167 if( !$this->show ) return; 168 169 if( $this->iFormatCallback != '' || $this->iFormatCallback2 != '' ) { 170 171 if( $this->iFormatCallback != '' ) { 172 $f = $this->iFormatCallback; 173 list($width,$color,$fcolor) = call_user_func($f,$this->yvalue); 174 $filename = $this->iFileName; 175 $imgscale = $this->iScale; 176 } 177 else { 178 $f = $this->iFormatCallback2; 179 list($width,$color,$fcolor,$filename,$imgscale) = call_user_func($f,$this->yvalue,$this->xvalue); 180 if( $filename=="" ) $filename = $this->iFileName; 181 if( $imgscale=="" ) $imgscale = $this->iScale; 182 } 183 184 if( $width=="" ) $width = $this->width; 185 if( $color=="" ) $color = $this->color; 186 if( $fcolor=="" ) $fcolor = $this->fill_color; 187 188 } 189 else { 190 $fcolor = $this->fill_color; 191 $color = $this->color; 192 $width = $this->width; 193 $filename = $this->iFileName; 194 $imgscale = $this->iScale; 195 } 196 197 if( $this->type == MARK_IMG || 198 ($this->type >= MARK_FLAG1 && $this->type <= MARK_FLAG4 ) || 199 $this->type >= MARK_IMG_PUSHPIN ) { 200 201 // Note: For the builtin images we use the "filename" parameter 202 // to denote the color 203 $anchor_x = 0.5; 204 $anchor_y = 0.5; 205 switch( $this->type ) { 206 case MARK_FLAG1: 207 case MARK_FLAG2: 208 case MARK_FLAG3: 209 case MARK_FLAG4: 210 $this->markimg = FlagCache::GetFlagImgByName($this->type-MARK_FLAG1+1,$filename); 211 break; 212 213 case MARK_IMG : 214 // Load an image and use that as a marker 215 // Small optimization, if we have already read an image don't 216 // waste time reading it again. 217 if( $this->markimg == '' || !($this->oldfilename === $filename) ) { 218 $this->markimg = Graph::LoadBkgImage('',$filename); 219 $this->oldfilename = $filename ; 220 } 221 break; 222 223 case MARK_IMG_PUSHPIN: 224 case MARK_IMG_SPUSHPIN: 225 case MARK_IMG_LPUSHPIN: 226 if( $this->imgdata_pushpins == null ) { 227 require_once 'imgdata_pushpins.inc.php'; 228 $this->imgdata_pushpins = new ImgData_PushPins(); 229 } 230 $this->markimg = $this->imgdata_pushpins->GetImg($this->type,$filename); 231 list($anchor_x,$anchor_y) = $this->imgdata_pushpins->GetAnchor(); 232 break; 233 234 case MARK_IMG_SQUARE: 235 if( $this->imgdata_squares == null ) { 236 require_once 'imgdata_squares.inc.php'; 237 $this->imgdata_squares = new ImgData_Squares(); 238 } 239 $this->markimg = $this->imgdata_squares->GetImg($this->type,$filename); 240 list($anchor_x,$anchor_y) = $this->imgdata_squares->GetAnchor(); 241 break; 242 243 case MARK_IMG_STAR: 244 if( $this->imgdata_stars == null ) { 245 require_once 'imgdata_stars.inc.php'; 246 $this->imgdata_stars = new ImgData_Stars(); 247 } 248 $this->markimg = $this->imgdata_stars->GetImg($this->type,$filename); 249 list($anchor_x,$anchor_y) = $this->imgdata_stars->GetAnchor(); 250 break; 251 252 case MARK_IMG_BEVEL: 253 if( $this->imgdata_bevels == null ) { 254 require_once 'imgdata_bevels.inc.php'; 255 $this->imgdata_bevels = new ImgData_Bevels(); 256 } 257 $this->markimg = $this->imgdata_bevels->GetImg($this->type,$filename); 258 list($anchor_x,$anchor_y) = $this->imgdata_bevels->GetAnchor(); 259 break; 260 261 case MARK_IMG_DIAMOND: 262 if( $this->imgdata_diamonds == null ) { 263 require_once 'imgdata_diamonds.inc.php'; 264 $this->imgdata_diamonds = new ImgData_Diamonds(); 265 } 266 $this->markimg = $this->imgdata_diamonds->GetImg($this->type,$filename); 267 list($anchor_x,$anchor_y) = $this->imgdata_diamonds->GetAnchor(); 268 break; 269 270 case MARK_IMG_BALL: 271 case MARK_IMG_SBALL: 272 case MARK_IMG_MBALL: 273 case MARK_IMG_LBALL: 274 if( $this->imgdata_balls == null ) { 275 require_once 'imgdata_balls.inc.php'; 276 $this->imgdata_balls = new ImgData_Balls(); 277 } 278 $this->markimg = $this->imgdata_balls->GetImg($this->type,$filename); 279 list($anchor_x,$anchor_y) = $this->imgdata_balls->GetAnchor(); 280 break; 281 } 282 283 $w = $img->GetWidth($this->markimg); 284 $h = $img->GetHeight($this->markimg); 285 286 $dw = round($imgscale * $w ); 287 $dh = round($imgscale * $h ); 288 289 // Do potential rotation 290 list($x,$y) = $img->Rotate($x,$y); 291 292 $dx = round($x-$dw*$anchor_x); 293 $dy = round($y-$dh*$anchor_y); 294 295 $this->width = max($dx,$dy); 296 297 $img->Copy($this->markimg,$dx,$dy,0,0,$dw,$dh,$w,$h); 298 if( !empty($this->csimtarget) ) { 299 $this->csimareas = "<area shape=\"rect\" coords=\"". 300 $dx.','.$dy.','.round($dx+$dw).','.round($dy+$dh).'" '. 301 "href=\"".htmlentities($this->csimtarget)."\""; 302 303 if( !empty($this->csimwintarget) ) { 304 $this->csimareas .= " target=\"".$this->csimwintarget."\" "; 305 } 306 307 if( !empty($this->csimalt) ) { 308 $tmp=sprintf($this->csimalt,$this->yvalue,$this->xvalue); 309 $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" "; 310 } 311 $this->csimareas .= " />\n"; 312 } 313 314 // Stroke title 315 $this->title->Align("center","top"); 316 $this->title->Stroke($img,$x,$y+round($dh/2)); 317 return; 318 } 319 320 $weight = $this->weight; 321 $dx=round($width/2,0); 322 $dy=round($width/2,0); 323 $pts=0; 324 325 switch( $this->type ) { 326 case MARK_SQUARE: 327 $c[]=$x-$dx;$c[]=$y-$dy; 328 $c[]=$x+$dx;$c[]=$y-$dy; 329 $c[]=$x+$dx;$c[]=$y+$dy; 330 $c[]=$x-$dx;$c[]=$y+$dy; 331 $c[]=$x-$dx;$c[]=$y-$dy; 332 $pts=5; 333 break; 334 case MARK_UTRIANGLE: 335 ++$dx;++$dy; 336 $c[]=$x-$dx;$c[]=$y+0.87*$dy; // tan(60)/2*$dx 337 $c[]=$x;$c[]=$y-0.87*$dy; 338 $c[]=$x+$dx;$c[]=$y+0.87*$dy; 339 $c[]=$x-$dx;$c[]=$y+0.87*$dy; // tan(60)/2*$dx 340 $pts=4; 341 break; 342 case MARK_DTRIANGLE: 343 ++$dx;++$dy; 344 $c[]=$x;$c[]=$y+0.87*$dy; // tan(60)/2*$dx 345 $c[]=$x-$dx;$c[]=$y-0.87*$dy; 346 $c[]=$x+$dx;$c[]=$y-0.87*$dy; 347 $c[]=$x;$c[]=$y+0.87*$dy; // tan(60)/2*$dx 348 $pts=4; 349 break; 350 case MARK_DIAMOND: 351 $c[]=$x;$c[]=$y+$dy; 352 $c[]=$x-$dx;$c[]=$y; 353 $c[]=$x;$c[]=$y-$dy; 354 $c[]=$x+$dx;$c[]=$y; 355 $c[]=$x;$c[]=$y+$dy; 356 $pts=5; 357 break; 358 case MARK_LEFTTRIANGLE: 359 $c[]=$x;$c[]=$y; 360 $c[]=$x;$c[]=$y+2*$dy; 361 $c[]=$x+$dx*2;$c[]=$y; 362 $c[]=$x;$c[]=$y; 363 $pts=4; 364 break; 365 case MARK_RIGHTTRIANGLE: 366 $c[]=$x-$dx*2;$c[]=$y; 367 $c[]=$x;$c[]=$y+2*$dy; 368 $c[]=$x;$c[]=$y; 369 $c[]=$x-$dx*2;$c[]=$y; 370 $pts=4; 371 break; 372 case MARK_FLASH: 373 $dy *= 2; 374 $c[]=$x+$dx/2; $c[]=$y-$dy; 375 $c[]=$x-$dx+$dx/2; $c[]=$y+$dy*0.7-$dy; 376 $c[]=$x+$dx/2; $c[]=$y+$dy*1.3-$dy; 377 $c[]=$x-$dx+$dx/2; $c[]=$y+2*$dy-$dy; 378 $img->SetLineWeight($weight); 379 $img->SetColor($color); 380 $img->Polygon($c); 381 $img->SetLineWeight(1); 382 $this->AddCSIMPoly($c); 383 break; 384 } 385 386 if( $pts>0 ) { 387 $this->AddCSIMPoly($c); 388 $img->SetLineWeight($weight); 389 $img->SetColor($fcolor); 390 $img->FilledPolygon($c); 391 $img->SetColor($color); 392 $img->Polygon($c); 393 $img->SetLineWeight(1); 394 } 395 elseif( $this->type==MARK_CIRCLE ) { 396 $img->SetColor($color); 397 $img->Circle($x,$y,$width); 398 $this->AddCSIMCircle($x,$y,$width); 399 } 400 elseif( $this->type==MARK_FILLEDCIRCLE ) { 401 $img->SetColor($fcolor); 402 $img->FilledCircle($x,$y,$width); 403 $img->SetColor($color); 404 $img->Circle($x,$y,$width); 405 $this->AddCSIMCircle($x,$y,$width); 406 } 407 elseif( $this->type==MARK_CROSS ) { 408 // Oversize by a pixel to match the X 409 $img->SetColor($color); 410 $img->SetLineWeight($weight); 411 $img->Line($x,$y+$dy+1,$x,$y-$dy-1); 412 $img->Line($x-$dx-1,$y,$x+$dx+1,$y); 413 $this->AddCSIMCircle($x,$y,$dx); 414 } 415 elseif( $this->type==MARK_X ) { 416 $img->SetColor($color); 417 $img->SetLineWeight($weight); 418 $img->Line($x+$dx,$y+$dy,$x-$dx,$y-$dy); 419 $img->Line($x-$dx,$y+$dy,$x+$dx,$y-$dy); 420 $this->AddCSIMCircle($x,$y,$dx+$dy); 421 } 422 elseif( $this->type==MARK_STAR ) { 423 $img->SetColor($color); 424 $img->SetLineWeight($weight); 425 $img->Line($x+$dx,$y+$dy,$x-$dx,$y-$dy); 426 $img->Line($x-$dx,$y+$dy,$x+$dx,$y-$dy); 427 // Oversize by a pixel to match the X 428 $img->Line($x,$y+$dy+1,$x,$y-$dy-1); 429 $img->Line($x-$dx-1,$y,$x+$dx+1,$y); 430 $this->AddCSIMCircle($x,$y,$dx+$dy); 431 } 432 433 // Stroke title 434 $this->title->Align("center","center"); 435 $this->title->Stroke($img,$x,$y); 436 436 } 437 437 } // Class … … 441 441 //======================================================================== 442 442 // CLASS ImgData 443 // Description: Base class for all image data classes that contains the 443 // Description: Base class for all image data classes that contains the 444 444 // real image data. 445 445 //======================================================================== 446 446 class ImgData { 447 protected $name = ''; 448 protected $an = array(); 449 protected $colors = array(); 450 protected $index = array(); 451 protected $maxidx = 0 ; 447 protected $name = ''; // Each subclass gives a name 448 protected $an = array(); // Data array names 449 protected $colors = array(); // Available colors 450 protected $index = array(); // Index for colors 451 protected $maxidx = 0 ; // Max color index 452 452 protected $anchor_x=0.5, $anchor_y=0.5 ; // Where is the center of the image 453 454 function __construct() { 455 // Empty 456 } 457 453 458 // Create a GD image from the data and return a GD handle 454 459 function GetImg($aMark,$aIdx) { 455 $n = $this->an[$aMark]; 456 if( is_string($aIdx) ) { 457 if( !in_array($aIdx,$this->colors) ) { 458 JpGraphError::RaiseL(23001,$this->name,$aIdx);//('This marker "'.($this->name).'" does not exist in color: '.$aIdx); 459 } 460 $idx = $this->index[$aIdx]; 461 } 462 elseif( !is_integer($aIdx) || 463 (is_integer($aIdx) && $aIdx > $this->maxidx ) ) { 464 JpGraphError::RaiseL(23002,$this->name);//('Mark color index too large for marker "'.($this->name).'"'); 465 } 466 else 467 $idx = $aIdx ; 468 return Image::CreateFromString(base64_decode($this->{$n}[$idx][1])); 469 } 460 $n = $this->an[$aMark]; 461 if( is_string($aIdx) ) { 462 if( !in_array($aIdx,$this->colors) ) { 463 JpGraphError::RaiseL(23001,$this->name,$aIdx);//('This marker "'.($this->name).'" does not exist in color: '.$aIdx); 464 } 465 $idx = $this->index[$aIdx]; 466 } 467 elseif( !is_integer($aIdx) || 468 (is_integer($aIdx) && $aIdx > $this->maxidx ) ) { 469 JpGraphError::RaiseL(23002,$this->name);//('Mark color index too large for marker "'.($this->name).'"'); 470 } 471 else 472 $idx = $aIdx ; 473 return Image::CreateFromString(base64_decode($this->{$n}[$idx][1])); 474 } 475 470 476 function GetAnchor() { 471 477 return array($this->anchor_x,$this->anchor_y); 472 478 } 473 479 } … … 476 482 // Keep a global flag cache to reduce memory usage 477 483 $_gFlagCache=array( 478 479 480 481 484 1 => null, 485 2 => null, 486 3 => null, 487 4 => null, 482 488 ); 483 489 // Only supposed to b called as statics 484 490 class FlagCache { 491 485 492 static function GetFlagImgByName($aSize,$aName) { 486 487 488 489 490 491 492 493 493 global $_gFlagCache; 494 require_once('jpgraph_flags.php'); 495 if( $_gFlagCache[$aSize] === null ) { 496 $_gFlagCache[$aSize] = new FlagImages($aSize); 497 } 498 $f = $_gFlagCache[$aSize]; 499 $idx = $f->GetIdxByName($aName,$aFullName); 500 return $f->GetImgByIdx($idx); 494 501 } 495 502 } -
trunk/client/modules/Elezioni/grafici/jpgraph_polar.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_POLAR.PHP4 // Description:Polar plot extension for JpGraph5 // Created:2003-02-026 // Ver: $Id: jpgraph_polar.php 1091 2009-01-18 22:57:40Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */3 // File: JPGRAPH_POLAR.PHP 4 // Description: Polar plot extension for JpGraph 5 // Created: 2003-02-02 6 // Ver: $Id: jpgraph_polar.php 1796 2009-09-07 09:37:19Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 require_once ('jpgraph_plotmark.inc.php'); … … 25 25 // There were two option. 1: Re-implement everything and get a clean design 26 26 // and 2: do some "small" trickery and be able to inherit most of 27 // the functionlity from the main graph package. 27 // the functionlity from the main graph package. 28 28 // We choose 2: here in order to save some time. 29 // 29 // 30 30 31 31 //-------------------------------------------------------------------------- … … 37 37 public $legendcsimalt=''; 38 38 public $legend=""; 39 public $csimtargets=array(); 40 public $csimareas=""; // Resultant CSIM area tags41 public $csimalts=null; 39 public $csimtargets=array(); // Array of targets for CSIM 40 public $csimareas=""; // Resultant CSIM area tags 41 public $csimalts=null; // ALT:s for corresponding target 42 42 public $scale=null; 43 43 private $numpoints=0; … … 46 46 private $coord=null; 47 47 48 function PolarPlot($aData) {49 50 51 52 //('Polar plots must have an even number of data point. Each data point is a tuple (angle,radius).');53 54 55 56 48 function __construct($aData) { 49 $n = count($aData); 50 if( $n & 1 ) { 51 JpGraphError::RaiseL(17001); 52 //('Polar plots must have an even number of data point. Each data point is a tuple (angle,radius).'); 53 } 54 $this->numpoints = $n/2; 55 $this->coord = $aData; 56 $this->mark = new PlotMark(); 57 57 } 58 58 59 59 function SetWeight($aWeight) { 60 60 $this->iLineWeight = $aWeight; 61 61 } 62 62 63 63 function SetColor($aColor){ 64 64 $this->iColor = $aColor; 65 65 } 66 66 67 67 function SetFillColor($aColor){ 68 68 $this->iFillColor = $aColor; 69 69 } 70 70 71 71 function Max() { 72 73 74 75 $m = max($m,$this->coord[2*$i+1]); 76 77 } 78 79 } 80 // Set href targets for CSIM 72 $m = $this->coord[1]; 73 $i=1; 74 while( $i < $this->numpoints ) { 75 $m = max($m,$this->coord[2*$i+1]); 76 ++$i; 77 } 78 return $m; 79 } 80 // Set href targets for CSIM 81 81 function SetCSIMTargets($aTargets,$aAlts=null) { 82 83 $this->csimalts=$aAlts; 84 } 85 82 $this->csimtargets=$aTargets; 83 $this->csimalts=$aAlts; 84 } 85 86 86 // Get all created areas 87 87 function GetCSIMareas() { 88 89 } 90 88 return $this->csimareas; 89 } 90 91 91 function SetLegend($aLegend,$aCSIM="",$aCSIMAlt="") { 92 93 94 92 $this->legend = $aLegend; 93 $this->legendcsimtarget = $aCSIM; 94 $this->legendcsimalt = $aCSIMAlt; 95 95 } 96 96 … … 98 98 99 99 function Legend($aGraph) { 100 101 102 103 104 105 $this->legendcsimtarget,$this->legendcsimalt); 106 107 108 109 $this->legendcsimtarget,$this->legendcsimalt); 110 111 100 $color = $this->iColor ; 101 if( $this->legend != "" ) { 102 if( $this->iFillColor!='' ) { 103 $color = $this->iFillColor; 104 $aGraph->legend->Add($this->legend,$color,$this->mark,0, 105 $this->legendcsimtarget,$this->legendcsimalt); 106 } 107 else { 108 $aGraph->legend->Add($this->legend,$color,$this->mark,$this->line_style, 109 $this->legendcsimtarget,$this->legendcsimalt); 110 } 111 } 112 112 } 113 113 114 114 function Stroke($img,$scale) { 115 115 116 $i=0; 117 $p=array(); 118 $this->csimareas=''; 119 while($i < $this->numpoints) { 120 list($x1,$y1) = $scale->PTranslate($this->coord[2*$i],$this->coord[2*$i+1]); 121 $p[2*$i] = $x1; 122 $p[2*$i+1] = $y1; 123 124 if( isset($this->csimtargets[$i]) ) { 125 $this->mark->SetCSIMTarget($this->csimtargets[$i]); 126 $this->mark->SetCSIMAlt($this->csimalts[$i]); 127 $this->mark->SetCSIMAltVal($this->coord[2*$i], $this->coord[2*$i+1]); 128 $this->mark->Stroke($img,$x1,$y1); 129 $this->csimareas .= $this->mark->GetCSIMAreas(); 130 } 131 else 132 $this->mark->Stroke($img,$x1,$y1); 133 134 ++$i; 135 } 136 137 if( $this->iFillColor != '' ) { 138 $img->SetColor($this->iFillColor); 139 $img->FilledPolygon($p); 140 } 141 $img->SetLineWeight($this->iLineWeight); 142 $img->SetColor($this->iColor); 143 $img->Polygon($p,$this->iFillColor!=''); 116 $i=0; 117 $p=array(); 118 $this->csimareas=''; 119 while($i < $this->numpoints) { 120 list($x1,$y1) = $scale->PTranslate($this->coord[2*$i],$this->coord[2*$i+1]); 121 $p[2*$i] = $x1; 122 $p[2*$i+1] = $y1; 123 124 if( isset($this->csimtargets[$i]) ) { 125 $this->mark->SetCSIMTarget($this->csimtargets[$i]); 126 $this->mark->SetCSIMAlt($this->csimalts[$i]); 127 $this->mark->SetCSIMAltVal($this->coord[2*$i], $this->coord[2*$i+1]); 128 $this->mark->Stroke($img,$x1,$y1); 129 $this->csimareas .= $this->mark->GetCSIMAreas(); 130 } 131 else { 132 $this->mark->Stroke($img,$x1,$y1); 133 } 134 135 ++$i; 136 } 137 138 if( $this->iFillColor != '' ) { 139 $img->SetColor($this->iFillColor); 140 $img->FilledPolygon($p); 141 } 142 $img->SetLineWeight($this->iLineWeight); 143 $img->SetColor($this->iColor); 144 $img->Polygon($p,$this->iFillColor!=''); 144 145 } 145 146 } … … 159 160 private $radius_tick_color='black'; 160 161 161 function PolarAxis($img,$aScale) {162 parent::Axis($img,$aScale);162 function __construct($img,$aScale) { 163 parent::__construct($img,$aScale); 163 164 } 164 165 165 166 function ShowAngleDegreeMark($aFlg=true) { 166 167 $this->show_angle_mark = $aFlg; 167 168 } 168 169 169 170 function SetAngleStep($aStep) { 170 171 $this->angle_step=$aStep; 171 172 } 172 173 173 174 function HideTicks($aFlg=true,$aAngleFlg=true) { 174 175 175 parent::HideTicks($aFlg,$aFlg); 176 $this->show_angle_tick = !$aAngleFlg; 176 177 } 177 178 178 179 function ShowAngleLabel($aFlg=true) { 179 180 $this->show_angle_label = $aFlg; 180 181 } 181 182 182 183 function ShowGrid($aMajor=true,$aMinor=false,$aAngle=true) { 183 184 185 184 $this->show_minor_grid = $aMinor; 185 $this->show_major_grid = $aMajor; 186 $this->show_angle_grid = $aAngle ; 186 187 } 187 188 188 189 function SetAngleFont($aFontFam,$aFontStyle=FS_NORMAL,$aFontSize=10) { 189 190 191 190 $this->angle_fontfam = $aFontFam; 191 $this->angle_fontstyle = $aFontStyle; 192 $this->angle_fontsize = $aFontSize; 192 193 } 193 194 194 195 function SetColor($aColor,$aRadColor='',$aAngleColor='') { 195 196 197 198 196 if( $aAngleColor == '' ) 197 $aAngleColor=$aColor; 198 parent::SetColor($aColor,$aRadColor); 199 $this->angle_fontcolor = $aAngleColor; 199 200 } 200 201 201 202 function SetGridColor($aMajorColor,$aMinorColor='',$aAngleColor='') { 202 if( $aMinorColor == '' ) 203 204 if( $aAngleColor == '' ) 205 206 207 208 209 203 if( $aMinorColor == '' ) 204 $aMinorColor = $aMajorColor; 205 if( $aAngleColor == '' ) 206 $aAngleColor = $aMajorColor; 207 208 $this->gridminor_color = $aMinorColor; 209 $this->gridmajor_color = $aMajorColor; 210 $this->angle_color = $aAngleColor; 210 211 } 211 212 212 213 function SetTickColors($aRadColor,$aAngleColor='') { 213 214 215 } 216 214 $this->radius_tick_color = $aRadColor; 215 $this->angle_tick_color = $aAngleColor; 216 } 217 217 218 // Private methods 218 219 function StrokeGrid($pos) { 219 220 221 222 // Stroke the minor arcs 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 // Stroke the major arcs 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 220 $x = round($this->img->left_margin + $this->img->plotwidth/2); 221 $this->scale->ticks->Stroke($this->img,$this->scale,$pos); 222 223 // Stroke the minor arcs 224 $pmin = array(); 225 $p = $this->scale->ticks->ticks_pos; 226 $n = count($p); 227 $i = 0; 228 $this->img->SetColor($this->gridminor_color); 229 while( $i < $n ) { 230 $r = $p[$i]-$x+1; 231 $pmin[]=$r; 232 if( $this->show_minor_grid ) { 233 $this->img->Circle($x,$pos,$r); 234 } 235 $i++; 236 } 237 238 $limit = max($this->img->plotwidth,$this->img->plotheight)*1.4 ; 239 while( $r < $limit ) { 240 $off = $r; 241 $i=1; 242 $r = $off + round($p[$i]-$x+1); 243 while( $r < $limit && $i < $n ) { 244 $r = $off+$p[$i]-$x; 245 $pmin[]=$r; 246 if( $this->show_minor_grid ) { 247 $this->img->Circle($x,$pos,$r); 248 } 249 $i++; 250 } 251 } 252 253 // Stroke the major arcs 254 if( $this->show_major_grid ) { 255 // First determine how many minor step on 256 // every major step. We have recorded the minor radius 257 // in pmin and use these values. This is done in order 258 // to avoid rounding errors if we were to recalculate the 259 // different major radius. 260 $pmaj = $this->scale->ticks->maj_ticks_pos; 261 $p = $this->scale->ticks->ticks_pos; 262 if( $this->scale->name == 'lin' ) { 263 $step=round(($pmaj[1] - $pmaj[0])/($p[1] - $p[0])); 264 } 265 else { 266 $step=9; 267 } 268 $n = round(count($pmin)/$step); 269 $i = 0; 270 $this->img->SetColor($this->gridmajor_color); 271 $limit = max($this->img->plotwidth,$this->img->plotheight)*1.4 ; 272 $off = $r; 273 $i=0; 274 $r = $pmin[$i*$step]; 275 while( $r < $limit && $i < $n ) { 276 $r = $pmin[$i*$step]; 277 $this->img->Circle($x,$pos,$r); 278 $i++; 279 } 280 } 281 282 // Draw angles 283 if( $this->show_angle_grid ) { 284 $this->img->SetColor($this->angle_color); 285 $d = max($this->img->plotheight,$this->img->plotwidth)*1.4 ; 286 $a = 0; 287 $p = $this->scale->ticks->ticks_pos; 288 $start_radius = $p[1]-$x; 289 while( $a < 360 ) { 290 if( $a == 90 || $a == 270 ) { 291 // Make sure there are no rounding problem with 292 // exactly vertical lines 293 $this->img->Line($x+$start_radius*cos($a/180*M_PI)+1, 294 $pos-$start_radius*sin($a/180*M_PI), 295 $x+$start_radius*cos($a/180*M_PI)+1, 296 $pos-$d*sin($a/180*M_PI)); 297 298 } 299 else { 300 $this->img->Line($x+$start_radius*cos($a/180*M_PI)+1, 301 $pos-$start_radius*sin($a/180*M_PI), 302 $x+$d*cos($a/180*M_PI), 303 $pos-$d*sin($a/180*M_PI)); 304 } 305 $a += $this->angle_step; 306 } 307 } 307 308 } 308 309 309 310 function StrokeAngleLabels($pos,$type) { 310 311 311 if( !$this->show_angle_label ) 312 return; 313 314 $x0 = round($this->img->left_margin+$this->img->plotwidth/2)+1; 315 316 $d = max($this->img->plotwidth,$this->img->plotheight)*1.42; 317 $a = $this->angle_step; 318 $t = new Text(); 319 $t->SetColor($this->angle_fontcolor); 320 $t->SetFont($this->angle_fontfam,$this->angle_fontstyle,$this->angle_fontsize); 321 $xright = $this->img->width - $this->img->right_margin; 322 $ytop = $this->img->top_margin; 323 $xleft = $this->img->left_margin; 324 $ybottom = $this->img->height - $this->img->bottom_margin; 325 $ha = 'left'; 326 $va = 'center'; 327 $w = $this->img->plotwidth/2; 328 $h = $this->img->plotheight/2; 329 $xt = $x0; $yt = $pos; 330 $margin=5; 331 332 $tl = $this->angle_tick_len ; // Outer len 333 $tl2 = $this->angle_tick_len2 ; // Interior len 334 335 $this->img->SetColor($this->angle_tick_color); 336 $rot90 = $this->img->a == 90 ; 337 338 if( $type == POLAR_360 ) { 339 $ca1 = atan($h/$w)/M_PI*180; 340 $ca2 = 180-$ca1; 341 $ca3 = $ca1+180; 342 $ca4 = 360-$ca1; 343 $end = 360; 344 while( $a < $end ) { 345 $ca = cos($a/180*M_PI); 346 $sa = sin($a/180*M_PI); 347 $x = $d*$ca; 348 $y = $d*$sa; 349 $xt=1000;$yt=1000; 350 if( $a <= $ca1 || $a >= $ca4 ) { 351 $yt = $pos - $w * $y/$x; 352 $xt = $xright + $margin; 353 if( $rot90 ) { 354 $ha = 'center'; 355 $va = 'top'; 356 } 357 else { 358 $ha = 'left'; 359 $va = 'center'; 360 } 361 $x1=$xright-$tl2; $x2=$xright+$tl; 362 $y1=$y2=$yt; 363 } 364 elseif( $a > $ca1 && $a < $ca2 ) { 365 $xt = $x0 + $h * $x/$y; 366 $yt = $ytop - $margin; 367 if( $rot90 ) { 368 $ha = 'left'; 369 $va = 'center'; 370 } 371 else { 372 $ha = 'center'; 373 $va = 'bottom'; 374 } 375 $y1=$ytop+$tl2;$y2=$ytop-$tl; 376 $x1=$x2=$xt; 377 } 378 elseif( $a >= $ca2 && $a <= $ca3 ) { 379 $yt = $pos + $w * $y/$x; 380 $xt = $xleft - $margin; 381 if( $rot90 ) { 382 $ha = 'center'; 383 $va = 'bottom'; 384 } 385 else { 386 $ha = 'right'; 387 $va = 'center'; 388 } 389 $x1=$xleft+$tl2;$x2=$xleft-$tl; 390 $y1=$y2=$yt; 391 } 392 else { 393 $xt = $x0 - $h * $x/$y; 394 $yt = $ybottom + $margin; 395 if( $rot90 ) { 396 $ha = 'right'; 397 $va = 'center'; 398 } 399 else { 400 $ha = 'center'; 401 $va = 'top'; 402 } 403 $y1=$ybottom-$tl2;$y2=$ybottom+$tl; 404 $x1=$x2=$xt; 405 } 406 if( $a != 0 && $a != 180 ) { 407 $t->Align($ha,$va); 408 if( $this->show_angle_mark ) 409 $a .= '°'; 410 $t->Set($a); 411 $t->Stroke($this->img,$xt,$yt); 412 if( $this->show_angle_tick ) 413 $this->img->Line($x1,$y1,$x2,$y2); 414 } 415 $a += $this->angle_step; 416 } 417 } 418 else { 419 // POLAR_HALF 420 $ca1 = atan($h/$w*2)/M_PI*180; 421 $ca2 = 180-$ca1; 422 $end = 180; 423 while( $a < $end ) { 424 $ca = cos($a/180*M_PI); 425 $sa = sin($a/180*M_PI); 426 $x = $d*$ca; 427 $y = $d*$sa; 428 if( $a <= $ca1 ) { 429 $yt = $pos - $w * $y/$x; 430 $xt = $xright + $margin; 431 if( $rot90 ) { 432 $ha = 'center'; 433 $va = 'top'; 434 } 435 else { 436 $ha = 'left'; 437 $va = 'center'; 438 } 439 $x1=$xright-$tl2; $x2=$xright+$tl; 440 $y1=$y2=$yt; 441 } 442 elseif( $a > $ca1 && $a < $ca2 ) { 443 $xt = $x0 + 2*$h * $x/$y; 444 $yt = $ytop - $margin; 445 if( $rot90 ) { 446 $ha = 'left'; 447 $va = 'center'; 448 } 449 else { 450 $ha = 'center'; 451 $va = 'bottom'; 452 } 453 $y1=$ytop+$tl2;$y2=$ytop-$tl; 454 $x1=$x2=$xt; 455 } 456 elseif( $a >= $ca2 ) { 457 $yt = $pos + $w * $y/$x; 458 $xt = $xleft - $margin; 459 if( $rot90 ) { 460 $ha = 'center'; 461 $va = 'bottom'; 462 } 463 else { 464 $ha = 'right'; 465 $va = 'center'; 466 } 467 $x1=$xleft+$tl2;$x2=$xleft-$tl; 468 $y1=$y2=$yt; 469 } 470 $t->Align($ha,$va); 471 if( $this->show_angle_mark ) 472 $a .= '°'; 473 $t->Set($a); 474 $t->Stroke($this->img,$xt,$yt); 475 if( $this->show_angle_tick ) 476 $this->img->Line($x1,$y1,$x2,$y2); 477 $a += $this->angle_step; 478 } 479 } 312 if( !$this->show_angle_label ) 313 return; 314 315 $x0 = round($this->img->left_margin+$this->img->plotwidth/2)+1; 316 317 $d = max($this->img->plotwidth,$this->img->plotheight)*1.42; 318 $a = $this->angle_step; 319 $t = new Text(); 320 $t->SetColor($this->angle_fontcolor); 321 $t->SetFont($this->angle_fontfam,$this->angle_fontstyle,$this->angle_fontsize); 322 $xright = $this->img->width - $this->img->right_margin; 323 $ytop = $this->img->top_margin; 324 $xleft = $this->img->left_margin; 325 $ybottom = $this->img->height - $this->img->bottom_margin; 326 $ha = 'left'; 327 $va = 'center'; 328 $w = $this->img->plotwidth/2; 329 $h = $this->img->plotheight/2; 330 $xt = $x0; $yt = $pos; 331 $margin=5; 332 333 $tl = $this->angle_tick_len ; // Outer len 334 $tl2 = $this->angle_tick_len2 ; // Interior len 335 336 $this->img->SetColor($this->angle_tick_color); 337 $rot90 = $this->img->a == 90 ; 338 339 if( $type == POLAR_360 ) { 340 341 // Corner angles of the four corners 342 $ca1 = atan($h/$w)/M_PI*180; 343 $ca2 = 180-$ca1; 344 $ca3 = $ca1+180; 345 $ca4 = 360-$ca1; 346 $end = 360; 347 348 while( $a < $end ) { 349 $ca = cos($a/180*M_PI); 350 $sa = sin($a/180*M_PI); 351 $x = $d*$ca; 352 $y = $d*$sa; 353 $xt=1000;$yt=1000; 354 if( $a <= $ca1 || $a >= $ca4 ) { 355 $yt = $pos - $w * $y/$x; 356 $xt = $xright + $margin; 357 if( $rot90 ) { 358 $ha = 'center'; 359 $va = 'top'; 360 } 361 else { 362 $ha = 'left'; 363 $va = 'center'; 364 } 365 $x1=$xright-$tl2; $x2=$xright+$tl; 366 $y1=$y2=$yt; 367 } 368 elseif( $a > $ca1 && $a < $ca2 ) { 369 $xt = $x0 + $h * $x/$y; 370 $yt = $ytop - $margin; 371 if( $rot90 ) { 372 $ha = 'left'; 373 $va = 'center'; 374 } 375 else { 376 $ha = 'center'; 377 $va = 'bottom'; 378 } 379 $y1=$ytop+$tl2;$y2=$ytop-$tl; 380 $x1=$x2=$xt; 381 } 382 elseif( $a >= $ca2 && $a <= $ca3 ) { 383 $yt = $pos + $w * $y/$x; 384 $xt = $xleft - $margin; 385 if( $rot90 ) { 386 $ha = 'center'; 387 $va = 'bottom'; 388 } 389 else { 390 $ha = 'right'; 391 $va = 'center'; 392 } 393 $x1=$xleft+$tl2;$x2=$xleft-$tl; 394 $y1=$y2=$yt; 395 } 396 else { 397 $xt = $x0 - $h * $x/$y; 398 $yt = $ybottom + $margin; 399 if( $rot90 ) { 400 $ha = 'right'; 401 $va = 'center'; 402 } 403 else { 404 $ha = 'center'; 405 $va = 'top'; 406 } 407 $y1=$ybottom-$tl2;$y2=$ybottom+$tl; 408 $x1=$x2=$xt; 409 } 410 if( $a != 0 && $a != 180 ) { 411 $t->Align($ha,$va); 412 if( $this->scale->clockwise ) { 413 $t->Set(360-$a); 414 } 415 else { 416 $t->Set($a); 417 } 418 if( $this->show_angle_mark && $t->font_family > 4 ) { 419 $a .= SymChar::Get('degree'); 420 } 421 $t->Stroke($this->img,$xt,$yt); 422 if( $this->show_angle_tick ) { 423 $this->img->Line($x1,$y1,$x2,$y2); 424 } 425 } 426 $a = (int) $a; 427 $a += $this->angle_step; 428 } 429 } 430 else { 431 // POLAR_HALF 432 $ca1 = atan($h/$w*2)/M_PI*180; 433 $ca2 = 180-$ca1; 434 $end = 180; 435 while( $a < $end ) { 436 $ca = cos($a/180*M_PI); 437 $sa = sin($a/180*M_PI); 438 $x = $d*$ca; 439 $y = $d*$sa; 440 if( $a <= $ca1 ) { 441 $yt = $pos - $w * $y/$x; 442 $xt = $xright + $margin; 443 if( $rot90 ) { 444 $ha = 'center'; 445 $va = 'top'; 446 } 447 else { 448 $ha = 'left'; 449 $va = 'center'; 450 } 451 $x1=$xright-$tl2; $x2=$xright+$tl; 452 $y1=$y2=$yt; 453 } 454 elseif( $a > $ca1 && $a < $ca2 ) { 455 $xt = $x0 + 2*$h * $x/$y; 456 $yt = $ytop - $margin; 457 if( $rot90 ) { 458 $ha = 'left'; 459 $va = 'center'; 460 } 461 else { 462 $ha = 'center'; 463 $va = 'bottom'; 464 } 465 $y1=$ytop+$tl2;$y2=$ytop-$tl; 466 $x1=$x2=$xt; 467 } 468 elseif( $a >= $ca2 ) { 469 $yt = $pos + $w * $y/$x; 470 $xt = $xleft - $margin; 471 if( $rot90 ) { 472 $ha = 'center'; 473 $va = 'bottom'; 474 } 475 else { 476 $ha = 'right'; 477 $va = 'center'; 478 } 479 $x1=$xleft+$tl2;$x2=$xleft-$tl; 480 $y1=$y2=$yt; 481 } 482 $t->Align($ha,$va); 483 if( $this->show_angle_mark && $t->font_family > 4 ) { 484 $a .= SymChar::Get('degree'); 485 } 486 $t->Set($a); 487 $t->Stroke($this->img,$xt,$yt); 488 if( $this->show_angle_tick ) { 489 $this->img->Line($x1,$y1,$x2,$y2); 490 } 491 $a = (int) $a; 492 $a += $this->angle_step; 493 } 494 } 480 495 } 481 496 482 497 function Stroke($pos,$dummy=true) { 483 498 484 $this->img->SetLineWeight($this->weight); 485 $this->img->SetColor($this->color); 486 $this->img->SetFont($this->font_family,$this->font_style,$this->font_size); 487 if( !$this->hide_line ) 488 $this->img->FilledRectangle($this->img->left_margin,$pos, 489 $this->img->width-$this->img->right_margin,$pos+$this->weight-1); 490 $y=$pos+$this->img->GetFontHeight()+$this->title_margin+$this->title->margin; 491 if( $this->title_adjust=="high" ) 492 $this->title->SetPos($this->img->width-$this->img->right_margin,$y,"right","top"); 493 elseif( $this->title_adjust=="middle" || $this->title_adjust=="center" ) 494 $this->title->SetPos(($this->img->width-$this->img->left_margin- 495 $this->img->right_margin)/2+$this->img->left_margin, 496 $y,"center","top"); 497 elseif($this->title_adjust=="low") 498 $this->title->SetPos($this->img->left_margin,$y,"left","top"); 499 else { 500 JpGraphError::RaiseL(17002,$this->title_adjust); 501 //('Unknown alignment specified for X-axis title. ('.$this->title_adjust.')'); 502 } 503 504 505 if (!$this->hide_labels) { 506 $this->StrokeLabels($pos,false); 507 } 508 $this->img->SetColor($this->radius_tick_color); 509 $this->scale->ticks->Stroke($this->img,$this->scale,$pos); 510 511 // 512 // Mirror the positions for the left side of the scale 499 $this->img->SetLineWeight($this->weight); 500 $this->img->SetColor($this->color); 501 $this->img->SetFont($this->font_family,$this->font_style,$this->font_size); 502 if( !$this->hide_line ) { 503 $this->img->FilledRectangle($this->img->left_margin,$pos, 504 $this->img->width-$this->img->right_margin, 505 $pos+$this->weight-1); 506 } 507 $y=$pos+$this->img->GetFontHeight()+$this->title_margin+$this->title->margin; 508 if( $this->title_adjust=="high" ) { 509 $this->title->SetPos($this->img->width-$this->img->right_margin,$y,"right","top"); 510 } 511 elseif( $this->title_adjust=="middle" || $this->title_adjust=="center" ) { 512 $this->title->SetPos(($this->img->width-$this->img->left_margin-$this->img->right_margin)/2+$this->img->left_margin, 513 $y,"center","top"); 514 } 515 elseif($this->title_adjust=="low") { 516 $this->title->SetPos($this->img->left_margin,$y,"left","top"); 517 } 518 else { 519 JpGraphError::RaiseL(17002,$this->title_adjust); 520 //('Unknown alignment specified for X-axis title. ('.$this->title_adjust.')'); 521 } 522 523 524 if (!$this->hide_labels) { 525 $this->StrokeLabels($pos,false); 526 } 527 $this->img->SetColor($this->radius_tick_color); 528 $this->scale->ticks->Stroke($this->img,$this->scale,$pos); 529 513 530 // 514 $mid = 2*($this->img->left_margin+$this->img->plotwidth/2); 515 $n = count($this->scale->ticks->ticks_pos); 516 $i=0; 517 while( $i < $n ) { 518 $this->scale->ticks->ticks_pos[$i] = 519 $mid-$this->scale->ticks->ticks_pos[$i] ; 520 ++$i; 521 } 522 523 $n = count($this->scale->ticks->maj_ticks_pos); 524 $i=0; 525 while( $i < $n ) { 526 $this->scale->ticks->maj_ticks_pos[$i] = 527 $mid-$this->scale->ticks->maj_ticks_pos[$i] ; 528 ++$i; 529 } 530 531 $n = count($this->scale->ticks->maj_ticklabels_pos); 532 $i=1; 533 while( $i < $n ) { 534 $this->scale->ticks->maj_ticklabels_pos[$i] = 535 $mid-$this->scale->ticks->maj_ticklabels_pos[$i] ; 536 ++$i; 537 } 538 539 // Draw the left side of the scale 540 $n = count($this->scale->ticks->ticks_pos); 541 $yu = $pos - $this->scale->ticks->direction*$this->scale->ticks->GetMinTickAbsSize(); 542 543 544 // Minor ticks 545 if( ! $this->scale->ticks->supress_minor_tickmarks ) { 546 $i=1; 547 while( $i < $n/2 ) { 548 $x = round($this->scale->ticks->ticks_pos[$i]) ; 549 $this->img->Line($x,$pos,$x,$yu); 550 ++$i; 551 } 552 } 553 554 $n = count($this->scale->ticks->maj_ticks_pos); 555 $yu = $pos - $this->scale->ticks->direction*$this->scale->ticks->GetMajTickAbsSize(); 556 557 558 // Major ticks 559 if( ! $this->scale->ticks->supress_tickmarks ) { 560 $i=1; 561 while( $i < $n/2 ) { 562 $x = round($this->scale->ticks->maj_ticks_pos[$i]) ; 563 $this->img->Line($x,$pos,$x,$yu); 564 ++$i; 565 } 566 } 567 if (!$this->hide_labels) { 568 $this->StrokeLabels($pos,false); 569 } 570 $this->title->Stroke($this->img); 531 // Mirror the positions for the left side of the scale 532 // 533 $mid = 2*($this->img->left_margin+$this->img->plotwidth/2); 534 $n = count($this->scale->ticks->ticks_pos); 535 $i=0; 536 while( $i < $n ) { 537 $this->scale->ticks->ticks_pos[$i] = 538 $mid-$this->scale->ticks->ticks_pos[$i] ; 539 ++$i; 540 } 541 542 $n = count($this->scale->ticks->maj_ticks_pos); 543 $i=0; 544 while( $i < $n ) { 545 $this->scale->ticks->maj_ticks_pos[$i] = 546 $mid-$this->scale->ticks->maj_ticks_pos[$i] ; 547 ++$i; 548 } 549 550 $n = count($this->scale->ticks->maj_ticklabels_pos); 551 $i=1; 552 while( $i < $n ) { 553 $this->scale->ticks->maj_ticklabels_pos[$i] = 554 $mid-$this->scale->ticks->maj_ticklabels_pos[$i] ; 555 ++$i; 556 } 557 558 // Draw the left side of the scale 559 $n = count($this->scale->ticks->ticks_pos); 560 $yu = $pos - $this->scale->ticks->direction*$this->scale->ticks->GetMinTickAbsSize(); 561 562 563 // Minor ticks 564 if( ! $this->scale->ticks->supress_minor_tickmarks ) { 565 $i=1; 566 while( $i < $n/2 ) { 567 $x = round($this->scale->ticks->ticks_pos[$i]) ; 568 $this->img->Line($x,$pos,$x,$yu); 569 ++$i; 570 } 571 } 572 573 $n = count($this->scale->ticks->maj_ticks_pos); 574 $yu = $pos - $this->scale->ticks->direction*$this->scale->ticks->GetMajTickAbsSize(); 575 576 577 // Major ticks 578 if( ! $this->scale->ticks->supress_tickmarks ) { 579 $i=1; 580 while( $i < $n/2 ) { 581 $x = round($this->scale->ticks->maj_ticks_pos[$i]) ; 582 $this->img->Line($x,$pos,$x,$yu); 583 ++$i; 584 } 585 } 586 if (!$this->hide_labels) { 587 $this->StrokeLabels($pos,false); 588 } 589 $this->title->Stroke($this->img); 571 590 } 572 591 } … … 574 593 class PolarScale extends LinearScale { 575 594 private $graph; 576 577 function PolarScale($aMax=0,$graph) { 578 parent::LinearScale(0,$aMax,'x'); 579 $this->graph = $graph; 595 public $clockwise=false; 596 597 function __construct($aMax,$graph,$aClockwise) { 598 parent::__construct(0,$aMax,'x'); 599 $this->graph = $graph; 600 $this->clockwise = $aClockwise; 601 } 602 603 function SetClockwise($aFlg) { 604 $this->clockwise = $aFlg; 580 605 } 581 606 582 607 function _Translate($v) { 583 608 return parent::Translate($v); 584 609 } 585 610 586 611 function PTranslate($aAngle,$aRad) { 587 588 $m = $this->scale[1]; 589 $w = $this->graph->img->plotwidth/2; 590 $aRad = $aRad/$m*$w; 591 592 $x = cos( $aAngle/180 * M_PI ) * $aRad; 593 $y = sin( $aAngle/180 * M_PI ) * $aRad; 594 595 $x += $this->_Translate(0); 596 597 if( $this->graph->iType == POLAR_360 ) { 598 $y = ($this->graph->img->top_margin + $this->graph->img->plotheight/2) - $y; 599 } 600 else { 601 $y = ($this->graph->img->top_margin + $this->graph->img->plotheight) - $y; 602 } 603 return array($x,$y); 612 613 $m = $this->scale[1]; 614 $w = $this->graph->img->plotwidth/2; 615 $aRad = $aRad/$m*$w; 616 617 $a = $aAngle/180 * M_PI; 618 if( $this->clockwise ) { 619 $a = 2*M_PI-$a; 620 } 621 622 $x = cos($a) * $aRad; 623 $y = sin($a) * $aRad; 624 625 $x += $this->_Translate(0); 626 627 if( $this->graph->iType == POLAR_360 ) { 628 $y = ($this->graph->img->top_margin + $this->graph->img->plotheight/2) - $y; 629 } 630 else { 631 $y = ($this->graph->img->top_margin + $this->graph->img->plotheight) - $y; 632 } 633 return array($x,$y); 604 634 } 605 635 } … … 607 637 class PolarLogScale extends LogScale { 608 638 private $graph; 609 function PolarLogScale($aMax=1,$graph) { 610 parent::LogScale(0,$aMax,'x'); 611 $this->graph = $graph; 612 $this->ticks->SetLabelLogType(LOGLABELS_MAGNITUDE); 613 639 public $clockwise=false; 640 641 function __construct($aMax,$graph,$aClockwise=false) { 642 parent::__construct(0,$aMax,'x'); 643 $this->graph = $graph; 644 $this->ticks->SetLabelLogType(LOGLABELS_MAGNITUDE); 645 $this->clockwise = $aClockwise; 646 647 } 648 649 function SetClockwise($aFlg) { 650 $this->clockwise = $aFlg; 614 651 } 615 652 616 653 function PTranslate($aAngle,$aRad) { 617 654 618 if( $aRad == 0 ) 619 $aRad = 1; 620 $aRad = log10($aRad); 621 $m = $this->scale[1]; 622 $w = $this->graph->img->plotwidth/2; 623 $aRad = $aRad/$m*$w; 624 625 $x = cos( $aAngle/180 * M_PI ) * $aRad; 626 $y = sin( $aAngle/180 * M_PI ) * $aRad; 627 628 $x += $w+$this->graph->img->left_margin;//$this->_Translate(0); 629 if( $this->graph->iType == POLAR_360 ) { 630 $y = ($this->graph->img->top_margin + $this->graph->img->plotheight/2) - $y; 631 } 632 else { 633 $y = ($this->graph->img->top_margin + $this->graph->img->plotheight) - $y; 634 } 635 return array($x,$y); 655 if( $aRad == 0 ) 656 $aRad = 1; 657 $aRad = log10($aRad); 658 $m = $this->scale[1]; 659 $w = $this->graph->img->plotwidth/2; 660 $aRad = $aRad/$m*$w; 661 662 $a = $aAngle/180 * M_PI; 663 if( $this->clockwise ) { 664 $a = 2*M_PI-$a; 665 } 666 667 $x = cos( $a ) * $aRad; 668 $y = sin( $a ) * $aRad; 669 670 $x += $w+$this->graph->img->left_margin;//$this->_Translate(0); 671 if( $this->graph->iType == POLAR_360 ) { 672 $y = ($this->graph->img->top_margin + $this->graph->img->plotheight/2) - $y; 673 } 674 else { 675 $y = ($this->graph->img->top_margin + $this->graph->img->plotheight) - $y; 676 } 677 return array($x,$y); 636 678 } 637 679 } … … 641 683 public $axis; 642 684 public $iType=POLAR_360; 643 644 function PolarGraph($aWidth=300,$aHeight=200,$aCachedName="",$aTimeOut=0,$aInline=true) { 645 parent::Graph($aWidth,$aHeight,$aCachedName,$aTimeOut,$aInline) ; 646 $this->SetDensity(TICKD_DENSE); 647 $this->SetBox(); 648 $this->SetMarginColor('white'); 685 private $iClockwise=false; 686 687 function __construct($aWidth=300,$aHeight=200,$aCachedName="",$aTimeOut=0,$aInline=true) { 688 parent::__construct($aWidth,$aHeight,$aCachedName,$aTimeOut,$aInline) ; 689 $this->SetDensity(TICKD_DENSE); 690 $this->SetBox(); 691 $this->SetMarginColor('white'); 649 692 } 650 693 651 694 function SetDensity($aDense) { 652 $this->SetTickDensity(TICKD_NORMAL,$aDense); 695 $this->SetTickDensity(TICKD_NORMAL,$aDense); 696 } 697 698 function SetClockwise($aFlg) { 699 $this->scale->SetClockwise($aFlg); 653 700 } 654 701 655 702 function Set90AndMargin($lm=0,$rm=0,$tm=0,$bm=0) { 656 $adj = ($this->img->height - $this->img->width)/2; 657 $this->SetAngle(90); 658 $this->img->SetMargin($lm-$adj,$rm-$adj,$tm+$adj,$bm+$adj); 659 $this->img->SetCenter(floor($this->img->width/2),floor($this->img->height/2)); 660 $this->axis->SetLabelAlign('right','center'); 661 //JpGraphError::Raise('Set90AndMargin() is not supported for polar graphs.'); 703 $adj = ($this->img->height - $this->img->width)/2; 704 $this->SetAngle(90); 705 $lm2 = -$adj + ($lm-$rm+$tm+$bm)/2; 706 $rm2 = -$adj + (-$lm+$rm+$tm+$bm)/2; 707 $tm2 = $adj + ($tm-$bm+$lm+$rm)/2; 708 $bm2 = $adj + (-$tm+$bm+$lm+$rm)/2; 709 $this->SetMargin($lm2, $rm2, $tm2, $bm2); 710 $this->axis->SetLabelAlign('right','center'); 662 711 } 663 712 664 713 function SetScale($aScale,$rmax=0,$dummy1=1,$dummy2=1,$dummy3=1) { 665 if( $aScale == 'lin' ) 666 $this->scale = new PolarScale($rmax,$this); 667 elseif( $aScale == 'log' ) { 668 $this->scale = new PolarLogScale($rmax,$this); 669 } 670 else { 671 JpGraphError::RaiseL(17004);//('Unknown scale type for polar graph. Must be "lin" or "log"'); 672 } 673 674 $this->axis = new PolarAxis($this->img,$this->scale); 675 $this->SetMargin(40,40,50,40); 714 if( $aScale == 'lin' ) { 715 $this->scale = new PolarScale($rmax,$this,$this->iClockwise); 716 } 717 elseif( $aScale == 'log' ) { 718 $this->scale = new PolarLogScale($rmax,$this,$this->iClockwise); 719 } 720 else { 721 JpGraphError::RaiseL(17004);//('Unknown scale type for polar graph. Must be "lin" or "log"'); 722 } 723 724 $this->axis = new PolarAxis($this->img,$this->scale); 725 $this->SetMargin(40,40,50,40); 676 726 } 677 727 678 728 function SetType($aType) { 679 729 $this->iType = $aType; 680 730 } 681 731 682 732 function SetPlotSize($w,$h) { 683 684 733 $this->SetMargin(($this->img->width-$w)/2,($this->img->width-$w)/2, 734 ($this->img->height-$h)/2,($this->img->height-$h)/2); 685 735 } 686 736 687 737 // Private methods 688 738 function GetPlotsMax() { 689 690 691 692 693 694 695 696 739 $n = count($this->plots); 740 $m = $this->plots[0]->Max(); 741 $i=1; 742 while($i < $n) { 743 $m = max($this->plots[$i]->Max(),$m); 744 ++$i; 745 } 746 return $m; 697 747 } 698 748 699 749 function Stroke($aStrokeFileName="") { 700 750 701 // Start by adjusting the margin so that potential titles will fit. 702 $this->AdjustMarginsForTitles(); 703 704 // If the filename is the predefined value = '_csim_special_' 705 // we assume that the call to stroke only needs to do enough 706 // to correctly generate the CSIM maps. 707 // We use this variable to skip things we don't strictly need 708 // to do to generate the image map to improve performance 709 // a best we can. Therefor you will see a lot of tests !$_csim in the 710 // code below. 711 $_csim = ($aStrokeFileName===_CSIM_SPECIALFILE); 712 713 // We need to know if we have stroked the plot in the 714 // GetCSIMareas. Otherwise the CSIM hasn't been generated 715 // and in the case of GetCSIM called before stroke to generate 716 // CSIM without storing an image to disk GetCSIM must call Stroke. 717 $this->iHasStroked = true; 718 719 //Check if we should autoscale axis 720 if( !$this->scale->IsSpecified() && count($this->plots)>0 ) { 721 $max = $this->GetPlotsMax(); 722 $t1 = $this->img->plotwidth; 723 $this->img->plotwidth /= 2; 724 $t2 = $this->img->left_margin; 725 $this->img->left_margin += $this->img->plotwidth+1; 726 $this->scale->AutoScale($this->img,0,$max, 727 $this->img->plotwidth/$this->xtick_factor/2); 728 $this->img->plotwidth = $t1; 729 $this->img->left_margin = $t2; 730 } 731 else { 732 // The tick calculation will use the user suplied min/max values to determine 733 // the ticks. If auto_ticks is false the exact user specifed min and max 734 // values will be used for the scale. 735 // If auto_ticks is true then the scale might be slightly adjusted 736 // so that the min and max values falls on an even major step. 737 //$min = 0; 738 $max = $this->scale->scale[1]; 739 $t1 = $this->img->plotwidth; 740 $this->img->plotwidth /= 2; 741 $t2 = $this->img->left_margin; 742 $this->img->left_margin += $this->img->plotwidth+1; 743 $this->scale->AutoScale($this->img,0,$max, 744 $this->img->plotwidth/$this->xtick_factor/2); 745 $this->img->plotwidth = $t1; 746 $this->img->left_margin = $t2; 747 } 748 749 if( $this->iType == POLAR_180 ) 750 $pos = $this->img->height - $this->img->bottom_margin; 751 else 752 $pos = $this->img->plotheight/2 + $this->img->top_margin; 753 754 755 if( !$_csim ) { 756 $this->StrokePlotArea(); 757 } 758 759 $this->iDoClipping = true; 760 761 if( $this->iDoClipping ) { 762 $oldimage = $this->img->CloneCanvasH(); 763 } 764 765 if( !$_csim ) { 766 $this->axis->StrokeGrid($pos); 767 } 768 769 // Stroke all plots for Y1 axis 770 for($i=0; $i < count($this->plots); ++$i) { 771 $this->plots[$i]->Stroke($this->img,$this->scale); 772 } 773 774 775 if( $this->iDoClipping ) { 776 // Clipping only supports graphs at 0 and 90 degrees 777 if( $this->img->a == 0 ) { 778 $this->img->CopyCanvasH($oldimage,$this->img->img, 779 $this->img->left_margin,$this->img->top_margin, 780 $this->img->left_margin,$this->img->top_margin, 781 $this->img->plotwidth+1,$this->img->plotheight+1); 782 } 783 elseif( $this->img->a == 90 ) { 784 $adj = round(($this->img->height - $this->img->width)/2); 785 $this->img->CopyCanvasH($oldimage,$this->img->img, 786 $this->img->bottom_margin-$adj,$this->img->left_margin+$adj, 787 $this->img->bottom_margin-$adj,$this->img->left_margin+$adj, 788 $this->img->plotheight,$this->img->plotwidth); 789 } 790 $this->img->Destroy(); 791 $this->img->SetCanvasH($oldimage); 792 } 793 794 if( !$_csim ) { 795 $this->axis->Stroke($pos); 796 $this->axis->StrokeAngleLabels($pos,$this->iType); 797 } 798 799 if( !$_csim ) { 800 $this->StrokePlotBox(); 801 $this->footer->Stroke($this->img); 802 803 // The titles and legends never gets rotated so make sure 804 // that the angle is 0 before stroking them 805 $aa = $this->img->SetAngle(0); 806 $this->StrokeTitles(); 807 } 808 809 for($i=0; $i < count($this->plots) ; ++$i ) { 810 $this->plots[$i]->Legend($this); 811 } 812 813 $this->legend->Stroke($this->img); 814 815 if( !$_csim ) { 816 817 $this->StrokeTexts(); 818 $this->img->SetAngle($aa); 819 820 // Draw an outline around the image map 821 if(_JPG_DEBUG) 822 $this->DisplayClientSideaImageMapAreas(); 823 824 // If the filename is given as the special "__handle" 825 // then the image handler is returned and the image is NOT 826 // streamed back 827 if( $aStrokeFileName == _IMG_HANDLER ) { 828 return $this->img->img; 829 } 830 else { 831 // Finally stream the generated picture 832 $this->cache->PutAndStream($this->img,$this->cache_name,$this->inline, 833 $aStrokeFileName); 834 } 835 } 751 // Start by adjusting the margin so that potential titles will fit. 752 $this->AdjustMarginsForTitles(); 753 754 // If the filename is the predefined value = '_csim_special_' 755 // we assume that the call to stroke only needs to do enough 756 // to correctly generate the CSIM maps. 757 // We use this variable to skip things we don't strictly need 758 // to do to generate the image map to improve performance 759 // a best we can. Therefor you will see a lot of tests !$_csim in the 760 // code below. 761 $_csim = ($aStrokeFileName===_CSIM_SPECIALFILE); 762 763 // We need to know if we have stroked the plot in the 764 // GetCSIMareas. Otherwise the CSIM hasn't been generated 765 // and in the case of GetCSIM called before stroke to generate 766 // CSIM without storing an image to disk GetCSIM must call Stroke. 767 $this->iHasStroked = true; 768 769 //Check if we should autoscale axis 770 if( !$this->scale->IsSpecified() && count($this->plots)>0 ) { 771 $max = $this->GetPlotsMax(); 772 $t1 = $this->img->plotwidth; 773 $this->img->plotwidth /= 2; 774 $t2 = $this->img->left_margin; 775 $this->img->left_margin += $this->img->plotwidth+1; 776 $this->scale->AutoScale($this->img,0,$max, 777 $this->img->plotwidth/$this->xtick_factor/2); 778 $this->img->plotwidth = $t1; 779 $this->img->left_margin = $t2; 780 } 781 else { 782 // The tick calculation will use the user suplied min/max values to determine 783 // the ticks. If auto_ticks is false the exact user specifed min and max 784 // values will be used for the scale. 785 // If auto_ticks is true then the scale might be slightly adjusted 786 // so that the min and max values falls on an even major step. 787 //$min = 0; 788 $max = $this->scale->scale[1]; 789 $t1 = $this->img->plotwidth; 790 $this->img->plotwidth /= 2; 791 $t2 = $this->img->left_margin; 792 $this->img->left_margin += $this->img->plotwidth+1; 793 $this->scale->AutoScale($this->img,0,$max, 794 $this->img->plotwidth/$this->xtick_factor/2); 795 $this->img->plotwidth = $t1; 796 $this->img->left_margin = $t2; 797 } 798 799 if( $this->iType == POLAR_180 ) { 800 $pos = $this->img->height - $this->img->bottom_margin; 801 } 802 else { 803 $pos = $this->img->plotheight/2 + $this->img->top_margin; 804 } 805 806 if( !$_csim ) { 807 $this->StrokePlotArea(); 808 } 809 810 $this->iDoClipping = true; 811 812 if( $this->iDoClipping ) { 813 $oldimage = $this->img->CloneCanvasH(); 814 } 815 816 if( !$_csim ) { 817 $this->axis->StrokeGrid($pos); 818 } 819 820 // Stroke all plots for Y1 axis 821 for($i=0; $i < count($this->plots); ++$i) { 822 $this->plots[$i]->Stroke($this->img,$this->scale); 823 } 824 825 826 if( $this->iDoClipping ) { 827 // Clipping only supports graphs at 0 and 90 degrees 828 if( $this->img->a == 0 ) { 829 $this->img->CopyCanvasH($oldimage,$this->img->img, 830 $this->img->left_margin,$this->img->top_margin, 831 $this->img->left_margin,$this->img->top_margin, 832 $this->img->plotwidth+1,$this->img->plotheight+1); 833 } 834 elseif( $this->img->a == 90 ) { 835 $adj1 = round(($this->img->height - $this->img->width)/2); 836 $adj2 = round(($this->img->width - $this->img->height)/2); 837 $lm = $this->img->left_margin; 838 $rm = $this->img->right_margin; 839 $tm = $this->img->top_margin; 840 $bm = $this->img->bottom_margin; 841 $this->img->CopyCanvasH($oldimage,$this->img->img, 842 $adj2 + round(($lm-$rm+$tm+$bm)/2), 843 $adj1 + round(($tm-$bm+$lm+$rm)/2), 844 $adj2 + round(($lm-$rm+$tm+$bm)/2), 845 $adj1 + round(($tm-$bm+$lm+$rm)/2), 846 $this->img->plotheight+1, 847 $this->img->plotwidth+1); 848 } 849 $this->img->Destroy(); 850 $this->img->SetCanvasH($oldimage); 851 } 852 853 if( !$_csim ) { 854 $this->axis->Stroke($pos); 855 $this->axis->StrokeAngleLabels($pos,$this->iType); 856 } 857 858 if( !$_csim ) { 859 $this->StrokePlotBox(); 860 $this->footer->Stroke($this->img); 861 862 // The titles and legends never gets rotated so make sure 863 // that the angle is 0 before stroking them 864 $aa = $this->img->SetAngle(0); 865 $this->StrokeTitles(); 866 } 867 868 for($i=0; $i < count($this->plots) ; ++$i ) { 869 $this->plots[$i]->Legend($this); 870 } 871 872 $this->legend->Stroke($this->img); 873 874 if( !$_csim ) { 875 876 $this->StrokeTexts(); 877 $this->img->SetAngle($aa); 878 879 // Draw an outline around the image map 880 if(_JPG_DEBUG) 881 $this->DisplayClientSideaImageMapAreas(); 882 883 // If the filename is given as the special "__handle" 884 // then the image handler is returned and the image is NOT 885 // streamed back 886 if( $aStrokeFileName == _IMG_HANDLER ) { 887 return $this->img->img; 888 } 889 else { 890 // Finally stream the generated picture 891 $this->cache->PutAndStream($this->img,$this->cache_name,$this->inline,$aStrokeFileName); 892 } 893 } 836 894 } 837 895 } -
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 -
trunk/client/modules/Elezioni/grafici/jpgraph_regstat.php
r267 r284 1 <?php 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_REGSTAT.PHP4 // Description: Regression and statistical analysis helper classes5 // Created:2002-12-016 // Ver: $Id: jpgraph_regstat.php 781 2006-10-08 08:07:47Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */3 // File: JPGRAPH_REGSTAT.PHP 4 // Description: Regression and statistical analysis helper classes 5 // Created: 2002-12-01 6 // Ver: $Id: jpgraph_regstat.php 1131 2009-03-11 20:08:24Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 //------------------------------------------------------------------------ … … 19 19 20 20 private $xdata,$ydata; // Data vectors 21 private $y2; // 2:nd derivate of ydata21 private $y2; // 2:nd derivate of ydata 22 22 private $n=0; 23 23 24 function Spline($xdata,$ydata) {25 26 27 28 29 30 31 32 33 //('Spline: Number of X and Y coordinates must be the same');34 35 36 37 38 39 40 41 42 43 44 45 46 //('Invalid input data for spline. Two or more consecutive input X-values are equal. Each input X-value must differ since from a mathematical point of view it must be a one-to-one mapping, i.e. each X-value must correspond to exactly one Y-value.');47 48 49 50 51 $delta[$i] = ($ydata[$i+1]-$ydata[$i])/($xdata[$i+1]-$xdata[$i]) - 52 53 54 55 56 57 58 59 24 function __construct($xdata,$ydata) { 25 $this->y2 = array(); 26 $this->xdata = $xdata; 27 $this->ydata = $ydata; 28 29 $n = count($ydata); 30 $this->n = $n; 31 if( $this->n !== count($xdata) ) { 32 JpGraphError::RaiseL(19001); 33 //('Spline: Number of X and Y coordinates must be the same'); 34 } 35 36 // Natural spline 2:derivate == 0 at endpoints 37 $this->y2[0] = 0.0; 38 $this->y2[$n-1] = 0.0; 39 $delta[0] = 0.0; 40 41 // Calculate 2:nd derivate 42 for($i=1; $i < $n-1; ++$i) { 43 $d = ($xdata[$i+1]-$xdata[$i-1]); 44 if( $d == 0 ) { 45 JpGraphError::RaiseL(19002); 46 //('Invalid input data for spline. Two or more consecutive input X-values are equal. Each input X-value must differ since from a mathematical point of view it must be a one-to-one mapping, i.e. each X-value must correspond to exactly one Y-value.'); 47 } 48 $s = ($xdata[$i]-$xdata[$i-1])/$d; 49 $p = $s*$this->y2[$i-1]+2.0; 50 $this->y2[$i] = ($s-1.0)/$p; 51 $delta[$i] = ($ydata[$i+1]-$ydata[$i])/($xdata[$i+1]-$xdata[$i]) - 52 ($ydata[$i]-$ydata[$i-1])/($xdata[$i]-$xdata[$i-1]); 53 $delta[$i] = (6.0*$delta[$i]/($xdata[$i+1]-$xdata[$i-1])-$s*$delta[$i-1])/$p; 54 } 55 56 // Backward substitution 57 for( $j=$n-2; $j >= 0; --$j ) { 58 $this->y2[$j] = $this->y2[$j]*$this->y2[$j+1] + $delta[$j]; 59 } 60 60 } 61 61 62 62 // Return the two new data vectors 63 63 function Get($num=50) { 64 65 66 67 68 69 70 71 72 73 74 64 $n = $this->n ; 65 $step = ($this->xdata[$n-1]-$this->xdata[0]) / ($num-1); 66 $xnew=array(); 67 $ynew=array(); 68 $xnew[0] = $this->xdata[0]; 69 $ynew[0] = $this->ydata[0]; 70 for( $j=1; $j < $num; ++$j ) { 71 $xnew[$j] = $xnew[0]+$j*$step; 72 $ynew[$j] = $this->Interpolate($xnew[$j]); 73 } 74 return array($xnew,$ynew); 75 75 } 76 76 … … 78 78 function Interpolate($xpoint) { 79 79 80 81 82 83 84 85 86 if( $this->xdata[$k] > $xpoint ) 87 88 else 89 90 } 91 92 93 94 95 96 97 //('Invalid input data for spline. Two or more consecutive input X-values are equal. Each input X-value must differ since from a mathematical point of view it must be a one-to-one mapping, i.e. each X-value must correspond to exactly one Y-value.');98 99 100 101 102 103 104 80 $max = $this->n-1; 81 $min = 0; 82 83 // Binary search to find interval 84 while( $max-$min > 1 ) { 85 $k = ($max+$min) / 2; 86 if( $this->xdata[$k] > $xpoint ) 87 $max=$k; 88 else 89 $min=$k; 90 } 91 92 // Each interval is interpolated by a 3:degree polynom function 93 $h = $this->xdata[$max]-$this->xdata[$min]; 94 95 if( $h == 0 ) { 96 JpGraphError::RaiseL(19002); 97 //('Invalid input data for spline. Two or more consecutive input X-values are equal. Each input X-value must differ since from a mathematical point of view it must be a one-to-one mapping, i.e. each X-value must correspond to exactly one Y-value.'); 98 } 99 100 101 $a = ($this->xdata[$max]-$xpoint)/$h; 102 $b = ($xpoint-$this->xdata[$min])/$h; 103 return $a*$this->ydata[$min]+$b*$this->ydata[$max]+ 104 (($a*$a*$a-$a)*$this->y2[$min]+($b*$b*$b-$b)*$this->y2[$max])*($h*$h)/6.0; 105 105 } 106 106 } … … 111 111 //------------------------------------------------------------------------ 112 112 class Bezier { 113 /**114 * @author Thomas Despoix, openXtrem company115 * @license released under QPL116 * @abstract Bezier interoplated point generation,117 * computed from control points data sets, based on Paul Bourke algorithm :118 * http://astronomy.swin.edu.au/~pbourke/curves/bezier/119 */113 /** 114 * @author Thomas Despoix, openXtrem company 115 * @license released under QPL 116 * @abstract Bezier interoplated point generation, 117 * computed from control points data sets, based on Paul Bourke algorithm : 118 * http://local.wasp.uwa.edu.au/~pbourke/geometry/bezier/index2.html 119 */ 120 120 private $datax = array(); 121 121 private $datay = array(); 122 122 private $n=0; 123 124 function Bezier($datax, $datay, $attraction_factor = 1) { 125 // Adding control point multiple time will raise their attraction power over the curve 126 $this->n = count($datax); 127 if( $this->n !== count($datay) ) { 128 JpGraphError::RaiseL(19003); 129 //('Bezier: Number of X and Y coordinates must be the same'); 130 } 131 $idx=0; 132 foreach($datax as $datumx) { 133 for ($i = 0; $i < $attraction_factor; $i++) { 134 $this->datax[$idx++] = $datumx; 135 } 136 } 137 $idx=0; 138 foreach($datay as $datumy) { 139 for ($i = 0; $i < $attraction_factor; $i++) { 140 $this->datay[$idx++] = $datumy; 141 } 142 } 143 $this->n *= $attraction_factor; 144 } 145 123 124 function __construct($datax, $datay, $attraction_factor = 1) { 125 // Adding control point multiple time will raise their attraction power over the curve 126 $this->n = count($datax); 127 if( $this->n !== count($datay) ) { 128 JpGraphError::RaiseL(19003); 129 //('Bezier: Number of X and Y coordinates must be the same'); 130 } 131 $idx=0; 132 foreach($datax as $datumx) { 133 for ($i = 0; $i < $attraction_factor; $i++) { 134 $this->datax[$idx++] = $datumx; 135 } 136 } 137 $idx=0; 138 foreach($datay as $datumy) { 139 for ($i = 0; $i < $attraction_factor; $i++) { 140 $this->datay[$idx++] = $datumy; 141 } 142 } 143 $this->n *= $attraction_factor; 144 } 145 146 /** 147 * Return a set of data points that specifies the bezier curve with $steps points 148 * @param $steps Number of new points to return 149 * @return array($datax, $datay) 150 */ 146 151 function Get($steps) { 147 $datax = array(); 148 $datay = array(); 149 for ($i = 0; $i < $steps; $i++) { 150 list($datumx, $datumy) = $this->GetPoint((double) $i / (double) $steps); 151 $datax[] = $datumx; 152 $datay[] = $datumy; 153 } 154 155 $datax[] = end($this->datax); 156 $datay[] = end($this->datay); 157 158 return array($datax, $datay); 159 } 160 152 $datax = array(); 153 $datay = array(); 154 for ($i = 0; $i < $steps; $i++) { 155 list($datumx, $datumy) = $this->GetPoint((double) $i / (double) $steps); 156 $datax[$i] = $datumx; 157 $datay[$i] = $datumy; 158 } 159 160 $datax[] = end($this->datax); 161 $datay[] = end($this->datay); 162 163 return array($datax, $datay); 164 } 165 166 /** 167 * Return one point on the bezier curve. $mu is the position on the curve where $mu is in the 168 * range 0 $mu < 1 where 0 is tha start point and 1 is the end point. Note that every newly computed 169 * point depends on all the existing points 170 * 171 * @param $mu Position on the bezier curve 172 * @return array($x, $y) 173 */ 161 174 function GetPoint($mu) { 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 175 $n = $this->n - 1; 176 $k = 0; 177 $kn = 0; 178 $nn = 0; 179 $nkn = 0; 180 $blend = 0.0; 181 $newx = 0.0; 182 $newy = 0.0; 183 184 $muk = 1.0; 185 $munk = (double) pow(1-$mu,(double) $n); 186 187 for ($k = 0; $k <= $n; $k++) { 188 $nn = $n; 189 $kn = $k; 190 $nkn = $n - $k; 191 $blend = $muk * $munk; 192 $muk *= $mu; 193 $munk /= (1-$mu); 194 while ($nn >= 1) { 195 $blend *= $nn; 196 $nn--; 197 if ($kn > 1) { 198 $blend /= (double) $kn; 199 $kn--; 200 } 201 if ($nkn > 1) { 202 $blend /= (double) $nkn; 203 $nkn--; 204 } 205 } 206 $newx += $this->datax[$k] * $blend; 207 $newy += $this->datay[$k] * $blend; 208 } 209 210 return array($newx, $newy); 198 211 } 199 212 } -
trunk/client/modules/Elezioni/grafici/jpgraph_rgb.inc.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: Class to handle RGb color space specification and5 // 6 // Created: 7 // Ver: $Id: jpgraph_rgb.inc.php 1049 2008-08-01 19:58:07Z ljp $3 // File: JPGRAPH_RGB.INC.PHP 4 // Description: Class to handle RGb color space specification and 5 // named colors 6 // Created: 2001-01-08 (Refactored to separate file 2008-08-01) 7 // Ver: $Id: jpgraph_rgb.inc.php 1893 2009-10-02 23:15:25Z ljp $ 8 8 // 9 // Copyright (c) A ditus Consulting. All rights reserved.9 // Copyright (c) Asial Corporation. All rights reserved. 10 10 //======================================================================== 11 11 12 12 13 / /===================================================13 /*=================================================== 14 14 // CLASS RGB 15 15 // Description: Color definitions as RGB triples 16 16 //=================================================== 17 */ 18 17 19 class RGB { 18 public $rgb_table; 20 public $rgb_table; 19 21 public $img; 20 22 21 function RGB($aImg=null) { 22 $this->img = $aImg; 23 24 // Conversion array between color names and RGB 25 $this->rgb_table = array( 26 "aqua"=> array(0,255,255), 27 "lime"=> array(0,255,0), 28 "teal"=> array(0,128,128), 29 "whitesmoke"=>array(245,245,245), 30 "gainsboro"=>array(220,220,220), 31 "oldlace"=>array(253,245,230), 32 "linen"=>array(250,240,230), 33 "antiquewhite"=>array(250,235,215), 34 "papayawhip"=>array(255,239,213), 35 "blanchedalmond"=>array(255,235,205), 36 "bisque"=>array(255,228,196), 37 "peachpuff"=>array(255,218,185), 38 "navajowhite"=>array(255,222,173), 39 "moccasin"=>array(255,228,181), 40 "cornsilk"=>array(255,248,220), 41 "ivory"=>array(255,255,240), 42 "lemonchiffon"=>array(255,250,205), 43 "seashell"=>array(255,245,238), 44 "mintcream"=>array(245,255,250), 45 "azure"=>array(240,255,255), 46 "aliceblue"=>array(240,248,255), 47 "lavender"=>array(230,230,250), 48 "lavenderblush"=>array(255,240,245), 49 "mistyrose"=>array(255,228,225), 50 "white"=>array(255,255,255), 51 "black"=>array(0,0,0), 52 "darkslategray"=>array(47,79,79), 53 "dimgray"=>array(105,105,105), 54 "slategray"=>array(112,128,144), 55 "lightslategray"=>array(119,136,153), 56 "gray"=>array(190,190,190), 57 "lightgray"=>array(211,211,211), 58 "midnightblue"=>array(25,25,112), 59 "navy"=>array(0,0,128), 60 "cornflowerblue"=>array(100,149,237), 61 "darkslateblue"=>array(72,61,139), 62 "slateblue"=>array(106,90,205), 63 "mediumslateblue"=>array(123,104,238), 64 "lightslateblue"=>array(132,112,255), 65 "mediumblue"=>array(0,0,205), 66 "royalblue"=>array(65,105,225), 67 "blue"=>array(0,0,255), 68 "dodgerblue"=>array(30,144,255), 69 "deepskyblue"=>array(0,191,255), 70 "skyblue"=>array(135,206,235), 71 "lightskyblue"=>array(135,206,250), 72 "steelblue"=>array(70,130,180), 73 "lightred"=>array(211,167,168), 74 "lightsteelblue"=>array(176,196,222), 75 "lightblue"=>array(173,216,230), 76 "powderblue"=>array(176,224,230), 77 "paleturquoise"=>array(175,238,238), 78 "darkturquoise"=>array(0,206,209), 79 "mediumturquoise"=>array(72,209,204), 80 "turquoise"=>array(64,224,208), 81 "cyan"=>array(0,255,255), 82 "lightcyan"=>array(224,255,255), 83 "cadetblue"=>array(95,158,160), 84 "mediumaquamarine"=>array(102,205,170), 85 "aquamarine"=>array(127,255,212), 86 "darkgreen"=>array(0,100,0), 87 "darkolivegreen"=>array(85,107,47), 88 "darkseagreen"=>array(143,188,143), 89 "seagreen"=>array(46,139,87), 90 "mediumseagreen"=>array(60,179,113), 91 "lightseagreen"=>array(32,178,170), 92 "palegreen"=>array(152,251,152), 93 "springgreen"=>array(0,255,127), 94 "lawngreen"=>array(124,252,0), 95 "green"=>array(0,255,0), 96 "chartreuse"=>array(127,255,0), 97 "mediumspringgreen"=>array(0,250,154), 98 "greenyellow"=>array(173,255,47), 99 "limegreen"=>array(50,205,50), 100 "yellowgreen"=>array(154,205,50), 101 "forestgreen"=>array(34,139,34), 102 "olivedrab"=>array(107,142,35), 103 "darkkhaki"=>array(189,183,107), 104 "khaki"=>array(240,230,140), 105 "palegoldenrod"=>array(238,232,170), 106 "lightgoldenrodyellow"=>array(250,250,210), 107 "lightyellow"=>array(255,255,200), 108 "yellow"=>array(255,255,0), 109 "gold"=>array(255,215,0), 110 "lightgoldenrod"=>array(238,221,130), 111 "goldenrod"=>array(218,165,32), 112 "darkgoldenrod"=>array(184,134,11), 113 "rosybrown"=>array(188,143,143), 114 "indianred"=>array(205,92,92), 115 "saddlebrown"=>array(139,69,19), 116 "sienna"=>array(160,82,45), 117 "peru"=>array(205,133,63), 118 "burlywood"=>array(222,184,135), 119 "beige"=>array(245,245,220), 120 "wheat"=>array(245,222,179), 121 "sandybrown"=>array(244,164,96), 122 "tan"=>array(210,180,140), 123 "chocolate"=>array(210,105,30), 124 "firebrick"=>array(178,34,34), 125 "brown"=>array(165,42,42), 126 "darksalmon"=>array(233,150,122), 127 "salmon"=>array(250,128,114), 128 "lightsalmon"=>array(255,160,122), 129 "orange"=>array(255,165,0), 130 "darkorange"=>array(255,140,0), 131 "coral"=>array(255,127,80), 132 "lightcoral"=>array(240,128,128), 133 "tomato"=>array(255,99,71), 134 "orangered"=>array(255,69,0), 135 "red"=>array(255,0,0), 136 "hotpink"=>array(255,105,180), 137 "deeppink"=>array(255,20,147), 138 "pink"=>array(255,192,203), 139 "lightpink"=>array(255,182,193), 140 "palevioletred"=>array(219,112,147), 141 "maroon"=>array(176,48,96), 142 "mediumvioletred"=>array(199,21,133), 143 "violetred"=>array(208,32,144), 144 "magenta"=>array(255,0,255), 145 "violet"=>array(238,130,238), 146 "plum"=>array(221,160,221), 147 "orchid"=>array(218,112,214), 148 "mediumorchid"=>array(186,85,211), 149 "darkorchid"=>array(153,50,204), 150 "darkviolet"=>array(148,0,211), 151 "blueviolet"=>array(138,43,226), 152 "purple"=>array(160,32,240), 153 "mediumpurple"=>array(147,112,219), 154 "thistle"=>array(216,191,216), 155 "snow1"=>array(255,250,250), 156 "snow2"=>array(238,233,233), 157 "snow3"=>array(205,201,201), 158 "snow4"=>array(139,137,137), 159 "seashell1"=>array(255,245,238), 160 "seashell2"=>array(238,229,222), 161 "seashell3"=>array(205,197,191), 162 "seashell4"=>array(139,134,130), 163 "AntiqueWhite1"=>array(255,239,219), 164 "AntiqueWhite2"=>array(238,223,204), 165 "AntiqueWhite3"=>array(205,192,176), 166 "AntiqueWhite4"=>array(139,131,120), 167 "bisque1"=>array(255,228,196), 168 "bisque2"=>array(238,213,183), 169 "bisque3"=>array(205,183,158), 170 "bisque4"=>array(139,125,107), 171 "peachPuff1"=>array(255,218,185), 172 "peachpuff2"=>array(238,203,173), 173 "peachpuff3"=>array(205,175,149), 174 "peachpuff4"=>array(139,119,101), 175 "navajowhite1"=>array(255,222,173), 176 "navajowhite2"=>array(238,207,161), 177 "navajowhite3"=>array(205,179,139), 178 "navajowhite4"=>array(139,121,94), 179 "lemonchiffon1"=>array(255,250,205), 180 "lemonchiffon2"=>array(238,233,191), 181 "lemonchiffon3"=>array(205,201,165), 182 "lemonchiffon4"=>array(139,137,112), 183 "ivory1"=>array(255,255,240), 184 "ivory2"=>array(238,238,224), 185 "ivory3"=>array(205,205,193), 186 "ivory4"=>array(139,139,131), 187 "honeydew"=>array(193,205,193), 188 "lavenderblush1"=>array(255,240,245), 189 "lavenderblush2"=>array(238,224,229), 190 "lavenderblush3"=>array(205,193,197), 191 "lavenderblush4"=>array(139,131,134), 192 "mistyrose1"=>array(255,228,225), 193 "mistyrose2"=>array(238,213,210), 194 "mistyrose3"=>array(205,183,181), 195 "mistyrose4"=>array(139,125,123), 196 "azure1"=>array(240,255,255), 197 "azure2"=>array(224,238,238), 198 "azure3"=>array(193,205,205), 199 "azure4"=>array(131,139,139), 200 "slateblue1"=>array(131,111,255), 201 "slateblue2"=>array(122,103,238), 202 "slateblue3"=>array(105,89,205), 203 "slateblue4"=>array(71,60,139), 204 "royalblue1"=>array(72,118,255), 205 "royalblue2"=>array(67,110,238), 206 "royalblue3"=>array(58,95,205), 207 "royalblue4"=>array(39,64,139), 208 "dodgerblue1"=>array(30,144,255), 209 "dodgerblue2"=>array(28,134,238), 210 "dodgerblue3"=>array(24,116,205), 211 "dodgerblue4"=>array(16,78,139), 212 "steelblue1"=>array(99,184,255), 213 "steelblue2"=>array(92,172,238), 214 "steelblue3"=>array(79,148,205), 215 "steelblue4"=>array(54,100,139), 216 "deepskyblue1"=>array(0,191,255), 217 "deepskyblue2"=>array(0,178,238), 218 "deepskyblue3"=>array(0,154,205), 219 "deepskyblue4"=>array(0,104,139), 220 "skyblue1"=>array(135,206,255), 221 "skyblue2"=>array(126,192,238), 222 "skyblue3"=>array(108,166,205), 223 "skyblue4"=>array(74,112,139), 224 "lightskyblue1"=>array(176,226,255), 225 "lightskyblue2"=>array(164,211,238), 226 "lightskyblue3"=>array(141,182,205), 227 "lightskyblue4"=>array(96,123,139), 228 "slategray1"=>array(198,226,255), 229 "slategray2"=>array(185,211,238), 230 "slategray3"=>array(159,182,205), 231 "slategray4"=>array(108,123,139), 232 "lightsteelblue1"=>array(202,225,255), 233 "lightsteelblue2"=>array(188,210,238), 234 "lightsteelblue3"=>array(162,181,205), 235 "lightsteelblue4"=>array(110,123,139), 236 "lightblue1"=>array(191,239,255), 237 "lightblue2"=>array(178,223,238), 238 "lightblue3"=>array(154,192,205), 239 "lightblue4"=>array(104,131,139), 240 "lightcyan1"=>array(224,255,255), 241 "lightcyan2"=>array(209,238,238), 242 "lightcyan3"=>array(180,205,205), 243 "lightcyan4"=>array(122,139,139), 244 "paleturquoise1"=>array(187,255,255), 245 "paleturquoise2"=>array(174,238,238), 246 "paleturquoise3"=>array(150,205,205), 247 "paleturquoise4"=>array(102,139,139), 248 "cadetblue1"=>array(152,245,255), 249 "cadetblue2"=>array(142,229,238), 250 "cadetblue3"=>array(122,197,205), 251 "cadetblue4"=>array(83,134,139), 252 "turquoise1"=>array(0,245,255), 253 "turquoise2"=>array(0,229,238), 254 "turquoise3"=>array(0,197,205), 255 "turquoise4"=>array(0,134,139), 256 "cyan1"=>array(0,255,255), 257 "cyan2"=>array(0,238,238), 258 "cyan3"=>array(0,205,205), 259 "cyan4"=>array(0,139,139), 260 "darkslategray1"=>array(151,255,255), 261 "darkslategray2"=>array(141,238,238), 262 "darkslategray3"=>array(121,205,205), 263 "darkslategray4"=>array(82,139,139), 264 "aquamarine1"=>array(127,255,212), 265 "aquamarine2"=>array(118,238,198), 266 "aquamarine3"=>array(102,205,170), 267 "aquamarine4"=>array(69,139,116), 268 "darkseagreen1"=>array(193,255,193), 269 "darkseagreen2"=>array(180,238,180), 270 "darkseagreen3"=>array(155,205,155), 271 "darkseagreen4"=>array(105,139,105), 272 "seagreen1"=>array(84,255,159), 273 "seagreen2"=>array(78,238,148), 274 "seagreen3"=>array(67,205,128), 275 "seagreen4"=>array(46,139,87), 276 "palegreen1"=>array(154,255,154), 277 "palegreen2"=>array(144,238,144), 278 "palegreen3"=>array(124,205,124), 279 "palegreen4"=>array(84,139,84), 280 "springgreen1"=>array(0,255,127), 281 "springgreen2"=>array(0,238,118), 282 "springgreen3"=>array(0,205,102), 283 "springgreen4"=>array(0,139,69), 284 "chartreuse1"=>array(127,255,0), 285 "chartreuse2"=>array(118,238,0), 286 "chartreuse3"=>array(102,205,0), 287 "chartreuse4"=>array(69,139,0), 288 "olivedrab1"=>array(192,255,62), 289 "olivedrab2"=>array(179,238,58), 290 "olivedrab3"=>array(154,205,50), 291 "olivedrab4"=>array(105,139,34), 292 "darkolivegreen1"=>array(202,255,112), 293 "darkolivegreen2"=>array(188,238,104), 294 "darkolivegreen3"=>array(162,205,90), 295 "darkolivegreen4"=>array(110,139,61), 296 "khaki1"=>array(255,246,143), 297 "khaki2"=>array(238,230,133), 298 "khaki3"=>array(205,198,115), 299 "khaki4"=>array(139,134,78), 300 "lightgoldenrod1"=>array(255,236,139), 301 "lightgoldenrod2"=>array(238,220,130), 302 "lightgoldenrod3"=>array(205,190,112), 303 "lightgoldenrod4"=>array(139,129,76), 304 "yellow1"=>array(255,255,0), 305 "yellow2"=>array(238,238,0), 306 "yellow3"=>array(205,205,0), 307 "yellow4"=>array(139,139,0), 308 "gold1"=>array(255,215,0), 309 "gold2"=>array(238,201,0), 310 "gold3"=>array(205,173,0), 311 "gold4"=>array(139,117,0), 312 "goldenrod1"=>array(255,193,37), 313 "goldenrod2"=>array(238,180,34), 314 "goldenrod3"=>array(205,155,29), 315 "goldenrod4"=>array(139,105,20), 316 "darkgoldenrod1"=>array(255,185,15), 317 "darkgoldenrod2"=>array(238,173,14), 318 "darkgoldenrod3"=>array(205,149,12), 319 "darkgoldenrod4"=>array(139,101,8), 320 "rosybrown1"=>array(255,193,193), 321 "rosybrown2"=>array(238,180,180), 322 "rosybrown3"=>array(205,155,155), 323 "rosybrown4"=>array(139,105,105), 324 "indianred1"=>array(255,106,106), 325 "indianred2"=>array(238,99,99), 326 "indianred3"=>array(205,85,85), 327 "indianred4"=>array(139,58,58), 328 "sienna1"=>array(255,130,71), 329 "sienna2"=>array(238,121,66), 330 "sienna3"=>array(205,104,57), 331 "sienna4"=>array(139,71,38), 332 "burlywood1"=>array(255,211,155), 333 "burlywood2"=>array(238,197,145), 334 "burlywood3"=>array(205,170,125), 335 "burlywood4"=>array(139,115,85), 336 "wheat1"=>array(255,231,186), 337 "wheat2"=>array(238,216,174), 338 "wheat3"=>array(205,186,150), 339 "wheat4"=>array(139,126,102), 340 "tan1"=>array(255,165,79), 341 "tan2"=>array(238,154,73), 342 "tan3"=>array(205,133,63), 343 "tan4"=>array(139,90,43), 344 "chocolate1"=>array(255,127,36), 345 "chocolate2"=>array(238,118,33), 346 "chocolate3"=>array(205,102,29), 347 "chocolate4"=>array(139,69,19), 348 "firebrick1"=>array(255,48,48), 349 "firebrick2"=>array(238,44,44), 350 "firebrick3"=>array(205,38,38), 351 "firebrick4"=>array(139,26,26), 352 "brown1"=>array(255,64,64), 353 "brown2"=>array(238,59,59), 354 "brown3"=>array(205,51,51), 355 "brown4"=>array(139,35,35), 356 "salmon1"=>array(255,140,105), 357 "salmon2"=>array(238,130,98), 358 "salmon3"=>array(205,112,84), 359 "salmon4"=>array(139,76,57), 360 "lightsalmon1"=>array(255,160,122), 361 "lightsalmon2"=>array(238,149,114), 362 "lightsalmon3"=>array(205,129,98), 363 "lightsalmon4"=>array(139,87,66), 364 "orange1"=>array(255,165,0), 365 "orange2"=>array(238,154,0), 366 "orange3"=>array(205,133,0), 367 "orange4"=>array(139,90,0), 368 "darkorange1"=>array(255,127,0), 369 "darkorange2"=>array(238,118,0), 370 "darkorange3"=>array(205,102,0), 371 "darkorange4"=>array(139,69,0), 372 "coral1"=>array(255,114,86), 373 "coral2"=>array(238,106,80), 374 "coral3"=>array(205,91,69), 375 "coral4"=>array(139,62,47), 376 "tomato1"=>array(255,99,71), 377 "tomato2"=>array(238,92,66), 378 "tomato3"=>array(205,79,57), 379 "tomato4"=>array(139,54,38), 380 "orangered1"=>array(255,69,0), 381 "orangered2"=>array(238,64,0), 382 "orangered3"=>array(205,55,0), 383 "orangered4"=>array(139,37,0), 384 "deeppink1"=>array(255,20,147), 385 "deeppink2"=>array(238,18,137), 386 "deeppink3"=>array(205,16,118), 387 "deeppink4"=>array(139,10,80), 388 "hotpink1"=>array(255,110,180), 389 "hotpink2"=>array(238,106,167), 390 "hotpink3"=>array(205,96,144), 391 "hotpink4"=>array(139,58,98), 392 "pink1"=>array(255,181,197), 393 "pink2"=>array(238,169,184), 394 "pink3"=>array(205,145,158), 395 "pink4"=>array(139,99,108), 396 "lightpink1"=>array(255,174,185), 397 "lightpink2"=>array(238,162,173), 398 "lightpink3"=>array(205,140,149), 399 "lightpink4"=>array(139,95,101), 400 "palevioletred1"=>array(255,130,171), 401 "palevioletred2"=>array(238,121,159), 402 "palevioletred3"=>array(205,104,137), 403 "palevioletred4"=>array(139,71,93), 404 "maroon1"=>array(255,52,179), 405 "maroon2"=>array(238,48,167), 406 "maroon3"=>array(205,41,144), 407 "maroon4"=>array(139,28,98), 408 "violetred1"=>array(255,62,150), 409 "violetred2"=>array(238,58,140), 410 "violetred3"=>array(205,50,120), 411 "violetred4"=>array(139,34,82), 412 "magenta1"=>array(255,0,255), 413 "magenta2"=>array(238,0,238), 414 "magenta3"=>array(205,0,205), 415 "magenta4"=>array(139,0,139), 416 "mediumred"=>array(140,34,34), 417 "orchid1"=>array(255,131,250), 418 "orchid2"=>array(238,122,233), 419 "orchid3"=>array(205,105,201), 420 "orchid4"=>array(139,71,137), 421 "plum1"=>array(255,187,255), 422 "plum2"=>array(238,174,238), 423 "plum3"=>array(205,150,205), 424 "plum4"=>array(139,102,139), 425 "mediumorchid1"=>array(224,102,255), 426 "mediumorchid2"=>array(209,95,238), 427 "mediumorchid3"=>array(180,82,205), 428 "mediumorchid4"=>array(122,55,139), 429 "darkorchid1"=>array(191,62,255), 430 "darkorchid2"=>array(178,58,238), 431 "darkorchid3"=>array(154,50,205), 432 "darkorchid4"=>array(104,34,139), 433 "purple1"=>array(155,48,255), 434 "purple2"=>array(145,44,238), 435 "purple3"=>array(125,38,205), 436 "purple4"=>array(85,26,139), 437 "mediumpurple1"=>array(171,130,255), 438 "mediumpurple2"=>array(159,121,238), 439 "mediumpurple3"=>array(137,104,205), 440 "mediumpurple4"=>array(93,71,139), 441 "thistle1"=>array(255,225,255), 442 "thistle2"=>array(238,210,238), 443 "thistle3"=>array(205,181,205), 444 "thistle4"=>array(139,123,139), 445 "gray1"=>array(10,10,10), 446 "gray2"=>array(40,40,30), 447 "gray3"=>array(70,70,70), 448 "gray4"=>array(100,100,100), 449 "gray5"=>array(130,130,130), 450 "gray6"=>array(160,160,160), 451 "gray7"=>array(190,190,190), 452 "gray8"=>array(210,210,210), 453 "gray9"=>array(240,240,240), 454 "darkgray"=>array(100,100,100), 455 "darkblue"=>array(0,0,139), 456 "darkcyan"=>array(0,139,139), 457 "darkmagenta"=>array(139,0,139), 458 "darkred"=>array(139,0,0), 459 "silver"=>array(192, 192, 192), 460 "eggplant"=>array(144,176,168), 461 "lightgreen"=>array(144,238,144)); 23 function __construct($aImg=null) { 24 $this->img = $aImg; 25 26 // Conversion array between color names and RGB 27 $this->rgb_table = array( 28 'aqua'=> array(0,255,255), 29 'lime'=> array(0,255,0), 30 'teal'=> array(0,128,128), 31 'whitesmoke'=>array(245,245,245), 32 'gainsboro'=>array(220,220,220), 33 'oldlace'=>array(253,245,230), 34 'linen'=>array(250,240,230), 35 'antiquewhite'=>array(250,235,215), 36 'papayawhip'=>array(255,239,213), 37 'blanchedalmond'=>array(255,235,205), 38 'bisque'=>array(255,228,196), 39 'peachpuff'=>array(255,218,185), 40 'navajowhite'=>array(255,222,173), 41 'moccasin'=>array(255,228,181), 42 'cornsilk'=>array(255,248,220), 43 'ivory'=>array(255,255,240), 44 'lemonchiffon'=>array(255,250,205), 45 'seashell'=>array(255,245,238), 46 'mintcream'=>array(245,255,250), 47 'azure'=>array(240,255,255), 48 'aliceblue'=>array(240,248,255), 49 'lavender'=>array(230,230,250), 50 'lavenderblush'=>array(255,240,245), 51 'mistyrose'=>array(255,228,225), 52 'white'=>array(255,255,255), 53 'black'=>array(0,0,0), 54 'darkslategray'=>array(47,79,79), 55 'dimgray'=>array(105,105,105), 56 'slategray'=>array(112,128,144), 57 'lightslategray'=>array(119,136,153), 58 'gray'=>array(190,190,190), 59 'lightgray'=>array(211,211,211), 60 'midnightblue'=>array(25,25,112), 61 'navy'=>array(0,0,128), 62 'indigo'=>array(75,0,130), 63 'electricindigo'=>array(102,0,255), 64 'deepindigo'=>array(138,43,226), 65 'pigmentindigo'=>array(75,0,130), 66 'indigodye'=>array(0,65,106), 67 'cornflowerblue'=>array(100,149,237), 68 'darkslateblue'=>array(72,61,139), 69 'slateblue'=>array(106,90,205), 70 'mediumslateblue'=>array(123,104,238), 71 'lightslateblue'=>array(132,112,255), 72 'mediumblue'=>array(0,0,205), 73 'royalblue'=>array(65,105,225), 74 'blue'=>array(0,0,255), 75 'dodgerblue'=>array(30,144,255), 76 'deepskyblue'=>array(0,191,255), 77 'skyblue'=>array(135,206,235), 78 'lightskyblue'=>array(135,206,250), 79 'steelblue'=>array(70,130,180), 80 'lightred'=>array(211,167,168), 81 'lightsteelblue'=>array(176,196,222), 82 'lightblue'=>array(173,216,230), 83 'powderblue'=>array(176,224,230), 84 'paleturquoise'=>array(175,238,238), 85 'darkturquoise'=>array(0,206,209), 86 'mediumturquoise'=>array(72,209,204), 87 'turquoise'=>array(64,224,208), 88 'cyan'=>array(0,255,255), 89 'lightcyan'=>array(224,255,255), 90 'cadetblue'=>array(95,158,160), 91 'mediumaquamarine'=>array(102,205,170), 92 'aquamarine'=>array(127,255,212), 93 'darkgreen'=>array(0,100,0), 94 'darkolivegreen'=>array(85,107,47), 95 'darkseagreen'=>array(143,188,143), 96 'seagreen'=>array(46,139,87), 97 'mediumseagreen'=>array(60,179,113), 98 'lightseagreen'=>array(32,178,170), 99 'palegreen'=>array(152,251,152), 100 'springgreen'=>array(0,255,127), 101 'lawngreen'=>array(124,252,0), 102 'green'=>array(0,255,0), 103 'chartreuse'=>array(127,255,0), 104 'mediumspringgreen'=>array(0,250,154), 105 'greenyellow'=>array(173,255,47), 106 'limegreen'=>array(50,205,50), 107 'yellowgreen'=>array(154,205,50), 108 'forestgreen'=>array(34,139,34), 109 'olivedrab'=>array(107,142,35), 110 'darkkhaki'=>array(189,183,107), 111 'khaki'=>array(240,230,140), 112 'palegoldenrod'=>array(238,232,170), 113 'lightgoldenrodyellow'=>array(250,250,210), 114 'lightyellow'=>array(255,255,200), 115 'yellow'=>array(255,255,0), 116 'gold'=>array(255,215,0), 117 'lightgoldenrod'=>array(238,221,130), 118 'goldenrod'=>array(218,165,32), 119 'darkgoldenrod'=>array(184,134,11), 120 'rosybrown'=>array(188,143,143), 121 'indianred'=>array(205,92,92), 122 'saddlebrown'=>array(139,69,19), 123 'sienna'=>array(160,82,45), 124 'peru'=>array(205,133,63), 125 'burlywood'=>array(222,184,135), 126 'beige'=>array(245,245,220), 127 'wheat'=>array(245,222,179), 128 'sandybrown'=>array(244,164,96), 129 'tan'=>array(210,180,140), 130 'chocolate'=>array(210,105,30), 131 'firebrick'=>array(178,34,34), 132 'brown'=>array(165,42,42), 133 'darksalmon'=>array(233,150,122), 134 'salmon'=>array(250,128,114), 135 'lightsalmon'=>array(255,160,122), 136 'orange'=>array(255,165,0), 137 'darkorange'=>array(255,140,0), 138 'coral'=>array(255,127,80), 139 'lightcoral'=>array(240,128,128), 140 'tomato'=>array(255,99,71), 141 'orangered'=>array(255,69,0), 142 'red'=>array(255,0,0), 143 'hotpink'=>array(255,105,180), 144 'deeppink'=>array(255,20,147), 145 'pink'=>array(255,192,203), 146 'lightpink'=>array(255,182,193), 147 'palevioletred'=>array(219,112,147), 148 'maroon'=>array(176,48,96), 149 'mediumvioletred'=>array(199,21,133), 150 'violetred'=>array(208,32,144), 151 'magenta'=>array(255,0,255), 152 'violet'=>array(238,130,238), 153 'plum'=>array(221,160,221), 154 'orchid'=>array(218,112,214), 155 'mediumorchid'=>array(186,85,211), 156 'darkorchid'=>array(153,50,204), 157 'darkviolet'=>array(148,0,211), 158 'blueviolet'=>array(138,43,226), 159 'purple'=>array(160,32,240), 160 'mediumpurple'=>array(147,112,219), 161 'thistle'=>array(216,191,216), 162 'snow1'=>array(255,250,250), 163 'snow2'=>array(238,233,233), 164 'snow3'=>array(205,201,201), 165 'snow4'=>array(139,137,137), 166 'seashell1'=>array(255,245,238), 167 'seashell2'=>array(238,229,222), 168 'seashell3'=>array(205,197,191), 169 'seashell4'=>array(139,134,130), 170 'AntiqueWhite1'=>array(255,239,219), 171 'AntiqueWhite2'=>array(238,223,204), 172 'AntiqueWhite3'=>array(205,192,176), 173 'AntiqueWhite4'=>array(139,131,120), 174 'bisque1'=>array(255,228,196), 175 'bisque2'=>array(238,213,183), 176 'bisque3'=>array(205,183,158), 177 'bisque4'=>array(139,125,107), 178 'peachPuff1'=>array(255,218,185), 179 'peachpuff2'=>array(238,203,173), 180 'peachpuff3'=>array(205,175,149), 181 'peachpuff4'=>array(139,119,101), 182 'navajowhite1'=>array(255,222,173), 183 'navajowhite2'=>array(238,207,161), 184 'navajowhite3'=>array(205,179,139), 185 'navajowhite4'=>array(139,121,94), 186 'lemonchiffon1'=>array(255,250,205), 187 'lemonchiffon2'=>array(238,233,191), 188 'lemonchiffon3'=>array(205,201,165), 189 'lemonchiffon4'=>array(139,137,112), 190 'ivory1'=>array(255,255,240), 191 'ivory2'=>array(238,238,224), 192 'ivory3'=>array(205,205,193), 193 'ivory4'=>array(139,139,131), 194 'honeydew'=>array(193,205,193), 195 'lavenderblush1'=>array(255,240,245), 196 'lavenderblush2'=>array(238,224,229), 197 'lavenderblush3'=>array(205,193,197), 198 'lavenderblush4'=>array(139,131,134), 199 'mistyrose1'=>array(255,228,225), 200 'mistyrose2'=>array(238,213,210), 201 'mistyrose3'=>array(205,183,181), 202 'mistyrose4'=>array(139,125,123), 203 'azure1'=>array(240,255,255), 204 'azure2'=>array(224,238,238), 205 'azure3'=>array(193,205,205), 206 'azure4'=>array(131,139,139), 207 'slateblue1'=>array(131,111,255), 208 'slateblue2'=>array(122,103,238), 209 'slateblue3'=>array(105,89,205), 210 'slateblue4'=>array(71,60,139), 211 'royalblue1'=>array(72,118,255), 212 'royalblue2'=>array(67,110,238), 213 'royalblue3'=>array(58,95,205), 214 'royalblue4'=>array(39,64,139), 215 'dodgerblue1'=>array(30,144,255), 216 'dodgerblue2'=>array(28,134,238), 217 'dodgerblue3'=>array(24,116,205), 218 'dodgerblue4'=>array(16,78,139), 219 'steelblue1'=>array(99,184,255), 220 'steelblue2'=>array(92,172,238), 221 'steelblue3'=>array(79,148,205), 222 'steelblue4'=>array(54,100,139), 223 'deepskyblue1'=>array(0,191,255), 224 'deepskyblue2'=>array(0,178,238), 225 'deepskyblue3'=>array(0,154,205), 226 'deepskyblue4'=>array(0,104,139), 227 'skyblue1'=>array(135,206,255), 228 'skyblue2'=>array(126,192,238), 229 'skyblue3'=>array(108,166,205), 230 'skyblue4'=>array(74,112,139), 231 'lightskyblue1'=>array(176,226,255), 232 'lightskyblue2'=>array(164,211,238), 233 'lightskyblue3'=>array(141,182,205), 234 'lightskyblue4'=>array(96,123,139), 235 'slategray1'=>array(198,226,255), 236 'slategray2'=>array(185,211,238), 237 'slategray3'=>array(159,182,205), 238 'slategray4'=>array(108,123,139), 239 'lightsteelblue1'=>array(202,225,255), 240 'lightsteelblue2'=>array(188,210,238), 241 'lightsteelblue3'=>array(162,181,205), 242 'lightsteelblue4'=>array(110,123,139), 243 'lightblue1'=>array(191,239,255), 244 'lightblue2'=>array(178,223,238), 245 'lightblue3'=>array(154,192,205), 246 'lightblue4'=>array(104,131,139), 247 'lightcyan1'=>array(224,255,255), 248 'lightcyan2'=>array(209,238,238), 249 'lightcyan3'=>array(180,205,205), 250 'lightcyan4'=>array(122,139,139), 251 'paleturquoise1'=>array(187,255,255), 252 'paleturquoise2'=>array(174,238,238), 253 'paleturquoise3'=>array(150,205,205), 254 'paleturquoise4'=>array(102,139,139), 255 'cadetblue1'=>array(152,245,255), 256 'cadetblue2'=>array(142,229,238), 257 'cadetblue3'=>array(122,197,205), 258 'cadetblue4'=>array(83,134,139), 259 'turquoise1'=>array(0,245,255), 260 'turquoise2'=>array(0,229,238), 261 'turquoise3'=>array(0,197,205), 262 'turquoise4'=>array(0,134,139), 263 'cyan1'=>array(0,255,255), 264 'cyan2'=>array(0,238,238), 265 'cyan3'=>array(0,205,205), 266 'cyan4'=>array(0,139,139), 267 'darkslategray1'=>array(151,255,255), 268 'darkslategray2'=>array(141,238,238), 269 'darkslategray3'=>array(121,205,205), 270 'darkslategray4'=>array(82,139,139), 271 'aquamarine1'=>array(127,255,212), 272 'aquamarine2'=>array(118,238,198), 273 'aquamarine3'=>array(102,205,170), 274 'aquamarine4'=>array(69,139,116), 275 'darkseagreen1'=>array(193,255,193), 276 'darkseagreen2'=>array(180,238,180), 277 'darkseagreen3'=>array(155,205,155), 278 'darkseagreen4'=>array(105,139,105), 279 'seagreen1'=>array(84,255,159), 280 'seagreen2'=>array(78,238,148), 281 'seagreen3'=>array(67,205,128), 282 'seagreen4'=>array(46,139,87), 283 'palegreen1'=>array(154,255,154), 284 'palegreen2'=>array(144,238,144), 285 'palegreen3'=>array(124,205,124), 286 'palegreen4'=>array(84,139,84), 287 'springgreen1'=>array(0,255,127), 288 'springgreen2'=>array(0,238,118), 289 'springgreen3'=>array(0,205,102), 290 'springgreen4'=>array(0,139,69), 291 'chartreuse1'=>array(127,255,0), 292 'chartreuse2'=>array(118,238,0), 293 'chartreuse3'=>array(102,205,0), 294 'chartreuse4'=>array(69,139,0), 295 'olivedrab1'=>array(192,255,62), 296 'olivedrab2'=>array(179,238,58), 297 'olivedrab3'=>array(154,205,50), 298 'olivedrab4'=>array(105,139,34), 299 'darkolivegreen1'=>array(202,255,112), 300 'darkolivegreen2'=>array(188,238,104), 301 'darkolivegreen3'=>array(162,205,90), 302 'darkolivegreen4'=>array(110,139,61), 303 'khaki1'=>array(255,246,143), 304 'khaki2'=>array(238,230,133), 305 'khaki3'=>array(205,198,115), 306 'khaki4'=>array(139,134,78), 307 'lightgoldenrod1'=>array(255,236,139), 308 'lightgoldenrod2'=>array(238,220,130), 309 'lightgoldenrod3'=>array(205,190,112), 310 'lightgoldenrod4'=>array(139,129,76), 311 'yellow1'=>array(255,255,0), 312 'yellow2'=>array(238,238,0), 313 'yellow3'=>array(205,205,0), 314 'yellow4'=>array(139,139,0), 315 'gold1'=>array(255,215,0), 316 'gold2'=>array(238,201,0), 317 'gold3'=>array(205,173,0), 318 'gold4'=>array(139,117,0), 319 'goldenrod1'=>array(255,193,37), 320 'goldenrod2'=>array(238,180,34), 321 'goldenrod3'=>array(205,155,29), 322 'goldenrod4'=>array(139,105,20), 323 'darkgoldenrod1'=>array(255,185,15), 324 'darkgoldenrod2'=>array(238,173,14), 325 'darkgoldenrod3'=>array(205,149,12), 326 'darkgoldenrod4'=>array(139,101,8), 327 'rosybrown1'=>array(255,193,193), 328 'rosybrown2'=>array(238,180,180), 329 'rosybrown3'=>array(205,155,155), 330 'rosybrown4'=>array(139,105,105), 331 'indianred1'=>array(255,106,106), 332 'indianred2'=>array(238,99,99), 333 'indianred3'=>array(205,85,85), 334 'indianred4'=>array(139,58,58), 335 'sienna1'=>array(255,130,71), 336 'sienna2'=>array(238,121,66), 337 'sienna3'=>array(205,104,57), 338 'sienna4'=>array(139,71,38), 339 'burlywood1'=>array(255,211,155), 340 'burlywood2'=>array(238,197,145), 341 'burlywood3'=>array(205,170,125), 342 'burlywood4'=>array(139,115,85), 343 'wheat1'=>array(255,231,186), 344 'wheat2'=>array(238,216,174), 345 'wheat3'=>array(205,186,150), 346 'wheat4'=>array(139,126,102), 347 'tan1'=>array(255,165,79), 348 'tan2'=>array(238,154,73), 349 'tan3'=>array(205,133,63), 350 'tan4'=>array(139,90,43), 351 'chocolate1'=>array(255,127,36), 352 'chocolate2'=>array(238,118,33), 353 'chocolate3'=>array(205,102,29), 354 'chocolate4'=>array(139,69,19), 355 'firebrick1'=>array(255,48,48), 356 'firebrick2'=>array(238,44,44), 357 'firebrick3'=>array(205,38,38), 358 'firebrick4'=>array(139,26,26), 359 'brown1'=>array(255,64,64), 360 'brown2'=>array(238,59,59), 361 'brown3'=>array(205,51,51), 362 'brown4'=>array(139,35,35), 363 'salmon1'=>array(255,140,105), 364 'salmon2'=>array(238,130,98), 365 'salmon3'=>array(205,112,84), 366 'salmon4'=>array(139,76,57), 367 'lightsalmon1'=>array(255,160,122), 368 'lightsalmon2'=>array(238,149,114), 369 'lightsalmon3'=>array(205,129,98), 370 'lightsalmon4'=>array(139,87,66), 371 'orange1'=>array(255,165,0), 372 'orange2'=>array(238,154,0), 373 'orange3'=>array(205,133,0), 374 'orange4'=>array(139,90,0), 375 'darkorange1'=>array(255,127,0), 376 'darkorange2'=>array(238,118,0), 377 'darkorange3'=>array(205,102,0), 378 'darkorange4'=>array(139,69,0), 379 'coral1'=>array(255,114,86), 380 'coral2'=>array(238,106,80), 381 'coral3'=>array(205,91,69), 382 'coral4'=>array(139,62,47), 383 'tomato1'=>array(255,99,71), 384 'tomato2'=>array(238,92,66), 385 'tomato3'=>array(205,79,57), 386 'tomato4'=>array(139,54,38), 387 'orangered1'=>array(255,69,0), 388 'orangered2'=>array(238,64,0), 389 'orangered3'=>array(205,55,0), 390 'orangered4'=>array(139,37,0), 391 'deeppink1'=>array(255,20,147), 392 'deeppink2'=>array(238,18,137), 393 'deeppink3'=>array(205,16,118), 394 'deeppink4'=>array(139,10,80), 395 'hotpink1'=>array(255,110,180), 396 'hotpink2'=>array(238,106,167), 397 'hotpink3'=>array(205,96,144), 398 'hotpink4'=>array(139,58,98), 399 'pink1'=>array(255,181,197), 400 'pink2'=>array(238,169,184), 401 'pink3'=>array(205,145,158), 402 'pink4'=>array(139,99,108), 403 'lightpink1'=>array(255,174,185), 404 'lightpink2'=>array(238,162,173), 405 'lightpink3'=>array(205,140,149), 406 'lightpink4'=>array(139,95,101), 407 'palevioletred1'=>array(255,130,171), 408 'palevioletred2'=>array(238,121,159), 409 'palevioletred3'=>array(205,104,137), 410 'palevioletred4'=>array(139,71,93), 411 'maroon1'=>array(255,52,179), 412 'maroon2'=>array(238,48,167), 413 'maroon3'=>array(205,41,144), 414 'maroon4'=>array(139,28,98), 415 'violetred1'=>array(255,62,150), 416 'violetred2'=>array(238,58,140), 417 'violetred3'=>array(205,50,120), 418 'violetred4'=>array(139,34,82), 419 'magenta1'=>array(255,0,255), 420 'magenta2'=>array(238,0,238), 421 'magenta3'=>array(205,0,205), 422 'magenta4'=>array(139,0,139), 423 'mediumred'=>array(140,34,34), 424 'orchid1'=>array(255,131,250), 425 'orchid2'=>array(238,122,233), 426 'orchid3'=>array(205,105,201), 427 'orchid4'=>array(139,71,137), 428 'plum1'=>array(255,187,255), 429 'plum2'=>array(238,174,238), 430 'plum3'=>array(205,150,205), 431 'plum4'=>array(139,102,139), 432 'mediumorchid1'=>array(224,102,255), 433 'mediumorchid2'=>array(209,95,238), 434 'mediumorchid3'=>array(180,82,205), 435 'mediumorchid4'=>array(122,55,139), 436 'darkorchid1'=>array(191,62,255), 437 'darkorchid2'=>array(178,58,238), 438 'darkorchid3'=>array(154,50,205), 439 'darkorchid4'=>array(104,34,139), 440 'purple1'=>array(155,48,255), 441 'purple2'=>array(145,44,238), 442 'purple3'=>array(125,38,205), 443 'purple4'=>array(85,26,139), 444 'mediumpurple1'=>array(171,130,255), 445 'mediumpurple2'=>array(159,121,238), 446 'mediumpurple3'=>array(137,104,205), 447 'mediumpurple4'=>array(93,71,139), 448 'thistle1'=>array(255,225,255), 449 'thistle2'=>array(238,210,238), 450 'thistle3'=>array(205,181,205), 451 'thistle4'=>array(139,123,139), 452 'gray1'=>array(10,10,10), 453 'gray2'=>array(40,40,30), 454 'gray3'=>array(70,70,70), 455 'gray4'=>array(100,100,100), 456 'gray5'=>array(130,130,130), 457 'gray6'=>array(160,160,160), 458 'gray7'=>array(190,190,190), 459 'gray8'=>array(210,210,210), 460 'gray9'=>array(240,240,240), 461 'darkgray'=>array(100,100,100), 462 'darkblue'=>array(0,0,139), 463 'darkcyan'=>array(0,139,139), 464 'darkmagenta'=>array(139,0,139), 465 'darkred'=>array(139,0,0), 466 'silver'=>array(192, 192, 192), 467 'eggplant'=>array(144,176,168), 468 'lightgreen'=>array(144,238,144)); 462 469 } 463 //---------------- 464 // PUBLIC METHODS 470 471 472 //---------------- 473 // PUBLIC METHODS 465 474 // Colors can be specified as either 466 // 1. #xxxxxx 467 // 2. "colorname" 468 // 3. array(r,g,b) 469 // This function translates this to a native RGB format and returns an 475 // 1. #xxxxxx HTML style 476 // 2. "colorname" as a named color 477 // 3. array(r,g,b) RGB triple 478 // This function translates this to a native RGB format and returns an 470 479 // RGB triple. 480 471 481 function Color($aColor) { 472 if (is_string($aColor)) { 473 // Strip of any alpha factor 474 $pos = strpos($aColor,'@'); 475 if( $pos === false ) { 476 $alpha = 0; 477 } 478 else { 479 $pos2 = strpos($aColor,':'); 480 if( $pos2===false ) 481 $pos2 = $pos-1; // Sentinel 482 if( $pos > $pos2 ) { 483 $alpha = str_replace(',','.',substr($aColor,$pos+1)); 484 $aColor = substr($aColor,0,$pos); 485 } 486 else { 487 $alpha = substr($aColor,$pos+1,$pos2-$pos-1); 488 $aColor = substr($aColor,0,$pos).substr($aColor,$pos2); 489 } 490 } 491 492 // Extract potential adjustment figure at end of color 493 // specification 494 $pos = strpos($aColor,":"); 495 if( $pos === false ) { 496 $adj = 1.0; 497 } 498 else { 499 $adj = 0.0 + str_replace(',','.',substr($aColor,$pos+1)); 500 $aColor = substr($aColor,0,$pos); 501 } 502 if( $adj < 0 ) 503 JpGraphError::RaiseL(25077);//('Adjustment factor for color must be > 0'); 504 505 if (substr($aColor, 0, 1) == "#") { 506 $r = hexdec(substr($aColor, 1, 2)); 507 $g = hexdec(substr($aColor, 3, 2)); 508 $b = hexdec(substr($aColor, 5, 2)); 509 } else { 510 if(!isset($this->rgb_table[$aColor]) ) 511 JpGraphError::RaiseL(25078,$aColor);//(" Unknown color: $aColor"); 512 $tmp=$this->rgb_table[$aColor]; 513 $r = $tmp[0]; 514 $g = $tmp[1]; 515 $b = $tmp[2]; 516 } 517 // Scale adj so that an adj=2 always 518 // makes the color 100% white (i.e. 255,255,255. 519 // and adj=1 neutral and adj=0 black. 520 if( $adj > 1 ) { 521 $m = ($adj-1.0)*(255-min(255,min($r,min($g,$b)))); 522 return array(min(255,$r+$m), min(255,$g+$m), min(255,$b+$m),$alpha); 523 } 524 elseif( $adj < 1 ) { 525 $m = ($adj-1.0)*max(255,max($r,max($g,$b))); 526 return array(max(0,$r+$m), max(0,$g+$m), max(0,$b+$m),$alpha); 527 } 528 else { 529 return array($r,$g,$b,$alpha); 530 } 531 532 } elseif( is_array($aColor) ) { 533 if( count($aColor)==3 ) { 534 $aColor[3]=0; 535 return $aColor; 536 } 537 else 538 return $aColor; 539 } 540 else 541 JpGraphError::RaiseL(25079,$aColor,count($aColor));//(" Unknown color specification: $aColor , size=".count($aColor)); 482 if (is_string($aColor)) { 483 $matches = array(); 484 // this regex will parse a color string and fill the $matches array as such: 485 // 0: the full match if any 486 // 1: a hex string preceded by a hash, can be 3 characters (#fff) or 6 (#ffffff) (4 or 5 also accepted but...) 487 // 2,3,4: r,g,b values in hex if the first character of the string is # 488 // 5: all alpha-numeric characters at the beginning of the string if string does not start with # 489 // 6: alpha value prefixed by @ if supplied 490 // 7: alpha value with @ stripped 491 // 8: adjust value prefixed with : if supplied 492 // 9: adjust value with : stripped 493 $regex = '/(#([0-9a-fA-F]{1,2})([0-9a-fA-F]{1,2})([0-9a-fA-F]{1,2}))?([\w]+)?(@([\d\.,]+))?(:([\d\.,]+))?/'; 494 if(!preg_match($regex, $aColor, $matches)) { 495 JpGraphError::RaiseL(25078,$aColor);//(" Unknown color: $aColor"); 496 } 497 if(empty($matches[5])) { 498 $r = strlen($matches[2]) == 1 ? $matches[2].$matches[2] : $matches[2]; 499 $g = strlen($matches[3]) == 1 ? $matches[3].$matches[3] : $matches[3]; 500 $b = strlen($matches[4]) == 1 ? $matches[4].$matches[4] : $matches[4]; 501 $r = hexdec($r); 502 $g = hexdec($g); 503 $b = hexdec($b); 504 }else { 505 if(!isset($this->rgb_table[$matches[5]]) ) { 506 JpGraphError::RaiseL(25078,$aColor);//(" Unknown color: $aColor"); 507 } 508 $r = $this->rgb_table[$matches[5]][0]; 509 $g = $this->rgb_table[$matches[5]][1]; 510 $b = $this->rgb_table[$matches[5]][2]; 511 } 512 $alpha = isset($matches[7]) ? str_replace(',','.',$matches[7]) : 0; 513 $adj = isset($matches[9]) ? str_replace(',','.',$matches[9]) : 1.0; 514 515 if( $adj < 0 ) { 516 JpGraphError::RaiseL(25077);//('Adjustment factor for color must be > 0'); 517 } 518 519 // Scale adj so that an adj=2 always 520 // makes the color 100% white (i.e. 255,255,255. 521 // and adj=1 neutral and adj=0 black. 522 if( $adj == 1) { 523 return array($r,$g,$b,$alpha); 524 } 525 elseif( $adj > 1 ) { 526 $m = ($adj-1.0)*(255-min(255,min($r,min($g,$b)))); 527 return array(min(255,$r+$m), min(255,$g+$m), min(255,$b+$m),$alpha); 528 } 529 elseif( $adj < 1 ) { 530 $m = ($adj-1.0)*max(255,max($r,max($g,$b))); 531 return array(max(0,$r+$m), max(0,$g+$m), max(0,$b+$m),$alpha); 532 } 533 } elseif( is_array($aColor) ) { 534 if(!isset($aColor[3])) $aColor[3] = 0; 535 return $aColor; 536 } 537 else { 538 JpGraphError::RaiseL(25079,$aColor,count($aColor));//(" Unknown color specification: $aColor , size=".count($aColor)); 539 } 542 540 } 543 541 544 542 // Compare two colors 545 543 // return true if equal 546 544 function Equal($aCol1,$aCol2) { 547 $c1 = $this->Color($aCol1); 548 $c2 = $this->Color($aCol2); 549 if( $c1[0]==$c2[0] && $c1[1]==$c2[1] && $c1[2]==$c2[2] ) 550 return true; 551 else 552 return false; 545 $c1 = $this->Color($aCol1); 546 $c2 = $this->Color($aCol2); 547 return $c1[0]==$c2[0] && $c1[1]==$c2[1] && $c1[2]==$c2[2] ; 553 548 } 554 549 555 550 // Allocate a new color in the current image 556 551 // Return new color index, -1 if no more colors could be allocated 557 552 function Allocate($aColor,$aAlpha=0.0) { 558 list ($r, $g, $b, $a) = $this->color($aColor); 559 // If alpha is specified in the color string then this 560 // takes precedence over the second argument 561 if( $a > 0 ) 562 $aAlpha = $a; 563 if( $aAlpha < 0 || $aAlpha > 1 ) { 564 JpGraphError::RaiseL(25080);//('Alpha parameter for color must be between 0.0 and 1.0'); 565 } 566 return imagecolorresolvealpha($this->img, $r, $g, $b, round($aAlpha * 127)); 553 list ($r, $g, $b, $a) = $this->color($aColor); 554 // If alpha is specified in the color string then this 555 // takes precedence over the second argument 556 if( $a > 0 ) { 557 $aAlpha = $a; 558 } 559 if( $aAlpha < 0 || $aAlpha > 1 ) { 560 JpGraphError::RaiseL(25080);//('Alpha parameter for color must be between 0.0 and 1.0'); 561 } 562 return imagecolorresolvealpha($this->img, $r, $g, $b, round($aAlpha * 127)); 567 563 } 564 565 // Try to convert an array with three valid numbers to the corresponding hex array 566 // This is currenly only used in processing the colors for barplots in order to be able 567 // to handle the case where the color might be specified as an array of colros as well. 568 // In that case we must be able to find out if an array of values should be interpretated as 569 // a single color (specifeid as an RGB triple) 570 static function tryHexConversion($aColor) { 571 if( is_array( $aColor ) ) { 572 if( count( $aColor ) == 3 ) { 573 if( is_numeric($aColor[0]) && is_numeric($aColor[1]) && is_numeric($aColor[2]) ) { 574 if( ($aColor[0] >= 0 && $aColor[0] <= 255) && 575 ($aColor[1] >= 0 && $aColor[1] <= 255) && 576 ($aColor[2] >= 0 && $aColor[2] <= 255) ) { 577 return sprintf('#%02x%02x%02x',$aColor[0],$aColor[1],$aColor[2]); 578 } 579 } 580 } 581 } 582 return $aColor; 583 } 584 585 // Return a RGB tripple corresponding to a position in the normal light spectrum 586 // The argumen values is in the range [0, 1] where a value of 0 correponds to blue and 587 // a value of 1 corresponds to red. Values in betwen is mapped to a linear interpolation 588 // of the constituting colors in the visible color spectra. 589 // The $aDynamicRange specified how much of the dynamic range we shold use 590 // a value of 1.0 give the full dyanmic range and a lower value give more dark 591 // colors. In the extreme of 0.0 then all colors will be black. 592 static function GetSpectrum($aVal,$aDynamicRange=1.0) { 593 if( $aVal < 0 || $aVal > 1.0001 ) { 594 return array(0,0,0); // Invalid case - just return black 595 } 596 597 $sat = round(255*$aDynamicRange); 598 $a = 0.25; 599 if( $aVal <= 0.25 ) { 600 return array(0, round($sat*$aVal/$a), $sat); 601 } 602 elseif( $aVal <= 0.5 ) { 603 return array(0, $sat, round($sat-$sat*($aVal-0.25)/$a)); 604 } 605 elseif( $aVal <= 0.75 ) { 606 return array(round($sat*($aVal-0.5)/$a), $sat, 0); 607 } 608 else { 609 return array($sat, round($sat-$sat*($aVal-0.75)/$a), 0); 610 } 611 } 612 568 613 } // Class 569 614 -
trunk/client/modules/Elezioni/grafici/jpgraph_scatter.php
r267 r284 1 <?php 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_SCATTER.PHP4 // Description: Scatter (and impuls) plot extension for JpGraph5 // Created:2001-02-116 // Ver: $Id: jpgraph_scatter.php 957 2007-12-01 14:00:29Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */3 // File: JPGRAPH_SCATTER.PHP 4 // Description: Scatter (and impuls) plot extension for JpGraph 5 // Created: 2001-02-11 6 // Ver: $Id: jpgraph_scatter.php 1397 2009-06-27 21:34:14Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 11 require_once ('jpgraph_plotmark.inc.php'); 12 12 … … 20 20 public $iArrowSize = 2; 21 21 private $isizespec = array( 22 array(2,1),array(3,2),array(4,3),array(6,4),array(7,4),array(8,5),array(10,6),array(12,7),array(16,8),array(20,10)); 23 function FieldArrow() { 22 array(2,1),array(3,2),array(4,3),array(6,4),array(7,4),array(8,5),array(10,6),array(12,7),array(16,8),array(20,10) 23 ); 24 function __construct() { 25 // Empty 24 26 } 25 27 26 28 function SetSize($aSize,$aArrowSize=2) { 27 28 29 $this->iSize = $aSize; 30 $this->iArrowSize = $aArrowSize; 29 31 } 30 32 31 33 function SetColor($aColor) { 32 34 $this->iColor = $aColor; 33 35 } 34 36 35 37 function Stroke($aImg,$x,$y,$a) { 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 38 // First rotate the center coordinates 39 list($x,$y) = $aImg->Rotate($x,$y); 40 41 $old_origin = $aImg->SetCenter($x,$y); 42 $old_a = $aImg->a; 43 $aImg->SetAngle(-$a+$old_a); 44 45 $dx = round($this->iSize/2); 46 $c = array($x-$dx,$y,$x+$dx,$y); 47 $x += $dx; 48 49 list($dx,$dy) = $this->isizespec[$this->iArrowSize]; 50 $ca = array($x,$y,$x-$dx,$y-$dy,$x-$dx,$y+$dy,$x,$y); 51 52 $aImg->SetColor($this->iColor); 53 $aImg->Polygon($c); 54 $aImg->FilledPolygon($ca); 55 56 $aImg->SetCenter($old_origin[0],$old_origin[1]); 57 $aImg->SetAngle($old_a); 56 58 } 57 59 } … … 65 67 private $iAngles = array(); 66 68 private $iCallback = ''; 67 68 function FieldPlot($datay,$datax,$angles) {69 70 71 72 73 74 75 76 $this->Plot($datay,$datax);77 78 79 80 69 70 function __construct($datay,$datax,$angles) { 71 if( (count($datax) != count($datay)) ) 72 JpGraphError::RaiseL(20001);//("Fieldplots must have equal number of X and Y points."); 73 if( (count($datax) != count($angles)) ) 74 JpGraphError::RaiseL(20002);//("Fieldplots must have an angle specified for each X and Y points."); 75 76 $this->iAngles = $angles; 77 78 parent::__construct($datay,$datax); 79 $this->value->SetAlign('center','center'); 80 $this->value->SetMargin(15); 81 82 $this->arrow = new FieldArrow(); 81 83 } 82 84 83 85 function SetCallback($aFunc) { 84 86 $this->iCallback = $aFunc; 85 87 } 86 88 87 89 function Stroke($img,$xscale,$yscale) { 88 90 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 $this->arrow->SetColor($cc); 107 108 109 110 111 $yt = $yscale->Translate($this->coords[0][$i]); 112 113 114 115 116 } 117 91 // Remeber base color and size 92 $bc = $this->arrow->iColor; 93 $bs = $this->arrow->iSize; 94 $bas = $this->arrow->iArrowSize; 95 96 for( $i=0; $i<$this->numpoints; ++$i ) { 97 // Skip null values 98 if( $this->coords[0][$i]==="" ) 99 continue; 100 101 $f = $this->iCallback; 102 if( $f != "" ) { 103 list($cc,$cs,$cas) = call_user_func($f,$this->coords[1][$i],$this->coords[0][$i],$this->iAngles[$i]); 104 // Fall back on global data if the callback isn't set 105 if( $cc == "" ) $cc = $bc; 106 if( $cs == "" ) $cs = $bs; 107 if( $cas == "" ) $cas = $bas; 108 $this->arrow->SetColor($cc); 109 $this->arrow->SetSize($cs,$cas); 110 } 111 112 $xt = $xscale->Translate($this->coords[1][$i]); 113 $yt = $yscale->Translate($this->coords[0][$i]); 114 115 $this->arrow->Stroke($img,$xt,$yt,$this->iAngles[$i]); 116 $this->value->Stroke($img,$this->coords[0][$i],$xt,$yt); 117 } 118 } 119 118 120 // Framework function 119 121 function Legend($aGraph) { 120 121 122 123 124 } 122 if( $this->legend != "" ) { 123 $aGraph->legend->Add($this->legend,$this->mark->fill_color,$this->mark,0, 124 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 125 } 126 } 125 127 } 126 128 … … 130 132 //=================================================== 131 133 class ScatterPlot extends Plot { 132 public $mark = '';134 public $mark,$link; 133 135 private $impuls = false; 134 private $linkpoints = false, $linkpointweight=1, $linkpointcolor="black"; 135 //--------------- 136 // CONSTRUCTOR 137 function ScatterPlot($datay,$datax=false) { 138 if( (count($datax) != count($datay)) && is_array($datax)) 139 JpGraphError::RaiseL(20003);//("Scatterplot must have equal number of X and Y points."); 140 $this->Plot($datay,$datax); 141 $this->mark = new PlotMark(); 142 $this->mark->SetType(MARK_SQUARE); 143 $this->mark->SetColor($this->color); 144 $this->value->SetAlign('center','center'); 145 $this->value->SetMargin(0); 146 } 147 148 //--------------- 149 // PUBLIC METHODS 136 //--------------- 137 // CONSTRUCTOR 138 function __construct($datay,$datax=false) { 139 if( is_array($datax) && (count($datax) != count($datay)) ) { 140 JpGraphError::RaiseL(20003);//("Scatterplot must have equal number of X and Y points."); 141 } 142 parent::__construct($datay,$datax); 143 $this->mark = new PlotMark(); 144 $this->mark->SetType(MARK_SQUARE); 145 $this->mark->SetColor($this->color); 146 $this->value->SetAlign('center','center'); 147 $this->value->SetMargin(0); 148 $this->link = new LineProperty(1,'black','solid'); 149 $this->link->iShow = false; 150 } 151 152 //--------------- 153 // PUBLIC METHODS 150 154 function SetImpuls($f=true) { 151 $this->impuls = $f; 152 } 155 $this->impuls = $f; 156 } 157 158 function SetStem($f=true) { 159 $this->impuls = $f; 160 } 153 161 154 162 // Combine the scatter plot points with a line 155 function SetLinkPoints($aFlag=true,$aColor="black",$aWeight=1) { 156 $this->linkpoints=$aFlag; 157 $this->linkpointcolor=$aColor; 158 $this->linkpointweight=$aWeight; 163 function SetLinkPoints($aFlag=true,$aColor="black",$aWeight=1,$aStyle='solid') { 164 $this->link->iShow = $aFlag; 165 $this->link->iColor = $aColor; 166 $this->link->iWeight = $aWeight; 167 $this->link->iStyle = $aStyle; 159 168 } 160 169 161 170 function Stroke($img,$xscale,$yscale) { 162 171 163 $ymin=$yscale->scale_abs[0]; 164 if( $yscale->scale[0] < 0 ) 165 $yzero=$yscale->Translate(0); 166 else 167 $yzero=$yscale->scale_abs[0]; 168 169 $this->csimareas = ''; 170 for( $i=0; $i<$this->numpoints; ++$i ) { 171 172 // Skip null values 173 if( $this->coords[0][$i]==='' || $this->coords[0][$i]==='-' || $this->coords[0][$i]==='x') 174 continue; 175 176 if( isset($this->coords[1]) ) 177 $xt = $xscale->Translate($this->coords[1][$i]); 178 else 179 $xt = $xscale->Translate($i); 180 $yt = $yscale->Translate($this->coords[0][$i]); 181 182 183 if( $this->linkpoints && isset($yt_old) ) { 184 $img->SetColor($this->linkpointcolor); 185 $img->SetLineWeight($this->linkpointweight); 186 $img->Line($xt_old,$yt_old,$xt,$yt); 187 } 188 189 if( $this->impuls ) { 190 $img->SetColor($this->color); 191 $img->SetLineWeight($this->weight); 192 $img->Line($xt,$yzero,$xt,$yt); 193 } 194 195 if( !empty($this->csimtargets[$i]) ) { 196 if( !empty($this->csimwintargets[$i]) ) { 197 $this->mark->SetCSIMTarget($this->csimtargets[$i],$this->csimwintargets[$i]); 198 } 199 else { 200 $this->mark->SetCSIMTarget($this->csimtargets[$i]); 201 } 202 $this->mark->SetCSIMAlt($this->csimalts[$i]); 203 } 204 205 if( isset($this->coords[1]) ) { 206 $this->mark->SetCSIMAltVal($this->coords[0][$i],$this->coords[1][$i]); 207 } 208 else { 209 $this->mark->SetCSIMAltVal($this->coords[0][$i],$i); 210 } 211 212 $this->mark->Stroke($img,$xt,$yt); 213 214 $this->csimareas .= $this->mark->GetCSIMAreas(); 215 $this->value->Stroke($img,$this->coords[0][$i],$xt,$yt); 216 217 $xt_old = $xt; 218 $yt_old = $yt; 219 } 220 } 221 172 $ymin=$yscale->scale_abs[0]; 173 if( $yscale->scale[0] < 0 ) 174 $yzero=$yscale->Translate(0); 175 else 176 $yzero=$yscale->scale_abs[0]; 177 178 $this->csimareas = ''; 179 for( $i=0; $i<$this->numpoints; ++$i ) { 180 181 // Skip null values 182 if( $this->coords[0][$i]==='' || $this->coords[0][$i]==='-' || $this->coords[0][$i]==='x') 183 continue; 184 185 if( isset($this->coords[1]) ) 186 $xt = $xscale->Translate($this->coords[1][$i]); 187 else 188 $xt = $xscale->Translate($i); 189 $yt = $yscale->Translate($this->coords[0][$i]); 190 191 192 if( $this->link->iShow && isset($yt_old) ) { 193 $img->SetColor($this->link->iColor); 194 $img->SetLineWeight($this->link->iWeight); 195 $old = $img->SetLineStyle($this->link->iStyle); 196 $img->StyleLine($xt_old,$yt_old,$xt,$yt); 197 $img->SetLineStyle($old); 198 } 199 200 if( $this->impuls ) { 201 $img->SetColor($this->color); 202 $img->SetLineWeight($this->weight); 203 $img->Line($xt,$yzero,$xt,$yt); 204 } 205 206 if( !empty($this->csimtargets[$i]) ) { 207 if( !empty($this->csimwintargets[$i]) ) { 208 $this->mark->SetCSIMTarget($this->csimtargets[$i],$this->csimwintargets[$i]); 209 } 210 else { 211 $this->mark->SetCSIMTarget($this->csimtargets[$i]); 212 } 213 $this->mark->SetCSIMAlt($this->csimalts[$i]); 214 } 215 216 if( isset($this->coords[1]) ) { 217 $this->mark->SetCSIMAltVal($this->coords[0][$i],$this->coords[1][$i]); 218 } 219 else { 220 $this->mark->SetCSIMAltVal($this->coords[0][$i],$i); 221 } 222 223 $this->mark->Stroke($img,$xt,$yt); 224 225 $this->csimareas .= $this->mark->GetCSIMAreas(); 226 $this->value->Stroke($img,$this->coords[0][$i],$xt,$yt); 227 228 $xt_old = $xt; 229 $yt_old = $yt; 230 } 231 } 232 222 233 // Framework function 223 234 function Legend($aGraph) { 224 225 226 227 228 } 235 if( $this->legend != "" ) { 236 $aGraph->legend->Add($this->legend,$this->mark->fill_color,$this->mark,0, 237 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 238 } 239 } 229 240 } // Class 230 241 /* EOF */ -
trunk/client/modules/Elezioni/grafici/jpgraph_stock.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_STOCK.PHP4 // Description:Stock plot extension for JpGraph5 // Created:2003-01-276 // Ver: $Id: jpgraph_stock.php 957 2007-12-01 14:00:29Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */3 // File: JPGRAPH_STOCK.PHP 4 // Description: Stock plot extension for JpGraph 5 // Created: 2003-01-27 6 // Ver: $Id: jpgraph_stock.php 1364 2009-06-24 07:07:44Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 //=================================================== … … 18 18 private $iEndLines=1; 19 19 private $iStockColor1='white',$iStockColor2='darkred',$iStockColor3='darkred'; 20 //---------------21 // CONSTRUCTOR22 function StockPlot($datay,$datax=false) {23 24 25 //('Data values for Stock charts must contain an even multiple of '.$this->iTupleSize.' data points.');26 27 $this->Plot($datay,$datax);28 20 //--------------- 21 // CONSTRUCTOR 22 function __construct($datay,$datax=false) { 23 if( count($datay) % $this->iTupleSize ) { 24 JpGraphError::RaiseL(21001,$this->iTupleSize); 25 //('Data values for Stock charts must contain an even multiple of '.$this->iTupleSize.' data points.'); 26 } 27 parent::__construct($datay,$datax); 28 $this->numpoints /= $this->iTupleSize; 29 29 } 30 //---------------31 // PUBLIC METHODS32 30 //--------------- 31 // PUBLIC METHODS 32 33 33 function SetColor($aColor,$aColor1='white',$aColor2='darkred',$aColor3='darkred') { 34 35 36 37 34 $this->color = $aColor; 35 $this->iStockColor1 = $aColor1; 36 $this->iStockColor2 = $aColor2; 37 $this->iStockColor3 = $aColor3; 38 38 } 39 39 40 40 function SetWidth($aWidth) { 41 42 41 // Make sure it's odd 42 $this->iWidth = 2*floor($aWidth/2)+1; 43 43 } 44 44 45 45 function HideEndLines($aHide=true) { 46 46 $this->iEndLines = !$aHide; 47 47 } 48 48 49 49 // Gets called before any axis are stroked 50 50 function PreStrokeAdjust($graph) { 51 52 53 54 55 56 57 58 $graph->SetTextScaleOff($b); 51 if( $this->center ) { 52 $a=0.5; $b=0.5; 53 $this->numpoints++; 54 } else { 55 $a=0; $b=0; 56 } 57 $graph->xaxis->scale->ticks->SetXLabelOffset($a); 58 $graph->SetTextScaleOff($b); 59 59 } 60 60 61 61 // Method description 62 62 function Stroke($img,$xscale,$yscale) { 63 $n=$this->numpoints; 64 if( $this->center ) $n--; 65 if( isset($this->coords[1]) ) { 66 if( count($this->coords[1])!=$n ) 67 JpGraphError::RaiseL(2003,count($this->coords[1]),$n); 68 //("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints"); 69 else 70 $exist_x = true; 71 } 72 else 73 $exist_x = false; 63 $n=$this->numpoints; 64 if( $this->center ) $n--; 65 if( isset($this->coords[1]) ) { 66 if( count($this->coords[1])!=$n ) { 67 JpGraphError::RaiseL(2003,count($this->coords[1]),$n); 68 // ("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints"); 69 } 70 else { 71 $exist_x = true; 72 } 73 } 74 else { 75 $exist_x = false; 76 } 74 77 75 if( $exist_x ) 76 $xs=$this->coords[1][0]; 77 else 78 $xs=0; 79 80 $ts = $this->iTupleSize; 81 $this->csimareas = ''; 82 for( $i=0; $i<$n; ++$i) { 78 if( $exist_x ) { 79 $xs=$this->coords[1][0]; 80 } 81 else { 82 $xs=0; 83 } 83 84 84 //If value is NULL, then don't draw a bar at all 85 if ($this->coords[0][$i] === null) continue; 85 $ts = $this->iTupleSize; 86 $this->csimareas = ''; 87 for( $i=0; $i<$n; ++$i) { 86 88 87 if( $exist_x ) $x=$this->coords[1][$i]; 88 else $x=$i; 89 $xt = $xscale->Translate($x); 90 91 $neg = $this->coords[0][$i*$ts] > $this->coords[0][$i*$ts+1] ; 92 $yopen = $yscale->Translate($this->coords[0][$i*$ts]); 93 $yclose = $yscale->Translate($this->coords[0][$i*$ts+1]); 94 $ymin = $yscale->Translate($this->coords[0][$i*$ts+2]); 95 $ymax = $yscale->Translate($this->coords[0][$i*$ts+3]); 89 //If value is NULL, then don't draw a bar at all 90 if ($this->coords[0][$i*$ts] === null) continue; 96 91 97 $dx = floor($this->iWidth/2); 98 $xl = $xt - $dx; 99 $xr = $xt + $dx; 92 if( $exist_x ) { 93 $x=$this->coords[1][$i]; 94 if ($x === null) continue; 95 } 96 else { 97 $x=$i; 98 } 99 $xt = $xscale->Translate($x); 100 100 101 if( $neg ) 102 $img->SetColor($this->iStockColor3); 103 else 104 $img->SetColor($this->iStockColor1); 105 $img->FilledRectangle($xl,$yopen,$xr,$yclose); 106 $img->SetLineWeight($this->weight); 107 if( $neg ) 108 $img->SetColor($this->iStockColor2); 109 else 110 $img->SetColor($this->color); 111 112 $img->Rectangle($xl,$yopen,$xr,$yclose); 101 $neg = $this->coords[0][$i*$ts] > $this->coords[0][$i*$ts+1] ; 102 $yopen = $yscale->Translate($this->coords[0][$i*$ts]); 103 $yclose = $yscale->Translate($this->coords[0][$i*$ts+1]); 104 $ymin = $yscale->Translate($this->coords[0][$i*$ts+2]); 105 $ymax = $yscale->Translate($this->coords[0][$i*$ts+3]); 113 106 114 if( $yopen < $yclose ) { 115 $ytop = $yopen ; 116 $ybottom = $yclose ; 117 } 118 else { 119 $ytop = $yclose ; 120 $ybottom = $yopen ; 121 } 122 $img->SetColor($this->color); 123 $img->Line($xt,$ytop,$xt,$ymax); 124 $img->Line($xt,$ybottom,$xt,$ymin); 107 $dx = floor($this->iWidth/2); 108 $xl = $xt - $dx; 109 $xr = $xt + $dx; 125 110 126 if( $this->iEndLines ) { 127 $img->Line($xl,$ymax,$xr,$ymax); 128 $img->Line($xl,$ymin,$xr,$ymin); 129 } 111 if( $neg ) { 112 $img->SetColor($this->iStockColor3); 113 } 114 else { 115 $img->SetColor($this->iStockColor1); 116 } 117 $img->FilledRectangle($xl,$yopen,$xr,$yclose); 118 $img->SetLineWeight($this->weight); 119 if( $neg ) { 120 $img->SetColor($this->iStockColor2); 121 } 122 else { 123 $img->SetColor($this->color); 124 } 130 125 131 // A chance for subclasses to add things to the bar 132 // for data point i 133 $this->ModBox($img,$xscale,$yscale,$i,$xl,$xr,$neg); 126 $img->Rectangle($xl,$yopen,$xr,$yclose); 134 127 135 // Setup image maps 136 if( !empty($this->csimtargets[$i]) ) { 137 $this->csimareas.= '<area shape="rect" coords="'. 138 round($xl).','.round($ytop).','. 139 round($xr).','.round($ybottom).'" '; 140 $this->csimareas .= ' href="'.$this->csimtargets[$i].'"'; 141 if( !empty($this->csimalts[$i]) ) { 142 $sval=$this->csimalts[$i]; 143 $this->csimareas .= " title=\"$sval\" alt=\"$sval\" "; 144 } 145 $this->csimareas.= " />\n"; 146 } 147 } 148 return true; 128 if( $yopen < $yclose ) { 129 $ytop = $yopen ; 130 $ybottom = $yclose ; 131 } 132 else { 133 $ytop = $yclose ; 134 $ybottom = $yopen ; 135 } 136 $img->SetColor($this->color); 137 $img->Line($xt,$ytop,$xt,$ymax); 138 $img->Line($xt,$ybottom,$xt,$ymin); 139 140 if( $this->iEndLines ) { 141 $img->Line($xl,$ymax,$xr,$ymax); 142 $img->Line($xl,$ymin,$xr,$ymin); 143 } 144 145 // A chance for subclasses to add things to the bar 146 // for data point i 147 $this->ModBox($img,$xscale,$yscale,$i,$xl,$xr,$neg); 148 149 // Setup image maps 150 if( !empty($this->csimtargets[$i]) ) { 151 $this->csimareas.= '<area shape="rect" coords="'. 152 round($xl).','.round($ytop).','. 153 round($xr).','.round($ybottom).'" '; 154 $this->csimareas .= ' href="'.$this->csimtargets[$i].'"'; 155 if( !empty($this->csimalts[$i]) ) { 156 $sval=$this->csimalts[$i]; 157 $this->csimareas .= " title=\"$sval\" alt=\"$sval\" "; 158 } 159 $this->csimareas.= " />\n"; 160 } 161 } 162 return true; 149 163 } 150 164 … … 159 173 class BoxPlot extends StockPlot { 160 174 private $iPColor='black',$iNColor='white'; 161 function BoxPlot($datay,$datax=false) { 162 $this->iTupleSize=5; 163 parent::StockPlot($datay,$datax); 175 176 function __construct($datay,$datax=false) { 177 $this->iTupleSize=5; 178 parent::__construct($datay,$datax); 164 179 } 165 180 166 181 function SetMedianColor($aPos,$aNeg) { 167 168 182 $this->iPColor = $aPos; 183 $this->iNColor = $aNeg; 169 184 } 170 185 171 186 function ModBox($img,$xscale,$yscale,$i,$xl,$xr,$neg) { 172 if( $neg ) 173 174 175 176 177 178 187 if( $neg ) 188 $img->SetColor($this->iNColor); 189 else 190 $img->SetColor($this->iPColor); 191 192 $y = $yscale->Translate($this->coords[0][$i*5+4]); 193 $img->Line($xl,$y,$xr,$y); 179 194 } 180 195 } -
trunk/client/modules/Elezioni/grafici/jpgraph_text.inc.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // 6 // Created: 7 // Ver: $Id: jpgraph_text.inc.php 1048 2008-08-01 19:56:46Z ljp $3 // File: JPGRAPH_TEXT.INC.PHP 4 // Description: Class to handle text as object in the graph. 5 // The low level text layout engine is handled by the GD class 6 // Created: 2001-01-08 (Refactored to separate file 2008-08-01) 7 // Ver: $Id: jpgraph_text.inc.php 1844 2009-09-26 17:05:31Z ljp $ 8 8 // 9 // Copyright (c) A ditus Consulting. All rights reserved.9 // Copyright (c) Asial Corporation. All rights reserved. 10 10 //======================================================================== 11 11 … … 16 16 //=================================================== 17 17 class Text { 18 public $t ,$margin=0;18 public $t; 19 19 public $x=0,$y=0,$halign="left",$valign="top",$color=array(0,0,0); 20 20 public $hide=false, $dir=0; 21 21 public $iScalePosY=null,$iScalePosX=null; 22 22 public $iWordwrap=0; 23 public $font_family=FF_ FONT1,$font_style=FS_NORMAL,$font_size=12;24 protected $boxed=false; 23 public $font_family=FF_DEFAULT,$font_style=FS_NORMAL; // old. FF_FONT1 24 protected $boxed=false; // Should the text be boxed 25 25 protected $paragraph_align="left"; 26 26 protected $icornerradius=0,$ishadowwidth=3; 27 27 protected $fcolor='white',$bcolor='black',$shadow=false; 28 28 protected $iCSIMarea='',$iCSIMalt='',$iCSIMtarget='',$iCSIMWinTarget=''; 29 30 //--------------- 31 // CONSTRUCTOR 29 private $iBoxType = 1; // Which variant of filled box around text we want 30 31 // for __get, __set 32 private $_margin; 33 private $_font_size=8; // old. 12 34 35 //--------------- 36 // CONSTRUCTOR 32 37 33 38 // Create new text at absolute pixel coordinates 34 function Text($aTxt="",$aXAbsPos=0,$aYAbsPos=0) {35 36 37 38 39 40 41 42 } 43 //---------------44 // PUBLIC METHODS 39 function __construct($aTxt="",$aXAbsPos=0,$aYAbsPos=0) { 40 if( ! is_string($aTxt) ) { 41 JpGraphError::RaiseL(25050);//('First argument to Text::Text() must be s atring.'); 42 } 43 $this->t = $aTxt; 44 $this->x = round($aXAbsPos); 45 $this->y = round($aYAbsPos); 46 $this->margin = 0; 47 } 48 //--------------- 49 // PUBLIC METHODS 45 50 // Set the string in the text object 46 51 function Set($aTxt) { 47 48 } 49 52 $this->t = $aTxt; 53 } 54 50 55 // Alias for Pos() 51 56 function SetPos($aXAbsPos=0,$aYAbsPos=0,$aHAlign="left",$aVAlign="top") { 52 53 54 55 56 57 //$this->Pos($aXAbsPos,$aYAbsPos,$aHAlign,$aVAlign); 58 $this->x = $aXAbsPos; 59 $this->y = $aYAbsPos; 60 $this->halign = $aHAlign; 61 $this->valign = $aVAlign; 57 62 } 58 63 59 64 function SetScalePos($aX,$aY) { 60 61 62 } 63 65 $this->iScalePosX = $aX; 66 $this->iScalePosY = $aY; 67 } 68 64 69 // Specify alignment for the text 65 70 function Align($aHAlign,$aVAlign="top",$aParagraphAlign="") { 66 67 68 69 70 } 71 71 $this->halign = $aHAlign; 72 $this->valign = $aVAlign; 73 if( $aParagraphAlign != "" ) 74 $this->paragraph_align = $aParagraphAlign; 75 } 76 72 77 // Alias 73 78 function SetAlign($aHAlign,$aVAlign="top",$aParagraphAlign="") { 74 79 $this->Align($aHAlign,$aVAlign,$aParagraphAlign); 75 80 } 76 81 77 82 // Specifies the alignment for a multi line text 78 83 function ParagraphAlign($aAlign) { 79 84 $this->paragraph_align = $aAlign; 80 85 } 81 86 82 87 // Specifies the alignment for a multi line text 83 88 function SetParagraphAlign($aAlign) { 84 89 $this->paragraph_align = $aAlign; 85 90 } 86 91 87 92 function SetShadow($aShadowColor='gray',$aShadowWidth=3) { 88 89 90 93 $this->ishadowwidth=$aShadowWidth; 94 $this->shadow=$aShadowColor; 95 $this->boxed=true; 91 96 } 92 97 93 98 function SetWordWrap($aCol) { 94 95 } 96 99 $this->iWordwrap = $aCol ; 100 } 101 97 102 // Specify that the text should be boxed. fcolor=frame color, bcolor=border color, 98 103 // $shadow=drop shadow should be added around the text. 99 104 function SetBox($aFrameColor=array(255,255,255),$aBorderColor=array(0,0,0),$aShadowColor=false,$aCornerRadius=4,$aShadowWidth=3) { 100 if( $aFrameColor==false ) 101 $this->boxed=false; 102 else 103 $this->boxed=true; 104 $this->fcolor=$aFrameColor; 105 $this->bcolor=$aBorderColor; 106 // For backwards compatibility when shadow was just true or false 107 if( $aShadowColor === true ) 108 $aShadowColor = 'gray'; 109 $this->shadow=$aShadowColor; 110 $this->icornerradius=$aCornerRadius; 111 $this->ishadowwidth=$aShadowWidth; 112 } 113 105 if( $aFrameColor === false ) { 106 $this->boxed=false; 107 } 108 else { 109 $this->boxed=true; 110 } 111 $this->fcolor=$aFrameColor; 112 $this->bcolor=$aBorderColor; 113 // For backwards compatibility when shadow was just true or false 114 if( $aShadowColor === true ) { 115 $aShadowColor = 'gray'; 116 } 117 $this->shadow=$aShadowColor; 118 $this->icornerradius=$aCornerRadius; 119 $this->ishadowwidth=$aShadowWidth; 120 } 121 122 function SetBox2($aFrameColor=array(255,255,255),$aBorderColor=array(0,0,0),$aShadowColor=false,$aCornerRadius=4,$aShadowWidth=3) { 123 $this->iBoxType=2; 124 $this->SetBox($aFrameColor,$aBorderColor,$aShadowColor,$aCornerRadius,$aShadowWidth); 125 } 126 114 127 // Hide the text 115 128 function Hide($aHide=true) { 116 117 } 118 119 // This looks ugly since it's not a very orthogonal design 129 $this->hide=$aHide; 130 } 131 132 // This looks ugly since it's not a very orthogonal design 120 133 // but I added this "inverse" of Hide() to harmonize 121 // with some classes which I designed more recently (especially) 134 // with some classes which I designed more recently (especially) 122 135 // jpgraph_gantt 123 136 function Show($aShow=true) { 124 125 } 126 137 $this->hide=!$aShow; 138 } 139 127 140 // Specify font 128 141 function SetFont($aFamily,$aStyle=FS_NORMAL,$aSize=10) { 129 130 131 132 } 133 142 $this->font_family=$aFamily; 143 $this->font_style=$aStyle; 144 $this->font_size=$aSize; 145 } 146 134 147 // Center the text between $left and $right coordinates 135 148 function Center($aLeft,$aRight,$aYAbsPos=false) { 136 $this->x = $aLeft + ($aRight-$aLeft)/2;137 138 139 $this->y = $aYAbsPos; 140 } 141 149 $this->x = $aLeft + ($aRight-$aLeft )/2; 150 $this->halign = "center"; 151 if( is_numeric($aYAbsPos) ) 152 $this->y = $aYAbsPos; 153 } 154 142 155 // Set text color 143 156 function SetColor($aColor) { 144 145 } 146 157 $this->color = $aColor; 158 } 159 147 160 function SetAngle($aAngle) { 148 149 } 150 161 $this->SetOrientation($aAngle); 162 } 163 151 164 // Orientation of text. Note only TTF fonts can have an arbitrary angle 152 165 function SetOrientation($aDirection=0) { 153 if( is_numeric($aDirection) ) 154 $this->dir=$aDirection; 155 elseif( $aDirection=="h" ) 156 $this->dir = 0; 157 elseif( $aDirection=="v" ) 158 $this->dir = 90; 159 else JpGraphError::RaiseL(25051);//(" Invalid direction specified for text."); 160 } 161 166 if( is_numeric($aDirection) ) 167 $this->dir=$aDirection; 168 elseif( $aDirection=="h" ) 169 $this->dir = 0; 170 elseif( $aDirection=="v" ) 171 $this->dir = 90; 172 else 173 JpGraphError::RaiseL(25051);//(" Invalid direction specified for text."); 174 } 175 162 176 // Total width of text 163 177 function GetWidth($aImg) { 164 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size);165 166 return $w; 167 } 168 178 $aImg->SetFont($this->font_family,$this->font_style,$this->raw_font_size); 179 $w = $aImg->GetTextWidth($this->t,$this->dir); 180 return $w; 181 } 182 169 183 // Hight of font 170 184 function GetFontHeight($aImg) { 171 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size);172 173 185 $aImg->SetFont($this->font_family,$this->font_style,$this->raw_font_size); 186 $h = $aImg->GetFontHeight(); 187 return $h; 174 188 175 189 } 176 190 177 191 function GetTextHeight($aImg) { 178 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 179 180 192 $aImg->SetFont($this->font_family,$this->font_style,$this->raw_font_size); 193 $h = $aImg->GetTextHeight($this->t,$this->dir); 194 return $h; 181 195 } 182 196 183 197 function GetHeight($aImg) { 184 185 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 186 187 198 // Synonym for GetTextHeight() 199 $aImg->SetFont($this->font_family,$this->font_style,$this->raw_font_size); 200 $h = $aImg->GetTextHeight($this->t,$this->dir); 201 return $h; 188 202 } 189 203 … … 191 205 // on the context. 192 206 function SetMargin($aMarg) { 193 207 $this->margin = $aMarg; 194 208 } 195 209 196 210 function StrokeWithScale($aImg,$axscale,$ayscale) { 197 if( $this->iScalePosX === null || 198 $this->iScalePosY === null ) { 199 $this->Stroke($aImg); 200 } 201 else { 202 $this->Stroke($aImg, 203 round($axscale->Translate($this->iScalePosX)), 204 round($ayscale->Translate($this->iScalePosY))); 205 } 211 if( $this->iScalePosX === null || $this->iScalePosY === null ) { 212 $this->Stroke($aImg); 213 } 214 else { 215 $this->Stroke($aImg, 216 round($axscale->Translate($this->iScalePosX)), 217 round($ayscale->Translate($this->iScalePosY))); 218 } 206 219 } 207 220 208 221 function SetCSIMTarget($aURITarget,$aAlt='',$aWinTarget='') { 209 210 211 222 $this->iCSIMtarget = $aURITarget; 223 $this->iCSIMalt = $aAlt; 224 $this->iCSIMWinTarget = $aWinTarget; 212 225 } 213 226 214 227 function GetCSIMareas() { 215 if( $this->iCSIMtarget !== '' ) 216 return $this->iCSIMarea; 217 else 218 return ''; 228 if( $this->iCSIMtarget !== '' ) { 229 return $this->iCSIMarea; 230 } 231 else { 232 return ''; 233 } 219 234 } 220 235 … … 222 237 function Stroke($aImg,$x=null,$y=null) { 223 238 224 if( !empty($x) ) $this->x = round($x); 225 if( !empty($y) ) $this->y = round($y); 226 227 // Insert newlines 228 if( $this->iWordwrap > 0 ) { 229 $this->t = wordwrap($this->t,$this->iWordwrap,"\n"); 230 } 231 232 // If position been given as a fraction of the image size 233 // calculate the absolute position 234 if( $this->x < 1 && $this->x > 0 ) $this->x *= $aImg->width; 235 if( $this->y < 1 && $this->y > 0 ) $this->y *= $aImg->height; 236 237 $aImg->PushColor($this->color); 238 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 239 $aImg->SetTextAlign($this->halign,$this->valign); 240 if( $this->boxed ) { 241 if( $this->fcolor=="nofill" ) 242 $this->fcolor=false; 243 $aImg->SetLineWeight(1); 244 $bbox = $aImg->StrokeBoxedText($this->x,$this->y,$this->t, 245 $this->dir,$this->fcolor,$this->bcolor,$this->shadow, 246 $this->paragraph_align,5,5,$this->icornerradius, 247 $this->ishadowwidth); 248 } 249 else { 250 $bbox = $aImg->StrokeText($this->x,$this->y,$this->t,$this->dir,$this->paragraph_align); 251 } 252 253 // Create CSIM targets 254 $coords = $bbox[0].','.$bbox[1].','.$bbox[2].','.$bbox[3].','.$bbox[4].','.$bbox[5].','.$bbox[6].','.$bbox[7]; 255 $this->iCSIMarea = "<area shape=\"poly\" coords=\"$coords\" href=\"".htmlentities($this->iCSIMtarget)."\" "; 256 if( trim($this->iCSIMalt) != '' ) { 257 $this->iCSIMarea .= " alt=\"".$this->iCSIMalt."\" "; 258 $this->iCSIMarea .= " title=\"".$this->iCSIMalt."\" "; 259 } 260 if( trim($this->iCSIMWinTarget) != '' ) { 261 $this->iCSIMarea .= " target=\"".$this->iCSIMWinTarget."\" "; 262 } 263 $this->iCSIMarea .= " />\n"; 264 265 $aImg->PopColor($this->color); 266 239 if( $x !== null ) $this->x = round($x); 240 if( $y !== null ) $this->y = round($y); 241 242 // Insert newlines 243 if( $this->iWordwrap > 0 ) { 244 $this->t = wordwrap($this->t,$this->iWordwrap,"\n"); 245 } 246 247 // If position been given as a fraction of the image size 248 // calculate the absolute position 249 if( $this->x < 1 && $this->x > 0 ) $this->x *= $aImg->width; 250 if( $this->y < 1 && $this->y > 0 ) $this->y *= $aImg->height; 251 252 $aImg->PushColor($this->color); 253 $aImg->SetFont($this->font_family,$this->font_style,$this->raw_font_size); 254 $aImg->SetTextAlign($this->halign,$this->valign); 255 256 if( $this->boxed ) { 257 if( $this->fcolor=="nofill" ) { 258 $this->fcolor=false; 259 } 260 261 $oldweight=$aImg->SetLineWeight(1); 262 263 if( $this->iBoxType == 2 && $this->font_family > FF_FONT2+2 ) { 264 265 $bbox = $aImg->StrokeBoxedText2($this->x, $this->y, 266 $this->t, $this->dir, 267 $this->fcolor, 268 $this->bcolor, 269 $this->shadow, 270 $this->paragraph_align, 271 2,4, 272 $this->icornerradius, 273 $this->ishadowwidth); 274 } 275 else { 276 $bbox = $aImg->StrokeBoxedText($this->x,$this->y,$this->t, 277 $this->dir,$this->fcolor,$this->bcolor,$this->shadow, 278 $this->paragraph_align,3,3,$this->icornerradius, 279 $this->ishadowwidth); 280 } 281 282 $aImg->SetLineWeight($oldweight); 283 } 284 else { 285 $debug=false; 286 $bbox = $aImg->StrokeText($this->x,$this->y,$this->t,$this->dir,$this->paragraph_align,$debug); 287 } 288 289 // Create CSIM targets 290 $coords = $bbox[0].','.$bbox[1].','.$bbox[2].','.$bbox[3].','.$bbox[4].','.$bbox[5].','.$bbox[6].','.$bbox[7]; 291 $this->iCSIMarea = "<area shape=\"poly\" coords=\"$coords\" href=\"".htmlentities($this->iCSIMtarget)."\" "; 292 if( trim($this->iCSIMalt) != '' ) { 293 $this->iCSIMarea .= " alt=\"".$this->iCSIMalt."\" "; 294 $this->iCSIMarea .= " title=\"".$this->iCSIMalt."\" "; 295 } 296 if( trim($this->iCSIMWinTarget) != '' ) { 297 $this->iCSIMarea .= " target=\"".$this->iCSIMWinTarget."\" "; 298 } 299 $this->iCSIMarea .= " />\n"; 300 301 $aImg->PopColor($this->color); 302 } 303 304 function __get($name) { 305 306 if (strpos($name, 'raw_') !== false) { 307 // if $name == 'raw_left_margin' , return $this->_left_margin; 308 $variable_name = '_' . str_replace('raw_', '', $name); 309 return $this->$variable_name; 310 } 311 312 $variable_name = '_' . $name; 313 314 if (isset($this->$variable_name)) { 315 return $this->$variable_name * SUPERSAMPLING_SCALE; 316 } else { 317 JpGraphError::RaiseL('25132', $name); 318 } 319 } 320 321 function __set($name, $value) { 322 $this->{'_'.$name} = $value; 267 323 } 268 324 } // Class -
trunk/client/modules/Elezioni/grafici/jpgraph_ttf.inc.php
r267 r284 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph_ttf.inc.php 1091 2009-01-18 22:57:40Z ljp $3 // File: jpgraph_ttf.inc.php 4 // Description: Handling of TTF fonts 5 // Created: 2006-11-19 6 // Ver: $Id: jpgraph_ttf.inc.php 1858 2009-09-28 14:39:51Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 … … 27 27 define("FF_SIMSUN",30); 28 28 define("FF_CHINESE",31); 29 define("FF_BIG5",3 1);29 define("FF_BIG5",32); 30 30 31 31 // Japanese font … … 48 48 49 49 // Extra fonts 50 // Download fonts from 50 // Download fonts from 51 51 // http://www.webfontlist.com 52 52 // http://www.webpagepublicity.com/free-fonts.html 53 54 define("FF_SPEEDO",71); // This font is also known as Bauer (Used for gauge fascia) 55 define("FF_DIGITAL",72); // Digital readout font 56 define("FF_COMPUTER",73); // The classic computer font 57 define("FF_CALCULATOR",74); // Triad font 53 // http://www.fontonic.com/fonts.asp?width=d&offset=120 54 // http://www.fontspace.com/category/famous 55 56 // define("FF_SPEEDO",71); // This font is also known as Bauer (Used for development gauge fascia) 57 define("FF_DIGITAL",72); // Digital readout font 58 define("FF_COMPUTER",73); // The classic computer font 59 define("FF_CALCULATOR",74); // Triad font 58 60 59 61 define("FF_USERFONT",90); … … 78 80 define("FF_FONT2",4); 79 81 82 //------------------------------------------------------------------------ 83 // Defines for font setup 84 //------------------------------------------------------------------------ 85 86 // Actual name of the TTF file used together with FF_CHINESE aka FF_BIG5 87 // This is the TTF file being used when the font family is specified as 88 // either FF_CHINESE or FF_BIG5 89 define('CHINESE_TTF_FONT','bkai00mp.ttf'); 90 91 // Special unicode greek language support 92 define("LANGUAGE_GREEK",false); 93 94 // If you are setting this config to true the conversion of greek characters 95 // will assume that the input text is windows 1251 96 define("GREEK_FROM_WINDOWS",false); 97 98 // Special unicode cyrillic language support 99 define("LANGUAGE_CYRILLIC",false); 100 101 // If you are setting this config to true the conversion 102 // will assume that the input text is windows 1251, if 103 // false it will assume koi8-r 104 define("CYRILLIC_FROM_WINDOWS",false); 105 106 // The following constant is used to auto-detect 107 // whether cyrillic conversion is really necessary 108 // if enabled. Just replace 'windows-1251' with a variable 109 // containing the input character encoding string 110 // of your application calling jpgraph. 111 // A typical such string would be 'UTF-8' or 'utf-8'. 112 // The comparison is case-insensitive. 113 // If this charset is not a 'koi8-r' or 'windows-1251' 114 // derivate then no conversion is done. 115 // 116 // This constant can be very important in multi-user 117 // multi-language environments where a cyrillic conversion 118 // could be needed for some cyrillic people 119 // and resulting in just erraneous conversions 120 // for not-cyrillic language based people. 121 // 122 // Example: In the free project management 123 // software dotproject.net $locale_char_set is dynamically 124 // set by the language environment the user has chosen. 125 // 126 // Usage: define('LANGUAGE_CHARSET', $locale_char_set); 127 // 128 // where $locale_char_set is a GLOBAL (string) variable 129 // from the application including JpGraph. 130 // 131 define('LANGUAGE_CHARSET', null); 132 133 // Japanese TrueType font used with FF_MINCHO, FF_PMINCHO, FF_GOTHIC, FF_PGOTHIC 134 // Standard fonts from Infomation-technology Promotion Agency (IPA) 135 // See http://mix-mplus-ipa.sourceforge.jp/ 136 define('MINCHO_TTF_FONT','ipam.ttf'); 137 define('PMINCHO_TTF_FONT','ipamp.ttf'); 138 define('GOTHIC_TTF_FONT','ipag.ttf'); 139 define('PGOTHIC_TTF_FONT','ipagp.ttf'); 140 141 // Assume that Japanese text have been entered in EUC-JP encoding. 142 // If this define is true then conversion from EUC-JP to UTF8 is done 143 // automatically in the library using the mbstring module in PHP. 144 define('ASSUME_EUCJP_ENCODING',false); 145 146 147 // Default font family 148 define('FF_DEFAULT', FF_DV_SANSSERIF); 149 150 151 80 152 //================================================================= 81 153 // CLASS LanguageConv 82 // Description: 154 // Description: 83 155 // Converts various character encoding into proper 84 156 // UTF-8 depending on how the library have been configured and … … 89 161 90 162 function Convert($aTxt,$aFF) { 91 92 93 $unistring = LanguageConv::gr_win2uni($aTxt); 94 95 96 97 98 99 100 $aTxt = convert_cyr_string($aTxt, "w", "k"); 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 elseif( $aFF === FF_CHINESE) {120 121 122 //('Usage of FF_CHINESE (FF_BIG5) font family requires that your PHP setup has the iconv() function. By default this is not compiled into PHP (needs the "--width-iconv" when configured).');123 124 125 126 127 128 129 130 131 132 133 134 135 136 else 137 163 if( LANGUAGE_GREEK ) { 164 if( GREEK_FROM_WINDOWS ) { 165 $unistring = LanguageConv::gr_win2uni($aTxt); 166 } else { 167 $unistring = LanguageConv::gr_iso2uni($aTxt); 168 } 169 return $unistring; 170 } elseif( LANGUAGE_CYRILLIC ) { 171 if( CYRILLIC_FROM_WINDOWS && (!defined('LANGUAGE_CHARSET') || stristr(LANGUAGE_CHARSET, 'windows-1251')) ) { 172 $aTxt = convert_cyr_string($aTxt, "w", "k"); 173 } 174 if( !defined('LANGUAGE_CHARSET') || stristr(LANGUAGE_CHARSET, 'koi8-r') || stristr(LANGUAGE_CHARSET, 'windows-1251')) { 175 $isostring = convert_cyr_string($aTxt, "k", "i"); 176 $unistring = LanguageConv::iso2uni($isostring); 177 } 178 else { 179 $unistring = $aTxt; 180 } 181 return $unistring; 182 } 183 elseif( $aFF === FF_SIMSUN ) { 184 // Do Chinese conversion 185 if( $this->g2312 == null ) { 186 include_once 'jpgraph_gb2312.php' ; 187 $this->g2312 = new GB2312toUTF8(); 188 } 189 return $this->g2312->gb2utf8($aTxt); 190 } 191 elseif( $aFF === FF_BIG5 ) { 192 if( !function_exists('iconv') ) { 193 JpGraphError::RaiseL(25006); 194 //('Usage of FF_CHINESE (FF_BIG5) font family requires that your PHP setup has the iconv() function. By default this is not compiled into PHP (needs the "--width-iconv" when configured).'); 195 } 196 return iconv('BIG5','UTF-8',$aTxt); 197 } 198 elseif( ASSUME_EUCJP_ENCODING && 199 ($aFF == FF_MINCHO || $aFF == FF_GOTHIC || $aFF == FF_PMINCHO || $aFF == FF_PGOTHIC) ) { 200 if( !function_exists('mb_convert_encoding') ) { 201 JpGraphError::RaiseL(25127); 202 } 203 return mb_convert_encoding($aTxt, 'UTF-8','EUC-JP'); 204 } 205 elseif( $aFF == FF_DAVID || $aFF == FF_MIRIAM || $aFF == FF_AHRON ) { 206 return LanguageConv::heb_iso2uni($aTxt); 207 } 208 else 209 return $aTxt; 138 210 } 139 211 140 212 // Translate iso encoding to unicode 141 213 public static function iso2uni ($isoline){ 142 143 144 145 146 147 148 214 $uniline=''; 215 for ($i=0; $i < strlen($isoline); $i++){ 216 $thischar=substr($isoline,$i,1); 217 $charcode=ord($thischar); 218 $uniline.=($charcode>175) ? "&#" . (1040+($charcode-176)). ";" : $thischar; 219 } 220 return $uniline; 149 221 } 150 222 151 223 // Translate greek iso encoding to unicode 152 224 public static function gr_iso2uni ($isoline) { 153 154 for ($i=0; $i < strlen($isoline); $i++){155 156 157 158 159 225 $uniline=''; 226 for ($i=0; $i < strlen($isoline); $i++) { 227 $thischar=substr($isoline,$i,1); 228 $charcode=ord($thischar); 229 $uniline.=($charcode>179 && $charcode!=183 && $charcode!=187 && $charcode!=189) ? "&#" . (900+($charcode-180)). ";" : $thischar; 230 } 231 return $uniline; 160 232 } 161 233 162 234 // Translate greek win encoding to unicode 163 235 public static function gr_win2uni ($winline) { 164 165 166 167 168 169 170 171 172 173 174 175 236 $uniline=''; 237 for ($i=0; $i < strlen($winline); $i++) { 238 $thischar=substr($winline,$i,1); 239 $charcode=ord($thischar); 240 if ($charcode==161 || $charcode==162) { 241 $uniline.="&#" . (740+$charcode). ";"; 242 } 243 else { 244 $uniline.=(($charcode>183 && $charcode!=187 && $charcode!=189) || $charcode==180) ? "&#" . (900+($charcode-180)). ";" : $thischar; 245 } 246 } 247 return $uniline; 176 248 } 177 249 178 250 public static function heb_iso2uni($isoline) { 179 180 181 182 183 184 185 186 187 251 $isoline = hebrev($isoline); 252 $o = ''; 253 254 $n = strlen($isoline); 255 for($i=0; $i < $n; $i++) { 256 $c=ord( substr($isoline,$i,1) ); 257 $o .= ($c > 223) && ($c < 251) ? '&#'.(1264+$c).';' : chr($c); 258 } 259 return utf8_encode($o); 188 260 } 189 261 } … … 191 263 //============================================================= 192 264 // CLASS TTF 193 // Description: Handle TTF font names and mapping and loading of 265 // Description: Handle TTF font names and mapping and loading of 194 266 // font files 195 267 //============================================================= … … 197 269 private $font_files,$style_names; 198 270 199 //--------------- 200 // CONSTRUCTOR 201 function TTF() { 202 203 // String names for font styles to be used in error messages 204 $this->style_names=array(FS_NORMAL =>'normal', 205 FS_BOLD =>'bold', 206 FS_ITALIC =>'italic', 207 FS_BOLDITALIC =>'bolditalic'); 208 209 // File names for available fonts 210 $this->font_files=array( 211 FF_COURIER => array(FS_NORMAL =>'cour.ttf', 212 FS_BOLD =>'courbd.ttf', 213 FS_ITALIC =>'couri.ttf', 214 FS_BOLDITALIC =>'courbi.ttf' ), 215 FF_GEORGIA => array(FS_NORMAL =>'georgia.ttf', 216 FS_BOLD =>'georgiab.ttf', 217 FS_ITALIC =>'georgiai.ttf', 218 FS_BOLDITALIC =>'' ), 219 FF_TREBUCHE =>array(FS_NORMAL =>'trebuc.ttf', 220 FS_BOLD =>'trebucbd.ttf', 221 FS_ITALIC =>'trebucit.ttf', 222 FS_BOLDITALIC =>'trebucbi.ttf' ), 223 FF_VERDANA => array(FS_NORMAL =>'verdana.ttf', 224 FS_BOLD =>'verdanab.ttf', 225 FS_ITALIC =>'verdanai.ttf', 226 FS_BOLDITALIC =>'' ), 227 FF_TIMES => array(FS_NORMAL =>'times.ttf', 228 FS_BOLD =>'timesbd.ttf', 229 FS_ITALIC =>'timesi.ttf', 230 FS_BOLDITALIC =>'timesbi.ttf' ), 231 FF_COMIC => array(FS_NORMAL =>'comic.ttf', 232 FS_BOLD =>'comicbd.ttf', 233 FS_ITALIC =>'', 234 FS_BOLDITALIC =>'' ), 235 FF_ARIAL => array(FS_NORMAL =>'arial.ttf', 236 FS_BOLD =>'arialbd.ttf', 237 FS_ITALIC =>'ariali.ttf', 238 FS_BOLDITALIC =>'arialbi.ttf' ) , 239 FF_VERA => array(FS_NORMAL =>'Vera.ttf', 240 FS_BOLD =>'VeraBd.ttf', 241 FS_ITALIC =>'VeraIt.ttf', 242 FS_BOLDITALIC =>'VeraBI.ttf' ), 243 FF_VERAMONO => array(FS_NORMAL =>'VeraMono.ttf', 244 FS_BOLD =>'VeraMoBd.ttf', 245 FS_ITALIC =>'VeraMoIt.ttf', 246 FS_BOLDITALIC =>'VeraMoBI.ttf' ), 247 FF_VERASERIF=> array(FS_NORMAL =>'VeraSe.ttf', 248 FS_BOLD =>'VeraSeBd.ttf', 249 FS_ITALIC =>'', 250 FS_BOLDITALIC =>'' ) , 271 function __construct() { 272 273 // String names for font styles to be used in error messages 274 $this->style_names=array( 275 FS_NORMAL =>'normal', 276 FS_BOLD =>'bold', 277 FS_ITALIC =>'italic', 278 FS_BOLDITALIC =>'bolditalic'); 279 280 // File names for available fonts 281 $this->font_files=array( 282 FF_COURIER => array(FS_NORMAL =>'cour.ttf', 283 FS_BOLD =>'courbd.ttf', 284 FS_ITALIC =>'couri.ttf', 285 FS_BOLDITALIC =>'courbi.ttf' ), 286 FF_GEORGIA => array(FS_NORMAL =>'georgia.ttf', 287 FS_BOLD =>'georgiab.ttf', 288 FS_ITALIC =>'georgiai.ttf', 289 FS_BOLDITALIC =>'' ), 290 FF_TREBUCHE =>array(FS_NORMAL =>'trebuc.ttf', 291 FS_BOLD =>'trebucbd.ttf', 292 FS_ITALIC =>'trebucit.ttf', 293 FS_BOLDITALIC =>'trebucbi.ttf' ), 294 FF_VERDANA => array(FS_NORMAL =>'verdana.ttf', 295 FS_BOLD =>'verdanab.ttf', 296 FS_ITALIC =>'verdanai.ttf', 297 FS_BOLDITALIC =>'' ), 298 FF_TIMES => array(FS_NORMAL =>'times.ttf', 299 FS_BOLD =>'timesbd.ttf', 300 FS_ITALIC =>'timesi.ttf', 301 FS_BOLDITALIC =>'timesbi.ttf' ), 302 FF_COMIC => array(FS_NORMAL =>'comic.ttf', 303 FS_BOLD =>'comicbd.ttf', 304 FS_ITALIC =>'', 305 FS_BOLDITALIC =>'' ), 306 FF_ARIAL => array(FS_NORMAL =>'arial.ttf', 307 FS_BOLD =>'arialbd.ttf', 308 FS_ITALIC =>'ariali.ttf', 309 FS_BOLDITALIC =>'arialbi.ttf' ) , 310 FF_VERA => array(FS_NORMAL =>'Vera.ttf', 311 FS_BOLD =>'VeraBd.ttf', 312 FS_ITALIC =>'VeraIt.ttf', 313 FS_BOLDITALIC =>'VeraBI.ttf' ), 314 FF_VERAMONO => array(FS_NORMAL =>'VeraMono.ttf', 315 FS_BOLD =>'VeraMoBd.ttf', 316 FS_ITALIC =>'VeraMoIt.ttf', 317 FS_BOLDITALIC =>'VeraMoBI.ttf' ), 318 FF_VERASERIF=> array(FS_NORMAL =>'VeraSe.ttf', 319 FS_BOLD =>'VeraSeBd.ttf', 320 FS_ITALIC =>'', 321 FS_BOLDITALIC =>'' ) , 251 322 252 323 /* Chinese fonts */ 253 FF_SIMSUN => array(FS_NORMAL =>'simsun.ttc', 254 FS_BOLD =>'simhei.ttf', 255 FS_ITALIC =>'', 256 FS_BOLDITALIC =>'' ), 257 FF_CHINESE => array(FS_NORMAL =>CHINESE_TTF_FONT, 258 FS_BOLD =>'', 259 FS_ITALIC =>'', 260 FS_BOLDITALIC =>'' ), 324 FF_SIMSUN => array( 325 FS_NORMAL =>'simsun.ttc', 326 FS_BOLD =>'simhei.ttf', 327 FS_ITALIC =>'', 328 FS_BOLDITALIC =>'' ), 329 FF_CHINESE => array( 330 FS_NORMAL =>CHINESE_TTF_FONT, 331 FS_BOLD =>'', 332 FS_ITALIC =>'', 333 FS_BOLDITALIC =>'' ), 334 FF_BIG5 => array( 335 FS_NORMAL =>CHINESE_TTF_FONT, 336 FS_BOLD =>'', 337 FS_ITALIC =>'', 338 FS_BOLDITALIC =>'' ), 261 339 262 340 /* Japanese fonts */ 263 FF_MINCHO => array(FS_NORMAL =>MINCHO_TTF_FONT, 264 FS_BOLD =>'', 265 FS_ITALIC =>'', 266 FS_BOLDITALIC =>'' ), 267 FF_PMINCHO => array(FS_NORMAL =>PMINCHO_TTF_FONT, 268 FS_BOLD =>'', 269 FS_ITALIC =>'', 270 FS_BOLDITALIC =>'' ), 271 FF_GOTHIC => array(FS_NORMAL =>GOTHIC_TTF_FONT, 272 FS_BOLD =>'', 273 FS_ITALIC =>'', 274 FS_BOLDITALIC =>'' ), 275 FF_PGOTHIC => array(FS_NORMAL =>PGOTHIC_TTF_FONT, 276 FS_BOLD =>'', 277 FS_ITALIC =>'', 278 FS_BOLDITALIC =>'' ), 279 FF_MINCHO => array(FS_NORMAL =>PMINCHO_TTF_FONT, 280 FS_BOLD =>'', 281 FS_ITALIC =>'', 282 FS_BOLDITALIC =>'' ), 341 FF_MINCHO => array( 342 FS_NORMAL =>MINCHO_TTF_FONT, 343 FS_BOLD =>'', 344 FS_ITALIC =>'', 345 FS_BOLDITALIC =>'' ), 346 347 FF_PMINCHO => array( 348 FS_NORMAL =>PMINCHO_TTF_FONT, 349 FS_BOLD =>'', 350 FS_ITALIC =>'', 351 FS_BOLDITALIC =>'' ), 352 353 FF_GOTHIC => array( 354 FS_NORMAL =>GOTHIC_TTF_FONT, 355 FS_BOLD =>'', 356 FS_ITALIC =>'', 357 FS_BOLDITALIC =>'' ), 358 359 FF_PGOTHIC => array( 360 FS_NORMAL =>PGOTHIC_TTF_FONT, 361 FS_BOLD =>'', 362 FS_ITALIC =>'', 363 FS_BOLDITALIC =>'' ), 283 364 284 365 /* Hebrew fonts */ 285 FF_DAVID => array(FS_NORMAL =>'DAVIDNEW.TTF', 286 FS_BOLD =>'', 287 FS_ITALIC =>'', 288 FS_BOLDITALIC =>'' ), 289 290 FF_MIRIAM => array(FS_NORMAL =>'MRIAMY.TTF', 291 FS_BOLD =>'', 292 FS_ITALIC =>'', 293 FS_BOLDITALIC =>'' ), 294 295 FF_AHRON => array(FS_NORMAL =>'ahronbd.ttf', 296 FS_BOLD =>'', 297 FS_ITALIC =>'', 298 FS_BOLDITALIC =>'' ), 366 FF_DAVID => array( 367 FS_NORMAL =>'DAVIDNEW.TTF', 368 FS_BOLD =>'', 369 FS_ITALIC =>'', 370 FS_BOLDITALIC =>'' ), 371 372 FF_MIRIAM => array( 373 FS_NORMAL =>'MRIAMY.TTF', 374 FS_BOLD =>'', 375 FS_ITALIC =>'', 376 FS_BOLDITALIC =>'' ), 377 378 FF_AHRON => array( 379 FS_NORMAL =>'ahronbd.ttf', 380 FS_BOLD =>'', 381 FS_ITALIC =>'', 382 FS_BOLDITALIC =>'' ), 299 383 300 384 /* Misc fonts */ 301 FF_DIGITAL => array(FS_NORMAL =>'DIGIRU__.TTF', 302 FS_BOLD =>'Digirtu_.ttf', 303 FS_ITALIC =>'Digir___.ttf', 304 FS_BOLDITALIC =>'DIGIRT__.TTF' ), 305 FF_SPEEDO => array(FS_NORMAL =>'Speedo.ttf', 306 FS_BOLD =>'', 307 FS_ITALIC =>'', 308 FS_BOLDITALIC =>'' ), 309 FF_COMPUTER => array(FS_NORMAL =>'COMPUTER.TTF', 310 FS_BOLD =>'', 311 FS_ITALIC =>'', 312 FS_BOLDITALIC =>'' ), 313 FF_CALCULATOR => array(FS_NORMAL =>'Triad_xs.ttf', 314 FS_BOLD =>'', 315 FS_ITALIC =>'', 316 FS_BOLDITALIC =>'' ), 385 FF_DIGITAL => array( 386 FS_NORMAL =>'DIGIRU__.TTF', 387 FS_BOLD =>'Digirtu_.ttf', 388 FS_ITALIC =>'Digir___.ttf', 389 FS_BOLDITALIC =>'DIGIRT__.TTF' ), 390 391 /* This is an experimental font for the speedometer development 392 FF_SPEEDO => array( 393 FS_NORMAL =>'Speedo.ttf', 394 FS_BOLD =>'', 395 FS_ITALIC =>'', 396 FS_BOLDITALIC =>'' ), 397 */ 398 399 FF_COMPUTER => array( 400 FS_NORMAL =>'COMPUTER.TTF', 401 FS_BOLD =>'', 402 FS_ITALIC =>'', 403 FS_BOLDITALIC =>'' ), 404 405 FF_CALCULATOR => array( 406 FS_NORMAL =>'Triad_xs.ttf', 407 FS_BOLD =>'', 408 FS_ITALIC =>'', 409 FS_BOLDITALIC =>'' ), 317 410 318 411 /* Dejavu fonts */ 319 FF_DV_SANSSERIF => array(FS_NORMAL =>'DejaVuSans.ttf', 320 FS_BOLD =>'DejaVuSans-Bold.ttf', 321 FS_ITALIC =>'DejaVuSans-Oblique.ttf', 322 FS_BOLDITALIC =>'DejaVuSans-BoldOblique.ttf' ), 323 324 FF_DV_SANSSERIFMONO => array(FS_NORMAL =>'DejaVuSansMono.ttf', 325 FS_BOLD =>'DejaVuSansMono-Bold.ttf', 326 FS_ITALIC =>'DejaVuSansMono-Oblique.ttf', 327 FS_BOLDITALIC =>'DejaVuSansMono-BoldOblique.ttf' ), 328 329 FF_DV_SANSSERIFCOND => array(FS_NORMAL =>'DejaVuSansCondensed.ttf', 330 FS_BOLD =>'DejaVuSansCondensed-Bold.ttf', 331 FS_ITALIC =>'DejaVuSansCondensed-Oblique.ttf', 332 FS_BOLDITALIC =>'DejaVuSansCondensed-BoldOblique.ttf' ), 333 334 FF_DV_SERIF => array(FS_NORMAL =>'DejaVuSerif.ttf', 335 FS_BOLD =>'DejaVuSerif-Bold.ttf', 336 FS_ITALIC =>'DejaVuSerif-Italic.ttf', 337 FS_BOLDITALIC =>'DejaVuSerif-BoldItalic.ttf' ), 338 339 FF_DV_SERIFCOND => array(FS_NORMAL =>'DejaVuSerifCondensed.ttf', 340 FS_BOLD =>'DejaVuSerifCondensed-Bold.ttf', 341 FS_ITALIC =>'DejaVuSerifCondensed-Italic.ttf', 342 FS_BOLDITALIC =>'DejaVuSerifCondensed-BoldItalic.ttf' ), 343 344 345 /* User defined font */ 346 FF_USERFONT1 => array(FS_NORMAL =>'', 347 FS_BOLD =>'', 348 FS_ITALIC =>'', 349 FS_BOLDITALIC =>'' ), 350 351 FF_USERFONT2 => array(FS_NORMAL =>'', 352 FS_BOLD =>'', 353 FS_ITALIC =>'', 354 FS_BOLDITALIC =>'' ), 355 356 FF_USERFONT3 => array(FS_NORMAL =>'', 357 FS_BOLD =>'', 358 FS_ITALIC =>'', 359 FS_BOLDITALIC =>'' ), 360 361 ); 362 } 363 364 //--------------- 365 // PUBLIC METHODS 412 FF_DV_SANSSERIF => array( 413 FS_NORMAL =>array('DejaVuSans.ttf'), 414 FS_BOLD =>array('DejaVuSans-Bold.ttf','DejaVuSansBold.ttf'), 415 FS_ITALIC =>array('DejaVuSans-Oblique.ttf','DejaVuSansOblique.ttf'), 416 FS_BOLDITALIC =>array('DejaVuSans-BoldOblique.ttf','DejaVuSansBoldOblique.ttf') ), 417 418 FF_DV_SANSSERIFMONO => array( 419 FS_NORMAL =>array('DejaVuSansMono.ttf','DejaVuMonoSans.ttf'), 420 FS_BOLD =>array('DejaVuSansMono-Bold.ttf','DejaVuMonoSansBold.ttf'), 421 FS_ITALIC =>array('DejaVuSansMono-Oblique.ttf','DejaVuMonoSansOblique.ttf'), 422 FS_BOLDITALIC =>array('DejaVuSansMono-BoldOblique.ttf','DejaVuMonoSansBoldOblique.ttf') ), 423 424 FF_DV_SANSSERIFCOND => array( 425 FS_NORMAL =>array('DejaVuSansCondensed.ttf','DejaVuCondensedSans.ttf'), 426 FS_BOLD =>array('DejaVuSansCondensed-Bold.ttf','DejaVuCondensedSansBold.ttf'), 427 FS_ITALIC =>array('DejaVuSansCondensed-Oblique.ttf','DejaVuCondensedSansOblique.ttf'), 428 FS_BOLDITALIC =>array('DejaVuSansCondensed-BoldOblique.ttf','DejaVuCondensedSansBoldOblique.ttf') ), 429 430 FF_DV_SERIF => array( 431 FS_NORMAL =>array('DejaVuSerif.ttf'), 432 FS_BOLD =>array('DejaVuSerif-Bold.ttf','DejaVuSerifBold.ttf'), 433 FS_ITALIC =>array('DejaVuSerif-Italic.ttf','DejaVuSerifItalic.ttf'), 434 FS_BOLDITALIC =>array('DejaVuSerif-BoldItalic.ttf','DejaVuSerifBoldItalic.ttf') ), 435 436 FF_DV_SERIFCOND => array( 437 FS_NORMAL =>array('DejaVuSerifCondensed.ttf','DejaVuCondensedSerif.ttf'), 438 FS_BOLD =>array('DejaVuSerifCondensed-Bold.ttf','DejaVuCondensedSerifBold.ttf'), 439 FS_ITALIC =>array('DejaVuSerifCondensed-Italic.ttf','DejaVuCondensedSerifItalic.ttf'), 440 FS_BOLDITALIC =>array('DejaVuSerifCondensed-BoldItalic.ttf','DejaVuCondensedSerifBoldItalic.ttf') ), 441 442 443 /* Placeholders for defined fonts */ 444 FF_USERFONT1 => array( 445 FS_NORMAL =>'', 446 FS_BOLD =>'', 447 FS_ITALIC =>'', 448 FS_BOLDITALIC =>'' ), 449 450 FF_USERFONT2 => array( 451 FS_NORMAL =>'', 452 FS_BOLD =>'', 453 FS_ITALIC =>'', 454 FS_BOLDITALIC =>'' ), 455 456 FF_USERFONT3 => array( 457 FS_NORMAL =>'', 458 FS_BOLD =>'', 459 FS_ITALIC =>'', 460 FS_BOLDITALIC =>'' ), 461 462 ); 463 } 464 465 //--------------- 466 // PUBLIC METHODS 366 467 // Create the TTF file from the font specification 367 468 function File($family,$style=FS_NORMAL) { 368 $fam = @$this->font_files[$family]; 369 if( !$fam ) { 370 JpGraphError::RaiseL(25046,$family);//("Specified TTF font family (id=$family) is unknown or does not exist. Please note that TTF fonts are not distributed with JpGraph for copyright reasons. You can find the MS TTF WEB-fonts (arial, courier etc) for download at http://corefonts.sourceforge.net/"); 371 } 372 $f = @$fam[$style]; 373 374 if( $f==='' ) 375 JpGraphError::RaiseL(25047,$this->style_names[$style],$this->font_files[$family][FS_NORMAL]);//('Style "'.$this->style_names[$style].'" is not available for font family '.$this->font_files[$family][FS_NORMAL].'.'); 376 if( !$f ) { 377 JpGraphError::RaiseL(25048,$fam);//("Unknown font style specification [$fam]."); 378 } 379 380 if ($family >= FF_MINCHO && $family <= FF_PGOTHIC) { 381 $f = MBTTF_DIR.$f; 382 } else { 383 $f = TTF_DIR.$f; 384 } 385 386 if( file_exists($f) === false || is_readable($f) === false ) { 387 JpGraphError::RaiseL(25049,$f);//("Font file \"$f\" is not readable or does not exist."); 388 } 389 return $f; 469 $fam = @$this->font_files[$family]; 470 if( !$fam ) { 471 JpGraphError::RaiseL(25046,$family);//("Specified TTF font family (id=$family) is unknown or does not exist. Please note that TTF fonts are not distributed with JpGraph for copyright reasons. You can find the MS TTF WEB-fonts (arial, courier etc) for download at http://corefonts.sourceforge.net/"); 472 } 473 $ff = @$fam[$style]; 474 475 // There are several optional file names. They are tried in order 476 // and the first one found is used 477 if( !is_array($ff) ) { 478 $ff = array($ff); 479 } 480 481 $jpgraph_font_dir = dirname(__FILE__).'/fonts/'; 482 483 foreach ($ff as $font_file) { 484 // All font families are guaranteed to have the normal style 485 486 if( $font_file==='' ) 487 JpGraphError::RaiseL(25047,$this->style_names[$style],$this->font_files[$family][FS_NORMAL]);//('Style "'.$this->style_names[$style].'" is not available for font family '.$this->font_files[$family][FS_NORMAL].'.'); 488 if( !$font_file ) { 489 JpGraphError::RaiseL(25048,$fam);//("Unknown font style specification [$fam]."); 490 } 491 492 // check jpgraph/src/fonts dir 493 $jpgraph_font_file = $jpgraph_font_dir . $font_file; 494 if (file_exists($jpgraph_font_file) === true && is_readable($jpgraph_font_file) === true) { 495 $font_file = $jpgraph_font_file; 496 break; 497 } 498 499 // check OS font dir 500 if ($family >= FF_MINCHO && $family <= FF_PGOTHIC) { 501 $font_file = MBTTF_DIR.$font_file; 502 } else { 503 $font_file = TTF_DIR.$font_file; 504 } 505 if (file_exists($font_file) === true && is_readable($font_file) === true) { 506 break; 507 } 508 } 509 510 if( !file_exists($font_file) ) { 511 JpGraphError::RaiseL(25049,$font_file);//("Font file \"$font_file\" is not readable or does not exist."); 512 } 513 514 return $font_file; 390 515 } 391 516 392 517 function SetUserFont($aNormal,$aBold='',$aItalic='',$aBoldIt='') { 393 $this->font_files[FF_USERFONT] = 394 array(FS_NORMAL => $aNormal, 395 FS_BOLD => $aBold, 396 FS_ITALIC => $aItalic, 397 FS_BOLDITALIC=> $aBoldIt ) ;518 $this->font_files[FF_USERFONT] = 519 array(FS_NORMAL => $aNormal, 520 FS_BOLD => $aBold, 521 FS_ITALIC => $aItalic, 522 FS_BOLDITALIC => $aBoldIt ) ; 398 523 } 399 524 400 525 function SetUserFont1($aNormal,$aBold='',$aItalic='',$aBoldIt='') { 401 $this->font_files[FF_USERFONT1] = 402 array(FS_NORMAL => $aNormal, 403 FS_BOLD => $aBold, 404 FS_ITALIC => $aItalic, 405 FS_BOLDITALIC=> $aBoldIt ) ;526 $this->font_files[FF_USERFONT1] = 527 array(FS_NORMAL => $aNormal, 528 FS_BOLD => $aBold, 529 FS_ITALIC => $aItalic, 530 FS_BOLDITALIC => $aBoldIt ) ; 406 531 } 407 532 408 533 function SetUserFont2($aNormal,$aBold='',$aItalic='',$aBoldIt='') { 409 $this->font_files[FF_USERFONT2] = 410 array(FS_NORMAL => $aNormal, 411 FS_BOLD => $aBold, 412 FS_ITALIC => $aItalic, 413 FS_BOLDITALIC=> $aBoldIt ) ;534 $this->font_files[FF_USERFONT2] = 535 array(FS_NORMAL => $aNormal, 536 FS_BOLD => $aBold, 537 FS_ITALIC => $aItalic, 538 FS_BOLDITALIC => $aBoldIt ) ; 414 539 } 415 540 416 541 function SetUserFont3($aNormal,$aBold='',$aItalic='',$aBoldIt='') { 417 $this->font_files[FF_USERFONT3] = 418 array(FS_NORMAL => $aNormal, 419 FS_BOLD => $aBold, 420 FS_ITALIC => $aItalic, 421 FS_BOLDITALIC=> $aBoldIt ) ;542 $this->font_files[FF_USERFONT3] = 543 array(FS_NORMAL => $aNormal, 544 FS_BOLD => $aBold, 545 FS_ITALIC => $aItalic, 546 FS_BOLDITALIC => $aBoldIt ) ; 422 547 } 423 548 … … 425 550 426 551 552 //============================================================================= 553 // CLASS SymChar 554 // Description: Code values for some commonly used characters that 555 // normally isn't available directly on the keyboard, for example 556 // mathematical and greek symbols. 557 //============================================================================= 558 class SymChar { 559 static function Get($aSymb,$aCapital=FALSE) { 560 $iSymbols = array( 561 /* Greek */ 562 array('alpha','03B1','0391'), 563 array('beta','03B2','0392'), 564 array('gamma','03B3','0393'), 565 array('delta','03B4','0394'), 566 array('epsilon','03B5','0395'), 567 array('zeta','03B6','0396'), 568 array('ny','03B7','0397'), 569 array('eta','03B8','0398'), 570 array('theta','03B8','0398'), 571 array('iota','03B9','0399'), 572 array('kappa','03BA','039A'), 573 array('lambda','03BB','039B'), 574 array('mu','03BC','039C'), 575 array('nu','03BD','039D'), 576 array('xi','03BE','039E'), 577 array('omicron','03BF','039F'), 578 array('pi','03C0','03A0'), 579 array('rho','03C1','03A1'), 580 array('sigma','03C3','03A3'), 581 array('tau','03C4','03A4'), 582 array('upsilon','03C5','03A5'), 583 array('phi','03C6','03A6'), 584 array('chi','03C7','03A7'), 585 array('psi','03C8','03A8'), 586 array('omega','03C9','03A9'), 587 /* Money */ 588 array('euro','20AC'), 589 array('yen','00A5'), 590 array('pound','20A4'), 591 /* Math */ 592 array('approx','2248'), 593 array('neq','2260'), 594 array('not','2310'), 595 array('def','2261'), 596 array('inf','221E'), 597 array('sqrt','221A'), 598 array('int','222B'), 599 /* Misc */ 600 array('copy','00A9'), 601 array('para','00A7'), 602 array('tm','2122'), /* Trademark symbol */ 603 array('rtm','00AE'), /* Registered trademark */ 604 array('degree','00b0'), 605 array('lte','2264'), /* Less than or equal */ 606 array('gte','2265'), /* Greater than or equal */ 607 608 ); 609 610 $n = count($iSymbols); 611 $i=0; 612 $found = false; 613 $aSymb = strtolower($aSymb); 614 while( $i < $n && !$found ) { 615 $found = $aSymb === $iSymbols[$i++][0]; 616 } 617 if( $found ) { 618 $ca = $iSymbols[--$i]; 619 if( $aCapital && count($ca)==3 ) 620 $s = $ca[2]; 621 else 622 $s = $ca[1]; 623 return sprintf('&#%04d;',hexdec($s)); 624 } 625 else 626 return ''; 627 } 628 } 629 427 630 428 631 ?> -
trunk/client/modules/Elezioni/grafici/jpgraph_utils.inc.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_UTILS.INC4 // Description: Collection of non-essential "nice to have" utilities 5 // Created:2005-11-206 // Ver: $Id: jpgraph_utils.inc.php 1091 2009-01-18 22:57:40Z ljp $7 //8 // Copyright (c) Aditus Consulting. All rights reserved.9 //========================================================================10 */3 // File: JPGRAPH_UTILS.INC 4 // Description: Collection of non-essential "nice to have" utilities 5 // Created: 2005-11-20 6 // Ver: $Id: jpgraph_utils.inc.php 1777 2009-08-23 17:34:36Z ljp $ 7 // 8 // Copyright (c) Asial Corporation. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 //=================================================== 13 13 // CLASS FuncGenerator 14 // Description: Utility class to help generate data for function plots. 14 // Description: Utility class to help generate data for function plots. 15 15 // The class supports both parametric and regular functions. 16 16 //=================================================== 17 17 class FuncGenerator { 18 18 private $iFunc='',$iXFunc='',$iMin,$iMax,$iStepSize; 19 20 function FuncGenerator($aFunc,$aXFunc='') {21 22 23 } 24 19 20 function __construct($aFunc,$aXFunc='') { 21 $this->iFunc = $aFunc; 22 $this->iXFunc = $aXFunc; 23 } 24 25 25 function E($aXMin,$aXMax,$aSteps=50) { 26 $this->iMin = $aXMin; 27 $this->iMax = $aXMax; 28 $this->iStepSize = ($aXMax-$aXMin)/$aSteps; 29 30 if( $this->iXFunc != '' ) 31 $t = 'for($i='.$aXMin.'; $i<='.$aXMax.'; $i += '.$this->iStepSize.') {$ya[]='.$this->iFunc.';$xa[]='.$this->iXFunc.';}'; 32 elseif( $this->iFunc != '' ) 33 $t = 'for($x='.$aXMin.'; $x<='.$aXMax.'; $x += '.$this->iStepSize.') {$ya[]='.$this->iFunc.';$xa[]=$x;} $x='.$aXMax.';$ya[]='.$this->iFunc.';$xa[]=$x;'; 34 else 35 JpGraphError::RaiseL(24001);//('FuncGenerator : No function specified. '); 36 37 @eval($t); 38 39 // If there is an error in the function specifcation this is the only 40 // way we can discover that. 41 if( empty($xa) || empty($ya) ) 42 JpGraphError::RaiseL(24002);//('FuncGenerator : Syntax error in function specification '); 43 44 return array($xa,$ya); 45 } 46 } 47 48 //============================================================================= 49 // CLASS SymChar 50 // Description: Code values for some commonly used characters that 51 // normally isn't available directly on the keyboard, for example 52 // mathematical and greek symbols. 53 //============================================================================= 54 class SymChar { 55 static function Get($aSymb,$aCapital=FALSE) { 56 $iSymbols = array( 57 /* Greek */ 58 array('alpha','03B1','0391'), 59 array('beta','03B2','0392'), 60 array('gamma','03B3','0393'), 61 array('delta','03B4','0394'), 62 array('epsilon','03B5','0395'), 63 array('zeta','03B6','0396'), 64 array('ny','03B7','0397'), 65 array('eta','03B8','0398'), 66 array('theta','03B8','0398'), 67 array('iota','03B9','0399'), 68 array('kappa','03BA','039A'), 69 array('lambda','03BB','039B'), 70 array('mu','03BC','039C'), 71 array('nu','03BD','039D'), 72 array('xi','03BE','039E'), 73 array('omicron','03BF','039F'), 74 array('pi','03C0','03A0'), 75 array('rho','03C1','03A1'), 76 array('sigma','03C3','03A3'), 77 array('tau','03C4','03A4'), 78 array('upsilon','03C5','03A5'), 79 array('phi','03C6','03A6'), 80 array('chi','03C7','03A7'), 81 array('psi','03C8','03A8'), 82 array('omega','03C9','03A9'), 83 /* Money */ 84 array('euro','20AC'), 85 array('yen','00A5'), 86 array('pound','20A4'), 87 /* Math */ 88 array('approx','2248'), 89 array('neq','2260'), 90 array('not','2310'), 91 array('def','2261'), 92 array('inf','221E'), 93 array('sqrt','221A'), 94 array('int','222B'), 95 /* Misc */ 96 array('copy','00A9'), 97 array('para','00A7'), 98 array('tm','2122'), /* Trademark symbol */ 99 array('rtm','00AE') /* Registered trademark */ 100 101 ); 102 103 $n = count($iSymbols); 104 $i=0; 105 $found = false; 106 $aSymb = strtolower($aSymb); 107 while( $i < $n && !$found ) { 108 $found = $aSymb === $iSymbols[$i++][0]; 109 } 110 if( $found ) { 111 $ca = $iSymbols[--$i]; 112 if( $aCapital && count($ca)==3 ) 113 $s = $ca[2]; 114 else 115 $s = $ca[1]; 116 return sprintf('&#%04d;',hexdec($s)); 117 } 118 else 119 return ''; 26 $this->iMin = $aXMin; 27 $this->iMax = $aXMax; 28 $this->iStepSize = ($aXMax-$aXMin)/$aSteps; 29 30 if( $this->iXFunc != '' ) 31 $t = 'for($i='.$aXMin.'; $i<='.$aXMax.'; $i += '.$this->iStepSize.') {$ya[]='.$this->iFunc.';$xa[]='.$this->iXFunc.';}'; 32 elseif( $this->iFunc != '' ) 33 $t = 'for($x='.$aXMin.'; $x<='.$aXMax.'; $x += '.$this->iStepSize.') {$ya[]='.$this->iFunc.';$xa[]=$x;} $x='.$aXMax.';$ya[]='.$this->iFunc.';$xa[]=$x;'; 34 else 35 JpGraphError::RaiseL(24001);//('FuncGenerator : No function specified. '); 36 37 @eval($t); 38 39 // If there is an error in the function specifcation this is the only 40 // way we can discover that. 41 if( empty($xa) || empty($ya) ) 42 JpGraphError::RaiseL(24002);//('FuncGenerator : Syntax error in function specification '); 43 44 return array($xa,$ya); 120 45 } 121 46 } … … 151 76 152 77 static function UseWeekFormat($aFlg) { 153 78 self::$iUseWeeks = $aFlg; 154 79 } 155 80 156 81 static function doYearly($aType,$aMinor=false) { 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); 180 181 182 183 $y=self::$startyear; 184 185 self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); 186 for($k=0; $k < 1; ++$k ) { 187 188 189 190 191 192 193 194 195 196 $y=self::$startyear; 197 198 self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); 199 for($k=0; $k < 4; ++$k ) { 200 201 202 203 204 205 206 207 208 82 $i=0; $j=0; 83 $m = self::$startmonth; 84 $y = self::$startyear; 85 86 if( self::$startday == 1 ) { 87 self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); 88 } 89 ++$m; 90 91 92 switch( $aType ) { 93 case DSUTILS_YEAR1: 94 for($y=self::$startyear; $y <= self::$endyear; ++$y ) { 95 if( $aMinor ) { 96 while( $m <= 12 ) { 97 if( !($y == self::$endyear && $m > self::$endmonth) ) { 98 self::$minTickPositions[$j++] = mktime(0,0,0,$m,1,$y); 99 } 100 ++$m; 101 } 102 $m=1; 103 } 104 self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); 105 } 106 break; 107 case DSUTILS_YEAR2: 108 $y=self::$startyear; 109 while( $y <= self::$endyear ) { 110 self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); 111 for($k=0; $k < 1; ++$k ) { 112 ++$y; 113 if( $aMinor ) { 114 self::$minTickPositions[$j++] = mktime(0,0,0,1,1,$y); 115 } 116 } 117 ++$y; 118 } 119 break; 120 case DSUTILS_YEAR5: 121 $y=self::$startyear; 122 while( $y <= self::$endyear ) { 123 self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); 124 for($k=0; $k < 4; ++$k ) { 125 ++$y; 126 if( $aMinor ) { 127 self::$minTickPositions[$j++] = mktime(0,0,0,1,1,$y); 128 } 129 } 130 ++$y; 131 } 132 break; 133 } 209 134 } 210 135 211 136 static function doDaily($aType,$aMinor=false) { 212 213 214 215 216 217 218 219 220 221 $t = mktime(0,0,0,$m,$d,$y); 222 223 224 225 226 227 228 229 self::$minTickPositions[$j++] = strtotime('+12 hours',$t); 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 137 $m = self::$startmonth; 138 $y = self::$startyear; 139 $d = self::$startday; 140 $h = self::$starthour; 141 $i=0;$j=0; 142 143 if( $h == 0 ) { 144 self::$tickPositions[$i++] = mktime(0,0,0,$m,$d,$y); 145 } 146 $t = mktime(0,0,0,$m,$d,$y); 147 148 switch($aType) { 149 case DSUTILS_DAY1: 150 while( $t <= self::$iMax ) { 151 $t = strtotime('+1 day',$t); 152 self::$tickPositions[$i++] = $t; 153 if( $aMinor ) { 154 self::$minTickPositions[$j++] = strtotime('+12 hours',$t); 155 } 156 } 157 break; 158 case DSUTILS_DAY2: 159 while( $t <= self::$iMax ) { 160 $t = strtotime('+1 day',$t); 161 if( $aMinor ) { 162 self::$minTickPositions[$j++] = $t; 163 } 164 $t = strtotime('+1 day',$t); 165 self::$tickPositions[$i++] = $t; 166 } 167 break; 168 case DSUTILS_DAY4: 169 while( $t <= self::$iMax ) { 170 for($k=0; $k < 3; ++$k ) { 171 $t = strtotime('+1 day',$t); 172 if( $aMinor ) { 173 self::$minTickPositions[$j++] = $t; 174 } 175 } 176 $t = strtotime('+1 day',$t); 177 self::$tickPositions[$i++] = $t; 178 } 179 break; 180 } 256 181 } 257 182 258 183 static function doWeekly($aType,$aMinor=false) { 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 184 $hpd = 3600*24; 185 $hpw = 3600*24*7; 186 // Find out week number of min date 187 $thursday = self::$iMin + $hpd * (3 - (date('w', self::$iMin) + 6) % 7); 188 $week = 1 + (date('z', $thursday) - (11 - date('w', mktime(0, 0, 0, 1, 1, date('Y', $thursday)))) % 7) / 7; 189 $daynumber = date('w',self::$iMin); 190 if( $daynumber == 0 ) $daynumber = 7; 191 $m = self::$startmonth; 192 $y = self::$startyear; 193 $d = self::$startday; 194 $i=0;$j=0; 195 // The assumption is that the weeks start on Monday. If the first day 196 // is later in the week then the first week tick has to be on the following 197 // week. 198 if( $daynumber == 1 ) { 199 self::$tickPositions[$i++] = mktime(0,0,0,$m,$d,$y); 200 $t = mktime(0,0,0,$m,$d,$y) + $hpw; 201 } 202 else { 203 $t = mktime(0,0,0,$m,$d,$y) + $hpd*(8-$daynumber); 204 } 205 206 switch($aType) { 207 case DSUTILS_WEEK1: 208 $cnt=0; 209 break; 210 case DSUTILS_WEEK2: 211 $cnt=1; 212 break; 213 case DSUTILS_WEEK4: 214 $cnt=3; 215 break; 216 } 217 while( $t <= self::$iMax ) { 218 self::$tickPositions[$i++] = $t; 219 for($k=0; $k < $cnt; ++$k ) { 220 $t += $hpw; 221 if( $aMinor ) { 222 self::$minTickPositions[$j++] = $t; 223 } 224 } 225 $t += $hpw; 226 } 302 227 } 303 228 304 229 static function doMonthly($aType,$aMinor=false) { 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 case DSUTILS_MONTH1: 332 333 334 335 if( !($y==self::$endyear && $m==$stopmonth && self::$endday < 15) ) 336 337 338 339 // Major at month 340 341 342 343 344 case DSUTILS_MONTH2: 345 346 347 348 349 350 // Major at every second month 351 352 353 354 355 356 case DSUTILS_MONTH3: 357 358 359 360 361 // Major at every third month 362 363 364 365 366 367 case DSUTILS_MONTH6: 368 369 370 371 372 // Major at every third month 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 } 391 392 230 $monthcount=0; 231 $m = self::$startmonth; 232 $y = self::$startyear; 233 $i=0; $j=0; 234 235 // Skip the first month label if it is before the startdate 236 if( self::$startday == 1 ) { 237 self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); 238 $monthcount=1; 239 } 240 if( $aType == 1 ) { 241 if( self::$startday < 15 ) { 242 self::$minTickPositions[$j++] = mktime(0,0,0,$m,15,$y); 243 } 244 } 245 ++$m; 246 247 // Loop through all the years included in the scale 248 for($y=self::$startyear; $y <= self::$endyear; ++$y ) { 249 // Loop through all the months. There are three cases to consider: 250 // 1. We are in the first year and must start with the startmonth 251 // 2. We are in the end year and we must stop at last month of the scale 252 // 3. A year in between where we run through all the 12 months 253 $stopmonth = $y == self::$endyear ? self::$endmonth : 12; 254 while( $m <= $stopmonth ) { 255 switch( $aType ) { 256 case DSUTILS_MONTH1: 257 // Set minor tick at the middle of the month 258 if( $aMinor ) { 259 if( $m <= $stopmonth ) { 260 if( !($y==self::$endyear && $m==$stopmonth && self::$endday < 15) ) 261 self::$minTickPositions[$j++] = mktime(0,0,0,$m,15,$y); 262 } 263 } 264 // Major at month 265 // Get timestamp of first hour of first day in each month 266 self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); 267 268 break; 269 case DSUTILS_MONTH2: 270 if( $aMinor ) { 271 // Set minor tick at start of each month 272 self::$minTickPositions[$j++] = mktime(0,0,0,$m,1,$y); 273 } 274 275 // Major at every second month 276 // Get timestamp of first hour of first day in each month 277 if( $monthcount % 2 == 0 ) { 278 self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); 279 } 280 break; 281 case DSUTILS_MONTH3: 282 if( $aMinor ) { 283 // Set minor tick at start of each month 284 self::$minTickPositions[$j++] = mktime(0,0,0,$m,1,$y); 285 } 286 // Major at every third month 287 // Get timestamp of first hour of first day in each month 288 if( $monthcount % 3 == 0 ) { 289 self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); 290 } 291 break; 292 case DSUTILS_MONTH6: 293 if( $aMinor ) { 294 // Set minor tick at start of each month 295 self::$minTickPositions[$j++] = mktime(0,0,0,$m,1,$y); 296 } 297 // Major at every third month 298 // Get timestamp of first hour of first day in each month 299 if( $monthcount % 6 == 0 ) { 300 self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); 301 } 302 break; 303 } 304 ++$m; 305 ++$monthcount; 306 } 307 $m=1; 308 } 309 310 // For the case where all dates are within the same month 311 // we want to make sure we have at least two ticks on the scale 312 // since the scale want work properly otherwise 313 if(self::$startmonth == self::$endmonth && self::$startyear == self::$endyear && $aType==1 ) { 314 self::$tickPositions[$i++] = mktime(0 ,0 ,0, self::$startmonth + 1, 1, self::$startyear); 315 } 316 317 return array(self::$tickPositions,self::$minTickPositions); 393 318 } 394 319 395 320 static function GetTicks($aData,$aType=1,$aMinor=false,$aEndPoints=false) { 396 397 321 $n = count($aData); 322 return self::GetTicksFromMinMax($aData[0],$aData[$n-1],$aType,$aMinor,$aEndPoints); 398 323 } 399 324 400 325 static function GetAutoTicks($aMin,$aMax,$aMaxTicks=10,$aMinor=false) { 401 $diff = $aMax - $aMin; 402 $spd = 3600*24; 403 $spw = $spd*7; 404 $spm = $spd*30; 405 $spy = $spd*352; 406 407 if( self::$iUseWeeks ) 408 $w = 'W'; 409 else 410 $w = 'd M'; 411 412 // Decision table for suitable scales 413 // First value: Main decision point 414 // Second value: Array of formatting depending on divisor for wanted max number of ticks. <divisor><formatting><format-string>,.. 415 $tt = array( 416 array($spw, array(1,DSUTILS_DAY1,'d M',2,DSUTILS_DAY2,'d M',-1,DSUTILS_DAY4,'d M')), 417 array($spm, array(1,DSUTILS_DAY1,'d M',2,DSUTILS_DAY2,'d M',4,DSUTILS_DAY4,'d M', 418 7,DSUTILS_WEEK1,$w,-1,DSUTILS_WEEK2,$w)), 419 array($spy, array(1,DSUTILS_DAY1,'d M',2,DSUTILS_DAY2,'d M',4,DSUTILS_DAY4,'d M', 420 7,DSUTILS_WEEK1,$w,14,DSUTILS_WEEK2,$w, 421 30,DSUTILS_MONTH1,'M',60,DSUTILS_MONTH2,'M',-1,DSUTILS_MONTH3,'M')), 422 array(-1, array(30,DSUTILS_MONTH1,'M-Y',60,DSUTILS_MONTH2,'M-Y',90,DSUTILS_MONTH3,'M-Y', 423 180,DSUTILS_MONTH6,'M-Y',352,DSUTILS_YEAR1,'Y',704,DSUTILS_YEAR2,'Y',-1,DSUTILS_YEAR5,'Y'))); 424 425 $ntt = count($tt); 426 $nd = floor($diff/$spd); 427 for($i=0; $i < $ntt; ++$i ) { 428 if( $diff <= $tt[$i][0] || $i==$ntt-1) { 429 $t = $tt[$i][1]; 430 $n = count($t)/3; 431 for( $j=0; $j < $n; ++$j ) { 432 if( $nd/$t[3*$j] <= $aMaxTicks || $j==$n-1) { 433 $type = $t[3*$j+1]; 434 $fs = $t[3*$j+2]; 435 list($tickPositions,$minTickPositions) = self::GetTicksFromMinMax($aMin,$aMax,$type,$aMinor); 436 return array($fs,$tickPositions,$minTickPositions,$type); 437 } 438 } 439 } 440 } 326 $diff = $aMax - $aMin; 327 $spd = 3600*24; 328 $spw = $spd*7; 329 $spm = $spd*30; 330 $spy = $spd*352; 331 332 if( self::$iUseWeeks ) 333 $w = 'W'; 334 else 335 $w = 'd M'; 336 337 // Decision table for suitable scales 338 // First value: Main decision point 339 // Second value: Array of formatting depending on divisor for wanted max number of ticks. <divisor><formatting><format-string>,.. 340 $tt = array( 341 array($spw, array(1,DSUTILS_DAY1,'d M',2,DSUTILS_DAY2,'d M',-1,DSUTILS_DAY4,'d M')), 342 array($spm, array(1,DSUTILS_DAY1,'d M',2,DSUTILS_DAY2,'d M',4,DSUTILS_DAY4,'d M',7,DSUTILS_WEEK1,$w,-1,DSUTILS_WEEK2,$w)), 343 array($spy, array(1,DSUTILS_DAY1,'d M',2,DSUTILS_DAY2,'d M',4,DSUTILS_DAY4,'d M',7,DSUTILS_WEEK1,$w,14,DSUTILS_WEEK2,$w,30,DSUTILS_MONTH1,'M',60,DSUTILS_MONTH2,'M',-1,DSUTILS_MONTH3,'M')), 344 array(-1, array(30,DSUTILS_MONTH1,'M-Y',60,DSUTILS_MONTH2,'M-Y',90,DSUTILS_MONTH3,'M-Y',180,DSUTILS_MONTH6,'M-Y',352,DSUTILS_YEAR1,'Y',704,DSUTILS_YEAR2,'Y',-1,DSUTILS_YEAR5,'Y'))); 345 346 $ntt = count($tt); 347 $nd = floor($diff/$spd); 348 for($i=0; $i < $ntt; ++$i ) { 349 if( $diff <= $tt[$i][0] || $i==$ntt-1) { 350 $t = $tt[$i][1]; 351 $n = count($t)/3; 352 for( $j=0; $j < $n; ++$j ) { 353 if( $nd/$t[3*$j] <= $aMaxTicks || $j==$n-1) { 354 $type = $t[3*$j+1]; 355 $fs = $t[3*$j+2]; 356 list($tickPositions,$minTickPositions) = self::GetTicksFromMinMax($aMin,$aMax,$type,$aMinor); 357 return array($fs,$tickPositions,$minTickPositions,$type); 358 } 359 } 360 } 361 } 441 362 } 442 363 443 364 static function GetTicksFromMinMax($aMin,$aMax,$aType,$aMinor=false,$aEndPoints=false) { 444 self::$starthour = date('G',$aMin); 445 self::$startmonth = date('n',$aMin); 446 self::$startday = date('j',$aMin); 447 self::$startyear = date('Y',$aMin); 448 self::$endmonth = date('n',$aMax); 449 self::$endyear = date('Y',$aMax); 450 self::$endday = date('j',$aMax); 451 self::$iMin = $aMin; 452 self::$iMax = $aMax; 453 454 if( $aType <= DSUTILS_MONTH6 ) { 455 self::doMonthly($aType,$aMinor); 456 } 457 elseif( $aType <= DSUTILS_WEEK4 ) { 458 self::doWeekly($aType,$aMinor); 459 } 460 elseif( $aType <= DSUTILS_DAY4 ) { 461 self::doDaily($aType,$aMinor); 462 } 463 elseif( $aType <= DSUTILS_YEAR5 ) { 464 self::doYearly($aType,$aMinor); 465 } 466 else { 467 JpGraphError::RaiseL(24003); 468 } 469 // put a label at the very left data pos 470 if( $aEndPoints ) { 471 $tickPositions[$i++] = $aData[0]; 472 } 473 474 // put a label at the very right data pos 475 if( $aEndPoints ) { 476 $tickPositions[$i] = $aData[$n-1]; 477 } 478 479 return array(self::$tickPositions,self::$minTickPositions); 480 } 481 365 self::$starthour = date('G',$aMin); 366 self::$startmonth = date('n',$aMin); 367 self::$startday = date('j',$aMin); 368 self::$startyear = date('Y',$aMin); 369 self::$endmonth = date('n',$aMax); 370 self::$endyear = date('Y',$aMax); 371 self::$endday = date('j',$aMax); 372 self::$iMin = $aMin; 373 self::$iMax = $aMax; 374 375 if( $aType <= DSUTILS_MONTH6 ) { 376 self::doMonthly($aType,$aMinor); 377 } 378 elseif( $aType <= DSUTILS_WEEK4 ) { 379 self::doWeekly($aType,$aMinor); 380 } 381 elseif( $aType <= DSUTILS_DAY4 ) { 382 self::doDaily($aType,$aMinor); 383 } 384 elseif( $aType <= DSUTILS_YEAR5 ) { 385 self::doYearly($aType,$aMinor); 386 } 387 else { 388 JpGraphError::RaiseL(24003); 389 } 390 // put a label at the very left data pos 391 if( $aEndPoints ) { 392 $tickPositions[$i++] = $aData[0]; 393 } 394 395 // put a label at the very right data pos 396 if( $aEndPoints ) { 397 $tickPositions[$i] = $aData[$n-1]; 398 } 399 400 return array(self::$tickPositions,self::$minTickPositions); 401 } 482 402 } 483 403 … … 486 406 //============================================================================= 487 407 Class ReadFileData { 488 489 408 //---------------------------------------------------------------------------- 490 409 // Desciption: 491 // Read numeric data from a file. 492 // Each value should be separated by either a new line or by a specified 410 // Read numeric data from a file. 411 // Each value should be separated by either a new line or by a specified 493 412 // separator character (default is ','). 494 // Before returning the data each value is converted to a proper float 495 // value. The routine is robust in the sense that non numeric data in the 413 // Before returning the data each value is converted to a proper float 414 // value. The routine is robust in the sense that non numeric data in the 496 415 // file will be discarded. 497 416 // 498 // Returns: 417 // Returns: 499 418 // The number of data values read on success, FALSE on failure 500 419 //---------------------------------------------------------------------------- 501 420 static function FromCSV($aFile,&$aData,$aSepChar=',',$aMaxLineLength=1024) { 502 $rh = fopen($aFile,'r'); 503 if( $rh === false ) 504 return false; 505 $tmp = array(); 506 $lineofdata = fgetcsv($rh, 1000, ','); 507 while ( $lineofdata !== FALSE) { 508 $tmp = array_merge($tmp,$lineofdata); 509 $lineofdata = fgetcsv($rh, $aMaxLineLength, $aSepChar); 510 } 511 fclose($rh); 512 513 // Now make sure that all data is numeric. By default 514 // all data is read as strings 515 $n = count($tmp); 516 $aData = array(); 517 $cnt=0; 518 for($i=0; $i < $n; ++$i) { 519 if( $tmp[$i] !== "" ) { 520 $aData[$cnt++] = floatval($tmp[$i]); 521 } 522 } 523 return $cnt; 524 } 421 $rh = @fopen($aFile,'r'); 422 if( $rh === false ) { 423 return false; 424 } 425 $tmp = array(); 426 $lineofdata = fgetcsv($rh, 1000, ','); 427 while ( $lineofdata !== FALSE) { 428 $tmp = array_merge($tmp,$lineofdata); 429 $lineofdata = fgetcsv($rh, $aMaxLineLength, $aSepChar); 430 } 431 fclose($rh); 432 433 // Now make sure that all data is numeric. By default 434 // all data is read as strings 435 $n = count($tmp); 436 $aData = array(); 437 $cnt=0; 438 for($i=0; $i < $n; ++$i) { 439 if( $tmp[$i] !== "" ) { 440 $aData[$cnt++] = floatval($tmp[$i]); 441 } 442 } 443 return $cnt; 444 } 445 446 //---------------------------------------------------------------------------- 447 // Desciption: 448 // Read numeric data from a file. 449 // Each value should be separated by either a new line or by a specified 450 // separator character (default is ','). 451 // Before returning the data each value is converted to a proper float 452 // value. The routine is robust in the sense that non numeric data in the 453 // file will be discarded. 454 // 455 // Options: 456 // 'separator' => ',', 457 // 'enclosure' => '"', 458 // 'readlength' => 1024, 459 // 'ignore_first' => false, 460 // 'first_as_key' => false 461 // 'escape' => '\', # PHP >= 5.3 only 462 // 463 // Returns: 464 // The number of lines read on success, FALSE on failure 465 //---------------------------------------------------------------------------- 466 static function FromCSV2($aFile, &$aData, $aOptions = array()) { 467 $aDefaults = array( 468 'separator' => ',', 469 'enclosure' => chr(34), 470 'escape' => chr(92), 471 'readlength' => 1024, 472 'ignore_first' => false, 473 'first_as_key' => false 474 ); 475 476 $aOptions = array_merge( 477 $aDefaults, is_array($aOptions) ? $aOptions : array()); 478 479 if( $aOptions['first_as_key'] ) { 480 $aOptions['ignore_first'] = true; 481 } 482 483 $rh = @fopen($aFile, 'r'); 484 485 if( $rh === false ) { 486 return false; 487 } 488 489 $aData = array(); 490 $aLine = fgetcsv($rh, 491 $aOptions['readlength'], 492 $aOptions['separator'], 493 $aOptions['enclosure'] 494 /*, $aOptions['escape'] # PHP >= 5.3 only */ 495 ); 496 497 // Use numeric array keys for the columns by default 498 // If specified use first lines values as assoc keys instead 499 $keys = array_keys($aLine); 500 if( $aOptions['first_as_key'] ) { 501 $keys = array_values($aLine); 502 } 503 504 $num_lines = 0; 505 $num_cols = count($aLine); 506 507 while ($aLine !== false) { 508 if( is_array($aLine) && count($aLine) != $num_cols ) { 509 JpGraphError::RaiseL(24004); 510 // 'ReadCSV2: Column count mismatch in %s line %d' 511 } 512 513 // fgetcsv returns NULL for empty lines 514 if( !is_null($aLine) ) { 515 $num_lines++; 516 517 if( !($aOptions['ignore_first'] && $num_lines == 1) && is_numeric($aLine[0]) ) { 518 for( $i = 0; $i < $num_cols; $i++ ) { 519 $aData[ $keys[$i] ][] = floatval($aLine[$i]); 520 } 521 } 522 } 523 524 $aLine = fgetcsv($rh, 525 $aOptions['readlength'], 526 $aOptions['separator'], 527 $aOptions['enclosure'] 528 /*, $aOptions['escape'] # PHP >= 5.3 only*/ 529 ); 530 } 531 532 fclose($rh); 533 534 if( $aOptions['ignore_first'] ) { 535 $num_lines--; 536 } 537 538 return $num_lines; 539 } 540 541 // Read data from two columns in a plain text file 542 static function From2Col($aFile, $aCol1, $aCol2, $aSepChar=' ') { 543 $lines = @file($aFile,FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES); 544 if( $lines === false ) { 545 return false; 546 } 547 $s = '/[\s]+/'; 548 if( $aSepChar == ',' ) { 549 $s = '/[\s]*,[\s]*/'; 550 } 551 elseif( $aSepChar == ';' ) { 552 $s = '/[\s]*;[\s]*/'; 553 } 554 foreach( $lines as $line => $datarow ) { 555 $split = preg_split($s,$datarow); 556 $aCol1[] = floatval(trim($split[0])); 557 $aCol2[] = floatval(trim($split[1])); 558 } 559 560 return count($lines); 561 } 562 563 // Read data from one columns in a plain text file 564 static function From1Col($aFile, $aCol1) { 565 $lines = @file($aFile,FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES); 566 if( $lines === false ) { 567 return false; 568 } 569 foreach( $lines as $line => $datarow ) { 570 $aCol1[] = floatval(trim($datarow)); 571 } 572 573 return count($lines); 574 } 575 576 static function FromMatrix($aFile,$aSepChar=' ') { 577 $lines = @file($aFile,FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES); 578 if( $lines === false ) { 579 return false; 580 } 581 $mat = array(); 582 $reg = '/'.$aSepChar.'/'; 583 foreach( $lines as $line => $datarow ) { 584 $row = preg_split($reg,trim($datarow)); 585 foreach ($row as $key => $cell ) { 586 $row[$key] = floatval(trim($cell)); 587 } 588 $mat[] = $row; 589 } 590 return $mat; 591 } 592 593 525 594 } 526 595 596 define('__LR_EPSILON', 1.0e-8); 597 //============================================================================= 598 // Class LinearRegression 599 //============================================================================= 600 class LinearRegression { 601 private $ix=array(),$iy=array(); 602 private $ib=0, $ia=0; 603 private $icalculated=false; 604 public $iDet=0, $iCorr=0, $iStdErr=0; 605 606 public function __construct($aDataX,$aDataY) { 607 if( count($aDataX) !== count($aDataY) ) { 608 JpGraph::Raise('LinearRegression: X and Y data array must be of equal length.'); 609 } 610 $this->ix = $aDataX; 611 $this->iy = $aDataY; 612 } 613 614 public function Calc() { 615 616 $this->icalculated = true; 617 618 $n = count($this->ix); 619 $sx2 = 0 ; 620 $sy2 = 0 ; 621 $sxy = 0 ; 622 $sx = 0 ; 623 $sy = 0 ; 624 625 for( $i=0; $i < $n; ++$i ) { 626 $sx2 += $this->ix[$i] * $this->ix[$i]; 627 $sy2 += $this->iy[$i] * $this->iy[$i]; 628 $sxy += $this->ix[$i] * $this->iy[$i]; 629 $sx += $this->ix[$i]; 630 $sy += $this->iy[$i]; 631 } 632 633 if( $n*$sx2 - $sx*$sx > __LR_EPSILON ) { 634 $this->ib = ($n*$sxy - $sx*$sy) / ( $n*$sx2 - $sx*$sx ); 635 $this->ia = ( $sy - $this->ib*$sx ) / $n; 636 637 $sx = $this->ib * ( $sxy - $sx*$sy/$n ); 638 $sy2 = $sy2 - $sy*$sy/$n; 639 $sy = $sy2 - $sx; 640 641 $this->iDet = $sx / $sy2; 642 $this->iCorr = sqrt($this->iDet); 643 if( $n > 2 ) { 644 $this->iStdErr = sqrt( $sy / ($n-2) ); 645 } 646 else { 647 $this->iStdErr = NAN ; 648 } 649 } 650 else { 651 $this->ib = 0; 652 $this->ia = 0; 653 } 654 655 } 656 657 public function GetAB() { 658 if( $this->icalculated == false ) 659 $this->Calc(); 660 return array($this->ia, $this->ib); 661 } 662 663 public function GetStat() { 664 if( $this->icalculated == false ) 665 $this->Calc(); 666 return array($this->iStdErr, $this->iCorr, $this->iDet); 667 } 668 669 public function GetY($aMinX, $aMaxX, $aStep=1) { 670 if( $this->icalculated == false ) 671 $this->Calc(); 672 673 $yy = array(); 674 $i = 0; 675 for( $x=$aMinX; $x <= $aMaxX; $x += $aStep ) { 676 $xx[$i ] = $x; 677 $yy[$i++] = $this->ia + $this->ib * $x; 678 } 679 680 return array($xx,$yy); 681 } 682 683 } 684 527 685 ?> -
trunk/client/modules/Elezioni/grafici/lang/de.inc.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File: 3 // File: DE.INC.PHP 4 4 // Description: German language file for error messages 5 // Created: 2006-03-06 6 // Author: Timo Leopold (timo@leopold-hh.de) 7 // Ver: $Id: de.inc.php 1017 2008-07-08 06:09:28Z ljp $ 5 // Created: 2006-03-06 6 // Author: Timo Leopold (timo@leopold-hh.de) 7 // Johan Persson (ljp@localhost.nil) 8 // Ver: $Id: de.inc.php 1886 2009-10-01 23:30:16Z ljp $ 8 9 // 9 10 // Copyright (c) … … 18 19 */ 19 20 10 => array('<table border="1"><tr><td style="color:darkred;font-size:1.2em;"><b>JpGraph Fehler:</b> 20 HTTP header wurden bereits gesendet.<br>Fehler in der Datei <b>%s</b> in der Zeile <b>%d</b>.</td></tr><tr><td><b>Erkl ärung:</b><br>HTTP header wurden bereits zum Browser gesendet, wobei die Daten als Text gekennzeichnet wurden, bevor die Bibliothek die Chance hatte, seinen Bild-HTTP-Header zum Browser zu schicken. Dies verhindert, dass die Bibliothek Bilddaten zum Browser schicken kann (weil sie vom Browser als Text interpretiert würden und daher nur Mist dargestellt würde).<p>Wahrscheinlich steht Text im Skript bevor <i>Graph::Stroke()</i> aufgerufen wird. Wenn dieser Text zum Browser gesendet wird, nimmt dieser an, dass die gesamten Daten aus Text bestehen. Such nach irgendwelchem Text, auch nach Leerzeichen und Zeilenumbrüchen, die eventuell bereits zum Browser gesendet wurden. <p>Zum Beispiel ist ein oft auftretender Fehler, eine Leerzeile am Anfang der Datei oder vor <i>Graph::Stroke()</i> zu lassen."<b><?php</b>".</td></tr></table>',2),21 HTTP header wurden bereits gesendet.<br>Fehler in der Datei <b>%s</b> in der Zeile <b>%d</b>.</td></tr><tr><td><b>ErklÀrung:</b><br>HTTP header wurden bereits zum Browser gesendet, wobei die Daten als Text gekennzeichnet wurden, bevor die Bibliothek die Chance hatte, seinen Bild-HTTP-Header zum Browser zu schicken. Dies verhindert, dass die Bibliothek Bilddaten zum Browser schicken kann (weil sie vom Browser als Text interpretiert wÃŒrden und daher nur Mist dargestellt wÃŒrde).<p>Wahrscheinlich steht Text im Skript bevor <i>Graph::Stroke()</i> aufgerufen wird. Wenn dieser Text zum Browser gesendet wird, nimmt dieser an, dass die gesamten Daten aus Text bestehen. Such nach irgendwelchem Text, auch nach Leerzeichen und ZeilenumbrÃŒchen, die eventuell bereits zum Browser gesendet wurden. <p>Zum Beispiel ist ein oft auftretender Fehler, eine Leerzeile am Anfang der Datei oder vor <i>Graph::Stroke()</i> zu lassen."<b><?php</b>".</td></tr></table>',2), 21 22 22 23 /* 23 24 ** Setup Fehler 24 25 */ 25 11 => array('Es wurde kein Pfad f ür CACHE_DIR angegeben. Bitte gib einen Pfad CACHE_DIR in der Datei jpg-config.inc an.',0),26 12 => array('Es wurde kein Pfad f ür TTF_DIR angegeben und der Pfad kann nicht automatisch ermittelt werden. Bitte gib den Pfad in der Datei jpg-config.inc an.',0),26 11 => array('Es wurde kein Pfad fÃŒr CACHE_DIR angegeben. Bitte gib einen Pfad CACHE_DIR in der Datei jpg-config.inc an.',0), 27 12 => array('Es wurde kein Pfad fÃŒr TTF_DIR angegeben und der Pfad kann nicht automatisch ermittelt werden. Bitte gib den Pfad in der Datei jpg-config.inc an.',0), 27 28 13 => array('The installed PHP version (%s) is not compatible with this release of the library. The library requires at least PHP version %s',2), 28 29 … … 34 35 2002 => array('Unbekannte Vorlage im Aufruf von BarPlot::SetPattern().',0), 35 36 2003 => array('Anzahl der X- und Y-Koordinaten sind nicht identisch. Anzahl der X-Koordinaten: %d; Anzahl der Y-Koordinaten: %d.',2), 36 2004 => array('Alle Werte f ür ein Balkendiagramm (barplot) müssen numerisch sein. Du hast den Wert nr [%d] == %s angegeben.',2),37 2005 => array('Du hast einen leeren Vektor f ür die Schattierungsfarben im Balkendiagramm (barplot) angegeben.',0),38 2006 => array('Unbekannte Position f ür die Werte der Balken: %s.',1),37 2004 => array('Alle Werte fÃŒr ein Balkendiagramm (barplot) mÃŒssen numerisch sein. Du hast den Wert nr [%d] == %s angegeben.',2), 38 2005 => array('Du hast einen leeren Vektor fÃŒr die Schattierungsfarben im Balkendiagramm (barplot) angegeben.',0), 39 2006 => array('Unbekannte Position fÃŒr die Werte der Balken: %s.',1), 39 40 2007 => array('Kann GroupBarPlot nicht aus einem leeren Vektor erzeugen.',0), 40 41 2008 => array('GroupBarPlot Element nbr %d wurde nicht definiert oder ist leer.',0), … … 43 44 2011 => array('AccBarPlot-Element nbr %d wurde nicht definiert oder ist leer.',1), 44 45 2012 => array('Eins der Objekte, das an AccBar weitergegeben wurde ist kein Balkendiagramm (barplot). Versichere Dich, dass Du den AccBar-Plot aus einem Vektor von Balkendiagrammen (barplot) erzeugst. (Class=%s)',1), 45 2013 => array('Du hast einen leeren Vektor f ür die Schattierungsfarben im Balkendiagramm (barplot) angegeben.',0),46 2013 => array('Du hast einen leeren Vektor fÃŒr die Schattierungsfarben im Balkendiagramm (barplot) angegeben.',0), 46 47 2014 => array('Die Anzahl der Datenpunkte jeder Datenreihe in AccBarPlot muss gleich sein.',0), 47 48 2015 => array('Individual bar plots in an AccBarPlot or GroupBarPlot can not have specified X-coordinates',0), … … 52 53 */ 53 54 54 3001 => array('Es ist nur m öglich, entweder SetDateAlign() oder SetTimeAlign() zu benutzen, nicht beides!',0),55 3001 => array('Es ist nur möglich, entweder SetDateAlign() oder SetTimeAlign() zu benutzen, nicht beides!',0), 55 56 56 57 /* … … 64 65 */ 65 66 66 5001 => array('Unbekannte Flaggen-Gr öße (%d).',1),67 5001 => array('Unbekannte Flaggen-GröÃe (%d).',1), 67 68 5002 => array('Der Flaggen-Index %s existiert nicht.',1), 68 5003 => array('Es wurde eine ung ültige Ordnungszahl (%d) für den Flaggen-Index angegeben.',1),69 5003 => array('Es wurde eine ungÃŒltige Ordnungszahl (%d) fÃŒr den Flaggen-Index angegeben.',1), 69 70 5004 => array('Der Landesname %s hat kein korrespondierendes Flaggenbild. Die Flagge mag existieren, abr eventuell unter einem anderen Namen, z.B. versuche "united states" statt "usa".',1), 70 71 … … 74 75 */ 75 76 76 6001 => array('Interner Fehler. Die H öhe für ActivityTitles ist < 0.',0),77 6002 => array('Es d ürfen keine negativen Werte für die Gantt-Diagramm-Dimensionen angegeben werden. Verwende 0, wenn die Dimensionen automatisch ermittelt werden sollen.',0),78 6003 => array('Ung ültiges Format für den Bedingungs-Parameter bei Index=%d in CreateSimple(). Der Parameter muss bei index 0 starten und Vektoren in der Form (Row,Constrain-To,Constrain-Type) enthalten.',1),79 6004 => array('Ung ültiges Format für den Fortschritts-Parameter bei Index=%d in CreateSimple(). Der Parameter muss bei Index 0 starten und Vektoren in der Form (Row,Progress) enthalten.',1),77 6001 => array('Interner Fehler. Die Höhe fÃŒr ActivityTitles ist < 0.',0), 78 6002 => array('Es dÃŒrfen keine negativen Werte fÃŒr die Gantt-Diagramm-Dimensionen angegeben werden. Verwende 0, wenn die Dimensionen automatisch ermittelt werden sollen.',0), 79 6003 => array('UngÃŒltiges Format fÃŒr den Bedingungs-Parameter bei Index=%d in CreateSimple(). Der Parameter muss bei index 0 starten und Vektoren in der Form (Row,Constrain-To,Constrain-Type) enthalten.',1), 80 6004 => array('UngÃŒltiges Format fÃŒr den Fortschritts-Parameter bei Index=%d in CreateSimple(). Der Parameter muss bei Index 0 starten und Vektoren in der Form (Row,Progress) enthalten.',1), 80 81 6005 => array('SetScale() ist nicht sinnvoll bei Gantt-Diagrammen.',0), 81 6006 => array('Das Gantt-Diagramm kann nicht automatisch skaliert werden. Es existieren keine Aktivit äten mit Termin. [GetBarMinMax() start >= n]',0),82 6007 => array('Plausibilt ätsprüfung für die automatische Gantt-Diagramm-Größe schlug fehl. Entweder die Breite (=%d) oder die Höhe (=%d) ist größer als MAX_GANTTIMG_SIZE. Dies kann möglicherweise durch einen falschen Wert bei einer Aktivität hervorgerufen worden sein.',2),83 6008 => array('Du hast eine Bedingung angegeben von Reihe=%d bis Reihe=%d, die keine Aktivit ät hat.',2),82 6006 => array('Das Gantt-Diagramm kann nicht automatisch skaliert werden. Es existieren keine AktivitÀten mit Termin. [GetBarMinMax() start >= n]',0), 83 6007 => array('PlausibiltÀtsprÃŒfung fÃŒr die automatische Gantt-Diagramm-GröÃe schlug fehl. Entweder die Breite (=%d) oder die Höhe (=%d) ist gröÃer als MAX_GANTTIMG_SIZE. Dies kann möglicherweise durch einen falschen Wert bei einer AktivitÀt hervorgerufen worden sein.',2), 84 6008 => array('Du hast eine Bedingung angegeben von Reihe=%d bis Reihe=%d, die keine AktivitÀt hat.',2), 84 85 6009 => array('Unbekannter Bedingungstyp von Reihe=%d bis Reihe=%d',2), 85 6010 => array('Ung ültiger Icon-Index für das eingebaute Gantt-Icon [%d]',1),86 6011 => array('Argument f ür IconImage muss entweder ein String oder ein Integer sein.',0),86 6010 => array('UngÃŒltiger Icon-Index fÃŒr das eingebaute Gantt-Icon [%d]',1), 87 6011 => array('Argument fÃŒr IconImage muss entweder ein String oder ein Integer sein.',0), 87 88 6012 => array('Unbekannter Typ bei der Gantt-Objekt-Title-Definition.',0), 88 6015 => array('Ung ültige vertikale Position %d',1),89 6016 => array('Der eingegebene Datums-String (%s) f ür eine Gantt-Aktivität kann nicht interpretiert werden. Versichere Dich, dass es ein gültiger Datumsstring ist, z.B. 2005-04-23 13:30',1),89 6015 => array('UngÃŒltige vertikale Position %d',1), 90 6016 => array('Der eingegebene Datums-String (%s) fÃŒr eine Gantt-AktivitÀt kann nicht interpretiert werden. Versichere Dich, dass es ein gÃŒltiger Datumsstring ist, z.B. 2005-04-23 13:30',1), 90 91 6017 => array('Unbekannter Datumstyp in GanttScale (%s).',1), 91 6018 => array('Intervall f ür Minuten muss ein gerader Teiler einer Stunde sein, z.B. 1,5,10,12,15,20,30, etc. Du hast ein Intervall von %d Minuten angegeben.',1),92 6019 => array('Die vorhandene Breite (%d) f ür die Minuten ist zu klein, um angezeigt zu werden. Bitte benutze die automatische Größenermittlung oder vergrößere die Breite des Diagramms.',1),93 6020 => array('Das Intervall f ür die Stunden muss ein gerader Teiler eines Tages sein, z.B. 0:30, 1:00, 1:30, 4:00, etc. Du hast ein Intervall von %d eingegeben.',1),94 6021 => array('Unbekanntes Format f ür die Woche.',0),92 6018 => array('Intervall fÃŒr Minuten muss ein gerader Teiler einer Stunde sein, z.B. 1,5,10,12,15,20,30, etc. Du hast ein Intervall von %d Minuten angegeben.',1), 93 6019 => array('Die vorhandene Breite (%d) fÃŒr die Minuten ist zu klein, um angezeigt zu werden. Bitte benutze die automatische GröÃenermittlung oder vergröÃere die Breite des Diagramms.',1), 94 6020 => array('Das Intervall fÃŒr die Stunden muss ein gerader Teiler eines Tages sein, z.B. 0:30, 1:00, 1:30, 4:00, etc. Du hast ein Intervall von %d eingegeben.',1), 95 6021 => array('Unbekanntes Format fÃŒr die Woche.',0), 95 96 6022 => array('Die Gantt-Skala wurde nicht eingegeben.',0), 96 97 6023 => array('Wenn Du sowohl Stunden als auch Minuten anzeigen lassen willst, muss das Stunden-Interval gleich 1 sein (anderenfalls ist es nicht sinnvoll, Minuten anzeigen zu lassen).',0), … … 98 99 6025 => array('Der CSIM-Alt-Text muss als String angegeben werden. Der Beginn des Alt-Textes ist: %d',1), 99 100 6027 => array('Der Fortschrittswert muss im Bereich [0, 1] liegen.',0), 100 6028 => array('Die eingegebene Höhe (%d) für GanttBar ist nicht im zulässigen Bereich.',1), 101 6029 => array('Der Offset für die vertikale Linie muss im Bereich [0,1] sein.',0), 102 6030 => array('Unbekannte Pfeilrichtung für eine Verbindung.',0), 103 6031 => array('Unbekannter Pfeiltyp für eine Verbindung.',0), 104 6032 => array('Interner Fehler: Unbekannter Pfadtyp (=%d) für eine Verbindung.',1), 101 6028 => array('Die eingegebene Höhe (%d) fÃŒr GanttBar ist nicht im zulÀssigen Bereich.',1), 102 6029 => array('Der Offset fÃŒr die vertikale Linie muss im Bereich [0,1] sein.',0), 103 6030 => array('Unbekannte Pfeilrichtung fÃŒr eine Verbindung.',0), 104 6031 => array('Unbekannter Pfeiltyp fÃŒr eine Verbindung.',0), 105 6032 => array('Interner Fehler: Unbekannter Pfadtyp (=%d) fÃŒr eine Verbindung.',1), 106 6033 => array('Array of fonts must contain arrays with 3 elements, i.e. (Family, Style, Size)',0), 105 107 106 108 /* … … 114 116 */ 115 117 116 8001 => array('Der Mix-Wert f ür das Icon muss zwischen 0 und 100 sein.',0),117 8002 => array('Die Ankerposition f ür Icons muss entweder "top", "bottom", "left", "right" oder "center" sein.',0),118 8003 => array('Es ist nicht m öglich, gleichzeitig ein Bild und eine Landesflagge für dasselbe Icon zu definieren',0),119 8004 => array('Wenn Du Landesflaggen benutzen willst, musst Du die Datei "jpgraph_flags.php" hinzuf ügen (per include).',0),118 8001 => array('Der Mix-Wert fÃŒr das Icon muss zwischen 0 und 100 sein.',0), 119 8002 => array('Die Ankerposition fÃŒr Icons muss entweder "top", "bottom", "left", "right" oder "center" sein.',0), 120 8003 => array('Es ist nicht möglich, gleichzeitig ein Bild und eine Landesflagge fÃŒr dasselbe Icon zu definieren',0), 121 8004 => array('Wenn Du Landesflaggen benutzen willst, musst Du die Datei "jpgraph_flags.php" hinzufÃŒgen (per include).',0), 120 122 121 123 /* … … 123 125 */ 124 126 125 9001 => array('Der Wert f ür die Bildtransformation ist außerhalb des zulässigen Bereichs. Der verschwindende Punkt am Horizont muss als Wert zwischen 0 und 1 angegeben werden.',0),127 9001 => array('Der Wert fÃŒr die Bildtransformation ist auÃerhalb des zulÀssigen Bereichs. Der verschwindende Punkt am Horizont muss als Wert zwischen 0 und 1 angegeben werden.',0), 126 128 127 129 /* … … 130 132 131 133 10001 => array('Die Methode LinePlot::SetFilled() sollte nicht mehr benutzt werden. Benutze lieber SetFillColor()',0), 132 10002 => array('Der Plot ist zu kompliziert f ür FastLineStroke. Benutze lieber den StandardStroke()',0),134 10002 => array('Der Plot ist zu kompliziert fÃŒr FastLineStroke. Benutze lieber den StandardStroke()',0), 133 135 10003 => array('Each plot in an accumulated lineplot must have the same number of data points.',0), 134 136 /* … … 137 139 138 140 11001 => array('Deine Daten enthalten nicht-numerische Werte.',0), 139 11002 => array('Negative Werte k önnen nicht für logarithmische Achsen verwendet werden.',0),141 11002 => array('Negative Werte können nicht fÃŒr logarithmische Achsen verwendet werden.',0), 140 142 11003 => array('Deine Daten enthalten nicht-numerische Werte.',0), 141 11004 => array('Skalierungsfehler f ür die logarithmische Achse. Es gibt ein Problem mit den Daten der Achse. Der größte Wert muss größer sein als Null. Es ist mathematisch nicht möglich, einen Wert gleich Null in der Skala zu haben.',0),142 11005 => array('Das Tick-Intervall f ür die logarithmische Achse ist nicht definiert. Lösche jeden Aufruf von SetTextLabelStart() oder SetTextTickInterval() bei der logarithmischen Achse.',0),143 11004 => array('Skalierungsfehler fÃŒr die logarithmische Achse. Es gibt ein Problem mit den Daten der Achse. Der gröÃte Wert muss gröÃer sein als Null. Es ist mathematisch nicht möglich, einen Wert gleich Null in der Skala zu haben.',0), 144 11005 => array('Das Tick-Intervall fÃŒr die logarithmische Achse ist nicht definiert. Lösche jeden Aufruf von SetTextLabelStart() oder SetTextTickInterval() bei der logarithmischen Achse.',0), 143 145 144 146 /* … … 146 148 */ 147 149 148 12001 => array("Du benutzt GD 2.x und versuchst ein Nicht-Truecolor-Bild als Hintergrundbild zu benutzen. Um Hintergrundbilder mit GD 2.x zu benutzen, ist es notwendig Truecolor zu aktivieren, indem die USE_TRUECOLOR-Konstante auf TRUE gesetzt wird. Wegen eines Bugs in GD 2.0.1 ist die Qualit ät der Truetype-Schriften sehr schlecht, wenn man Truetype-Schriften mit Truecolor-Bildern verwendet.",0),149 12002 => array('Ung ültiger Dateiname für MGraph::SetBackgroundImage() : %s. Die Datei muss eine gültige Dateierweiterung haben (jpg,gif,png), wenn die automatische Typerkennung verwendet wird.',1),150 12003 => array('Unbekannte Dateierweiterung (%s) in MGraph::SetBackgroundImage() f ür Dateiname: %s',2),151 12004 => array('Das Bildformat des Hintergrundbildes (%s) wird von Deiner System-Konfiguration nicht unterst ützt. ',1),150 12001 => array("Du benutzt GD 2.x und versuchst ein Nicht-Truecolor-Bild als Hintergrundbild zu benutzen. Um Hintergrundbilder mit GD 2.x zu benutzen, ist es notwendig Truecolor zu aktivieren, indem die USE_TRUECOLOR-Konstante auf TRUE gesetzt wird. Wegen eines Bugs in GD 2.0.1 ist die QualitÀt der Truetype-Schriften sehr schlecht, wenn man Truetype-Schriften mit Truecolor-Bildern verwendet.",0), 151 12002 => array('UngÃŒltiger Dateiname fÃŒr MGraph::SetBackgroundImage() : %s. Die Datei muss eine gÃŒltige Dateierweiterung haben (jpg,gif,png), wenn die automatische Typerkennung verwendet wird.',1), 152 12003 => array('Unbekannte Dateierweiterung (%s) in MGraph::SetBackgroundImage() fÃŒr Dateiname: %s',2), 153 12004 => array('Das Bildformat des Hintergrundbildes (%s) wird von Deiner System-Konfiguration nicht unterstÃŒtzt. ',1), 152 154 12005 => array('Das Hintergrundbild kann nicht gelesen werden: %s',1), 153 12006 => array('Es wurden ung ültige Größen für Breite oder Höhe beim Erstellen des Bildes angegeben, (Breite=%d, Höhe=%d)',2),154 12007 => array('Das Argument f ür MGraph::Add() ist nicht gültig für GD.',0),155 12008 => array('Deine PHP- (und GD-lib-) Installation scheint keine bekannten Bildformate zu unterst ützen.',0),156 12009 => array('Deine PHP-Installation unterst ützt das gewählte Bildformat nicht: %s',1),157 12010 => array('Es konnte kein Bild als Datei %s erzeugt werden. Überprüfe, ob Du die entsprechenden Schreibrechte im aktuellen Verzeichnis hast.',1),158 12011 => array('Es konnte kein Truecolor-Bild erzeugt werden. Überprüfe, ob Du wirklich die GD2-Bibliothek installiert hast.',0),159 12012 => array('Es konnte kein Bild erzeugt werden. Überprüfe, ob Du wirklich die GD2-Bibliothek installiert hast.',0),155 12006 => array('Es wurden ungÃŒltige GröÃen fÃŒr Breite oder Höhe beim Erstellen des Bildes angegeben, (Breite=%d, Höhe=%d)',2), 156 12007 => array('Das Argument fÃŒr MGraph::Add() ist nicht gÃŒltig fÃŒr GD.',0), 157 12008 => array('Deine PHP- (und GD-lib-) Installation scheint keine bekannten Bildformate zu unterstÃŒtzen.',0), 158 12009 => array('Deine PHP-Installation unterstÃŒtzt das gewÀhlte Bildformat nicht: %s',1), 159 12010 => array('Es konnte kein Bild als Datei %s erzeugt werden. ÃberprÃŒfe, ob Du die entsprechenden Schreibrechte im aktuellen Verzeichnis hast.',1), 160 12011 => array('Es konnte kein Truecolor-Bild erzeugt werden. ÃberprÃŒfe, ob Du wirklich die GD2-Bibliothek installiert hast.',0), 161 12012 => array('Es konnte kein Bild erzeugt werden. ÃberprÃŒfe, ob Du wirklich die GD2-Bibliothek installiert hast.',0), 160 162 161 163 /* … … 163 165 */ 164 166 165 14001 => array('Pie3D::ShowBorder(). Missbilligte Funktion. Benutze Pie3D::SetEdge(), um die Ecken der Tortenst ücke zu kontrollieren.',0),167 14001 => array('Pie3D::ShowBorder(). Missbilligte Funktion. Benutze Pie3D::SetEdge(), um die Ecken der TortenstÃŒcke zu kontrollieren.',0), 166 168 14002 => array('PiePlot3D::SetAngle() 3D-Torten-Projektionswinkel muss zwischen 5 und 85 Grad sein.',0), 167 169 14003 => array('Interne Festlegung schlug fehl. Pie3D::Pie3DSlice',0), 168 14004 => array('Tortenst ück-Startwinkel muss zwischen 0 und 360 Grad sein.',0),169 14005 => array('Pie3D Interner Fehler: Versuch, zweimal zu umh üllen bei der Suche nach dem Startindex.',0,),170 14006 => array('Pie3D Interner Fehler: Z-Sortier-Algorithmus f ür 3D-Tortendiagramme funktioniert nicht einwandfrei (2). Versuch, zweimal zu umhüllen beim Erstellen des Bildes.',0),171 14007 => array('Die Breite f ür das 3D-Tortendiagramm ist 0. Gib eine Breite > 0 an.',0),170 14004 => array('TortenstÃŒck-Startwinkel muss zwischen 0 und 360 Grad sein.',0), 171 14005 => array('Pie3D Interner Fehler: Versuch, zweimal zu umhÃŒllen bei der Suche nach dem Startindex.',0,), 172 14006 => array('Pie3D Interner Fehler: Z-Sortier-Algorithmus fÃŒr 3D-Tortendiagramme funktioniert nicht einwandfrei (2). Versuch, zweimal zu umhÃŒllen beim Erstellen des Bildes.',0), 173 14007 => array('Die Breite fÃŒr das 3D-Tortendiagramm ist 0. Gib eine Breite > 0 an.',0), 172 174 173 175 /* … … 176 178 177 179 15001 => array('PiePLot::SetTheme() Unbekannter Stil: %s',1), 178 15002 => array('Argument f ür PiePlot::ExplodeSlice() muss ein Integer-Wert sein',0),179 15003 => array('Argument f ür PiePlot::Explode() muss ein Vektor mit Integer-Werten sein.',0),180 15004 => array('Tortenst ück-Startwinkel muss zwischen 0 und 360 Grad sein.',0),180 15002 => array('Argument fÃŒr PiePlot::ExplodeSlice() muss ein Integer-Wert sein',0), 181 15003 => array('Argument fÃŒr PiePlot::Explode() muss ein Vektor mit Integer-Werten sein.',0), 182 15004 => array('TortenstÃŒck-Startwinkel muss zwischen 0 und 360 Grad sein.',0), 181 183 15005 => array('PiePlot::SetFont() sollte nicht mehr verwendet werden. Benutze stattdessen PiePlot->value->SetFont().',0), 182 15006 => array('PiePlot::SetSize() Radius f ür Tortendiagramm muss entweder als Bruch [0, 0.5] der Bildgröße oder als Absoluwert in Pixel im Bereich [10, 1000] angegeben werden.',0),184 15006 => array('PiePlot::SetSize() Radius fÃŒr Tortendiagramm muss entweder als Bruch [0, 0.5] der BildgröÃe oder als Absoluwert in Pixel im Bereich [10, 1000] angegeben werden.',0), 183 185 15007 => array('PiePlot::SetFontColor() sollte nicht mehr verwendet werden. Benutze stattdessen PiePlot->value->SetColor()..',0), 184 15008 => array('PiePlot::SetLabelType() der Typ f ür Tortendiagramme muss entweder 0 or 1 sein (nicht %d).',1),185 15009 => array('Ung ültiges Tortendiagramm. Die Summe aller Daten ist Null.',0),186 15008 => array('PiePlot::SetLabelType() der Typ fÃŒr Tortendiagramme muss entweder 0 or 1 sein (nicht %d).',1), 187 15009 => array('UngÃŒltiges Tortendiagramm. Die Summe aller Daten ist Null.',0), 186 188 15010 => array('Die Summe aller Daten ist Null.',0), 187 15011 => array('Um Bildtransformationen benutzen zu können, muss die Datei jpgraph_imgtrans.php eingefügt werden (per include).',0), 189 15011 => array('Um Bildtransformationen benutzen zu können, muss die Datei jpgraph_imgtrans.php eingefÃŒgt werden (per include).',0), // @todo translate into German 190 15012 => array('PiePlot::SetTheme() is no longer recommended. Use PieGraph::SetTheme()',0), 188 191 189 192 /* … … 191 194 */ 192 195 193 16001 => array('Die Dichte f ür das Pattern muss zwischen 1 und 100 sein. (Du hast %f eingegeben)',1),194 16002 => array('Es wurde keine Position f ür das Pattern angegeben.',0),196 16001 => array('Die Dichte fÃŒr das Pattern muss zwischen 1 und 100 sein. (Du hast %f eingegeben)',1), 197 16002 => array('Es wurde keine Position fÃŒr das Pattern angegeben.',0), 195 198 16003 => array('Unbekannte Pattern-Definition (%d)',0), 196 16004 => array('Der Mindeswert f ür das PlotBand ist größer als der Maximalwert. Bitte korrigiere dies!',0),199 16004 => array('Der Mindeswert fÃŒr das PlotBand ist gröÃer als der Maximalwert. Bitte korrigiere dies!',0), 197 200 198 201 … … 201 204 */ 202 205 203 17001 => array('PolarPlots m üssen eine gerade Anzahl von Datenpunkten haben. Jeder Datenpunkt ist ein Tupel (Winkel, Radius).',0),204 17002 => array('Unbekannte Ausrichtung f ür X-Achsen-Titel. (%s)',1),205 //17003 => array('Set90AndMargin() wird f ür PolarGraph nicht unterstützt.',0),206 17004 => array('Unbekannter Achsentyp f ür PolarGraph. Er muss entweder \'lin\' oder \'log\' sein.',0),206 17001 => array('PolarPlots mÃŒssen eine gerade Anzahl von Datenpunkten haben. Jeder Datenpunkt ist ein Tupel (Winkel, Radius).',0), 207 17002 => array('Unbekannte Ausrichtung fÃŒr X-Achsen-Titel. (%s)',1), 208 //17003 => array('Set90AndMargin() wird fÃŒr PolarGraph nicht unterstÃŒtzt.',0), 209 17004 => array('Unbekannter Achsentyp fÃŒr PolarGraph. Er muss entweder \'lin\' oder \'log\' sein.',0), 207 210 208 211 /* … … 210 213 */ 211 214 212 18001 => array('ClientSideImageMaps werden f ür RadarPlots nicht unterstützt.',0),215 18001 => array('ClientSideImageMaps werden fÃŒr RadarPlots nicht unterstÃŒtzt.',0), 213 216 18002 => array('RadarGraph::SupressTickMarks() sollte nicht mehr verwendet werden. Benutze stattdessen HideTickMarks().',0), 214 18003 => array('Ung ültiger Achsentyp für RadarPlot (%s). Er muss entweder \'lin\' oder \'log\' sein.',1),215 18004 => array('Die RadarPlot-Gr öße muss zwischen 0.1 und 1 sein. (Dein Wert=%f)',1),216 18005 => array('RadarPlot: nicht unterst ützte Tick-Dichte: %d',1),217 18003 => array('UngÃŒltiger Achsentyp fÃŒr RadarPlot (%s). Er muss entweder \'lin\' oder \'log\' sein.',1), 218 18004 => array('Die RadarPlot-GröÃe muss zwischen 0.1 und 1 sein. (Dein Wert=%f)',1), 219 18005 => array('RadarPlot: nicht unterstÃŒtzte Tick-Dichte: %d',1), 217 220 18006 => array('Minimum Daten %f (RadarPlots sollten nur verwendet werden, wenn alle Datenpunkte einen Wert > 0 haben).',1), 218 221 18007 => array('Die Anzahl der Titel entspricht nicht der Anzahl der Datenpunkte.',0), … … 224 227 225 228 19001 => array('Spline: Anzahl der X- und Y-Koordinaten muss gleich sein.',0), 226 19002 => array('Ung ültige Dateneingabe für Spline. Zwei oder mehr aufeinanderfolgende X-Werte sind identisch. Jeder eigegebene X-Wert muss unterschiedlich sein, weil vom mathematischen Standpunkt ein Eins-zu-Eins-Mapping vorliegen muss, d.h. jeder X-Wert korrespondiert mit exakt einem Y-Wert.',0),229 19002 => array('UngÃŒltige Dateneingabe fÃŒr Spline. Zwei oder mehr aufeinanderfolgende X-Werte sind identisch. Jeder eigegebene X-Wert muss unterschiedlich sein, weil vom mathematischen Standpunkt ein Eins-zu-Eins-Mapping vorliegen muss, d.h. jeder X-Wert korrespondiert mit exakt einem Y-Wert.',0), 227 230 19003 => array('Bezier: Anzahl der X- und Y-Koordinaten muss gleich sein.',0), 228 231 … … 231 234 */ 232 235 233 20001 => array('Fieldplots m üssen die gleiche Anzahl von X und Y Datenpunkten haben.',0),234 20002 => array('Bei Fieldplots muss ein Winkel f ür jeden X und Y Datenpunkt angegeben werden.',0),235 20003 => array('Scatterplots m üssen die gleiche Anzahl von X- und Y-Datenpunkten haben.',0),236 20001 => array('Fieldplots mÃŒssen die gleiche Anzahl von X und Y Datenpunkten haben.',0), 237 20002 => array('Bei Fieldplots muss ein Winkel fÃŒr jeden X und Y Datenpunkt angegeben werden.',0), 238 20003 => array('Scatterplots mÃŒssen die gleiche Anzahl von X- und Y-Datenpunkten haben.',0), 236 239 237 240 /* … … 239 242 */ 240 243 241 21001 => array('Die Anzahl der Datenwerte f ür Stock-Charts müssen ein Mehrfaches von %d Datenpunkten sein.',1),244 21001 => array('Die Anzahl der Datenwerte fÃŒr Stock-Charts mÃŒssen ein Mehrfaches von %d Datenpunkten sein.',1), 242 245 243 246 /* … … 246 249 247 250 23001 => array('Der Marker "%s" existiert nicht in der Farbe: %d',2), 248 23002 => array('Der Farb-Index ist zu hoch f ür den Marker "%s"',1),251 23002 => array('Der Farb-Index ist zu hoch fÃŒr den Marker "%s"',1), 249 252 23003 => array('Ein Dateiname muss angegeben werden, wenn Du den Marker-Typ auf MARK_IMG setzt.',0), 250 253 … … 256 259 24002 => array('FuncGenerator : Syntax-Fehler in der Funktionsdefinition ',0), 257 260 24003 => array('DateScaleUtils: Unknown tick type specified in call to GetTicks()',0), 258 261 24004 => array('ReadCSV2: Die anzahl der spalten fehler in %s reihe %d',2), 259 262 /* 260 263 ** jpgraph 261 264 */ 262 265 263 25001 => array('Diese PHP-Installation ist nicht mit der GD-Bibliothek kompiliert. Bitte kompiliere PHP mit GD-Unterst ützung neu, damit JpGraph funktioniert. (Weder die Funktion imagetypes() noch imagecreatefromstring() existiert!)',0),264 25002 => array('Diese PHP-Installation scheint nicht die ben ötigte GD-Bibliothek zu unterstützen. Bitte schau in der PHP-Dokumentation nach, wie man die GD-Bibliothek installiert und aktiviert.',0),266 25001 => array('Diese PHP-Installation ist nicht mit der GD-Bibliothek kompiliert. Bitte kompiliere PHP mit GD-UnterstÃŒtzung neu, damit JpGraph funktioniert. (Weder die Funktion imagetypes() noch imagecreatefromstring() existiert!)',0), 267 25002 => array('Diese PHP-Installation scheint nicht die benötigte GD-Bibliothek zu unterstÃŒtzen. Bitte schau in der PHP-Dokumentation nach, wie man die GD-Bibliothek installiert und aktiviert.',0), 265 268 25003 => array('Genereller PHP Fehler : Bei %s:%d : %s',3), 266 269 25004 => array('Genereller PHP Fehler : %s ',1), 267 270 25005 => array('PHP_SELF, die PHP-Global-Variable kann nicht ermittelt werden. PHP kann nicht von der Kommandozeile gestartet werden, wenn der Cache oder die Bilddateien automatisch benannt werden sollen.',0), 268 25006 => array('Die Benutzung der FF_CHINESE (FF_BIG5) Schriftfamilie ben ötigt die iconv() Funktion in Deiner PHP-Konfiguration. Dies wird nicht defaultmäßig in PHP kompiliert (benötigt "--width-iconv" bei der Konfiguration).',0),269 25007 => array('Du versuchst das lokale (%s) zu verwenden, was von Deiner PHP-Installation nicht unterst ützt wird. Hinweis: Benutze \'\', um das defaultmäßige Lokale für diese geographische Region festzulegen.',1),270 25008 => array('Die Bild-Breite und H öhe in Graph::Graph() müssen numerisch sein',0),271 25006 => array('Die Benutzung der FF_CHINESE (FF_BIG5) Schriftfamilie benötigt die iconv() Funktion in Deiner PHP-Konfiguration. Dies wird nicht defaultmÀÃig in PHP kompiliert (benötigt "--width-iconv" bei der Konfiguration).',0), 272 25007 => array('Du versuchst das lokale (%s) zu verwenden, was von Deiner PHP-Installation nicht unterstÃŒtzt wird. Hinweis: Benutze \'\', um das defaultmÀÃige Lokale fÃŒr diese geographische Region festzulegen.',1), 273 25008 => array('Die Bild-Breite und Höhe in Graph::Graph() mÃŒssen numerisch sein',0), 271 274 25009 => array('Die Skalierung der Achsen muss angegeben werden mit Graph::SetScale()',0), 272 275 273 25010 => array('Graph::Add() Du hast versucht, einen leeren Plot zum Graph hinzuzuf ügen.',0),274 25011 => array('Graph::AddY2() Du hast versucht, einen leeren Plot zum Graph hinzuzuf ügen.',0),275 25012 => array('Graph::AddYN() Du hast versucht, einen leeren Plot zum Graph hinzuzuf ügen.',0),276 25013 => array('Es k önnen nur Standard-Plots zu multiplen Y-Achsen hinzugefügt werden',0),277 25014 => array('Graph::AddText() Du hast versucht, einen leeren Text zum Graph hinzuzuf ügen.',0),278 25015 => array('Graph::AddLine() Du hast versucht, eine leere Linie zum Graph hinzuzuf ügen.',0),279 25016 => array('Graph::AddBand() Du hast versucht, ein leeres Band zum Graph hinzuzuf ügen.',0),280 25017 => array('Du benutzt GD 2.x und versuchst, ein Hintergrundbild in einem Truecolor-Bild zu verwenden. Um Hintergrundbilder mit GD 2.x zu verwenden, ist es notwendig, Truecolor zu aktivieren, indem die USE_TRUECOLOR-Konstante auf TRUE gesetzt wird. Wegen eines Bugs in GD 2.0.1 ist die Qualit ät der Schrift sehr schlecht, wenn Truetype-Schrift in Truecolor-Bildern verwendet werden.',0),281 25018 => array('Falscher Dateiname f ür Graph::SetBackgroundImage() : "%s" muss eine gültige Dateinamenerweiterung (jpg,gif,png) haben, wenn die automatische Dateityperkennung verwenndet werden soll.',1),282 25019 => array('Unbekannte Dateinamenerweiterung (%s) in Graph::SetBackgroundImage() f ür Dateiname: "%s"',2),283 284 25020 => array('Graph::SetScale(): Dar Maximalwert muss gr ößer sein als der Mindestwert.',0),285 25021 => array('Unbekannte Achsendefinition f ür die Y-Achse. (%s)',1),286 25022 => array('Unbekannte Achsendefinition f ür die X-Achse. (%s)',1),287 25023 => array('Nicht unterst ützter Y2-Achsentyp: "%s" muss einer von (lin,log,int) sein.',1),288 25024 => array('Nicht unterst ützter X-Achsentyp: "%s" muss einer von (lin,log,int) sein.',1),289 25025 => array('Nicht unterst ützte Tick-Dichte: %d',1),290 25026 => array('Nicht unterst ützter Typ der nicht angegebenen Y-Achse. Du hast entweder: 1. einen Y-Achsentyp für automatisches Skalieren definiert, aber keine Plots angegeben. 2. eine Achse direkt definiert, aber vergessen, die Tick-Dichte zu festzulegen.',0),291 25027 => array('Kann cached CSIM "%s" zum Lesen nicht öffnen.',1),292 25028 => array('Apache/PHP hat keine Schreibrechte, in das CSIM-Cache-Verzeichnis (%s) zu schreiben. Überprüfe die Rechte.',1),293 25029 => array('Kann nicht in das CSIM "%s" schreiben. Überprüfe die Schreibrechte und den freien Speicherplatz.',1),294 295 25030 => array('Fehlender Skriptname f ür StrokeCSIM(). Der Name des aktuellen Skriptes muss als erster Parameter von StrokeCSIM() angegeben werden.',0),276 25010 => array('Graph::Add() Du hast versucht, einen leeren Plot zum Graph hinzuzufÃŒgen.',0), 277 25011 => array('Graph::AddY2() Du hast versucht, einen leeren Plot zum Graph hinzuzufÃŒgen.',0), 278 25012 => array('Graph::AddYN() Du hast versucht, einen leeren Plot zum Graph hinzuzufÃŒgen.',0), 279 25013 => array('Es können nur Standard-Plots zu multiplen Y-Achsen hinzugefÃŒgt werden',0), 280 25014 => array('Graph::AddText() Du hast versucht, einen leeren Text zum Graph hinzuzufÃŒgen.',0), 281 25015 => array('Graph::AddLine() Du hast versucht, eine leere Linie zum Graph hinzuzufÃŒgen.',0), 282 25016 => array('Graph::AddBand() Du hast versucht, ein leeres Band zum Graph hinzuzufÃŒgen.',0), 283 25017 => array('Du benutzt GD 2.x und versuchst, ein Hintergrundbild in einem Truecolor-Bild zu verwenden. Um Hintergrundbilder mit GD 2.x zu verwenden, ist es notwendig, Truecolor zu aktivieren, indem die USE_TRUECOLOR-Konstante auf TRUE gesetzt wird. Wegen eines Bugs in GD 2.0.1 ist die QualitÀt der Schrift sehr schlecht, wenn Truetype-Schrift in Truecolor-Bildern verwendet werden.',0), 284 25018 => array('Falscher Dateiname fÃŒr Graph::SetBackgroundImage() : "%s" muss eine gÃŒltige Dateinamenerweiterung (jpg,gif,png) haben, wenn die automatische Dateityperkennung verwenndet werden soll.',1), 285 25019 => array('Unbekannte Dateinamenerweiterung (%s) in Graph::SetBackgroundImage() fÃŒr Dateiname: "%s"',2), 286 287 25020 => array('Graph::SetScale(): Dar Maximalwert muss gröÃer sein als der Mindestwert.',0), 288 25021 => array('Unbekannte Achsendefinition fÃŒr die Y-Achse. (%s)',1), 289 25022 => array('Unbekannte Achsendefinition fÃŒr die X-Achse. (%s)',1), 290 25023 => array('Nicht unterstÃŒtzter Y2-Achsentyp: "%s" muss einer von (lin,log,int) sein.',1), 291 25024 => array('Nicht unterstÃŒtzter X-Achsentyp: "%s" muss einer von (lin,log,int) sein.',1), 292 25025 => array('Nicht unterstÃŒtzte Tick-Dichte: %d',1), 293 25026 => array('Nicht unterstÃŒtzter Typ der nicht angegebenen Y-Achse. Du hast entweder: 1. einen Y-Achsentyp fÃŒr automatisches Skalieren definiert, aber keine Plots angegeben. 2. eine Achse direkt definiert, aber vergessen, die Tick-Dichte zu festzulegen.',0), 294 25027 => array('Kann cached CSIM "%s" zum Lesen nicht öffnen.',1), 295 25028 => array('Apache/PHP hat keine Schreibrechte, in das CSIM-Cache-Verzeichnis (%s) zu schreiben. ÃberprÃŒfe die Rechte.',1), 296 25029 => array('Kann nicht in das CSIM "%s" schreiben. ÃberprÃŒfe die Schreibrechte und den freien Speicherplatz.',1), 297 298 25030 => array('Fehlender Skriptname fÃŒr StrokeCSIM(). Der Name des aktuellen Skriptes muss als erster Parameter von StrokeCSIM() angegeben werden.',0), 296 299 25031 => array('Der Achsentyp muss mittels Graph::SetScale() angegeben werden.',0), 297 25032 => array('Es existieren keine Plots f ür die Y-Achse nbr:%d',1),300 25032 => array('Es existieren keine Plots fÃŒr die Y-Achse nbr:%d',1), 298 301 25033 => array('',0), 299 302 25034 => array('Undefinierte X-Achse kann nicht gezeichnet werden. Es wurden keine Plots definiert.',0), 300 25035 => array('Du hast Clipping aktiviert. Clipping wird nur f ür Diagramme mit 0 oder 90 Grad Rotation unterstützt. Bitte verändere Deinen Rotationswinkel (=%d Grad) dementsprechend oder deaktiviere Clipping.',1),303 25035 => array('Du hast Clipping aktiviert. Clipping wird nur fÃŒr Diagramme mit 0 oder 90 Grad Rotation unterstÃŒtzt. Bitte verÀndere Deinen Rotationswinkel (=%d Grad) dementsprechend oder deaktiviere Clipping.',1), 301 304 25036 => array('Unbekannter Achsentyp AxisStyle() : %s',1), 302 25037 => array('Das Bildformat Deines Hintergrundbildes (%s) wird von Deiner System-Konfiguration nicht unterst ützt. ',1),305 25037 => array('Das Bildformat Deines Hintergrundbildes (%s) wird von Deiner System-Konfiguration nicht unterstÃŒtzt. ',1), 303 306 25038 => array('Das Hintergrundbild scheint von einem anderen Typ (unterschiedliche Dateierweiterung) zu sein als der angegebene Typ. Angegebenen: %s; Datei: %s',2), 304 307 25039 => array('Hintergrundbild kann nicht gelesen werden: "%s"',1), 305 308 306 25040 => array('Es ist nicht m öglich, sowohl ein Hintergrundbild als auch eine Hintergrund-Landesflagge anzugeben.',0),307 25041 => array('Um Landesflaggen als Hintergrund benutzen zu k önnen, muss die Datei "jpgraph_flags.php" eingefügt werden (per include).',0),309 25040 => array('Es ist nicht möglich, sowohl ein Hintergrundbild als auch eine Hintergrund-Landesflagge anzugeben.',0), 310 25041 => array('Um Landesflaggen als Hintergrund benutzen zu können, muss die Datei "jpgraph_flags.php" eingefÃŒgt werden (per include).',0), 308 311 25042 => array('Unbekanntes Hintergrundbild-Layout',0), 309 312 25043 => array('Unbekannter Titelhintergrund-Stil.',0), 310 25044 => array('Automatisches Skalieren kann nicht verwendet werden, weil es unm öglich ist, einen gültigen min/max Wert für die Y-Achse zu ermitteln (nur Null-Werte).',0),311 25045 => array('Die Schriftfamilien FF_HANDWRT und FF_BOOK sind wegen Copyright-Problemen nicht mehr verf ügbar. Diese Schriften können nicht mehr mit JpGraph verteilt werden. Bitte lade Dir Schriften von http://corefonts.sourceforge.net/ herunter.',0),313 25044 => array('Automatisches Skalieren kann nicht verwendet werden, weil es unmöglich ist, einen gÃŒltigen min/max Wert fÃŒr die Y-Achse zu ermitteln (nur Null-Werte).',0), 314 25045 => array('Die Schriftfamilien FF_HANDWRT und FF_BOOK sind wegen Copyright-Problemen nicht mehr verfÃŒgbar. Diese Schriften können nicht mehr mit JpGraph verteilt werden. Bitte lade Dir Schriften von http://corefonts.sourceforge.net/ herunter.',0), 312 315 25046 => array('Angegebene TTF-Schriftfamilie (id=%d) ist unbekannt oder existiert nicht. Bitte merke Dir, dass TTF-Schriften wegen Copyright-Problemen nicht mit JpGraph mitgeliefert werden. Du findest MS-TTF-Internetschriften (arial, courier, etc.) zum Herunterladen unter http://corefonts.sourceforge.net/',1), 313 25047 => array('Stil %s ist nicht verf ügbar für Schriftfamilie %s',2),316 25047 => array('Stil %s ist nicht verfÃŒgbar fÃŒr Schriftfamilie %s',2), 314 317 25048 => array('Unbekannte Schriftstildefinition [%s].',1), 315 318 25049 => array('Schriftdatei "%s" ist nicht lesbar oder existiert nicht.',1), 316 319 317 25050 => array('Erstes Argument f ür Text::Text() muss ein String sein.',0),318 25051 => array('Ung ültige Richtung angegeben für Text.',0),319 25052 => array('PANIK: Interner Fehler in SuperScript::Stroke(). Unbekannte vertikale Ausrichtung f ür Text.',0),320 25053 => array('PANIK: Interner Fehler in SuperScript::Stroke(). Unbekannte horizontale Ausrichtung f ür Text.',0),320 25050 => array('Erstes Argument fÃŒr Text::Text() muss ein String sein.',0), 321 25051 => array('UngÃŒltige Richtung angegeben fÃŒr Text.',0), 322 25052 => array('PANIK: Interner Fehler in SuperScript::Stroke(). Unbekannte vertikale Ausrichtung fÃŒr Text.',0), 323 25053 => array('PANIK: Interner Fehler in SuperScript::Stroke(). Unbekannte horizontale Ausrichtung fÃŒr Text.',0), 321 324 25054 => array('Interner Fehler: Unbekannte Grid-Achse %s',1), 322 325 25055 => array('Axis::SetTickDirection() sollte nicht mehr verwendet werden. Benutze stattdessen Axis::SetTickSide().',0), … … 326 329 25059 => array('SetLabelPos() sollte nicht mehr verwendet werden. Benutze stattdessen Axis::SetLabelSide().',0), 327 330 328 25060 => array('Unbekannte Ausrichtung angegeben f ür X-Achsentitel (%s).',1),329 25061 => array('Unbekannte Ausrichtung angegeben f ür Y-Achsentitel (%s).',1),330 25062 => array('Label unter einem Winkel werden f ür die Y-Achse nicht unterstützt.',0),331 25060 => array('Unbekannte Ausrichtung angegeben fÃŒr X-Achsentitel (%s).',1), 332 25061 => array('Unbekannte Ausrichtung angegeben fÃŒr Y-Achsentitel (%s).',1), 333 25062 => array('Label unter einem Winkel werden fÃŒr die Y-Achse nicht unterstÃŒtzt.',0), 331 334 25063 => array('Ticks::SetPrecision() sollte nicht mehr verwendet werden. Benutze stattdessen Ticks::SetLabelFormat() (oder Ticks::SetFormatCallback()).',0), 332 25064 => array('Kleinere oder gr ößere Schrittgröße ist 0. Überprüfe, ob Du fälschlicherweise SetTextTicks(0) in Deinem Skript hast. Wenn dies nicht der Fall ist, bist Du eventuell über einen Bug in JpGraph gestolpert. Bitte sende einen Report und füge den Code an, der den Fehler verursacht hat.',0),333 25065 => array('Tick-Positionen m üssen als array() angegeben werden',0),335 25064 => array('Kleinere oder gröÃere SchrittgröÃe ist 0. ÃberprÃŒfe, ob Du fÀlschlicherweise SetTextTicks(0) in Deinem Skript hast. Wenn dies nicht der Fall ist, bist Du eventuell ÃŒber einen Bug in JpGraph gestolpert. Bitte sende einen Report und fÃŒge den Code an, der den Fehler verursacht hat.',0), 336 25065 => array('Tick-Positionen mÃŒssen als array() angegeben werden',0), 334 337 25066 => array('Wenn die Tick-Positionen und -Label von Hand eingegeben werden, muss die Anzahl der Ticks und der Label gleich sein.',0), 335 25067 => array('Deine von Hand eingegebene Achse und Ticks sind nicht korrekt. Die Skala scheint zu klein zu sein f ür den Tickabstand.',0),336 25068 => array('Ein Plot hat eine ung ültige Achse. Dies kann beispielsweise der Fall sein, wenn Du automatisches Text-Skalieren verwendest, um ein Liniendiagramm zu zeichnen mit nur einem Datenpunkt, oder wenn die Bildfläche zu klein ist. Es kann auch der Fall sein, dass kein Datenpunkt einen numerischen Wert hat (vielleicht nur \'-\' oder \'x\').',0),337 25069 => array('Grace muss gr ößer sein als 0',0),338 25067 => array('Deine von Hand eingegebene Achse und Ticks sind nicht korrekt. Die Skala scheint zu klein zu sein fÃŒr den Tickabstand.',0), 339 25068 => array('Ein Plot hat eine ungÃŒltige Achse. Dies kann beispielsweise der Fall sein, wenn Du automatisches Text-Skalieren verwendest, um ein Liniendiagramm zu zeichnen mit nur einem Datenpunkt, oder wenn die BildflÀche zu klein ist. Es kann auch der Fall sein, dass kein Datenpunkt einen numerischen Wert hat (vielleicht nur \'-\' oder \'x\').',0), 340 25069 => array('Grace muss gröÃer sein als 0',0), 338 341 339 342 25070 => array('Deine Daten enthalten nicht-numerische Werte.',0), 340 25071 => array('Du hast mit SetAutoMin() einen Mindestwert angegeben, der gr ößer ist als der Maximalwert für die Achse. Dies ist nicht möglich.',0),341 25072 => array('Du hast mit SetAutoMax() einen Maximalwert angegeben, der kleiner ist als der Minimalwert der Achse. Dies ist nicht m öglich.',0),342 25073 => array('Interner Fehler. Der Integer-Skalierungs-Algorithmus-Vergleich ist au ßerhalb der Grenzen (r=%f).',1),343 25074 => array('Interner Fehler. Der Skalierungsbereich ist negativ (%f) [f ür %s Achse]. Dieses Problem könnte verursacht werden durch den Versuch, \'ungültige\' Werte in die Daten-Vektoren einzugeben (z.B. nur String- oder NULL-Werte), was beim automatischen Skalieren einen Fehler erzeugt.',2),344 25075 => array('Die automatischen Ticks k önnen nicht gesetzt werden, weil min==max.',0),345 25077 => array('Einstellfaktor f ür die Farbe muss größer sein als 0',0),343 25071 => array('Du hast mit SetAutoMin() einen Mindestwert angegeben, der gröÃer ist als der Maximalwert fÃŒr die Achse. Dies ist nicht möglich.',0), 344 25072 => array('Du hast mit SetAutoMax() einen Maximalwert angegeben, der kleiner ist als der Minimalwert der Achse. Dies ist nicht möglich.',0), 345 25073 => array('Interner Fehler. Der Integer-Skalierungs-Algorithmus-Vergleich ist auÃerhalb der Grenzen (r=%f).',1), 346 25074 => array('Interner Fehler. Der Skalierungsbereich ist negativ (%f) [fÃŒr %s Achse]. Dieses Problem könnte verursacht werden durch den Versuch, \'ungÃŒltige\' Werte in die Daten-Vektoren einzugeben (z.B. nur String- oder NULL-Werte), was beim automatischen Skalieren einen Fehler erzeugt.',2), 347 25075 => array('Die automatischen Ticks können nicht gesetzt werden, weil min==max.',0), 348 25077 => array('Einstellfaktor fÃŒr die Farbe muss gröÃer sein als 0',0), 346 349 25078 => array('Unbekannte Farbe: %s',1), 347 25079 => array('Unbekannte Farbdefinition: %s, Gr öße=%d',2),348 349 25080 => array('Der Alpha-Parameter f ür Farben muss zwischen 0.0 und 1.0 liegen.',0),350 25081 => array('Das ausgew ählte Grafikformat wird entweder nicht unterstützt oder ist unbekannt [%s]',1),351 25082 => array('Es wurden ung ültige Größen für Breite und Höhe beim Erstellen des Bildes definiert (Breite=%d, Höhe=%d).',2),352 25083 => array('Es wurde eine ung ültige Größe beim Kopieren des Bildes angegeben. Die Größe für das kopierte Bild wurde auf 1 Pixel oder weniger gesetzt.',0),353 25084 => array('Fehler beim Erstellen eines tempor ären GD-Canvas. Möglicherweise liegt ein Arbeitsspeicherproblem vor.',0),354 25085 => array('Ein Bild kann nicht aus dem angegebenen String erzeugt werden. Er ist entweder in einem nicht unterst ützen Format oder er represäntiert ein kaputtes Bild.',0),355 25086 => array('Du scheinst nur GD 1.x installiert zu haben. Um Alphablending zu aktivieren, ist GD 2.x oder h öher notwendig. Bitte installiere GD 2.x oder versichere Dich, dass die Konstante USE_GD2 richtig gesetzt ist. Standardmäßig wird die installierte GD-Version automatisch erkannt. Ganz selten wird GD2 erkannt, obwohl nur GD1 installiert ist. Die Konstante USE_GD2 muss dann zu "false" gesetzt werden.',0),356 25087 => array('Diese PHP-Version wurde ohne TTF-Unterst ützung konfiguriert. PHP muss mit TTF-Unterstützung neu kompiliert und installiert werden.',0),357 25088 => array('Die GD-Schriftunterst ützung wurde falsch konfiguriert. Der Aufruf von imagefontwidth() ist fehlerhaft.',0),358 25089 => array('Die GD-Schriftunterst ützung wurde falsch konfiguriert. Der Aufruf von imagefontheight() ist fehlerhaft.',0),350 25079 => array('Unbekannte Farbdefinition: %s, GröÃe=%d',2), 351 352 25080 => array('Der Alpha-Parameter fÃŒr Farben muss zwischen 0.0 und 1.0 liegen.',0), 353 25081 => array('Das ausgewÀhlte Grafikformat wird entweder nicht unterstÃŒtzt oder ist unbekannt [%s]',1), 354 25082 => array('Es wurden ungÃŒltige GröÃen fÃŒr Breite und Höhe beim Erstellen des Bildes definiert (Breite=%d, Höhe=%d).',2), 355 25083 => array('Es wurde eine ungÃŒltige GröÃe beim Kopieren des Bildes angegeben. Die GröÃe fÃŒr das kopierte Bild wurde auf 1 Pixel oder weniger gesetzt.',0), 356 25084 => array('Fehler beim Erstellen eines temporÀren GD-Canvas. Möglicherweise liegt ein Arbeitsspeicherproblem vor.',0), 357 25085 => array('Ein Bild kann nicht aus dem angegebenen String erzeugt werden. Er ist entweder in einem nicht unterstÃŒtzen Format oder er represÀntiert ein kaputtes Bild.',0), 358 25086 => array('Du scheinst nur GD 1.x installiert zu haben. Um Alphablending zu aktivieren, ist GD 2.x oder höher notwendig. Bitte installiere GD 2.x oder versichere Dich, dass die Konstante USE_GD2 richtig gesetzt ist. StandardmÀÃig wird die installierte GD-Version automatisch erkannt. Ganz selten wird GD2 erkannt, obwohl nur GD1 installiert ist. Die Konstante USE_GD2 muss dann zu "false" gesetzt werden.',0), 359 25087 => array('Diese PHP-Version wurde ohne TTF-UnterstÃŒtzung konfiguriert. PHP muss mit TTF-UnterstÃŒtzung neu kompiliert und installiert werden.',0), 360 25088 => array('Die GD-SchriftunterstÃŒtzung wurde falsch konfiguriert. Der Aufruf von imagefontwidth() ist fehlerhaft.',0), 361 25089 => array('Die GD-SchriftunterstÃŒtzung wurde falsch konfiguriert. Der Aufruf von imagefontheight() ist fehlerhaft.',0), 359 362 360 363 25090 => array('Unbekannte Richtung angegeben im Aufruf von StrokeBoxedText() [%s].',1), 361 25091 => array('Die interne Schrift untest ützt das Schreiben von Text in einem beliebigen Winkel nicht. Benutze stattdessen TTF-Schriften.',0),362 25092 => array('Es liegt entweder ein Konfigurationsproblem mit TrueType oder ein Problem beim Lesen der Schriftdatei "%s" vor. Versichere Dich, dass die Datei existiert und Leserechte und -pfad vergeben sind. (wenn \'basedir\' restriction in PHP aktiviert ist, muss die Schriftdatei im Dokumentwurzelverzeichnis abgelegt werden). M öglicherweise ist die FreeType-Bibliothek falsch installiert. Versuche, mindestens zur FreeType-Version 2.1.13 zu aktualisieren und kompiliere GD mit einem korrekten Setup neu, damit die FreeType-Bibliothek gefunden werden kann.',1),364 25091 => array('Die interne Schrift untestÃŒtzt das Schreiben von Text in einem beliebigen Winkel nicht. Benutze stattdessen TTF-Schriften.',0), 365 25092 => array('Es liegt entweder ein Konfigurationsproblem mit TrueType oder ein Problem beim Lesen der Schriftdatei "%s" vor. Versichere Dich, dass die Datei existiert und Leserechte und -pfad vergeben sind. (wenn \'basedir\' restriction in PHP aktiviert ist, muss die Schriftdatei im Dokumentwurzelverzeichnis abgelegt werden). Möglicherweise ist die FreeType-Bibliothek falsch installiert. Versuche, mindestens zur FreeType-Version 2.1.13 zu aktualisieren und kompiliere GD mit einem korrekten Setup neu, damit die FreeType-Bibliothek gefunden werden kann.',1), 363 366 25093 => array('Die Schriftdatei "%s" kann nicht gelesen werden beim Aufruf von Image::GetBBoxTTF. Bitte versichere Dich, dass die Schrift gesetzt wurde, bevor diese Methode aufgerufen wird, und dass die Schrift im TTF-Verzeichnis installiert ist.',1), 364 367 25094 => array('Die Textrichtung muss in einem Winkel zwischen 0 und 90 engegeben werden.',0), 365 368 25095 => array('Unbekannte Schriftfamilien-Definition. ',0), 366 25096 => array('Der Farbpalette k önnen keine weiteren Farben zugewiesen werden. Dem Bild wurde bereits die größtmögliche Anzahl von Farben (%d) zugewiesen und die Palette ist voll. Verwende stattdessen ein TrueColor-Bild',0),369 25096 => array('Der Farbpalette können keine weiteren Farben zugewiesen werden. Dem Bild wurde bereits die gröÃtmögliche Anzahl von Farben (%d) zugewiesen und die Palette ist voll. Verwende stattdessen ein TrueColor-Bild',0), 367 370 25097 => array('Eine Farbe wurde als leerer String im Aufruf von PushColor() angegegeben.',0), 368 371 25098 => array('Negativer Farbindex. Unpassender Aufruf von PopColor().',0), 369 25099 => array('Die Parameter f ür Helligkeit und Kontrast sind außerhalb des zulässigen Bereichs [-1,1]',0),372 25099 => array('Die Parameter fÃŒr Helligkeit und Kontrast sind auÃerhalb des zulÀssigen Bereichs [-1,1]',0), 370 373 371 374 25100 => array('Es liegt ein Problem mit der Farbpalette und dem GD-Setup vor. Bitte deaktiviere anti-aliasing oder verwende GD2 mit TrueColor. Wenn die GD2-Bibliothek installiert ist, versichere Dich, dass die Konstante USE_GD2 auf "true" gesetzt und TrueColor aktiviert ist.',0), 372 25101 => array('Ung ültiges numerisches Argument für SetLineStyle(): (%d)',1),373 25102 => array('Ung ültiges String-Argument für SetLineStyle(): %s',1),374 25103 => array('Ung ültiges Argument für SetLineStyle %s',1),375 25101 => array('UngÃŒltiges numerisches Argument fÃŒr SetLineStyle(): (%d)',1), 376 25102 => array('UngÃŒltiges String-Argument fÃŒr SetLineStyle(): %s',1), 377 25103 => array('UngÃŒltiges Argument fÃŒr SetLineStyle %s',1), 375 378 25104 => array('Unbekannter Linientyp: %s',1), 376 25105 => array('Es wurden NULL-Daten f ür ein gefülltes Polygon angegeben. Sorge dafür, dass keine NULL-Daten angegeben werden.',0),377 25106 => array('Image::FillToBorder : es k önnen keine weiteren Farben zugewiesen werden.',0),378 25107 => array('In Datei "%s" kann nicht geschrieben werden. Überprüfe die aktuellen Schreibrechte.',1),379 25108 => array('Das Bild kann nicht gestreamt werden. M öglicherweise liegt ein Fehler im PHP/GD-Setup vor. Kompiliere PHP neu und verwende die eingebaute GD-Bibliothek, die mit PHP angeboten wird.',0),380 25109 => array('Deine PHP- (und GD-lib-) Installation scheint keine bekannten Grafikformate zu unterst ützen. Sorge zunächst dafür, dass GD als PHP-Modul kompiliert ist. Wenn Du außerdem JPEG-Bilder verwenden willst, musst Du die JPEG-Bibliothek installieren. Weitere Details sind in der PHP-Dokumentation zu finden.',0),381 382 25110 => array('Dein PHP-Installation unterst ützt das gewählte Grafikformat nicht: %s',1),383 25111 => array('Das gecachete Bild %s kann nicht gel öscht werden. Problem mit den Rechten?',1),379 25105 => array('Es wurden NULL-Daten fÃŒr ein gefÃŒlltes Polygon angegeben. Sorge dafÃŒr, dass keine NULL-Daten angegeben werden.',0), 380 25106 => array('Image::FillToBorder : es können keine weiteren Farben zugewiesen werden.',0), 381 25107 => array('In Datei "%s" kann nicht geschrieben werden. ÃberprÃŒfe die aktuellen Schreibrechte.',1), 382 25108 => array('Das Bild kann nicht gestreamt werden. Möglicherweise liegt ein Fehler im PHP/GD-Setup vor. Kompiliere PHP neu und verwende die eingebaute GD-Bibliothek, die mit PHP angeboten wird.',0), 383 25109 => array('Deine PHP- (und GD-lib-) Installation scheint keine bekannten Grafikformate zu unterstÃŒtzen. Sorge zunÀchst dafÃŒr, dass GD als PHP-Modul kompiliert ist. Wenn Du auÃerdem JPEG-Bilder verwenden willst, musst Du die JPEG-Bibliothek installieren. Weitere Details sind in der PHP-Dokumentation zu finden.',0), 384 385 25110 => array('Dein PHP-Installation unterstÃŒtzt das gewÀhlte Grafikformat nicht: %s',1), 386 25111 => array('Das gecachete Bild %s kann nicht gelöscht werden. Problem mit den Rechten?',1), 384 387 25112 => array('Das Datum der gecacheten Datei (%s) liegt in der Zukunft.',1), 385 25113 => array('Das gecachete Bild %s kann nicht gel öscht werden. Problem mit den Rechten?',1),386 25114 => array('PHP hat nicht die erforderlichen Rechte, um in die Cache-Datei %s zu schreiben. Bitte versichere Dich, dass der Benutzer, der PHP anwendet, die entsprechenden Schreibrechte f ür die Datei hat, wenn Du das Cache-System in JPGraph verwenden willst.',1),387 25115 => array('Berechtigung f ür gecachetes Bild %s kann nicht gesetzt werden. Problem mit den Rechten?',1),388 25116 => array('Datei kann nicht aus dem Cache %s ge öffnet werden',1),389 25117 => array('Gecachetes Bild %s kann nicht zum Lesen ge öffnet werden.',1),388 25113 => array('Das gecachete Bild %s kann nicht gelöscht werden. Problem mit den Rechten?',1), 389 25114 => array('PHP hat nicht die erforderlichen Rechte, um in die Cache-Datei %s zu schreiben. Bitte versichere Dich, dass der Benutzer, der PHP anwendet, die entsprechenden Schreibrechte fÃŒr die Datei hat, wenn Du das Cache-System in JPGraph verwenden willst.',1), 390 25115 => array('Berechtigung fÃŒr gecachetes Bild %s kann nicht gesetzt werden. Problem mit den Rechten?',1), 391 25116 => array('Datei kann nicht aus dem Cache %s geöffnet werden',1), 392 25117 => array('Gecachetes Bild %s kann nicht zum Lesen geöffnet werden.',1), 390 393 25118 => array('Verzeichnis %s kann nicht angelegt werden. Versichere Dich, dass PHP die Schreibrechte in diesem Verzeichnis hat.',1), 391 25119 => array('Rechte f ür Datei %s können nicht gesetzt werden. Problem mit den Rechten?',1),392 393 25120 => array('Die Position f ür die Legende muss als Prozentwert im Bereich 0-1 angegeben werden.',0),394 25121 => array('Eine leerer Datenvektor wurde f ür den Plot eingegeben. Es muss wenigstens ein Datenpunkt vorliegen.',0),394 25119 => array('Rechte fÃŒr Datei %s können nicht gesetzt werden. Problem mit den Rechten?',1), 395 396 25120 => array('Die Position fÃŒr die Legende muss als Prozentwert im Bereich 0-1 angegeben werden.',0), 397 25121 => array('Eine leerer Datenvektor wurde fÃŒr den Plot eingegeben. Es muss wenigstens ein Datenpunkt vorliegen.',0), 395 398 25122 => array('Stroke() muss als Subklasse der Klasse Plot definiert sein.',0), 396 399 25123 => array('Du kannst keine Text-X-Achse mit X-Koordinaten verwenden. Benutze stattdessen eine "int" oder "lin" Achse.',0), 397 25124 => array('Der Eingabedatenvektor mus aufeinanderfolgende Werte von 0 aufw ärts beinhalten. Der angegebene Y-Vektor beginnt mit leeren Werten (NULL).',0),398 25125 => array('Ung ültige Richtung für statische Linie.',0),399 25126 => array('Es kann kein TrueColor-Bild erzeugt werden. Überprüfe, ob die GD2-Bibliothek und PHP korrekt aufgesetzt wurden.',0),400 25124 => array('Der Eingabedatenvektor mus aufeinanderfolgende Werte von 0 aufwÀrts beinhalten. Der angegebene Y-Vektor beginnt mit leeren Werten (NULL).',0), 401 25125 => array('UngÃŒltige Richtung fÃŒr statische Linie.',0), 402 25126 => array('Es kann kein TrueColor-Bild erzeugt werden. ÃberprÃŒfe, ob die GD2-Bibliothek und PHP korrekt aufgesetzt wurden.',0), 400 403 25127 => array('The library has been configured for automatic encoding conversion of Japanese fonts. This requires that PHP has the mb_convert_encoding() function. Your PHP installation lacks this function (PHP needs the "--enable-mbstring" when compiled).',0), 401 404 25128 => array('The function imageantialias() is not available in your PHP installation. Use the GD version that comes with PHP and not the standalone version.',0), 402 405 25129 => array('Anti-alias can not be used with dashed lines. Please disable anti-alias or use solid lines.',0), 406 25130 => array('Too small plot area. (%d x %d). With the given image size and margins there is to little space left for the plot. Increase the plot size or reduce the margins.',2), 407 408 25131 => array('StrokeBoxedText2() only supports TTF fonts and not built-in bitmap fonts.',0), 409 25132 => array('Undefined property %s.',1), // @todo translate 410 25133 => array('Use Graph::SetTheme() after Graph::SetScale().',0), // @todo translate 411 412 /* 413 ** jpgraph_led 414 */ 415 416 25500 => array('Multibyte strings must be enabled in the PHP installation in order to run the LED module so that the function mb_strlen() is available. See PHP documentation for more information.',0), 417 418 403 419 /* 404 420 **--------------------------------------------------------------------------------------------- … … 411 427 */ 412 428 413 27001 => array('GTextTable: Ung ültiges Argument für Set(). Das Array-Argument muss 2-- dimensional sein.',0),414 27002 => array('GTextTable: Ung ültiges Argument für Set()',0),415 27003 => array('GTextTable: Falsche Anzahl von Argumenten f ür GTextTable::SetColor()',0),416 27004 => array('GTextTable: Angegebener Zellenbereich, der verschmolzen werden soll, ist ung ültig.',0),417 27005 => array('GTextTable: Bereits verschmolzene Zellen im Bereich (%d,%d) bis (%d,%d) k önnen nicht ein weiteres Mal verschmolzen werden.',4),418 27006 => array('GTextTable: Spalten-Argument = %d liegt au ßerhalb der festgelegten Tabellengröße.',1),419 27007 => array('GTextTable: Zeilen-Argument = %d liegt au ßerhalb der festgelegten Tabellengröße.',1),420 27008 => array('GTextTable: Spalten- und Zeilengr öße müssen zu den Dimensionen der Tabelle passen.',0),429 27001 => array('GTextTable: UngÃŒltiges Argument fÃŒr Set(). Das Array-Argument muss 2-- dimensional sein.',0), 430 27002 => array('GTextTable: UngÃŒltiges Argument fÃŒr Set()',0), 431 27003 => array('GTextTable: Falsche Anzahl von Argumenten fÃŒr GTextTable::SetColor()',0), 432 27004 => array('GTextTable: Angegebener Zellenbereich, der verschmolzen werden soll, ist ungÃŒltig.',0), 433 27005 => array('GTextTable: Bereits verschmolzene Zellen im Bereich (%d,%d) bis (%d,%d) können nicht ein weiteres Mal verschmolzen werden.',4), 434 27006 => array('GTextTable: Spalten-Argument = %d liegt auÃerhalb der festgelegten TabellengröÃe.',1), 435 27007 => array('GTextTable: Zeilen-Argument = %d liegt auÃerhalb der festgelegten TabellengröÃe.',1), 436 27008 => array('GTextTable: Spalten- und ZeilengröÃe mÃŒssen zu den Dimensionen der Tabelle passen.',0), 421 437 27009 => array('GTextTable: Die Anzahl der Tabellenspalten oder -zeilen ist 0. Versichere Dich, dass die Methoden Init() oder Set() aufgerufen werden.',0), 422 438 27010 => array('GTextTable: Es wurde keine Ausrichtung beim Aufruf von SetAlign() angegeben.',0), 423 439 27011 => array('GTextTable: Es wurde eine unbekannte Ausrichtung beim Aufruf von SetAlign() abgegeben. Horizontal=%s, Vertikal=%s',2), 424 27012 => array('GTextTable: Interner Fehler. Es wurde ein ung ültiges Argument festgeleget %s',1),425 27013 => array('GTextTable: Das Argument f ür FormatNumber() muss ein String sein.',0),440 27012 => array('GTextTable: Interner Fehler. Es wurde ein ungÃŒltiges Argument festgeleget %s',1), 441 27013 => array('GTextTable: Das Argument fÃŒr FormatNumber() muss ein String sein.',0), 426 442 27014 => array('GTextTable: Die Tabelle wurde weder mit einem Aufruf von Set() noch von Init() initialisiert.',0), 427 443 27015 => array('GTextTable: Der Zellenbildbedingungstyp muss entweder TIMG_WIDTH oder TIMG_HEIGHT sein.',0), … … 431 447 */ 432 448 433 22001 => array('Die Gesamtsumme der prozentualen Anteile aller Windrosenarme darf 100%% nicht überschreiten!\n(Aktuell max: %d)',1),434 22002 => array('Das Bild ist zu klein f ür eine Skala. Bitte vergrößere das Bild.',0),435 22004 => array('Die Etikettendefinition f ür Windrosenrichtungen müssen 16 Werte haben (eine für jede Kompassrichtung).',0),436 22005 => array('Der Linientyp f ür radiale Linien muss einer von ("solid","dotted","dashed","longdashed") sein.',0),437 22006 => array('Es wurde ein ung ültiger Windrosentyp angegeben.',0),438 22007 => array('Es wurden zu wenig Werte f ür die Bereichslegende angegeben.',0),449 22001 => array('Die Gesamtsumme der prozentualen Anteile aller Windrosenarme darf 100%% nicht ÃŒberschreiten!\n(Aktuell max: %d)',1), 450 22002 => array('Das Bild ist zu klein fÃŒr eine Skala. Bitte vergröÃere das Bild.',0), 451 22004 => array('Die Etikettendefinition fÃŒr Windrosenrichtungen mÃŒssen 16 Werte haben (eine fÃŒr jede Kompassrichtung).',0), 452 22005 => array('Der Linientyp fÃŒr radiale Linien muss einer von ("solid","dotted","dashed","longdashed") sein.',0), 453 22006 => array('Es wurde ein ungÃŒltiger Windrosentyp angegeben.',0), 454 22007 => array('Es wurden zu wenig Werte fÃŒr die Bereichslegende angegeben.',0), 439 455 22008 => array('Interner Fehler: Versuch, eine freie Windrose zu plotten, obwohl der Typ keine freie Windrose ist.',0), 440 456 22009 => array('Du hast die gleiche Richtung zweimal angegeben, einmal mit einem Winkel und einmal mit einer Kompassrichtung (%f Grad).',0), 441 457 22010 => array('Die Richtung muss entweder ein numerischer Wert sein oder eine der 16 Kompassrichtungen',0), 442 458 22011 => array('Der Windrosenindex muss ein numerischer oder Richtungswert sein. Du hast angegeben Index=%d',1), 443 22012 => array('Die radiale Achsendefinition f ür die Windrose enthält eine nicht aktivierte Richtung.',0),444 22013 => array('Du hast dasselbe Look&Feel f ür die gleiche Kompassrichtung zweimal engegeben, einmal mit Text und einmal mit einem Index (Index=%d)',1),445 22014 => array('Der Index f ür eine Kompassrichtung muss zwischen 0 und 15 sein.',0),459 22012 => array('Die radiale Achsendefinition fÃŒr die Windrose enthÀlt eine nicht aktivierte Richtung.',0), 460 22013 => array('Du hast dasselbe Look&Feel fÃŒr die gleiche Kompassrichtung zweimal engegeben, einmal mit Text und einmal mit einem Index (Index=%d)',1), 461 22014 => array('Der Index fÃŒr eine Kompassrichtung muss zwischen 0 und 15 sein.',0), 446 462 22015 => array('Du hast einen unbekannten Windrosenplottyp angegeben.',0), 447 463 22016 => array('Der Windrosenarmindex muss ein numerischer oder ein Richtungswert sein.',0), 448 464 22017 => array('Die Windrosendaten enthalten eine Richtung, die nicht aktiviert ist. Bitte berichtige, welche Label angezeigt werden sollen.',0), 449 22018 => array('Du hast f ür dieselbe Kompassrichtung zweimal Daten angegeben, einmal mit Text und einmal mit einem Index (Index=%d)',1),450 22019 => array('Der Index f ür eine Richtung muss zwischen 0 und 15 sein. Winkel dürfen nicht für einen regelmäßigen Windplot angegeben werden, sondern entweder ein Index oder eine Kompassrichtung.',0),451 22020 => array('Der Windrosenplot ist zu gro ß für die angegebene Bildgröße. Benutze entweder WindrosePlot::SetSize(), um den Plot kleiner zu machen oder vergrößere das Bild im ursprünglichen Aufruf von WindroseGraph().',0),465 22018 => array('Du hast fÃŒr dieselbe Kompassrichtung zweimal Daten angegeben, einmal mit Text und einmal mit einem Index (Index=%d)',1), 466 22019 => array('Der Index fÃŒr eine Richtung muss zwischen 0 und 15 sein. Winkel dÃŒrfen nicht fÃŒr einen regelmÀÃigen Windplot angegeben werden, sondern entweder ein Index oder eine Kompassrichtung.',0), 467 22020 => array('Der Windrosenplot ist zu groà fÃŒr die angegebene BildgröÃe. Benutze entweder WindrosePlot::SetSize(), um den Plot kleiner zu machen oder vergröÃere das Bild im ursprÃŒnglichen Aufruf von WindroseGraph().',0), 452 468 22021 => array('It is only possible to add Text, IconPlot or WindrosePlot to a Windrose Graph',0), 453 469 … … 457 473 458 474 13001 => array('Unbekannter Nadeltypstil (%d).',1), 459 13002 => array('Ein Wert f ür das Odometer (%f) ist außerhalb des angegebenen Bereichs [%f,%f]',3),475 13002 => array('Ein Wert fÃŒr das Odometer (%f) ist auÃerhalb des angegebenen Bereichs [%f,%f]',3), 460 476 461 477 /* … … 465 481 1001 => array('Unbekannte Kodier-Specifikation: %s',1), 466 482 1002 => array('datenvalidierung schlug fehl. [%s] kann nicht mittels der Kodierung "%s" kodiert werden',2), 467 1003 => array('Interner Kodierfehler. Kodieren von %s ist nicht m öglich in Code 128',1),483 1003 => array('Interner Kodierfehler. Kodieren von %s ist nicht möglich in Code 128',1), 468 484 1004 => array('Interner barcode Fehler. Unbekannter UPC-E Kodiertyp: %s',1), 469 485 1005 => array('Interner Fehler. Das Textzeichen-Tupel (%s, %s) kann nicht im Code-128 Zeichensatz C kodiert werden.',2), 470 1006 => array('Interner Kodierfehler f ür CODE 128. Es wurde versucht, CTRL in CHARSET != A zu kodieren.',0),471 1007 => array('Interner Kodierfehler f ür CODE 128. Es wurde versucht, DEL in CHARSET != B zu kodieren.',0),472 1008 => array('Interner Kodierfehler f ür CODE 128. Es wurde versucht, kleine Buchstaben in CHARSET != B zu kodieren.',0),473 1009 => array('Kodieren mittels CODE 93 wird noch nicht unterst ützt.',0),474 1010 => array('Kodieren mittels POSTNET wird noch nicht unterst ützt.',0),475 1011 => array('Nicht untrst ütztes Barcode-Backend für den Typ %s',1),486 1006 => array('Interner Kodierfehler fÃŒr CODE 128. Es wurde versucht, CTRL in CHARSET != A zu kodieren.',0), 487 1007 => array('Interner Kodierfehler fÃŒr CODE 128. Es wurde versucht, DEL in CHARSET != B zu kodieren.',0), 488 1008 => array('Interner Kodierfehler fÃŒr CODE 128. Es wurde versucht, kleine Buchstaben in CHARSET != B zu kodieren.',0), 489 1009 => array('Kodieren mittels CODE 93 wird noch nicht unterstÃŒtzt.',0), 490 1010 => array('Kodieren mittels POSTNET wird noch nicht unterstÃŒtzt.',0), 491 1011 => array('Nicht untrstÃŒtztes Barcode-Backend fÃŒr den Typ %s',1), 476 492 477 493 /* … … 479 495 */ 480 496 497 26000 => array('PDF417: The PDF417 module requires that the PHP installation must support the function bcmod(). This is normally enabled at compile time. See documentation for more information.',0), 481 498 26001 => array('PDF417: Die Anzahl der Spalten muss zwischen 1 und 30 sein.',0), 482 499 26002 => array('PDF417: Der Fehler-Level muss zwischen 0 und 8 sein.',0), 483 26003 => array('PDF417: Ung ültiges Format für Eingabedaten, um sie mit PDF417 zu kodieren.',0),484 26004 => array('PDF417: die eigebenen Daten k önnen nicht mit Fehler-Level %d und %d spalten kodiert werden, weil daraus zu viele Symbole oder mehr als 90 Zeilen resultieren.',2),485 26005 => array('PDF417: Die Datei "%s" kann nicht zum Schreiben ge öffnet werden.',1),486 26006 => array('PDF417: Interner Fehler. Die Eingabedatendatei f ür PDF417-Cluster %d ist fehlerhaft.',1),487 26007 => array('PDF417: Interner Fehler. GetPattern: Ung ültiger Code-Wert %d (Zeile %d)',2),500 26003 => array('PDF417: UngÃŒltiges Format fÃŒr Eingabedaten, um sie mit PDF417 zu kodieren.',0), 501 26004 => array('PDF417: die eigebenen Daten können nicht mit Fehler-Level %d und %d spalten kodiert werden, weil daraus zu viele Symbole oder mehr als 90 Zeilen resultieren.',2), 502 26005 => array('PDF417: Die Datei "%s" kann nicht zum Schreiben geöffnet werden.',1), 503 26006 => array('PDF417: Interner Fehler. Die Eingabedatendatei fÃŒr PDF417-Cluster %d ist fehlerhaft.',1), 504 26007 => array('PDF417: Interner Fehler. GetPattern: UngÃŒltiger Code-Wert %d (Zeile %d)',2), 488 505 26008 => array('PDF417: Interner Fehler. Modus wurde nicht in der Modusliste!! Modus %d',1), 489 26009 => array('PDF417: Kodierfehler: Ung ültiges Zeichen. Zeichen kann nicht mit ASCII-Code %d kodiert werden.',1),506 26009 => array('PDF417: Kodierfehler: UngÃŒltiges Zeichen. Zeichen kann nicht mit ASCII-Code %d kodiert werden.',1), 490 507 26010 => array('PDF417: Interner Fehler: Keine Eingabedaten beim Dekodieren.',0), 491 26011 => array('PDF417: Kodierfehler. Numerisches Kodieren bei nicht-numerischen Daten nicht m öglich.',0),492 26012 => array('PDF417: Interner Fehler. Es wurden f ür den Binary-Kompressor keine Daten zum Dekodieren eingegeben.',0),508 26011 => array('PDF417: Kodierfehler. Numerisches Kodieren bei nicht-numerischen Daten nicht möglich.',0), 509 26012 => array('PDF417: Interner Fehler. Es wurden fÃŒr den Binary-Kompressor keine Daten zum Dekodieren eingegeben.',0), 493 510 26013 => array('PDF417: Interner Fehler. Checksum Fehler. Koeffiziententabellen sind fehlerhaft.',0), 494 26014 => array('PDF417: Interner Fehler. Es wurden keine Daten zum Berechnen von Kodewörtern eingegeben.',0), 495 26015 => array('PDF417: Interner Fehler. Ein Eintrag 0 in die Statusübertragungstabellen ist nicht NULL. Eintrag 1 = (%s)',1), 496 26016 => array('PDF417: Interner Fehler: Nichtregistrierter Statusübertragungsmodus beim Dekodieren.',0), 511 26014 => array('PDF417: Interner Fehler. Es wurden keine Daten zum Berechnen von Kodewörtern eingegeben.',0), 512 26015 => array('PDF417: Interner Fehler. Ein Eintrag 0 in die StatusÃŒbertragungstabellen ist nicht NULL. Eintrag 1 = (%s)',1), 513 26016 => array('PDF417: Interner Fehler: Nichtregistrierter StatusÃŒbertragungsmodus beim Dekodieren.',0), 514 515 516 /* 517 ** jpgraph_contour 518 */ 519 520 28001 => array('Dritten parameter fur Contour muss ein vector der fargen sind.',0), 521 28002 => array('Die anzahlen der farges jeder isobar linien muss gleich sein.',0), 522 28003 => array('ContourPlot Interner Fehler: isobarHCrossing: Spalten index ist zu hoch (%d)',1), 523 28004 => array('ContourPlot Interner Fehler: isobarHCrossing: Reihe index ist zu hoch (%d)',1), 524 28005 => array('ContourPlot Interner Fehler: isobarVCrossing: Reihe index ist zu hoch (%d)',1), 525 28006 => array('ContourPlot Interner Fehler: isobarVCrossing: Spalten index ist zu hoch (%d)',1), 526 28007 => array('ContourPlot. Interpolation faktor ist zu hoch (>5)',0), 527 528 529 /* 530 * jpgraph_matrix and colormap 531 */ 532 29201 => array('Min range value must be less or equal to max range value for colormaps',0), 533 29202 => array('The distance between min and max value is too small for numerical precision',0), 534 29203 => array('Number of color quantification level must be at least %d',1), 535 29204 => array('Number of colors (%d) is invalid for this colormap. It must be a number that can be written as: %d + k*%d',3), 536 29205 => array('Colormap specification out of range. Must be an integer in range [0,%d]',1), 537 29206 => array('Invalid object added to MatrixGraph',0), 538 29207 => array('Empty input data specified for MatrixPlot',0), 539 29208 => array('Unknown side specifiction for matrix labels "%s"',1), 540 29209 => array('CSIM Target matrix must be the same size as the data matrix (csim=%d x %d, data=%d x %d)',4), 541 29210 => array('CSIM Target for matrix labels does not match the number of labels (csim=%d, labels=%d)',2), 542 543 544 /* 545 * jpgraph_theme 546 */ 547 30001 => array("Theme::%s() is not defined. \nPlease make %s(\$graph) function in your theme classs.",2), 497 548 498 549 -
trunk/client/modules/Elezioni/grafici/lang/en.inc.php
r267 r284 1 1 <?php 2 2 /*======================================================================= 3 // File: 3 // File: EN.INC.PHP 4 4 // Description: English language file for error messages 5 // Created: 6 // Ver: $Id: en.inc.php 1017 2008-07-08 06:09:28Z ljp $5 // Created: 2006-01-25 6 // Ver: $Id: en.inc.php 1886 2009-10-01 23:30:16Z ljp $ 7 7 // 8 // Copyright (c) A ditus Consulting. All rights reserved.8 // Copyright (c) Asial Corporation. All rights reserved. 9 9 //======================================================================== 10 10 */ … … 16 16 ** Headers already sent error. This is formatted as HTML different since this will be sent back directly as text 17 17 */ 18 10 => array('<table border="1"><tr><td style="color:darkred; font-size:1.2em;"><b>JpGraph Error:</b> 18 10 => array('<table border="1"><tr><td style="color:darkred; font-size:1.2em;"><b>JpGraph Error:</b> 19 19 HTTP headers have already been sent.<br>Caused by output from file <b>%s</b> at line <b>%d</b>.</td></tr><tr><td><b>Explanation:</b><br>HTTP headers have already been sent back to the browser indicating the data as text before the library got a chance to send it\'s image HTTP header to this browser. This makes it impossible for the library to send back image data to the browser (since that would be interpretated as text by the browser and show up as junk text).<p>Most likely you have some text in your script before the call to <i>Graph::Stroke()</i>. If this texts gets sent back to the browser the browser will assume that all data is plain text. Look for any text, even spaces and newlines, that might have been sent back to the browser. <p>For example it is a common mistake to leave a blank line before the opening "<b><?php</b>".</td></tr></table>',2), 20 20 … … 76 76 6001 => array('Internal error. Height for ActivityTitles is < 0',0), 77 77 6002 => array('You can\'t specify negative sizes for Gantt graph dimensions. Use 0 to indicate that you want the library to automatically determine a dimension.',0), 78 6003 => array('Invalid format for Constrain parameter at index=%d in CreateSimple(). Parameter must start with index 0 and contain arrays of (Row,Constrain-To,Constrain-Type)',1), 79 6004 => array('Invalid format for Progress parameter at index=%d in CreateSimple(). Parameter must start with index 0 and contain arrays of (Row,Progress)',1), 78 6003 => array('Invalid format for Constrain parameter at index=%d in CreateSimple(). Parameter must start with index 0 and contain arrays of (Row,Constrain-To,Constrain-Type)',1), 79 6004 => array('Invalid format for Progress parameter at index=%d in CreateSimple(). Parameter must start with index 0 and contain arrays of (Row,Progress)',1), 80 80 6005 => array('SetScale() is not meaningful with Gantt charts.',0), 81 81 6006 => array('Cannot autoscale Gantt chart. No dated activities exist. [GetBarMinMax() start >= n]',0), … … 103 103 6031 => array('Unknown arrow type for link.',0), 104 104 6032 => array('Internal error: Unknown path type (=%d) specified for link.',1), 105 6033 => array('Array of fonts must contain arrays with 3 elements, i.e. (Family, Style, Size)',0), 105 106 106 107 /* … … 187 188 15010 => array('Sum of all data is 0 for Pie.',0), 188 189 15011 => array('In order to use image transformation you must include the file jpgraph_imgtrans.php in your script.',0), 190 15012 => array('PiePlot::SetTheme() is no longer supported. Use PieGraph::SetTheme()',0), 189 191 190 192 /* … … 257 259 24002 => array('FuncGenerator : Syntax error in function specification ',0), 258 260 24003 => array('DateScaleUtils: Unknown tick type specified in call to GetTicks()',0), 261 24004 => array('ReadCSV2: Column count mismatch in %s line %d',2), 259 262 /* 260 263 ** jpgraph … … 272 275 273 276 25010 => array('Graph::Add() You tried to add a null plot to the graph.',0), 274 25011 => array('Graph::AddY2() You tried to add a null plot to the graph.',0), 275 25012 => array('Graph::AddYN() You tried to add a null plot to the graph.',0), 277 25011 => array('Graph::AddY2() You tried to add a null plot to the graph.',0), 278 25012 => array('Graph::AddYN() You tried to add a null plot to the graph.',0), 276 279 25013 => array('You can only add standard plots to multiple Y-axis',0), 277 25014 => array('Graph::AddText() You tried to add a null text to the graph.',0), 278 25015 => array('Graph::AddLine() You tried to add a null line to the graph.',0), 280 25014 => array('Graph::AddText() You tried to add a null text to the graph.',0), 281 25015 => array('Graph::AddLine() You tried to add a null line to the graph.',0), 279 282 25016 => array('Graph::AddBand() You tried to add a null band to the graph.',0), 280 283 25017 => array('You are using GD 2.x and are trying to use a background images on a non truecolor image. To use background images with GD 2.x it is necessary to enable truecolor by setting the USE_TRUECOLOR constant to TRUE. Due to a bug in GD 2.0.1 using any truetype fonts with truecolor images will result in very poor quality fonts.',0), … … 302 305 25037 => array('The image format of your background image (%s) is not supported in your system configuration. ',1), 303 306 25038 => array('Background image seems to be of different type (has different file extension) than specified imagetype. Specified: %s File: %s',2), 304 25039 => array('Can\'t read background image: "%s"',1), 307 25039 => array('Can\'t read background image: "%s"',1), 305 308 306 309 25040 => array('It is not possible to specify both a background image and a background country flag.',0), … … 322 325 25055 => array('Axis::SetTickDirection() is deprecated. Use Axis::SetTickSide() instead',0), 323 326 25056 => array('SetTickLabelMargin() is deprecated. Use Axis::SetLabelMargin() instead.',0), 324 25057 => array('SetTextTicks() is deprecated. Use SetTextTickInterval() instead.',0), 327 25057 => array('SetTextTicks() is deprecated. Use SetTextTickInterval() instead.',0), 325 328 25058 => array('Text label interval must be specified >= 1.',0), 326 329 25059 => array('SetLabelPos() is deprecated. Use Axis::SetLabelSide() instead.',0), … … 366 369 25097 => array('Color specified as empty string in PushColor().',0), 367 370 25098 => array('Negative Color stack index. Unmatched call to PopColor()',0), 368 25099 => array('Parameters for brightness and Contrast out of range [-1,1]',0), 371 25099 => array('Parameters for brightness and Contrast out of range [-1,1]',0), 369 372 370 373 25100 => array('Problem with color palette and your GD setup. Please disable anti-aliasing or use GD2 with true-color. If you have GD2 library installed please make sure that you have set the USE_GD2 constant to true and truecolor is enabled.',0), … … 385 388 25114 => array('PHP has not enough permissions to write to the cache file "%s". Please make sure that the user running PHP has write permission for this file if you wan to use the cache system with JpGraph.',1), 386 389 25115 => array('Can\'t set permission for cached image "%s". Permission problem?',1), 387 25116 => array('Cant open file from cache "%s"',1), 390 25116 => array('Cant open file from cache "%s"',1), 388 391 25117 => array('Can\'t open cached image "%s" for reading.',1), 389 392 25118 => array('Can\'t create directory "%s". Make sure PHP has write permission to this directory.',1), … … 400 403 25128 => array('The function imageantialias() is not available in your PHP installation. Use the GD version that comes with PHP and not the standalone version.',0), 401 404 25129 => array('Anti-alias can not be used with dashed lines. Please disable anti-alias or use solid lines.',0), 402 405 25130 => array('Too small plot area. (%d x %d). With the given image size and margins there is to little space left for the plot. Increase the plot size or reduce the margins.',2), 406 407 25131 => array('StrokeBoxedText2() only supports TTF fonts and not built-in bitmap fonts.',0), 408 25132 => array('Undefined property %s.',1), 409 25133 => array('Use Graph::SetTheme() after Graph::SetScale().',0), 410 411 /* 412 ** jpgraph_led 413 */ 414 415 25500 => array('Multibyte strings must be enabled in the PHP installation in order to run the LED module so that the function mb_strlen() is available. See PHP documentation for more information.',0), 403 416 404 417 /* … … 409 422 410 423 /* 411 ** jpgraph_table 424 ** jpgraph_table 412 425 */ 413 426 … … 478 491 ** PDF417 479 492 */ 480 493 26000 => array('PDF417: The PDF417 module requires that the PHP installation must support the function bcmod(). This is normally enabled at compile time. See documentation for more information.',0), 481 494 26001 => array('PDF417: Number of Columns must be >= 1 and <= 30',0), 482 495 26002 => array('PDF417: Error level must be between 0 and 8',0), … … 496 509 26016 => array('PDF417: Internal error: Unrecognized state transition mode in decode.',0), 497 510 511 /* 512 ** jpgraph_contour 513 */ 514 515 28001 => array('Third argument to Contour must be an array of colors.',0), 516 28002 => array('Number of colors must equal the number of isobar lines specified',0), 517 28003 => array('ContourPlot Internal Error: isobarHCrossing: Coloumn index too large (%d)',1), 518 28004 => array('ContourPlot Internal Error: isobarHCrossing: Row index too large (%d)',1), 519 28005 => array('ContourPlot Internal Error: isobarVCrossing: Row index too large (%d)',1), 520 28006 => array('ContourPlot Internal Error: isobarVCrossing: Col index too large (%d)',1), 521 28007 => array('ContourPlot interpolation factor is too large (>5)',0), 522 523 /* 524 * jpgraph_matrix and colormap 525 */ 526 29201 => array('Min range value must be less or equal to max range value for colormaps',0), 527 29202 => array('The distance between min and max value is too small for numerical precision',0), 528 29203 => array('Number of color quantification level must be at least %d',1), 529 29204 => array('Number of colors (%d) is invalid for this colormap. It must be a number that can be written as: %d + k*%d',3), 530 29205 => array('Colormap specification out of range. Must be an integer in range [0,%d]',1), 531 29206 => array('Invalid object added to MatrixGraph',0), 532 29207 => array('Empty input data specified for MatrixPlot',0), 533 29208 => array('Unknown side specifiction for matrix labels "%s"',1), 534 29209 => array('CSIM Target matrix must be the same size as the data matrix (csim=%d x %d, data=%d x %d)',4), 535 29210 => array('CSIM Target for matrix labels does not match the number of labels (csim=%d, labels=%d)',2), 536 537 538 /* 539 * jpgraph_theme 540 */ 541 30001 => array("Theme::%s() is not defined. \nPlease make %s(\$graph) function in your theme classs.",2), 498 542 499 543 ); -
trunk/client/modules/Elezioni/grafici/lang/prod.inc.php
r267 r284 2 2 /*======================================================================= 3 3 // File: PROD.INC.PHP 4 // Description: Special localization file with the same error messages 4 // Description: Special localization file with the same error messages 5 5 // for all errors. 6 6 // Created: 2006-02-18 7 // Ver: $Id: prod.inc.php 993 2008-03-30 21:17:41Z ljp $7 // Ver: $Id: prod.inc.php 1886 2009-10-01 23:30:16Z ljp $ 8 8 // 9 // Copyright (c) A ditus Consulting. All rights reserved.9 // Copyright (c) Asial Corporation. All rights reserved. 10 10 //======================================================================== 11 11 */ … … 20 20 ** Headers already sent error. This is formatted as HTML different since this will be sent back directly as text 21 21 */ 22 10 => array('<table border=1><tr><td><font color=darkred size=4><b>JpGraph Error:</b> 22 10 => array('<table border=1><tr><td><font color=darkred size=4><b>JpGraph Error:</b> 23 23 HTTP headers have already been sent.<br>Caused by output from file <b>%s</b> at line <b>%d</b>.</font></td></tr><tr><td><b>Explanation:</b><br>HTTP headers have already been sent back to the browser indicating the data as text before the library got a chance to send it\'s image HTTP header to this browser. This makes it impossible for the library to send back image data to the browser (since that would be interpretated as text by the browser and show up as junk text).<p>Most likely you have some text in your script before the call to <i>Graph::Stroke()</i>. If this texts gets sent back to the browser the browser will assume that all data is plain text. Look for any text, even spaces and newlines, that might have been sent back to the browser. <p>For example it is a common mistake to leave a blank line before the opening "<b><?php</b>".</td></tr></table>',2), 24 24 … … 76 76 6031 => array(DEFAULT_ERROR_MESSAGE.'6031',0), 77 77 6032 => array(DEFAULT_ERROR_MESSAGE.'6032',0), 78 6033 => array(DEFAULT_ERROR_MESSAGE.'6033',0), 78 79 7001 => array(DEFAULT_ERROR_MESSAGE.'7001',0), 79 80 8001 => array(DEFAULT_ERROR_MESSAGE.'8001',0), … … 120 121 15010 => array(DEFAULT_ERROR_MESSAGE.'15010',0), 121 122 15011 => array(DEFAULT_ERROR_MESSAGE.'15011',0), 123 15012 => array(DEFAULT_ERROR_MESSAGE.'15012',0), 122 124 16001 => array(DEFAULT_ERROR_MESSAGE.'16001',0), 123 125 16002 => array(DEFAULT_ERROR_MESSAGE.'16002',0), … … 148 150 24002 => array(DEFAULT_ERROR_MESSAGE.'24002',0), 149 151 24003 => array(DEFAULT_ERROR_MESSAGE.'24003',0), 152 24004 => array(DEFAULT_ERROR_MESSAGE.'24004',0), 150 153 25001 => array(DEFAULT_ERROR_MESSAGE.'25001',0), 151 154 25002 => array(DEFAULT_ERROR_MESSAGE.'25002',0), … … 276 279 25128 => array(DEFAULT_ERROR_MESSAGE.'25128',0), 277 280 25129 => array(DEFAULT_ERROR_MESSAGE.'25129',0), 281 25130 => array(DEFAULT_ERROR_MESSAGE.'25130',0), 282 25131 => array(DEFAULT_ERROR_MESSAGE.'25131',0), 283 25132 => array(DEFAULT_ERROR_MESSAGE.'25132',0), 284 25133 => array(DEFAULT_ERROR_MESSAGE.'25133',0), 285 25500 => array(DEFAULT_ERROR_MESSAGE.'25500',0), 278 286 24003 => array(DEFAULT_ERROR_MESSAGE.'24003',0), 279 287 24004 => array(DEFAULT_ERROR_MESSAGE.'24004',0), … … 321 329 1010 => array(DEFAULT_ERROR_MESSAGE.'1010',0), 322 330 1011 => array(DEFAULT_ERROR_MESSAGE.'1011',0), 331 26000 => array(DEFAULT_ERROR_MESSAGE.'26000',0), 323 332 26001 => array(DEFAULT_ERROR_MESSAGE.'26001',0), 324 333 26002 => array(DEFAULT_ERROR_MESSAGE.'26002',0), … … 353 362 27014 => array(DEFAULT_ERROR_MESSAGE.'27014',0), 354 363 27015 => array(DEFAULT_ERROR_MESSAGE.'27015',0), 364 365 28001 => array(DEFAULT_ERROR_MESSAGE.'28001',0), 366 28002 => array(DEFAULT_ERROR_MESSAGE.'28002',0), 367 28003 => array(DEFAULT_ERROR_MESSAGE.'28003',0), 368 28004 => array(DEFAULT_ERROR_MESSAGE.'28004',0), 369 28005 => array(DEFAULT_ERROR_MESSAGE.'28005',0), 370 28006 => array(DEFAULT_ERROR_MESSAGE.'28006',0), 371 28007 => array(DEFAULT_ERROR_MESSAGE.'28007',0), 372 373 29201 => array(DEFAULT_ERROR_MESSAGE.'28001',0), 374 29202 => array(DEFAULT_ERROR_MESSAGE.'28002',0), 375 29203 => array(DEFAULT_ERROR_MESSAGE.'28003',0), 376 29204 => array(DEFAULT_ERROR_MESSAGE.'28004',0), 377 29205 => array(DEFAULT_ERROR_MESSAGE.'28005',0), 378 29206 => array(DEFAULT_ERROR_MESSAGE.'28006',0), 379 29207 => array(DEFAULT_ERROR_MESSAGE.'28007',0), 380 29208 => array(DEFAULT_ERROR_MESSAGE.'28008',0), 381 29209 => array(DEFAULT_ERROR_MESSAGE.'28009',0), 382 29210 => array(DEFAULT_ERROR_MESSAGE.'28010',0), 383 355 384 ); 356 385 -
trunk/client/temi/spectral/index.php
r282 r284 156 156 if($resblk->rowCount()){ 157 157 158 while ($row = mysql_fetch_array($resblk)) {158 while ($row = $resblk->fetch(PDO::FETCH_BOTH)) { 159 159 $id_w=$row['id']; 160 160 $nome=$row['nome_file'];
Note:
See TracChangeset
for help on using the changeset viewer.