- Timestamp:
- Apr 14, 2019, 2:31:40 PM (6 years ago)
- Location:
- trunk/client
- Files:
-
- 65 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/client/class/charts.php
r265 r267 1 1 <?php 2 // charts.php v4. 72 // charts.php v4.5 3 3 // ------------------------------------------------------------------------ 4 // Copyright (c) 2003-200 7, maani.us4 // Copyright (c) 2003-2006, maani.us 5 5 // ------------------------------------------------------------------------ 6 6 // This file is part of "PHP/SWF Charts" … … 11 11 12 12 //==================================== 13 function InsertChart( $flash_file, $library_path, $php_source, $width=4 00, $height=250, $bg_color="666666", $transparent=false, $license=null){14 13 function InsertChart( $flash_file, $library_path, $php_source, $width=470, $height=350, $bg_color="ffffff", $transparent=false, $license=null ){ 14 15 15 $php_source=urlencode($php_source); 16 16 $library_path=urlencode($library_path); 17 $protocol = (strtolower($_SERVER['HTTPS']) != 'on')? 'http': 'https'; 17 $x=$_SESSION['max']; 18 $u=(strpos ($flash_file,"?")==false)? "?" : ((substr($flash_file, -1)=="&")? "":"&"); 18 19 19 $html="<OBJECT classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' codebase='".$protocol."://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0' "; 20 $html.="width='".$width."' height='".$height."' id='charts' />"; 21 $u=(strpos ($flash_file,"?")===false)? "?" : ((substr($flash_file, -1)==="&")? "":"&"); 22 $html.="<PARAM NAME='movie' VALUE='".$flash_file.$u."library_path=".$library_path."&stage_width=".$width."&stage_height=".$height."&php_source=".$php_source; 23 if($license!=null){$html.="&license=".$license;} 24 $html.="' /> <PARAM NAME='quality' VALUE='high' /><param name='allowScriptAccess' value='sameDomain' /><PARAM NAME='bgcolor' VALUE='#".$bg_color."' /> "; 25 if($transparent){$html.="<PARAM NAME='wmode' VALUE='transparent' /> ";} 26 $html.="<EMBED src='".$flash_file.$u."library_path=".$library_path."&stage_width=".$width."&stage_height=".$height."&php_source=".$php_source; 27 if($license!=null){$html.="&license=".$license;} 28 $html.="' quality='high' bgcolor='#".$bg_color."' width='".$width."' height='".$height."' NAME='charts' allowScriptAccess='sameDomain' swLiveConnect='true' "; 29 if($transparent){$html.="wmode=transparent ";} //use wmode=opaque to prevent printing on black 30 $html.="TYPE='application/x-shockwave-flash' PLUGINSPAGE='".$protocol."://www.macromedia.com/go/getflashplayer'></EMBED></OBJECT>"; 20 21 $html="<div style=\"text-align: right;\">"; 22 if (strstr($_SERVER['HTTP_USER_AGENT'],"MSIE")){ 23 $html.="<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0' "; 24 $html.="width='".$width."' height='".$height."' id='charts$x'>"; 25 $u=(strpos ($flash_file,"?")==false)? "?" : ((substr($flash_file, -1)=="&")? "":"&"); 26 $html.="<param name='movie' value='".$flash_file.$u."library_path=".$library_path."&php_source=".$php_source; 27 if($license!=null){$html.="&license=".$license;} 28 $html.="'/> <param name='quality' value='high'/> <param name='bgcolor' value='#".$bg_color."'/> "; 29 if($transparent){$html.="<param name='wmode' value='transparent'/> ";} 30 $html.="</object>"; 31 }else{ 32 $html.="<embed src=\"".$flash_file.$u."library_path=".$library_path."&php_source=".$php_source; 33 if($license!=null){$html.="&license=".$license;} 34 $html.="\" quality=high bgcolor=#".$bg_color." width=".$width." height=".$height." name='charts' align='right' swLiveConnect='true' "; 35 if($transparent){$html.="wmode=transparent ";} 36 $html.="type='application/x-shockwave-flash' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed>"; 37 } 38 $html.="</div>"; 39 31 40 return $html; 41 32 42 33 43 } … … 35 45 //==================================== 36 46 function SendChartData( $chart=array() ){ 37 38 //header("Content-Type: text/xml"); 39 //header("Cache-Control: cache, must-revalidate"); 40 //header("Pragma: public"); 47 41 48 42 49 $xml="<chart>\r\n"; … … 54 61 for($i3=0;$i3<count($Keys3);$i3++){ 55 62 switch(true){ 56 case ($chart[$Keys1[$i1]][$Keys2[$i2]][$Keys3[$i3]]== =null):63 case ($chart[$Keys1[$i1]][$Keys2[$i2]][$Keys3[$i3]]==null): 57 64 $xml.="\t\t\t<null/>\r\n"; 58 65 break; … … 74 81 $count=0; 75 82 for($i3=0;$i3<count($Keys3);$i3++){ 76 if($chart[$Keys1[$i1]][$Keys2[$i2]][$Keys3[$i3]]== =null){$xml.="\t\t\t<null/>\r\n";}83 if($chart[$Keys1[$i1]][$Keys2[$i2]][$Keys3[$i3]]==null){$xml.="\t\t\t<null/>\r\n";} 77 84 else{$xml.="\t\t\t<string>".$chart[$Keys1[$i1]][$Keys2[$i2]][$Keys3[$i3]]."</string>\r\n";} 78 85 } … … 84 91 $count=0; 85 92 for($i3=0;$i3<count($Keys3);$i3++){ 86 if($chart[$Keys1[$i1]][$Keys2[$i2]][$Keys3[$i3]]== =null){$xml.="\t\t\t<null/>\r\n";}93 if($chart[$Keys1[$i1]][$Keys2[$i2]][$Keys3[$i3]]==null){$xml.="\t\t\t<null/>\r\n";} 87 94 else{$xml.="\t\t\t<string>".$chart[$Keys1[$i1]][$Keys2[$i2]][$Keys3[$i3]]."</string>\r\n";} 88 95 } … … 118 125 $xml.="\t<".$Keys1[$i1].">\r\n"; 119 126 for($i2=0;$i2<count($Keys2);$i2++){ 120 if($chart[$Keys1[$i1]][$Keys2[$i2]]== =null){$xml.="\t\t<null/>\r\n";}127 if($chart[$Keys1[$i1]][$Keys2[$i2]]==null){$xml.="\t\t<null/>\r\n";} 121 128 else{$xml.="\t\t<value>".$chart[$Keys1[$i1]][$Keys2[$i2]]."</value>\r\n";} 122 129 } … … 135 142 } 136 143 $xml.="</chart>\r\n"; 137 echo $xml; 144 /* // stampa su file by Linuxap 145 mt_srand ((double)microtime()*1000000); 146 $maxran = 1000000; 147 $random_num = mt_rand(0, $maxran); 148 $fileout="./temp/$random_num"; 149 $fp = fopen($fileout,"w"); 150 fwrite($fp,$xml); 151 fclose($fp); 152 */ 153 //echo $xml; 154 //MODIFICHE PER TOGLIERE FILETEMP 155 return $xml; //return $fileout; 138 156 } 139 157 //==================================== -
trunk/client/modules/Elezioni/grafici.php
r265 r267 7 7 /* info@eleonline.it luciano@aniene.net rgigli@libero.it */ 8 8 /************************************************************************/ 9 define('MODULE_FILE'); 9 10 10 if (!defined('MODULE_FILE')) { 11 #die ("You can't access this file directly...");11 die ("You can't access this file directly..."); 12 12 } 13 13 … … 164 164 $_GET : $_POST; 165 165 if (isset($param['anim'])) $anim=intval($param['anim']); else $anim=''; 166 #$anim=1; 166 167 if ($siteistat==$id_comune) $logo="$siteistat"; else $logo=''; // logo per il comune 167 168 $logo=verificasimbolo(); // carica_logo da funzioni.php … … 604 605 echo "</td></tr></table><table><tr><td>"; 605 606 # grafico flash 606 if($flash=='1') flash_torta($gruppos,$pre,40,145); 607 # if($flash=='1') flash_torta($gruppos,$pre,40,145); 608 $uno=''; 609 foreach($gruppos as $k=>$v) $uno.="- $v"; 610 $due='due:'; 611 foreach($pre as $k=>$v) $due.="- $v"; 612 include("flash_torta($uno,$due,20,70)"); 607 613 echo "</td></tr></table>"; 608 614 … … 674 680 675 681 if($flash=='1')flash_torta($gruppos,$pre,20,70); 676 682 677 683 678 684 … … 796 802 797 803 $chart[ 'chart_data' ] = array ($gruppos, $pre); 798 //$chart[ 'chart_data' ] = array ( array ("","Ciao", "Bella"), array ( "",40, 60));804 $chart[ 'chart_data' ] = array ( array ("","Ciao", "Bella"), array ( "",40, 60)); 799 805 $chart[ 'chart_grid_h' ] = array ( 'thickness'=>0 ); 800 806 $chart[ 'chart_pref' ] = array ( 'rotation_x'=>60 ); -
trunk/client/modules/Elezioni/grafici/gd_image.inc.php
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: gd_image.inc.php 1922 2010-01-11 11:42:50Z ljp$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$ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. All rights reserved. 9 9 //======================================================================== 10 10 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 //======================================================================== 11 12 //=================================================== 30 13 // CLASS Image 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 //========================================================================= 14 // Description: Wrapper class with some goodies to form the 15 // Interface to low level image drawing routines. 16 //=================================================== 37 17 class Image { 18 public $left_margin=30,$right_margin=30,$top_margin=20,$bottom_margin=30; 38 19 public $img=null; 20 public $plotwidth=0,$plotheight=0; 21 public $width=0, $height=0; 39 22 public $rgb=null; 23 public $current_color,$current_color_name; 24 public $line_weight=1, $line_style=LINESTYLE_SOLID; 40 25 public $img_format; 41 26 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, __set48 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 53 27 protected $expired=true; 54 28 protected $lastx=0, $lasty=0; 55 29 protected $obs_list=array(); 56 protected $font_size=12,$font_family=FF_ DEFAULT, $font_style=FS_NORMAL;30 protected $font_size=12,$font_family=FF_FONT1, $font_style=FS_NORMAL; 57 31 protected $font_file=''; 58 32 protected $text_halign="left",$text_valign="bottom"; … … 63 37 protected $langconv = null ; 64 38 protected $iInterlace=false; 65 protected $bbox_cache = array(); // STore the last found tetx bounding box66 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 74 39 //--------------- 75 40 // CONSTRUCTOR 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"); 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(); 97 51 } 98 52 99 53 // Enable interlacing in images 100 54 function SetInterlace($aFlg=true) { 101 55 $this->iInterlace=$aFlg; 102 56 } 103 57 104 58 // Should we use anti-aliasing. Note: This really slows down graphics! 105 59 function SetAntiAliasing($aFlg=true) { 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 ; 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 } 117 67 } 118 68 119 69 function CreateRawCanvas($aWidth=0,$aHeight=0) { 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 } 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); 144 96 } 145 97 146 98 function CloneCanvasH() { 147 148 149 150 151 } 152 99 $oldimage = $this->img; 100 $this->CreateRawCanvas($this->width,$this->height); 101 imagecopy($this->img,$oldimage,0,0,0,0,$this->width,$this->height); 102 return $oldimage; 103 } 104 153 105 function CreateImgCanvas($aWidth=0,$aHeight=0) { 154 106 155 156 157 158 159 160 161 $this->height=$aHeight; 162 163 164 165 // We will set the final size later. 166 167 168 169 170 171 172 173 174 // Set canvas color (will also be the background color for a 175 176 $this->SetColor($this->canvascolor); 177 $this->FilledRectangle(0,0,$this->width-1,$this->height-1);178 179 107 $old = array($this->img,$this->width,$this->height); 108 109 $aWidth = round($aWidth); 110 $aHeight = round($aHeight); 111 112 $this->width=$aWidth; 113 $this->height=$aHeight; 114 115 116 if( $aWidth==0 || $aHeight==0 ) { 117 // We will set the final size later. 118 // Note: The size must be specified before any other 119 // img routines that stroke anything are called. 120 $this->img = null; 121 $this->rgb = null; 122 return $old; 123 } 124 125 $this->CreateRawCanvas($aWidth,$aHeight); 126 // Set canvas color (will also be the background color for a 127 // a pallett image 128 $this->SetColor($this->canvascolor); 129 $this->FilledRectangle(0,0,$aWidth,$aHeight); 130 131 return $old ; 180 132 } 181 133 182 134 function CopyCanvasH($aToHdl,$aFromHdl,$aToX,$aToY,$aFromX,$aFromY,$aWidth,$aHeight,$aw=-1,$ah=-1) { 183 184 185 186 187 188 189 190 191 135 if( $aw === -1 ) { 136 $aw = $aWidth; 137 $ah = $aHeight; 138 $f = 'imagecopyresized'; 139 } 140 else { 141 $f = 'imagecopyresampled'; 142 } 143 $f($aToHdl,$aFromHdl,$aToX,$aToY,$aFromX,$aFromY, $aWidth,$aHeight,$aw,$ah); 192 144 } 193 145 194 146 function Copy($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth=-1,$fromHeight=-1) { 195 $this->CopyCanvasH($this->img,$fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth,$fromHeight); 147 $this->CopyCanvasH($this->img,$fromImg,$toX,$toY,$fromX,$fromY, 148 $toWidth,$toHeight,$fromWidth,$fromHeight); 196 149 } 197 150 198 151 function CopyMerge($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth=-1,$fromHeight=-1,$aMix=100) { 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 } 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 } 221 177 } 222 178 223 179 static function GetWidth($aImg=null) { 224 if( $aImg === null ) { 225 $aImg = $this->img; 226 } 227 return imagesx($aImg); 180 if( $aImg === null ) 181 $aImg = $this->img; 182 return imagesx($aImg); 228 183 } 229 184 230 185 static function GetHeight($aImg=null) { 231 if( $aImg === null ) { 232 $aImg = $this->img; 233 } 234 return imagesy($aImg); 235 } 236 186 if( $aImg === null ) 187 $aImg = $this->img; 188 return imagesy($aImg); 189 } 190 237 191 static function CreateFromString($aStr) { 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; 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; 244 197 } 245 198 246 199 function SetCanvasH($aHdl) { 247 248 200 $this->img = $aHdl; 201 $this->rgb->img = $aHdl; 249 202 } 250 203 251 204 function SetCanvasColor($aColor) { 252 205 $this->canvascolor = $aColor ; 253 206 } 254 207 255 208 function SetAlphaBlending($aFlg=true) { 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 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 268 228 //--------------- 269 // PUBLIC METHODS 270 229 // PUBLIC METHODS 230 271 231 function SetFont($family,$style=FS_NORMAL,$size=10) { 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 } 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 } 290 247 } 291 248 292 249 // Get the specific height for a text string 293 250 function GetTextHeight($txt="",$angle=0) { 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 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 325 281 // Estimate font height 326 282 function GetFontHeight($angle=0) { 327 328 329 } 330 283 $txt = "XOMg"; 284 return $this->GetTextHeight($txt,$angle); 285 } 286 331 287 // Approximate font width with width of letter "O" 332 288 function GetFontWidth($angle=0) { 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. 289 $txt = 'O'; 290 return $this->GetTextWidth($txt,$angle); 291 } 292 293 // Get actual width of text in absolute pixels 340 294 function GetTextWidth($txt,$angle=0) { 341 295 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 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 386 339 // Draw text with a box around it 387 340 function StrokeBoxedText($x,$y,$txt,$dir=0,$fcolor="white",$bcolor="black", 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; 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 414 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)); 444 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 } 473 if( $aDebug ) { 474 // Draw the bounding rectangle and the bounding box 475 $p1 = array(round($x),round($y),round($x),round($y-$h),round($x+$w),round($y-$h),round($x+$w),round($y)); 476 477 // Draw bounding box 478 $this->PushColor('green'); 479 $this->Polygon($p1,true); 480 $this->PopColor(); 481 442 482 } 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; 483 $aBoundingBox=array(round($x),round($y),round($x),round($y-$h),round($x+$w),round($y-$h),round($x+$w),round($y)); 484 } 485 } 486 487 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 500 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; 507 } 508 509 function GetBBoxTTF($aTxt,$aAngle=0) { 510 // Normalize the bounding box to become a minimum 511 // enscribing rectangle 512 513 $aTxt = $this->AddTxtCR($aTxt); 514 515 if( !is_readable($this->font_file) ) { 516 JpGraphError::RaiseL(25093,$this->font_file); 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 if( $aAngle >= 0 ) { 524 if( $aAngle <= 90 ) { //<=0 525 $bbox = array($bbox[6],$bbox[1],$bbox[2],$bbox[1], 526 $bbox[2],$bbox[5],$bbox[6],$bbox[5]); 527 } 528 elseif( $aAngle <= 180 ) { //<= 2 529 $bbox = array($bbox[4],$bbox[7],$bbox[0],$bbox[7], 530 $bbox[0],$bbox[3],$bbox[4],$bbox[3]); 531 } 532 elseif( $aAngle <= 270 ) { //<= 3 533 $bbox = array($bbox[2],$bbox[5],$bbox[6],$bbox[5], 534 $bbox[6],$bbox[1],$bbox[2],$bbox[1]); 535 } 536 else { 537 $bbox = array($bbox[0],$bbox[3],$bbox[4],$bbox[3], 538 $bbox[4],$bbox[7],$bbox[0],$bbox[7]); 539 } 540 } 541 elseif( $aAngle < 0 ) { 542 if( $aAngle <= -270 ) { // <= -3 543 $bbox = array($bbox[6],$bbox[1],$bbox[2],$bbox[1], 544 $bbox[2],$bbox[5],$bbox[6],$bbox[5]); 545 } 546 elseif( $aAngle <= -180 ) { // <= -2 547 $bbox = array($bbox[0],$bbox[3],$bbox[4],$bbox[3], 548 $bbox[4],$bbox[7],$bbox[0],$bbox[7]); 549 } 550 elseif( $aAngle <= -90 ) { // <= -1 551 $bbox = array($bbox[2],$bbox[5],$bbox[6],$bbox[5], 552 $bbox[6],$bbox[1],$bbox[2],$bbox[1]); 553 } 554 else { 555 $bbox = array($bbox[0],$bbox[3],$bbox[4],$bbox[3], 556 $bbox[4],$bbox[7],$bbox[0],$bbox[7]); 557 } 558 } 559 return $bbox; 560 } 561 562 function GetBBoxHeight($aTxt,$aAngle=0) { 563 $box = $this->GetBBoxTTF($aTxt,$aAngle); 564 return $box[1]-$box[7]+1; 565 } 566 567 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 621 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(); 448 648 } 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 625 function SetTextAlign($halign,$valign="bottom") { 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)); 659 if( $aDebug ) { 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 } 686 if( $aDebug ) { 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 } 698 } 699 700 function AddTxtCR($aTxt) { 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 816 function GetTTFBBox($aTxt,$aAngle=0) { 817 $bbox = $this->imagettfbbox_fixed($this->font_size,$aAngle,$this->font_file,$aTxt); 818 return $bbox; 819 } 820 821 function GetBBoxTTF($aTxt,$aAngle=0) { 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; 872 } 873 874 function GetBBoxHeight($aTxt,$aAngle=0) { 875 $box = $this->GetBBoxTTF($aTxt,$aAngle); 876 return abs($box[7]-$box[1]); 877 } 878 879 function GetBBoxWidth($aTxt,$aAngle=0) { 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 956 if( $debug ) { 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 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 1086 744 function StrokeText($x,$y,$txt,$dir=0,$paragraph_align="left",$debug=false) { 1087 745 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 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 1110 766 function SetMargin($lm,$rm,$tm,$bm) { 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 } 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 } 1126 777 } 1127 778 1128 779 function SetTransparent($color) { 1129 1130 } 1131 780 imagecolortransparent ($this->img,$this->rgb->allocate($color)); 781 } 782 1132 783 function SetColor($color,$aAlpha=0) { 1133 1134 1135 1136 1137 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 1141 } 1142 784 $this->current_color_name = $color; 785 $this->current_color=$this->rgb->allocate($color,$aAlpha); 786 if( $this->current_color == -1 ) { 787 $tc=imagecolorstotal($this->img); 788 JpGraphError::RaiseL(25096); 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 return $this->current_color; 792 } 793 1143 794 function PushColor($color) { 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 } 1154 795 if( $color != "" ) { 796 $this->colorstack[$this->colorstackidx]=$this->current_color_name; 797 $this->colorstack[$this->colorstackidx+1]=$this->current_color; 798 $this->colorstackidx+=2; 799 $this->SetColor($color); 800 } 801 else { 802 JpGraphError::RaiseL(25097);//("Color specified as empty string in PushColor()."); 803 } 804 } 805 1155 806 function PopColor() { 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 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 1164 814 function SetLineWeight($weight) { 1165 $old = $this->line_weight; 1166 imagesetthickness($this->img,$weight); 1167 $this->line_weight = $weight; 1168 return $old; 1169 } 1170 815 imagesetthickness($this->img,$weight); 816 $this->line_weight = $weight; 817 } 818 1171 819 function SetStartPoint($x,$y) { 1172 1173 1174 } 1175 820 $this->lastx=round($x); 821 $this->lasty=round($y); 822 } 823 1176 824 function Arc($cx,$cy,$w,$h,$s,$e) { 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 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 1183 833 function FilledArc($xc,$yc,$w,$h,$s,$e,$style='') { 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 } 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 } 1194 842 } 1195 843 1196 844 function FilledCakeSlice($cx,$cy,$w,$h,$s,$e) { 1197 845 $this->CakeSlice($cx,$cy,$w,$h,$s,$e,$this->current_color_name); 1198 846 } 1199 847 1200 848 function CakeSlice($xc,$yc,$w,$h,$s,$e,$fillcolor="",$arccolor="") { 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 } 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 } 1232 874 } 1233 875 1234 876 function Ellipse($xc,$yc,$w,$h) { 1235 1236 } 1237 877 $this->Arc($xc,$yc,$w,$h,0,360); 878 } 879 1238 880 function Circle($xc,$yc,$r) { 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 881 imageellipse($this->img,round($xc),round($yc),$r*2,$r*2,$this->current_color); 882 } 883 1244 884 function FilledCircle($xc,$yc,$r) { 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 885 imagefilledellipse($this->img,round($xc),round($yc),2*$r,2*$r,$this->current_color); 886 } 887 1249 888 // Linear Color InterPolation 1250 889 function lip($f,$t,$p) { 1251 1252 1253 1254 1255 890 $p = round($p,1); 891 $r = $f[0] + ($t[0]-$f[0])*$p; 892 $g = $f[1] + ($t[1]-$f[1])*$p; 893 $b = $f[2] + ($t[2]-$f[2])*$p; 894 return array($r,$g,$b); 1256 895 } 1257 896 1258 897 // Set line style dashed, dotted etc 1259 898 function SetLineStyle($s) { 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 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 1282 918 // Same as Line but take the line_style into account 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 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 1331 949 function DashedLine($x1,$y1,$x2,$y2,$dash_length=1,$dash_space=4) { 1332 950 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 } 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 } 1391 973 1392 974 function Line($x1,$y1,$x2,$y2) { 1393 975 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; 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; 1405 986 } 1406 987 1407 988 function Polygon($p,$closed=FALSE,$fast=FALSE) { 1408 989 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 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 1436 1017 function FilledPolygon($pts) { 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 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 1451 1027 function Rectangle($xl,$yu,$xr,$yl) { 1452 1453 } 1454 1028 $this->Polygon(array($xl,$yu,$xr,$yu,$xr,$yl,$xl,$yl,$xl,$yu)); 1029 } 1030 1455 1031 function FilledRectangle($xl,$yu,$xr,$yl) { 1456 1032 $this->FilledPolygon(array($xl,$yu,$xr,$yu,$xr,$yl,$xl,$yl)); 1457 1033 } 1458 1034 1459 1035 function FilledRectangle2($xl,$yu,$xr,$yl,$color1,$color2,$style=1) { 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 } 1487 1488 function ShadowRectangle($xl,$yu,$xr,$yl,$fcolor=false,$shadow_width= 4,$shadow_color='darkgray',$useAlpha=true) {1489 1036 // Fill a rectangle with lines of two colors 1037 if( $style===1 ) { 1038 // Horizontal stripe 1039 if( $yl < $yu ) { 1040 $t = $yl; $yl=$yu; $yu=$t; 1041 } 1042 for( $y=$yu; $y <= $yl; ++$y) { 1043 $this->SetColor($color1); 1044 $this->Line($xl,$y,$xr,$y); 1045 ++$y; 1046 $this->SetColor($color2); 1047 $this->Line($xl,$y,$xr,$y); 1048 } 1049 } 1050 else { 1051 if( $xl < $xl ) { 1052 $t = $xl; $xl=$xr; $xr=$t; 1053 } 1054 for( $x=$xl; $x <= $xr; ++$x) { 1055 $this->SetColor($color1); 1056 $this->Line($x,$yu,$x,$yl); 1057 ++$x; 1058 $this->SetColor($color2); 1059 $this->Line($x,$yu,$x,$yl); 1060 } 1061 } 1062 } 1063 1064 function ShadowRectangle($xl,$yu,$xr,$yl,$fcolor=false,$shadow_width=3,$shadow_color=array(102,102,102)) { 1065 // This is complicated by the fact that we must also handle the case where 1490 1066 // the reactangle has no fill color 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 } 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 } 1520 1080 } 1521 1081 1522 1082 function FilledRoundedRectangle($xt,$yt,$xr,$yl,$r=5) { 1523 1524 1525 1526 1527 1528 1529 // when alphablending is enabled) we have no choice but 1530 1531 1532 1533 1534 1535 $this->FilledRectangle($xt+$r,$yt,$xr-$r,$yt+$r);1536 1537 $this->FilledRectangle($xt+$r,$yl-$r,$xr-$r,$yl);1538 1539 $this->FilledRectangle($xt,$yt+$r,$xt+$r,$yl-$r);1540 1541 $this->FilledRectangle($xr-$r,$yt+$r,$xr,$yl-$r);1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 } 1552 1553 function RoundedRectangle($xt,$yt,$xr,$yl,$r=5) { 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1083 if( $r==0 ) { 1084 $this->FilledRectangle($xt,$yt,$xr,$yl); 1085 return; 1086 } 1087 1088 // To avoid overlapping fillings (which will look strange 1089 // when alphablending is enabled) we have no choice but 1090 // to fill the five distinct areas one by one. 1091 1092 // Center square 1093 $this->FilledRectangle($xt+$r,$yt+$r,$xr-$r,$yl-$r); 1094 // Top band 1095 $this->FilledRectangle($xt+$r,$yt,$xr-$r,$yt+$r-1); 1096 // Bottom band 1097 $this->FilledRectangle($xt+$r,$yl-$r+1,$xr-$r,$yl); 1098 // Left band 1099 $this->FilledRectangle($xt,$yt+$r+1,$xt+$r-1,$yl-$r); 1100 // Right band 1101 $this->FilledRectangle($xr-$r+1,$yt+$r,$xr,$yl-$r); 1102 1103 // Topleft & Topright arc 1104 $this->FilledArc($xt+$r,$yt+$r,$r*2,$r*2,180,270); 1105 $this->FilledArc($xr-$r,$yt+$r,$r*2,$r*2,270,360); 1106 1107 // Bottomleft & Bottom right arc 1108 $this->FilledArc($xt+$r,$yl-$r,$r*2,$r*2,90,180); 1109 $this->FilledArc($xr-$r,$yl-$r,$r*2,$r*2,0,90); 1110 1111 } 1112 1113 function RoundedRectangle($xt,$yt,$xr,$yl,$r=5) { 1114 1115 if( $r==0 ) { 1116 $this->Rectangle($xt,$yt,$xr,$yl); 1117 return; 1118 } 1119 1120 // Top & Bottom line 1121 $this->Line($xt+$r,$yt,$xr-$r,$yt); 1122 $this->Line($xt+$r,$yl,$xr-$r,$yl); 1123 1124 // Left & Right line 1125 $this->Line($xt,$yt+$r,$xt,$yl-$r); 1126 $this->Line($xr,$yt+$r,$xr,$yl-$r); 1127 1128 // Topleft & Topright arc 1129 $this->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270); 1130 $this->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360); 1131 1132 // Bottomleft & Bottomright arc 1133 $this->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180); 1134 $this->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90); 1575 1135 } 1576 1136 1577 1137 function FilledBevel($x1,$y1,$x2,$y2,$depth=2,$color1='white@0.4',$color2='darkgray@0.4') { 1578 1579 1138 $this->FilledRectangle($x1,$y1,$x2,$y2); 1139 $this->Bevel($x1,$y1,$x2,$y2,$depth,$color1,$color2); 1580 1140 } 1581 1141 1582 1142 function Bevel($x1,$y1,$x2,$y2,$depth=2,$color1='white@0.4',$color2='black@0.5') { 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1143 $this->PushColor($color1); 1144 for( $i=0; $i < $depth; ++$i ) { 1145 $this->Line($x1+$i,$y1+$i,$x1+$i,$y2-$i); 1146 $this->Line($x1+$i,$y1+$i,$x2-$i,$y1+$i); 1147 } 1148 $this->PopColor(); 1149 1150 $this->PushColor($color2); 1151 for( $i=0; $i < $depth; ++$i ) { 1152 $this->Line($x1+$i,$y2-$i,$x2-$i,$y2-$i); 1153 $this->Line($x2-$i,$y1+$i,$x2-$i,$y2-$i-1); 1154 } 1155 $this->PopColor(); 1596 1156 } 1597 1157 1598 1158 function StyleLineTo($x,$y) { 1599 1600 1601 1602 } 1603 1159 $this->StyleLine($this->lastx,$this->lasty,$x,$y); 1160 $this->lastx=$x; 1161 $this->lasty=$y; 1162 } 1163 1604 1164 function LineTo($x,$y) { 1605 1606 1607 1608 } 1609 1165 $this->Line($this->lastx,$this->lasty,$x,$y); 1166 $this->lastx=$x; 1167 $this->lasty=$y; 1168 } 1169 1610 1170 function Point($x,$y) { 1611 1612 } 1613 1171 imagesetpixel($this->img,round($x),round($y),$this->current_color); 1172 } 1173 1614 1174 function Fill($x,$y) { 1615 1175 imagefill($this->img,round($x),round($y),$this->current_color); 1616 1176 } 1617 1177 1618 1178 function FillToBorder($x,$y,$aBordColor) { 1619 1620 1621 1622 1623 1179 $bc = $this->rgb->allocate($aBordColor); 1180 if( $bc == -1 ) { 1181 JpGraphError::RaiseL(25106);//('Image::FillToBorder : Can not allocate more colors'); 1182 } 1183 imagefilltoborder($this->img,round($x),round($y),$bc,$this->current_color); 1624 1184 } 1625 1185 1626 1186 function SetExpired($aFlg=true) { 1627 1628 } 1629 1187 $this->expired = $aFlg; 1188 } 1189 1630 1190 // Generate image header 1631 1191 function Headers() { 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"); 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"); 1656 1217 } 1657 1218 1658 1219 // Adjust image quality for formats that allow this 1659 1220 function SetQuality($q) { 1660 1661 } 1662 1221 $this->quality = $q; 1222 } 1223 1663 1224 // Stream image to browser or to file 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 } 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."); 1677 1240 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 1241 } 1242 } 1243 } 1244 1245 // Clear resource tide up by image 1711 1246 function Destroy() { 1712 1713 } 1714 1247 imagedestroy($this->img); 1248 } 1249 1715 1250 // Specify image format. Note depending on your installation 1716 1251 // of PHP not all formats may be supported. 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 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 } 1941 1296 } // CLASS 1942 1297 … … 1948 1303 class RotImage extends Image { 1949 1304 public $a=0; 1950 public $dx=0,$dy=0,$transx=0,$transy=0; 1305 public $dx=0,$dy=0,$transx=0,$transy=0; 1951 1306 private $m=array(); 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 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 1960 1315 function SetCenter($dx,$dy) { 1961 1962 1963 1964 1965 1966 1967 } 1968 1316 $old_dx = $this->dx; 1317 $old_dy = $this->dy; 1318 $this->dx=$dx; 1319 $this->dy=$dy; 1320 $this->SetAngle($this->a); 1321 return array($old_dx,$old_dy); 1322 } 1323 1969 1324 function SetTranslation($dx,$dy) { 1970 1971 1972 1973 1325 $old = array($this->transx,$this->transy); 1326 $this->transx = $dx; 1327 $this->transy = $dy; 1328 return $old; 1974 1329 } 1975 1330 1976 1331 function UpdateRotMatrice() { 1977 1978 1979 $sa=sin($a); $ca=cos($a); 1980 1981 1982 1983 1984 1985 1986 1332 $a = $this->a; 1333 $a *= M_PI/180; 1334 $sa=sin($a); $ca=cos($a); 1335 // Create the rotation matrix 1336 $this->m[0][0] = $ca; 1337 $this->m[0][1] = -$sa; 1338 $this->m[0][2] = $this->dx*(1-$ca) + $sa*$this->dy ; 1339 $this->m[1][0] = $sa; 1340 $this->m[1][1] = $ca; 1341 $this->m[1][2] = $this->dy*(1-$ca) - $sa*$this->dx ; 1987 1342 } 1988 1343 1989 1344 function SetAngle($a) { 1990 1991 1992 1993 1345 $tmp = $this->a; 1346 $this->a = $a; 1347 $this->UpdateRotMatrice(); 1348 return $tmp; 1994 1349 } 1995 1350 1996 1351 function Circle($xc,$yc,$r) { 1997 1998 1352 list($xc,$yc) = $this->Rotate($xc,$yc); 1353 parent::Circle($xc,$yc,$r); 1999 1354 } 2000 1355 2001 1356 function FilledCircle($xc,$yc,$r) { 2002 2003 2004 } 2005 2006 1357 list($xc,$yc) = $this->Rotate($xc,$yc); 1358 parent::FilledCircle($xc,$yc,$r); 1359 } 1360 1361 2007 1362 function Arc($xc,$yc,$w,$h,$s,$e) { 2008 2009 2010 2011 1363 list($xc,$yc) = $this->Rotate($xc,$yc); 1364 $s += $this->a; 1365 $e += $this->a; 1366 parent::Arc($xc,$yc,$w,$h,$s,$e); 2012 1367 } 2013 1368 2014 1369 function FilledArc($xc,$yc,$w,$h,$s,$e,$style='') { 2015 2016 2017 2018 1370 list($xc,$yc) = $this->Rotate($xc,$yc); 1371 $s += $this->a; 1372 $e += $this->a; 1373 parent::FilledArc($xc,$yc,$w,$h,$s,$e); 2019 1374 } 2020 1375 2021 1376 function SetMargin($lm,$rm,$tm,$bm) { 2022 parent::SetMargin($lm,$rm,$tm,$bm); 2023 $this->UpdateRotMatrice(); 2024 } 2025 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 2026 1383 function Rotate($x,$y) { 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 } 2037 1384 // Optimization. Ignore rotation if Angle==0 || Angle==360 1385 if( $this->a == 0 || $this->a == 360 ) { 1386 return array($x + $this->transx, $y + $this->transy ); 1387 } 1388 else { 1389 $x1=round($this->m[0][0]*$x + $this->m[0][1]*$y,1) + $this->m[0][2] + $this->transx; 1390 $y1=round($this->m[1][0]*$x + $this->m[1][1]*$y,1) + $this->m[1][2] + $this->transy; 1391 return array($x1,$y1); 1392 } 1393 } 1394 2038 1395 function CopyMerge($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth=-1,$fromHeight=-1,$aMix=100) { 2039 2040 1396 list($toX,$toY) = $this->Rotate($toX,$toY); 1397 parent::CopyMerge($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth,$fromHeight,$aMix); 2041 1398 2042 1399 } 2043 1400 2044 1401 function ArrRotate($pnts) { 2045 2046 2047 2048 2049 2050 1402 $n = count($pnts)-1; 1403 for($i=0; $i < $n; $i+=2) { 1404 list ($x,$y) = $this->Rotate($pnts[$i],$pnts[$i+1]); 1405 $pnts[$i] = $x; $pnts[$i+1] = $y; 1406 } 1407 return $pnts; 2051 1408 } 2052 1409 2053 1410 function DashedLine($x1,$y1,$x2,$y2,$dash_length=1,$dash_space=4) { 2054 2055 2056 2057 } 2058 1411 list($x1,$y1) = $this->Rotate($x1,$y1); 1412 list($x2,$y2) = $this->Rotate($x2,$y2); 1413 parent::DashedLine($x1,$y1,$x2,$y2,$dash_length,$dash_space); 1414 } 1415 2059 1416 function Line($x1,$y1,$x2,$y2) { 2060 2061 2062 1417 list($x1,$y1) = $this->Rotate($x1,$y1); 1418 list($x2,$y2) = $this->Rotate($x2,$y2); 1419 parent::Line($x1,$y1,$x2,$y2); 2063 1420 } 2064 1421 2065 1422 function Rectangle($x1,$y1,$x2,$y2) { 2066 2067 2068 } 2069 1423 // Rectangle uses Line() so it will be rotated through that call 1424 parent::Rectangle($x1,$y1,$x2,$y2); 1425 } 1426 2070 1427 function FilledRectangle($x1,$y1,$x2,$y2) { 2071 2072 2073 else 2074 2075 } 2076 1428 if( $y1==$y2 || $x1==$x2 ) 1429 $this->Line($x1,$y1,$x2,$y2); 1430 else 1431 $this->FilledPolygon(array($x1,$y1,$x2,$y1,$x2,$y2,$x1,$y2)); 1432 } 1433 2077 1434 function Polygon($pnts,$closed=FALSE,$fast=FALSE) { 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 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 2088 1444 function FilledPolygon($pnts) { 2089 2090 } 2091 1445 parent::FilledPolygon($this->ArrRotate($pnts)); 1446 } 1447 2092 1448 function Point($x,$y) { 2093 2094 2095 } 2096 1449 list($xp,$yp) = $this->Rotate($x,$y); 1450 parent::Point($xp,$yp); 1451 } 1452 2097 1453 function StrokeText($x,$y,$txt,$dir=0,$paragraph_align="left",$debug=false) { 2098 2099 1454 list($xp,$yp) = $this->Rotate($x,$y); 1455 return parent::StrokeText($xp,$yp,$txt,$dir,$paragraph_align,$debug); 2100 1456 } 2101 1457 } 2102 1458 2103 //=================================================== ====================1459 //=================================================== 2104 1460 // CLASS ImgStreamCache 2105 // Description: Handle caching of graphs to files. All image output goes 2106 // through this class 2107 //======================================================================= 1461 // Description: Handle caching of graphs to files 1462 //=================================================== 2108 1463 class ImgStreamCache { 2109 private $cache_dir, $ timeout=0;// Infinite timeout1464 private $cache_dir, $img=null, $timeout=0; // Infinite timeout 2110 1465 //--------------- 2111 1466 // CONSTRUCTOR 2112 function __construct($aCacheDir=CACHE_DIR) { 2113 $this->cache_dir = $aCacheDir; 2114 } 2115 2116 //--------------- 2117 // PUBLIC METHODS 1467 function ImgStreamCache($aImg, $aCacheDir=CACHE_DIR) { 1468 $this->img = $aImg; 1469 $this->cache_dir = $aCacheDir; 1470 } 1471 1472 //--------------- 1473 // PUBLIC METHODS 2118 1474 2119 1475 // Specify a timeout (in minutes) for the file. If the file is older then the … … 2122 1478 // timeout is set to -1 this is the same as infinite small timeout 2123 1479 function SetTimeout($aTimeout) { 2124 $this->timeout=$aTimeout; 2125 } 2126 1480 $this->timeout=$aTimeout; 1481 } 1482 2127 1483 // Output image to browser and also write it to the cache 2128 1484 function PutAndStream($aImage,$aCacheFileName,$aInline,$aStrokeFileName) { 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 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 2268 1567 // Check if a given image is in cache and in that case 2269 1568 // pass it directly on to web browser. Return false if the 2270 1569 // image file doesn't exist or exists but is to old 2271 function GetAndStream($aImage,$aCacheFileName) { 2272 if( $this->Isvalid($aCacheFileName) ) { 2273 $this->StreamImgFile($aImage,$aCacheFileName); 2274 } 2275 else { 2276 return false; 2277 } 2278 } 2279 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 2280 1590 //--------------- 2281 // PRIVATE METHODS 1591 // PRIVATE METHODS 2282 1592 // Create all necessary directories in a path 2283 1593 function MakeDirs($aFile) { 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 } 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 } 2310 1616 } // CLASS Cache 2311 1617 1618 2312 1619 ?> -
trunk/client/modules/Elezioni/grafici/imgdata_balls.inc.php
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: imgdata_balls.inc.php 1106 2009-02-22 20:16:35Z 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 860 2007-03-23 19:16:19Z ljp $ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. All rights reserved. 9 9 //======================================================================== 10 10 … … 12 12 protected $name = 'Round Balls'; 13 13 protected $an = array(MARK_IMG_LBALL => 'imgdata_large', 14 MARK_IMG_MBALL => 'imgdata_small',15 MARK_IMG_SBALL => 'imgdata_xsmall',16 MARK_IMG_BALL => 'imgdata_xsmall');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 __construct() {74 75 76 77 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 112 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 155 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 191 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 237 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 274 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 305 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 340 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 376 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 422 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 460 461 462 $this->imgdata_small[0][1]= 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 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 503 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 524 525 526 $this->imgdata_small[3][1]= 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 $this->imgdata_small[4][1]= 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 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 588 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 612 613 614 $this->imgdata_small[7][1]= 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 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 656 657 658 $this->imgdata_small[9][1]= 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 $this->imgdata_small[10][1]= 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 $this->imgdata_small[11][1]= 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 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 737 738 739 $this->imgdata_small[13][1]= 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 $this->imgdata_xsmall[0][1]= 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 $this->imgdata_xsmall[1][1]= 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 $this->imgdata_xsmall[2][1]= 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 $this->imgdata_xsmall[3][1]= 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 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 870 871 872 $this->imgdata_xsmall[5][1]= 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 $this->imgdata_xsmall[6][1]= 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 $this->imgdata_xsmall[7][1]= 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 $this->imgdata_xsmall[8][1]= 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 $this->imgdata_xsmall[9][1]= 940 941 942 943 944 945 946 947 948 949 950 951 952 953 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 975 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 996 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 1018 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 1039 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 ImgData_Balls() { 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
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: imgdata_bevels.inc.php 1106 2009-02-22 20:16:35Z 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 860 2007-03-23 19:16:19Z ljp $ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. 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 __construct() {22 23 24 25 26 $this->imgdata[0][1]= 27 28 29 30 31 32 33 34 35 36 21 function ImgData_Bevels() { 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 40 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 56 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 72 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 87 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
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: imgdata_diamonds.inc.php 1106 2009-02-22 20:16:35Z 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 860 2007-03-23 19:16:19Z ljp $ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. 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 __construct() {23 24 25 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 ImgData_Diamonds() { 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 49 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 63 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 87 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 101 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 125 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 149 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 163 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
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: imgdata_pushpins.inc.php 1106 2009-02-22 20:16:35Z 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 860 2007-03-23 19:16:19Z ljp $ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. All rights reserved. 9 9 //======================================================================== 10 10 … … 12 12 protected $name = 'Push pins'; 13 13 protected $an = array(MARK_IMG_PUSHPIN => 'imgdata_small', 14 MARK_IMG_SPUSHPIN => 'imgdata_small',15 MARK_IMG_LPUSHPIN => 'imgdata_large');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 __construct() {23 24 25 26 27 28 29 30 31 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 104 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 184 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 265 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 332 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 416 417 418 $this->imgdata_small[0][1]= 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 $this->imgdata_small[1][1]= 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 $this->imgdata_small[2][1]= 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 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 499 500 501 $this->imgdata_small[4][1]= 502 503 504 505 506 507 508 509 510 511 512 513 22 function ImgData_PushPins() { 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
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: imgdata_squares.inc.php 1106 2009-02-22 20:16:35Z 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 860 2007-03-23 19:16:19Z ljp $ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. 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 25 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 41 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 57 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 73 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 88 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 106 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 120 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 135 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
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: imgdata_stars.inc.php 1106 2009-02-22 20:16:35Z 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 860 2007-03-23 19:16:19Z ljp $ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. 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 __construct() {23 24 25 26 27 $this->imgdata[0][1]= 28 29 30 31 32 33 34 35 36 37 38 39 40 41 $this->imgdata[1][1]= 42 43 44 45 46 47 48 49 50 22 function ImgData_Stars() { 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 54 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 69 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 84 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 99 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 114 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 129 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
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpg-config.inc.php 1871 2009-09-29 05:56:39Z ljp $7 // 8 // Copyright (c) A sial Corporation. All rights reserved.3 // File: JPG-CONFIG.INC 4 // Description: Configuration file for JpGraph library 5 // Created: 2004-03-27 6 // Ver: $Id: jpg-config.inc.php 1091 2009-01-18 22:57:40Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. All rights reserved. 9 9 //======================================================================== 10 10 11 11 12 //------------------------------------------------------------------------ 13 // Directories for cache and font directory. 12 13 //------------------------------------------------------------------------ 14 // Directories for cache and font directory. 14 15 // 15 16 // CACHE_DIR: … … 28 29 // CACHE_DIR /tmp/jpgraph_cache/ 29 30 // TTF_DIR /usr/share/fonts/truetype/ 30 // MBTTF_DIR /usr/share/fonts/truetype/ 31 // 31 // MBTTF_DIR /usr/share/fonts/ja/TrueType/ 32 // 33 define("TTF_DIR","/usr/share/fonts/truetype/ttf-dejavu/"); 32 34 // WINDOWS: 33 35 // CACHE_DIR $SERVER_TEMP/jpgraph_cache/ … … 36 38 // 37 39 //------------------------------------------------------------------------ 38 // define( 'CACHE_DIR','/tmp/jpgraph_cache/');39 // define( 'TTF_DIR','/usr/share/fonts/TrueType/');40 // define( 'MBTTF_DIR','/usr/share/fonts/TrueType/');40 // define("CACHE_DIR","/tmp/jpgraph_cache/"); 41 // define("TTF_DIR","/usr/share/fonts/truetype/"); 42 // define("MBTTF_DIR","/usr/share/fonts/ja/TrueType/"); 41 43 42 44 //------------------------------------------------------------------------- … … 44 46 // using the cache. 45 47 // The directory must be the filesysystem name as seen by PHP 46 // and the 'http' version must be the same directory but as 47 // seen by the HTTP server relative to the 'htdocs' ddirectory. 48 // and the 'http' version must be the same directory but as 49 // seen by the HTTP server relative to the 'htdocs' ddirectory. 48 50 // If a relative path is specified it is taken to be relative from where 49 51 // the image script is executed. 50 // Note: The default setting is to create a subdirectory in the 52 // Note: The default setting is to create a subdirectory in the 51 53 // directory from where the image script is executed and store all files 52 54 // there. As ususal this directory must be writeable by the PHP process. 53 define('CSIMCACHE_DIR','csimcache/'); 54 define('CSIMCACHE_HTTP_DIR','csimcache/'); 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); 55 119 56 120 //------------------------------------------------------------------------ … … 64 128 define('DEFAULT_ERR_LOCALE','en'); 65 129 66 // Deafult graphic format set to 'auto'which will automatically130 // Deafult graphic format set to "auto" which will automatically 67 131 // choose the best available format in the order png,gif,jpeg 68 132 // (The supported format depends on what your PHP installation supports) 69 define( 'DEFAULT_GFORMAT','auto');133 define("DEFAULT_GFORMAT","auto"); 70 134 71 135 // Should the cache be used at all? By setting this to false no 72 // files will be generated in the cache directory. 136 // files will be generated in the cache directory. 73 137 // The difference from READ_CACHE being that setting READ_CACHE to 74 138 // false will still create the image in the cache directory 75 139 // just not use it. By setting USE_CACHE=false no files will even 76 140 // be generated in the cache directory. 77 define( 'USE_CACHE',false);78 79 // Should we try to find an image in the cache before generating it? 141 define("USE_CACHE",false); 142 143 // Should we try to find an image in the cache before generating it? 80 144 // Set this define to false to bypass the reading of the cache and always 81 // regenerate the image. Note that even if reading the cache is 145 // regenerate the image. Note that even if reading the cache is 82 146 // disabled the cached will still be updated with the newly generated 83 // image. Set also 'USE_CACHE'below.84 define( 'READ_CACHE',true);147 // image. Set also "USE_CACHE" below. 148 define("READ_CACHE",true); 85 149 86 150 // Determine if the error handler should be image based or purely 87 151 // text based. Image based makes it easier since the script will 88 152 // always return an image even in case of errors. 89 define( 'USE_IMAGE_ERROR_HANDLER',true);90 91 // Should the library examin ethe global php_errmsg string and convert153 define("USE_IMAGE_ERROR_HANDLER",true); 154 155 // Should the library examin the global php_errmsg string and convert 92 156 // any error in it to a graphical representation. This is handy for the 93 157 // occasions when, for example, header files cannot be found and this results 94 // in the graph not being created and just a 'red-cross'image would be seen.158 // in the graph not being created and just a "red-cross" image would be seen. 95 159 // This should be turned off for a production site. 96 define( 'CATCH_PHPERRMSG',true);160 define("CATCH_PHPERRMSG",true); 97 161 98 162 // Determine if the library should also setup the default PHP 99 163 // error handler to generate a graphic error mesage. This is useful 100 164 // during development to be able to see the error message as an image 101 // instead as a 'red-cross' in a page where an image is expected. 102 define('INSTALL_PHP_ERR_HANDLER',false); 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); 103 178 104 179 // Should usage of deprecated functions and parameters give a fatal error? 105 180 // (Useful to check if code is future proof.) 106 define('ERR_DEPRECATED',true); 107 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); 181 define("ERR_DEPRECATED",true); 182 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)"); 116 190 117 191 //------------------------------------------------------------------------ … … 120 194 121 195 // What group should the cached file belong to 122 // (Set to '' will give the default group for the 'PHP-user')196 // (Set to "" will give the default group for the "PHP-user") 123 197 // Please note that the Apache user must be a member of the 124 198 // specified group since otherwise it is impossible for Apache 125 199 // to set the specified group. 126 define( 'CACHE_FILE_GROUP','www');200 define("CACHE_FILE_GROUP","wwwadmin"); 127 201 128 202 // What permissions should the cached file have 129 // (Set to '' will give the default persmissions for the 'PHP-user') 130 define('CACHE_FILE_MOD',0664); 131 132 // Default theme class name 133 define('DEFAULT_THEME_CLASS', 'UniversalTheme'); 134 135 define('SUPERSAMPLING', true); 136 define('SUPERSAMPLING_SCALE', 1); 203 // (Set to "" will give the default persmissions for the "PHP-user") 204 define("CACHE_FILE_MOD",0664); 205 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); 211 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 137 227 138 228 ?> -
trunk/client/modules/Elezioni/grafici/jpgraph.php
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph.php 1924 2010-01-11 14:03:26Z ljp $3 // File: JPGRAPH.PHP 4 // Description: PHP Graph Plotting library. Base module. 5 // Created: 2001-01-08 6 // Ver: $Id: jpgraph.php 1091 2009-01-18 22:57:40Z ljp $ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. 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');20 18 21 19 // Version info 22 define('JPG_VERSION',' 4.2.6');20 define('JPG_VERSION','2.3.5-dev'); 23 21 24 22 // Minimum required PHP version 25 23 define('MIN_PHPVERSION','5.1.0'); 26 24 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'); 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 45 88 46 89 // Tick density … … 50 93 define("TICKD_VERYSPARSE",4); 51 94 52 // Side for ticks and labels. 95 // Side for ticks and labels. 53 96 define("SIDE_LEFT",-1); 54 97 define("SIDE_RIGHT",1); … … 113 156 define("HORIZONTAL",0); 114 157 158 115 159 // Axis styles for scientific style axis 116 160 define('AXSTYLE_SIMPLE',1); … … 132 176 define('TITLEBKG_FILLSTYLE_SOLID',3); 133 177 134 // Styles for axis labels background135 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 144 178 // Style for background gradient fills 145 179 define('BGRAD_FRAME',1); … … 157 191 define('SKEW3D_RIGHT',3); 158 192 193 // Line styles 194 define('LINESTYLE_SOLID',1); 195 define('LINESTYLE_DOTTED',2); 196 define('LINESTYLE_DASHED',3); 197 define('LINESTYLE_LONGDASH',4); 198 159 199 // For internal use only 160 200 define("_JPG_DEBUG",false); … … 162 202 define("_FORCE_IMGDIR",'/tmp/jpgimg/'); 163 203 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 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; 234 212 if ($majorC < $majorR) return false; 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 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; 244 218 return true; 245 219 } … … 253 227 } 254 228 229 255 230 // 256 231 // Make GD sanity check … … 258 233 if( !function_exists("imagetypes") || !function_exists('imagecreatefromstring') ) { 259 234 JpGraphError::RaiseL(25001); 260 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)"); 261 236 } 262 237 … … 267 242 // Respect current error level 268 243 if( $errno & error_reporting() ) { 269 JpGraphError::RaiseL(25003,basename($filename),$linenum,$errmsg); 244 JpGraphError::RaiseL(25003,basename($filename),$linenum,$errmsg); 270 245 } 271 246 } … … 276 251 277 252 // 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 253 //Check if there were any warnings, perhaps some wrong includes by the 254 //user 281 255 // 282 if( isset($GLOBALS['php_errormsg']) && CATCH_PHPERRMSG && !preg_match('/|Deprecated|/i', $GLOBALS['php_errormsg']) ) { 256 if( isset($GLOBALS['php_errormsg']) && CATCH_PHPERRMSG && 257 !preg_match('/|Deprecated|/i', $GLOBALS['php_errormsg']) ) { 283 258 JpGraphError::RaiseL(25004,$GLOBALS['php_errormsg']); 284 259 } 285 260 261 286 262 // Useful mathematical function 287 263 function sign($a) {return $a >= 0 ? 1 : -1;} 288 264 289 //290 265 // Utility function to generate an image name based on the filename we 291 266 // are running from and assuming we use auto detection of graphic format 292 267 // (top level), i.e it is safe to call this function 293 268 // from a script that uses JpGraph 294 //295 269 function GenImgName() { 296 270 // Determine what format we should use when we save the images 297 271 $supported = imagetypes(); 298 if( $supported & IMG_PNG ) 272 if( $supported & IMG_PNG ) $img_format="png"; 299 273 elseif( $supported & IMG_GIF ) $img_format="gif"; 300 274 elseif( $supported & IMG_JPG ) $img_format="jpeg"; … … 303 277 304 278 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 } 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."); 309 282 $fname = basename($_SERVER['PHP_SELF']); 310 283 if( !empty($_SERVER['QUERY_STRING']) ) { 311 312 284 $q = @$_SERVER['QUERY_STRING']; 285 $fname .= '_'.preg_replace("/\W/", "_", $q).'.'.$img_format; 313 286 } 314 287 else { 315 288 $fname = substr($fname,0,strlen($fname)-4).'.'.$img_format; 316 289 } 317 290 return $fname; 318 291 } 292 319 293 320 294 //=================================================== … … 325 299 //=================================================== 326 300 class JpgTimer { 327 private $start, $idx; 328 329 function __construct() { 330 $this->idx=0; 331 } 301 private $start, $idx; 302 //--------------- 303 // CONSTRUCTOR 304 function JpgTimer() { 305 $this->idx=0; 306 } 307 308 //--------------- 309 // PUBLIC METHODS 332 310 333 311 // Push a new timer start on stack 334 312 function Push() { 335 list($ms,$s)=explode(" ",microtime()); 336 $this->start[$this->idx++]=floor($ms*1000) + 1000*$s; 313 list($ms,$s)=explode(" ",microtime()); 314 $this->start[$this->idx++]=floor($ms*1000) + 1000*$s; 337 315 } 338 316 … … 340 318 // current time 341 319 function Pop() { 342 343 list($ms,$s)=explode(" ",microtime()); 344 345 346 320 assert($this->idx>0); 321 list($ms,$s)=explode(" ",microtime()); 322 $etime=floor($ms*1000) + (1000*$s); 323 $this->idx--; 324 return $etime-$this->start[$this->idx]; 347 325 } 348 326 } // Class 349 327 328 $gJpgBrandTiming = BRAND_TIMING; 350 329 //=================================================== 351 330 // CLASS DateLocale … … 353 332 //=================================================== 354 333 class DateLocale { 355 334 356 335 public $iLocale = 'C'; // environmental locale be used by default 357 336 private $iDayAbb = null, $iShortDay = null, $iShortMonth = null, $iMonthName = null; 358 337 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 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 367 352 function Set($aLocale) { 368 if ( in_array($aLocale, array_keys($this->iDayAbb)) ){ 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 if ( ! $res ){389 390 391 392 393 394 395 for( $i = 0, $ofs = 0 - strftime('%w'); $i < 7; $i++, $ofs++ ){396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 353 if ( in_array($aLocale, array_keys($this->iDayAbb)) ){ 354 $this->iLocale = $aLocale; 355 return TRUE; // already cached nothing else to do! 356 } 357 358 $pLocale = setlocale(LC_TIME, 0); // get current locale for LC_TIME 359 360 if (is_array($aLocale)) { 361 foreach ($aLocale as $loc) { 362 $res = @setlocale(LC_TIME, $loc); 363 if ( $res ) { 364 $aLocale = $loc; 365 break; 366 } 367 } 368 } 369 else { 370 $res = @setlocale(LC_TIME, $aLocale); 371 } 372 373 if ( ! $res ){ 374 JpGraphError::RaiseL(25007,$aLocale); 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 return FALSE; 377 } 378 379 $this->iLocale = $aLocale; 380 for ( $i = 0, $ofs = 0 - strftime('%w'); $i < 7; $i++, $ofs++ ){ 381 $day = strftime('%a', strtotime("$ofs day")); 382 $day[0] = strtoupper($day[0]); 383 $this->iDayAbb[$aLocale][]= $day[0]; 384 $this->iShortDay[$aLocale][]= $day; 385 } 386 387 for($i=1; $i<=12; ++$i) { 388 list($short ,$full) = explode('|', strftime("%b|%B",strtotime("2001-$i-01"))); 389 $this->iShortMonth[$aLocale][] = ucfirst($short); 390 $this->iMonthName [$aLocale][] = ucfirst($full); 391 } 392 393 setlocale(LC_TIME, $pLocale); 394 395 return TRUE; 411 396 } 412 397 413 398 414 399 function GetDayAbb() { 415 416 } 417 400 return $this->iDayAbb[$this->iLocale]; 401 } 402 418 403 function GetShortDay() { 419 404 return $this->iShortDay[$this->iLocale]; 420 405 } 421 406 422 407 function GetShortMonth() { 423 424 } 425 408 return $this->iShortMonth[$this->iLocale]; 409 } 410 426 411 function GetShortMonthName($aNbr) { 427 412 return $this->iShortMonth[$this->iLocale][$aNbr]; 428 413 } 429 414 430 415 function GetLongMonthName($aNbr) { 431 416 return $this->iMonthName[$this->iLocale][$aNbr]; 432 417 } 433 418 434 419 function GetMonth() { 435 420 return $this->iMonthName[$this->iLocale]; 436 421 } 437 422 } 438 423 439 // Global object handlers440 424 $gDateLocale = new DateLocale(); 441 425 $gJpgDateLocale = new DateLocale(); … … 448 432 public $iLeftMargin = 3, $iRightMargin = 3, $iBottomMargin = 3 ; 449 433 public $left,$center,$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; 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'); 464 442 } 465 443 466 444 function SetMargin($aLeft=3,$aRight=3,$aBottom=3) { 467 468 469 445 $this->iLeftMargin = $aLeft; 446 $this->iRightMargin = $aRight; 447 $this->iBottomMargin = $aBottom; 470 448 } 471 449 472 450 function Stroke($aImg) { 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); 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); 488 463 } 489 464 } … … 495 470 //=================================================== 496 471 class Graph { 497 public $cache=null; 498 public $img=null; 499 public $plots=array(); 500 public $y2plots=array(); 472 public $cache=null; // Cache object (singleton) 473 public $img=null; // Img object (singleton) 474 public $plots=array(); // Array of all plot object in the graph (for Y 1 axis) 475 public $y2plots=array(); // Array of all plot object in the graph (for Y 2 axis) 501 476 public $ynplots=array(); 502 public $xscale=null; 477 public $xscale=null; // X Scale object (could be instance of LinearScale or LogScale 503 478 public $yscale=null,$y2scale=null, $ynscale=array(); 504 public $iIcons = array(); // Array of Icons to add to505 public $cache_name; 506 public $xgrid=null; 507 public $ygrid=null,$y2grid=null; 508 public $doframe ,$frame_color, $frame_weight;// Frame around graph509 public $boxed=false, $box_color= 'black', $box_weight=1;// Box around plot area510 public $doshadow=false,$shadow_width=4,$shadow_color= 'gray@0.5';// Shadow for graph511 public $xaxis=null; 512 public $yaxis=null, $y2axis=null, $ynaxis=array(); 513 public $margin_color ;// Margin color of graph514 public $plotarea_color=array(255,255,255); 515 public $title,$subtitle,$subsubtitle; 516 public $axtype="linlin"; 517 public $xtick_factor,$ytick_factor; 518 public $texts=null, $y2texts=null; 479 public $iIcons = array(); // Array of Icons to add to 480 public $cache_name; // File name to be used for the current graph in the cache directory 481 public $xgrid=null; // X Grid object (linear or logarithmic) 482 public $ygrid=null,$y2grid=null; //dito for Y 483 public $doframe=true,$frame_color=array(0,0,0), $frame_weight=1; // Frame around graph 484 public $boxed=false, $box_color=array(0,0,0), $box_weight=1; // Box around plot area 485 public $doshadow=false,$shadow_width=4,$shadow_color=array(102,102,102); // Shadow for graph 486 public $xaxis=null; // X-axis (instane of Axis class) 487 public $yaxis=null, $y2axis=null, $ynaxis=array(); // Y axis (instance of Axis class) 488 public $margin_color=array(200,200,200); // Margin color of graph 489 public $plotarea_color=array(255,255,255); // Plot area color 490 public $title,$subtitle,$subsubtitle; // Title and subtitle(s) text object 491 public $axtype="linlin"; // Type of axis 492 public $xtick_factor,$ytick_factor; // Factor to determine the maximum number of ticks depending on the plot width 493 public $texts=null, $y2texts=null; // Text object to ge shown in the graph 519 494 public $lines=null, $y2lines=null; 520 495 public $bands=null, $y2bands=null; 521 public $text_scale_off=0, $text_scale_abscenteroff=-1; 522 public $background_image= '',$background_image_type=-1,$background_image_format="png";496 public $text_scale_off=0, $text_scale_abscenteroff=-1; // Text scale in fractions and for centering bars 497 public $background_image="",$background_image_type=-1,$background_image_format="png"; 523 498 public $background_image_bright=0,$background_image_contr=0,$background_image_sat=0; 524 499 public $background_image_xpos=0,$background_image_ypos=0; … … 526 501 public $inline; 527 502 public $showcsim=0,$csimcolor="red";//debug stuff, draw the csim boundaris on the image if <>0 528 public $grid_depth=DEPTH_BACK; 503 public $grid_depth=DEPTH_BACK; // Draw grid under all plots as default 529 504 public $iAxisStyle = AXSTYLE_SIMPLE; 530 505 public $iCSIMdisplay=false,$iHasStroked = false; … … 536 511 public $bkg_gradtype=-1,$bkg_gradstyle=BGRAD_MARGIN; 537 512 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 541 513 public $titlebackground = false; 542 514 public $titlebackground_color = 'lightblue', 543 544 $titlebackground_framecolor,545 $titlebackground_framestyle,546 $titlebackground_frameweight,547 $titlebackground_bevelheight;515 $titlebackground_style = 1, 516 $titlebackground_framecolor = 'blue', 517 $titlebackground_framestyle = 2, 518 $titlebackground_frameweight = 1, 519 $titlebackground_bevelheight = 3 ; 548 520 public $titlebkg_fillstyle=TITLEBKG_FILLSTYLE_SOLID; 549 521 public $titlebkg_scolor1='black',$titlebkg_scolor2='white'; 550 public $framebevel , $framebeveldepth;551 public $framebevelborder , $framebevelbordercolor;552 public $framebevelcolor1 , $framebevelcolor2;522 public $framebevel = false, $framebeveldepth = 2 ; 523 public $framebevelborder = false, $framebevelbordercolor='black'; 524 public $framebevelcolor1='white@0.4', $framebevelcolor2='black@0.4'; 553 525 public $background_image_mix=100; 554 526 public $background_cflag = ''; … … 556 528 public $background_cflag_mix = 100; 557 529 public $iImgTrans=false, 558 559 560 561 530 $iImgTransHorizon = 100,$iImgTransSkewDist=150, 531 $iImgTransDirection = 1, $iImgTransMinSize = true, 532 $iImgTransFillColor='white',$iImgTransHighQ=false, 533 $iImgTransBorder=false,$iImgTransHorizonPos=0.5; 562 534 public $legend; 563 public $graph_theme;564 535 protected $iYAxisDeltaPos=50; 565 536 protected $iIconDepth=DEPTH_BACK; 566 537 protected $iAxisLblBgType = 0, 567 568 538 $iXAxisLblBgFillColor = 'lightgray', $iXAxisLblBgColor = 'black', 539 $iYAxisLblBgFillColor = 'lightgray', $iYAxisLblBgColor = 'black'; 569 540 protected $iTables=NULL; 570 541 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 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 679 614 // Enable final image perspective transformation 680 615 function Set3DPerspective($aDir=1,$aHorizon=100,$aSkewDist=120,$aQuality=false,$aFillColor='#FFFFFF',$aBorder=false,$aMinSize=true,$aHorizonPos=0.5) { 681 682 683 684 685 686 687 688 689 616 $this->iImgTrans = true; 617 $this->iImgTransHorizon = $aHorizon; 618 $this->iImgTransSkewDist= $aSkewDist; 619 $this->iImgTransDirection = $aDir; 620 $this->iImgTransMinSize = $aMinSize; 621 $this->iImgTransFillColor=$aFillColor; 622 $this->iImgTransHighQ=$aQuality; 623 $this->iImgTransBorder=$aBorder; 624 $this->iImgTransHorizonPos=$aHorizonPos; 690 625 } 691 626 692 627 function SetUserFont($aNormal,$aBold='',$aItalic='',$aBoldIt='') { 693 628 $this->img->ttf->SetUserFont($aNormal,$aBold,$aItalic,$aBoldIt); 694 629 } 695 630 696 631 function SetUserFont1($aNormal,$aBold='',$aItalic='',$aBoldIt='') { 697 632 $this->img->ttf->SetUserFont1($aNormal,$aBold,$aItalic,$aBoldIt); 698 633 } 699 634 700 635 function SetUserFont2($aNormal,$aBold='',$aItalic='',$aBoldIt='') { 701 636 $this->img->ttf->SetUserFont2($aNormal,$aBold,$aItalic,$aBoldIt); 702 637 } 703 638 704 639 function SetUserFont3($aNormal,$aBold='',$aItalic='',$aBoldIt='') { 705 640 $this->img->ttf->SetUserFont3($aNormal,$aBold,$aItalic,$aBoldIt); 706 641 } 707 642 708 643 // Set Image format and optional quality 709 644 function SetImgFormat($aFormat,$aQuality=75) { 710 645 $this->img->SetImgFormat($aFormat,$aQuality); 711 646 } 712 647 713 648 // Should the grid be in front or back of the plot? 714 649 function SetGridDepth($aDepth) { 715 650 $this->grid_depth=$aDepth; 716 651 } 717 652 718 653 function SetIconDepth($aDepth) { 719 720 } 721 654 $this->iIconDepth=$aDepth; 655 } 656 722 657 // Specify graph angle 0-360 degrees. 723 658 function SetAngle($aAngle) { 724 659 $this->img->SetAngle($aAngle); 725 660 } 726 661 727 662 function SetAlphaBlending($aFlg=true) { 728 663 $this->img->SetAlphaBlending($aFlg); 729 664 } 730 665 731 666 // Shortcut to image margin 732 667 function SetMargin($lm,$rm,$tm,$bm) { 733 668 $this->img->SetMargin($lm,$rm,$tm,$bm); 734 669 } 735 670 736 671 function SetY2OrderBack($aBack=true) { 737 738 } 739 740 // Rotate the graph 90 degrees and set the margin 672 $this->y2orderback = $aBack; 673 } 674 675 // Rotate the graph 90 degrees and set the margin 741 676 // when we have done a 90 degree rotation 742 677 function Set90AndMargin($lm=0,$rm=0,$tm=0,$bm=0) { 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 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 754 694 function SetClipping($aFlg=true) { 755 695 $this->iDoClipping = $aFlg ; 756 696 } 757 697 758 698 // Add a plot object to the graph 759 699 function Add($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 } 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; 787 719 } 788 720 789 721 function AddTable($aTable) { 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 } 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 } 798 729 } 799 730 800 731 function AddIcon($aIcon) { 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 } 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 } 809 739 } 810 740 811 741 // Add plot to second Y-scale 812 742 function AddY2($aPlot) { 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 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 842 761 // Add plot to the extra Y-axises 843 762 function AddY($aN,$aPlot) { 844 763 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 } 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; 868 777 } 869 778 870 779 // Add text object to the graph 871 780 function AddText($aTxt,$aToY2=false) { 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 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 897 801 // Add a line object (class PlotLine) to the graph 898 802 function AddLine($aLine,$aToY2=false) { 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 } 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 } 927 822 } 928 823 929 824 // Add vertical or horizontal band 930 825 function AddBand($aBand,$aToY2=false) { 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; 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 } 961 845 } 962 846 963 847 function SetBackgroundGradient($aFrom='navy',$aTo='silver',$aGradType=2,$aStyle=BGRAD_FRAME) { 964 965 966 967 968 } 969 848 $this->bkg_gradtype=$aGradType; 849 $this->bkg_gradstyle=$aStyle; 850 $this->bkg_gradfrom = $aFrom; 851 $this->bkg_gradto = $aTo; 852 } 853 970 854 // Set a country flag in the background 971 855 function SetBackgroundCFlag($aName,$aBgType=BGIMG_FILLPLOT,$aMix=100) { 972 973 974 856 $this->background_cflag = $aName; 857 $this->background_cflag_type = $aBgType; 858 $this->background_cflag_mix = $aMix; 975 859 } 976 860 977 861 // Alias for the above method 978 862 function SetBackgroundCountryFlag($aName,$aBgType=BGIMG_FILLPLOT,$aMix=100) { 979 980 981 863 $this->background_cflag = $aName; 864 $this->background_cflag_type = $aBgType; 865 $this->background_cflag_mix = $aMix; 982 866 } 983 867 984 868 985 869 // Specify a background image 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; 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; 1008 896 } 1009 897 1010 898 function SetBackgroundImageMix($aMix) { 1011 1012 } 1013 899 $this->background_image_mix = $aMix ; 900 } 901 1014 902 // Adjust background image position 1015 903 function SetBackgroundImagePos($aXpos,$aYpos) { 1016 1017 1018 } 1019 904 $this->background_image_xpos = $aXpos ; 905 $this->background_image_ypos = $aYpos ; 906 } 907 1020 908 // Specify axis style (boxed or single) 1021 909 function SetAxisStyle($aStyle) { 1022 910 $this->iAxisStyle = $aStyle ; 1023 911 } 1024 912 1025 913 // Set a frame around the plot area 1026 914 function SetBox($aDrawPlotFrame=true,$aPlotFrameColor=array(0,0,0),$aPlotFrameWeight=1) { 1027 1028 1029 1030 } 1031 915 $this->boxed = $aDrawPlotFrame; 916 $this->box_weight = $aPlotFrameWeight; 917 $this->box_color = $aPlotFrameColor; 918 } 919 1032 920 // Specify color for the plotarea (not the margins) 1033 921 function SetColor($aColor) { 1034 1035 } 1036 922 $this->plotarea_color=$aColor; 923 } 924 1037 925 // Specify color for the margins (all areas outside the plotarea) 1038 926 function SetMarginColor($aColor) { 1039 1040 } 1041 927 $this->margin_color=$aColor; 928 } 929 1042 930 // Set a frame around the entire image 1043 931 function SetFrame($aDrawImgFrame=true,$aImgFrameColor=array(0,0,0),$aImgFrameWeight=1) { 1044 1045 1046 932 $this->doframe = $aDrawImgFrame; 933 $this->frame_color = $aImgFrameColor; 934 $this->frame_weight = $aImgFrameWeight; 1047 935 } 1048 936 1049 937 function SetFrameBevel($aDepth=3,$aBorder=false,$aBorderColor='black',$aColor1='white@0.4',$aColor2='darkgray@0.4',$aFlg=true) { 1050 1051 1052 1053 1054 1055 1056 1057 938 $this->framebevel = $aFlg ; 939 $this->framebeveldepth = $aDepth ; 940 $this->framebevelborder = $aBorder ; 941 $this->framebevelbordercolor = $aBorderColor ; 942 $this->framebevelcolor1 = $aColor1 ; 943 $this->framebevelcolor2 = $aColor2 ; 944 945 $this->doshadow = false ; 1058 946 } 1059 947 1060 948 // Set the shadow around the whole image 1061 function SetShadow($aShowShadow=true,$aShadowWidth=5,$aShadowColor= 'darkgray') {1062 1063 1064 1065 1066 949 function SetShadow($aShowShadow=true,$aShadowWidth=5,$aShadowColor=array(102,102,102)) { 950 $this->doshadow = $aShowShadow; 951 $this->shadow_color = $aShadowColor; 952 $this->shadow_width = $aShadowWidth; 953 $this->footer->iBottomMargin += $aShadowWidth; 954 $this->footer->iRightMargin += $aShadowWidth; 1067 955 } 1068 956 … … 1070 958 // you must also specify the tick distance with a call to Ticks::Set() 1071 959 function SetScale($aAxisType,$aYMin=1,$aYMax=1,$aXMin=1,$aXMax=1) { 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 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 1134 1001 // Specify secondary Y scale 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 } 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); 1162 1022 } 1163 1023 1164 1024 // Set the delta position (in pixels) between the multiple Y-axis 1165 1025 function SetYDeltaDist($aDist) { 1166 1026 $this->iYAxisDeltaPos = $aDist; 1167 1027 } 1168 1028 … … 1170 1030 function SetYScale($aN,$aAxisType="lin",$aYMin=1,$aYMax=1) { 1171 1031 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 } 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); 1193 1046 } 1194 1047 1195 1048 // Specify density of ticks when autoscaling 'normal', 'dense', 'sparse', 'verysparse' 1196 // The dividing factor have been determined heuristically according to my aesthetic 1049 // The dividing factor have been determined heuristically according to my aesthetic 1197 1050 // sense (or lack off) y.m.m.v ! 1198 1051 function SetTickDensity($aYDensity=TICKD_NORMAL,$aXDensity=TICKD_NORMAL) { 1199 1200 $this->ytick_factor=25; 1201 1202 1203 $this->ytick_factor=12; 1204 1205 1206 $this->ytick_factor=25; 1207 1208 1209 $this->ytick_factor=40; 1210 1211 1212 $this->ytick_factor=100; 1213 break; 1214 1215 1216 1217 1218 1219 $this->xtick_factor=15; 1220 1221 1222 $this->xtick_factor=30; 1223 1224 1225 $this->xtick_factor=45; 1226 1227 1228 $this->xtick_factor=60; 1229 break; 1230 1231 1232 } 1233 } 1234 1235 1236 // Get a string of all image map areas 1052 $this->xtick_factor=30; 1053 $this->ytick_factor=25; 1054 switch( $aYDensity ) { 1055 case TICKD_DENSE: 1056 $this->ytick_factor=12; 1057 break; 1058 case TICKD_NORMAL: 1059 $this->ytick_factor=25; 1060 break; 1061 case TICKD_SPARSE: 1062 $this->ytick_factor=40; 1063 break; 1064 case TICKD_VERYSPARSE: 1065 $this->ytick_factor=100; 1066 break; 1067 default: 1068 JpGraphError::RaiseL(25025,$densy);//("JpGraph: Unsupported Tick density: $densy"); 1069 } 1070 switch( $aXDensity ) { 1071 case TICKD_DENSE: 1072 $this->xtick_factor=15; 1073 break; 1074 case TICKD_NORMAL: 1075 $this->xtick_factor=30; 1076 break; 1077 case TICKD_SPARSE: 1078 $this->xtick_factor=45; 1079 break; 1080 case TICKD_VERYSPARSE: 1081 $this->xtick_factor=60; 1082 break; 1083 default: 1084 JpGraphError::RaiseL(25025,$densx);//("JpGraph: Unsupported Tick density: $densx"); 1085 } 1086 } 1087 1088 1089 // Get a string of all image map areas 1237 1090 function GetCSIMareas() { 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 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 1298 1146 // Get a complete <MAP>..</MAP> tag for the final image map 1299 1147 function GetHTMLImageMap($aMapName) { 1300 1301 1302 $im .= "</map>"; 1303 1148 $im = "<map name=\"$aMapName\" id=\"$aMapName\" >\n"; 1149 $im .= $this->GetCSIMareas(); 1150 $im .= "</map>"; 1151 return $im; 1304 1152 } 1305 1153 1306 1154 function CheckCSIMCache($aCacheName,$aTimeOut=60) { 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; 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; 1354 1200 } 1355 1201 1356 1202 // Build the argument string to be used with the csim images 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; 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; 1394 1238 } 1395 1239 1396 1240 function SetCSIMImgAlt($aAlt) { 1397 1241 $this->iCSIMImgAlt = $aAlt; 1398 1242 } 1399 1243 1400 1244 function StrokeCSIM($aScriptName='auto',$aCSIMName='',$aBorder=0) { 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"; 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 } 1483 1312 } 1484 1313 1485 1314 function GetTextsYMinMax($aY2=false) { 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 } 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; 1512 1339 } 1513 1340 1514 1341 function GetTextsXMinMax($aY2=false) { 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 } 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; 1541 1366 } 1542 1367 1543 1368 function GetXMinMax() { 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); 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); 1593 1399 } 1594 1400 1595 1401 function AdjustMarginsForTitles() { 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 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 } 2008 1451 2009 1452 // Stroke the graph 2010 // $aStrokeFileName 1453 // $aStrokeFileName If != "" the image will be written to this file and NOT 2011 1454 // streamed back to the browser 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 } 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 } 2283 2042 } 2284 2043 2285 2044 function SetAxisLabelBackground($aType,$aXFColor='lightgray',$aXColor='black',$aYFColor='lightgray',$aYColor='black') { 2286 $this->iAxisLblBgType = $aType; 2287 $this->iXAxisLblBgFillColor = $aXFColor; 2288 $this->iXAxisLblBgColor = $aXColor; 2289 $this->iYAxisLblBgFillColor = $aYFColor; 2290 $this->iYAxisLblBgColor = $aYColor; 2291 } 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 2292 2054 2293 2055 function StrokeAxisLabelBackground() { 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 } 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 } 2374 2135 } 2375 2136 2376 2137 function StrokeAxis($aStrokeLabels=true) { 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 $bottompos = SIDE_DOWN; 2394 2395 2396 2397 2398 $toppos = FALSE; 2399 2400 2401 2402 2403 2404 2405 $bottompos = SIDE_DOWN; 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 $this->xscale->ticks->SupressFirst(false); 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 // No title for the top X-axis 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 // No title for the right side 2448 2449 2450 2451 2452 2453 $this->yaxis->Stroke($this->xscale,$aStrokeLabels); 2454 2455 2456 2457 $this->yaxis->Stroke($this->xscale,$aStrokeLabels); 2458 2138 2139 if( $aStrokeLabels ) { 2140 $this->StrokeAxisLabelBackground(); 2141 } 2142 2143 // Stroke axis 2144 if( $this->iAxisStyle != AXSTYLE_SIMPLE ) { 2145 switch( $this->iAxisStyle ) { 2146 case AXSTYLE_BOXIN : 2147 $toppos = SIDE_DOWN; 2148 $bottompos = SIDE_UP; 2149 $leftpos = SIDE_RIGHT; 2150 $rightpos = SIDE_LEFT; 2151 break; 2152 case AXSTYLE_BOXOUT : 2153 $toppos = SIDE_UP; 2154 $bottompos = SIDE_DOWN; 2155 $leftpos = SIDE_LEFT; 2156 $rightpos = SIDE_RIGHT; 2157 break; 2158 case AXSTYLE_YBOXIN: 2159 $toppos = FALSE; 2160 $bottompos = SIDE_UP; 2161 $leftpos = SIDE_RIGHT; 2162 $rightpos = SIDE_LEFT; 2163 break; 2164 case AXSTYLE_YBOXOUT: 2165 $toppos = FALSE; 2166 $bottompos = SIDE_DOWN; 2167 $leftpos = SIDE_LEFT; 2168 $rightpos = SIDE_RIGHT; 2169 break; 2170 default: 2171 JpGRaphError::RaiseL(25036,$this->iAxisStyle); //('Unknown AxisStyle() : '.$this->iAxisStyle); 2172 break; 2173 } 2174 2175 // By default we hide the first label so it doesn't cross the 2176 // Y-axis in case the positon hasn't been set by the user. 2177 // However, if we use a box we always want the first value 2178 // displayed so we make sure it will be displayed. 2179 $this->xscale->ticks->SupressFirst(false); 2180 2181 // Now draw the bottom X-axis 2182 $this->xaxis->SetPos('min'); 2183 $this->xaxis->SetLabelSide(SIDE_DOWN); 2184 $this->xaxis->scale->ticks->SetSide($bottompos); 2185 $this->xaxis->Stroke($this->yscale,$aStrokeLabels); 2186 2187 if( $toppos !== FALSE ) { 2188 // We also want a top X-axis 2189 $this->xaxis = $this->xaxis; 2190 $this->xaxis->SetPos('max'); 2191 $this->xaxis->SetLabelSide(SIDE_UP); 2192 // No title for the top X-axis 2193 if( $aStrokeLabels ) { 2194 $this->xaxis->title->Set(''); 2195 } 2196 $this->xaxis->scale->ticks->SetSide($toppos); 2197 $this->xaxis->Stroke($this->yscale,$aStrokeLabels); 2198 } 2199 2200 // Stroke the left Y-axis 2201 $this->yaxis->SetPos('min'); 2202 $this->yaxis->SetLabelSide(SIDE_LEFT); 2203 $this->yaxis->scale->ticks->SetSide($leftpos); 2204 $this->yaxis->Stroke($this->xscale,$aStrokeLabels); 2205 2206 // Stroke the right Y-axis 2207 $this->yaxis->SetPos('max'); 2208 // No title for the right side 2209 if( $aStrokeLabels ) { 2210 $this->yaxis->title->Set(''); 2211 } 2212 $this->yaxis->SetLabelSide(SIDE_RIGHT); 2213 $this->yaxis->scale->ticks->SetSide($rightpos); 2214 $this->yaxis->Stroke($this->xscale,$aStrokeLabels); 2215 } 2216 else { 2217 $this->xaxis->Stroke($this->yscale,$aStrokeLabels); 2218 $this->yaxis->Stroke($this->xscale,$aStrokeLabels); 2219 } 2459 2220 } 2460 2221 … … 2462 2223 // Private helper function for backgound image 2463 2224 static function LoadBkgImage($aImgFormat='',$aFile='',$aImgStr='') { 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 } 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 } 2531 2278 2532 2279 function StrokeBackgroundGrad() { 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 } 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 } 2563 2309 } 2564 2310 2565 2311 function StrokeFrameBackground() { 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); 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); 2655 2402 } 2656 2403 … … 2658 2405 // Draw a frame around the image 2659 2406 function StrokeFrame() { 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 } 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 } 2696 2444 } 2697 2445 2698 2446 function FillMarginArea() { 2699 2700 2701 2702 2703 2704 2705 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 2711 2712 2713 $this->img->height-1-$hadj); 2714 2715 2716 2717 $this->img->height-$this->img->bottom_margin-1); 2447 $hadj=0; $vadj=0; 2448 if( $this->doshadow ) { 2449 $hadj = $this->shadow_width; 2450 $vadj = $this->shadow_width; 2451 } 2452 2453 $this->img->SetColor($this->margin_color); 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 $this->img->FilledRectangle($this->img->left_margin+1, 2459 $this->img->height-$this->img->bottom_margin, 2460 $this->img->width-1-$hadj, 2461 $this->img->height-1-$hadj); 2462 $this->img->FilledRectangle($this->img->width-$this->img->right_margin, 2463 $this->img->top_margin+1, 2464 $this->img->width-1-$hadj, 2465 $this->img->height-$this->img->bottom_margin-1); 2718 2466 } 2719 2467 2720 2468 function FillPlotArea() { 2721 2722 2723 2724 2725 $this->img->height-$this->img->bottom_margin); 2726 2727 } 2728 2469 $this->img->PushColor($this->plotarea_color); 2470 $this->img->FilledRectangle($this->img->left_margin, 2471 $this->img->top_margin, 2472 $this->img->width-$this->img->right_margin, 2473 $this->img->height-$this->img->bottom_margin); 2474 $this->img->PopColor(); 2475 } 2476 2729 2477 // Stroke the plot area with either a solid color or a background image 2730 2478 function StrokePlotArea() { 2731 2732 2733 2734 // means it has no way of compensating for the adjusted plotarea in case of a 2735 2736 2737 2738 2739 2740 if( $this->background_image != '' || $this->background_cflag != '') {2741 2742 2743 2744 2745 2746 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 } 2479 // Note: To be consistent we really should take a possible shadow 2480 // into account. However, that causes some problem for the LinearScale class 2481 // since in the current design it does not have any links to class Graph which 2482 // means it has no way of compensating for the adjusted plotarea in case of a 2483 // shadow. So, until I redesign LinearScale we can't compensate for this. 2484 // So just set the two adjustment parameters to zero for now. 2485 $boxadj = 0; //$this->doframe ? $this->frame_weight : 0 ; 2486 $adj = 0; //$this->doshadow ? $this->shadow_width : 0 ; 2487 2488 if( $this->background_image != "" || $this->background_cflag != "" ) { 2489 $this->StrokeFrameBackground(); 2490 } 2491 else { 2492 $aa = $this->img->SetAngle(0); 2493 $this->StrokeFrame(); 2494 $aa = $this->img->SetAngle($aa); 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 } 2754 2502 2755 2503 function StrokeIcons() { 2756 2757 2758 2759 2760 } 2761 2504 $n = count($this->iIcons); 2505 for( $i=0; $i < $n; ++$i ) { 2506 $this->iIcons[$i]->StrokeWithScale($this->img,$this->xscale,$this->yscale); 2507 } 2508 } 2509 2762 2510 function StrokePlotBox() { 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 } 2775 } 2511 // Should we draw a box around the plot area? 2512 if( $this->boxed ) { 2513 $this->img->SetLineWeight(1); 2514 $this->img->SetLineStyle('solid'); 2515 $this->img->SetColor($this->box_color); 2516 for($i=0; $i < $this->box_weight; ++$i ) { 2517 $this->img->Rectangle( 2518 $this->img->left_margin-$i,$this->img->top_margin-$i, 2519 $this->img->width-$this->img->right_margin+$i, 2520 $this->img->height-$this->img->bottom_margin+$i); 2521 } 2522 } 2523 } 2776 2524 2777 2525 function SetTitleBackgroundFillStyle($aStyle,$aColor1='black',$aColor2='white') { 2778 2779 2780 2526 $this->titlebkg_fillstyle = $aStyle; 2527 $this->titlebkg_scolor1 = $aColor1; 2528 $this->titlebkg_scolor2 = $aColor2; 2781 2529 } 2782 2530 2783 2531 function SetTitleBackground($aBackColor='gray', $aStyle=TITLEBKG_STYLE1, $aFrameStyle=TITLEBKG_FRAME_NONE, $aFrameColor='black', $aFrameWeight=1, $aBevelHeight=3, $aEnable=true) { 2784 2785 2786 2787 2788 2789 $this->titlebackground_frameweight = $aFrameWeight; 2790 2532 $this->titlebackground = $aEnable; 2533 $this->titlebackground_color = $aBackColor; 2534 $this->titlebackground_style = $aStyle; 2535 $this->titlebackground_framecolor = $aFrameColor; 2536 $this->titlebackground_framestyle = $aFrameStyle; 2537 $this->titlebackground_frameweight = $aFrameWeight; 2538 $this->titlebackground_bevelheight = $aBevelHeight ; 2791 2539 } 2792 2540 … … 2794 2542 function StrokeTitles() { 2795 2543 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); 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); 2954 2700 2955 2701 } 2956 2702 2957 2703 function StrokeTexts() { 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2704 // Stroke any user added text objects 2705 if( $this->texts != null ) { 2706 for($i=0; $i < count($this->texts); ++$i) { 2707 $this->texts[$i]->StrokeWithScale($this->img,$this->xscale,$this->yscale); 2708 } 2709 } 2710 2711 if( $this->y2texts != null && $this->y2scale != null ) { 2712 for($i=0; $i < count($this->y2texts); ++$i) { 2713 $this->y2texts[$i]->StrokeWithScale($this->img,$this->xscale,$this->y2scale); 2714 } 2715 } 2970 2716 2971 2717 } 2972 2718 2973 2719 function StrokeTables() { 2974 2975 2976 2977 2978 2979 2720 if( $this->iTables != null ) { 2721 $n = count($this->iTables); 2722 for( $i=0; $i < $n; ++$i ) { 2723 $this->iTables[$i]->StrokeWithScale($this->img,$this->xscale,$this->yscale); 2724 } 2725 } 2980 2726 } 2981 2727 2982 2728 function DisplayClientSideaImageMapAreas() { 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 if ( $coords[1][$i] == 'poly') {2994 2995 2996 2997 2998 2999 3000 } elseif ( $coords[1][$i] == 'rect') {3001 3002 3003 3004 3005 3006 $this->img->LineTo($pts[0],$pts[1]); 3007 3008 3009 2729 // Debug stuff - display the outline of the image map areas 2730 $csim=''; 2731 foreach ($this->plots as $p) { 2732 $csim.= $p->GetCSIMareas(); 2733 } 2734 $csim .= $this->legend->GetCSIMareas(); 2735 if (preg_match_all("/area shape=\"(\w+)\" coords=\"([0-9\, ]+)\"/", $csim, $coords)) { 2736 $this->img->SetColor($this->csimcolor); 2737 $n = count($coords[0]); 2738 for ($i=0; $i < $n; $i++) { 2739 if ($coords[1][$i]=="poly") { 2740 preg_match_all('/\s*([0-9]+)\s*,\s*([0-9]+)\s*,*/',$coords[2][$i],$pts); 2741 $this->img->SetStartPoint($pts[1][count($pts[0])-1],$pts[2][count($pts[0])-1]); 2742 $m = count($pts[0]); 2743 for ($j=0; $j < $m; $j++) { 2744 $this->img->LineTo($pts[1][$j],$pts[2][$j]); 2745 } 2746 } else if ($coords[1][$i]=="rect") { 2747 $pts = preg_split('/,/', $coords[2][$i]); 2748 $this->img->SetStartPoint($pts[0],$pts[1]); 2749 $this->img->LineTo($pts[2],$pts[1]); 2750 $this->img->LineTo($pts[2],$pts[3]); 2751 $this->img->LineTo($pts[0],$pts[3]); 2752 $this->img->LineTo($pts[0],$pts[1]); 2753 } 2754 } 2755 } 3010 2756 } 3011 2757 3012 2758 // Text scale offset in world coordinates 3013 2759 function SetTextScaleOff($aOff) { 3014 3015 2760 $this->text_scale_off = $aOff; 2761 $this->xscale->text_scale_off = $aOff; 3016 2762 } 3017 2763 3018 2764 // Text width of bar to be centered in absolute pixels 3019 2765 function SetTextScaleAbsCenterOff($aOff) { 3020 2766 $this->text_scale_abscenteroff = $aOff; 3021 2767 } 3022 2768 3023 2769 // Get Y min and max values for added lines 3024 2770 function GetLinesYMinMax( $aLines ) { 3025 $n = is_array($aLines) ? count($aLines) : 0;3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 2771 $n = count($aLines); 2772 if( $n == 0 ) return false; 2773 $min = $aLines[0]->scaleposition ; 2774 $max = $min ; 2775 $flg = false; 2776 for( $i=0; $i < $n; ++$i ) { 2777 if( $aLines[$i]->direction == HORIZONTAL ) { 2778 $flg = true ; 2779 $v = $aLines[$i]->scaleposition ; 2780 if( $min > $v ) $min = $v ; 2781 if( $max < $v ) $max = $v ; 2782 } 2783 } 2784 return $flg ? array($min,$max) : false ; 3039 2785 } 3040 2786 3041 2787 // Get X min and max values for added lines 3042 2788 function GetLinesXMinMax( $aLines ) { 3043 $n = is_array($aLines) ? count($aLines) : 0;3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 2789 $n = count($aLines); 2790 if( $n == 0 ) return false ; 2791 $min = $aLines[0]->scaleposition ; 2792 $max = $min ; 2793 $flg = false; 2794 for( $i=0; $i < $n; ++$i ) { 2795 if( $aLines[$i]->direction == VERTICAL ) { 2796 $flg = true ; 2797 $v = $aLines[$i]->scaleposition ; 2798 if( $min > $v ) $min = $v ; 2799 if( $max < $v ) $max = $v ; 2800 } 2801 } 2802 return $flg ? array($min,$max) : false ; 3057 2803 } 3058 2804 3059 2805 // Get min and max values for all included plots 3060 2806 function GetPlotsYMinMax($aPlots) { 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 } 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); 3162 2835 } 3163 2836 … … 3169 2842 //=================================================== 3170 2843 class LineProperty { 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 2844 public $iWeight=1, $iColor="black",$iStyle="solid",$iShow=true; 2845 2846 //--------------- 2847 // PUBLIC METHODS 3179 2848 function SetColor($aColor) { 3180 3181 } 3182 2849 $this->iColor = $aColor; 2850 } 2851 3183 2852 function SetWeight($aWeight) { 3184 3185 } 3186 2853 $this->iWeight = $aWeight; 2854 } 2855 3187 2856 function SetStyle($aStyle) { 3188 3189 } 3190 2857 $this->iStyle = $aStyle; 2858 } 2859 3191 2860 function Show($aShow=true) { 3192 3193 } 3194 2861 $this->iShow=$aShow; 2862 } 2863 3195 2864 function Stroke($aImg,$aX1,$aY1,$aX2,$aY2) { 3196 3197 3198 3199 3200 3201 $aImg->SetLineStyle($this->iStyle); 3202 3203 3204 3205 3206 3207 2865 if( $this->iShow ) { 2866 $aImg->PushColor($this->iColor); 2867 $oldls = $aImg->line_style; 2868 $oldlw = $aImg->line_weight; 2869 $aImg->SetLineWeight($this->iWeight); 2870 $aImg->SetLineStyle($this->iStyle); 2871 $aImg->StyleLine($aX1,$aY1,$aX2,$aY2); 2872 $aImg->PopColor($this->iColor); 2873 $aImg->line_style = $oldls; 2874 $aImg->line_weight = $oldlw; 2875 2876 } 3208 2877 } 3209 2878 } 3210 2879 3211 //===================================================3212 // CLASS GraphTabTitle3213 // Description: Draw "tab" titles on top of graphs3214 //===================================================3215 2880 class GraphTabTitle extends Text{ 3216 2881 private $corner = 6 , $posx = 7, $posy = 4; 3217 2882 private $fillcolor='lightyellow',$bordercolor='black'; 3218 2883 private $align = 'left', $width=TABTITLE_WIDTHFIT; 3219 function __construct() {3220 3221 3222 3223 2884 function GraphTabTitle() { 2885 $this->t = ''; 2886 $this->font_style = FS_BOLD; 2887 $this->hide = true; 2888 $this->color = 'darkred'; 3224 2889 } 3225 2890 3226 2891 function SetColor($aTxtColor,$aFillColor='lightyellow',$aBorderColor='black') { 3227 3228 3229 2892 $this->color = $aTxtColor; 2893 $this->fillcolor = $aFillColor; 2894 $this->bordercolor = $aBorderColor; 3230 2895 } 3231 2896 3232 2897 function SetFillColor($aFillColor) { 3233 2898 $this->fillcolor = $aFillColor; 3234 2899 } 3235 2900 3236 2901 function SetTabAlign($aAlign) { 3237 3238 } 3239 2902 $this->align = $aAlign; 2903 } 2904 3240 2905 function SetWidth($aWidth) { 3241 2906 $this->width = $aWidth ; 3242 2907 } 3243 2908 3244 2909 function Set($t) { 3245 3246 2910 $this->t = $t; 2911 $this->hide = false; 3247 2912 } 3248 2913 3249 2914 function SetCorner($aD) { 3250 2915 $this->corner = $aD ; 3251 2916 } 3252 2917 3253 2918 function Stroke($aImg,$aDummy1=null,$aDummy2=null) { 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'); 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'); 3333 2996 } 3334 2997 … … 3340 3003 //=================================================== 3341 3004 class SuperScriptText extends Text { 3342 private $iSuper= '';3343 private $sfont_family= '',$sfont_style='',$sfont_size=8;3005 private $iSuper=""; 3006 private $sfont_family="",$sfont_style="",$sfont_size=8; 3344 3007 private $iSuperMargin=2,$iVertOverlap=4,$iSuperScale=0.65; 3345 3008 private $iSDir=0; 3346 3009 private $iSimple=false; 3347 3010 3348 function __construct($aTxt='',$aSuper='',$aXAbsPos=0,$aYAbsPos=0) {3349 parent::__construct($aTxt,$aXAbsPos,$aYAbsPos);3350 3011 function SuperScriptText($aTxt="",$aSuper="",$aXAbsPos=0,$aYAbsPos=0) { 3012 parent::Text($aTxt,$aXAbsPos,$aYAbsPos); 3013 $this->iSuper = $aSuper; 3351 3014 } 3352 3015 3353 3016 function FromReal($aVal,$aPrecision=2) { 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; 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; 3383 3043 } 3384 3044 3385 3045 function SetSuperFont($aFontFam,$aFontStyle=FS_NORMAL,$aFontSize=8) { 3386 3387 3388 3046 $this->sfont_family = $aFontFam; 3047 $this->sfont_style = $aFontStyle; 3048 $this->sfont_size = $aFontSize; 3389 3049 } 3390 3050 3391 3051 // Total width of text 3392 3052 function GetWidth($aImg) { 3393 3394 3395 3396 3397 3398 3399 } 3400 3053 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 3054 $w = $aImg->GetTextWidth($this->t); 3055 $aImg->SetFont($this->sfont_family,$this->sfont_style,$this->sfont_size); 3056 $w += $aImg->GetTextWidth($this->iSuper); 3057 $w += $this->iSuperMargin; 3058 return $w; 3059 } 3060 3401 3061 // Hight of font (approximate the height of the text) 3402 3062 function GetFontHeight($aImg) { 3403 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 3404 3405 3406 3407 3063 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 3064 $h = $aImg->GetFontHeight(); 3065 $aImg->SetFont($this->sfont_family,$this->sfont_style,$this->sfont_size); 3066 $h += $aImg->GetFontHeight(); 3067 return $h; 3408 3068 } 3409 3069 3410 3070 // Hight of text 3411 3071 function GetTextHeight($aImg) { 3412 3413 3414 3415 3416 3072 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 3073 $h = $aImg->GetTextHeight($this->t); 3074 $aImg->SetFont($this->sfont_family,$this->sfont_style,$this->sfont_size); 3075 $h += $aImg->GetTextHeight($this->iSuper); 3076 return $h; 3417 3077 } 3418 3078 3419 3079 function Stroke($aImg,$ax=-1,$ay=-1) { 3420 3080 3421 3081 // To position the super script correctly we need different 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(); 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(); 3513 3172 } 3514 3173 } … … 3522 3181 protected $img; 3523 3182 protected $scale; 3524 protected $ majorcolor='#CCCCCC',$minorcolor='#DDDDDD';3525 protected $ majortype='solid',$minortype='solid';3526 protected $show=false, $showMinor=false,$ majorweight=1,$minorweight=1;3183 protected $grid_color='#DDDDDD',$grid_mincolor='#DDDDDD'; 3184 protected $type="solid"; 3185 protected $show=false, $showMinor=false,$weight=1; 3527 3186 protected $fill=false,$fillcolor=array('#EFEFEF','#BBCCFF'); 3528 3529 function __construct($aAxis) { 3530 $this->scale = $aAxis->scale; 3531 $this->img = $aAxis->img; 3532 } 3533 3187 //--------------- 3188 // CONSTRUCTOR 3189 function Grid($aAxis) { 3190 $this->scale = $aAxis->scale; 3191 $this->img = $aAxis->img; 3192 } 3193 //--------------- 3194 // PUBLIC METHODS 3534 3195 function SetColor($aMajColor,$aMinColor=false) { 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 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 3547 3206 // Specify if grid should be dashed, dotted or solid 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 3207 function SetLineStyle($aType) { 3208 $this->type = $aType; 3209 } 3210 3557 3211 // Decide if both major and minor grid should be displayed 3558 3212 function Show($aShowMajor=true,$aShowMinor=false) { 3559 3560 3561 } 3562 3213 $this->show=$aShowMajor; 3214 $this->showMinor=$aShowMinor; 3215 } 3216 3563 3217 function SetFill($aFlg=true,$aColor1='lightgray',$aColor2='lightblue') { 3564 3565 3566 } 3567 3218 $this->fill = $aFlg; 3219 $this->fillcolor = array( $aColor1, $aColor2 ); 3220 } 3221 3568 3222 // Display the grid 3569 3223 function Stroke() { 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 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 3581 3239 // Draw the grid 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; 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; 3658 3321 } 3659 3322 } // Class … … 3665 3328 // several occasion must know wheter it's an X or Y axis. 3666 3329 // This was a design decision to make the code easier to 3667 // follow. 3330 // follow. 3668 3331 //=================================================== 3669 3332 class AxisPrototype { 3670 public $scale=null; 3333 public $scale=null; 3671 3334 public $img=null; 3672 3335 public $hide=false,$hide_labels=false; 3673 3336 public $title=null; 3674 public $font_family=FF_ DEFAULT,$font_style=FS_NORMAL,$font_size=8,$label_angle=0;3337 public $font_family=FF_FONT1,$font_style=FS_NORMAL,$font_size=12,$label_angle=0; 3675 3338 public $tick_step=1; 3676 3339 public $pos = false; … … 3685 3348 protected $labelPos=0; // Which side of the axis should the labels be? 3686 3349 protected $title_adjust,$title_margin,$title_side=SIDE_LEFT; 3687 protected $tick_label_margin= 5;3350 protected $tick_label_margin=7; 3688 3351 protected $label_halign = '',$label_valign = '', $label_para_align='left'; 3689 3352 protected $hide_line=false; 3690 3353 protected $iDeltaAbsPos=0; 3691 3354 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 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 3715 3382 function SetLabelFormat($aFormStr) { 3716 3383 $this->scale->ticks->SetLabelFormat($aFormStr); 3717 3384 } 3718 3385 3719 3386 function SetLabelFormatString($aFormStr,$aDate=false) { 3720 3721 } 3722 3387 $this->scale->ticks->SetLabelFormat($aFormStr,$aDate); 3388 } 3389 3723 3390 function SetLabelFormatCallback($aFuncName) { 3724 3725 } 3726 3727 function SetLabelAlign($aHAlign,$aVAlign= 'top',$aParagraphAlign='left') {3728 3729 3730 3731 } 3391 $this->scale->ticks->SetFormatCallback($aFuncName); 3392 } 3393 3394 function SetLabelAlign($aHAlign,$aVAlign="top",$aParagraphAlign='left') { 3395 $this->label_halign = $aHAlign; 3396 $this->label_valign = $aVAlign; 3397 $this->label_para_align = $aParagraphAlign; 3398 } 3732 3399 3733 3400 // Don't display the first label 3734 3401 function HideFirstTickLabel($aShow=false) { 3735 3402 $this->show_first_label=$aShow; 3736 3403 } 3737 3404 3738 3405 function HideLastTickLabel($aShow=false) { 3739 3406 $this->show_last_label=$aShow; 3740 3407 } 3741 3408 3742 3409 // Manually specify the major and (optional) minor tick position and labels 3743 3410 function SetTickPositions($aMajPos,$aMinPos=NULL,$aLabels=NULL) { 3744 3411 $this->scale->ticks->SetTickPositions($aMajPos,$aMinPos,$aLabels); 3745 3412 } 3746 3413 3747 3414 // Manually specify major tick positions and optional labels 3748 3415 function SetMajTickPositions($aMajPos,$aLabels=NULL) { 3749 3416 $this->scale->ticks->SetTickPositions($aMajPos,NULL,$aLabels); 3750 3417 } 3751 3418 3752 3419 // Hide minor or major tick marks 3753 3420 function HideTicks($aHideMinor=true,$aHideMajor=true) { 3754 3755 3421 $this->scale->ticks->SupressMinorTickMarks($aHideMinor); 3422 $this->scale->ticks->SupressTickMarks($aHideMajor); 3756 3423 } 3757 3424 3758 3425 // Hide zero label 3759 3426 function HideZeroLabel($aFlag=true) { 3760 3761 } 3762 3427 $this->scale->ticks->SupressZeroLabel(); 3428 } 3429 3763 3430 function HideFirstLastLabel() { 3764 // The two first calls to ticks method will supress 3765 3766 3767 3768 3769 3770 3771 $this->show_first_label= false;3772 3773 } 3774 3431 // The two first calls to ticks method will supress 3432 // automatically generated scale values. However, that 3433 // will not affect manually specified value, e.g text-scales. 3434 // therefor we also make a kludge here to supress manually 3435 // specified scale labels. 3436 $this->scale->ticks->SupressLast(); 3437 $this->scale->ticks->SupressFirst(); 3438 $this->show_first_label = false; 3439 $this->show_last_label = false; 3440 } 3441 3775 3442 // Hide the axis 3776 3443 function Hide($aHide=true) { 3777 3444 $this->hide=$aHide; 3778 3445 } 3779 3446 3780 3447 // Hide the actual axis-line, but still print the labels 3781 3448 function HideLine($aHide=true) { 3782 3449 $this->hide_line = $aHide; 3783 3450 } 3784 3451 3785 3452 function HideLabels($aHide=true) { 3786 $this->hide_labels = $aHide; 3787 } 3453 $this->hide_labels = $aHide; 3454 } 3455 3788 3456 3789 3457 // Weight of axis 3790 3458 function SetWeight($aWeight) { 3791 3459 $this->weight = $aWeight; 3792 3460 } 3793 3461 3794 3462 // Axis color 3795 3463 function SetColor($aColor,$aLabelColor=false) { 3796 3797 3798 3799 } 3800 3464 $this->color = $aColor; 3465 if( !$aLabelColor ) $this->label_color = $aColor; 3466 else $this->label_color = $aLabelColor; 3467 } 3468 3801 3469 // Title on axis 3802 function SetTitle($aTitle,$aAdjustAlign= 'high') {3803 3804 3805 } 3806 3470 function SetTitle($aTitle,$aAdjustAlign="high") { 3471 $this->title->Set($aTitle); 3472 $this->title_adjust=$aAdjustAlign; 3473 } 3474 3807 3475 // Specify distance from the axis 3808 3476 function SetTitleMargin($aMargin) { 3809 3810 } 3811 3477 $this->title_margin=$aMargin; 3478 } 3479 3812 3480 // Which side of the axis should the axis title be? 3813 3481 function SetTitleSide($aSideOfAxis) { 3814 $this->title_side = $aSideOfAxis; 3815 } 3816 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 3817 3493 function SetTickSide($aDir) { 3818 $this->scale->ticks->SetSide($aDir); 3819 } 3820 3821 function SetTickSize($aMajSize,$aMinSize=3) { 3822 $this->scale->ticks->SetSize($aMajSize,$aMinSize=3); 3823 } 3824 3494 $this->scale->ticks->SetSide($aDir); 3495 } 3496 3825 3497 // Specify text labels for the ticks. One label for each data point 3826 3498 function SetTickLabels($aLabelArray,$aLabelColorArray=null) { 3827 $this->ticks_label = $aLabelArray; 3828 $this->ticks_label_colors = $aLabelColorArray; 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; 3829 3508 } 3830 3509 3831 3510 function SetLabelMargin($aMargin) { 3832 3833 } 3834 3511 $this->tick_label_margin=$aMargin; 3512 } 3513 3835 3514 // Specify that every $step of the ticks should be displayed starting 3836 3515 // at $start 3516 // DEPRECATED FUNCTION: USE SetTextTickInterval() INSTEAD 3517 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 starting 3522 // at $start 3837 3523 function SetTextTickInterval($aStep,$aStart=0) { 3838 3839 3840 } 3841 3842 // Specify that every $step tick mark should have a label 3524 $this->scale->ticks->SetTextLabelStart($aStart); 3525 $this->tick_step=$aStep; 3526 } 3527 3528 // Specify that every $step tick mark should have a label 3843 3529 // should be displayed starting 3844 3530 function SetTextLabelInterval($aStep) { 3845 if( $aStep < 1 ) { 3846 JpGraphError::RaiseL(25058);//(" Text label interval must be specified >= 1."); 3847 } 3848 $this->label_step=$aStep; 3849 } 3850 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 3851 3544 function SetLabelSide($aSidePos) { 3852 3545 $this->labelPos=$aSidePos; 3853 3546 } 3854 3547 3855 3548 // Set the font 3856 3549 function SetFont($aFamily,$aStyle=FS_NORMAL,$aSize=10) { 3857 3858 3859 3550 $this->font_family = $aFamily; 3551 $this->font_style = $aStyle; 3552 $this->font_size = $aSize; 3860 3553 } 3861 3554 3862 3555 // Position for axis line on the "other" scale 3863 3556 function SetPos($aPosOnOtherScale) { 3864 3865 } 3866 3867 // Set the position of the axis to be X-pixels delta to the right 3557 $this->pos=$aPosOnOtherScale; 3558 } 3559 3560 // Set the position of the axis to be X-pixels delta to the right 3868 3561 // of the max X-position (used to position the multiple Y-axis) 3869 3562 function SetPosAbsDelta($aDelta) { 3870 3871 } 3872 3563 $this->iDeltaAbsPos=$aDelta; 3564 } 3565 3873 3566 // Specify the angle for the tick labels 3874 3567 function SetLabelAngle($aAngle) { 3875 3876 } 3568 $this->label_angle = $aAngle; 3569 } 3877 3570 3878 3571 } // Class … … 3885 3578 // several occasion must know wheter it's an X or Y axis. 3886 3579 // This was a design decision to make the code easier to 3887 // follow. 3580 // follow. 3888 3581 //=================================================== 3889 3582 class Axis extends AxisPrototype { 3890 3583 3891 function __construct($img,$aScale,$color='black') {3892 parent::__construct($img,$aScale,$color);3893 } 3894 3584 function Axis($img,$aScale,$color=array(0,0,0)) { 3585 parent::Axis($img,$aScale,$color); 3586 } 3587 3895 3588 // Stroke the axis. 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 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 4008 3677 // Draw all the tick labels on major tick marks 4009 3678 function StrokeLabels($aPos,$aMinor=false,$aAbsLabel=false) { 4010 3679 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 } 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 } 4154 3792 4155 3793 } … … 4167 3805 public $direction=1; // Should ticks be in(=1) the plot area or outside (=-1) 4168 3806 public $supress_last=false,$supress_tickmarks=false,$supress_minor_tickmarks=false; 4169 public $maj_ticks_pos = array(), $maj_ticklabels_pos = array(), 4170 3807 public $maj_ticks_pos = array(), $maj_ticklabels_pos = array(), 3808 $ticks_pos = array(), $maj_ticks_label = array(); 4171 3809 public $precision; 4172 3810 … … 4175 3813 protected $is_set=false; 4176 3814 protected $supress_zerolabel=false,$supress_first=false; 4177 protected $mincolor= '',$majcolor='';3815 protected $mincolor="",$majcolor=""; 4178 3816 protected $weight=1; 4179 3817 protected $label_usedateformat=FALSE; 4180 3818 4181 function __construct($aScale) { 4182 $this->scale=$aScale; 4183 $this->precision = -1; 4184 } 4185 3819 //--------------- 3820 // CONSTRUCTOR 3821 function Ticks($aScale) { 3822 $this->scale=$aScale; 3823 $this->precision = -1; 3824 } 3825 3826 //--------------- 3827 // PUBLIC METHODS 4186 3828 // Set format string for automatic labels 4187 3829 function SetLabelFormat($aFormatString,$aDate=FALSE) { 4188 4189 4190 } 4191 3830 $this->label_formatstr=$aFormatString; 3831 $this->label_usedateformat=$aDate; 3832 } 3833 4192 3834 function SetLabelDateFormat($aFormatString) { 4193 4194 } 4195 3835 $this->label_dateformatstr=$aFormatString; 3836 } 3837 4196 3838 function SetFormatCallback($aCallbackFuncName) { 4197 4198 } 4199 3839 $this->label_formfunc = $aCallbackFuncName; 3840 } 3841 4200 3842 // Don't display the first zero label 4201 3843 function SupressZeroLabel($aFlag=true) { 4202 4203 } 4204 3844 $this->supress_zerolabel=$aFlag; 3845 } 3846 4205 3847 // Don't display minor tick marks 4206 3848 function SupressMinorTickMarks($aHide=true) { 4207 4208 } 4209 3849 $this->supress_minor_tickmarks=$aHide; 3850 } 3851 4210 3852 // Don't display major tick marks 4211 3853 function SupressTickMarks($aHide=true) { 4212 4213 } 4214 3854 $this->supress_tickmarks=$aHide; 3855 } 3856 4215 3857 // Hide the first tick mark 4216 3858 function SupressFirst($aHide=true) { 4217 4218 } 4219 3859 $this->supress_first=$aHide; 3860 } 3861 4220 3862 // Hide the last tick mark 4221 3863 function SupressLast($aHide=true) { 4222 3864 $this->supress_last=$aHide; 4223 3865 } 4224 3866 4225 3867 // Size (in pixels) of minor tick marks 4226 3868 function GetMinTickAbsSize() { 4227 4228 } 4229 3869 return $this->minor_abs_size; 3870 } 3871 4230 3872 // Size (in pixels) of major tick marks 4231 3873 function GetMajTickAbsSize() { 4232 return $this->major_abs_size; 4233 } 4234 3874 return $this->major_abs_size; 3875 } 3876 4235 3877 function SetSize($aMajSize,$aMinSize=3) { 4236 $this->major_abs_size = $aMajSize; 4237 $this->minor_abs_size = $aMinSize; 3878 $this->major_abs_size = $aMajSize; 3879 $this->minor_abs_size = $aMinSize; 4238 3880 } 4239 3881 4240 3882 // Have the ticks been specified 4241 3883 function IsSpecified() { 4242 return $this->is_set; 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; 4243 3893 } 4244 3894 4245 3895 function SetSide($aSide) { 4246 4247 } 4248 3896 $this->direction=$aSide; 3897 } 3898 4249 3899 // Which side of the axis should the ticks be on 4250 3900 function SetDirection($aSide=SIDE_RIGHT) { 4251 4252 } 4253 3901 $this->direction=$aSide; 3902 } 3903 4254 3904 // Set colors for major and minor tick marks 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 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 4271 3919 function SetWeight($aWeight) { 4272 4273 } 4274 3920 $this->weight=$aWeight; 3921 } 3922 4275 3923 } // Class 4276 3924 … … 4288 3936 private $iAdjustForDST = false; // If a date falls within the DST period add one hour to the diaplyed time 4289 3937 4290 function __construct() { 4291 $this->precision = -1; 4292 } 4293 3938 //--------------- 3939 // CONSTRUCTOR 3940 function LinearTicks() { 3941 $this->precision = -1; 3942 } 3943 3944 //--------------- 3945 // PUBLIC METHODS 3946 3947 4294 3948 // Return major step size in world coordinates 4295 3949 function GetMajor() { 4296 4297 } 4298 3950 return $this->major_step; 3951 } 3952 4299 3953 // Return minor step size in world coordinates 4300 3954 function GetMinor() { 4301 4302 } 4303 3955 return $this->minor_step; 3956 } 3957 4304 3958 // Set Minor and Major ticks (in world coordinates) 4305 3959 function Set($aMajStep,$aMinStep=false) { 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; 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; 4318 3971 } 4319 3972 4320 3973 function SetMajTickPositions($aMajPos,$aLabels=NULL) { 4321 3974 $this->SetTickPositions($aMajPos,NULL,$aLabels); 4322 3975 } 4323 3976 4324 3977 function SetTickPositions($aMajPos,$aMinPos=NULL,$aLabels=NULL) { 4325 4326 4327 4328 4329 4330 4331 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 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 if( empty($this->iManualMinTickPos[$i]) || $this->iManualMinTickPos[$i] < $minScale || $this->iManualMinTickPos[$i] > $maxScale) { 4388 continue; 4389 } 4390 4391 4392 3978 if( !is_array($aMajPos) || ($aMinPos!==NULL && !is_array($aMinPos)) ) { 3979 JpGraphError::RaiseL(25065);//('Tick positions must be specifued as an array()'); 3980 return; 3981 } 3982 $n=count($aMajPos); 3983 if( is_array($aLabels) && (count($aLabels) != $n) ) { 3984 JpGraphError::RaiseL(25066);//('When manually specifying tick positions and labels the number of labels must be the same as the number of specified ticks.'); 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 labels 3993 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 $this->maj_ticks_label[$j] = $this->iManualTickLabels[$i]; 4025 } 4026 else { 4027 $this->maj_ticks_label[$j]=$this->_doLabelFormat($this->iManualTickPos[$i],$i,$n); 4028 } 4029 ++$j; 4030 } 4031 4032 // Some sanity check 4033 if( count($this->maj_ticks_pos) < 2 ) { 4034 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.'); 4035 } 4036 4037 // Setup the minor tick marks 4038 $j=0; 4039 for($i=0; $i < $m; ++$i ) { 4040 if( empty($this->iManualMinTickPos[$i]) || 4041 $this->iManualMinTickPos[$i] < $minScale || $this->iManualMinTickPos[$i] > $maxScale) 4042 continue; 4043 $this->ticks_pos[$j] = $aScale->Translate($this->iManualMinTickPos[$i]); 4044 ++$j; 4045 } 4393 4046 } 4394 4047 4395 4048 function _doAutoTickPos($aScale) { 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 } 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 } 4476 4125 } 4477 4126 4478 4127 function AdjustForDST($aFlg=true) { 4479 4128 $this->iAdjustForDST = $aFlg; 4480 4129 } 4481 4130 … … 4483 4132 function _doLabelFormat($aVal,$aIdx,$aNbrTicks) { 4484 4133 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; 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; 4551 4188 } 4552 4189 4553 4190 // Stroke ticks on either X or Y axis 4554 4191 function _StrokeTicks($aImg,$aScale,$aPos) { 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 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 4613 4242 } 4614 4243 4615 4244 // Draw linear ticks 4616 4245 function Stroke($aImg,$aScale,$aPos) { 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 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 4628 4255 // Spoecify the offset of the displayed tick mark with the tick "space" 4629 // Legal values for $o is [0,1] used to adjust where the tick marks and label 4256 // Legal values for $o is [0,1] used to adjust where the tick marks and label 4630 4257 // should be positioned within the major tick-size 4631 4258 // $lo specifies the label offset and $to specifies the tick offset … … 4633 4260 // tick but have the labels displayed halfway under the bars. 4634 4261 function SetXLabelOffset($aLabelOff,$aTickOff=-1) { 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 } 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 4646 4269 } 4647 4270 4648 4271 // Which tick label should we start with? 4649 4272 function SetTextLabelStart($aTextLabelOff) { 4650 4651 } 4652 4273 $this->text_label_start=$aTextLabelOff; 4274 } 4275 4653 4276 } // Class 4654 4277 4655 4278 //=================================================== 4656 4279 // CLASS LinearScale 4657 // Description: Handle linear scaling between screen and world 4280 // Description: Handle linear scaling between screen and world 4658 4281 //=================================================== 4659 4282 class LinearScale { … … 4674 4297 public $auto_ticks=false; // When using manual scale should the ticks be automatically set? 4675 4298 public $world_abs_size; // Plot area size in pixels (Needed public in jpgraph_radar.php) 4299 public $world_size; // Plot area size in world coordinates 4676 4300 public $intscale=false; // Restrict autoscale to integers 4677 4301 protected $autoscale_min=false; // Forced minimum value, auto determine max 4678 4302 protected $autoscale_max=false; // Forced maximum value, auto determine min 4679 4303 private $gracetop=0,$gracebottom=0; 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 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 4693 4318 // Check if scale is set or if we should autoscale 4694 4319 // We should do this is either scale or ticks has not been set 4695 4320 function IsSpecified() { 4696 if( $this->GetMinVal()==$this->GetMaxVal() ) {// Scale not set4697 4698 4699 4700 } 4701 4702 // Set the minimum data value when the autoscaling is used. 4321 if( $this->GetMinVal()==$this->GetMaxVal() ) { // Scale not set 4322 return false; 4323 } 4324 return true; 4325 } 4326 4327 // Set the minimum data value when the autoscaling is used. 4703 4328 // Usefull if you want a fix minimum (like 0) but have an 4704 4329 // automatic maximum 4705 4330 function SetAutoMin($aMin) { 4706 4707 } 4708 4709 // Set the minimum data value when the autoscaling is used. 4331 $this->autoscale_min=$aMin; 4332 } 4333 4334 // Set the minimum data value when the autoscaling is used. 4710 4335 // Usefull if you want a fix minimum (like 0) but have an 4711 4336 // automatic maximum 4712 4337 function SetAutoMax($aMax) { 4713 4338 $this->autoscale_max=$aMax; 4714 4339 } 4715 4340 … … 4717 4342 // still be set automatically? 4718 4343 function SetAutoTicks($aFlag=true) { 4719 4344 $this->auto_ticks = $aFlag; 4720 4345 } 4721 4346 4722 4347 // Specify scale "grace" value (top and bottom) 4723 4348 function SetGrace($aGraceTop,$aGraceBottom=0) { 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 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 4731 4355 // Get the minimum value in the scale 4732 4356 function GetMinVal() { 4733 4734 } 4735 4357 return $this->scale[0]; 4358 } 4359 4736 4360 // get maximum value for scale 4737 4361 function GetMaxVal() { 4738 4739 } 4740 4741 // Specify a new min/max value for sclae 4362 return $this->scale[1]; 4363 } 4364 4365 // Specify a new min/max value for sclae 4742 4366 function Update($aImg,$aMin,$aMax) { 4743 $this->scale=array($aMin,$aMax); 4744 $this->world_size=$aMax-$aMin; 4745 $this->InitConstants($aImg); 4746 } 4747 4367 $this->scale=array($aMin,$aMax); 4368 $this->world_size=$aMax-$aMin; 4369 $this->InitConstants($aImg); 4370 } 4371 4748 4372 // Translate between world and screen 4749 4373 function Translate($aCoord) { 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 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 4761 4384 // Relative translate (don't include offset) usefull when we just want 4762 4385 // to know the relative position (in pixels) on the axis 4763 4386 function RelTranslate($aCoord) { 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 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 4775 4397 // Restrict autoscaling to only use integers 4776 4398 function SetIntScale($aIntScale=true) { 4777 4778 } 4779 4399 $this->intscale=$aIntScale; 4400 } 4401 4780 4402 // Calculate an integer autoscale 4781 4403 function IntAutoScale($img,$min,$max,$maxsteps,$majend=true) { 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 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 4895 4525 // Calculate autoscale. Used if user hasn't given a scale and ticks 4896 4526 // $maxsteps is the maximum number of major tickmarks allowed. 4897 4527 function AutoScale($img,$min,$max,$maxsteps,$majend=true) { 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 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 5002 4631 5003 4632 // This method recalculates all constants that are depending on the … … 5006 4635 // that image. Should really be installed as an observer of that image. 5007 4636 function InitConstants($img) { 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 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 5028 4655 // Initialize the conversion constants for this scale 5029 4656 // This tries to pre-calculate as much as possible to speed up the 5030 4657 // actual conversion (with Translate()) later on 5031 // $start 5032 // 5033 // $len =absolute length in pixels of scale4658 // $start =scale start in absolute pixels (for x-scale this is an y-position 4659 // and for an y-scale this is an x-position 4660 // $len =absolute length in pixels of scale 5034 4661 function SetConstants($aStart,$aLen) { 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 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 5052 4680 // Calculate number of ticks steps with a specific division 5053 4681 // $a is the divisor of 10**x to generate the first maj tick intervall … … 5056 4684 // $a=2, $b=5 give major ticks with multiple of 5:s ...,0.5,5,50,... 5057 4685 // We return a vector of 5058 // 4686 // [$numsteps,$adjmin,$adjmax,$minstep,$majstep] 5059 4687 // If $majend==true then the first and last marks on the axis will be major 5060 4688 // labeled tick marks otherwise it will be adjusted to the closest min tick mark 5061 4689 function CalcTicks($maxsteps,$min,$max,$a,$b,$majend=true) { 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); 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); 5101 4726 } 5102 4727 5103 4728 function CalcTicksFreeze($maxsteps,$min,$max,$a,$b) { 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 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 5128 4751 function IntCalcTicks($maxsteps,$min,$max,$a,$majend=true) { 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); 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); 5173 4789 } 5174 4790 5175 4791 5176 4792 function IntCalcTicksFreeze($maxsteps,$min,$max,$a) { 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 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 5205 4819 // Determine the minimum of three values witha weight for last value 5206 4820 function MatchMin3($a,$b,$c,$weight) { 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; 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 5233 4830 } 5234 4831 } // Class … … 5242 4839 public $margin=5; 5243 4840 public $show=false; 5244 public $valign= '',$halign='center';5245 public $format= '%.1f',$negformat='';5246 private $ff=FF_ DEFAULT,$fs=FS_NORMAL,$fsize=8;4841 public $valign="",$halign="center"; 4842 public $format="%.1f",$negformat=""; 4843 private $ff=FF_FONT1,$fs=FS_NORMAL,$fsize=10; 5247 4844 private $iFormCallback=''; 5248 4845 private $angle=0; 5249 private $color= 'navy',$negcolor='';4846 private $color="navy",$negcolor=""; 5250 4847 private $iHideZero=false; 5251 public $txt=null;5252 5253 function __construct() {5254 $this->txt = new Text();5255 }5256 4848 5257 4849 function Show($aFlag=true) { 5258 5259 } 5260 5261 function SetColor($aColor,$aNegcolor= '') {5262 5263 5264 } 5265 5266 function SetFont($aFontFamily,$aFontStyle=FS_NORMAL,$aFontSize= 8) {5267 5268 5269 4850 $this->show=$aFlag; 4851 } 4852 4853 function SetColor($aColor,$aNegcolor="") { 4854 $this->color = $aColor; 4855 $this->negcolor = $aNegcolor; 4856 } 4857 4858 function SetFont($aFontFamily,$aFontStyle=FS_NORMAL,$aFontSize=10) { 4859 $this->ff=$aFontFamily; 4860 $this->fs=$aFontStyle; 4861 $this->fsize=$aFontSize; 5270 4862 } 5271 4863 5272 4864 function ApplyFont($aImg) { 5273 4865 $aImg->SetFont($this->ff,$this->fs,$this->fsize); 5274 4866 } 5275 4867 5276 4868 function SetMargin($aMargin) { 5277 4869 $this->margin = $aMargin; 5278 4870 } 5279 4871 5280 4872 function SetAngle($aAngle) { 5281 4873 $this->angle = $aAngle; 5282 4874 } 5283 4875 5284 4876 function SetAlign($aHAlign,$aVAlign='') { 5285 5286 5287 } 5288 5289 function SetFormat($aFormat,$aNegFormat= '') {5290 5291 4877 $this->halign = $aHAlign; 4878 $this->valign = $aVAlign; 4879 } 4880 4881 function SetFormat($aFormat,$aNegFormat="") { 4882 $this->format= $aFormat; 4883 $this->negformat= $aNegFormat; 5292 4884 } 5293 4885 5294 4886 function SetFormatCallback($aFunc) { 5295 4887 $this->iFormCallback = $aFunc; 5296 4888 } 5297 4889 5298 4890 function HideZero($aFlag=true) { 5299 4891 $this->iHideZero=$aFlag; 5300 4892 } 5301 4893 5302 4894 function Stroke($img,$aVal,$x,$y) { 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 } 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 } 5368 4946 } 5369 4947 } … … 5378 4956 public $legend=''; 5379 4957 public $coords=array(); 5380 public $color= 'black';4958 public $color="black"; 5381 4959 public $hidelegend=false; 5382 4960 public $line_weight=1; 5383 4961 public $csimtargets=array(),$csimwintargets=array(); // Array of targets for CSIM 5384 public $csimareas= ''; // Resultant CSIM area tags5385 public $csimalts=null; 4962 public $csimareas=""; // Resultant CSIM area tags 4963 public $csimalts=null; // ALT:s for corresponding target 5386 4964 public $legendcsimtarget='',$legendcsimwintarget=''; 5387 4965 public $legendcsimalt=''; 5388 protected $weight=1; 4966 protected $weight=1; 5389 4967 protected $center=false; 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 } 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 5418 4989 5419 4990 // Stroke the plot … … 5421 4992 // the subclasses 5422 4993 function Stroke($aImg,$aXScale,$aYScale) { 5423 4994 JpGraphError::RaiseL(25122);//("JpGraph: Stroke() must be implemented by concrete subclass to class Plot"); 5424 4995 } 5425 4996 5426 4997 function HideLegend($f=true) { 5427 4998 $this->hidelegend = $f; 5428 4999 } 5429 5000 5430 5001 function DoLegend($graph) { 5431 5432 5002 if( !$this->hidelegend ) 5003 $this->Legend($graph); 5433 5004 } 5434 5005 5435 5006 function StrokeDataValue($img,$aVal,$x,$y) { 5436 5437 } 5438 5439 // Set href targets for CSIM 5007 $this->value->Stroke($img,$aVal,$x,$y); 5008 } 5009 5010 // Set href targets for CSIM 5440 5011 function SetCSIMTargets($aTargets,$aAlts='',$aWinTargets='') { 5441 5442 5443 $this->csimalts=$aAlts; 5444 } 5445 5012 $this->csimtargets=$aTargets; 5013 $this->csimwintargets=$aWinTargets; 5014 $this->csimalts=$aAlts; 5015 } 5016 5446 5017 // Get all created areas 5447 5018 function GetCSIMareas() { 5448 5449 } 5450 5019 return $this->csimareas; 5020 } 5021 5451 5022 // "Virtual" function which gets called before any scale 5452 5023 // or axis are stroked used to do any plot specific adjustment 5453 5024 function PreStrokeAdjust($aGraph) { 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 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 5466 5030 // Get minimum values in plot 5467 5031 function Min() { 5468 if( isset($this->coords[1]) ) { 5469 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 5498 } 5499 5032 if( isset($this->coords[1]) ) 5033 $x=$this->coords[1]; 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 return array($xm,$ym); 5062 } 5063 5500 5064 // Get maximum value in plot 5501 5065 function Max() { 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 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 5535 5101 function SetColor($aColor) { 5536 5537 } 5538 5102 $this->color=$aColor; 5103 } 5104 5539 5105 function SetLegend($aLegend,$aCSIM='',$aCSIMAlt='',$aCSIMWinTarget='') { 5540 5541 5542 5543 5106 $this->legend = $aLegend; 5107 $this->legendcsimtarget = $aCSIM; 5108 $this->legendcsimwintarget = $aCSIMWinTarget; 5109 $this->legendcsimalt = $aCSIMAlt; 5544 5110 } 5545 5111 5546 5112 function SetWeight($aWeight) { 5547 5548 } 5549 5113 $this->weight=$aWeight; 5114 } 5115 5550 5116 function SetLineWeight($aWeight=1) { 5551 5552 } 5553 5117 $this->line_weight=$aWeight; 5118 } 5119 5554 5120 function SetCenter($aCenter=true) { 5555 5556 } 5557 5121 $this->center = $aCenter; 5122 } 5123 5558 5124 // This method gets called by Graph class to plot anything that should go 5559 5125 // into the margin after the margin color has been set. 5560 5126 function StrokeMargin($aImg) { 5561 5127 return true; 5562 5128 } 5563 5129 5564 5130 // Framework function the chance for each plot class to set a legend 5565 5131 function Legend($aGraph) { 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 5132 if( $this->legend != "" ) 5133 $aGraph->legend->Add($this->legend,$this->color,"",0,$this->legendcsimtarget, 5134 $this->legendcsimalt,$this->legendcsimwintarget); 5135 } 5136 5577 5137 } // Class 5578 5138 5579 5139 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 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 } 5627 5241 } 5628 5242 -
trunk/client/modules/Elezioni/grafici/jpgraph_antispam-digits.php
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph_antispam-digits.php 1930 2010-01-22 20:19:27Z ljp $3 // File: JPGRAPH_ANTISPAM.PHP 4 // Description: Genarate anti-spam challenge 5 // Created: 2004-10-07 6 // Ver: $Id: jpgraph_antispam-digits.php 781 2006-10-08 08:07:47Z ljp $ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. All rights reserved. 9 9 //======================================================================== 10 10 … … 13 13 public $iHeight=30, $iWidth=30; 14 14 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=' ; 15 function HandDigits() { 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 } 154 155 class AntiSpam { 156 157 var $iNumber=''; 158 159 function AntiSpam($aNumber='') { 160 $this->iNumber = $aNumber; 161 } 162 163 function Rand($aLen) { 164 $d=''; 165 for($i=0; $i < $aLen; ++$i) { 166 $d .= rand(1,9); 167 } 168 $this->iNumber = $d; 169 return $d; 170 } 171 172 function Stroke() { 173 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; 152 202 } 153 203 } 154 204 155 class AntiSpam {156 157 private $iNumber='';158 159 function __construct($aNumber='') {160 $this->iNumber = $aNumber;161 }162 163 function Rand($aLen) {164 $d='';165 for($i=0; $i < $aLen; ++$i) {166 $d .= rand(1,9);167 }168 $this->iNumber = $d;169 return $d;170 }171 172 function Stroke() {173 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 }203 }204 205 205 ?> -
trunk/client/modules/Elezioni/grafici/jpgraph_antispam.php
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph_antispam.php 1106 2009-02-22 20:16:35Z ljp $3 // File: JPGRAPH_ANTISPAM.PHP 4 // Description: Genarate anti-spam challenge 5 // Created: 2004-10-07 6 // Ver: $Id: jpgraph_antispam.php 808 2006-11-28 19:10:40Z ljp $ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. All rights reserved. 9 9 //======================================================================== 10 10 … … 13 13 public $iHeight=30, $iWidth=30; 14 14 15 function __construct() {16 17 18 19 20 21 $this->chars['j'][1]= 15 function HandDigits() { 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 34 35 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 49 50 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 64 65 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 79 80 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 94 95 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 109 110 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 124 125 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 139 140 141 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 155 156 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 171 172 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 187 188 189 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 203 204 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 219 220 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 234 235 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 249 250 251 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 265 266 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 281 282 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 298 299 300 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 314 315 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 330 331 332 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 346 347 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 361 362 363 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 376 377 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 392 393 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 408 409 410 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 423 424 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 438 439 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 453 454 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 468 469 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 483 484 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 498 499 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 513 514 515 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 528 529 530 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 } 544 } 545 546 class AntiSpam { 547 548 private $iData=''; 549 private $iDD=null; 550 551 function AntiSpam($aData='') { 552 $this->iData = $aData; 553 $this->iDD = new HandDigits(); 554 } 555 556 function Set($aData) { 557 $this->iData = $aData; 558 } 559 560 function Rand($aLen) { 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 } 578 579 function Stroke() { 580 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; 543 612 } 544 613 } 545 614 546 class AntiSpam {547 548 private $iData='';549 private $iDD=null;550 551 function __construct($aData='') {552 $this->iData = $aData;553 $this->iDD = new HandDigits();554 }555 556 function Set($aData) {557 $this->iData = $aData;558 }559 560 function Rand($aLen) {561 $d='';562 for($i=0; $i < $aLen; ++$i) {563 if( rand(0,9) < 6 ) {564 // Digits565 $d .= chr( ord('1') + rand(0,8) );566 }567 else {568 // Letters569 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 }578 579 function Stroke() {580 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 }613 }614 615 615 ?> -
trunk/client/modules/Elezioni/grafici/jpgraph_bar.php
r265 r267 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 1905 2009-10-06 18:00:21Z ljp $7 8 // Copyright (c) Asial Corporation. 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 1017 2008-07-08 06:09:28Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. 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 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 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 57 55 // Set a drop shadow for the bar (or rather an "up-right" shadow) 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 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 76 66 // DEPRECATED use SetYBase instead 77 67 function SetYMin($aYStartValue) { 78 //die("JpGraph Error: Deprecated function SetYMin. Use SetYBase() instead."); 79 68 //die("JpGraph Error: Deprecated function SetYMin. Use SetYBase() instead."); 69 $this->ybase=$aYStartValue; 80 70 } 81 71 82 72 // Specify the base value for the bars 83 73 function SetYBase($aYStartValue) { 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 74 $this->ybase=$aYStartValue; 75 } 76 101 77 function Legend($graph) { 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 } 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 } 135 110 } 136 111 137 112 // Gets called before any axis are stroked 138 113 function PreStrokeAdjust($graph) { 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 // Center the bars 154 155 156 157 158 159 160 161 $graph->SetTextScaleOff(1-$this->width); 162 163 164 elseif( ($this instanceof AccBarPlot) || ($this instanceof GroupBarPlot) ) { 165 166 167 168 114 parent::PreStrokeAdjust($graph); 115 116 // If we are using a log Y-scale we want the base to be at the 117 // minimum Y-value unless the user have specifically set some other 118 // value than the default. 119 if( substr($graph->axtype,-3,3)=="log" && $this->ybase==0 ) 120 $this->ybase = $graph->yaxis->scale->GetMinVal(); 121 122 // For a "text" X-axis scale we will adjust the 123 // display of the bars a little bit. 124 if( substr($graph->axtype,0,3)=="tex" ) { 125 // Position the ticks between the bars 126 $graph->xaxis->scale->ticks->SetXLabelOffset(0.5,0); 127 128 // Center the bars 129 if( $this->abswidth > -1 ) { 130 $graph->SetTextScaleAbsCenterOff($this->abswidth); 131 } 132 else { 133 if( $this->align == "center" ) 134 $graph->SetTextScaleOff(0.5-$this->width/2); 135 elseif( $this->align == "right" ) 136 $graph->SetTextScaleOff(1-$this->width); 137 } 138 } 139 elseif( ($this instanceof AccBarPlot) || ($this instanceof GroupBarPlot) ) { 140 // We only set an absolute width for linear and int scale 141 // for text scale the width will be set to a fraction of 142 // the majstep width. 143 if( $this->abswidth == -1 ) { 169 144 // Not set 170 171 172 173 145 // set width to a visuable sensible default 146 $this->abswidth = $graph->img->plotwidth/(2*$this->numpoints); 147 } 148 } 174 149 } 175 150 176 151 function Min() { 177 $m = parent::Min(); 178 if( $m[1] >= $this->ybase ) $m[1] = $this->ybase; 179 return $m; 152 $m = parent::Min(); 153 if( $m[1] >= $this->ybase ) 154 $m[1] = $this->ybase; 155 return $m; 180 156 } 181 157 182 158 function Max() { 183 $m = parent::Max(); 184 if( $m[1] <= $this->ybase ) $m[1] = $this->ybase; 185 return $m; 186 } 187 159 $m = parent::Max(); 160 if( $m[1] <= $this->ybase ) 161 $m[1] = $this->ybase; 162 return $m; 163 } 164 188 165 // Specify width as fractions of the major stepo size 189 166 function SetWidth($aWidth) { 190 if( $aWidth > 1 ) { 191 // Interpret this as absolute width 192 $this->abswidth=$aWidth; 193 } 194 else { 195 $this->width=$aWidth; 196 } 197 } 198 167 if( $aWidth > 1 ) { 168 // Interpret this as absolute width 169 $this->abswidth=$aWidth; 170 } 171 else 172 $this->width=$aWidth; 173 } 174 199 175 // Specify width in absolute pixels. If specified this 200 176 // overrides SetWidth() 201 177 function SetAbsWidth($aWidth) { 202 203 } 204 178 $this->abswidth=$aWidth; 179 } 180 205 181 function SetAlign($aAlign) { 206 207 } 208 182 $this->align=$aAlign; 183 } 184 209 185 function SetNoFill() { 210 211 212 213 } 214 186 $this->grad = false; 187 $this->fill_color=false; 188 $this->fill=false; 189 } 190 215 191 function SetFillColor($aColor) { 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 192 $this->fill = true ; 193 $this->fill_color=$aColor; 194 } 195 226 196 function SetFillGradient($aFromColor,$aToColor=null,$aStyle=null) { 227 228 229 230 231 } 232 197 $this->grad = true; 198 $this->grad_fromcolor = $aFromColor; 199 $this->grad_tocolor = $aToColor; 200 $this->grad_style = $aStyle; 201 } 202 233 203 function SetValuePos($aPos) { 234 204 $this->valuepos = $aPos; 235 205 } 236 206 237 207 function SetPattern($aPattern, $aColor='black'){ 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 } 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 } 262 231 } 263 232 264 233 function _SetPatternHelper($aPattern, &$aPatternValue, &$aDensity){ 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; 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; 672 579 } 673 580 } // Class … … 678 585 //=================================================== 679 586 class GroupBarPlot extends BarPlot { 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 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 702 608 function Legend($graph) { 703 704 705 706 707 708 709 710 711 712 } 713 609 $n = count($this->plots); 610 for($i=0; $i < $n; ++$i) { 611 $c = get_class($this->plots[$i]); 612 if( !($this->plots[$i] instanceof BarPlot) ) { 613 JpGraphError::RaiseL(2009,$c); 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 $this->plots[$i]->DoLegend($graph); 617 } 618 } 619 714 620 function Min() { 715 716 717 718 719 720 721 722 return array($xmin,$ymin); 723 } 724 621 list($xmin,$ymin) = $this->plots[0]->Min(); 622 $n = count($this->plots); 623 for($i=0; $i < $n; ++$i) { 624 list($xm,$ym) = $this->plots[$i]->Min(); 625 $xmin = max($xmin,$xm); 626 $ymin = min($ymin,$ym); 627 } 628 return array($xmin,$ymin); 629 } 630 725 631 function Max() { 726 727 728 729 730 731 732 733 734 } 735 632 list($xmax,$ymax) = $this->plots[0]->Max(); 633 $n = count($this->plots); 634 for($i=0; $i < $n; ++$i) { 635 list($xm,$ym) = $this->plots[$i]->Max(); 636 $xmax = max($xmax,$xm); 637 $ymax = max($ymax,$ym); 638 } 639 return array($xmax,$ymax); 640 } 641 736 642 function GetCSIMareas() { 737 738 739 740 741 742 743 } 744 643 $n = count($this->plots); 644 $csimareas=''; 645 for($i=0; $i < $n; ++$i) { 646 $csimareas .= $this->plots[$i]->csimareas; 647 } 648 return $csimareas; 649 } 650 745 651 // Stroke all the bars next to each other 746 function Stroke($img,$xscale,$yscale) { 747 748 749 $subwidth = $this->width/$this->nbrplots ; 750 751 752 753 754 755 756 757 758 759 760 761 762 763 652 function Stroke($img,$xscale,$yscale) { 653 $tmp=$xscale->off; 654 $n = count($this->plots); 655 $subwidth = $this->width/$this->nbrplots ; 656 657 for( $i=0; $i < $n; ++$i ) { 658 $this->plots[$i]->ymin=$this->ybase; 659 $this->plots[$i]->SetWidth($subwidth); 660 661 // If the client have used SetTextTickInterval() then 662 // major_step will be > 1 and the positioning will fail. 663 // If we assume it is always one the positioning will work 664 // fine with a text scale but this will not work with 665 // arbitrary linear scale 666 $xscale->off = $tmp+$i*round($xscale->scale_factor* $subwidth); 667 $this->plots[$i]->Stroke($img,$xscale,$yscale); 668 } 669 $xscale->off=$tmp; 764 670 } 765 671 } // Class … … 770 676 //=================================================== 771 677 class AccBarPlot extends BarPlot { 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 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 806 707 function Legend($graph) { 807 808 809 810 811 812 813 } 814 815 708 $n = count($this->plots); 709 for( $i=$n-1; $i >= 0; --$i ) { 710 $c = get_class($this->plots[$i]); 711 if( !($this->plots[$i] instanceof BarPlot) ) { 712 JpGraphError::RaiseL(2012,$c); 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 $this->plots[$i]->DoLegend($graph); 716 } 816 717 } 817 718 818 719 function Max() { 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 if( $ymax <= $this->ybase ) 852 853 720 list($xmax) = $this->plots[0]->Max(); 721 $nmax=0; 722 for($i=0; $i < count($this->plots); ++$i) { 723 $n = count($this->plots[$i]->coords[0]); 724 $nmax = max($nmax,$n); 725 list($x) = $this->plots[$i]->Max(); 726 $xmax = max($xmax,$x); 727 } 728 for( $i = 0; $i < $nmax; $i++ ) { 729 // Get y-value for bar $i by adding the 730 // individual bars from all the plots added. 731 // It would be wrong to just add the 732 // individual plots max y-value since that 733 // would in most cases give to large y-value. 734 $y=0; 735 if( !isset($this->plots[0]->coords[0][$i]) ) { 736 JpGraphError::RaiseL(2014); 737 } 738 if( $this->plots[0]->coords[0][$i] > 0 ) 739 $y=$this->plots[0]->coords[0][$i]; 740 for( $j = 1; $j < $this->nbrplots; $j++ ) { 741 if( !isset($this->plots[$j]->coords[0][$i]) ) { 742 JpGraphError::RaiseL(2014); 743 } 744 if( $this->plots[$j]->coords[0][$i] > 0 ) 745 $y += $this->plots[$j]->coords[0][$i]; 746 } 747 $ymax[$i] = $y; 748 } 749 $ymax = max($ymax); 750 751 // Bar always start at baseline 752 if( $ymax <= $this->ybase ) 753 $ymax = $this->ybase; 754 return array($xmax,$ymax); 854 755 } 855 756 856 757 function Min() { 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 758 $nmax=0; 759 list($xmin,$ysetmin) = $this->plots[0]->Min(); 760 for($i=0; $i < count($this->plots); ++$i) { 761 $n = count($this->plots[$i]->coords[0]); 762 $nmax = max($nmax,$n); 763 list($x,$y) = $this->plots[$i]->Min(); 764 $xmin = Min($xmin,$x); 765 $ysetmin = Min($y,$ysetmin); 766 } 767 for( $i = 0; $i < $nmax; $i++ ) { 768 // Get y-value for bar $i by adding the 769 // individual bars from all the plots added. 770 // It would be wrong to just add the 771 // individual plots max y-value since that 772 // would in most cases give to large y-value. 773 $y=0; 774 if( $this->plots[0]->coords[0][$i] < 0 ) 775 $y=$this->plots[0]->coords[0][$i]; 776 for( $j = 1; $j < $this->nbrplots; $j++ ) { 777 if( $this->plots[$j]->coords[0][$i] < 0 ) 778 $y += $this->plots[ $j ]->coords[0][$i]; 779 } 780 $ymin[$i] = $y; 781 } 782 $ymin = Min($ysetmin,Min($ymin)); 783 // Bar always start at baseline 784 if( $ymin >= $this->ybase ) 785 $ymin = $this->ybase; 786 return array($xmin,$ymin); 886 787 } 887 788 888 789 // Stroke acc bar plot 889 790 function Stroke($img,$xscale,$yscale) { 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; 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; 1185 1038 } 1186 1039 } // Class -
trunk/client/modules/Elezioni/grafici/jpgraph_canvas.php
r265 r267 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 1923 2010-01-11 13:48:49Z ljp $7 8 // Copyright (c) Asial Corporation. 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 781 2006-10-08 08:07:47Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. 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 23 function __construct($aWidth=300,$aHeight=200,$aCachedName="",$timeout=0,$inline=1) {24 parent::__construct($aWidth,$aHeight,$aCachedName,$timeout,$inline);21 //--------------- 22 // CONSTRUCTOR 23 function CanvasGraph($aWidth=300,$aHeight=200,$aCachedName="",$timeout=0,$inline=1) { 24 $this->Graph($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',false) ) { 68 require_once('jpgraph_imgtrans.php'); 69 } 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 70 78 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 } 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
r265 r267 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 1857 2009-09-28 14:38:14Z ljp $7 8 // Copyright (c) Asial Corporation. 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 1091 2009-01-18 22:57:40Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. 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 __construct($graph,$xmin=0,$xmax=10,$ymin=0,$ymax=10) {30 31 32 33 34 35 36 37 } 38 29 function CanvasScale($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; 44 } 45 46 function Get() { 47 return array($this->ixmin,$this->ixmax,$this->iymin,$this->iymax); 40 $this->ixmin = $xmin; 41 $this->ixmax = $xmax; 42 $this->iymin = $ymin; 43 $this->iymax = $ymax; 48 44 } 49 45 50 46 function Translate($x,$y) { 51 52 53 47 $xp = round(($x-$this->ixmin)/($this->ixmax - $this->ixmin) * $this->w); 48 $yp = round(($y-$this->iymin)/($this->iymax - $this->iymin) * $this->h); 49 return array($xp,$yp); 54 50 } 55 51 56 52 function TranslateX($x) { 57 58 53 $xp = round(($x-$this->ixmin)/($this->ixmax - $this->ixmin) * $this->w); 54 return $xp; 59 55 } 60 56 61 57 function TranslateY($y) { 62 63 58 $yp = round(($y-$this->iymin)/($this->iymax - $this->iymin) * $this->h); 59 return $yp; 64 60 } 65 61 … … 74 70 private $img,$scale; 75 71 76 function __construct($aGraph,$scale) {77 78 79 72 function Shape($aGraph,$scale) { 73 $this->img = $aGraph->img; 74 $this->img->SetColor('black'); 75 $this->scale = $scale; 80 76 } 81 77 82 78 function SetColor($aColor) { 83 79 $this->img->SetColor($aColor); 84 80 } 85 81 86 82 function 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); 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); 94 86 } 95 87 96 88 function Polygon($p,$aClosed=false) { 97 98 99 100 101 102 89 $n=count($p); 90 for($i=0; $i < $n; $i+=2 ) { 91 $p[$i] = $this->scale->TranslateX($p[$i]); 92 $p[$i+1] = $this->scale->TranslateY($p[$i+1]); 93 } 94 $this->img->Polygon($p,$aClosed); 103 95 } 104 96 105 97 function FilledPolygon($p) { 106 107 108 109 110 111 112 } 113 98 $n=count($p); 99 for($i=0; $i < $n; $i+=2 ) { 100 $p[$i] = $this->scale->TranslateX($p[$i]); 101 $p[$i+1] = $this->scale->TranslateY($p[$i+1]); 102 } 103 $this->img->FilledPolygon($p); 104 } 105 114 106 115 107 // Draw a bezier curve with defining points in the $aPnts array … … 120 112 // 6=x3, 7=y3 121 113 function Bezier($p,$aSteps=40) { 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 114 $x0 = $p[0]; 115 $y0 = $p[1]; 116 // Calculate coefficients 117 $cx = 3*($p[2]-$p[0]); 118 $bx = 3*($p[4]-$p[2])-$cx; 119 $ax = $p[6]-$p[0]-$cx-$bx; 120 $cy = 3*($p[3]-$p[1]); 121 $by = 3*($p[5]-$p[3])-$cy; 122 $ay = $p[7]-$p[1]-$cy-$by; 123 124 // Step size 125 $delta = 1.0/$aSteps; 126 127 $x_old = $x0; 128 $y_old = $y0; 129 for($t=$delta; $t<=1.0; $t+=$delta) { 130 $tt = $t*$t; $ttt=$tt*$t; 131 $x = $ax*$ttt + $bx*$tt + $cx*$t + $x0; 132 $y = $ay*$ttt + $by*$tt + $cy*$t + $y0; 133 $this->Line($x_old,$y_old,$x,$y); 134 $x_old = $x; 135 $y_old = $y; 136 } 137 $this->Line($x_old,$y_old,$p[6],$p[7]); 146 138 } 147 139 148 140 function Rectangle($x1,$y1,$x2,$y2) { 149 150 151 141 list($x1,$y1) = $this->scale->Translate($x1,$y1); 142 list($x2,$y2) = $this->scale->Translate($x2,$y2); 143 $this->img->Rectangle($x1,$y1,$x2,$y2); 152 144 } 153 145 154 146 function FilledRectangle($x1,$y1,$x2,$y2) { 155 156 157 158 } 159 147 list($x1,$y1) = $this->scale->Translate($x1,$y1); 148 list($x2,$y2) = $this->scale->Translate($x2,$y2); 149 $this->img->FilledRectangle($x1,$y1,$x2,$y2); 150 } 151 160 152 function Circle($x1,$y1,$r) { 161 162 163 164 165 166 153 list($x1,$y1) = $this->scale->Translate($x1,$y1); 154 if( $r >= 0 ) 155 $r = $this->scale->TranslateX($r); 156 else 157 $r = -$r; 158 $this->img->Circle($x1,$y1,$r); 167 159 } 168 160 169 161 function FilledCircle($x1,$y1,$r) { 170 171 172 173 174 175 176 } 177 178 function RoundedRectangle($x1,$y1,$x2,$y2,$r=null) { 179 180 181 182 183 184 185 186 187 188 189 } 190 191 function FilledRoundedRectangle($x1,$y1,$x2,$y2,$r=null) { 192 193 194 195 196 197 198 199 200 201 $this->img->FilledRoundedRectangle($x1,$y1,$x2,$y2,$r); 162 list($x1,$y1) = $this->scale->Translate($x1,$y1); 163 if( $r >= 0 ) 164 $r = $this->scale->TranslateX($r); 165 else 166 $r = -$r; 167 $this->img->FilledCircle($x1,$y1,$r); 168 } 169 170 function RoundedRectangle($x1,$y1,$x2,$y2,$r=null) { 171 list($x1,$y1) = $this->scale->Translate($x1,$y1); 172 list($x2,$y2) = $this->scale->Translate($x2,$y2); 173 174 if( $r == null ) 175 $r = 5; 176 elseif( $r >= 0 ) 177 $r = $this->scale->TranslateX($r); 178 else 179 $r = -$r; 180 $this->img->RoundedRectangle($x1,$y1,$x2,$y2,$r); 181 } 182 183 function FilledRoundedRectangle($x1,$y1,$x2,$y2,$r=null) { 184 list($x1,$y1) = $this->scale->Translate($x1,$y1); 185 list($x2,$y2) = $this->scale->Translate($x2,$y2); 186 187 if( $r == null ) 188 $r = 5; 189 elseif( $r > 0 ) 190 $r = $this->scale->TranslateX($r); 191 else 192 $r = -$r; 193 $this->img->FilledRoundedRectangle($x1,$y1,$x2,$y2,$r); 202 194 } 203 195 204 196 function ShadowRectangle($x1,$y1,$x2,$y2,$fcolor=false,$shadow_width=null,$shadow_color=array(102,102,102)) { 205 206 207 if( $shadow_width == null ) 208 209 210 211 197 list($x1,$y1) = $this->scale->Translate($x1,$y1); 198 list($x2,$y2) = $this->scale->Translate($x2,$y2); 199 if( $shadow_width == null ) 200 $shadow_width=4; 201 else 202 $shadow_width=$this->scale->TranslateX($shadow_width); 203 $this->img->ShadowRectangle($x1,$y1,$x2,$y2,$fcolor,$shadow_width,$shadow_color); 212 204 } 213 205 214 206 function SetTextAlign($halign,$valign="bottom") { 215 207 $this->img->SetTextAlign($halign,$valign="bottom"); 216 208 } 217 209 218 210 function StrokeText($x1,$y1,$txt,$dir=0,$paragraph_align="left") { 219 220 211 list($x1,$y1) = $this->scale->Translate($x1,$y1); 212 $this->img->StrokeText($x1,$y1,$txt,$dir,$paragraph_align); 221 213 } 222 214 … … 225 217 // 0=Top left, 1=top right, 2=bottom right, 3=bottom left 226 218 function IndentedRectangle($xt,$yt,$w,$h,$iw=0,$ih=0,$aCorner=3,$aFillColor="",$r=4) { 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 366 367 368 369 370 371 372 373 219 220 list($xt,$yt) = $this->scale->Translate($xt,$yt); 221 list($w,$h) = $this->scale->Translate($w,$h); 222 list($iw,$ih) = $this->scale->Translate($iw,$ih); 223 224 $xr = $xt + $w - 0; 225 $yl = $yt + $h - 0; 226 227 switch( $aCorner ) { 228 case 0: // Upper left 229 230 // Bottom line, left & right arc 231 $this->img->Line($xt+$r,$yl,$xr-$r,$yl); 232 $this->img->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180); 233 $this->img->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90); 234 235 // Right line, Top right arc 236 $this->img->Line($xr,$yt+$r,$xr,$yl-$r); 237 $this->img->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360); 238 239 // Top line, Top left arc 240 $this->img->Line($xt+$iw+$r,$yt,$xr-$r,$yt); 241 $this->img->Arc($xt+$iw+$r,$yt+$r,$r*2,$r*2,180,270); 242 243 // Left line 244 $this->img->Line($xt,$yt+$ih+$r,$xt,$yl-$r); 245 246 // Indent horizontal, Lower left arc 247 $this->img->Line($xt+$r,$yt+$ih,$xt+$iw-$r,$yt+$ih); 248 $this->img->Arc($xt+$r,$yt+$ih+$r,$r*2,$r*2,180,270); 249 250 // Indent vertical, Indent arc 251 $this->img->Line($xt+$iw,$yt+$r,$xt+$iw,$yt+$ih-$r); 252 $this->img->Arc($xt+$iw-$r,$yt+$ih-$r,$r*2,$r*2,0,90); 253 254 if( $aFillColor != '' ) { 255 $bc = $this->img->current_color_name; 256 $this->img->PushColor($aFillColor); 257 $this->img->FillToBorder($xr-$r,$yl-$r,$bc); 258 $this->img->PopColor(); 259 } 260 261 break; 262 263 case 1: // Upper right 264 265 // Bottom line, left & right arc 266 $this->img->Line($xt+$r,$yl,$xr-$r,$yl); 267 $this->img->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180); 268 $this->img->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90); 269 270 // Left line, Top left arc 271 $this->img->Line($xt,$yt+$r,$xt,$yl-$r); 272 $this->img->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270); 273 274 // Top line, Top right arc 275 $this->img->Line($xt+$r,$yt,$xr-$iw-$r,$yt); 276 $this->img->Arc($xr-$iw-$r,$yt+$r,$r*2,$r*2,270,360); 277 278 // Right line 279 $this->img->Line($xr,$yt+$ih+$r,$xr,$yl-$r); 280 281 // Indent horizontal, Lower right arc 282 $this->img->Line($xr-$iw+$r,$yt+$ih,$xr-$r,$yt+$ih); 283 $this->img->Arc($xr-$r,$yt+$ih+$r,$r*2,$r*2,270,360); 284 285 // Indent vertical, Indent arc 286 $this->img->Line($xr-$iw,$yt+$r,$xr-$iw,$yt+$ih-$r); 287 $this->img->Arc($xr-$iw+$r,$yt+$ih-$r,$r*2,$r*2,90,180); 288 289 if( $aFillColor != '' ) { 290 $bc = $this->img->current_color_name; 291 $this->img->PushColor($aFillColor); 292 $this->img->FillToBorder($xt+$r,$yl-$r,$bc); 293 $this->img->PopColor(); 294 } 295 296 break; 297 298 case 2: // Lower right 299 // Top line, Top left & Top right arc 300 $this->img->Line($xt+$r,$yt,$xr-$r,$yt); 301 $this->img->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270); 302 $this->img->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360); 303 304 // Left line, Bottom left arc 305 $this->img->Line($xt,$yt+$r,$xt,$yl-$r); 306 $this->img->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180); 307 308 // Bottom line, Bottom right arc 309 $this->img->Line($xt+$r,$yl,$xr-$iw-$r,$yl); 310 $this->img->Arc($xr-$iw-$r,$yl-$r,$r*2,$r*2,0,90); 311 312 // Right line 313 $this->img->Line($xr,$yt+$r,$xr,$yl-$ih-$r); 314 315 // Indent horizontal, Lower right arc 316 $this->img->Line($xr-$r,$yl-$ih,$xr-$iw+$r,$yl-$ih); 317 $this->img->Arc($xr-$r,$yl-$ih-$r,$r*2,$r*2,0,90); 318 319 // Indent vertical, Indent arc 320 $this->img->Line($xr-$iw,$yl-$r,$xr-$iw,$yl-$ih+$r); 321 $this->img->Arc($xr-$iw+$r,$yl-$ih+$r,$r*2,$r*2,180,270); 322 323 if( $aFillColor != '' ) { 324 $bc = $this->img->current_color_name; 325 $this->img->PushColor($aFillColor); 326 $this->img->FillToBorder($xt+$r,$yt+$r,$bc); 327 $this->img->PopColor(); 328 } 329 330 break; 331 332 case 3: // Lower left 333 // Top line, Top left & Top right arc 334 $this->img->Line($xt+$r,$yt,$xr-$r,$yt); 335 $this->img->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270); 336 $this->img->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360); 337 338 // Right line, Bottom right arc 339 $this->img->Line($xr,$yt+$r,$xr,$yl-$r); 340 $this->img->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90); 341 342 // Bottom line, Bottom left arc 343 $this->img->Line($xt+$iw+$r,$yl,$xr-$r,$yl); 344 $this->img->Arc($xt+$iw+$r,$yl-$r,$r*2,$r*2,90,180); 345 346 // Left line 347 $this->img->Line($xt,$yt+$r,$xt,$yl-$ih-$r); 348 349 // Indent horizontal, Lower left arc 350 $this->img->Line($xt+$r,$yl-$ih,$xt+$iw-$r,$yl-$ih); 351 $this->img->Arc($xt+$r,$yl-$ih-$r,$r*2,$r*2,90,180); 352 353 // Indent vertical, Indent arc 354 $this->img->Line($xt+$iw,$yl-$ih+$r,$xt+$iw,$yl-$r); 355 $this->img->Arc($xt+$iw-$r,$yl-$ih+$r,$r*2,$r*2,270,360); 356 357 if( $aFillColor != '' ) { 358 $bc = $this->img->current_color_name; 359 $this->img->PushColor($aFillColor); 360 $this->img->FillToBorder($xr-$r,$yt+$r,$bc); 361 $this->img->PopColor(); 362 } 363 364 break; 365 } 374 366 } 375 367 } … … 378 370 //=================================================== 379 371 // CLASS RectangleText 380 // Description: Draws a text paragraph inside a 372 // Description: Draws a text paragraph inside a 381 373 // rounded, possible filled, rectangle. 382 374 //=================================================== … … 388 380 private $iShadowWidth=3,$iShadowColor=''; 389 381 390 function __construct($aTxt='',$xl=0,$yt=0,$w=0,$h=0) {391 392 393 394 395 396 } 397 382 function CanvasRectangleText($aTxt='',$xl=0,$yt=0,$w=0,$h=0) { 383 $this->iTxt = new Text($aTxt); 384 $this->ix = $xl; 385 $this->iy = $yt; 386 $this->iw = $w; 387 $this->ih = $h; 388 } 389 398 390 function SetShadow($aColor='gray',$aWidth=3) { 399 400 391 $this->iShadowColor = $aColor; 392 $this->iShadowWidth = $aWidth; 401 393 } 402 394 403 395 function SetFont($FontFam,$aFontStyle,$aFontSize=12) { 404 396 $this->iTxt->SetFont($FontFam,$aFontStyle,$aFontSize); 405 397 } 406 398 407 399 function SetTxt($aTxt) { 408 400 $this->iTxt->Set($aTxt); 409 401 } 410 402 411 403 function ParagraphAlign($aParaAlign) { 412 404 $this->iParaAlign = $aParaAlign; 413 405 } 414 406 415 407 function SetFillColor($aFillColor) { 416 408 $this->iFillColor = $aFillColor; 417 409 } 418 410 419 411 function SetAutoMargin($aMargin) { 420 412 $this->iAutoBoxMargin=$aMargin; 421 413 } 422 414 423 415 function SetColor($aColor) { 424 416 $this->iColor = $aColor; 425 417 } 426 418 427 419 function SetFontColor($aColor) { 428 420 $this->iFontColor = $aColor; 429 421 } 430 422 431 423 function SetPos($xl=0,$yt=0,$w=0,$h=0) { 432 433 434 435 424 $this->ix = $xl; 425 $this->iy = $yt; 426 $this->iw = $w; 427 $this->ih = $h; 436 428 } 437 429 438 430 function Pos($xl=0,$yt=0,$w=0,$h=0) { 439 440 441 442 431 $this->ix = $xl; 432 $this->iy = $yt; 433 $this->iw = $w; 434 $this->ih = $h; 443 435 } 444 436 445 437 function Set($aTxt,$xl,$yt,$w=0,$h=0) { 446 447 448 449 450 438 $this->iTxt->Set($aTxt); 439 $this->ix = $xl; 440 $this->iy = $yt; 441 $this->iw = $w; 442 $this->ih = $h; 451 443 } 452 444 453 445 function SetCornerRadius($aRad=5) { 454 446 $this->ir = $aRad; 455 447 } 456 448 457 449 function Stroke($aImg,$scale) { 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 if( $this->iw == 0 ) 478 479 480 481 482 483 484 485 486 487 488 489 490 $aImg->PopColor(); 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 450 451 // If coordinates are specifed as negative this means we should 452 // treat them as abolsute (pixels) coordinates 453 if( $this->ix > 0 ) { 454 $this->ix = $scale->TranslateX($this->ix) ; 455 } 456 else { 457 $this->ix = -$this->ix; 458 } 459 460 if( $this->iy > 0 ) { 461 $this->iy = $scale->TranslateY($this->iy) ; 462 } 463 else { 464 $this->iy = -$this->iy; 465 } 466 467 list($this->iw,$this->ih) = $scale->Translate($this->iw,$this->ih) ; 468 469 if( $this->iw == 0 ) 470 $this->iw = round($this->iTxt->GetWidth($aImg) + $this->iAutoBoxMargin); 471 if( $this->ih == 0 ) { 472 $this->ih = round($this->iTxt->GetTextHeight($aImg) + $this->iAutoBoxMargin); 473 } 474 475 if( $this->iShadowColor != '' ) { 476 $aImg->PushColor($this->iShadowColor); 477 $aImg->FilledRoundedRectangle($this->ix+$this->iShadowWidth, 478 $this->iy+$this->iShadowWidth, 479 $this->ix+$this->iw-1+$this->iShadowWidth, 480 $this->iy+$this->ih-1+$this->iShadowWidth, 481 $this->ir); 482 $aImg->PopColor(); 483 } 484 485 if( $this->iFillColor != '' ) { 486 $aImg->PushColor($this->iFillColor); 487 $aImg->FilledRoundedRectangle($this->ix,$this->iy, 488 $this->ix+$this->iw-1, 489 $this->iy+$this->ih-1, 490 $this->ir); 491 $aImg->PopColor(); 492 } 493 494 if( $this->iColor != '' ) { 495 $aImg->PushColor($this->iColor); 496 $aImg->RoundedRectangle($this->ix,$this->iy, 497 $this->ix+$this->iw-1, 498 $this->iy+$this->ih-1, 499 $this->ir); 500 $aImg->PopColor(); 501 } 502 503 $this->iTxt->Align('center','center'); 504 $this->iTxt->ParagraphAlign($this->iParaAlign); 505 $this->iTxt->SetColor($this->iFontColor); 506 $this->iTxt->Stroke($aImg, $this->ix+$this->iw/2, $this->iy+$this->ih/2); 507 508 return array($this->iw, $this->ih); 517 509 518 510 } -
trunk/client/modules/Elezioni/grafici/jpgraph_date.php
r265 r267 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 1106 2009-02-22 20:16:35Z ljp $7 8 // Copyright (c) Asial Corporation. 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 1091 2009-01-18 22:57:40Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. 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 56 function __construct($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 70 // Description: Will round a given time stamp to an even year, month or day 71 // argument. 72 54 //--------------- 55 // CONSTRUCTOR 56 function DateScale($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 129 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 137 138 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 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 210 211 212 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 219 220 221 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 228 229 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 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
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // 6 // 7 // Created: 8 // Ver: $Id: jpgraph_errhandler.inc.php 1920 2009-12-08 10:02:26Z 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 973 2008-03-09 15:29:44Z 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 }20 13 21 14 GLOBAL $__jpg_err_locale ; … … 24 17 class ErrMsgText { 25 18 private $lt=NULL; 26 function __construct() {27 28 29 30 31 32 33 34 35 36 37 38 39 40 19 function ErrMsgText() { 20 GLOBAL $__jpg_err_locale; 21 $file = 'lang/'.$__jpg_err_locale.'.inc.php'; 22 23 // If the chosen locale doesn't exist try english 24 if( !file_exists(dirname(__FILE__).'/'.$file) ) { 25 $__jpg_err_locale = 'en'; 26 } 27 28 $file = 'lang/'.$__jpg_err_locale.'.inc.php'; 29 if( !file_exists(dirname(__FILE__).'/'.$file) ) { 30 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.'); 31 } 32 require($file); 33 $this->lt = $_jpg_messages; 41 34 } 42 35 43 36 function Get($errnbr,$a1=null,$a2=null,$a3=null,$a4=null,$a5=null) { 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 $numargs = $j; 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 37 GLOBAL $__jpg_err_locale; 38 if( !isset($this->lt[$errnbr]) ) { 39 return 'Internal error: The specified error message ('.$errnbr.') does not exist in the chosen locale ('.$__jpg_err_locale.')'; 40 } 41 $ea = $this->lt[$errnbr]; 42 $j=0; 43 if( $a1 !== null ) { 44 $argv[$j++] = $a1; 45 if( $a2 !== null ) { 46 $argv[$j++] = $a2; 47 if( $a3 !== null ) { 48 $argv[$j++] = $a3; 49 if( $a4 !== null ) { 50 $argv[$j++] = $a4; 51 if( $a5 !== null ) { 52 $argv[$j++] = $a5; 53 } 54 } 55 } 56 } 57 } 58 $numargs = $j; 59 if( $ea[1] != $numargs ) { 60 // Error message argument count do not match. 61 // Just return the error message without arguments. 62 return $ea[0]; 63 } 64 switch( $numargs ) { 65 case 1: 66 $msg = sprintf($ea[0],$argv[0]); 67 break; 68 case 2: 69 $msg = sprintf($ea[0],$argv[0],$argv[1]); 70 break; 71 case 3: 72 $msg = sprintf($ea[0],$argv[0],$argv[1],$argv[2]); 73 break; 74 case 4: 75 $msg = sprintf($ea[0],$argv[0],$argv[1],$argv[2],$argv[3]); 76 break; 77 case 5: 78 $msg = sprintf($ea[0],$argv[0],$argv[1],$argv[2],$argv[3],$argv[4]); 79 break; 80 case 0: 81 default: 82 $msg = sprintf($ea[0]); 83 break; 84 } 85 return $msg; 86 } 87 } 88 96 89 // 97 90 // A wrapper class that is used to access the specified error object … … 100 93 // 101 94 class JpGraphError { 102 private static $__iImgFlg = true; 103 private static $__iLogFile = ''; 104 private static $__iTitle = 'JpGraph Error: '; 95 private static $__jpg_err; 96 public static function Install($aErrObject) { 97 self::$__jpg_err = new $aErrObject; 98 } 105 99 public static function Raise($aMsg,$aHalt=true){ 106 throw new JpGraphException($aMsg);100 self::$__jpg_err->Raise($aMsg,$aHalt); 107 101 } 108 102 public static function SetErrLocale($aLoc) { 109 110 103 GLOBAL $__jpg_err_locale ; 104 $__jpg_err_locale = $aLoc; 111 105 } 112 106 public static function RaiseL($errnbr,$a1=null,$a2=null,$a3=null,$a4=null,$a5=null) { 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')); 107 $t = new ErrMsgText(); 108 $msg = $t->Get($errnbr,$a1,$a2,$a3,$a4,$a5); 109 self::$__jpg_err->Raise($msg); 110 } 111 } 186 112 187 113 // … … 194 120 class JpGraphErrObject { 195 121 196 protected $iTitle = "JpGraph error:";122 protected $iTitle = "JpGraph Error"; 197 123 protected $iDest = false; 198 124 199 125 200 function __construct() {201 126 function JpGraphErrObject() { 127 // Empty. Reserved for future use 202 128 } 203 129 204 130 function SetTitle($aTitle) { 205 206 } 207 208 function SetStrokeDest($aDest) { 209 $this->iDest = $aDest; 131 $this->iTitle = $aTitle; 132 } 133 134 function SetStrokeDest($aDest) { 135 $this->iDest = $aDest; 210 136 } 211 137 212 138 // If aHalt is true then execution can't continue. Typical used for fatal errors 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); 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(); 240 153 } 241 154 } … … 245 158 //============================================================== 246 159 class JpGraphErrObjectImg extends JpGraphErrObject { 247 248 function __construct() {249 parent::__construct();250 // Empty. Reserved for future use251 }252 160 253 161 function Raise($aMsg,$aHalt=true) { 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 } 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 369 278 ?> -
trunk/client/modules/Elezioni/grafici/jpgraph_error.php
r265 r267 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 1106 2009-02-22 20:16:35Z ljp $7 8 // Copyright (c) Asial Corporation. 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 781 2006-10-08 08:07:47Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. 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 //--------------- 21 // CONSTRUCTOR 22 function __construct($datay,$datax=false) { 23 parent::__construct($datay,$datax); 24 $this->numpoints /= 2; 19 //--------------- 20 // CONSTRUCTOR 21 function ErrorPlot($datay,$datax=false) { 22 $this->Plot($datay,$datax); 23 $this->numpoints /= 2; 25 24 } 26 27 28 25 //--------------- 26 // PUBLIC METHODS 27 29 28 // Gets called before any axis are stroked 30 29 function PreStrokeAdjust($graph) { 31 32 33 ++$this->numpoints; 34 35 36 37 38 $graph->SetTextScaleOff($b); 39 30 if( $this->center ) { 31 $a=0.5; $b=0.5; 32 ++$this->numpoints; 33 } else { 34 $a=0; $b=0; 35 } 36 $graph->xaxis->scale->ticks->SetXLabelOffset($a); 37 $graph->SetTextScaleOff($b); 38 //$graph->xaxis->scale->ticks->SupressMinorTickMarks(); 40 39 } 41 40 42 41 // Method description 43 42 function Stroke($img,$xscale,$yscale) { 44 45 46 $img->SetLineWeight($this->weight); 43 $numpoints=count($this->coords[0])/2; 44 $img->SetColor($this->color); 45 $img->SetLineWeight($this->weight); 47 46 48 49 50 51 52 53 54 55 else 56 47 if( isset($this->coords[1]) ) { 48 if( count($this->coords[1])!=$numpoints ) 49 JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints); 50 //("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints"); 51 else 52 $exist_x = true; 53 } 54 else 55 $exist_x = false; 57 56 58 59 if( $exist_x ) 60 61 else 62 57 for( $i=0; $i<$numpoints; ++$i) { 58 if( $exist_x ) 59 $x=$this->coords[1][$i]; 60 else 61 $x=$i; 63 62 64 if( !is_numeric($x) || 65 66 67 63 if( !is_numeric($x) || 64 !is_numeric($this->coords[0][$i*2]) || !is_numeric($this->coords[0][$i*2+1]) ) { 65 continue; 66 } 68 67 69 70 71 72 73 74 75 } 76 68 $xt = $xscale->Translate($x); 69 $yt1 = $yscale->Translate($this->coords[0][$i*2]); 70 $yt2 = $yscale->Translate($this->coords[0][$i*2+1]); 71 $img->Line($xt,$yt1,$xt,$yt2); 72 $img->Line($xt-$this->errwidth,$yt1,$xt+$this->errwidth,$yt1); 73 $img->Line($xt-$this->errwidth,$yt2,$xt+$this->errwidth,$yt2); 74 } 75 return true; 77 76 } 78 77 } // Class … … 87 86 class ErrorLinePlot extends ErrorPlot { 88 87 public $line=null; 89 90 91 function __construct($datay,$datax=false) {92 parent::__construct($datay,$datax);93 94 95 96 97 } 98 88 //--------------- 89 // CONSTRUCTOR 90 function ErrorLinePlot($datay,$datax=false) { 91 $this->ErrorPlot($datay,$datax); 92 // Calculate line coordinates as the average of the error limits 93 $n = count($datay); 94 for($i=0; $i < $n; $i+=2 ) { 95 $ly[]=($datay[$i]+$datay[$i+1])/2; 96 } 97 $this->line=new LinePlot($ly,$datax); 99 98 } 100 99 101 102 100 //--------------- 101 // PUBLIC METHODS 103 102 function Legend($graph) { 104 105 106 103 if( $this->legend != "" ) 104 $graph->legend->Add($this->legend,$this->color); 105 $this->line->Legend($graph); 107 106 } 108 107 109 108 function Stroke($img,$xscale,$yscale) { 110 111 109 parent::Stroke($img,$xscale,$yscale); 110 $this->line->Stroke($img,$xscale,$yscale); 112 111 } 113 112 } // Class … … 120 119 class LineErrorPlot extends ErrorPlot { 121 120 public $line=null; 122 123 121 //--------------- 122 // CONSTRUCTOR 124 123 // Data is (val, errdeltamin, errdeltamax) 125 function __construct($datay,$datax=false) {126 127 128 129 130 131 132 133 134 135 136 } 137 parent::__construct($ey,$datax);138 124 function LineErrorPlot($datay,$datax=false) { 125 $ly=array(); $ey=array(); 126 $n = count($datay); 127 if( $n % 3 != 0 ) { 128 JpGraphError::RaiseL(4002); 129 //('Error in input data to LineErrorPlot. Number of data points must be a multiple of 3'); 130 } 131 for($i=0; $i < $n; $i+=3 ) { 132 $ly[]=$datay[$i]; 133 $ey[]=$datay[$i]+$datay[$i+1]; 134 $ey[]=$datay[$i]+$datay[$i+2]; 135 } 136 $this->ErrorPlot($ey,$datax); 137 $this->line=new LinePlot($ly,$datax); 139 138 } 140 139 141 142 140 //--------------- 141 // PUBLIC METHODS 143 142 function Legend($graph) { 144 145 146 143 if( $this->legend != "" ) 144 $graph->legend->Add($this->legend,$this->color); 145 $this->line->Legend($graph); 147 146 } 148 147 149 148 function Stroke($img,$xscale,$yscale) { 150 151 149 parent::Stroke($img,$xscale,$yscale); 150 $this->line->Stroke($img,$xscale,$yscale); 152 151 } 153 152 } // Class -
trunk/client/modules/Elezioni/grafici/jpgraph_flags.php
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph_flags.php 1106 2009-02-22 20:16:35Z ljp $3 // File: JPGRAPH_FLAGS.PHP 4 // Description: Class Jpfile. Handles plotmarks 5 // Created: 2003-06-28 6 // Ver: $Id: jpgraph_flags.php 957 2007-12-01 14:00:29Z ljp $ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. 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 __construct($aSize=FLAGSIZE1) {271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 270 function FlagImages($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 $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 } 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 } 331 332 } 332 333 333 334 function GetIdxByName($aName,&$outFullName) { 334 335 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 } 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 } 367 370 } 368 371 } -
trunk/client/modules/Elezioni/grafici/jpgraph_gantt.php
r265 r267 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_GANTT.PHP4 // Description:JpGraph Gantt plot extension5 // Created:2001-11-126 // 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'); 3 // File: JPGRAPH_GANTT.PHP 4 // Description: JpGraph Gantt plot extension 5 // Created: 2001-11-12 6 // 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'); 14 14 require_once('jpgraph_plotmark.inc.php'); 15 15 16 16 // Maximum size for Automatic Gantt chart 17 define('MAX_GANTTIMG_SIZE_W', 8000);17 define('MAX_GANTTIMG_SIZE_W',4000); 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 __construct() {156 155 function GanttActivityInfo() { 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,$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 } 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 } 322 323 } 323 324 } … … 329 330 //=================================================== 330 331 class GanttGraph extends Graph { 331 public $scale; 332 public $scale; // Public accessible 332 333 public $hgrid=null; 333 private $iObj=array(); 334 private $iLabelHMarginFactor=0.2; 335 private $iLabelVMarginFactor=0.4; 336 private $iLayout=GANTT_FROMTOP; 334 private $iObj=array(); // Gantt objects 335 private $iLabelHMarginFactor=0.2; // 10% margin on each side of the labels 336 private $iLabelVMarginFactor=0.4; // 40% margin on top and bottom of label 337 private $iLayout=GANTT_FROMTOP; // Could also be GANTT_EVEN 337 338 private $iSimpleFont = FF_FONT1,$iSimpleFontSize=11; 338 339 private $iSimpleStyle=GANTT_RDIAG,$iSimpleColor='yellow',$iSimpleBkgColor='red'; 339 340 private $iSimpleProgressBkgColor='gray',$iSimpleProgressColor='darkgreen'; 340 341 private $iSimpleProgressStyle=GANTT_SOLID; 341 private $iZoomFactor = 1.0; 342 //--------------- 343 // CONSTRUCTOR 342 //--------------- 343 // CONSTRUCTOR 344 344 // Create a new gantt graph 345 function __construct($aWidth=0,$aHeight=0,$aCachedName="",$aTimeOut=0,$aInline=true) {346 347 348 349 350 351 352 353 354 355 parent::__construct($aWidth,$aHeight,$aCachedName,$aTimeOut,$aInline); 356 357 358 359 360 361 362 363 364 365 } 366 367 368 369 370 // 345 function GanttGraph($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 Graph::Graph($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 // Set user specified scale zoom factor when auto sizing is used 475 function SetZoomFactor($aZoom) { 476 $this->iZoomFactor = $aZoom; 477 } 478 479 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 480 475 // Set what headers should be shown 481 476 function ShowHeaders($aFlg) { 482 483 } 484 485 // Specify the fraction of the font height that should be added 477 $this->scale->ShowHeaders($aFlg); 478 } 479 480 // Specify the fraction of the font height that should be added 486 481 // as vertical margin 487 482 function SetLabelVMarginFactor($aVal) { 488 483 $this->iLabelVMarginFactor = $aVal; 489 484 } 490 485 491 486 // Synonym to the method above 492 487 function SetVMarginFactor($aVal) { 493 494 } 495 496 488 $this->iLabelVMarginFactor = $aVal; 489 } 490 491 497 492 // Add a new Gantt object 498 493 function Add($aObject) { 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 } 542 } 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 } 504 } 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 } 543 514 544 515 // Override inherit method from Graph and give a warning message 545 516 function SetScale($aAxisType,$aYMin=1,$aYMax=1,$aXMin=1,$aXMax=1) { 546 547 517 JpGraphError::RaiseL(6005); 518 //("SetScale() is not meaningfull with Gantt charts."); 548 519 } 549 520 … … 551 522 // automtically determined from the input data) 552 523 function SetDateRange($aStart,$aEnd) { 553 554 555 556 557 558 559 560 } 561 524 // Adjust the start and end so that the indicate the 525 // begining and end of respective start and end days 526 if( strpos($aStart,':') === false ) 527 $aStart = date('Y-m-d 00:00',strtotime($aStart)); 528 if( strpos($aEnd,':') === false ) 529 $aEnd = date('Y-m-d 23:59',strtotime($aEnd)); 530 $this->scale->SetRange($aStart,$aEnd); 531 } 532 562 533 // Get the maximum width of the activity titles columns for the bars 563 534 // The name is lightly misleading since we from now on can have … … 565 536 // it only supported a single label, hence the name. 566 537 function GetMaxLabelWidth() { 567 568 569 570 571 572 573 574 575 576 577 else 578 579 580 581 582 583 } 584 538 $m=10; 539 if( $this->iObj != null ) { 540 $marg = $this->scale->actinfo->iLeftColMargin+$this->scale->actinfo->iRightColMargin; 541 $n = count($this->iObj); 542 for($i=0; $i < $n; ++$i) { 543 if( !empty($this->iObj[$i]->title) ) { 544 if( $this->iObj[$i]->title->HasTabs() ) { 545 list($tot,$w) = $this->iObj[$i]->title->GetWidth($this->img,true); 546 $m=max($m,$tot); 547 } 548 else 549 $m=max($m,$this->iObj[$i]->title->GetWidth($this->img)); 550 } 551 } 552 } 553 return $m; 554 } 555 585 556 // Get the maximum height of the titles for the bars 586 557 function GetMaxLabelHeight() { 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; 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; 599 568 } 600 569 601 570 function GetMaxBarAbsHeight() { 602 603 604 605 606 607 608 609 610 return $m; 611 } 612 571 $m=0; 572 if( $this->iObj != null ) { 573 $m = $this->iObj[0]->GetAbsHeight($this->img); 574 $n = count($this->iObj); 575 for($i=1; $i < $n; ++$i) { 576 $m=max($m,$this->iObj[$i]->GetAbsHeight($this->img)); 577 } 578 } 579 return $m; 580 } 581 613 582 // Get the maximum used line number (vertical position) for bars 614 583 function GetBarMaxLineNumber() { 615 616 617 618 619 620 621 622 623 624 } 625 584 $m=1; 585 if( $this->iObj != null ) { 586 $m = $this->iObj[0]->GetLineNbr(); 587 $n = count($this->iObj); 588 for($i=1; $i < $n; ++$i) { 589 $m=max($m,$this->iObj[$i]->GetLineNbr()); 590 } 591 } 592 return $m; 593 } 594 626 595 // Get the minumum and maximum used dates for all bars 627 596 function GetBarMinMax() { 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 if( $rmax != false ) 643 644 645 if( $rmin != false ) 646 647 648 649 650 651 $max = strtotime($maxDate); 652 597 $start = 0 ; 598 $n = count($this->iObj); 599 while( $start < $n && $this->iObj[$start]->GetMaxDate() === false ) 600 ++$start; 601 if( $start >= $n ) { 602 JpgraphError::RaiseL(6006); 603 //('Cannot autoscale Gantt chart. No dated activities exist. [GetBarMinMax() start >= n]'); 604 } 605 606 $max=$this->scale->NormalizeDate($this->iObj[$start]->GetMaxDate()); 607 $min=$this->scale->NormalizeDate($this->iObj[$start]->GetMinDate()); 608 609 for($i=$start+1; $i < $n; ++$i) { 610 $rmax = $this->scale->NormalizeDate($this->iObj[$i]->GetMaxDate()); 611 if( $rmax != false ) 612 $max=Max($max,$rmax); 613 $rmin = $this->scale->NormalizeDate($this->iObj[$i]->GetMinDate()); 614 if( $rmin != false ) 615 $min=Min($min,$rmin); 616 } 617 $minDate = date("Y-m-d",$min); 618 $min = strtotime($minDate); 619 $maxDate = date("Y-m-d 23:59",$max); 620 $max = strtotime($maxDate); 621 return array($min,$max); 653 622 } 654 623 … … 659 628 function AutoSize() { 660 629 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 : 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 : 745 700 $txt = "Mon 23/6"; 746 747 748 749 750 751 752 753 701 break; 702 case DAYSTYLE_SHORTDAYDATE2 : 703 $txt = "Mon 23 Jun"; 704 break; 705 case DAYSTYLE_SHORTDAYDATE3 : 706 $txt = "Mon 23"; 707 break; 708 case DAYSTYLE_SHORTDATE1 : 754 709 $txt = "23/6"; 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 } 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 } 925 879 } 926 880 … … 930 884 // must walk through all the objects, sigh... 931 885 function GetMaxActInfoColWidth() { 932 933 934 935 936 937 938 939 940 941 if( empty($w[$j]) ) 942 943 else 944 945 946 947 886 $n = count($this->iObj); 887 if( $n == 0 ) return; 888 $w = array(); 889 $m = $this->scale->actinfo->iLeftColMargin + $this->scale->actinfo->iRightColMargin; 890 891 for( $i=0; $i < $n; ++$i ) { 892 $tmp = $this->iObj[$i]->title->GetColWidth($this->img,$m); 893 $nn = count($tmp); 894 for( $j=0; $j < $nn; ++$j ) { 895 if( empty($w[$j]) ) 896 $w[$j] = $tmp[$j]; 897 else 898 $w[$j] = max($w[$j],$tmp[$j]); 899 } 900 } 901 return $w; 948 902 } 949 903 950 904 // Stroke the gantt chart 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 } 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 } 1056 1007 } 1057 1008 1058 1009 function StrokeConstrains() { 1059 1060 1061 1062 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 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 1010 $n = count($this->iObj); 1011 1012 // Stroke all constrains 1013 for($i=0; $i < $n; ++$i) { 1014 1015 // Some gantt objects may not have constraints associated with them 1016 // for example we can add IconPlots which doesn't have this property. 1017 if( empty($this->iObj[$i]->constraints) ) continue; 1018 1019 $numConstrains = count($this->iObj[$i]->constraints); 1020 1021 for( $k = 0; $k < $numConstrains; $k++ ) { 1022 $vpos = $this->iObj[$i]->constraints[$k]->iConstrainRow; 1023 if( $vpos >= 0 ) { 1024 $c1 = $this->iObj[$i]->iConstrainPos; 1025 1026 // Find out which object is on the target row 1027 $targetobj = -1; 1028 for( $j=0; $j < $n && $targetobj == -1; ++$j ) { 1029 if( $this->iObj[$j]->iVPos == $vpos ) { 1030 $targetobj = $j; 1031 } 1032 } 1033 if( $targetobj == -1 ) { 1034 JpGraphError::RaiseL(6008,$this->iObj[$i]->iVPos,$vpos); 1035 //('You have specifed a constrain from row='.$this->iObj[$i]->iVPos.' to row='.$vpos.' which does not have any activity.'); 1036 } 1037 $c2 = $this->iObj[$targetobj]->iConstrainPos; 1038 if( count($c1) == 4 && count($c2 ) == 4) { 1039 switch( $this->iObj[$i]->constraints[$k]->iConstrainType ) { 1040 case CONSTRAIN_ENDSTART: 1041 if( $c1[1] < $c2[1] ) { 1042 $link = new GanttLink($c1[2],$c1[3],$c2[0],$c2[1]); 1043 } 1044 else { 1045 $link = new GanttLink($c1[2],$c1[1],$c2[0],$c2[3]); 1046 } 1047 $link->SetPath(3); 1048 break; 1049 case CONSTRAIN_STARTEND: 1050 if( $c1[1] < $c2[1] ) { 1051 $link = new GanttLink($c1[0],$c1[3],$c2[2],$c2[1]); 1052 } 1053 else { 1054 $link = new GanttLink($c1[0],$c1[1],$c2[2],$c2[3]); 1055 } 1056 $link->SetPath(0); 1057 break; 1058 case CONSTRAIN_ENDEND: 1059 if( $c1[1] < $c2[1] ) { 1060 $link = new GanttLink($c1[2],$c1[3],$c2[2],$c2[1]); 1061 } 1062 else { 1063 $link = new GanttLink($c1[2],$c1[1],$c2[2],$c2[3]); 1064 } 1065 $link->SetPath(1); 1066 break; 1067 case CONSTRAIN_STARTSTART: 1068 if( $c1[1] < $c2[1] ) { 1069 $link = new GanttLink($c1[0],$c1[3],$c2[0],$c2[1]); 1070 } 1071 else { 1072 $link = new GanttLink($c1[0],$c1[1],$c2[0],$c2[3]); 1073 } 1074 $link->SetPath(3); 1075 break; 1076 default: 1077 JpGraphError::RaiseL(6009,$this->iObj[$i]->iVPos,$vpos); 1078 //('Unknown constrain type specified from row='.$this->iObj[$i]->iVPos.' to row='.$vpos); 1079 break; 1080 } 1081 1082 $link->SetColor($this->iObj[$i]->constraints[$k]->iConstrainColor); 1083 $link->SetArrow($this->iObj[$i]->constraints[$k]->iConstrainArrowSize, 1084 $this->iObj[$i]->constraints[$k]->iConstrainArrowType); 1085 1086 $link->Stroke($this->img); 1087 } 1088 } 1089 } 1090 } 1140 1091 } 1141 1092 1142 1093 function GetCSIMAreas() { 1143 1144 1145 1146 1147 1148 1149 1150 1151 for( $i=$n-1; $i >= 0; --$i ) 1152 1153 1094 if( !$this->iHasStroked ) 1095 $this->Stroke(_CSIM_SPECIALFILE); 1096 1097 $csim = $this->title->GetCSIMAreas(); 1098 $csim .= $this->subtitle->GetCSIMAreas(); 1099 $csim .= $this->subsubtitle->GetCSIMAreas(); 1100 1101 $n = count($this->iObj); 1102 for( $i=$n-1; $i >= 0; --$i ) 1103 $csim .= $this->iObj[$i]->GetCSIMArea(); 1104 return $csim; 1154 1105 } 1155 1106 } … … 1177 1128 1178 1129 function GetLen() { 1179 return $this->iLen ; 1130 return $this->iLen ; 1180 1131 } 1181 1132 1182 1133 function GetImg($aIdx) { 1183 1184 1185 1186 1187 return Image::CreateFromString(base64_decode($this->iBuiltinIcon[$aIdx][1])); 1188 } 1189 1190 function __construct() {1191 1192 1193 1194 1195 $this->iBuiltinIcon[0][1]= 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 'uX1gU36dymgqYxJIJJNJT1W9QqHgNwFQBGYqo94OwHZQUuPD7ACglSvc+5n5T9m/wfJJX4U9qzEAAAAASUVORK5CYII=' ; 1210 1211 1212 1213 1214 1215 $this->iBuiltinIcon[1][1]= 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 'EOm71HUINiY7mGb95l/8jZCyQmJjMDGJjUmsdCROtZ0n/P/Z8v4Fs2MTUUf7vYoAAAAASUVORK5CYII=' ; 1229 1230 1231 1232 1233 1234 $this->iBuiltinIcon[2][1]= 1235 1236 1237 1238 1239 1240 1241 1242 1243 'avXYaXXxPwsnt0imdttCocMmZBdK7YU9D8wuNOW0nXc6QWzPsSa5naZ1beb9BbGB6dxGtMnXAAAAAElFTkSuQmCC' ; 1244 1245 1246 1247 1248 1249 $this->iBuiltinIcon[3][1]= 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 'LBbVR8feJDs0Rlv6GFKeXJ21rNRXESxMPR+CBUl0nN7PjtO+dye7Up/8v1I88bf/ixT/AO1/hZsqW+C6AAAAAElFTkSuQmCC' ; 1265 1266 1267 1268 1269 1270 $this->iBuiltinIcon[4][1]= 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 'EVgKVsutKPl0TGWGhwofoquaoKK4apsq/tH/e/kFwBMXLgAEKK4AAAAASUVORK5CYII=' ; 1281 1282 1283 1284 1285 1286 $this->iBuiltinIcon[5][1]= 1287 1288 1289 1290 1291 1292 1293 1294 'rABG1EL/BilZP8DjU2uR4U+2E49P1Z8QJmNXUzl24A9GBT0IruCfi86d9x+D12RGzt+pNAAAAABJRU5ErkJggg==' ; 1295 1296 1297 1298 1299 1300 $this->iBuiltinIcon[6][1]= 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 'p/TXyYkTJ0Xe59jf7QOyAKDWp/QXxcFQ61P4pT3ShBBcvnUHIQTjxmX19/8BCeVg+/GPpskAAAAASUVORK5CYII=' ; 1320 1321 1322 1323 1324 1325 $this->iBuiltinIcon[7][1]= 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 'opHP7/Do90Ua+WWUyezzZHObP/7cfX54/dowE1d66s8TV3oE+Mfn+L/zb4XmHPjRG9YjAAAAAElFTkSuQmCC' ; 1339 1340 1341 1342 1343 1344 $this->iBuiltinIcon[8][1]= 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 'LbQVOIcP+HG2UauH3xgwBqOz9Cc3l1tC24Fz+MvUDroeGNb5if9H/1dM/wLPCYMw9fryKgAAAABJRU5ErkJggg==' ; 1357 1358 1359 1360 1361 1362 $this->iBuiltinIcon[9][1]= 1363 1364 1365 1366 1367 1368 1369 1370 'iOsCHgAAAABJRU5ErkJggg==' ; 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 1134 if( $aIdx < 0 || $aIdx >= $this->iLen ) { 1135 JpGraphError::RaiseL(6010,$aIdx); 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 // warning.png 1144 //========================================================== 1145 $this->iBuiltinIcon[0][0]= 1043 ; 1146 $this->iBuiltinIcon[0][1]= 1147 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsSAAALEgHS3X78AAAA'. 1148 'B3RJTUUH0wgKFSgilWPhUQAAA6BJREFUeNrtl91rHFUYh5/3zMx+Z5JNUoOamCZNaqTZ6IWIkqRiQWmi1IDetHfeiCiltgXBP8AL'. 1149 '0SIUxf/AvfRSBS9EKILFFqyIH9CEmFZtPqrBJLs7c+b1YneT3WTTbNsUFPLCcAbmzPt73o9zzgzs2Z793231UOdv3w9k9Z2uzOdA'. 1150 '5+2+79yNeL7Hl7hw7oeixRMZ6PJM26W18DNAm/Vh7lR8fqh97NmMF11es1iFpMATqdirwMNA/J4DpIzkr5YsAF1PO6gIMYHRdPwl'. 1151 'oO2elmB+qH3sm7XozbkgYvy8SzYnZPtcblyM6I+5z3jQ+0vJfgpEu56BfI9vUkbyi2HZd1QJoeWRiAjBd4SDCW8SSAOy6wBHMzF7'. 1152 'YdV2A+ROuvRPLfHoiSU0EMY/cDAIhxJeGngKaN1VgHyPL7NBxI1K9P4QxBzw3K1zJ/zkG8B9uwaQ7/HNsRZv9kohBGD0o7JqMYS/'. 1153 '/ynPidQw/LrBiPBcS/yFCT95DvB2BWAy4575PaQbQKW+tPd3GCItu2odKI++YxiKu0d26oWmAD7paZU/rLz37VqIijD2YbnzNBBE'. 1154 'IBHf8K8qjL7vYhCGErEU8CTg3xXAeMp96GrJEqkyXkm9Bhui1xfsunjdGhcYLq+IzjsGmBt5YH/cmJkFq6gIqlon3u4LxdKGuCIo'. 1155 'Qu41g0E41po+2R33Xt5uz9kRIB2UTle7PnfKrROP1HD4sRjZlq0lzhwoZ6rDNeTi3nEg1si/7FT7kYQbXS6E5E65tA5uRF9tutq0'. 1156 'K/VwAF+/FbIYWt6+tjQM/AqUms7A4Wy6d7YSfSNxgMmzi0ycWWworio4QJvj4LpuL5BqugTnXzzqJsJwurrlNhJXFaavW67NRw3F'. 1157 'q+aJcCQVe9fzvJGmAY7/dPH0gi0f64OveGxa+usCuQMeZ0+kt8BVrX+qPO9Bzx0MgqBvs+a2PfDdYIf+WAjXU1ub4tqNaPPzRs8A'. 1158 'blrli+WVn79cXn0cWKl+tGx7HLc7pu3CSmnfitL+l1UihAhwjFkPQev4K/fSABjBM8JCaFuurJU+rgW41SroA8aNMVNAFtgHJCsn'. 1159 'XGy/58QVxAC9MccJtZ5kIzNlW440WrJ2ea4YPA9cAooA7i0A/gS+iqLoOpB1HOegqrYB3UBmJrAtQAJwpwPr1Ry92wVlgZsiYlW1'. 1160 'uX1gU36dymgqYxJIJJNJT1W9QqHgNwFQBGYqo94OwHZQUuPD7ACglSvc+5n5T9m/wfJJX4U9qzEAAAAASUVORK5CYII=' ; 1161 1162 //========================================================== 1163 // edit.png 1164 //========================================================== 1165 $this->iBuiltinIcon[1][0]= 959 ; 1166 $this->iBuiltinIcon[1][1]= 1167 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAFgAWABY9j+ZuwAAAAlwSFlz'. 1168 'AAALEAAACxABrSO9dQAAAAd0SU1FB9AKDAwbIEXOA6AAAAM8SURBVHicpdRPaBxlHMbx76ZvsmOTmm1dsEqQSIIsEmGVBAQjivEQ'. 1169 'PAUJngpWsAWlBw8egpQepKwplN4ULEG9CjkEyUFKlSJrWTG0IU51pCsdYW2ncUPjdtp9Z+f3vuNhu8nKbmhaf5cZeGc+PO8zf1Lc'. 1170 'm0KhkACICCKCMeaBjiLC0tLSnjNvPmuOHRpH0TZTU1M8zBi9wakzn7OFTs5sw8YYACYmJrre7HkeuVyu69qPF77hlT1XmZ0eQ03O'. 1171 'wOLJTvhBx1rLz18VmJ0eY+jVd2FxDkKXnvYLHgb97OgLzE4ON9Hzc1B1QaQzsed5O0Lta3Ec89OnR5h5McfQ+Mw2qgQUnfBOPbZ3'. 1172 'bK3l+xOvMT0+3ERLp5FNF6UEjcL32+DdVmGt5WLhDYYPZrbRqreFumXwql0S3w9tnDvLWD5PZigPpdOwuYpSCo3C8wU3UHxQdHbf'. 1173 'cZIkNM6dxcnlUM4k1eUFMlUPpUADbpkttFarHe6oYqeOr6yt4RzMQHYUcUsQVtGicHDwKprViuLDkkOtVnsHCHZVRVy/zcj1i5Af'. 1174 'h8AjdIts+hUcGcYPK3iBtKM3gD/uAzf/AdY2mmmVgy6X8YNNKmGIvyloPcB8SUin07RQ4EZHFdsdG0wkJEnEaHAJxvKEpSLeaokV'. 1175 'r4zWmhUZYLlY4b1D03y5eIEWCtS7vsciAgiIxkQRabWOrlQor66y4pUphoJb1jiO4uO5o0S3q6RSqVbiOmC7VCEgAhLSaDQ48dH7'. 1176 'vD46REY0iysegSjKQciRt99ib7qXwX0O+pG4teM6YKHLB9JMq4mTmF9/+AKA4wvLZByH7OgYL7+UY2qvw/7Bfg5kHiXjJFyv3CGO'. 1177 'Y1rof+BW4t/XLiPG0DCGr79d4XzRxRnIMn98huXSTYyJ6et1UNYQhRvcinpJq86H3wGPPPM0iBDd+QffD1g4eZjLvuG7S1Wef26E'. 1178 'J7L7eSx7gAHVg7V3MSbi6m/r93baBd6qQjerAJg/9Ql/XrvG0ON1+vv7GH3qSfY5fahUnSTpwZgIEQesaVXRPbHRG/xyJSAxMYlp'. 1179 'EOm71HUINiY7mGb95l/8jZCyQmJjMDGJjUmsdCROtZ0n/P/Z8v4Fs2MTUUf7vYoAAAAASUVORK5CYII=' ; 1180 1181 //========================================================== 1182 // endconstrain.png 1183 //========================================================== 1184 $this->iBuiltinIcon[2][0]= 666 ; 1185 $this->iBuiltinIcon[2][1]= 1186 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlz'. 1187 'AAALDwAACw8BkvkDpQAAAAd0SU1FB9ALEREILkh0+eQAAAIXSURBVHictZU9aFNRFMd/N81HX77aptJUWmp1LHRpIcWhg5sIDlUQ'. 1188 'LAXB4t7RRUpwEhy7iQ46CCIoSHcl0CFaoVARU2MFMYktadLXJNok7x2HtCExvuYFmnO4w/3gx+Gc/z1HKRTdMEdXqHbB/sgc/sic'. 1189 'nDoYAI8XwDa8o1RMLT+2hAsigtTvbIGVqhX46szUifBGswUeCPgAGB7QeLk0X4Ork+HOxo1VgSqGASjMqkn8W4r4vVtEgI/RRQEL'. 1190 'vaoGD85cl5V3nySR/S1mxWxab7f35PnntNyMJeRr9kCMqiHTy09EoeToLwggx6ymiMOD/VwcD7Oa/MHkcIiQx026WGYto5P/U+ZZ'. 1191 '7gD0QwDuT5z9N3LrVPi0Xs543eQPKkRzaS54eviJIp4tMFQFMllAWN2qcRZHBnixNM8NYD162xq8u7ePSQ+GX2Pjwxc2dB2cLtB8'. 1192 '7GgamCb0anBYBeChMtl8855CarclxU1gvViiUK4w2OMkNDnGeJ8bt9fH90yOnOkCwLFTwhzykhvtYzOWoBBbY//R3dbaNTYhf2RO'. 1193 'QpeuUMzv188MlwuHy0H13HnE48UzMcL0WAtUHX8OxZHoG1URiFw7rnLLCswuSPD1ulze/iWjT2PSf+dBXRFtVVGIvzqph0pQL7VE'. 1194 'avXYaXXxPwsnt0imdttCocMmZBdK7YU9D8wuNOW0nXc6QWzPsSa5naZ1beb9BbGB6dxGtMnXAAAAAElFTkSuQmCC' ; 1195 1196 //========================================================== 1197 // mail.png 1198 //========================================================== 1199 $this->iBuiltinIcon[3][0]= 1122 ; 1200 $this->iBuiltinIcon[3][1]= 1201 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlz'. 1202 'AAALEAAACxABrSO9dQAAAAd0SU1FB9AJHAMfFvL9OU8AAAPfSURBVHictZRdaBRXFMd/987H7tbNx8aYtGCrEexDsOBDaKHFxirb'. 1203 'h0qhsiY0ykppKq1osI99C4H2WSiFFMHWUhXBrjRi0uCmtSEUGgP1QWqhWjGkoW7M1kTX3WRn5p4+TJJNGolQ6IXDnDtz+N0z/3PP'. 1204 'UWBIpdpYa23b9g09PZ2kUrOrvmUyGVKp1Ao/mUyi56YnVgWfO/P1CihAd/dJMpmaNROIRq8BkM1m0bH6TasC3j6QXgFdXI+DR6PR'. 1205 'JX/Pno8B+KLnMKqlpUU8z8MYs2RBEDzWf9J+0RcRbMdxGBsbw/fmCXwPMUEYID4iAVp8wIRmDIHMo4yHSIBSASKC+CWE0C/PF9jU'. 1206 '3B6Cp+4M07C5FUtKGNvGwQJctPgIsgD2wRhEIqAMGB+UQYkHJgYYZD7P1HwVlmWhHcfhyk83KeRGUW4t6CgoG5SNUS4KBWgQDUov'. 1207 '7AGlwYASBVqH0Bk49dXpCviVV3dw/tI1Bvr7kMIIlh0NYUpjlF0BAYvcxSXmEVLKceHSCJm+PnbueBHbtkNwTXUNBzo6aGpq4sSZ'. 1208 'GwT5H7BsF6Wdf1GWHQAoM0upeI9PT1yioS7B7tdaSdSuw7KsUGMAy7HYsmUztTW1nMwM0txssX1rlHjjS5jy/Uq2YkK/eJuLl6/z'. 1209 'x+1xkslW6mrixGIODx8EFSlEBC0+tmXT0NhA2763iEUjnLv4C8XpUbSbAB1mKkGJ3J83Od77HW5EszvZSqK2iljMIeJaRGNuJePF'. 1210 '6mspY7BJ1DXwQnCd2fxGRq5OUCz8xt72dyhMZcn++Cu3xu9SKhdp2b4ZHWnAtTSxmIWlhcIjlksR3lNBYzlxZsb7+f7ne+xtSzOd'. 1211 'u83szH1OnThOPp/n+a0beeP1l4mvq+PU2Qyd+5PY1RuwlAqLYFaBfbTbyPSdfgaH77A//QF4f1O/vpr6RJyq+C5Kc/M8FbFxXItY'. 1212 'xOHDrvfo/fxLDnbsJBp5BowBReVWYAzabeTh5ABDw7cWoNNL3YYYNtSv57lnn6Z+Qx01VeuIuBa2DV1HD3H63BAPZu4u1WGpeLHq'. 1213 'Rh7+NcjA0O+0p4+CNwXigwnbWlQQdpuEpli+n+PIkcOc//YKuckJJFh2K2anrjFw+QZt6S6kPImIF/b+cqAJD1LihWAxC61twBTo'. 1214 'fPcQF/oGsVW5ovHQlavs2/8+uYnRVSOUgHAmmAClBIOBwKC0gPjhIRgEIX2wg7NnwpZW3d3d4vs+vu8TBMGK51rvPM9b8hdteZxd'. 1215 'LBbVR8feJDs0Rlv6GFKeXJ21rNRXESxMPR+CBUl0nN7PjtO+dye7Up/8v1I88bf/ixT/AO1/hZsqW+C6AAAAAElFTkSuQmCC' ; 1216 1217 //========================================================== 1218 // startconstrain.png 1219 //========================================================== 1220 $this->iBuiltinIcon[4][0]= 725 ; 1221 $this->iBuiltinIcon[4][1]= 1222 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlz'. 1223 'AAALDgAACw4BQL7hQQAAAAd0SU1FB9ALEREICJp5fBkAAAJSSURBVHic3dS9a1NRGMfx77kxtS+xqS9FG6p1ER3qVJpBQUUc3CRU'. 1224 'BwURVLB1EAuKIP0THJQiiNRJBK3iJl18AyeltRZa0bbaJMbUNmlNSm5e7s25j0NqpSSmyag/OMM9POdzDuflwn8djz8gClVRrVEV'. 1225 'ur4Bl1FTNSzLrSS6vbml0jUUwSXj8Qfk3PkLtLW2AeBIybmrgz3+gFzpucjlE4f4btuFTuWuCF5XDr3a3UPf6cM8GQvxzbsRAJdh'. 1226 'ScfxSywml5j7mVypN0eGEJ0tebIre+zxB6Tv7jPReS2hREpOvpmUXU+H5eC913JnNCSRVE60pUVbWoZjprR39Yq70bdqj4pW7PEH'. 1227 '5FpvL9e79jOTTHM7ssDL6CJZ08LbvAGnrpZg2mI2Z/MlZfN8IkxuSwu4V9+WIrj7zFlOHfXzKrLIi2SGh5ECKjnNVNxkQEc55vOw'. 1228 'rb6O8JLFdHyJ+ayFElUeHvjwkfteL/V7fKTSkFvIQE4DoLI2Mz/muTkTApcBKIwaN8pwIUrKw+ajWwDknAO0d/r4zFaMuRS63sWm'. 1229 'RoOdm+vRIriUYjKexrQV+t1o0YEVwfZSVJmD/dIABJuO0LG3lRFx0GOfiAELE9OgCrfU0XnIp5FwGLEy5WEAOxlR5uN+ARhP7GN3'. 1230 '5w7Gv4bQI2+xpt4jjv2nWBmIlcExE2vDAHYioszBZXw6CPE4ADoWVHmd/tuwlZR9eXYyoszBfpiNQqaAOU5+TXRN+DeeenADPT9b'. 1231 'EVgKVsutKPl0TGWGhwofoquaoKK4apsq/tH/e/kFwBMXLgAEKK4AAAAASUVORK5CYII=' ; 1232 1233 //========================================================== 1234 // calc.png 1235 //========================================================== 1236 $this->iBuiltinIcon[5][0]= 589 ; 1237 $this->iBuiltinIcon[5][1]= 1238 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAA4AIwBbgMF12wAAAAlwSFlz'. 1239 'AAALEQAACxEBf2RfkQAAAAd0SU1FB9AHBxQeFsqn0wQAAAHKSURBVHicnZWff+RAGIef3U/gcOEgUAgUCgcLhYXCwsHBQeGgUDgs'. 1240 'FgMHB4VA/4Bg4XChWFgIFIqBwkJhsRAYeOGF+TQHmWSTTbKd9pU37/x45jvfTDITXEynAbdWKVQB0NazcVm0alcL4rJaRVzm+w/e'. 1241 '3iwAkzbYRcnnYgI04GCvsxxSPabYaEdt2Ra6D0atcvvvDmyrMWBX1zPq2ircP/Tk98DiJtjV/fim6ziOCL6dDHZNhxQ3arIMsox4'. 1242 'vejleL2Ay9+jaw6A+4OSICG2cacGKhsGxg+CxeqAQS0Y7BYJvowq7iGMOhXHEfzpvpQkA9bLKgOgWKt+4Lo1mM9hs9m17QNsJ70P'. 1243 'Fjc/O52joogoX8MZKiBiAFxd9Z1vcj9wfSpUlDRNMcYQxzFpmnJ0FPH8nDe1MQaWSz9woQpWSZKEojDkeaWoKAyr1tlu+s48wfVx'. 1244 'u7n5i7jthmGIiEGcT+36PP+gFeJrxWLhb0UA/lb4ggGs1T0rZs0zwM/ZjNfilcIY5tutPxgOW3F6dUX464LrKILLiw+A7WErrl+2'. 1245 'rABG1EL/BilZP8DjU2uR4U+2E49P1Z8QJmNXUzl24A9GBT0IruCfi86d9x+D12RGzt+pNAAAAABJRU5ErkJggg==' ; 1246 1247 //========================================================== 1248 // mag.png 1249 //========================================================== 1250 $this->iBuiltinIcon[6][0]= 1415 ; 1251 $this->iBuiltinIcon[6][1]= 1252 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlz'. 1253 'AAALDAAACwwBP0AiyAAAAAd0SU1FB9ALDxEWDY6Ul+UAAAUESURBVHicdZVrbFRFGIafsyyF0nalV1R6WiggaAptlzsr1OgEogmC'. 1254 '0IgoBAsBgkIrBAPEhBj/AP6xRTCUFEwRI4jcgsitXMrFCJptJWvBNpXYbbXtbtttt6e7e86ec/yxadlCfZPJZDIz73zzzjfvR2VL'. 1255 'F7U+hf0HD2JduIzTFy6SlJRkPtkcDgdCCE65OxFC8NPV6wghyM7OptankJ2dzbSC5QghEEIgCSHog9PpNAF27dlN6miZuPgElB4/'. 1256 'nmY3O7ZtByA1NVUCkGWZweD1eklJScESTbqxuIjrd+/x6uIl5M19hSy7nfGOeUxf+g7VjU1sKi7C4/GYsiyz7tAJAD4/cRaA1tZW'. 1257 'AHIPnECUVGD1+/3U19ebG4uLeHf1akamjsIwoVnVCOvQEdLoVILYYmMo3PIxSBJflpSaDX5FAmju1QAYv/8k/s8+wLVxOU0jR2LZ'. 1258 '8sMFAApWrCApbRRDrRZirBYSLBKaoRPQw3SFernf2sav7T0Ubt4KwL4FMwF4Vu8FoHBCKgCzDhwHwLIhZ7y5a89u4m2JhA0wTdDC'. 1259 'OrphEjJMNElCHxKDEjaobmvlfo/Krj27CQQCJsCGJW8C0KXqAMxMiosQA8hZWcTFx9OsaniDKh1qmG7VoFsL0x0K06kbeAMhWpRe'. 1260 '/KpG+gwHAKUnz7Dz3BUMw6DK18nuw99wt0Nh6VdHI8RJicmETQgFg7SFwjSrGv+oKp6ghldV6dZ0ugJBlF6FmCESQ2w2AIqXLsan'. 1261 'BrFYLJTnTCBrdBqveeopWZiPFaBHUegJhegMqGgxEkHDwB/UaQ9rdIV06v0+TD2EEQjQFtAY0dsNgNvt5sialQAIIXh7wQKuVf6J'. 1262 'gTsSccPDWlQstClBGjr9eHpVWvUQncEwdYEedF8noQ4vmYmpZMTH0nTvDn25vLbrNmu7bvfnsYEbAMnhcPDgwQPzUo2LJusw/mhp'. 1263 'QwlHNO0KBAnoIfxtrcQMT2De1Mm891wyUzNlUlJSpIyMDBobGzlzr5rFM/Koq6vrP8ASGxsLwPmKcvIShjPGZiPOakE3VFB8hHwd'. 1264 'vJAxhrk5L7Ly+RQuH/sWgPdXrwFg/6HDFBUsIj09nehfbAWwPWOT9n5RYhqGwarNWxkRM5TRCfF4U1PQsDDJFk9uYhwXvzvKjm3b'. 1265 'KSsro3DJInNW5RXp7u2bAKSlpeH1esnPz6eqqgqLpmmcr3Fht9ulfaV7mZk1Bs+lM6T1djM9fhg5egDPpTNMy5TZsW07kydPYdWM'. 1266 'aXx96ixOp9O8cfUa80srmDpjOgAulytiQqZpMnvObLbt/JTtHxXj9/tRVdU0DGOAufRpevPDTeac0hJyc3NxOOawfv161lVWS6eX'. 1267 'z+9/UOCxu1VWVvaTRGv16NFfjB2bNeAQp9NpTpmSM4DcbrdL0WsGDKLRR+52uwe1yP8jb2lpYfikyY9t80n03UCWZeaXVjw1f+zs'. 1268 'Oen+/d+pqanhzp2fKSsrw+l0mi6XiyPl5ZGITdN8fAVJwjRNJEmi1qfw1kw7siyTnJxMe3s71dXV3GpoZO64DG41NPJylvxU5D/e'. 1269 'qJKsfWQD9IkaZ2RmUvr9aV4aGYcQgjfO3aWoYBF5eXm4ewIsu/CbdPz1aWb0/p1bNoOrQxlUiuiaFo3c3FyEEOx9+C9CCD6paaTW'. 1270 'p/TXyYkTJ0Xe59jf7QOyAKDWp/QXxcFQ61P4pT3ShBBcvnUHIQTjxmX19/8BCeVg+/GPpskAAAAASUVORK5CYII=' ; 1271 1272 //========================================================== 1273 // lock.png 1274 //========================================================== 1275 $this->iBuiltinIcon[7][0]= 963 ; 1276 $this->iBuiltinIcon[7][1]= 1277 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlz'. 1278 'AAALCwAACwsBbQSEtwAAAAd0SU1FB9AKAw0XDmwMOwIAAANASURBVHic7ZXfS1t3GMY/3+PprI7aisvo2YU6h6ATA8JW4rrlsF4U'. 1279 'qiAsF9mhl0N2cYTRy9G/wptAYWPD9iJtRy5asDe7cYFmyjaXOLaMImOrmkRrjL9yTmIS3120JybWQgfb3R74wuc8Lzw858vLOUpE'. 1280 'OK6pqSm2trbY39+nu7tbPHYch7m5OcLhMIA67kWj0aMQEWk6tm17rNm2LSIie3t7ksvlJJ1OSyqVkls3Z8SyLMnlcqTTaVKpFLdu'. 1281 'zmBZVj1HeY2VUti2TSQSQSml2bZdi0QirK2tMT09zerqKtlslqGhISYnJ4nHv2N+foFsNquOe9FotLlxOBwmk8lgWRbhcFgymYxY'. 1282 'liUi0mqaJoAuIi2macrdO7fFsizx3to0Te7euV1vrXtXEgqFmJmZYWVlhXK5LB4/U9kwDL784kYV0A3DYHd3m4sXRymXywKoRi8U'. 1283 'Ch01DgQCJBIJLMsiEAhIIpHw2uLz+eqtYrEYIqKZpimxWEyCwaCMjY01zYPBIJpXqVQqsby8TLVabWKA/v5+RkZGMAyDrq4ulFKH'. 1284 'HsfjcWZnZ+ns7KTRqwcnk0mKxSKFQqGJlVKtruuSTCYB6O3trW9UI/v9/iZPB/j8s2HOnX0FgHfeXpeffnzK+fWf+fijvhLs0PtG'. 1285 'D/n1OJ9+MsrlSwb3733DwMCAt1EyPj6uACYmJp56168NU6nUqFSE9nZdPE7+WqC/r4NKTagcCJVqDaUUB5VDAA4Pa9x7sMLlSwan'. 1286 'WjRmv13D7/erpaWlo604qOp88OF7LC48rPNosMq5Th+Dgxd4/XyA1rbzADi7j8jnf2P++wdcvSr8MJ/i8eomAKlUqn41OsDAQDeD'. 1287 'g++yuPCwzm/2vU8+n2a7sMFfj79mp7BBuVzioFSiXHJx3SKuW2Rzy0Up9dxnQVvODALQerqNRn4ZKe0Mvtc6TpzpmqbxalcY9Ato'. 1288 '2v06t515C73YQftZB9GLnDrt4LoujuPgOA4Ui+C6yOpXJwZrJ7r/gv4P/u+D9W7fLxTz+1ScQxrZ3atRLaVxdjbY2d184R6/sLHe'. 1289 'opHP7/Do90Ua+WWUyezzZHObP/7cfX54/dowE1d66s8TV3oE+Mfn+L/zb4XmHPjRG9YjAAAAAElFTkSuQmCC' ; 1290 1291 //========================================================== 1292 // stop.png 1293 //========================================================== 1294 $this->iBuiltinIcon[8][0]= 889 ; 1295 $this->iBuiltinIcon[8][1]= 1296 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlz'. 1297 'AAALDwAACw8BkvkDpQAAAAd0SU1FB9AJDwEvNyD6M/0AAAL2SURBVHic1ZTLaxVnGIefb2bO5OScHJN4oWrFNqcUJYoUEgU3/Qf6'. 1298 'F7gwCkIrvdBLUtqqiLhSg9bgBduFSHZdiG5ctkJ3xRDbUFwUmghNzBDanPGMkzOX79LFJGPMOSd204U/+Bbzvd/78F4H/ieJdoad'. 1299 'pZKxRFszAI/DcP0HazXY22v+HB01kee1PA/v3zfnjx4xgGnHcNZe7OvuNj+cOEF1ZATv5nUA4jhBSgmADCVWo8Ge2Of9wb18P/G7'. 1300 'oUXmYi30zqlTVEdGWLh1g2D6MYlKkXGE0Vl8aa2GEB149+4xXSzyoOIw/mimiZV/DPb25pFOj13A9gOMEChhUEqhVYqWKUk9QAUp'. 1301 'sT/P4s8PmKlUmNhQaIJbkDVqBbpw6wZ2zUc4Nm+ePku5p4eOrgpueQOFUoVCVxcD4+N07dpF9+5tVJeWGPBjhvr7WF1zC8ASgtcP'. 1302 'H8a7eZ1odh4sh50nzwCw9ZNh3M4Stutiu0X2nB/LyjZ6lcIbVTpdQU/jWVPzLADM8+ZGBRdtC7wrF/O7bR99iu26VL86iU4SAH4b'. 1303 'Po5d6AQhstMSvGyI4wS5FJBKSRwnzF8byx/u+PjzzMF1mfryQ1K/jnCahqp1xEopjFLoNEFJSRJHzF799gWHqa+/QKcSUXBI609f'. 1304 'Al5W4teQSiHDOipNUKnMI13RvnOXAIEKQixvGWya98SC560MFwPiqEG86JM8q79Q06lvhnOndy5/B6GPCUOMUu3BQgg8z0M3GmBZ'. 1305 'iGJn3v2VmsqnfzNx7FDueODuj8ROCFpjtG5TCmOYv32bJ09msP0ISydMfnAUgF8/O45RAA6WTPjlvXcB+Gn7FuRf/zAnNX6x3ARe'. 1306 'PSdmqL+P/YHkwMGDOGWDZTlQcNBRhPEComgB/YeHfq2InF1kLlXUOkpMbio1bd7aATRD/X0M1lPeSlM2vt2X1XBZjZnpLG2tmZO6'. 1307 'LbQVOIcP+HG2UauH3xgwBqOz9Cc3l1tC24Fz+MvUDroeGNb5if9H/1dM/wLPCYMw9fryKgAAAABJRU5ErkJggg==' ; 1308 1309 //========================================================== 1310 // error.png 1311 //========================================================== 1312 $this->iBuiltinIcon[9][0]= 541 ; 1313 $this->iBuiltinIcon[9][1]= 1314 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAAAaVBMVEX//////2Xy8mLl5V/Z2VvMzFi/v1WyslKlpU+ZmUyMjEh/'. 1315 'f0VyckJlZT9YWDxMTDjAwMDy8sLl5bnY2K/MzKW/v5yyspKlpYiYmH+MjHY/PzV/f2xycmJlZVlZWU9MTEXY2Ms/PzwyMjLFTjea'. 1316 'AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfTCAkUMSj9wWSOAAABLUlEQVR4'. 1317 '2s2U3ZKCMAxGjfzJanFAXFkUle/9H9JUKA1gKTN7Yy6YMjl+kNPK5rlZVSuxf1ZRnlZxFYAm93NnIKvR+MEHUgqBXx93wZGIUrSe'. 1318 'h+ctEgbpiMo3iQ4kioHCGxir/ZYUbr7AgPXs9bX0BCYM8vN/cPe8oQYzom3tVsSBMVHEoOJ5dm5F1RsIe9CtqGgRacCAkUvRtevT'. 1319 'e2pd6vOWF+gCuc/brcuhyARakBU9FgK5bUBWdHEH8tHpDsZnRTZQGzdLVvQ3CzyYZiTAmSIODEwzFCAdJopuvbpeZDisJ4pKEcjD'. 1320 'ijWPJhU1MjCo9dkYfiUVjQNTDKY6CVbR6A0niUSZjRwFanR0l9i/TyvGnFdqwStq5axMfDbyBksld/FUumvxS/Bd9VyJvQDWiiMx'. 1321 'iOsCHgAAAABJRU5ErkJggg==' ; 1322 1323 //========================================================== 1324 // openfolder.png 1325 //========================================================== 1326 $this->iBuiltinIcon[10][0]= 2040 ; 1327 $this->iBuiltinIcon[10][1]= 1328 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEANAAtwClFht71AAAAAlwSFlz'. 1329 'AAALEAAACxABrSO9dQAAAAd0SU1FB9AKDQ4RIXMeaLcAAAd1SURBVHicxZd7jBXVHcc/58zcvTNzH8vusqw8FsTsKiCUUh5WBZXG'. 1330 'GkOptmqwNWsWLKXFGlEpzZI0AWNKSy0WhDS22gJKtWlTsSRqzYIuLGB2WVvDIwQMZQMsy2OFfdzde+/OnHP6x907vJaFpjb9JZM5'. 1331 'c85Mfp/f9/s7Jxn4P4e41gtSyp78WGvtfdEAcqDFYUOH9HS0NhGk9tPb/ilSyp789UUB2AMuqhQy3Uzm7HGkE6W3dTNZMRI3EcWO'. 1332 'jf9ClLmWBT3dzW8jUsevWHCG3UpWl+IkHSxnbDh/Mcz12NevBcuWXTmf6TjnXvJ88gDmVB3pw3+nt3UzHa1NqMzBS2zqPLGFjtMN'. 1333 'ZNr3XdW+qyqwZcFk76HX/tHWfuQvyO4W7qhaHwL8efkMRlRUpPv7rqD0RrJ+FgAjLy1a20OIxZJEEuNCRfIApj+om4bGM3u2/sYU'. 1334 '9J41d8973f3Dhg1pISTV1dXXBRNJxPGFCzhou+DCQrScZOkktNaeDZjamgeZ9MgiYmVDccvHhjAzJw0NTh8/alyZMaVJicp0iTHj'. 1335 'JpgNv38tjWUhhGROdbUL9W5/MH5XCkjlcibi+KIop5LVHLKEu8A/f4r286doa9pGrGwYAAsfqbbH3b8MgO/Nqgy6WvdbbXHMkEFJ'. 1336 '4xUOMVEvaTZu3BgmvF4Yk4hz9rO/Ulr5cE9owae/rcGxohSOuiWkC2IjcIqKyPZm+OmCH7GhoZEF077EEzVVweAbJ+riEeO0Ey8y'. 1337 'UubqOHn0AOgMwvf59txnBrSp9dgxKmf/+kIP1NY8SFk0jh5ajmNHAWg5b2E5EexojGHjbiVRMoRMNs0LC+Yz46vTuH3enN7BI8fr'. 1338 'qFdo0BoVZNC9aVSQ4fNjBzEmQJiARxb+/AqYPMAVB5FsPU5v37g9OxgLhe14ZM5/ju052E6MNZvf5pmHHuLmmWOkEysxUtpGAtme'. 1339 'dtHTflJkezqQto3jFRnLssyf1jydxiiM7zNnye/c3ZsqLu2BN5fcMfzrv/hby1tPzmRUoihcTJ87CwQI2yLtDcIqsIjYUf51qBlf'. 1340 'OnScOSrdQUOMURkiXsLUzJnvbGhoBGDHH5cGyZLhOpYoNl5hqYnYEXOu5fDl9eYAHntx98n8hFHZcPHUuTSxSASAeK/CGIOxJJ0f'. 1341 'bOGNPU280dgkq6Y2yu8vfjCIlwwzr+/ZQ/PHO0gOLuO5qsftDQ2NbN+4OCgqG6WTxWVaq6zpF+DiSHWnicdylp3r6aZTWthIOrNp'. 1342 'ktHcvBu0sHX1Sm6ozB3B42d90zZA9bQp7PvgPSzXZfnqX/HS4DKKK2+x69Y/HURs26iBAN5ccsfw7774UcumF37C6f07KSt2OHji'. 1343 'DEUJD0tISjyPrrSPlAKvN0JP/U4O1NfjuhG2rvklN1SOpfXwftpbTqAyKRrff5fb7rs9V1R7m4wlz2ihA3HpmXflUWyOH2umpLiY'. 1344 'ui3v8M+6bWzfsRNbSgqkxaCkiy0simMuEWEhpcRzIhQWOIAh6tiAwS4owInFiTou5dOnMnl2NR++ujBwXEc9terD6M43nrj6LgAB'. 1345 'QnDPA9/irtkP8JRS7Hr/3T6YekDQ1pEiEXOwpUVJzCVlZZFS4mZtkpEo9ChAkDp/jtLMBACy6S4RiQghLyv5cgBRPnKUOX6smUGF'. 1346 'hSil0MYw9d77mPy1e5mnFE3batm3czvb6nYgEJztSFGU9LCRlMRdUjIH0+lnEMIwPNXD3NumoVJnrMCJaiciMUZfvQnz4QcBSvV1'. 1347 'vjE5GK358t0zmXDnDB79saLpo20c+aSRD+t25JTp7GZQwsEWFiVxl6hlUf/WO9z32CxmL1rOe6u/I2KuwGhzLQCB7/sYY9Bah3el'. 1348 'FKbvrrVm4vS7GH/7ncx+chEHGz7myCeNbPtoO0JI2jq78WIRLGkzsqs7V5SfFV5EovXACoiqqsfNpk2vo5VCWtYFBfoU0VoTBAFa'. 1349 'a7TRaK2p+MoURk+cxMzq+Rzbv49DDbuo27UTW9h0dedssPxuK+kIfN8XxhgDYPVXf2Fh4XKtFIl4AiklAlBKAYRKKK36wHIweTCt'. 1350 'NfHiEkaOn8j0+7/BmDFjaT30GbHywSxcuZkpFfFg+m1jjZ/NmnVvNfRvwd69e8WBA/uNFAIh4JVXXmHsmDHE4vEQQgjQ2lxQIm9N'. 1351 'nz35q3BEOZOHzaG2thaA4mRU+L29It+IV21CpbRQfeMFC35gRB/M2rVrubnyZmLxWJhECBEmz/eHyo/7lMlH3LFFujsthNFCCGOu'. 1352 '+WNyeUgpjSVzMKtWraKyshLPdcPEeYWCIEBdpIxSivr6eta8vI7d6+cGnhdV06pe1QP+F/QXWmuRL+jZZ58LlVmxYgUVFRV4rhtu'. 1353 '4TzMxXAA6XRaRAtsYUkx8I/JtSJQOlSwpmZpCLN8+fPcdNNoHMfB9/0QJgRoP295TlR7UVv8xxZcHMuWIZ9/Hn35vG3JEGZpzVJG'. 1354 'jx5N1IlitKahsZE1L69j69qHgx+urFX/lQL9JYdLlfnZihUhzOLFi8N3Ml1dthOxVH/f/8/CtqSJ2JaJ2JZ59J7RPsC/AViJsQS/'. 1355 'dBntAAAAAElFTkSuQmCC' ; 1356 1357 //========================================================== 1358 // folder.png 1359 //========================================================== 1409 1360 $this->iBuiltinIcon[11][0]= 1824 ; 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1361 $this->iBuiltinIcon[11][1]= 1362 'iVBORw0KGgoAAAANSUhEUgAAACIAAAAiCAYAAAA6RwvCAAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlz'. 1363 'AAALEAAACxABrSO9dQAAAAd0SU1FB9ECAQgFFyd9cRUAAAadSURBVHiczdhvbBP3Hcfx9/2xfefEOA5JoCNNnIT8AdtZmYBETJsI'. 1364 '6+jQOlQihT1AYgytqzZpD1atfyYqlT1h0lRpT7aRJ4NQpRvZGELVuo5Ua9jEJDIETQsNQyPBsUJMWGPnj//e+e72wNg4xElMR6ed'. 1365 'ZNln3933dZ/f93f6yfB/sgmrHdDV1WXlPg8NDZUDScD8LFFFEZZlWYZhWMFg0Orq6sq/gDJAfFy1iiZy9OjrVnj4JzQ1rMWqfxm/'. 1366 '309jYyNtbW0kEgnu3bvH4cOH88c/jqSKQl4/XGkd+eVtAN46up1LH92ktqYS++ZX8Pv9NDQ0sGnTJlKpFOFwmO7u7vy5IyMjeVRd'. 1367 'XV1+WEOh0IrY4pDnq6wXX/sTiCJaMkFZdRNqxefoe7VtCSqXVDqdZnZ2ltraWkzTpKqqijt3JpFlG7dvj7NzZ1f++qFQyA3EClHL'. 1368 'Ql743nFkhxPDtJAd5eTaYSVUfX09lZWVlJWVIUnSg7sVQMBCUcu4ceMGe/bsIRQK1QAzOcyykIM9P0KyudAyCWyqG8nhwqa4SkLt'. 1369 '3r0bVVVxu924XC40TUOWZUQxe97CwgIdHR2LMHIxSCaVInVvFElxE0vMY1Pd2NUKJMWNTXHlUfF//4vETJCelwbpFm3MjP2dt37x'. 1370 'AlN+PzU1NViWRSwW4+7du3g8HjweD4qi5EFAJzAExIpCANbooxhplfB0FJvTg6xWIqsVRVF6MopkU3FXPcnkJxGU0VEAdF2noqKC'. 1371 'W3/8DpnqLjzep2lubsblcjE8PExHR8fboVDID9xYFpLBDpJF0jDQIncQpWlkm31FlFLtp9PfyuW/vYQj1kPSuRW/38+lj27S2Q7v'. 1372 '/aWXUBVUffVNtm3blivVCEwsC5Eyc5iiApEpDEAXMqQdldhSiWVQHjJagud+8Fuexck/zv+K82dfoSbSCsDe75/km+4GVPd6+l5t'. 1373 '4zJHcqVUYN2yEEtZQDCSJCueRAYsPY49HsFIZVG6p25JUumFafT4DKJN4amtT7Nz38sk5+5A70HMtEYyMkFiZhxzjQ/poXrLQrRU'. 1374 'DFGEeFpAlkQkm4pRiCpIKodKzk0T/2QMh+piPjxKZPwiSkUtu/b9mNnJEWS7E8nhAmvpM60oJDkXJxqNozxRRUxPIesispBBlsXV'. 1375 'UaKEFo8gzoaJhz8s2lOmrpUG+WBhJ9/60g+Z+fDXTAXfxllRjl1VkO0OFATsYhYliiK21ZKKhhHnFveUqSdKgwAEOp7F2v51vvw8'. 1376 'XH7/N1wd/BlTweuUV65BdtgfoLTSkipsdD3tRi0VYpommUwGwzDwdT5HYEc3giAwcvH3jLz3BlPB67jWeZBEKYsSBWwpHZtNKo4q'. 1377 'aHTDsJeeiGEYWJaFZVmYpommaRiGQdPnv0bb1m8gSRL/vPIOV979aR4lmAJ2p4qCgCxksNuKJ6VNpx4NYhgGpmkuQhmGQTqdxjAM'. 1378 'qr2d7HtxEEEQuH1tkKvvvkF44tqDnrIcKJKAPf1g+LAUElq8dIiu60sApmnm93Pfzc7OYhgGrie+wFe++ztcLhcT1wf54PzPCU9c'. 1379 'w7XWjWS3IdsdOAUBWZAxrRJnTQ6SG5bce2FCpmkughmGQSqVYm5uDtnj44sH38TtdhP6+Dwf//V4ttHXrkGURZJaic8RgHQ6jWma'. 1380 'SJKUL5RLKNfIOczDKF3XSSaTRCIRhLJWntp3nGfWrSMxc5OLf3iNP4+68T9Ub9nF76lTpxgfHycajZJKpdA0LZ9GbjYV7hcDWZaF'. 1381 'pmnMz88Ti8UYunSLmu1HFi2aVkxkaGjINTY2ttDb24vX6+XQoUNs3ryZ8vJyIDu1BUFYkkxhgxeiWlpaOHPmDE1NTdTX1xe98eWG'. 1382 'JnF/9dQZCoXUYDA4AOD1ejlw4ACtra2Ul5fniwmCkEcUJiUIAoFAgL6+Pnw+H21tbfT39z8SxCS7hHsfWH9/8dL4MKqnp4eWlhac'. 1383 'TmcekEvMNE2am5s5ceIEgUCA9vZ2Tp48ic/nY3j4UsmQHCYOjJHtpeBKqL1799Lc3IzT6UTXdRobGxkYGKC9vZ3W1tZ8Ko86NJ8a'. 1384 'tXHjRo4dO8bp06fZsmULGzZsoL+/n0AggNfr5ezZs/8VpGTU5OSkc//+/acBfD4f1dXV7Nq1i4aGBs6dO4fP5+Pq1SuPBbIiyjTN'. 1385 'RUnV1dUNXLhwAa/Xy44dO4jFYgBEo9FFF1r134BPuYlk16LrAYXsAlmtq6sbKDwoFAp9m+ykuP5ZQVZF3f8tCdwCov8LyHIoAANI'. 1386 'AXf/A1TI0XCDh7OWAAAAAElFTkSuQmCC' ; 1387 1388 //========================================================== 1389 // file_important.png 1390 //========================================================== 1391 $this->iBuiltinIcon[12][0]= 1785 ; 1392 $this->iBuiltinIcon[12][1]= 1393 'iVBORw0KGgoAAAANSUhEUgAAACIAAAAiCAYAAAA6RwvCAAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlz'. 1394 'AAALDwAACw8BkvkDpQAAAAd0SU1FB9ECDAcjDeD3lKsAAAZ2SURBVHicrZhPaFzHHcc/897s7lutJCsr2VHsOHWMk0MPbsBUrcnF'. 1395 'OFRdSo6FNhdB6SGHlpDmYtJCDyoxyKe6EBxKQkt7KKL0T6ABo0NbciqigtC6PhWKI2NFqqxdSd7V2/dmftPDvPd212t55dCBYfbN'. 1396 'zpvfZ77z+/1mdhUjytWrV93Hf/24eD5z9gwiMlDjOKbb7dLtdhER2u02u7u73Lp1CxEZBw4AeZwdNQqkMd9wbziFGINJUt6rRbz5'. 1397 '1ptUq1XK5TJBEAAUMHt7e+zu7gKwvLzMysoKwAng/uNg9CgQgFKlgg1DUJ67Vqtx6tQpZmdniaIIpRTOOZRSdDoddnZ2aLfbLC8v'. 1398 's7S0xJUrV7ZGwQSj1PhhfRodVdDlMrpc5vup5Z2fvMPdu3fZ29vDWjvwztjYGPV6nVqtRqVS4dKlSywtLQFsAdOH2XwsCEApg3jl'. 1399 'w98Rak2gvYjNZpNms0mSJDjnHgkDMDc3dySYQ0Ea8w139YUX0OUKulzyg7UmCEO+l1huvHuDra0t9vf3h1TJYSqVypFhHquIrlQI'. 1400 'S5qv/uIDAC7/4bcEQYAKvK+0Wq1DVQGIoog7d+4cCeaRII35hrt+8SsEOkRlUaEyR0UpFIrXHxyMVKVUKnHv3r0jwRwaNelBjBjL'. 1401 'Sz/7KYuLiwAsLi7y4z/9kY9e+TpkCuSqjI+Po7XuAWeKXLt2DWNMUZMkwRjDhQsXWFtbK6JpCCT3jfQgxomPtPX19YHWicM5x3c2'. 1402 '73Pj3Ru8/aO3mZqaolKpoHVvyuvXr/Ppnf/Q7uzz380NPtu4y/qnG+ztd1hfX2dtbQ3gIvDnRyqSxl1UoPjyz98D4PTp0wPtq39Z'. 1403 '4fdzLxegrVaLVqvF5OQkYRgWqpRKJZ77wvNsbW1RG5tgfKLOTH2G7Z1twqBQrgrMDvhInjfSOCY5iIv+hYWFgRZArEWsZWF941Bf'. 1404 'SdMUgMnJCWpjVU4cn+HUyePM1Gc4+fRUPkzBI5w1jbukcczLv/5l0XfmzJmBFuCba38r/CRXpT+CrDUoZ0jjB4RYonJAOYRobJKT'. 1405 'z5zgqfqxAbsFSH6mpHFM2qdGXh4VnoViD6mSJF2cTQeqDqBaKVHWmonJCWpZjhkC6anR5WsffTgwaHV1FaUUq6urA/2v3f5k4LnV'. 1406 'arG9tUn3oI2YBCcWHYAxMVYs1qZEZY2SFB2aYZDGfMN9d7uJiWPSeFiNo5Rclc3NTXZbO6RpF7EJVixYA9agwwDnUiqlEPdQ3imi'. 1407 'Jo27BGHIt/7x9yEjc3Nzh27Na7c/4TdffKl4bja3ae5MUIu0T/HOEIaOpJt4gwoSsVTK4SBIY77hFtY3ABBjBiZ90rKwvsH77/+K'. 1408 't37wOhO1iPpTk4SBw1mLsz6CnKQ4l3qV+kE+t9XHlNZOk+bUJLVIE1VCcIJWQmJ6qjj30NbcXLkZMt8YPig+Z3n1G5fZ39/j/vY2'. 1409 '9ckqZT2Ochbn0p4qNkU/dDfUADdXbh4HXgRO4zNdEU0XL1784PLly5w9e7Z4SazFOfGrEotDcOKrcoJPmrYIXf/Zop3QNd1skuGt'. 1410 'cUAb2MgAxvHZTgFUq1Wmp6eZnZ0F8JlTjDduDThBnDeECEoJtbGIp6enqEblzCcEZ1PECU4yVRiOGgd0gc+AB0CZvkv1sWPHOHfu'. 1411 'HOfPn8da41cpkkltEBEPJhYnBkTQJcdYVKGkgRxCfBsq5xXNgAa2Bn+hjTOgHEKBP8pzRUxykIH4ifLJRTJAl+UMBJzPHQ6bfe/f'. 1412 'cWIzPxlUpD+zugzIZtVk1d8znBAqRxgoQuVQgSJQ3h9C5QhDRYgjUILCAzlnEdsHYTKfMTEBcP7F54YUGVmc2GLlIn6ve6v0ahSt'. 1413 '8X25TzjJ+rIx1grKpQPWR4LkGVVsMgghvS0qjPdvm5OeceOTWA5Evo2mFzkjQfL7hZPUy5yvvF/uPFQL3+nbDmsLCEmT3sTmCTNr'. 1414 'rogT6yFsOix3ftw7OwQhkvSU6CuinhCk0+kAkFoBazEEICHaHHiPVmU0gnUp4EAc1mYrF0EBVpwPi34VrBkwPxKk3W5ju/e5/c+d'. 1415 'bGUHIAIuydTIE5zfc5Wr4lJcahHnHTP3CVGm78DrgY38N+DEibp7dmYKdAQmBh1hjEFjis+9CTWYGK21H6PxPyOI0DobYwzZF/z7'. 1416 '7jadTvJtYG0kCD7lfwl49ijgT1gc0AH+dZSJA/xB+Mz/GSIvFoj/B7H1mAd8CO/zAAAAAElFTkSuQmCC' ; 1417 1418 $this->iLen = count($this->iBuiltinIcon); 1468 1419 } 1469 1420 } … … 1476 1427 //=================================================== 1477 1428 // CLASS IconImage 1478 // Description: Holds properties for an icon image 1429 // Description: Holds properties for an icon image 1479 1430 //=================================================== 1480 1431 class IconImage { … … 1484 1435 private $iScale=1.0; 1485 1436 1486 function __construct($aIcon,$aScale=1) {1487 GLOBAL $_gPredefIcons ; 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1437 function IconImage($aIcon,$aScale=1) { 1438 GLOBAL $_gPredefIcons ; 1439 if( is_string($aIcon) ) { 1440 $this->iGDImage = Graph::LoadBkgImage('',$aIcon); 1441 } 1442 elseif( is_integer($aIcon) ) { 1443 // Builtin image 1444 $this->iGDImage = $_gPredefIcons->GetImg($aIcon); 1445 } 1446 else { 1447 JpGraphError::RaiseL(6011); 1448 //('Argument to IconImage must be string or integer'); 1449 } 1450 $this->iScale = $aScale; 1451 $this->iWidth = Image::GetWidth($this->iGDImage); 1452 $this->iHeight = Image::GetHeight($this->iGDImage); 1502 1453 } 1503 1454 1504 1455 function GetWidth() { 1505 1456 return round($this->iScale*$this->iWidth); 1506 1457 } 1507 1458 1508 1459 function GetHeight() { 1509 1460 return round($this->iScale*$this->iHeight); 1510 1461 } 1511 1462 1512 1463 function SetAlign($aX='left',$aY='center') { 1513 $this->ixalign = $aX; 1514 $this->iyalign = $aY; 1464 1465 $this->ixalign = $aX; 1466 $this->iyalign = $aY; 1467 1515 1468 } 1516 1469 1517 1470 function Stroke($aImg,$x,$y) { 1518 1471 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1472 if( $this->ixalign == 'right' ) { 1473 $x -= $this->iWidth; 1474 } 1475 elseif( $this->ixalign == 'center' ) { 1476 $x -= round($this->iWidth/2*$this->iScale); 1477 } 1478 1479 if( $this->iyalign == 'bottom' ) { 1480 $y -= $this->iHeight; 1481 } 1482 elseif( $this->iyalign == 'center' ) { 1483 $y -= round($this->iHeight/2*$this->iScale); 1484 } 1485 1486 $aImg->Copy($this->iGDImage, 1487 $x,$y,0,0, 1488 round($this->iWidth*$this->iScale),round($this->iHeight*$this->iScale), 1489 $this->iWidth,$this->iHeight); 1537 1490 } 1538 1491 } … … 1547 1500 public $csimtarget='',$csimwintarget='',$csimalt=''; 1548 1501 private $iFFamily=FF_FONT1,$iFStyle=FS_NORMAL,$iFSize=10; 1549 private $iFontArray=array();1550 1502 private $iColor="black"; 1551 1503 private $iText=""; 1552 1504 private $iHAlign="left",$iVAlign="bottom"; 1553 1554 1555 // CONSTRUCTOR 1556 function __construct($aTxt='') {1557 1558 } 1559 1560 1561 // PUBLIC METHODS 1505 1506 //--------------- 1507 // CONSTRUCTOR 1508 function TextProperty($aTxt='') { 1509 $this->iText = $aTxt; 1510 } 1511 1512 //--------------- 1513 // PUBLIC METHODS 1562 1514 function Set($aTxt) { 1563 1515 $this->iText = $aTxt; 1564 1516 } 1565 1517 1566 1518 function SetCSIMTarget($aTarget,$aAltText='',$aWinTarget='') { 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1519 if( is_string($aTarget) ) 1520 $aTarget = array($aTarget); 1521 $this->csimtarget=$aTarget; 1522 1523 if( is_string($aWinTarget) ) 1524 $aWinTarget = array($aWinTarget); 1525 $this->csimwintarget=$aWinTarget; 1526 1527 if( is_string($aAltText) ) 1528 $aAltText = array($aAltText); 1577 1529 $this->csimalt=$aAltText; 1578 1579 } 1580 1530 1531 } 1532 1581 1533 function SetCSIMAlt($aAltText) { 1582 1583 1534 if( is_string($aAltText) ) 1535 $aAltText = array($aAltText); 1584 1536 $this->csimalt=$aAltText; 1585 1537 } … … 1587 1539 // Set text color 1588 1540 function SetColor($aColor) { 1589 1590 } 1591 1541 $this->iColor = $aColor; 1542 } 1543 1592 1544 function HasTabs() { 1593 1594 1595 1596 1597 1598 1599 } 1600 1545 if( is_string($this->iText) ) { 1546 return substr_count($this->iText,"\t") > 0; 1547 } 1548 elseif( is_array($this->iText) ) { 1549 return false; 1550 } 1551 } 1552 1601 1553 // Get number of tabs in string 1602 1554 function GetNbrTabs() { 1603 1604 1605 1606 1607 1608 1609 } 1610 1555 if( is_string($this->iText) ) { 1556 return substr_count($this->iText,"\t") ; 1557 } 1558 else{ 1559 return 0; 1560 } 1561 } 1562 1611 1563 // Set alignment 1612 1564 function Align($aHAlign,$aVAlign="bottom") { 1613 1614 1615 } 1616 1565 $this->iHAlign=$aHAlign; 1566 $this->iVAlign=$aVAlign; 1567 } 1568 1617 1569 // Synonym 1618 1570 function SetAlign($aHAlign,$aVAlign="bottom") { 1619 1620 1621 } 1622 1571 $this->iHAlign=$aHAlign; 1572 $this->iVAlign=$aVAlign; 1573 } 1574 1623 1575 // Specify font 1624 1576 function SetFont($aFFamily,$aFStyle=FS_NORMAL,$aFSize=10) { 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 1577 $this->iFFamily = $aFFamily; 1578 $this->iFStyle = $aFStyle; 1579 $this->iFSize = $aFSize; 1580 } 1638 1581 1639 1582 function IsColumns() { 1640 return is_array($this->iText) ; 1641 } 1642 1583 return is_array($this->iText) ; 1584 } 1585 1643 1586 // Get width of text. If text contains several columns separated by 1644 // tabs then return both the total width as well as an array with a 1587 // tabs then return both the total width as well as an array with a 1645 1588 // width for each column. 1646 1589 function GetWidth($aImg,$aUseTabs=false,$aTabExtraMargin=1.1) { 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 } 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 } 1698 1634 } 1699 1635 … … 1702 1638 // column as an array of one 1703 1639 function GetColWidth($aImg,$aMargin=0) { 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 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 1733 1662 // Get total height of text 1734 1663 function GetHeight($aImg) { 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 1664 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1665 return $aImg->GetFontHeight(); 1666 } 1667 1668 // Unhide/hide the text 1755 1669 function Show($aShow=true) { 1756 1757 } 1758 1670 $this->iShow=$aShow; 1671 } 1672 1759 1673 // Stroke text at (x,y) coordinates. If the text contains tabs then the 1760 1674 // x parameter should be an array of positions to be used for each successive 1761 1675 // tab mark. If no array is supplied then the tabs will be ignored. 1762 1676 function Stroke($aImg,$aX,$aY) { 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 } 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 } 1824 1724 } 1825 1725 } … … 1827 1727 //=================================================== 1828 1728 // CLASS HeaderProperty 1829 // Description: Data encapsulating class to hold property 1729 // Description: Data encapsulating class to hold property 1830 1730 // for each type of the scale headers 1831 1731 //=================================================== … … 1842 1742 public $iIntervall = 1; 1843 1743 1844 1845 // CONSTRUCTOR 1846 function __construct() {1847 1848 } 1849 1850 1851 // PUBLIC METHODS 1744 //--------------- 1745 // CONSTRUCTOR 1746 function HeaderProperty() { 1747 $this->grid = new LineProperty(); 1748 } 1749 1750 //--------------- 1751 // PUBLIC METHODS 1852 1752 function Show($aShow=true) { 1853 1753 $this->iShowLabels = $aShow; 1854 1754 } 1855 1755 1856 1756 function SetIntervall($aInt) { 1857 $this->iIntervall = $aInt; 1858 } 1859 1860 function SetInterval($aInt) { 1861 $this->iIntervall = $aInt; 1757 $this->iIntervall = $aInt; 1862 1758 } 1863 1759 1864 1760 function GetIntervall() { 1865 1866 } 1867 1761 return $this->iIntervall ; 1762 } 1763 1868 1764 function SetFont($aFFamily,$aFStyle=FS_NORMAL,$aFSize=10) { 1869 1870 $this->iFStyle= $aFStyle;1871 $this->iFSize= $aFSize;1765 $this->iFFamily = $aFFamily; 1766 $this->iFStyle = $aFStyle; 1767 $this->iFSize = $aFSize; 1872 1768 } 1873 1769 1874 1770 function SetFontColor($aColor) { 1875 1876 } 1877 1771 $this->iTextColor = $aColor; 1772 } 1773 1878 1774 function GetFontHeight($aImg) { 1879 1880 1775 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1776 return $aImg->GetFontHeight(); 1881 1777 } 1882 1778 1883 1779 function GetFontWidth($aImg) { 1884 1885 1780 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1781 return $aImg->GetFontWidth(); 1886 1782 } 1887 1783 1888 1784 function GetStrWidth($aImg,$aStr) { 1889 1890 1891 } 1892 1785 $aImg->SetFont($this->iFFamily,$this->iFStyle,$this->iFSize); 1786 return $aImg->GetTextWidth($aStr); 1787 } 1788 1893 1789 function SetStyle($aStyle) { 1894 1895 } 1896 1790 $this->iStyle = $aStyle; 1791 } 1792 1897 1793 function SetBackgroundColor($aColor) { 1898 1794 $this->iBackgroundColor=$aColor; 1899 1795 } 1900 1796 1901 1797 function SetFrameWeight($aWeight) { 1902 1798 $this->iFrameWeight=$aWeight; 1903 1799 } 1904 1800 1905 1801 function SetFrameColor($aColor) { 1906 1907 } 1908 1802 $this->iFrameColor=$aColor; 1803 } 1804 1909 1805 // Only used by day scale 1910 1806 function SetWeekendColor($aColor) { 1911 1912 } 1913 1807 $this->iWeekendBackgroundColor=$aColor; 1808 } 1809 1914 1810 // Only used by day scale 1915 1811 function SetSundayFontColor($aColor) { 1916 1917 } 1918 1812 $this->iSundayTextColor=$aColor; 1813 } 1814 1919 1815 function SetTitleVertMargin($aMargin) { 1920 1921 } 1922 1816 $this->iTitleVertMargin=$aMargin; 1817 } 1818 1923 1819 function SetLabelFormatString($aStr) { 1924 1820 $this->iLabelFormStr=$aStr; 1925 1821 } 1926 1822 1927 1823 function SetFormatString($aStr) { 1928 1824 $this->SetLabelFormatString($aStr); 1929 1825 } 1930 1826 … … 1948 1844 public $actinfo; 1949 1845 public $iTopPlotMargin=10,$iBottomPlotMargin=15; 1950 public $iVertLines=-1; 1846 public $iVertLines=-1; 1951 1847 public $iVertHeaderSize=-1; 1952 1848 // The width of the labels (defaults to the widest of all labels) 1953 private $iLabelWidth; 1849 private $iLabelWidth; 1954 1850 // Out image to stroke the scale to 1955 private $iImg; 1851 private $iImg; 1956 1852 private $iTableHeaderBackgroundColor="white",$iTableHeaderFrameColor="black"; 1957 1853 private $iTableHeaderFrameWeight=1; … … 1960 1856 private $iVertLayout=GANTT_EVEN; 1961 1857 private $iUsePlotWeekendBackground=true; 1962 private $iWeekStart = 1; 1963 1964 1965 // CONSTRUCTOR 1966 function __construct($aImg) {1967 $this->iImg = $aImg; 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 $this->year->SetFont(FF_FONT1,FS_BOLD); 1996 1997 1998 $this->dividerh=new LineProperty(); 1999 2000 2001 2002 2003 2004 2005 2006 2007 } 2008 2009 2010 // PUBLIC METHODS 1858 private $iWeekStart = 1; // Default to have weekends start on Monday 1859 1860 //--------------- 1861 // CONSTRUCTOR 1862 function GanttScale($aImg) { 1863 $this->iImg = $aImg; 1864 $this->iDateLocale = new DateLocale(); 1865 1866 $this->minute = new HeaderProperty(); 1867 $this->minute->SetIntervall(15); 1868 $this->minute->SetLabelFormatString('i'); 1869 $this->minute->SetFont(FF_FONT0); 1870 $this->minute->grid->SetColor("gray"); 1871 1872 $this->hour = new HeaderProperty(); 1873 $this->hour->SetFont(FF_FONT0); 1874 $this->hour->SetIntervall(6); 1875 $this->hour->SetStyle(HOURSTYLE_HM24); 1876 $this->hour->SetLabelFormatString('H:i'); 1877 $this->hour->grid->SetColor("gray"); 1878 1879 $this->day = new HeaderProperty(); 1880 $this->day->grid->SetColor("gray"); 1881 $this->day->SetLabelFormatString('l'); 1882 1883 $this->week = new HeaderProperty(); 1884 $this->week->SetLabelFormatString("w%d"); 1885 $this->week->SetFont(FF_FONT1); 1886 1887 $this->month = new HeaderProperty(); 1888 $this->month->SetFont(FF_FONT1,FS_BOLD); 1889 1890 $this->year = new HeaderProperty(); 1891 $this->year->SetFont(FF_FONT1,FS_BOLD); 1892 1893 $this->divider=new LineProperty(); 1894 $this->dividerh=new LineProperty(); 1895 $this->dividerh->SetWeight(2); 1896 $this->divider->SetWeight(6); 1897 $this->divider->SetColor('gray'); 1898 $this->divider->SetStyle('fancy'); 1899 1900 $this->tableTitle=new TextProperty(); 1901 $this->tableTitle->Show(false); 1902 $this->actinfo = new GanttActivityInfo(); 1903 } 1904 1905 //--------------- 1906 // PUBLIC METHODS 2011 1907 // Specify what headers should be visible 2012 1908 function ShowHeaders($aFlg) { 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 } 2029 1909 $this->day->Show($aFlg & GANTT_HDAY); 1910 $this->week->Show($aFlg & GANTT_HWEEK); 1911 $this->month->Show($aFlg & GANTT_HMONTH); 1912 $this->year->Show($aFlg & GANTT_HYEAR); 1913 $this->hour->Show($aFlg & GANTT_HHOUR); 1914 $this->minute->Show($aFlg & GANTT_HMIN); 1915 1916 // Make some default settings of gridlines whihc makes sense 1917 if( $aFlg & GANTT_HWEEK ) { 1918 $this->month->grid->Show(false); 1919 $this->year->grid->Show(false); 1920 } 1921 if( $aFlg & GANTT_HHOUR ) { 1922 $this->day->grid->SetColor("black"); 1923 } 1924 } 1925 2030 1926 // Should the weekend background stretch all the way down in the plotarea 2031 1927 function UseWeekendBackground($aShow) { 2032 2033 } 2034 1928 $this->iUsePlotWeekendBackground = $aShow; 1929 } 1930 2035 1931 // Have a range been specified? 2036 1932 function IsRangeSet() { 2037 2038 } 2039 1933 return $this->iStartDate!=-1 && $this->iEndDate!=-1; 1934 } 1935 2040 1936 // Should the layout be from top or even? 2041 1937 function SetVertLayout($aLayout) { 2042 2043 } 2044 1938 $this->iVertLayout = $aLayout; 1939 } 1940 2045 1941 // Which locale should be used? 2046 1942 function SetDateLocale($aLocale) { 2047 2048 } 2049 1943 $this->iDateLocale->Set($aLocale); 1944 } 1945 2050 1946 // Number of days we are showing 2051 1947 function GetNumberOfDays() { 2052 2053 } 2054 1948 return round(($this->iEndDate-$this->iStartDate)/SECPERDAY); 1949 } 1950 2055 1951 // The width of the actual plot area 2056 1952 function GetPlotWidth() { 2057 2058 1953 $img=$this->iImg; 1954 return $img->width - $img->left_margin - $img->right_margin; 2059 1955 } 2060 1956 … … 2063 1959 // widest title) 2064 1960 function SetLabelWidth($aLabelWidth) { 2065 2066 } 2067 2068 2069 1961 $this->iLabelWidth=$aLabelWidth; 1962 } 1963 1964 // Which day should the week start? 1965 // 0==Sun, 1==Monday, 2==Tuesday etc 2070 1966 function SetWeekStart($aStartDay) { 2071 2072 2073 2074 1967 $this->iWeekStart = $aStartDay % 7; 1968 1969 //Recalculate the startday since this will change the week start 1970 $this->SetRange($this->iStartDate,$this->iEndDate); 2075 1971 } 2076 1972 2077 1973 // Do we show min scale? 2078 1974 function IsDisplayMinute() { 2079 1975 return $this->minute->iShowLabels; 2080 1976 } 2081 1977 2082 1978 // Do we show day scale? 2083 1979 function IsDisplayHour() { 2084 2085 } 2086 2087 1980 return $this->hour->iShowLabels; 1981 } 1982 1983 2088 1984 // Do we show day scale? 2089 1985 function IsDisplayDay() { 2090 2091 } 2092 1986 return $this->day->iShowLabels; 1987 } 1988 2093 1989 // Do we show week scale? 2094 1990 function IsDisplayWeek() { 2095 2096 } 2097 1991 return $this->week->iShowLabels; 1992 } 1993 2098 1994 // Do we show month scale? 2099 1995 function IsDisplayMonth() { 2100 2101 } 2102 1996 return $this->month->iShowLabels; 1997 } 1998 2103 1999 // Do we show year scale? 2104 2000 function IsDisplayYear() { 2105 2001 return $this->year->iShowLabels; 2106 2002 } 2107 2003 2108 2004 // Specify spacing (in percent of bar height) between activity bars 2109 2005 function SetVertSpacing($aSpacing) { 2110 2006 $this->iVertSpacing = $aSpacing; 2111 2007 } 2112 2008 … … 2114 2010 // Always round to the nearest week boundary 2115 2011 function SetRange($aMin,$aMax) { 2116 2117 $this->iEndDate = $this->NormalizeDate($aMax); 2012 $this->iStartDate = $this->NormalizeDate($aMin); 2013 $this->iEndDate = $this->NormalizeDate($aMax); 2118 2014 } 2119 2015 … … 2123 2019 function AdjustStartEndDay() { 2124 2020 2125 2126 2127 2128 2129 2130 2131 2132 $de=strftime("%w",$this->iEndDate); 2133 2134 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 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 if( $preferredEndDay != $de ) { 2149 2150 2151 2152 $this->iEndDate = $adjdate; 2153 } 2154 } 2155 2156 // Specify background for the table title area (upper left corner of the table) 2021 if( !($this->IsDisplayYear() ||$this->IsDisplayMonth() || $this->IsDisplayWeek()) ) { 2022 // Don't adjust 2023 return; 2024 } 2025 2026 // Get day in week for start and ending date (Sun==0) 2027 $ds=strftime("%w",$this->iStartDate); 2028 $de=strftime("%w",$this->iEndDate); 2029 2030 // We want to start on iWeekStart day. But first we subtract a week 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 // to start at might be later than the start date. 2035 if( $ds < $this->iWeekStart ) 2036 $d = strtotime('-7 day',$this->iStartDate); 2037 else 2038 $d = $this->iStartDate; 2039 $adjdate = strtotime(($this->iWeekStart-$ds).' day',$d /*$this->iStartDate*/ ); 2040 $this->iStartDate = $adjdate; 2041 2042 // We want to end on the last day of the week 2043 $preferredEndDay = ($this->iWeekStart+6)%7; 2044 if( $preferredEndDay != $de ) { 2045 // Solve equivalence eq: $de + x ~ $preferredDay (mod 7) 2046 $adj = (7+($preferredEndDay - $de)) % 7; 2047 $adjdate = strtotime("+$adj day",$this->iEndDate); 2048 $this->iEndDate = $adjdate; 2049 } 2050 } 2051 2052 // Specify background for the table title area (upper left corner of the table) 2157 2053 function SetTableTitleBackground($aColor) { 2158 2159 } 2160 2161 2162 2163 2054 $this->iTableHeaderBackgroundColor = $aColor; 2055 } 2056 2057 /////////////////////////////////////// 2058 // PRIVATE Methods 2059 2164 2060 // Determine the height of all the scale headers combined 2165 2061 function GetHeaderHeight() { 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 } 2194 2062 $img=$this->iImg; 2063 $height=1; 2064 if( $this->minute->iShowLabels ) { 2065 $height += $this->minute->GetFontHeight($img); 2066 $height += $this->minute->iTitleVertMargin; 2067 } 2068 if( $this->hour->iShowLabels ) { 2069 $height += $this->hour->GetFontHeight($img); 2070 $height += $this->hour->iTitleVertMargin; 2071 } 2072 if( $this->day->iShowLabels ) { 2073 $height += $this->day->GetFontHeight($img); 2074 $height += $this->day->iTitleVertMargin; 2075 } 2076 if( $this->week->iShowLabels ) { 2077 $height += $this->week->GetFontHeight($img); 2078 $height += $this->week->iTitleVertMargin; 2079 } 2080 if( $this->month->iShowLabels ) { 2081 $height += $this->month->GetFontHeight($img); 2082 $height += $this->month->iTitleVertMargin; 2083 } 2084 if( $this->year->iShowLabels ) { 2085 $height += $this->year->GetFontHeight($img); 2086 $height += $this->year->iTitleVertMargin; 2087 } 2088 return $height; 2089 } 2090 2195 2091 // Get width (in pixels) for a single day 2196 2092 function GetDayWidth() { 2197 return ($this->GetPlotWidth()-$this->iLabelWidth+1)/$this->GetNumberOfDays(); 2093 return ($this->GetPlotWidth()-$this->iLabelWidth+1)/$this->GetNumberOfDays(); 2198 2094 } 2199 2095 2200 2096 // Get width (in pixels) for a single hour 2201 2097 function GetHourWidth() { 2202 2098 return $this->GetDayWidth() / 24 ; 2203 2099 } 2204 2100 2205 2101 function GetMinuteWidth() { 2206 2102 return $this->GetHourWidth() / 60 ; 2207 2103 } 2208 2104 2209 2105 // Nuber of days in a year 2210 2106 function GetNumDaysInYear($aYear) { 2211 2212 2213 2214 2215 } 2216 2217 // Get week number 2107 if( $this->IsLeap($aYear) ) 2108 return 366; 2109 else 2110 return 365; 2111 } 2112 2113 // Get week number 2218 2114 function GetWeekNbr($aDate,$aSunStart=true) { 2219 2220 2221 2222 2223 2224 2225 2226 2227 // version of Week Nbr calculation. 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 } 2253 2115 // We can't use the internal strftime() since it gets the weeknumber 2116 // wrong since it doesn't follow ISO on all systems since this is 2117 // system linrary dependent. 2118 // Even worse is that this works differently if we are on a Windows 2119 // or UNIX box (it even differs between UNIX boxes how strftime() 2120 // is natively implemented) 2121 // 2122 // Credit to Nicolas Hoizey <nhoizey@phpheaven.net> for this elegant 2123 // version of Week Nbr calculation. 2124 2125 $day = $this->NormalizeDate($aDate); 2126 if( $aSunStart ) 2127 $day += 60*60*24; 2128 2129 /*------------------------------------------------------------------------- 2130 According to ISO-8601 : 2131 "Week 01 of a year is per definition the first week that has the Thursday in this year, 2132 which is equivalent to the week that contains the fourth day of January. 2133 In other words, the first week of a new year is the week that has the majority of its 2134 days in the new year." 2135 2136 Be carefull, with PHP, -3 % 7 = -3, instead of 4 !!! 2137 2138 day of year = date("z", $day) + 1 2139 offset to thursday = 3 - (date("w", $day) + 6) % 7 2140 first thursday of year = 1 + (11 - date("w", mktime(0, 0, 0, 1, 1, date("Y", $day)))) % 7 2141 week number = (thursday's day of year - first thursday's day of year) / 7 + 1 2142 ---------------------------------------------------------------------------*/ 2143 2144 $thursday = $day + 60 * 60 * 24 * (3 - (date("w", $day) + 6) % 7); // take week's thursday 2145 $week = 1 + (date("z", $thursday) - (11 - date("w", mktime(0, 0, 0, 1, 1, date("Y", $thursday)))) % 7) / 7; 2146 2147 return $week; 2148 } 2149 2254 2150 // Is year a leap year? 2255 2151 function IsLeap($aYear) { 2256 2257 2258 2259 2260 2261 2152 // Is the year a leap year? 2153 //$year = 0+date("Y",$aDate); 2154 if( $aYear % 4 == 0) 2155 if( !($aYear % 100 == 0) || ($aYear % 400 == 0) ) 2156 return true; 2157 return false; 2262 2158 } 2263 2159 2264 2160 // Get current year 2265 2161 function GetYear($aDate) { 2266 2267 } 2268 2162 return 0+Date("Y",$aDate); 2163 } 2164 2269 2165 // Return number of days in a year 2270 2166 function GetNumDaysInMonth($aMonth,$aYear) { 2271 2272 2273 2274 2275 2276 2277 } 2278 2167 $days=array(31,28,31,30,31,30,31,31,30,31,30,31); 2168 $daysl=array(31,29,31,30,31,30,31,31,30,31,30,31); 2169 if( $this->IsLeap($aYear)) 2170 return $daysl[$aMonth]; 2171 else 2172 return $days[$aMonth]; 2173 } 2174 2279 2175 // Get day in month 2280 2176 function GetMonthDayNbr($aDate) { 2281 2177 return 0+strftime("%d",$aDate); 2282 2178 } 2283 2179 2284 2180 // Get day in year 2285 2181 function GetYearDayNbr($aDate) { 2286 2287 } 2288 2182 return 0+strftime("%j",$aDate); 2183 } 2184 2289 2185 // Get month number 2290 2186 function GetMonthNbr($aDate) { 2291 2292 } 2293 2294 // Translate a date to screen coordinates 2187 return 0+strftime("%m",$aDate); 2188 } 2189 2190 // Translate a date to screen coordinates (horizontal scale) 2295 2191 function TranslateDate($aDate) { 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 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 2341 2233 // What is the vertical spacing? 2342 2234 function GetVertSpacing() { 2343 2344 } 2345 2235 return $this->iVertSpacing; 2236 } 2237 2346 2238 // Convert a date to timestamp 2347 2239 function NormalizeDate($aDate) { 2348 if( $aDate === false ) return false; 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 } 2363 2364 2240 if( $aDate === false ) return false; 2241 if( is_string($aDate) ) { 2242 $t = strtotime($aDate); 2243 if( $t === FALSE || $t === -1 ) { 2244 JpGraphError::RaiseL(6016,$aDate); 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 return $t; 2248 } 2249 elseif( is_int($aDate) || is_float($aDate) ) 2250 return $aDate; 2251 else 2252 JpGraphError::RaiseL(6017,$aDate); 2253 //Unknown date format in GanttScale ($aDate)."); 2254 } 2255 2256 2365 2257 // Convert a time string to minutes 2366 2258 2367 2259 function TimeToMinutes($aTimeString) { 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 } 2382 2383 // Stroke the day scale (including gridlines) 2260 // Split in hours and minutes 2261 $pos=strpos($aTimeString,':'); 2262 $minint=60; 2263 if( $pos === false ) { 2264 $hourint = $aTimeString; 2265 $minint = 0; 2266 } 2267 else { 2268 $hourint = floor(substr($aTimeString,0,$pos)); 2269 $minint = floor(substr($aTimeString,$pos+1)); 2270 } 2271 $minint += 60 * $hourint; 2272 return $minint; 2273 } 2274 2275 // Stroke the day scale (including gridlines) 2384 2276 function StrokeMinutes($aYCoord,$getHeight=false) { 2385 $img=$this->iImg; 2386 2387 $yt=$aYCoord+$img->top_margin; 2388 2389 2390 $yb = $yt + $img->GetFontHeight() + 2391 2392 2393 2394 2395 2396 2397 2398 2399 $x = $xt; 2400 2401 2402 2403 2404 if( 60 % $minint !== 0 ) { 2277 $img=$this->iImg; 2278 $xt=$img->left_margin+$this->iLabelWidth; 2279 $yt=$aYCoord+$img->top_margin; 2280 if( $this->minute->iShowLabels ) { 2281 $img->SetFont($this->minute->iFFamily,$this->minute->iFStyle,$this->minute->iFSize); 2282 $yb = $yt + $img->GetFontHeight() + 2283 $this->minute->iTitleVertMargin + $this->minute->iFrameWeight; 2284 if( $getHeight ) { 2285 return $yb - $img->top_margin; 2286 } 2287 $xb = $img->width-$img->right_margin+1; 2288 $img->SetColor($this->minute->iBackgroundColor); 2289 $img->FilledRectangle($xt,$yt,$xb,$yb); 2290 2291 $x = $xt; 2292 $img->SetTextAlign("center"); 2293 $day = date('w',$this->iStartDate); 2294 $minint = $this->minute->GetIntervall() ; 2295 2296 if( 60 % $minint !== 0 ) { 2405 2297 JpGraphError::RaiseL(6018,$minint); 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) 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) 2479 2373 function StrokeHours($aYCoord,$getHeight=false) { 2480 $img=$this->iImg; 2481 2482 $yt=$aYCoord+$img->top_margin; 2483 2484 2485 $yb = $yt + $img->GetFontHeight() + 2486 2487 2488 2489 2490 2491 2492 2493 2494 $x = $xt; 2495 2496 2497 2498 if( 1440 % $minint !== 0 ) { 2374 $img=$this->iImg; 2375 $xt=$img->left_margin+$this->iLabelWidth; 2376 $yt=$aYCoord+$img->top_margin; 2377 if( $this->hour->iShowLabels ) { 2378 $img->SetFont($this->hour->iFFamily,$this->hour->iFStyle,$this->hour->iFSize); 2379 $yb = $yt + $img->GetFontHeight() + 2380 $this->hour->iTitleVertMargin + $this->hour->iFrameWeight; 2381 if( $getHeight ) { 2382 return $yb - $img->top_margin; 2383 } 2384 $xb = $img->width-$img->right_margin+1; 2385 $img->SetColor($this->hour->iBackgroundColor); 2386 $img->FilledRectangle($xt,$yt,$xb,$yb); 2387 2388 $x = $xt; 2389 $img->SetTextAlign("center"); 2390 $tmp = $this->hour->GetIntervall() ; 2391 $minint = $this->TimeToMinutes($tmp); 2392 if( 1440 % $minint !== 0 ) { 2499 2393 JpGraphError::RaiseL(6020,$tmp); 2500 2501 } 2502 2503 2504 2505 2506 2507 2508 2509 for($i=0; $i < $n ;++$i, $x+=$width) { 2510 2511 2512 2513 2514 $img->FilledRectangle($x,$yt+$this->day->iFrameWeight,$x+$width,$img->height-$img->bottom_margin); 2515 2516 2517 2518 2519 2520 2521 if( $day==0 ) 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 } 2556 2557 2558 2559 2560 2561 2562 2563 } 2564 2565 2566 // Stroke the day scale (including gridlines) 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 $n = ceil(24*60 / $minint ); 2398 $datestamp = $this->iStartDate; 2399 $day = date('w',$this->iStartDate); 2400 $doback = !$this->minute->iShowLabels; 2401 $width = $this->GetDayWidth() / $n ; 2402 for($j=0; $j < $this->GetNumberOfDays(); ++$j, $day += 1,$day %= 7) { 2403 for($i=0; $i < $n ;++$i, $x+=$width) { 2404 if( $day==6 || $day==0 ) { 2405 2406 $img->PushColor($this->day->iWeekendBackgroundColor); 2407 if( $this->iUsePlotWeekendBackground && $doback ) 2408 $img->FilledRectangle($x,$yt+$this->day->iFrameWeight,$x+$width,$img->height-$img->bottom_margin); 2409 else 2410 $img->FilledRectangle($x,$yt+$this->day->iFrameWeight,$x+$width,$yb-$this->day->iFrameWeight); 2411 $img->PopColor(); 2412 2413 } 2414 2415 if( $day==0 ) 2416 $img->SetColor($this->day->iSundayTextColor); 2417 else 2418 $img->SetColor($this->day->iTextColor); 2419 2420 switch( $this->hour->iStyle ) { 2421 case HOURSTYLE_HMAMPM: 2422 // 1:35pm 2423 $txt = date('g:ia',$datestamp); 2424 break; 2425 case HOURSTYLE_H24: 2426 // 13 2427 $txt = date('H',$datestamp); 2428 break; 2429 case HOURSTYLE_HAMPM: 2430 $txt = date('ga',$datestamp); 2431 break; 2432 case HOURSTYLE_CUSTOM: 2433 $txt = date($this->hour->iLabelFormStr,$datestamp); 2434 break; 2435 case HOURSTYLE_HM24: 2436 default: 2437 $txt = date('H:i',$datestamp); 2438 break; 2439 } 2440 $img->StrokeText(round($x+$width/2),round($yb-$this->hour->iTitleVertMargin),$txt); 2441 $img->SetColor($this->hour->grid->iColor); 2442 $img->SetLineWeight($this->hour->grid->iWeight); 2443 $img->Line($x,$yt,$x,$yb); 2444 $this->hour->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin); 2445 //$datestamp += $minint*60 2446 $datestamp = mktime(date('H',$datestamp),date('i',$datestamp)+$minint,0, 2447 date("m",$datestamp),date("d",$datestamp)+1,date("Y",$datestamp)); 2448 2449 } 2450 } 2451 $img->SetColor($this->hour->iFrameColor); 2452 $img->SetLineWeight($this->hour->iFrameWeight); 2453 $img->Rectangle($xt,$yt,$xb,$yb); 2454 return $yb - $img->top_margin; 2455 } 2456 return $aYCoord; 2457 } 2458 2459 2460 // Stroke the day scale (including gridlines) 2567 2461 function StrokeDays($aYCoord,$getHeight=false) { 2568 $img=$this->iImg; 2569 2570 2571 $yt=$aYCoord+$img->top_margin; 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 $x = $xt; 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 $x+$daywidth,$img->height-$img->bottom_margin); 2597 2598 2599 2600 2601 2602 2603 if( $mn[0]=='0' ) 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 break; 2639 2640 2641 2642 break; 2643 2644 2645 2646 break; 2647 2648 2649 2650 break; 2651 2652 2653 2654 break; 2655 2656 2657 2658 2659 2660 2661 2662 2663 if( $day==0 ) 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 } 2677 2678 2679 2680 2681 2682 2683 } 2684 2462 $img=$this->iImg; 2463 $daywidth=$this->GetDayWidth(); 2464 $xt=$img->left_margin+$this->iLabelWidth; 2465 $yt=$aYCoord+$img->top_margin; 2466 if( $this->day->iShowLabels ) { 2467 $img->SetFont($this->day->iFFamily,$this->day->iFStyle,$this->day->iFSize); 2468 $yb=$yt + $img->GetFontHeight() + $this->day->iTitleVertMargin + $this->day->iFrameWeight; 2469 if( $getHeight ) { 2470 return $yb - $img->top_margin; 2471 } 2472 $xb=$img->width-$img->right_margin+1; 2473 $img->SetColor($this->day->iBackgroundColor); 2474 $img->FilledRectangle($xt,$yt,$xb,$yb); 2475 2476 $x = $xt; 2477 $img->SetTextAlign("center"); 2478 $day = date('w',$this->iStartDate); 2479 $datestamp = $this->iStartDate; 2480 2481 $doback = !($this->hour->iShowLabels || $this->minute->iShowLabels); 2482 2483 setlocale(LC_TIME,$this->iDateLocale->iLocale); 2484 2485 for($i=0; $i < $this->GetNumberOfDays(); ++$i, $x+=$daywidth, $day += 1,$day %= 7) { 2486 if( $day==6 || $day==0 ) { 2487 $img->SetColor($this->day->iWeekendBackgroundColor); 2488 if( $this->iUsePlotWeekendBackground && $doback) 2489 $img->FilledRectangle($x,$yt+$this->day->iFrameWeight, 2490 $x+$daywidth,$img->height-$img->bottom_margin); 2491 else 2492 $img->FilledRectangle($x,$yt+$this->day->iFrameWeight, 2493 $x+$daywidth,$yb-$this->day->iFrameWeight); 2494 } 2495 2496 $mn = strftime('%m',$datestamp); 2497 if( $mn[0]=='0' ) 2498 $mn = $mn[1]; 2499 2500 switch( $this->day->iStyle ) { 2501 case DAYSTYLE_LONG: 2502 // "Monday" 2503 $txt = strftime('%A',$datestamp); 2504 break; 2505 case DAYSTYLE_SHORT: 2506 // "Mon" 2507 $txt = strftime('%a',$datestamp); 2508 break; 2509 case DAYSTYLE_SHORTDAYDATE1: 2510 // "Mon 23/6" 2511 $txt = strftime('%a %d/'.$mn,$datestamp); 2512 break; 2513 case DAYSTYLE_SHORTDAYDATE2: 2514 // "Mon 23 Jun" 2515 $txt = strftime('%a %d %b',$datestamp); 2516 break; 2517 case DAYSTYLE_SHORTDAYDATE3: 2518 // "Mon 23 Jun 2003" 2519 $txt = strftime('%a %d %b %Y',$datestamp); 2520 break; 2521 case DAYSTYLE_LONGDAYDATE1: 2522 // "Monday 23 Jun" 2523 $txt = strftime('%A %d %b',$datestamp); 2524 break; 2525 case DAYSTYLE_LONGDAYDATE2: 2526 // "Monday 23 Jun 2003" 2527 $txt = strftime('%A %d %b %Y',$datestamp); 2528 break; 2529 case DAYSTYLE_SHORTDATE1: 2530 // "23/6" 2531 $txt = strftime('%d/'.$mn,$datestamp); 2532 break; 2533 case DAYSTYLE_SHORTDATE2: 2534 // "23 Jun" 2535 $txt = strftime('%d %b',$datestamp); 2536 break; 2537 case DAYSTYLE_SHORTDATE3: 2538 // "Mon 23" 2539 $txt = strftime('%a %d',$datestamp); 2540 break; 2541 case DAYSTYLE_SHORTDATE4: 2542 // "23" 2543 $txt = strftime('%d',$datestamp); 2544 break; 2545 case DAYSTYLE_CUSTOM: 2546 // Custom format 2547 $txt = strftime($this->day->iLabelFormStr,$datestamp); 2548 break; 2549 case DAYSTYLE_ONELETTER: 2550 default: 2551 // "M" 2552 $txt = strftime('%A',$datestamp); 2553 $txt = strtoupper($txt[0]); 2554 break; 2555 } 2556 2557 if( $day==0 ) 2558 $img->SetColor($this->day->iSundayTextColor); 2559 else 2560 $img->SetColor($this->day->iTextColor); 2561 $img->StrokeText(round($x+$daywidth/2+1), 2562 round($yb-$this->day->iTitleVertMargin),$txt); 2563 $img->SetColor($this->day->grid->iColor); 2564 $img->SetLineWeight($this->day->grid->iWeight); 2565 $img->Line($x,$yt,$x,$yb); 2566 $this->day->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin); 2567 $datestamp = mktime(0,0,0,date("m",$datestamp),date("d",$datestamp)+1,date("Y",$datestamp)); 2568 //$datestamp += SECPERDAY; 2569 2570 } 2571 $img->SetColor($this->day->iFrameColor); 2572 $img->SetLineWeight($this->day->iFrameWeight); 2573 $img->Rectangle($xt,$yt,$xb,$yb); 2574 return $yb - $img->top_margin; 2575 } 2576 return $aYCoord; 2577 } 2578 2685 2579 // Stroke week header and grid 2686 2580 function StrokeWeeks($aYCoord,$getHeight=false) { 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 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 2762 2655 // Format the mont scale header string 2763 2656 function GetMonthLabel($aMonthNbr,$year) { 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 } 2791 2657 $sn = $this->iDateLocale->GetShortMonthName($aMonthNbr); 2658 $ln = $this->iDateLocale->GetLongMonthName($aMonthNbr); 2659 switch($this->month->iStyle) { 2660 case MONTHSTYLE_SHORTNAME: 2661 $m=$sn; 2662 break; 2663 case MONTHSTYLE_LONGNAME: 2664 $m=$ln; 2665 break; 2666 case MONTHSTYLE_SHORTNAMEYEAR2: 2667 $m=$sn." '".substr("".$year,2); 2668 break; 2669 case MONTHSTYLE_SHORTNAMEYEAR4: 2670 $m=$sn." ".$year; 2671 break; 2672 case MONTHSTYLE_LONGNAMEYEAR2: 2673 $m=$ln." '".substr("".$year,2); 2674 break; 2675 case MONTHSTYLE_LONGNAMEYEAR4: 2676 $m=$ln." ".$year; 2677 break; 2678 case MONTHSTYLE_FIRSTLETTER: 2679 $m=$sn[0]; 2680 break; 2681 } 2682 return $m; 2683 } 2684 2792 2685 // Stroke month scale and gridlines 2793 2686 function StrokeMonths($aYCoord,$getHeight=false) { 2794 2795 $img=$this->iImg; 2796 2797 $yt=$aYCoord+$img->top_margin; 2798 2799 2800 return $yb - $img->top_margin; 2801 2802 $monthnbr = $this->GetMonthNbr($this->iStartDate)-1; 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 if( $this->GetMonthNbr($this->iStartDate) == $this->GetMonthNbr($this->iEndDate) 2814 2815 2816 } 2817 2818 2819 2820 2821 2822 2823 $img->SetColor($this->month->iTextColor); 2824 2825 2826 2827 2828 2829 2830 $img->SetColor($this->month->grid->iColor); 2831 2832 2833 2834 2835 2836 2837 2838 2839 $monthwidth=$this->GetDayWidth()*$this->GetNumDaysInMonth($monthnbr,$year); 2840 2841 2842 2843 2844 2845 $img->SetColor($this->month->iTextColor); 2846 2847 2848 2849 2850 } 2851 2852 2853 $img->Rectangle($xt,$yt,$xb,$yb); 2854 2855 2856 2687 if( $this->month->iShowLabels ) { 2688 $img=$this->iImg; 2689 $img->SetFont($this->month->iFFamily,$this->month->iFStyle,$this->month->iFSize); 2690 $yt=$aYCoord+$img->top_margin; 2691 $yb=$yt + $img->GetFontHeight() + $this->month->iTitleVertMargin + $this->month->iFrameWeight; 2692 if( $getHeight ) { 2693 return $yb - $img->top_margin; 2694 } 2695 $monthnbr = $this->GetMonthNbr($this->iStartDate)-1; 2696 $xt=$img->left_margin+$this->iLabelWidth; 2697 $xb=$img->width-$img->right_margin+1; 2698 2699 $img->SetColor($this->month->iBackgroundColor); 2700 $img->FilledRectangle($xt,$yt,$xb,$yb); 2701 2702 $img->SetLineWeight($this->month->grid->iWeight); 2703 $img->SetColor($this->month->iTextColor); 2704 $year = 0+strftime("%Y",$this->iStartDate); 2705 $img->SetTextAlign("center"); 2706 if( $this->GetMonthNbr($this->iStartDate) == $this->GetMonthNbr($this->iEndDate) 2707 && $this->GetYear($this->iStartDate)==$this->GetYear($this->iEndDate) ) { 2708 $monthwidth=$this->GetDayWidth()*($this->GetMonthDayNbr($this->iEndDate) - $this->GetMonthDayNbr($this->iStartDate) + 1); 2709 } 2710 else { 2711 $monthwidth=$this->GetDayWidth()*($this->GetNumDaysInMonth($monthnbr,$year)-$this->GetMonthDayNbr($this->iStartDate)+1); 2712 } 2713 // Is it enough space to stroke the first month? 2714 $monthName = $this->GetMonthLabel($monthnbr,$year); 2715 if( $monthwidth >= 1.2*$img->GetTextWidth($monthName) ) { 2716 $img->SetColor($this->month->iTextColor); 2717 $img->StrokeText(round($xt+$monthwidth/2+1), 2718 round($yb-$this->month->iTitleVertMargin), 2719 $monthName); 2720 } 2721 $x = $xt + $monthwidth; 2722 while( $x < $xb ) { 2723 $img->SetColor($this->month->grid->iColor); 2724 $img->Line($x,$yt,$x,$yb); 2725 $this->month->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin); 2726 $monthnbr++; 2727 if( $monthnbr==12 ) { 2728 $monthnbr=0; 2729 $year++; 2730 } 2731 $monthName = $this->GetMonthLabel($monthnbr,$year); 2732 $monthwidth=$this->GetDayWidth()*$this->GetNumDaysInMonth($monthnbr,$year); 2733 if( $x + $monthwidth < $xb ) 2734 $w = $monthwidth; 2735 else 2736 $w = $xb-$x; 2737 if( $w >= 1.2*$img->GetTextWidth($monthName) ) { 2738 $img->SetColor($this->month->iTextColor); 2739 $img->StrokeText(round($x+$w/2+1), 2740 round($yb-$this->month->iTitleVertMargin),$monthName); 2741 } 2742 $x += $monthwidth; 2743 } 2744 $img->SetColor($this->month->iFrameColor); 2745 $img->SetLineWeight($this->month->iFrameWeight); 2746 $img->Rectangle($xt,$yt,$xb,$yb); 2747 return $yb-$img->top_margin; 2748 } 2749 return $aYCoord; 2857 2750 } 2858 2751 2859 2752 // Stroke year scale and gridlines 2860 2753 function StrokeYears($aYCoord,$getHeight=false) { 2861 2862 $img=$this->iImg; 2863 $yt=$aYCoord+$img->top_margin; 2864 2865 2866 2867 2868 return $yb - $img->top_margin; 2869 2870 2871 2872 2873 $year = $this->GetYear($this->iStartDate); 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 // The space for a year must be at least 20% bigger than the actual text 2884 2885 2886 $img->SetColor($this->year->iTextColor); 2887 2888 2889 2890 2891 2892 2893 $img->SetColor($this->year->grid->iColor); 2894 2895 2896 2897 $yearwidth=$this->GetDayWidth()*$this->GetNumDaysInYear($year); 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 $img->Rectangle($xt,$yt,$xb,$yb); 2913 2914 2915 2916 } 2917 2754 if( $this->year->iShowLabels ) { 2755 $img=$this->iImg; 2756 $yt=$aYCoord+$img->top_margin; 2757 $img->SetFont($this->year->iFFamily,$this->year->iFStyle,$this->year->iFSize); 2758 $yb=$yt + $img->GetFontHeight() + $this->year->iTitleVertMargin + $this->year->iFrameWeight; 2759 2760 if( $getHeight ) { 2761 return $yb - $img->top_margin; 2762 } 2763 2764 $xb=$img->width-$img->right_margin+1; 2765 $xt=$img->left_margin+$this->iLabelWidth; 2766 $year = $this->GetYear($this->iStartDate); 2767 $img->SetColor($this->year->iBackgroundColor); 2768 $img->FilledRectangle($xt,$yt,$xb,$yb); 2769 $img->SetLineWeight($this->year->grid->iWeight); 2770 $img->SetTextAlign("center"); 2771 if( $year == $this->GetYear($this->iEndDate) ) 2772 $yearwidth=$this->GetDayWidth()*($this->GetYearDayNbr($this->iEndDate)-$this->GetYearDayNbr($this->iStartDate)+1); 2773 else 2774 $yearwidth=$this->GetDayWidth()*($this->GetNumDaysInYear($year)-$this->GetYearDayNbr($this->iStartDate)+1); 2775 2776 // The space for a year must be at least 20% bigger than the actual text 2777 // so we allow 10% margin on each side 2778 if( $yearwidth >= 1.20*$img->GetTextWidth("".$year) ) { 2779 $img->SetColor($this->year->iTextColor); 2780 $img->StrokeText(round($xt+$yearwidth/2+1), 2781 round($yb-$this->year->iTitleVertMargin), 2782 $year); 2783 } 2784 $x = $xt + $yearwidth; 2785 while( $x < $xb ) { 2786 $img->SetColor($this->year->grid->iColor); 2787 $img->Line($x,$yt,$x,$yb); 2788 $this->year->grid->Stroke($img,$x,$yb,$x,$img->height-$img->bottom_margin); 2789 $year += 1; 2790 $yearwidth=$this->GetDayWidth()*$this->GetNumDaysInYear($year); 2791 if( $x + $yearwidth < $xb ) 2792 $w = $yearwidth; 2793 else 2794 $w = $xb-$x; 2795 if( $w >= 1.2*$img->GetTextWidth("".$year) ) { 2796 $img->SetColor($this->year->iTextColor); 2797 $img->StrokeText(round($x+$w/2+1), 2798 round($yb-$this->year->iTitleVertMargin), 2799 $year); 2800 } 2801 $x += $yearwidth; 2802 } 2803 $img->SetColor($this->year->iFrameColor); 2804 $img->SetLineWeight($this->year->iFrameWeight); 2805 $img->Rectangle($xt,$yt,$xb,$yb); 2806 return $yb-$img->top_margin; 2807 } 2808 return $aYCoord; 2809 } 2810 2918 2811 // Stroke table title (upper left corner) 2919 2812 function StrokeTableHeaders($aYBottom) { 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 $this->tableTitle->Stroke($img,$xt+($xb-$xt)/2+1,$yt+2); 2931 2932 2933 2934 2935 2936 2937 2938 2939 // Draw the horizontal dividing line 2940 $this->dividerh->Stroke($img,$xt,$yb,$img->width-$img->right_margin,$yb); 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 $tmp = $this->divider->iWeight; 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2813 $img=$this->iImg; 2814 $xt=$img->left_margin; 2815 $yt=$img->top_margin; 2816 $xb=$xt+$this->iLabelWidth; 2817 $yb=$aYBottom+$img->top_margin; 2818 2819 if( $this->tableTitle->iShow ) { 2820 $img->SetColor($this->iTableHeaderBackgroundColor); 2821 $img->FilledRectangle($xt,$yt,$xb,$yb); 2822 $this->tableTitle->Align("center","top"); 2823 $this->tableTitle->Stroke($img,$xt+($xb-$xt)/2+1,$yt+2); 2824 $img->SetColor($this->iTableHeaderFrameColor); 2825 $img->SetLineWeight($this->iTableHeaderFrameWeight); 2826 $img->Rectangle($xt,$yt,$xb,$yb); 2827 } 2828 2829 $this->actinfo->Stroke($img,$xt,$yt,$xb,$yb,$this->tableTitle->iShow); 2830 2831 2832 // Draw the horizontal dividing line 2833 $this->dividerh->Stroke($img,$xt,$yb,$img->width-$img->right_margin,$yb); 2834 2835 // Draw the vertical dividing line 2836 // We do the width "manually" since we want the line only to grow 2837 // to the left 2838 $fancy = $this->divider->iStyle == 'fancy' ; 2839 if( $fancy ) { 2840 $this->divider->iStyle = 'solid'; 2841 } 2842 2843 $tmp = $this->divider->iWeight; 2844 $this->divider->iWeight=1; 2845 $y = $img->height-$img->bottom_margin; 2846 for($i=0; $i < $tmp; ++$i ) { 2847 $this->divider->Stroke($img,$xb-$i,$yt,$xb-$i,$y); 2848 } 2849 2850 // Should we draw "fancy" divider 2851 if( $fancy ) { 2852 $img->SetLineWeight(1); 2853 $img->SetColor($this->iTableHeaderFrameColor); 2854 $img->Line($xb,$yt,$xb,$y); 2855 $img->Line($xb-$tmp+1,$yt,$xb-$tmp+1,$y); 2856 $img->SetColor('white'); 2857 $img->Line($xb-$tmp+2,$yt,$xb-$tmp+2,$y); 2858 } 2966 2859 } 2967 2860 2968 2861 // Main entry point to stroke scale 2969 2862 function Stroke() { 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 } 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 } 3014 2905 } 3015 2906 … … 3026 2917 public $iConstrainArrowType; 3027 2918 3028 3029 3030 function __construct($aRow,$aType,$aColor,$aArrowSize,$aArrowType){3031 3032 3033 3034 3035 2919 //--------------- 2920 // CONSTRUCTOR 2921 function GanttConstraint($aRow,$aType,$aColor,$aArrowSize,$aArrowType){ 2922 $this->iConstrainType = $aType; 2923 $this->iConstrainRow = $aRow; 2924 $this->iConstrainColor=$aColor; 2925 $this->iConstrainArrowSize=$aArrowSize; 2926 $this->iConstrainArrowType=$aArrowType; 3036 2927 } 3037 2928 } … … 3045 2936 public $title,$caption; 3046 2937 public $csimarea='',$csimtarget='',$csimwintarget='',$csimalt=''; 3047 public $constraints = array(); 2938 public $constraints = array(); 3048 2939 public $iCaptionMargin=5; 3049 2940 public $iConstrainPos=array(); 3050 protected $iStart=""; 3051 public $iVPos=0; 3052 protected $iLabelLeftMargin=2; 3053 3054 function __construct() {3055 3056 $this->title->Align('left','center');3057 2941 protected $iStart=""; // Start date 2942 public $iVPos=0; // Vertical position 2943 protected $iLabelLeftMargin=2; // Title margin 2944 2945 function GanttPlotObject() { 2946 $this->title = new TextProperty(); 2947 $this->title->Align("left","center"); 2948 $this->caption = new TextProperty(); 3058 2949 } 3059 2950 3060 2951 function GetCSIMArea() { 3061 2952 return $this->csimarea; 3062 2953 } 3063 2954 3064 2955 function SetCSIMTarget($aTarget,$aAlt='',$aWinTarget='') { 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 2956 if( !is_string($aTarget) ) { 2957 $tv = substr(var_export($aTarget,true),0,40); 2958 JpGraphError::RaiseL(6024,$tv); 2959 //('CSIM Target must be specified as a string.'."\nStart of target is:\n$tv"); 2960 } 2961 if( !is_string($aAlt) ) { 2962 $tv = substr(var_export($aAlt,true),0,40); 2963 JpGraphError::RaiseL(6025,$tv); 2964 //('CSIM Alt text must be specified as a string.'."\nStart of alt text is:\n$tv"); 2965 } 3075 2966 3076 2967 $this->csimtarget=$aTarget; … … 3078 2969 $this->csimalt=$aAlt; 3079 2970 } 3080 2971 3081 2972 function SetCSIMAlt($aAlt) { 3082 3083 3084 3085 3086 2973 if( !is_string($aAlt) ) { 2974 $tv = substr(var_export($aAlt,true),0,40); 2975 JpGraphError::RaiseL(6025,$tv); 2976 //('CSIM Alt text must be specified as a string.'."\nStart of alt text is:\n$tv"); 2977 } 3087 2978 $this->csimalt=$aAlt; 3088 2979 } 3089 2980 3090 2981 function SetConstrain($aRow,$aType,$aColor='black',$aArrowSize=ARROW_S2,$aArrowType=ARROWT_SOLID) { 3091 2982 $this->constraints[] = new GanttConstraint($aRow, $aType, $aColor, $aArrowSize, $aArrowType); 3092 2983 } 3093 2984 3094 2985 function SetConstrainPos($xt,$yt,$xb,$yb) { 3095 $this->iConstrainPos = array($xt,$yt,$xb,$yb); 3096 } 3097 2986 $this->iConstrainPos = array($xt,$yt,$xb,$yb); 2987 } 2988 2989 /* 2990 function GetConstrain() { 2991 return array($this->iConstrainRow,$this->iConstrainType); 2992 } 2993 */ 2994 3098 2995 function GetMinDate() { 3099 2996 return $this->iStart; 3100 2997 } 3101 2998 3102 2999 function GetMaxDate() { 3103 3104 } 3105 3000 return $this->iStart; 3001 } 3002 3106 3003 function SetCaptionMargin($aMarg) { 3107 3004 $this->iCaptionMargin=$aMarg; 3108 3005 } 3109 3006 3110 3007 function GetAbsHeight($aImg) { 3111 return 0; 3112 } 3113 3008 return 0; 3009 } 3010 3114 3011 function GetLineNbr() { 3115 3012 return $this->iVPos; 3116 3013 } 3117 3014 3118 3015 function SetLabelLeftMargin($aOff) { 3119 3120 } 3016 $this->iLabelLeftMargin=$aOff; 3017 } 3121 3018 3122 3019 function StrokeActInfo($aImg,$aScale,$aYPos) { 3123 3124 3125 $this->title->Stroke($aImg,$cols,$aYPos); 3020 $cols=array(); 3021 $aScale->actinfo->GetColStart($aImg,$cols,true); 3022 $this->title->Stroke($aImg,$cols,$aYPos); 3126 3023 } 3127 3024 } … … 3129 3026 //=================================================== 3130 3027 // CLASS Progress 3131 // Holds parameters for the progress indicator 3028 // Holds parameters for the progress indicator 3132 3029 // displyed within a bar 3133 3030 //=================================================== … … 3136 3033 public $iPattern=GANTT_SOLID; 3137 3034 public $iColor="black", $iFillColor='black'; 3138 public $iDensity=98, $iHeight=0.65; 3139 3035 public $iDensity=98, $iHeight=0.65; 3036 3140 3037 function Set($aProg) { 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; 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; 3152 3048 } 3153 3049 3154 3050 function SetFillColor($aColor) { 3155 3156 } 3157 3051 $this->iFillColor = $aColor; 3052 } 3053 3158 3054 function SetHeight($aHeight) { 3159 3055 $this->iHeight = $aHeight; 3160 3056 } 3161 3057 } … … 3175 3071 private $iStart=0; // 0=from left margin, 1=just along header 3176 3072 3177 function __construct() {3178 3179 3180 3181 } 3182 3073 function HorizontalGridLine() { 3074 $this->line = new LineProperty(); 3075 $this->line->SetColor('gray@0.4'); 3076 $this->line->SetStyle('dashed'); 3077 } 3078 3183 3079 function Show($aShow=true) { 3184 3080 $this->iShow = $aShow; 3185 3081 } 3186 3082 3187 3083 function SetRowFillColor($aColor1,$aColor2='') { 3188 3189 3084 $this->iRowColor1 = $aColor1; 3085 $this->iRowColor2 = $aColor2; 3190 3086 } 3191 3087 3192 3088 function SetStart($aStart) { 3193 3089 $this->iStart = $aStart; 3194 3090 } 3195 3091 3196 3092 function Stroke($aImg,$aScale) { 3197 3198 3199 3200 3201 3202 3203 3204 3205 $xb = round($aScale->TranslateDate($limen)); 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 $yb = round($aScale->TranslateVertPos(1)); 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3093 3094 if( ! $this->iShow ) return; 3095 3096 // Get horizontal width of line 3097 /* 3098 $limst = $aScale->iStartDate; 3099 $limen = $aScale->iEndDate; 3100 $xt = round($aScale->TranslateDate($aScale->iStartDate)); 3101 $xb = round($aScale->TranslateDate($limen)); 3102 */ 3103 3104 if( $this->iStart === 0 ) { 3105 $xt = $aImg->left_margin-1; 3106 } 3107 else { 3108 $xt = round($aScale->TranslateDate($aScale->iStartDate))+1; 3109 } 3110 3111 $xb = $aImg->width-$aImg->right_margin; 3112 3113 $yt = round($aScale->TranslateVertPos(0)); 3114 $yb = round($aScale->TranslateVertPos(1)); 3115 $height = $yb - $yt; 3116 3117 // Loop around for all lines in the chart 3118 for($i=0; $i < $aScale->iVertLines; ++$i ) { 3119 $yb = $yt - $height; 3120 $this->line->Stroke($aImg,$xt,$yb,$xb,$yb); 3121 if( $this->iRowColor1 !== '' ) { 3122 if( $i % 2 == 0 ) { 3123 $aImg->PushColor($this->iRowColor1); 3124 $aImg->FilledRectangle($xt,$yt,$xb,$yb); 3125 $aImg->PopColor(); 3126 } 3127 elseif( $this->iRowColor2 !== '' ) { 3128 $aImg->PushColor($this->iRowColor2); 3129 $aImg->FilledRectangle($xt,$yt,$xb,$yb); 3130 $aImg->PopColor(); 3131 } 3132 } 3133 $yt = round($aScale->TranslateVertPos($i+1)); 3134 } 3135 $yb = $yt - $height; 3136 $this->line->Stroke($aImg,$xt,$yb,$xb,$yb); 3241 3137 } 3242 3138 } … … 3255 3151 private $iShadow=false,$iShadowColor="darkgray",$iShadowWidth=1,$iShadowFrame="black"; 3256 3152 private $iPattern=GANTT_RDIAG,$iPatternColor="blue",$iPatternDensity=95; 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 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 3291 3183 function SetShadow($aShadow=true,$aColor="gray") { 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 3184 $this->iShadow=$aShadow; 3185 $this->iShadowColor=$aColor; 3186 } 3187 3302 3188 function GetMaxDate() { 3303 3304 } 3305 3189 return $this->iEnd; 3190 } 3191 3306 3192 function SetHeight($aHeight) { 3307 3193 $this->iHeightFactor = $aHeight; 3308 3194 } 3309 3195 3310 3196 function SetColor($aColor) { 3311 3197 $this->iFrameColor = $aColor; 3312 3198 } 3313 3199 3314 3200 function SetFillColor($aColor) { 3315 3201 $this->iFillColor = $aColor; 3316 3202 } 3317 3203 3318 3204 function GetAbsHeight($aImg) { 3319 3320 3321 3322 3323 if( $this->leftMark->show ) 3324 3325 if( $this->rightMark->show ) 3326 3327 3328 3329 3330 3331 } 3332 3333 function SetPattern($aPattern,$aColor="blue",$aDensity=95) { 3334 3335 3336 3205 if( is_int($this->iHeightFactor) || $this->leftMark->show || $this->rightMark->show ) { 3206 $m=-1; 3207 if( is_int($this->iHeightFactor) ) 3208 $m = $this->iHeightFactor; 3209 if( $this->leftMark->show ) 3210 $m = max($m,$this->leftMark->width*2); 3211 if( $this->rightMark->show ) 3212 $m = max($m,$this->rightMark->width*2); 3213 return $m; 3214 } 3215 else 3216 return -1; 3217 } 3218 3219 function SetPattern($aPattern,$aColor="blue",$aDensity=95) { 3220 $this->iPattern = $aPattern; 3221 $this->iPatternColor = $aColor; 3222 $this->iPatternDensity = $aDensity; 3337 3223 } 3338 3224 3339 3225 function Stroke($aImg,$aScale) { 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 } 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 } 3510 3384 } 3511 3385 } … … 3517 3391 class MileStone extends GanttPlotObject { 3518 3392 public $mark; 3519 3520 3521 // CONSTRUCTOR 3522 function __construct($aVPos,$aLabel,$aDate,$aCaption="") {3523 GanttPlotObject::__construct();3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 } 3537 3538 3539 // PUBLIC METHODS 3540 3393 3394 //--------------- 3395 // CONSTRUCTOR 3396 function MileStone($aVPos,$aLabel,$aDate,$aCaption="") { 3397 GanttPlotObject::GanttPlotObject(); 3398 $this->caption->Set($aCaption); 3399 $this->caption->Align("left","center"); 3400 $this->caption->SetFont(FF_FONT1,FS_BOLD); 3401 $this->title->Set($aLabel); 3402 $this->title->SetColor("darkred"); 3403 $this->mark = new PlotMark(); 3404 $this->mark->SetWidth(10); 3405 $this->mark->SetType(MARK_DIAMOND); 3406 $this->mark->SetColor("darkred"); 3407 $this->mark->SetFillColor("darkred"); 3408 $this->iVPos = $aVPos; 3409 $this->iStart = $aDate; 3410 } 3411 3412 //--------------- 3413 // PUBLIC METHODS 3414 3541 3415 function GetAbsHeight($aImg) { 3542 3543 } 3544 3416 return max($this->title->GetHeight($aImg),$this->mark->GetWidth()); 3417 } 3418 3545 3419 function Stroke($aImg,$aScale) { 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 $this->mark->Stroke($aImg,$x,$y); 3600 3601 3602 3420 // Put the mark in the middle at the middle of the day 3421 $d = $aScale->NormalizeDate($this->iStart)+SECPERDAY/2; 3422 $x = $aScale->TranslateDate($d); 3423 $y = $aScale->TranslateVertPos($this->iVPos)-($aScale->GetVertSpacing()/2); 3424 3425 $this->StrokeActInfo($aImg,$aScale,$y); 3426 3427 // CSIM for title 3428 if( ! empty($this->title->csimtarget) ) { 3429 3430 $yt = round($y - $this->title->GetHeight($aImg)/2); 3431 $yb = round($y + $this->title->GetHeight($aImg)/2); 3432 3433 $colwidth = $this->title->GetColWidth($aImg); 3434 $colstarts=array(); 3435 $aScale->actinfo->GetColStart($aImg,$colstarts,true); 3436 $n = min(count($colwidth),count($this->title->csimtarget)); 3437 for( $i=0; $i < $n; ++$i ) { 3438 $title_xt = $colstarts[$i]; 3439 $title_xb = $title_xt + $colwidth[$i]; 3440 $coords = "$title_xt,$yt,$title_xb,$yt,$title_xb,$yb,$title_xt,$yb"; 3441 3442 if( !empty($this->title->csimtarget[$i]) ) { 3443 3444 $this->csimarea .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->title->csimtarget[$i]."\""; 3445 3446 if( !empty($this->title->csimwintarget[$i]) ) { 3447 $this->csimarea .= "target=\"".$this->title->csimwintarget[$i]."\""; 3448 } 3449 3450 if( ! empty($this->title->csimalt[$i]) ) { 3451 $tmp = $this->title->csimalt[$i]; 3452 $this->csimarea .= " title=\"$tmp\" alt=\"$tmp\" "; 3453 } 3454 $this->csimarea .= " />\n"; 3455 } 3456 } 3457 } 3458 3459 if( $d < $aScale->iStartDate || $d > $aScale->iEndDate ) 3460 return; 3461 3462 // Remember the coordinates for any constrains linking to 3463 // this milestone 3464 $w = $this->mark->GetWidth()/2; 3465 $this->SetConstrainPos($x,round($y-$w),$x,round($y+$w)); 3466 3467 // Setup CSIM 3468 if( $this->csimtarget != '' ) { 3469 $this->mark->SetCSIMTarget( $this->csimtarget ); 3470 $this->mark->SetCSIMAlt( $this->csimalt ); 3471 } 3472 3473 $this->mark->Stroke($aImg,$x,$y); 3474 $this->caption->Stroke($aImg,$x+$this->mark->width/2+$this->iCaptionMargin,$y); 3475 3476 $this->csimarea .= $this->mark->GetCSIMAreas(); 3603 3477 } 3604 3478 } … … 3611 3485 3612 3486 class TextPropertyBelow extends TextProperty { 3613 function __construct($aTxt='') {3614 parent::__construct($aTxt);3487 function TextPropertyBelow($aTxt='') { 3488 parent::TextProperty($aTxt); 3615 3489 } 3616 3490 3617 3491 function GetColWidth($aImg,$aMargin=0) { 3618 3619 3620 3492 // Since we are not stroking the title in the columns 3493 // but rather under the graph we want this to return 0. 3494 return array(0); 3621 3495 } 3622 3496 } … … 3624 3498 class GanttVLine extends GanttPlotObject { 3625 3499 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 } 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 3651 3517 3652 3518 function SetDayOffset($aOff=0.5) { 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 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 3660 3525 function SetTitleMargin($aMarg) { 3661 $this->title_margin = $aMarg; 3662 } 3663 3664 function SetWeight($aWeight) { 3665 $this->iLine->SetWeight($aWeight); 3666 } 3667 3526 $this->title_margin = $aMarg; 3527 } 3528 3668 3529 function Stroke($aImg,$aScale) { 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 } 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 } 3694 3542 } 3695 3543 3696 3544 //=================================================== 3697 3545 // CLASS LinkArrow 3698 // Handles the drawing of a an arrow 3546 // Handles the drawing of a an arrow 3699 3547 //=================================================== 3700 3548 class LinkArrow { 3701 3549 private $ix,$iy; 3702 3550 private $isizespec = array( 3703 3551 array(2,3),array(3,5),array(3,8),array(6,15),array(8,22)); 3704 3552 private $iDirection=ARROW_DOWN,$iType=ARROWT_SOLID,$iSize=ARROW_S2; 3705 3553 private $iColor='black'; 3706 3554 3707 function __construct($x,$y,$aDirection,$aType=ARROWT_SOLID,$aSize=ARROW_S2) {3708 3709 3710 3711 3712 3713 } 3714 3555 function LinkArrow($x,$y,$aDirection,$aType=ARROWT_SOLID,$aSize=ARROW_S2) { 3556 $this->iDirection = $aDirection; 3557 $this->iType = $aType; 3558 $this->iSize = $aSize; 3559 $this->ix = $x; 3560 $this->iy = $y; 3561 } 3562 3715 3563 function SetColor($aColor) { 3716 3564 $this->iColor = $aColor; 3717 3565 } 3718 3566 3719 3567 function SetSize($aSize) { 3720 3568 $this->iSize = $aSize; 3721 3569 } 3722 3570 3723 3571 function SetType($aType) { 3724 3572 $this->iType = $aType; 3725 3573 } 3726 3574 3727 3575 function Stroke($aImg) { 3728 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 3757 3758 3759 3760 3761 3762 break; 3763 3576 list($dx,$dy) = $this->isizespec[$this->iSize]; 3577 $x = $this->ix; 3578 $y = $this->iy; 3579 switch ( $this->iDirection ) { 3580 case ARROW_DOWN: 3581 $c = array($x,$y,$x-$dx,$y-$dy,$x+$dx,$y-$dy,$x,$y); 3582 break; 3583 case ARROW_UP: 3584 $c = array($x,$y,$x-$dx,$y+$dy,$x+$dx,$y+$dy,$x,$y); 3585 break; 3586 case ARROW_LEFT: 3587 $c = array($x,$y,$x+$dy,$y-$dx,$x+$dy,$y+$dx,$x,$y); 3588 break; 3589 case ARROW_RIGHT: 3590 $c = array($x,$y,$x-$dy,$y-$dx,$x-$dy,$y+$dx,$x,$y); 3591 break; 3592 default: 3593 JpGraphError::RaiseL(6030); 3594 //('Unknown arrow direction for link.'); 3595 die(); 3596 break; 3597 } 3598 $aImg->SetColor($this->iColor); 3599 switch( $this->iType ) { 3600 case ARROWT_SOLID: 3601 $aImg->FilledPolygon($c); 3602 break; 3603 case ARROWT_OPEN: 3604 $aImg->Polygon($c); 3605 break; 3606 default: 3607 JpGraphError::RaiseL(6031); 3608 //('Unknown arrow type for link.'); 3609 die(); 3610 break; 3611 } 3764 3612 } 3765 3613 } … … 3776 3624 private $iArrowSize=ARROW_S2,$iArrowType=ARROWT_SOLID; 3777 3625 3778 function __construct($x1=0,$y1=0,$x2=0,$y2=0) {3779 3780 3781 3782 3626 function GanttLink($x1=0,$y1=0,$x2=0,$y2=0) { 3627 $this->ix1 = $x1; 3628 $this->ix2 = $x2; 3629 $this->iy1 = $y1; 3630 $this->iy2 = $y2; 3783 3631 } 3784 3632 3785 3633 function SetPos($x1,$y1,$x2,$y2) { 3786 3787 3788 3789 3634 $this->ix1 = $x1; 3635 $this->ix2 = $x2; 3636 $this->iy1 = $y1; 3637 $this->iy2 = $y2; 3790 3638 } 3791 3639 3792 3640 function SetPath($aPath) { 3793 3641 $this->iPathType = $aPath; 3794 3642 } 3795 3643 3796 3644 function SetColor($aColor) { 3797 3645 $this->iColor = $aColor; 3798 3646 } 3799 3647 3800 3648 function SetArrow($aSize,$aType=ARROWT_SOLID) { 3801 3802 3803 } 3804 3649 $this->iArrowSize = $aSize; 3650 $this->iArrowType = $aType; 3651 } 3652 3805 3653 function SetWeight($aWeight) { 3806 3654 $this->iWeight = $aWeight; 3807 3655 } 3808 3656 3809 3657 function Stroke($aImg) { 3810 3811 3812 3813 3814 3815 // space between axctivities then no suh detour is made and the 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 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 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3658 // The way the path for the arrow is constructed is partly based 3659 // on some heuristics. This is not an exact science but draws the 3660 // path in a way that, for me, makes esthetic sence. For example 3661 // if the start and end activities are very close we make a small 3662 // detour to endter the target horixontally. If there are more 3663 // space between axctivities then no suh detour is made and the 3664 // target is "hit" directly vertical. I have tried to keep this 3665 // simple. no doubt this could become almost infinitive complex 3666 // and have some real AI. Feel free to modify this. 3667 // This will no-doubt be tweaked as times go by. One design aim 3668 // is to avoid having the user choose what types of arrow 3669 // he wants. 3670 3671 // The arrow is drawn between (x1,y1) to (x2,y2) 3672 $x1 = $this->ix1 ; 3673 $x2 = $this->ix2 ; 3674 $y1 = $this->iy1 ; 3675 $y2 = $this->iy2 ; 3676 3677 // Depending on if the target is below or above we have to 3678 // handle thi different. 3679 if( $y2 > $y1 ) { 3680 $arrowtype = ARROW_DOWN; 3681 $midy = round(($y2-$y1)/2+$y1); 3682 if( $x2 > $x1 ) { 3683 switch ( $this->iPathType ) { 3684 case 0: 3685 $c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2); 3686 break; 3687 case 1: 3688 case 2: 3689 case 3: 3690 $c = array($x1,$y1,$x2,$y1,$x2,$y2); 3691 break; 3692 default: 3693 JpGraphError::RaiseL(6032,$this->iPathType); 3694 //('Internal error: Unknown path type (='.$this->iPathType .') specified for link.'); 3695 exit(1); 3696 break; 3697 } 3698 } 3699 else { 3700 switch ( $this->iPathType ) { 3701 case 0: 3702 case 1: 3703 $c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2); 3704 break; 3705 case 2: 3706 // Always extend out horizontally a bit from the first point 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 // the left on the activity 3710 $c = array($x1,$y1,$x1+$this->iPathExtend,$y1, 3711 $x1+$this->iPathExtend,$midy, 3712 $x2,$midy,$x2,$y2); 3713 break; 3714 case 3: 3715 if( $y2-$midy < 6 ) { 3716 $c = array($x1,$y1,$x1,$midy, 3717 $x2-$this->iPathExtend,$midy, 3718 $x2-$this->iPathExtend,$y2, 3719 $x2,$y2); 3720 $arrowtype = ARROW_RIGHT; 3721 } 3722 else { 3723 $c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2); 3724 } 3725 break; 3726 default: 3727 JpGraphError::RaiseL(6032,$this->iPathType); 3728 //('Internal error: Unknown path type specified for link.'); 3729 exit(1); 3730 break; 3731 } 3732 } 3733 $arrow = new LinkArrow($x2,$y2,$arrowtype); 3734 } 3735 else { 3736 // Y2 < Y1 3737 $arrowtype = ARROW_UP; 3738 $midy = round(($y1-$y2)/2+$y2); 3739 if( $x2 > $x1 ) { 3740 switch ( $this->iPathType ) { 3741 case 0: 3742 case 1: 3743 $c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2); 3744 break; 3745 case 3: 3746 if( $midy-$y2 < 8 ) { 3747 $arrowtype = ARROW_RIGHT; 3748 $c = array($x1,$y1,$x1,$y2,$x2,$y2); 3749 } 3750 else { 3751 $c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2); 3752 } 3753 break; 3754 default: 3755 JpGraphError::RaiseL(6032,$this->iPathType); 3756 //('Internal error: Unknown path type specified for link.'); 3757 break; 3758 } 3759 } 3760 else { 3761 switch ( $this->iPathType ) { 3762 case 0: 3763 case 1: 3764 $c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2); 3765 break; 3766 case 2: 3767 // Always extend out horizontally a bit from the first point 3768 $c = array($x1,$y1,$x1+$this->iPathExtend,$y1, 3769 $x1+$this->iPathExtend,$midy, 3770 $x2,$midy,$x2,$y2); 3771 break; 3772 case 3: 3773 if( $midy-$y2 < 16 ) { 3774 $arrowtype = ARROW_RIGHT; 3775 $c = array($x1,$y1,$x1,$midy,$x2-$this->iPathExtend,$midy, 3776 $x2-$this->iPathExtend,$y2, 3777 $x2,$y2); 3778 } 3779 else { 3780 $c = array($x1,$y1,$x1,$midy,$x2,$midy,$x2,$y2); 3781 } 3782 break; 3783 default: 3784 JpGraphError::RaiseL(6032,$this->iPathType); 3785 //('Internal error: Unknown path type specified for link.'); 3786 break; 3787 } 3788 } 3789 $arrow = new LinkArrow($x2,$y2,$arrowtype); 3790 } 3791 $aImg->SetColor($this->iColor); 3792 $aImg->SetLineWeight($this->iWeight); 3793 $aImg->Polygon($c); 3794 $aImg->SetLineWeight(1); 3795 $arrow->SetColor($this->iColor); 3796 $arrow->SetSize($this->iArrowSize); 3797 $arrow->SetType($this->iArrowType); 3798 $arrow->Stroke($aImg); 3951 3799 } 3952 3800 } -
trunk/client/modules/Elezioni/grafici/jpgraph_gb2312.php
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: Chinese font conversions5 // Created: 6 // Ver: $Id: jpgraph_gb2312.php 1106 2009-02-22 20:16:35Z ljp $3 // File: JPGRAPH_GB2312.PHP 4 // Description: PHP4 Graph Plotting library. Chinese font conversions 5 // Created: 2003-05-30 6 // Ver: $Id: jpgraph_gb2312.php 781 2006-10-08 08:07:47Z ljp $ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. 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 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 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 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 416 417 418 419 420 421 422 423 424 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 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 492 493 494 495 496 497 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 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 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 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 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 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 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 753 754 755 756 757 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 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 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 855 856 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 899 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 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 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 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 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 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 1143 1144 1145 1146 1147 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 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 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 1360 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 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 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; 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; 1525 1548 } 1526 1549 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 1550 } // END Class 1551 1551 1552 1552 ?> -
trunk/client/modules/Elezioni/grafici/jpgraph_gradient.php
r265 r267 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_GRADIENT.PHP4 // Description:Create a color gradient5 // Created:2003-02-016 // Ver: $Id: jpgraph_gradient.php 1761 2009-08-01 08:31:28Z ljp $7 8 // Copyright (c) Asial Corporation. 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 1091 2009-01-18 22:57:40Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. 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 35 function __construct(&$img) {36 33 //--------------- 34 // CONSTRUCTOR 35 function Gradient(&$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 $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 } 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 } 328 323 } 329 324 … … 334 329 // of a mountain) 335 330 function FilledFlatPolygon($pts,$from_color,$to_color) { 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 } 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 } 393 386 } 394 387 395 396 // PRIVATE METHODS 388 //--------------- 389 // PRIVATE METHODS 397 390 // Add to the image color map the necessary colors to do the transition 398 391 // between the two colors using $numcolors intermediate colors 399 392 function GetColArray($from_color,$to_color,$arr_size,&$colors,$numcols=100) { 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 } 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 } 432 421 } // Class 433 422 -
trunk/client/modules/Elezioni/grafici/jpgraph_iconplot.php
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: Extension module to add icons to plots5 // Created: 6 // Ver: $Id: jpgraph_iconplot.php 1404 2009-06-28 15:25:41Z ljp $3 // File: JPGRAPH_ICONPLOT.PHP 4 // Description: PHP4 Graph Plotting library. Extension module. 5 // Created: 2004-02-18 6 // Ver: $Id: jpgraph_iconplot.php 781 2006-10-08 08:07:47Z ljp $ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. All rights reserved. 9 9 //======================================================================== 10 10 … … 25 25 26 26 27 function __construct($aFile="",$aX=0,$aY=0,$aScale=1.0,$aMix=100) {28 29 30 31 32 33 34 35 27 function IconPlot($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 =null,$ayscale=null) {115 114 function Stroke($aImg,$axscale,$ayscale) { 115 $this->StrokeWithScale($aImg,$axscale,$ayscale); 116 116 } 117 117 118 118 function StrokeWithScale($aImg,$axscale,$ayscale) { 119 if( $this->iScalePosX === null || $this->iScalePosY=== null ||120 $axscale === null || $ayscale=== null ) {121 122 123 124 125 126 127 119 if( $this->iScalePosX === null || 120 $this->iScalePosY === 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); 155 $iconw = imagesx($gdimg); 156 $iconh = imagesy($gdimg); 157 158 if( $aReturnWidthHeight ) { 159 return array(round($iconw*$this->iScale),round($iconh*$this->iScale)); 160 } 157 161 158 if( $aReturnWidthHeight ) { 159 return array(round($iconw*$this->iScale),round($iconh*$this->iScale)); 160 } 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 } 161 173 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 } 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); 173 182 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); 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
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph_imgtrans.php 1106 2009-02-22 20:16:35Z 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 781 2006-10-08 08:07:47Z ljp $ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. 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 __construct($aGdImg) {19 20 21 } 22 23 // -------------------------------------------------------------------- 24 // _TransVert3D() and _TransHor3D() are helper methods to 25 // Skew3D(). 18 function ImgTrans($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 34 35 36 37 38 39 40 41 if( $aMinSize ) 42 $hh = ceil($h * $aHorizon / ($aSkewDist+$h));43 else 44 $hh = $h;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
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph_led.php 1674 2009-07-22 19:42:23Z ljp $7 // 8 // Copyright 2006 (c) A sial Corporation. All rights reserved.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 1091 2009-01-18 22:57:40Z ljp $ 7 // 8 // Copyright 2006 (c) Aditus Consulting. 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 for 13 // 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 StrokeNumber 19 // function to _GetLED: 251; 20 // 11 21 //======================================================================== 12 22 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 } 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 37 68 38 69 //======================================================================== 39 70 // CLASS DigitalLED74 40 // Description: 71 // Description: 41 72 // Construct a number as an image that looks like LED numbers in a 42 73 // 7x4 digital matrix … … 46 77 private $iLED_X = 4, $iLED_Y=7, 47 78 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; 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; 212 228 } 213 214 function SetSupersampling($aSuperSampling = 2) 215 229 230 function SetSupersampling($aSuperSampling = 2) { 231 $this->iSuperSampling = $aSuperSampling; 216 232 } 217 233 218 function _GetLED($aLedIdx, $aColor = 0) 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 if( array_key_exists($aLedIdx, $this->iLEDSpec)) {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 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; 265 281 } 266 282 267 268 function Stroke($aValStr, $aColor = 0, $aFileName = '') {269 $this->StrokeNumber($aValStr, $aColor, $aFileName);270 }271 272 273 283 function StrokeNumber($aValStr, $aColor = 0, $aFileName = '') { 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 } 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 } 309 318 } 310 319 } -
trunk/client/modules/Elezioni/grafici/jpgraph_legend.inc.php
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // 6 // 7 // Created: 8 // Ver: $Id: jpgraph_legend.inc.php 1926 2010-01-11 16:33:07Z 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 1048 2008-08-01 19:56:46Z ljp $ 9 9 // 10 // Copyright (c) A sial Corporation. All rights reserved.10 // Copyright (c) Aditus Consulting. 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 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'; 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'; 29 28 private $mark_abs_hsize=_DEFAULT_LPM_SIZE,$mark_abs_vsize=_DEFAULT_LPM_SIZE; 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 29 private $xmargin=10,$ymargin=3,$shadow_width=2; 30 private $xlmargin=2, $ylmargin=''; 37 31 private $xpos=0.05, $ypos=0.15, $xabspos=-1, $yabspos=-1; 38 32 private $halign="right", $valign="top"; 33 private $font_family=FF_FONT1,$font_style=FS_NORMAL,$font_size=12; 39 34 private $font_color='black'; 40 35 private $hide=false,$layout_n=1; … … 42 37 private $csimareas=''; 43 38 private $reverse = false ; 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 39 40 //--------------- 41 // CONSTRUCTOR 42 function Legend() { 43 // Empty 44 } 45 //--------------- 46 // PUBLIC METHODS 53 47 function Hide($aHide=true) { 54 55 } 56 48 $this->hide=$aHide; 49 } 50 57 51 function SetHColMargin($aXMarg) { 58 52 $this->xmargin = $aXMarg; 59 53 } 60 54 61 55 function SetVColMargin($aSpacing) { 62 $this->ylinespacing= $aSpacing ;56 $this->ymargin = $aSpacing ; 63 57 } 64 58 65 59 function SetLeftMargin($aXMarg) { 66 60 $this->xlmargin = $aXMarg; 67 61 } 68 62 69 63 // Synonym 70 64 function SetLineSpacing($aSpacing) { 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; 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; 83 76 } 84 77 85 78 function SetMarkAbsSize($aSize) { 86 87 79 $this->mark_abs_vsize = $aSize ; 80 $this->mark_abs_hsize = $aSize ; 88 81 } 89 82 90 83 function SetMarkAbsVSize($aSize) { 91 84 $this->mark_abs_vsize = $aSize ; 92 85 } 93 86 94 87 function SetMarkAbsHSize($aSize) { 95 88 $this->mark_abs_hsize = $aSize ; 96 89 } 97 90 98 91 function SetLineWeight($aWeight) { 99 92 $this->weight = $aWeight; 100 93 } 101 94 102 95 function SetFrameWeight($aWeight) { 103 104 } 105 96 $this->frameweight = $aWeight; 97 } 98 106 99 function SetLayout($aDirection=LEGEND_VERT) { 107 108 } 109 100 $this->layout_n = $aDirection==LEGEND_VERT ? 1 : 99 ; 101 } 102 110 103 function SetColumns($aCols) { 111 104 $this->layout_n = $aCols ; 112 105 } 113 106 114 107 function SetReverse($f=true) { 115 108 $this->reverse = $f ; 116 109 } 117 110 118 111 // Set color on frame around box 119 112 function SetColor($aFontColor,$aColor='black') { 120 121 122 } 123 113 $this->font_color=$aFontColor; 114 $this->color=$aColor; 115 } 116 124 117 function SetFont($aFamily,$aStyle=FS_NORMAL,$aSize=10) { 125 126 127 128 } 129 130 function SetPos($aX,$aY,$aHAlign= 'right',$aVAlign='top') {131 132 } 133 134 function SetAbsPos($aX,$aY,$aHAlign= 'right',$aVAlign='top') {135 136 137 138 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 146 147 148 118 $this->font_family = $aFamily; 119 $this->font_style = $aStyle; 120 $this->font_size = $aSize; 121 } 122 123 function SetPos($aX,$aY,$aHAlign="right",$aVAlign="top") { 124 $this->Pos($aX,$aY,$aHAlign,$aVAlign); 125 } 126 127 function SetAbsPos($aX,$aY,$aHAlign="right",$aVAlign="top") { 128 $this->xabspos=$aX; 129 $this->yabspos=$aY; 130 $this->halign=$aHAlign; 131 $this->valign=$aVAlign; 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 $this->xpos=$aX; 139 $this->ypos=$aY; 140 $this->halign=$aHAlign; 141 $this->valign=$aVAlign; 149 142 } 150 143 151 144 function SetFillColor($aColor) { 152 $this->fill_color=$aColor; 153 } 154 155 function Clear() { 156 $this->txtcol = array(); 157 } 158 145 $this->fill_color=$aColor; 146 } 147 159 148 function Add($aTxt,$aColor,$aPlotmark='',$aLinestyle=0,$csimtarget='',$csimalt='',$csimwintarget='') { 160 149 $this->txtcol[]=array($aTxt,$aColor,$aPlotmark,$aLinestyle,$csimtarget,$csimalt,$csimwintarget); 161 150 } 162 151 163 152 function GetCSIMAreas() { 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 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 193 172 // to size the legend box. 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 } 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 } 491 391 } 492 392 } // Class 493 393 494 394 ?> -
trunk/client/modules/Elezioni/grafici/jpgraph_line.php
r265 r267 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 1921 2009-12-11 11:46:39Z ljp $7 8 // Copyright (c) Asial Corporation. 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 981 2008-03-24 11:51:12Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. 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 , $fillFromMax = false;32 protected $fillFromMin = 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 __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 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 51 50 function SetBarCenter($aFlag=true) { 52 51 $this->barcenter=$aFlag; 53 52 } 54 53 55 54 function SetStyle($aStyle) { 56 57 } 58 55 $this->line_style=$aStyle; 56 } 57 59 58 function SetStepStyle($aFlag=true) { 60 61 } 62 59 $this->step_style = $aFlag; 60 } 61 63 62 function SetColor($aColor) { 64 65 } 66 63 parent::SetColor($aColor); 64 } 65 67 66 function SetFillFromYMin($f=true) { 68 $this->fillFromMin = $f ; 69 } 70 71 function SetFillFromYMax($f=true) { 72 $this->fillFromMax = $f ; 73 } 74 67 $this->fillFromMin = $f ; 68 } 69 75 70 function SetFillColor($aColor,$aFilled=true) { 76 //$this->color = $aColor; 77 $this->fill_color=$aColor; 78 $this->filled=$aFilled; 71 $this->fill_color=$aColor; 72 $this->filled=$aFilled; 79 73 } 80 74 81 75 function SetFillGradient($aFromColor,$aToColor,$aNumColors=100,$aFilled=true) { 82 83 84 85 86 87 } 88 76 $this->fillgrad_fromcolor = $aFromColor; 77 $this->fillgrad_tocolor = $aToColor; 78 $this->fillgrad_numcolors = $aNumColors; 79 $this->filled = $aFilled; 80 $this->fillgrad = true; 81 } 82 89 83 function Legend($graph) { 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 } 84 if( $this->legend!="" ) { 85 if( $this->filled && !$this->fillgrad ) { 86 $graph->legend->Add($this->legend, 87 $this->fill_color,$this->mark,0, 88 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 89 } 90 elseif( $this->fillgrad ) { 91 $color=array($this->fillgrad_fromcolor,$this->fillgrad_tocolor); 92 // In order to differentiate between gradients and cooors specified as an RGB triple 93 $graph->legend->Add($this->legend,$color,"",-2 /* -GRAD_HOR */, 94 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 95 } else { 96 $graph->legend->Add($this->legend, 97 $this->color,$this->mark,$this->line_style, 98 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 99 } 100 } 107 101 } 108 102 109 103 function AddArea($aMin=0,$aMax=0,$aFilled=LP_AREA_NOT_FILLED,$aColor="gray9",$aBorder=LP_AREA_BORDER) { 110 111 112 113 114 115 } 116 117 } 118 104 if($aMin > $aMax) { 105 // swap 106 $tmp = $aMin; 107 $aMin = $aMax; 108 $aMax = $tmp; 109 } 110 $this->filledAreas[] = array($aMin,$aMax,$aColor,$aFilled,$aBorder); 111 } 112 119 113 // Gets called before any axis are stroked 120 114 function PreStrokeAdjust($graph) { 121 115 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 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 139 134 function SetFastStroke($aFlg=true) { 140 135 $this->iFastStroke = $aFlg; 141 136 } 142 137 143 138 function FastStroke($img,$xscale,$yscale,$aStartPoint=0,$exist_x=true) { 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 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 184 173 function Stroke($img,$xscale,$yscale) { 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 } 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 } 462 415 } 463 416 } // Class … … 466 419 //=================================================== 467 420 // CLASS AccLinePlot 468 // Description: 421 // Description: 469 422 //=================================================== 470 423 class AccLinePlot extends Plot { 471 424 protected $plots=null,$nbrplots=0; 472 425 private $iStartEndZero=true; 473 474 475 function __construct($plots) {426 //--------------- 427 // CONSTRUCTOR 428 function AccLinePlot($plots) { 476 429 $this->plots = $plots; 477 478 479 480 481 482 483 484 485 } 486 487 488 489 } 490 } 491 492 493 // PUBLIC METHODS 430 $this->nbrplots = count($plots); 431 $this->numpoints = $plots[0]->numpoints; 432 433 // Verify that all plots have the same number of data points 434 for( $i=1; $i < $this->nbrplots; ++$i ) { 435 if( $plots[$i]->numpoints != $this->numpoints ) { 436 JpGraphError::RaiseL(10003);//('Each plot in an accumulated lineplot must have the same number of data points',0) 437 } 438 } 439 440 for($i=0; $i < $this->nbrplots; ++$i ) { 441 $this->LineInterpolate($this->plots[$i]->coords[0]); 442 } 443 } 444 445 //--------------- 446 // PUBLIC METHODS 494 447 function Legend($graph) { 495 foreach( $this->plots as $p ) { 496 $p->DoLegend($graph); 497 } 498 } 499 448 foreach( $this->plots as $p ) 449 $p->DoLegend($graph); 450 } 451 500 452 function Max() { 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 } 453 list($xmax) = $this->plots[0]->Max(); 454 $nmax=0; 455 $n = count($this->plots); 456 for($i=0; $i < $n; ++$i) { 457 $nc = count($this->plots[$i]->coords[0]); 458 $nmax = max($nmax,$nc); 459 list($x) = $this->plots[$i]->Max(); 460 $xmax = Max($xmax,$x); 461 } 462 for( $i = 0; $i < $nmax; $i++ ) { 463 // Get y-value for line $i by adding the 464 // individual bars from all the plots added. 465 // It would be wrong to just add the 466 // individual plots max y-value since that 467 // would in most cases give to large y-value. 468 $y=$this->plots[0]->coords[0][$i]; 469 for( $j = 1; $j < $this->nbrplots; $j++ ) { 470 $y += $this->plots[ $j ]->coords[0][$i]; 471 } 472 $ymax[$i] = $y; 473 } 474 $ymax = max($ymax); 475 return array($xmax,$ymax); 476 } 525 477 526 478 function Min() { 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 479 $nmax=0; 480 list($xmin,$ysetmin) = $this->plots[0]->Min(); 481 $n = count($this->plots); 482 for($i=0; $i < $n; ++$i) { 483 $nc = count($this->plots[$i]->coords[0]); 484 $nmax = max($nmax,$nc); 485 list($x,$y) = $this->plots[$i]->Min(); 486 $xmin = Min($xmin,$x); 487 $ysetmin = Min($y,$ysetmin); 488 } 489 for( $i = 0; $i < $nmax; $i++ ) { 490 // Get y-value for line $i by adding the 491 // individual bars from all the plots added. 492 // It would be wrong to just add the 493 // individual plots min y-value since that 494 // would in most cases give to small y-value. 495 $y=$this->plots[0]->coords[0][$i]; 496 for( $j = 1; $j < $this->nbrplots; $j++ ) { 497 $y += $this->plots[ $j ]->coords[0][$i]; 498 } 499 $ymin[$i] = $y; 500 } 501 $ymin = Min($ysetmin,Min($ymin)); 502 return array($xmin,$ymin); 551 503 } 552 504 … … 554 506 function PreStrokeAdjust($graph) { 555 507 556 557 558 // (We check for empty in case the scale is a log scale 559 560 561 562 563 564 565 566 567 568 569 570 $graph->SetTextScaleOff($b); 571 572 573 508 // If another plot type have already adjusted the 509 // offset we don't touch it. 510 // (We check for empty in case the scale is a log scale 511 // and hence doesn't contain any xlabel_offset) 512 513 if( empty($graph->xaxis->scale->ticks->xlabel_offset) || 514 $graph->xaxis->scale->ticks->xlabel_offset == 0 ) { 515 if( $this->center ) { 516 ++$this->numpoints; 517 $a=0.5; $b=0.5; 518 } else { 519 $a=0; $b=0; 520 } 521 $graph->xaxis->scale->ticks->SetXLabelOffset($a); 522 $graph->SetTextScaleOff($b); 523 $graph->xaxis->scale->ticks->SupressMinorTickMarks(); 524 } 525 574 526 } 575 527 576 528 function SetInterpolateMode($aIntMode) { 577 529 $this->iStartEndZero=$aIntMode; 578 530 } 579 531 … … 583 535 function LineInterpolate(&$aData) { 584 536 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 } 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 645 596 646 597 // To avoid duplicate of line drawing code here we just … … 651 602 // since this method would have a side effect. 652 603 function Stroke($img,$xscale,$yscale) { 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 } 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 } 677 627 } 678 628 } // Class -
trunk/client/modules/Elezioni/grafici/jpgraph_log.php
r265 r267 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 1106 2009-02-22 20:16:35Z ljp $7 8 // Copyright (c) Asial Corporation. 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 957 2007-12-01 14:00:29Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 DEFINE('LOGLABELS_PLAIN',0); … … 18 18 //=================================================== 19 19 class LogScale extends LinearScale { 20 21 20 //--------------- 21 // CONSTRUCTOR 22 22 23 23 // Log scale is specified using the log of min and max 24 function __construct($min,$max,$type="y") {25 parent::__construct($min,$max,$type);26 27 28 } 29 30 31 // PUBLIC METHODS 24 function LogScale($min,$max,$type="y") { 25 $this->LinearScale($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 } 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); 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); 50 49 } 51 50 52 51 // Relative translate (don't include offset) usefull when we just want 53 // to know the relative position (in pixels) on the axis 52 // to know the relative position (in pixels) on the axis 54 53 function RelTranslate($a) { 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 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 69 65 // Use bcpow() for increased precision 70 66 function GetMinVal() { 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 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 79 73 function GetMaxVal() { 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 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 88 80 // Logarithmic autoscaling is much simplier since we just 89 81 // set the min and max to logs of the min and max values. … … 92 84 // signature as the linear counterpart. 93 85 function AutoScale($img,$min,$max,$maxsteps,$majend=true) { 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 $this->Update($img,$smin,$smax); 120 } 121 122 // PRIVATE METHODS 86 if( $min==0 ) $min=1; 87 88 if( $max <= 0 ) { 89 JpGraphError::RaiseL(11004); 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 if( is_numeric($this->autoscale_min) ) { 93 $smin = round($this->autoscale_min); 94 $smax = ceil(log10($max)); 95 if( $min >= $max ) { 96 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.'); 97 } 98 } 99 else { 100 $smin = floor(log10($min)); 101 if( is_numeric($this->autoscale_max) ) { 102 $smax = round($this->autoscale_max); 103 if( $smin >= $smax ) { 104 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.'); 105 } 106 } 107 else 108 $smax = ceil(log10($max)); 109 } 110 111 $this->Update($img,$smin,$smax); 112 } 113 //--------------- 114 // PRIVATE METHODS 123 115 } // Class 124 116 125 117 //=================================================== 126 118 // CLASS LogTicks 127 // Description: 119 // Description: 128 120 //=================================================== 129 121 class LogTicks extends Ticks{ 130 122 private $label_logtype=LOGLABELS_MAGNITUDE; 131 123 private $ticklabels_pos = array(); 132 133 134 function __construct() {135 } 136 137 // PUBLIC METHODS 124 //--------------- 125 // CONSTRUCTOR 126 function LogTicks() { 127 } 128 //--------------- 129 // PUBLIC METHODS 138 130 function IsSpecified() { 139 131 return true; 140 132 } 141 133 142 134 function SetLabelLogType($aType) { 143 144 } 145 135 $this->label_logtype = $aType; 136 } 137 146 138 // For log scale it's meaningless to speak about a major step 147 139 // We just return -1 to make the framework happy (specifically 148 140 // StrokeLabels() ) 149 141 function GetMajor() { 150 142 return -1; 151 143 } 152 144 153 145 function SetTextLabelStart($aStart) { 154 155 146 JpGraphError::RaiseL(11005); 147 //('Specifying tick interval for a logarithmic scale is undefined. Remove any calls to SetTextLabelStart() or SetTextTickInterval() on the logarithmic scale.'); 156 148 } 157 149 158 150 function SetXLabelOffset($dummy) { 159 151 // For log scales we dont care about XLabel offset 160 152 } 161 153 … … 165 157 // absolute x-position. 166 158 function Stroke($img,$scale,$pos) { 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; 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; 302 280 } 303 281 } // Class -
trunk/client/modules/Elezioni/grafici/jpgraph_mgraph.php
r265 r267 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_MGRAPH.PHP4 5 // Created:2006-01-156 // Ver: $Id: jpgraph_mgraph.php 1770 2009-08-17 06:10:22Z ljp $7 8 // Copyright (c) Asial Corporation. 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 1012 2008-06-23 15:02:15Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. 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;19 17 20 18 protected $img=NULL; 21 19 protected $iCnt=0,$iGraphs = array(); // image_handle, x, y, fx, fy, sizex, sizey 22 20 protected $iFillColor='white', $iCurrentColor=0; 23 protected $lm= 4,$rm=4,$tm=4,$bm=4;21 protected $lm=0,$rm=0,$tm=0,$bm=0; 24 22 protected $iDoFrame = FALSE, $iFrameColor = 'black', $iFrameWeight = 1; 25 23 protected $iLineWeight = 1; 26 24 protected $expired=false; 27 protected $cache=null,$cache_name = '',$inline=true; 28 protected $image_format='png',$image_quality=75; 25 protected $img_format='png',$image_quality=75; 29 26 protected $iWidth=NULL,$iHeight=NULL; 30 27 protected $background_image='',$background_image_center=true, 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 28 $backround_image_format='',$background_image_mix=100, 29 $background_image_y=NULL, $background_image_x=NULL; 36 30 37 31 // Create a new instane of the combined graph 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 32 function MGraph($aWidth=NULL,$aHeight=NULL) { 33 $this->iWidth = $aWidth; 34 $this->iHeight = $aHeight; 75 35 } 76 36 77 37 // Specify background fill color for the combined graph 78 38 function SetFillColor($aColor) { 79 39 $this->iFillColor = $aColor; 80 40 } 81 41 82 42 // Add a frame around the combined graph 83 43 function SetFrame($aFlg,$aColor='black',$aWeight=1) { 84 85 86 87 } 88 89 // Specify a background image blend 44 $this->iDoFrame = $aFlg; 45 $this->iFrameColor = $aColor; 46 $this->iFrameWeight = $aWeight; 47 } 48 49 // Specify a background image blend 90 50 function SetBackgroundImageMix($aMix) { 91 51 $this->background_image_mix = $aMix ; 92 52 } 93 53 94 54 // Specify a background image 95 55 function SetBackgroundImage($aFileName,$aCenter_aX=NULL,$aY=NULL) { 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 } 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 } 128 132 129 133 function _strokeBackgroundImage() { 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); 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); 162 222 } 163 223 164 224 function AddMix($aGraph,$x=0,$y=0,$mix=100,$fx=0,$fy=0,$w=0,$h=0) { 165 166 } 167 225 $this->_gdImgHandle($aGraph->Stroke( _IMG_HANDLER),$x,$y,$fx=0,$fy=0,$w,$h,$mix); 226 } 227 168 228 function Add($aGraph,$x=0,$y=0,$fx=0,$fy=0,$w=0,$h=0) { 169 229 $this->_gdImgHandle($aGraph->Stroke( _IMG_HANDLER),$x,$y,$fx=0,$fy=0,$w,$h); 170 230 } 171 231 172 232 function _gdImgHandle($agdCanvas,$x,$y,$fx=0,$fy=0,$w=0,$h=0,$mix=100) { 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); 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); 185 241 } 186 242 187 243 function SetMargin($lm,$rm,$tm,$bm) { 188 189 190 191 244 $this->lm = $lm; 245 $this->rm = $rm; 246 $this->tm = $tm; 247 $this->bm = $bm; 192 248 } 193 249 194 250 function SetExpired($aFlg=true) { 195 $this->expired = $aFlg; 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"); 196 279 } 197 280 198 281 function SetImgFormat($aFormat,$aQuality=75) { 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 } 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."); 269 335 } 270 336 271 337 function Stroke($aFileName='') { 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 } 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 } 340 389 } 341 390 } 342 391 343 // EOF344 345 392 ?> -
trunk/client/modules/Elezioni/grafici/jpgraph_pie.php
r265 r267 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 1926 2010-01-11 16:33:07Z ljp $7 8 // Copyright (c) Asial Corporation. 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 1091 2009-01-18 22:57:40Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. 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;29 26 protected $radius=0.3; 30 27 protected $explode_radius=array(),$explode_all=false,$explode_r=20; 31 28 protected $labels=null, $legends=null; 32 29 protected $csimtargets=null,$csimwintargets=null; // Array of targets for CSIM 33 protected $csimareas=''; // Generated CSIM text34 protected $csimalts=null; 30 protected $csimareas=''; // Generated CSIM text 31 protected $csimalts=null; // ALT tags for corresponding target 35 32 protected $data=null; 36 33 public $title; … … 39 36 protected $legend_margin=6,$show_labels=true; 40 37 protected $themearr = array( 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)); 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"; 45 43 protected $setslicecolors=array(); 46 44 protected $labeltype=0; // Default to percentage … … 56 54 protected $iGuideLineCurve = false,$iGuideVFactor=1.4,$iGuideLineRFactor=0.8; 57 55 protected $la = array(); // Holds the exact angle for each label 58 59 60 61 function __construct($data) {62 63 64 $this->title->SetFont(FF_DEFAULT,FS_BOLD);65 66 67 68 69 } 70 71 72 // PUBLIC METHODS 56 57 //--------------- 58 // CONSTRUCTOR 59 function PiePlot($data) { 60 $this->data = array_reverse($data); 61 $this->title = new Text(""); 62 $this->title->SetFont(FF_FONT1,FS_BOLD); 63 $this->value = new DisplayValue(); 64 $this->value->Show(); 65 $this->value->SetFormat('%.1f%%'); 66 $this->guideline = new LineProperty(); 67 } 68 69 //--------------- 70 // PUBLIC METHODS 73 71 function SetCenter($x,$y=0.5) { 74 75 72 $this->posx = $x; 73 $this->posy = $y; 76 74 } 77 75 78 76 // Enable guideline and set drwaing policy 79 77 function SetGuideLines($aFlg=true,$aCurved=true,$aAlways=false) { 80 81 82 78 $this->guideline->Show($aFlg); 79 $this->iShowGuideLineForSingle = $aAlways; 80 $this->iGuideLineCurve = $aCurved; 83 81 } 84 82 85 83 // Adjuste the distance between labels and labels and pie 86 84 function SetGuideLinesAdjust($aVFactor,$aRFactor=0.8) { 87 88 85 $this->iGuideVFactor=$aVFactor; 86 $this->iGuideLineRFactor=$aRFactor; 89 87 } 90 88 91 89 function SetColor($aColor) { 92 93 } 94 90 $this->color = $aColor; 91 } 92 95 93 function SetSliceColors($aColors) { 96 97 } 98 94 $this->setslicecolors = $aColors; 95 } 96 99 97 function SetShadow($aColor='darkgray',$aDropWidth=4) { 100 101 98 $this->ishadowcolor = $aColor; 99 $this->ishadowdrop = $aDropWidth; 102 100 } 103 101 104 102 function SetCSIMTargets($aTargets,$aAlts='',$aWinTargets='') { 105 106 107 108 109 110 } 111 103 $this->csimtargets=array_reverse($aTargets); 104 if( is_array($aWinTargets) ) 105 $this->csimwintargets=array_reverse($aWinTargets); 106 if( is_array($aAlts) ) 107 $this->csimalts=array_reverse($aAlts); 108 } 109 112 110 function GetCSIMareas() { 113 114 } 115 116 function AddSliceToCSIM($i,$xc,$yc,$radius,$sa,$ea) { 111 return $this->csimareas; 112 } 113 114 function AddSliceToCSIM($i,$xc,$yc,$radius,$sa,$ea) { 117 115 //Slice number, ellipse centre (x,y), height, width, start angle, end angle 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 $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; 171 172 173 174 175 176 177 178 } 179 180 116 while( $sa > 2*M_PI ) $sa = $sa - 2*M_PI; 117 while( $ea > 2*M_PI ) $ea = $ea - 2*M_PI; 118 119 $sa = 2*M_PI - $sa; 120 $ea = 2*M_PI - $ea; 121 122 // Special case when we have only one slice since then both start and end 123 // angle will be == 0 124 if( abs($sa - $ea) < 0.0001 ) { 125 $sa=2*M_PI; $ea=0; 126 } 127 128 //add coordinates of the centre to the map 129 $xc = floor($xc);$yc=floor($yc); 130 $coords = "$xc, $yc"; 131 132 //add coordinates of the first point on the arc to the map 133 $xp = floor(($radius*cos($ea))+$xc); 134 $yp = floor($yc-$radius*sin($ea)); 135 $coords.= ", $xp, $yp"; 136 137 //add coordinates every 0.2 radians 138 $a=$ea+0.2; 139 140 // If we cross the 360-limit with a slice we need to handle 141 // the fact that end angle is smaller than start 142 if( $sa < $ea ) { 143 while ($a <= 2*M_PI) { 144 $xp = floor($radius*cos($a)+$xc); 145 $yp = floor($yc-$radius*sin($a)); 146 $coords.= ", $xp, $yp"; 147 $a += 0.2; 148 } 149 $a -= 2*M_PI; 150 } 151 152 153 while ($a < $sa) { 154 $xp = floor($radius*cos($a)+$xc); 155 $yp = floor($yc-$radius*sin($a)); 156 $coords.= ", $xp, $yp"; 157 $a += 0.2; 158 } 159 160 //Add the last point on the arc 161 $xp = floor($radius*cos($sa)+$xc); 162 $yp = floor($yc-$radius*sin($sa)); 163 $coords.= ", $xp, $yp"; 164 if( !empty($this->csimtargets[$i]) ) { 165 $this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->csimtargets[$i]."\""; 166 $tmp=""; 167 if( !empty($this->csimwintargets[$i]) ) { 168 $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; 169 } 170 if( !empty($this->csimalts[$i]) ) { 171 $tmp=sprintf($this->csimalts[$i],$this->data[$i]); 172 $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" "; 173 } 174 $this->csimareas .= " />\n"; 175 } 176 } 177 178 181 179 function SetTheme($aTheme) { 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 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 193 186 function ExplodeSlice($e,$radius=20) { 194 if( ! is_integer($e) ) 195 196 187 if( ! is_integer($e) ) 188 JpGraphError::RaiseL(15002);//('Argument to PiePlot::ExplodeSlice() must be an integer'); 189 $this->explode_radius[$e]=$radius; 197 190 } 198 191 199 192 function ExplodeAll($radius=20) { 200 201 193 $this->explode_all=true; 194 $this->explode_r = $radius; 202 195 } 203 196 204 197 function Explode($aExplodeArr) { 205 206 207 208 209 198 if( !is_array($aExplodeArr) ) { 199 JpGraphError::RaiseL(15003); 200 //("Argument to PiePlot::Explode() must be an array with integer distances."); 201 } 202 $this->explode_radius = $aExplodeArr; 210 203 } 211 204 212 205 function SetStartAngle($aStart) { 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 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 225 217 // Size in percentage 226 218 function SetSize($aSize) { 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 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 234 231 // Set label arrays 235 232 function SetLegends($aLegend) { 236 237 } 238 239 // Set text labels for slices 233 $this->legends = $aLegend; 234 } 235 236 // Set text labels for slices 240 237 function SetLabels($aLabels,$aLblPosAdj="auto") { 241 242 238 $this->labels = array_reverse($aLabels); 239 $this->ilabelposadj=$aLblPosAdj; 243 240 } 244 241 245 242 function SetLabelPos($aLblPosAdj) { 246 247 } 248 243 $this->ilabelposadj=$aLblPosAdj; 244 } 245 249 246 // Should we display actual value or percentage? 250 function SetLabelType($ aType) {251 if( $aType < 0 || $aType > 2 ) 252 JpGraphError::RaiseL(15008,$aType);253 254 $this->labeltype = $aType;255 } 256 257 // Deprecated. 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. 258 255 function SetValueType($aType) { 259 256 $this->SetLabelType($aType); 260 257 } 261 258 262 259 // Should the circle around a pie plot be displayed 263 260 function ShowBorder($exterior=true,$interior=true) { 264 265 266 } 267 261 $this->pie_border = $exterior; 262 $this->pie_interior_border = $interior; 263 } 264 268 265 // Setup the legends 269 266 function Legend($graph) { 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 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 345 340 // Adjust the rounded percetage value so that the sum of 346 341 // of the pie slices are always 100% 347 342 // Using the Hare/Niemeyer method 348 343 function AdjPercentage($aData,$aPrec=0) { 349 350 351 if( $aPrec == 1 ) 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 344 $mul=100; 345 if( $aPrec > 0 && $aPrec < 3 ) { 346 if( $aPrec == 1 ) 347 $mul=1000; 348 else 349 $mul=10000; 350 } 351 352 $tmp = array(); 353 $result = array(); 354 $quote_sum=0; 355 $n = count($aData) ; 356 for( $i=0, $sum=0; $i < $n; ++$i ) 357 $sum+=$aData[$i]; 358 foreach($aData as $index => $value) { 359 $tmp_percentage=$value/$sum*$mul; 360 $result[$index]=floor($tmp_percentage); 361 $tmp[$index]=$tmp_percentage-$result[$index]; 362 $quote_sum+=$result[$index]; 363 } 364 if( $quote_sum == $mul) { 365 if( $mul > 100 ) { 366 $tmp = $mul / 100; 367 for( $i=0; $i < $n; ++$i ) { 368 $result[$i] /= $tmp ; 369 } 370 } 371 return $result; 372 } 373 arsort($tmp,SORT_NUMERIC); 374 reset($tmp); 375 for($i=0; $i < $mul-$quote_sum; $i++) 376 { 377 $result[key($tmp)]++; 378 next($tmp); 379 } 380 if( $mul > 100 ) { 381 $tmp = $mul / 100; 382 for( $i=0; $i < $n; ++$i ) { 383 $result[$i] /= $tmp ; 384 } 385 } 386 return $result; 392 387 } 393 388 394 389 395 390 function Stroke($img,$aaoption=0) { 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 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 659 641 660 642 function NormAngle($a) { 661 662 663 643 while( $a < 0 ) $a += 2*M_PI; 644 while( $a > 2*M_PI ) $a -= 2*M_PI; 645 return $a; 664 646 } 665 647 666 648 function Quadrant($a) { 667 668 669 670 671 672 673 674 675 649 $a=$this->NormAngle($a); 650 if( $a > 0 && $a <= M_PI/2 ) 651 return 0; 652 if( $a > M_PI/2 && $a <= M_PI ) 653 return 1; 654 if( $a > M_PI && $a <= 1.5*M_PI ) 655 return 2; 656 if( $a > 1.5*M_PI ) 657 return 3; 676 658 } 677 659 678 660 function StrokeGuideLabels($img,$xc,$yc,$radius) { 679 680 681 682 683 684 685 686 687 $incluster=false;// flag if we are currently in a cluster or not688 $clusters = array();// array of clusters689 $cidx=-1;// running cluster index690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 // If we cross a quadrant boundary we normally start a 706 707 708 709 // the cluster for q=1 is close to 12'a clock and the 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 $i++; 738 739 740 741 742 743 744 745 746 747 748 749 if( $q1 == 0 && $cidx > -1 && 750 $clusters[$cidx][1] == 1 && 751 752 753 754 755 756 757 758 759 760 else { 761 762 763 764 765 $clusters[$cidx][1] = 1; 766 767 768 769 770 771 772 773 774 775 776 777 $clusters[$cidx][1] = 1; 778 779 780 781 782 783 784 785 786 787 788 $clusters[$cidx][1] = 1; 789 790 791 792 if( true ) { 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 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 for($j=0; $j < $csize; ++$j) { 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 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 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 $this->StrokeLabel($label,$img,$xc,$yc,$a,$r); 917 if( $this->iShowGuideLineForSingle ) 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 661 $n = count($this->labels); 662 663 //----------------------------------------------------------------------- 664 // Step 1 of the algorithm is to construct a number of clusters 665 // a cluster is defined as all slices within the same quadrant (almost) 666 // that has an angular distance less than the treshold 667 //----------------------------------------------------------------------- 668 $tresh_hold=25 * M_PI/180; // 25 degrees difference to be in a cluster 669 $incluster=false; // flag if we are currently in a cluster or not 670 $clusters = array(); // array of clusters 671 $cidx=-1; // running cluster index 672 673 // Go through all the labels and construct a number of clusters 674 for($i=0; $i < $n-1; ++$i) { 675 // Calc the angle distance between two consecutive slices 676 $a1=$this->la[$i]; 677 $a2=$this->la[$i+1]; 678 $q1 = $this->Quadrant($a1); 679 $q2 = $this->Quadrant($a2); 680 $diff = abs($a1-$a2); 681 if( $diff < $tresh_hold ) { 682 if( $incluster ) { 683 $clusters[$cidx][1]++; 684 // Each cluster can only cover one quadrant 685 // Do we cross a quadrant ( and must break the cluster) 686 if( $q1 != $q2 ) { 687 // If we cross a quadrant boundary we normally start a 688 // new cluster. However we need to take the 12'a clock 689 // and 6'a clock positions into a special consideration. 690 // Case 1: WE go from q=1 to q=2 if the last slice on 691 // the cluster for q=1 is close to 12'a clock and the 692 // first slice in q=0 is small we extend the previous 693 // cluster 694 if( $q1 == 1 && $q2 == 0 && $a2 > (90-15)*M_PI/180 ) { 695 if( $i < $n-2 ) { 696 $a3 = $this->la[$i+2]; 697 // If there isn't a cluster coming up with the next-next slice 698 // we extend the previous cluster to cover this slice as well 699 if( abs($a3-$a2) >= $tresh_hold ) { 700 $clusters[$cidx][1]++; 701 $i++; 702 } 703 } 704 } 705 elseif( $q1 == 3 && $q2 == 2 && $a2 > (270-15)*M_PI/180 ) { 706 if( $i < $n-2 ) { 707 $a3 = $this->la[$i+2]; 708 // If there isn't a cluster coming up with the next-next slice 709 // we extend the previous cluster to cover this slice as well 710 if( abs($a3-$a2) >= $tresh_hold ) { 711 $clusters[$cidx][1]++; 712 $i++; 713 } 714 } 715 } 716 717 if( $q1==2 && $q2==1 && $a2 > (180-15)*M_PI/180 ) { 718 $clusters[$cidx][1]++; 719 $i++; 720 } 721 722 $incluster = false; 723 } 724 } 725 elseif( $q1 == $q2) { 726 $incluster = true; 727 // Now we have a special case for quadrant 0. If we previously 728 // have a cluster of one in quadrant 0 we just extend that 729 // cluster. If we don't do this then we risk that the label 730 // for the cluster of one will cross the guide-line 731 if( $q1 == 0 && $cidx > -1 && 732 $clusters[$cidx][1] == 1 && 733 $this->Quadrant($this->la[$clusters[$cidx][0]]) == 0 ) { 734 $clusters[$cidx][1]++; 735 } 736 else { 737 $cidx++; 738 $clusters[$cidx][0] = $i; 739 $clusters[$cidx][1] = 1; 740 } 741 } 742 else { 743 // Create a "cluster" of one since we are just crossing 744 // a quadrant 745 $cidx++; 746 $clusters[$cidx][0] = $i; 747 $clusters[$cidx][1] = 1; 748 } 749 } 750 else { 751 if( $incluster ) { 752 // Add the last slice 753 $clusters[$cidx][1]++; 754 $incluster = false; 755 } 756 else { // Create a "cluster" of one 757 $cidx++; 758 $clusters[$cidx][0] = $i; 759 $clusters[$cidx][1] = 1; 760 } 761 } 762 } 763 // Handle the very last slice 764 if( $incluster ) { 765 $clusters[$cidx][1]++; 766 } 767 else { // Create a "cluster" of one 768 $cidx++; 769 $clusters[$cidx][0] = $i; 770 $clusters[$cidx][1] = 1; 771 } 772 773 /* 774 if( true ) { 775 // Debug printout in labels 776 for( $i=0; $i <= $cidx; ++$i ) { 777 for( $j=0; $j < $clusters[$i][1]; ++$j ) { 778 $a = $this->la[$clusters[$i][0]+$j]; 779 $aa = round($a*180/M_PI); 780 $q = $this->Quadrant($a); 781 $this->labels[$clusters[$i][0]+$j]="[$q:$aa] $i:$j"; 782 } 783 } 784 } 785 */ 786 787 //----------------------------------------------------------------------- 788 // Step 2 of the algorithm is use the clusters and draw the labels 789 // and guidelines 790 //----------------------------------------------------------------------- 791 792 // We use the font height as the base factor for how far we need to 793 // spread the labels in the Y-direction. 794 $this->value->ApplyFont($img); 795 $fh = $img->GetFontHeight(); 796 $origvstep=$fh*$this->iGuideVFactor; 797 $this->value->SetMargin(0); 798 799 // Number of clusters found 800 $nc = count($clusters); 801 802 // Walk through all the clusters 803 for($i=0; $i < $nc; ++$i) { 804 805 // Start angle and number of slices in this cluster 806 $csize = $clusters[$i][1]; 807 $a = $this->la[$clusters[$i][0]]; 808 $q = $this->Quadrant($a); 809 810 // Now set up the start and end conditions to make sure that 811 // in each cluster we walk through the all the slices starting with the slice 812 // closest to the equator. Since all slices are numbered clockwise from "3'a clock" 813 // we have different conditions depending on in which quadrant the slice lies within. 814 if( $q == 0 ) { 815 $start = $csize-1; $idx = $start; $step = -1; $vstep = -$origvstep; 816 } 817 elseif( $q == 1 ) { 818 $start = 0; $idx = $start; $step = 1; $vstep = -$origvstep; 819 } 820 elseif( $q == 2 ) { 821 $start = $csize-1; $idx = $start; $step = -1; $vstep = $origvstep; 822 } 823 elseif( $q == 3 ) { 824 $start = 0; $idx = $start; $step = 1; $vstep = $origvstep; 825 } 826 827 // Walk through all slices within this cluster 828 for($j=0; $j < $csize; ++$j) { 829 // Now adjust the position of the labels in each cluster starting 830 // with the slice that is closest to the equator of the pie 831 $a = $this->la[$clusters[$i][0]+$idx]; 832 833 // Guide line start in the center of the arc of the slice 834 $r = $radius+$this->explode_radius[$n-1-($clusters[$i][0]+$idx)]; 835 $x = round($r*cos($a)+$xc); 836 $y = round($yc-$r*sin($a)); 837 838 // The distance from the arc depends on chosen font and the "R-Factor" 839 $r += $fh*$this->iGuideLineRFactor; 840 841 // Should the labels be placed curved along the pie or in straight columns 842 // outside the pie? 843 if( $this->iGuideLineCurve ) 844 $xt=round($r*cos($a)+$xc); 845 846 // If this is the first slice in the cluster we need some first time 847 // proessing 848 if( $idx == $start ) { 849 if( ! $this->iGuideLineCurve ) 850 $xt=round($r*cos($a)+$xc); 851 $yt=round($yc-$r*sin($a)); 852 853 // Some special consideration in case this cluster starts 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 // so it doesn't collide with 858 // the slice in the previous cluster 859 $prevcluster = ($i + ($nc-1) ) % $nc; 860 $previdx=$clusters[$prevcluster][0]+$clusters[$prevcluster][1]-1; 861 if( $q == 1 && $a > 160*M_PI/180 ) { 862 // Get the angle for the previous clusters last slice 863 $diff = abs($a-$this->la[$previdx]); 864 if( $diff < $tresh_hold ) { 865 $yt -= $fh; 866 } 867 } 868 elseif( $q == 3 && $a > 340*M_PI/180 ) { 869 // We need to subtract 360 to compare angle distance between 870 // q=0 and q=3 871 $diff = abs($a-$this->la[$previdx]-360*M_PI/180); 872 if( $diff < $tresh_hold ) { 873 $yt += $fh; 874 } 875 } 876 877 } 878 else { 879 // The step is at minimum $vstep but if the slices are relatively large 880 // we make sure that we add at least a step that corresponds to the vertical 881 // distance between the centers at the arc on the slice 882 $prev_a = $this->la[$clusters[$i][0]+($idx-$step)]; 883 $dy = abs($radius*(sin($a)-sin($prev_a))*1.2); 884 if( $vstep > 0 ) 885 $yt += max($vstep,$dy); 886 else 887 $yt += min($vstep,-$dy); 888 } 889 890 $label = $this->labels[$clusters[$i][0]+$idx]; 891 892 if( $csize == 1 ) { 893 // A "meta" cluster with only one slice 894 $r = $radius+$this->explode_radius[$n-1-($clusters[$i][0]+$idx)]; 895 $rr = $r+$img->GetFontHeight()/2; 896 $xt=round($rr*cos($a)+$xc); 897 $yt=round($yc-$rr*sin($a)); 898 $this->StrokeLabel($label,$img,$xc,$yc,$a,$r); 899 if( $this->iShowGuideLineForSingle ) 900 $this->guideline->Stroke($img,$x,$y,$xt,$yt); 901 } 902 else { 903 $this->guideline->Stroke($img,$x,$y,$xt,$yt); 904 if( $q==1 || $q==2 ) { 905 // Left side of Pie 906 $this->guideline->Stroke($img,$xt,$yt,$xt-$this->guidelinemargin,$yt); 907 $lbladj = -$this->guidelinemargin-5; 908 $this->value->halign = "right"; 909 $this->value->valign = "center"; 910 } 911 else { 912 // Right side of pie 913 $this->guideline->Stroke($img,$xt,$yt,$xt+$this->guidelinemargin,$yt); 914 $lbladj = $this->guidelinemargin+5; 915 $this->value->halign = "left"; 916 $this->value->valign = "center"; 917 } 918 $this->value->Stroke($img,$label,$xt+$lbladj,$yt); 919 } 920 921 // Udate idx to point to next slice in the cluster to process 922 $idx += $step; 923 } 924 } 943 925 } 944 926 945 927 function StrokeAllLabels($img,$xc,$yc,$radius) { 946 947 948 949 950 951 952 953 954 955 956 957 958 959 $radius + $this->explode_radius[$n-1-$i]); 960 961 928 // First normalize all angles for labels 929 $n = count($this->la); 930 for($i=0; $i < $n; ++$i) { 931 $this->la[$i] = $this->NormAngle($this->la[$i]); 932 } 933 if( $this->guideline->iShow ) { 934 $this->StrokeGuideLabels($img,$xc,$yc,$radius); 935 } 936 else { 937 $n = count($this->labels); 938 for($i=0; $i < $n; ++$i) { 939 $this->StrokeLabel($this->labels[$i],$img,$xc,$yc, 940 $this->la[$i], 941 $radius + $this->explode_radius[$n-1-$i]); 942 } 943 } 962 944 } 963 945 … … 965 947 function StrokeLabel($label,$img,$xc,$yc,$a,$r) { 966 948 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 } 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 } 1038 1016 } // Class 1039 1017 … … 1041 1019 //=================================================== 1042 1020 // CLASS PiePlotC 1043 // Description: Same as a normal pie plot but with a 1021 // Description: Same as a normal pie plot but with a 1044 1022 // filled circle in the center 1045 1023 //=================================================== 1046 1024 class PiePlotC extends PiePlot { 1047 private $imidsize=0.5; 1025 private $imidsize=0.5; // Fraction of total width 1048 1026 private $imidcolor='white'; 1049 1027 public $midtitle=''; 1050 1028 private $middlecsimtarget='',$middlecsimwintarget='',$middlecsimalt=''; 1051 1029 1052 function __construct($data,$aCenterTitle='') {1053 parent::__construct($data);1054 1055 1030 function PiePlotC($data,$aCenterTitle='') { 1031 parent::PiePlot($data); 1032 $this->midtitle = new Text(); 1033 $this->midtitle->ParagraphAlign('center'); 1056 1034 } 1057 1035 1058 1036 function SetMid($aTitle,$aColor='white',$aSize=0.5) { 1059 1060 1061 $this->imidsize = $aSize ; 1062 $this->imidcolor = $aColor ; 1037 $this->midtitle->Set($aTitle); 1038 1039 $this->imidsize = $aSize ; 1040 $this->imidcolor = $aColor ; 1063 1041 } 1064 1042 1065 1043 function SetMidTitle($aTitle) { 1066 1044 $this->midtitle->Set($aTitle); 1067 1045 } 1068 1046 1069 1047 function SetMidSize($aSize) { 1070 $this->imidsize = $aSize ; 1048 $this->imidsize = $aSize ; 1071 1049 } 1072 1050 1073 1051 function SetMidColor($aColor) { 1074 $this->imidcolor = $aColor ; 1052 $this->imidcolor = $aColor ; 1075 1053 } 1076 1054 1077 1055 function SetMidCSIM($aTarget,$aAlt='',$aWinTarget='') { 1078 1079 1080 1081 } 1082 1083 function AddSliceToCSIM($i,$xc,$yc,$radius,$sa,$ea) { 1056 $this->middlecsimtarget = $aTarget; 1057 $this->middlecsimwintarget = $aWinTarget; 1058 $this->middlecsimalt = $aAlt; 1059 } 1060 1061 function AddSliceToCSIM($i,$xc,$yc,$radius,$sa,$ea) { 1084 1062 //Slice number, ellipse centre (x,y), radius, start angle, end angle 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 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 $coords.= ", $xp, $yp"; 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1063 while( $sa > 2*M_PI ) $sa = $sa - 2*M_PI; 1064 while( $ea > 2*M_PI ) $ea = $ea - 2*M_PI; 1065 1066 $sa = 2*M_PI - $sa; 1067 $ea = 2*M_PI - $ea; 1068 1069 // Special case when we have only one slice since then both start and end 1070 // angle will be == 0 1071 if( abs($sa - $ea) < 0.0001 ) { 1072 $sa=2*M_PI; $ea=0; 1073 } 1074 1075 // Add inner circle first point 1076 $xp = floor(($this->imidsize*$radius*cos($ea))+$xc); 1077 $yp = floor($yc-($this->imidsize*$radius*sin($ea))); 1078 $coords = "$xp, $yp"; 1079 1080 //add coordinates every 0.25 radians 1081 $a=$ea+0.25; 1082 1083 // If we cross the 360-limit with a slice we need to handle 1084 // the fact that end angle is smaller than start 1085 if( $sa < $ea ) { 1086 while ($a <= 2*M_PI) { 1087 $xp = floor($radius*cos($a)+$xc); 1088 $yp = floor($yc-$radius*sin($a)); 1089 $coords.= ", $xp, $yp"; 1090 $a += 0.25; 1091 } 1092 $a -= 2*M_PI; 1093 } 1094 1095 while ($a < $sa) { 1096 $xp = floor(($this->imidsize*$radius*cos($a)+$xc)); 1097 $yp = floor($yc-($this->imidsize*$radius*sin($a))); 1098 $coords.= ", $xp, $yp"; 1099 $a += 0.25; 1100 } 1101 1102 // Make sure we end at the last point 1103 $xp = floor(($this->imidsize*$radius*cos($sa)+$xc)); 1104 $yp = floor($yc-($this->imidsize*$radius*sin($sa))); 1105 $coords.= ", $xp, $yp"; 1106 1107 // Straight line to outer circle 1108 $xp = floor($radius*cos($sa)+$xc); 1109 $yp = floor($yc-$radius*sin($sa)); 1110 $coords.= ", $xp, $yp"; 1111 1112 //add coordinates every 0.25 radians 1113 $a=$sa - 0.25; 1114 while ($a > $ea) { 1115 $xp = floor($radius*cos($a)+$xc); 1116 $yp = floor($yc-$radius*sin($a)); 1117 $coords.= ", $xp, $yp"; 1118 $a -= 0.25; 1119 } 1120 1121 //Add the last point on the arc 1122 $xp = floor($radius*cos($ea)+$xc); 1123 $yp = floor($yc-$radius*sin($ea)); 1124 $coords.= ", $xp, $yp"; 1125 1126 // Close the arc 1127 $xp = floor(($this->imidsize*$radius*cos($ea))+$xc); 1128 $yp = floor($yc-($this->imidsize*$radius*sin($ea))); 1129 $coords .= ", $xp, $yp"; 1130 1131 if( !empty($this->csimtargets[$i]) ) { 1132 $this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"". 1133 $this->csimtargets[$i]."\""; 1134 if( !empty($this->csimwintargets[$i]) ) { 1135 $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; 1136 } 1137 if( !empty($this->csimalts[$i]) ) { 1138 $tmp=sprintf($this->csimalts[$i],$this->data[$i]); 1139 $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" "; 1140 } 1141 $this->csimareas .= " />\n"; 1142 } 1165 1143 } 1166 1144 … … 1168 1146 function Stroke($img,$aaoption=0) { 1169 1147 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1148 // Stroke the pie but don't stroke values 1149 $tmp = $this->value->show; 1150 $this->value->show = false; 1151 parent::Stroke($img,$aaoption); 1152 $this->value->show = $tmp; 1153 1154 $xc = round($this->posx*$img->width); 1155 $yc = round($this->posy*$img->height); 1156 1157 $radius = floor($this->radius * min($img->width,$img->height)) ; 1158 1159 1160 if( $this->imidsize > 0 && $aaoption !== 2 ) { 1161 1162 if( $this->ishadowcolor != "" ) { 1163 $img->SetColor($this->ishadowcolor); 1164 $img->FilledCircle($xc+$this->ishadowdrop,$yc+$this->ishadowdrop, 1165 round($radius*$this->imidsize)); 1166 } 1167 1168 $img->SetColor($this->imidcolor); 1169 $img->FilledCircle($xc,$yc,round($radius*$this->imidsize)); 1170 1171 if( $this->pie_border && $aaoption === 0 ) { 1172 $img->SetColor($this->color); 1173 $img->Circle($xc,$yc,round($radius*$this->imidsize)); 1174 } 1175 1176 if( !empty($this->middlecsimtarget) ) 1177 $this->AddMiddleCSIM($xc,$yc,round($radius*$this->imidsize)); 1178 1179 } 1180 1181 if( $this->value->show && $aaoption !== 1) { 1182 $this->StrokeAllLabels($img,$xc,$yc,$radius); 1183 $this->midtitle->SetPos($xc,$yc,'center','center'); 1184 $this->midtitle->Stroke($img); 1185 } 1208 1186 1209 1187 } 1210 1188 1211 1189 function AddMiddleCSIM($xc,$yc,$r) { 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1190 $xc=round($xc);$yc=round($yc);$r=round($r); 1191 $this->csimareas .= "<area shape=\"circle\" coords=\"$xc,$yc,$r\" href=\"". 1192 $this->middlecsimtarget."\""; 1193 if( !empty($this->middlecsimwintarget) ) { 1194 $this->csimareas .= " target=\"".$this->middlecsimwintarget."\""; 1195 } 1196 if( !empty($this->middlecsimalt) ) { 1197 $tmp = $this->middlecsimalt; 1198 $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" "; 1199 } 1200 $this->csimareas .= " />\n"; 1223 1201 } 1224 1202 1225 1203 function StrokeLabel($label,$img,$xc,$yc,$a,$r) { 1226 1204 1227 1228 1229 1230 1205 if( $this->ilabelposadj === 'auto' ) 1206 $this->ilabelposadj = (1-$this->imidsize)/2+$this->imidsize; 1207 1208 parent::StrokeLabel($label,$img,$xc,$yc,$a,$r); 1231 1209 1232 1210 } … … 1237 1215 //=================================================== 1238 1216 // CLASS PieGraph 1239 // Description: 1217 // Description: 1240 1218 //=================================================== 1241 1219 class PieGraph extends Graph { 1242 private $posx, $posy, $radius; 1243 private $legends=array(); 1220 private $posx, $posy, $radius; 1221 private $legends=array(); 1244 1222 public $plots=array(); 1245 1223 public $pieaa = false ; 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 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 1261 1235 function Add($aObj) { 1262 1236 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 } 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 } 1296 1257 } 1297 1258 1298 1259 function SetAntiAliasing($aFlg=true) { 1299 1300 } 1301 1260 $this->pieaa = $aFlg; 1261 } 1262 1302 1263 function SetColor($c) { 1303 1264 $this->SetMarginColor($c); 1304 1265 } 1305 1266 1306 1267 1307 1268 function DisplayCSIMAreas() { 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 } 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 } 1336 1296 } 1337 1297 1338 1298 // Method description 1339 1299 function Stroke($aStrokeFileName="") { 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 } 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 } 1493 1445 } 1494 1446 } // Class -
trunk/client/modules/Elezioni/grafici/jpgraph_pie3d.php
r265 r267 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_PIE3D.PHP4 5 // Created:2001-03-246 // Ver: $Id: jpgraph_pie3d.php 1329 2009-06-20 19:23:30Z ljp $7 8 // Copyright (c) Asial Corporation. 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 956 2007-11-17 13:19:20Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. 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 25 function __construct($data) {26 27 28 29 30 31 32 33 } 34 35 36 // PUBLIC METHODS 37 22 23 //--------------- 24 // CONSTRUCTOR 25 function PiePlot3d($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; 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.'); 63 69 } 64 70 … … 66 72 // Must be between 20 and 70 degrees 67 73 function SetAngle($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 } 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; 75 79 } 76 80 77 81 function Add3DSliceToCSIM($i,$xc,$yc,$height,$width,$thick,$sa,$ea) { //Slice number, ellipse centre (x,y), height, width, start angle, end angle 78 82 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 $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; 125 126 127 if( !empty($this->csimalts[$i]) ) { 128 129 130 131 132 83 $sa *= M_PI/180; 84 $ea *= M_PI/180; 85 86 //add coordinates of the centre to the map 87 $coords = "$xc, $yc"; 88 89 //add coordinates of the first point on the arc to the map 90 $xp = floor($width*cos($sa)/2+$xc); 91 $yp = floor($yc-$height*sin($sa)/2); 92 $coords.= ", $xp, $yp"; 93 94 //If on the front half, add the thickness offset 95 if ($sa >= M_PI && $sa <= 2*M_PI*1.01) { 96 $yp = floor($yp+$thick); 97 $coords.= ", $xp, $yp"; 98 } 99 100 //add coordinates every 0.2 radians 101 $a=$sa+0.2; 102 while ($a<$ea) { 103 $xp = floor($width*cos($a)/2+$xc); 104 if ($a >= M_PI && $a <= 2*M_PI*1.01) { 105 $yp = floor($yc-($height*sin($a)/2)+$thick); 106 } else { 107 $yp = floor($yc-$height*sin($a)/2); 108 } 109 $coords.= ", $xp, $yp"; 110 $a += 0.2; 111 } 112 113 //Add the last point on the arc 114 $xp = floor($width*cos($ea)/2+$xc); 115 $yp = floor($yc-$height*sin($ea)/2); 116 117 118 if ($ea >= M_PI && $ea <= 2*M_PI*1.01) { 119 $coords.= ", $xp, ".floor($yp+$thick); 120 } 121 $coords.= ", $xp, $yp"; 122 $alt=''; 123 124 if( !empty($this->csimtargets[$i]) ) { 125 $this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->csimtargets[$i]."\""; 126 127 if( !empty($this->csimwintargets[$i]) ) { 128 $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; 129 } 130 131 if( !empty($this->csimalts[$i]) ) { 132 $tmp=sprintf($this->csimalts[$i],$this->data[$i]); 133 $this->csimareas .= "alt=\"$tmp\" title=\"$tmp\" "; 134 } 135 $this->csimareas .= " />\n"; 136 } 133 137 134 138 } 135 139 136 140 function SetLabels($aLabels,$aLblPosAdj="auto") { 137 138 139 } 140 141 141 $this->labels = $aLabels; 142 $this->ilabelposadj=$aLblPosAdj; 143 } 144 145 142 146 // Distance from the pie to the labels 143 147 function SetLabelMargin($m) { 144 145 } 146 148 $this->value->SetMargin($m); 149 } 150 147 151 // Show a thin line from the pie to the label for a specific slice 148 152 function ShowLabelHint($f=true) { 149 150 } 151 153 $this->showlabelhint=$f; 154 } 155 152 156 // Set color of hint line to label for each slice 153 157 function SetLabelHintColor($c) { 154 158 $this->labelhintcolor=$c; 155 159 } 156 160 157 161 function SetHeight($aHeight) { 158 159 } 160 161 162 162 $this->iThickness = $aHeight; 163 } 164 165 166 // Normalize Angle between 0-360 163 167 function NormAngle($a) { 164 165 // 166 167 168 169 170 171 172 173 174 175 176 177 } 178 179 180 181 168 // Normalize anle to 0 to 2M_PI 169 // 170 if( $a > 0 ) { 171 while($a > 360) $a -= 360; 172 } 173 else { 174 while($a < 0) $a += 360; 175 } 176 if( $a < 0 ) 177 $a = 360 + $a; 178 179 if( $a == 360 ) $a=0; 180 return $a; 181 } 182 183 184 185 // Draw one 3D pie slice at position ($xc,$yc) with height $z 182 186 function Pie3DSlice($img,$xc,$yc,$w,$h,$sa,$ea,$z,$fillcolor,$shadow=0.65) { 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 $rsa = $sa/180*M_PI;// to Rad198 $rea = $ea/180*M_PI;// to Rad199 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 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 $tsa = sin($a); 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 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 187 188 // Due to the way the 3D Pie algorithm works we are 189 // guaranteed that any slice we get into this method 190 // belongs to either the left or right side of the 191 // pie ellipse. Hence, no slice will cross 90 or 270 192 // point. 193 if( ($sa < 90 && $ea > 90) || ( ($sa > 90 && $sa < 270) && $ea > 270) ) { 194 JpGraphError::RaiseL(14003);//('Internal assertion failed. Pie3D::Pie3DSlice'); 195 exit(1); 196 } 197 198 $p[] = array(); 199 200 // Setup pre-calculated values 201 $rsa = $sa/180*M_PI; // to Rad 202 $rea = $ea/180*M_PI; // to Rad 203 $sinsa = sin($rsa); 204 $cossa = cos($rsa); 205 $sinea = sin($rea); 206 $cosea = cos($rea); 207 208 // p[] is the points for the overall slice and 209 // pt[] is the points for the top pie 210 211 // Angular step when approximating the arc with a polygon train. 212 $step = 0.05; 213 214 if( $sa >= 270 ) { 215 if( $ea > 360 || ($ea > 0 && $ea <= 90) ) { 216 if( $ea > 0 && $ea <= 90 ) { 217 // Adjust angle to simplify conditions in loops 218 $rea += 2*M_PI; 219 } 220 221 $p = array($xc,$yc,$xc,$yc+$z, 222 $xc+$w*$cossa,$z+$yc-$h*$sinsa); 223 $pt = array($xc,$yc,$xc+$w*$cossa,$yc-$h*$sinsa); 224 225 for( $a=$rsa; $a < 2*M_PI; $a += $step ) { 226 $tca = cos($a); 227 $tsa = sin($a); 228 $p[] = $xc+$w*$tca; 229 $p[] = $z+$yc-$h*$tsa; 230 $pt[] = $xc+$w*$tca; 231 $pt[] = $yc-$h*$tsa; 232 } 233 234 $pt[] = $xc+$w; 235 $pt[] = $yc; 236 237 $p[] = $xc+$w; 238 $p[] = $z+$yc; 239 $p[] = $xc+$w; 240 $p[] = $yc; 241 $p[] = $xc; 242 $p[] = $yc; 243 244 for( $a=2*M_PI+$step; $a < $rea; $a += $step ) { 245 $pt[] = $xc + $w*cos($a); 246 $pt[] = $yc - $h*sin($a); 247 } 248 249 $pt[] = $xc+$w*$cosea; 250 $pt[] = $yc-$h*$sinea; 251 $pt[] = $xc; 252 $pt[] = $yc; 253 254 } 255 else { 256 $p = array($xc,$yc,$xc,$yc+$z, 257 $xc+$w*$cossa,$z+$yc-$h*$sinsa); 258 $pt = array($xc,$yc,$xc+$w*$cossa,$yc-$h*$sinsa); 259 260 $rea = $rea == 0.0 ? 2*M_PI : $rea; 261 for( $a=$rsa; $a < $rea; $a += $step ) { 262 $tca = cos($a); 263 $tsa = sin($a); 264 $p[] = $xc+$w*$tca; 265 $p[] = $z+$yc-$h*$tsa; 266 $pt[] = $xc+$w*$tca; 267 $pt[] = $yc-$h*$tsa; 268 } 269 270 $pt[] = $xc+$w*$cosea; 271 $pt[] = $yc-$h*$sinea; 272 $pt[] = $xc; 273 $pt[] = $yc; 274 275 $p[] = $xc+$w*$cosea; 276 $p[] = $z+$yc-$h*$sinea; 277 $p[] = $xc+$w*$cosea; 278 $p[] = $yc-$h*$sinea; 279 $p[] = $xc; 280 $p[] = $yc; 281 } 282 } 283 elseif( $sa >= 180 ) { 284 $p = array($xc,$yc,$xc,$yc+$z,$xc+$w*$cosea,$z+$yc-$h*$sinea); 285 $pt = array($xc,$yc,$xc+$w*$cosea,$yc-$h*$sinea); 286 287 for( $a=$rea; $a>$rsa; $a -= $step ) { 288 $tca = cos($a); 289 $tsa = sin($a); 290 $p[] = $xc+$w*$tca; 291 $p[] = $z+$yc-$h*$tsa; 292 $pt[] = $xc+$w*$tca; 293 $pt[] = $yc-$h*$tsa; 294 } 295 296 $pt[] = $xc+$w*$cossa; 297 $pt[] = $yc-$h*$sinsa; 298 $pt[] = $xc; 299 $pt[] = $yc; 300 301 $p[] = $xc+$w*$cossa; 302 $p[] = $z+$yc-$h*$sinsa; 303 $p[] = $xc+$w*$cossa; 304 $p[] = $yc-$h*$sinsa; 305 $p[] = $xc; 306 $p[] = $yc; 307 308 } 309 elseif( $sa >= 90 ) { 310 if( $ea > 180 ) { 311 $p = array($xc,$yc,$xc,$yc+$z,$xc+$w*$cosea,$z+$yc-$h*$sinea); 312 $pt = array($xc,$yc,$xc+$w*$cosea,$yc-$h*$sinea); 313 314 for( $a=$rea; $a > M_PI; $a -= $step ) { 315 $tca = cos($a); 316 $tsa = sin($a); 317 $p[] = $xc+$w*$tca; 318 $p[] = $z + $yc - $h*$tsa; 319 $pt[] = $xc+$w*$tca; 320 $pt[] = $yc-$h*$tsa; 321 } 322 323 $p[] = $xc-$w; 324 $p[] = $z+$yc; 325 $p[] = $xc-$w; 326 $p[] = $yc; 327 $p[] = $xc; 328 $p[] = $yc; 329 330 $pt[] = $xc-$w; 331 $pt[] = $z+$yc; 332 $pt[] = $xc-$w; 333 $pt[] = $yc; 334 335 for( $a=M_PI-$step; $a > $rsa; $a -= $step ) { 336 $pt[] = $xc + $w*cos($a); 337 $pt[] = $yc - $h*sin($a); 338 } 339 340 $pt[] = $xc+$w*$cossa; 341 $pt[] = $yc-$h*$sinsa; 342 $pt[] = $xc; 343 $pt[] = $yc; 344 345 } 346 else { // $sa >= 90 && $ea <= 180 347 $p = array($xc,$yc,$xc,$yc+$z, 348 $xc+$w*$cosea,$z+$yc-$h*$sinea, 349 $xc+$w*$cosea,$yc-$h*$sinea, 350 $xc,$yc); 351 352 $pt = array($xc,$yc,$xc+$w*$cosea,$yc-$h*$sinea); 353 354 for( $a=$rea; $a>$rsa; $a -= $step ) { 355 $pt[] = $xc + $w*cos($a); 356 $pt[] = $yc - $h*sin($a); 357 } 358 359 $pt[] = $xc+$w*$cossa; 360 $pt[] = $yc-$h*$sinsa; 361 $pt[] = $xc; 362 $pt[] = $yc; 363 364 } 365 } 366 else { // sa > 0 && ea < 90 367 368 $p = array($xc,$yc,$xc,$yc+$z, 369 $xc+$w*$cossa,$z+$yc-$h*$sinsa, 370 $xc+$w*$cossa,$yc-$h*$sinsa, 371 $xc,$yc); 372 373 $pt = array($xc,$yc,$xc+$w*$cossa,$yc-$h*$sinsa); 374 375 for( $a=$rsa; $a < $rea; $a += $step ) { 376 $pt[] = $xc + $w*cos($a); 377 $pt[] = $yc - $h*sin($a); 378 } 379 380 $pt[] = $xc+$w*$cosea; 381 $pt[] = $yc-$h*$sinea; 382 $pt[] = $xc; 383 $pt[] = $yc; 384 } 385 386 $img->PushColor($fillcolor.":".$shadow); 387 $img->FilledPolygon($p); 388 $img->PopColor(); 389 390 $img->PushColor($fillcolor); 391 $img->FilledPolygon($pt); 392 $img->PopColor(); 389 393 } 390 394 391 395 function SetStartAngle($aStart) { 392 393 394 395 396 } 397 398 396 if( $aStart < 0 || $aStart > 360 ) { 397 JpGraphError::RaiseL(14004);//('Slice start angle must be between 0 and 360 degrees.'); 398 } 399 $this->startangle = $aStart; 400 } 401 402 // Draw a 3D Pie 399 403 function Pie3D($aaoption,$img,$data,$colors,$xc,$yc,$d,$angle,$z, 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(); 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(); 716 723 } 717 724 718 725 function StrokeFullSliceFrame($img,$xc,$yc,$sa,$ea,$w,$h,$z,$edgecolor,$exploderadius,$fulledge) { 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 } 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 } 776 781 } 777 782 778 783 function Stroke($img,$aaoption=0) { 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 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 872 869 873 870 // Position the labels of each slice 874 871 function StrokeLabels($label,$img,$a,$xp,$yp,$z) { 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 } 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 } 930 920 } // Class 931 921 -
trunk/client/modules/Elezioni/grafici/jpgraph_plotband.php
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph_plotband.php 1106 2009-02-22 20:16:35Z 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 1091 2009-01-18 22:57:40Z ljp $ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. 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 __construct($aX,$aY,$aWidth,$aHeight) {27 28 29 30 31 32 26 function Rectangle($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 __construct($aColor,$aWeight=1) {52 53 $this->weight = $aWeight; 50 51 function RectPattern($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 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 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 __construct($aColor="black",$aWeight=1) {109 parent::__construct($aColor,$aWeight);110 } 111 112 function DoPattern($aImg) { 113 114 115 108 function RectPatternSolid($aColor="black",$aWeight=1) { 109 parent::RectPattern($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 __construct($aColor="black",$aWeight=1,$aLineSpacing=7) {126 parent::__construct($aColor,$aWeight);127 128 } 129 130 function DoPattern($aImg) { 131 $x0 = $this->rect->x; 132 133 134 135 136 137 124 125 function RectPatternHor($aColor="black",$aWeight=1,$aLineSpacing=7) { 126 parent::RectPattern($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 __construct($aColor="black",$aWeight=1,$aLineSpacing=7) {148 parent::__construct($aColor,$aWeight);149 146 147 function RectPatternVert($aColor="black",$aWeight=1,$aLineSpacing=7) { 148 parent::RectPattern($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 __construct($aColor="black",$aWeight=1,$aLineSpacing=12) {174 parent::__construct($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 RectPatternRDiag($aColor="black",$aWeight=1,$aLineSpacing=12) { 174 parent::RectPattern($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 __construct($aColor="black",$aWeight=1,$aLineSpacing=12) {243 244 parent::__construct($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 RectPatternLDiag($aColor="black",$aWeight=1,$aLineSpacing=12) { 243 $this->linespacing = $aLineSpacing; 244 parent::RectPattern($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 __construct($aColor="black",$aWeight=1) {311 parent::__construct($aColor,$aWeight);312 310 function RectPattern3DPlane($aColor="black",$aWeight=1) { 311 parent::RectPattern($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 __construct($aColor="black",$aWeight=1) {425 parent::__construct($aColor,$aWeight);426 427 424 function RectPatternCross($aColor="black",$aWeight=1) { 425 parent::RectPattern($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 __construct($aColor="black",$aWeight=1) {461 parent::__construct($aColor,$aWeight);462 463 460 function RectPatternDiagCross($aColor="black",$aWeight=1) { 461 parent::RectPattern($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 __construct() {495 494 function RectPatternFactory() { 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 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 __construct($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 549 550 551 552 553 } 554 543 function PlotBand($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
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph_plotmark.inc.php 1106 2009-02-22 20:16:35Z ljp $3 // File: JPGRAPH_PLOTMARK.PHP 4 // Description: Class file. Handles plotmarks 5 // Created: 2003-03-21 6 // Ver: $Id: jpgraph_plotmark.inc.php 956 2007-11-17 13:19:20Z ljp $ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. All rights reserved. 9 9 //======================================================================== 10 10 … … 31 31 private $imgdata_pushpins = null; 32 32 33 34 35 function __construct() {36 37 38 39 40 } 41 42 // PUBLIC METHODS 33 //-------------- 34 // CONSTRUCTOR 35 function PlotMark() { 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 $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"; 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 function AddCSIMCircle($x,$y,$r) { 149 $x = round($x); $y=round($y); $r=round($r); 150 $this->csimareas=""; 151 if( !empty($this->csimtarget) ) { 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"; 145 163 } 146 164 } 147 148 function AddCSIMCircle($x,$y,$r) { 149 $x = round($x); $y=round($y); $r=round($r); 150 $this->csimareas=""; 151 if( !empty($this->csimtarget) ) { 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 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 // Empty456 }457 458 453 // Create a GD image from the data and return a GD handle 459 454 function GetImg($aMark,$aIdx) { 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 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 } 476 470 function GetAnchor() { 477 471 return array($this->anchor_x,$this->anchor_y); 478 472 } 479 473 } … … 482 476 // Keep a global flag cache to reduce memory usage 483 477 $_gFlagCache=array( 484 1 => null,485 2 => null,486 3 => null,487 4 => null,478 1 => null, 479 2 => null, 480 3 => null, 481 4 => null, 488 482 ); 489 483 // Only supposed to b called as statics 490 484 class FlagCache { 491 492 485 static function GetFlagImgByName($aSize,$aName) { 493 494 495 496 497 498 499 500 486 global $_gFlagCache; 487 require_once('jpgraph_flags.php'); 488 if( $_gFlagCache[$aSize] === null ) { 489 $_gFlagCache[$aSize] = new FlagImages($aSize); 490 } 491 $f = $_gFlagCache[$aSize]; 492 $idx = $f->GetIdxByName($aName,$aFullName); 493 return $f->GetImgByIdx($idx); 501 494 } 502 495 } -
trunk/client/modules/Elezioni/grafici/jpgraph_polar.php
r265 r267 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 1796 2009-09-07 09:37:19Z ljp $7 8 // Copyright (c) Asial Corporation. 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 1091 2009-01-18 22:57:40Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. 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 __construct($aData) {49 50 51 52 53 54 55 56 48 function PolarPlot($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 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!=''); 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!=''); 145 144 } 146 145 } … … 160 159 private $radius_tick_color='black'; 161 160 162 function __construct($img,$aScale) {163 parent::__construct($img,$aScale);161 function PolarAxis($img,$aScale) { 162 parent::Axis($img,$aScale); 164 163 } 165 164 166 165 function ShowAngleDegreeMark($aFlg=true) { 167 166 $this->show_angle_mark = $aFlg; 168 167 } 169 168 170 169 function SetAngleStep($aStep) { 171 170 $this->angle_step=$aStep; 172 171 } 173 172 174 173 function HideTicks($aFlg=true,$aAngleFlg=true) { 175 176 174 parent::HideTicks($aFlg,$aFlg); 175 $this->show_angle_tick = !$aAngleFlg; 177 176 } 178 177 179 178 function ShowAngleLabel($aFlg=true) { 180 179 $this->show_angle_label = $aFlg; 181 180 } 182 181 183 182 function ShowGrid($aMajor=true,$aMinor=false,$aAngle=true) { 184 185 186 183 $this->show_minor_grid = $aMinor; 184 $this->show_major_grid = $aMajor; 185 $this->show_angle_grid = $aAngle ; 187 186 } 188 187 189 188 function SetAngleFont($aFontFam,$aFontStyle=FS_NORMAL,$aFontSize=10) { 190 191 192 189 $this->angle_fontfam = $aFontFam; 190 $this->angle_fontstyle = $aFontStyle; 191 $this->angle_fontsize = $aFontSize; 193 192 } 194 193 195 194 function SetColor($aColor,$aRadColor='',$aAngleColor='') { 196 197 198 199 195 if( $aAngleColor == '' ) 196 $aAngleColor=$aColor; 197 parent::SetColor($aColor,$aRadColor); 198 $this->angle_fontcolor = $aAngleColor; 200 199 } 201 200 202 201 function SetGridColor($aMajorColor,$aMinorColor='',$aAngleColor='') { 203 if( $aMinorColor == '' ) 204 205 if( $aAngleColor == '' ) 206 207 208 209 210 202 if( $aMinorColor == '' ) 203 $aMinorColor = $aMajorColor; 204 if( $aAngleColor == '' ) 205 $aAngleColor = $aMajorColor; 206 207 $this->gridminor_color = $aMinorColor; 208 $this->gridmajor_color = $aMajorColor; 209 $this->angle_color = $aAngleColor; 211 210 } 212 211 213 212 function SetTickColors($aRadColor,$aAngleColor='') { 214 215 216 } 217 213 $this->radius_tick_color = $aRadColor; 214 $this->angle_tick_color = $aAngleColor; 215 } 216 218 217 // Private methods 219 218 function StrokeGrid($pos) { 220 221 222 223 // Stroke the minor arcs 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 // Stroke the major arcs 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 219 $x = round($this->img->left_margin + $this->img->plotwidth/2); 220 $this->scale->ticks->Stroke($this->img,$this->scale,$pos); 221 222 // Stroke the minor arcs 223 $pmin = array(); 224 $p = $this->scale->ticks->ticks_pos; 225 $n = count($p); 226 $i = 0; 227 $this->img->SetColor($this->gridminor_color); 228 while( $i < $n ) { 229 $r = $p[$i]-$x+1; 230 $pmin[]=$r; 231 if( $this->show_minor_grid ) { 232 $this->img->Circle($x,$pos,$r); 233 } 234 $i++; 235 } 236 237 $limit = max($this->img->plotwidth,$this->img->plotheight)*1.4 ; 238 while( $r < $limit ) { 239 $off = $r; 240 $i=1; 241 $r = $off + round($p[$i]-$x+1); 242 while( $r < $limit && $i < $n ) { 243 $r = $off+$p[$i]-$x; 244 $pmin[]=$r; 245 if( $this->show_minor_grid ) { 246 $this->img->Circle($x,$pos,$r); 247 } 248 $i++; 249 } 250 } 251 252 // Stroke the major arcs 253 if( $this->show_major_grid ) { 254 // First determine how many minor step on 255 // every major step. We have recorded the minor radius 256 // in pmin and use these values. This is done in order 257 // to avoid rounding errors if we were to recalculate the 258 // different major radius. 259 $pmaj = $this->scale->ticks->maj_ticks_pos; 260 $p = $this->scale->ticks->ticks_pos; 261 if( $this->scale->name == 'lin' ) { 262 $step=round(($pmaj[1] - $pmaj[0])/($p[1] - $p[0])); 263 } 264 else { 265 $step=9; 266 } 267 $n = round(count($pmin)/$step); 268 $i = 0; 269 $this->img->SetColor($this->gridmajor_color); 270 $limit = max($this->img->plotwidth,$this->img->plotheight)*1.4 ; 271 $off = $r; 272 $i=0; 273 $r = $pmin[$i*$step]; 274 while( $r < $limit && $i < $n ) { 275 $r = $pmin[$i*$step]; 276 $this->img->Circle($x,$pos,$r); 277 $i++; 278 } 279 } 280 281 // Draw angles 282 if( $this->show_angle_grid ) { 283 $this->img->SetColor($this->angle_color); 284 $d = max($this->img->plotheight,$this->img->plotwidth)*1.4 ; 285 $a = 0; 286 $p = $this->scale->ticks->ticks_pos; 287 $start_radius = $p[1]-$x; 288 while( $a < 360 ) { 289 if( $a == 90 || $a == 270 ) { 290 // Make sure there are no rounding problem with 291 // exactly vertical lines 292 $this->img->Line($x+$start_radius*cos($a/180*M_PI)+1, 293 $pos-$start_radius*sin($a/180*M_PI), 294 $x+$start_radius*cos($a/180*M_PI)+1, 295 $pos-$d*sin($a/180*M_PI)); 296 297 } 298 else { 299 $this->img->Line($x+$start_radius*cos($a/180*M_PI)+1, 300 $pos-$start_radius*sin($a/180*M_PI), 301 $x+$d*cos($a/180*M_PI), 302 $pos-$d*sin($a/180*M_PI)); 303 } 304 $a += $this->angle_step; 305 } 306 } 308 307 } 309 308 310 309 function StrokeAngleLabels($pos,$type) { 311 310 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 } 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 } 495 480 } 496 481 497 482 function Stroke($pos,$dummy=true) { 498 483 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 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 530 513 // 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); 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); 590 571 } 591 572 } … … 593 574 class PolarScale extends LinearScale { 594 575 private $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; 576 577 function PolarScale($aMax=0,$graph) { 578 parent::LinearScale(0,$aMax,'x'); 579 $this->graph = $graph; 605 580 } 606 581 607 582 function _Translate($v) { 608 583 return parent::Translate($v); 609 584 } 610 585 611 586 function PTranslate($aAngle,$aRad) { 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); 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); 634 604 } 635 605 } … … 637 607 class PolarLogScale extends LogScale { 638 608 private $graph; 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; 609 function PolarLogScale($aMax=1,$graph) { 610 parent::LogScale(0,$aMax,'x'); 611 $this->graph = $graph; 612 $this->ticks->SetLabelLogType(LOGLABELS_MAGNITUDE); 613 651 614 } 652 615 653 616 function PTranslate($aAngle,$aRad) { 654 617 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); 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); 678 636 } 679 637 } … … 683 641 public $axis; 684 642 public $iType=POLAR_360; 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'); 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'); 692 649 } 693 650 694 651 function SetDensity($aDense) { 695 $this->SetTickDensity(TICKD_NORMAL,$aDense); 696 } 697 698 function SetClockwise($aFlg) { 699 $this->scale->SetClockwise($aFlg); 652 $this->SetTickDensity(TICKD_NORMAL,$aDense); 700 653 } 701 654 702 655 function Set90AndMargin($lm=0,$rm=0,$tm=0,$bm=0) { 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'); 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.'); 711 662 } 712 663 713 664 function SetScale($aScale,$rmax=0,$dummy1=1,$dummy2=1,$dummy3=1) { 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); 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); 726 676 } 727 677 728 678 function SetType($aType) { 729 679 $this->iType = $aType; 730 680 } 731 681 732 682 function SetPlotSize($w,$h) { 733 734 683 $this->SetMargin(($this->img->width-$w)/2,($this->img->width-$w)/2, 684 ($this->img->height-$h)/2,($this->img->height-$h)/2); 735 685 } 736 686 737 687 // Private methods 738 688 function GetPlotsMax() { 739 740 741 742 743 744 745 746 689 $n = count($this->plots); 690 $m = $this->plots[0]->Max(); 691 $i=1; 692 while($i < $n) { 693 $m = max($this->plots[$i]->Max(),$m); 694 ++$i; 695 } 696 return $m; 747 697 } 748 698 749 699 function Stroke($aStrokeFileName="") { 750 700 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 } 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 } 894 836 } 895 837 } -
trunk/client/modules/Elezioni/grafici/jpgraph_radar.php
r265 r267 1 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_RADAR.PHP4 5 // Created:2001-02-046 // Ver: $Id: jpgraph_radar.php 1783 2009-08-25 11:41:01Z ljp $7 8 // Copyright (c) Asial Corporation. 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 1044 2008-07-31 18:34:55Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. All rights reserved. 9 //======================================================================== 10 */ 11 11 12 12 require_once('jpgraph_plotmark.inc.php'); 13 13 14 //===================================================15 // CLASS RadarLogTicks16 // Description: Logarithmic ticks17 //===================================================18 14 class RadarLogTicks extends Ticks { 19 20 function __construct() { 21 // Empty 22 } 23 15 //--------------- 16 // CONSTRUCTOR 17 function RadarLogTicks() { 18 } 19 //--------------- 20 // PUBLIC METHODS 21 22 // TODO: Add Argument grid 24 23 function Stroke($aImg,&$grid,$aPos,$aAxisAngle,$aScale,&$aMajPos,&$aMajLabel) { 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 } 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 } 102 88 } 103 104 //=================================================== 105 // CLASS RadarLinear 106 // Description: Linear ticks 107 //=================================================== 108 class RadarLinearTicks extends Ticks { 89 90 class RadarLinearTicks extends Ticks { 109 91 110 92 private $minor_step=1, $major_step=2; 111 93 private $xlabel_offset=0,$xtick_offset=0; 112 94 113 function __construct() { 114 // Empty 115 } 116 95 //--------------- 96 // CONSTRUCTOR 97 function RadarLinearTicks() { 98 // Empty 99 } 100 101 //--------------- 102 // PUBLIC METHODS 103 104 117 105 // Return major step size in world coordinates 118 106 function GetMajor() { 119 120 } 121 107 return $this->major_step; 108 } 109 122 110 // Return minor step size in world coordinates 123 111 function GetMinor() { 124 125 } 126 112 return $this->minor_step; 113 } 114 127 115 // Set Minor and Major ticks (in world coordinates) 128 116 function Set($aMajStep,$aMinStep=false) { 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; 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; 141 131 } 142 132 143 133 function Stroke($aImg,&$grid,$aPos,$aAxisAngle,$aScale,&$aMajPos,&$aMajLabel) { 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 } 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 } 211 189 } 212 190 } 213 191 192 214 193 215 194 //=================================================== … … 219 198 class RadarAxis extends AxisPrototype { 220 199 public $title=null; 221 private $title_color= 'navy';200 private $title_color="navy"; 222 201 private $len=0; 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 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 234 221 // $aAxisAngle = Axis angle 235 // $grid 236 // $lf= Label flag, TRUE if the axis should have labels222 // $grid = Returns an array with positions used to draw the grid 223 // $lf = Label flag, TRUE if the axis should have labels 237 224 function Stroke($pos,$aAxisAngle,&$grid,$title,$lf) { 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 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 284 268 function _StrokeAxisTitle($pos,$aAxisAngle,$title) { 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 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 329 310 } // Class 330 311 … … 339 320 private $show=false, $weight=1; 340 321 341 function __construct() { 342 // Empty 343 } 344 322 //------------ 323 // CONSTRUCTOR 324 function RadarGrid() { 325 } 326 327 // PUBLIC METHODS 345 328 function SetColor($aMajColor) { 346 347 } 348 329 $this->grid_color = $aMajColor; 330 } 331 349 332 function SetWeight($aWeight) { 350 351 } 352 333 $this->weight=$aWeight; 334 } 335 353 336 // Specify if grid should be dashed, dotted or solid 354 337 function SetLineStyle($aType) { 355 356 } 357 338 $this->type = $aType; 339 } 340 358 341 // Decide if both major and minor grid should be displayed 359 342 function Show($aShowMajor=true) { 360 $this->show=$aShowMajor; 361 } 362 343 $this->show=$aShowMajor; 344 } 345 346 //---------------- 347 // PRIVATE METHODS 363 348 function Stroke($img,$grid) { 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 } 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 } 391 372 } 392 373 } // Class … … 399 380 class RadarPlot { 400 381 public $mark=null; 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 382 public $legend=""; 407 383 private $data=array(); 408 384 private $fill=false, $fill_color=array(200,170,180); … … 410 386 private $weight=1; 411 387 private $linestyle='solid'; 412 413 //--------------- 414 // CONSTRUCTOR 415 function __construct($data) { 416 $this->data = $data; 417 $this->mark = new PlotMark(); 418 } 419 388 //--------------- 389 // CONSTRUCTOR 390 function RadarPlot($data) { 391 $this->data = $data; 392 $this->mark = new PlotMark(); 393 } 394 395 //--------------- 396 // PUBLIC METHODS 420 397 function Min() { 421 422 } 423 398 return Min($this->data); 399 } 400 424 401 function Max() { 425 426 } 427 402 return Max($this->data); 403 } 404 428 405 function SetLegend($legend) { 429 406 $this->legend=$legend; 430 407 } 431 408 432 409 function SetLineStyle($aStyle) { 433 434 } 435 410 $this->linestyle=$aStyle; 411 } 412 436 413 function SetLineWeight($w) { 437 438 } 439 414 $this->weight=$w; 415 } 416 440 417 function SetFillColor($aColor) { 441 442 $this->fill = true; 443 } 444 418 $this->fill_color = $aColor; 419 $this->fill = true; 420 } 421 445 422 function SetFill($f=true) { 446 447 } 448 423 $this->fill = $f; 424 } 425 449 426 function SetColor($aColor,$aFillColor=false) { 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 427 $this->color = $aColor; 428 if( $aFillColor ) { 429 $this->SetFillColor($aFillColor); 430 $this->fill = true; 431 } 432 } 433 464 434 function GetCSIMareas() { 465 return $this->csimareas; 466 } 467 435 JpGraphError::RaiseL(18001); 436 //("Client side image maps not supported for RadarPlots."); 437 } 438 468 439 function Stroke($img, $pos, $scale, $startangle) { 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 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 533 489 function GetCount() { 534 535 } 536 490 return count($this->data); 491 } 492 537 493 function Legend($graph) { 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 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 548 501 } // Class 549 502 … … 555 508 public $grid,$axis=null; 556 509 private $posx,$posy; 557 private $len; 510 private $len; 558 511 private $axis_title=null; 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); 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); 569 533 } 570 534 571 535 function HideTickMarks($aFlag=true) { 572 573 } 574 536 $this->axis->scale->ticks->SupressTickMarks($aFlag); 537 } 538 575 539 function ShowMinorTickmarks($aFlag=true) { 576 577 } 578 540 $this->yscale->ticks->SupressMinorTickMarks(!$aFlag); 541 } 542 579 543 function SetScale($axtype,$ymin=1,$ymax=1,$dummy1=null,$dumy2=null) { 580 if( $axtype != 'lin' && $axtype != 'log') {581 582 583 584 if( $axtype == 'lin') {585 586 587 588 589 elseif( $axtype == 'log') {590 591 592 593 594 595 $this->grid = new RadarGrid(); 544 if( $axtype != "lin" && $axtype != "log" ) { 545 JpGraphError::RaiseL(18003,$axtype); 546 //("Illegal scale for radarplot ($axtype). Must be \"lin\" or \"log\""); 547 } 548 if( $axtype=="lin" ) { 549 $this->yscale = new LinearScale($ymin,$ymax); 550 $this->yscale->ticks = new RadarLinearTicks(); 551 $this->yscale->ticks->SupressMinorTickMarks(); 552 } 553 elseif( $axtype=="log" ) { 554 $this->yscale = new LogScale($ymin,$ymax); 555 $this->yscale->ticks = new RadarLogTicks(); 556 } 557 558 $this->axis = new RadarAxis($this->img,$this->yscale); 559 $this->grid = new RadarGrid(); 596 560 } 597 561 598 562 function SetSize($aSize) { 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; 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; 604 567 } 605 568 606 569 function SetPlotSize($aSize) { 607 570 $this->SetSize($aSize); 608 571 } 609 572 610 573 function SetTickDensity($densy=TICKD_NORMAL,$dummy1=null) { 611 $this->ytick_factor=25; 612 613 614 $this->ytick_factor=12; 615 616 617 $this->ytick_factor=25; 618 619 620 $this->ytick_factor=40; 621 622 623 $this->ytick_factor=70; 624 break; 625 626 627 628 574 $this->ytick_factor=25; 575 switch( $densy ) { 576 case TICKD_DENSE: 577 $this->ytick_factor=12; 578 break; 579 case TICKD_NORMAL: 580 $this->ytick_factor=25; 581 break; 582 case TICKD_SPARSE: 583 $this->ytick_factor=40; 584 break; 585 case TICKD_VERYSPARSE: 586 $this->ytick_factor=70; 587 break; 588 default: 589 JpGraphError::RaiseL(18005,$densy); 590 //("RadarPlot Unsupported Tick density: $densy"); 591 } 629 592 } 630 593 631 594 function SetPos($px,$py=0.5) { 632 595 $this->SetCenter($px,$py); 633 596 } 634 597 635 598 function SetCenter($px,$py=0.5) { 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 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 676 616 function GetPlotsYMinMax($aPlots) { 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 } 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 } 707 628 708 629 // Stroke the Radar graph 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 } 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 } 857 735 } 858 736 } // Class -
trunk/client/modules/Elezioni/grafici/jpgraph_regstat.php
r265 r267 1 <?php 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_REGSTAT.PHP4 5 // Created:2002-12-016 // Ver: $Id: jpgraph_regstat.php 1131 2009-03-11 20:08:24Z ljp $7 8 // Copyright (c) Asial Corporation. 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 781 2006-10-08 08:07:47Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. 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 __construct($xdata,$ydata) {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 $delta[$i] = ($ydata[$i+1]-$ydata[$i])/($xdata[$i+1]-$xdata[$i]) - 52 53 54 55 56 57 58 59 24 function Spline($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 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 115 116 117 118 * http://local.wasp.uwa.edu.au/~pbourke/geometry/bezier/index2.html119 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://astronomy.swin.edu.au/~pbourke/curves/bezier/ 119 */ 120 120 private $datax = array(); 121 121 private $datay = array(); 122 122 private $n=0; 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 */ 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 151 146 function Get($steps) { 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 */ 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 174 161 function GetPoint($mu) { 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 162 $n = $this->n - 1; 163 $k = 0; 164 $kn = 0; 165 $nn = 0; 166 $nkn = 0; 167 $blend = 0.0; 168 $newx = 0.0; 169 $newy = 0.0; 170 171 $muk = 1.0; 172 $munk = (double) pow(1-$mu,(double) $n); 173 174 for ($k = 0; $k <= $n; $k++) { 175 $nn = $n; 176 $kn = $k; 177 $nkn = $n - $k; 178 $blend = $muk * $munk; 179 $muk *= $mu; 180 $munk /= (1-$mu); 181 while ($nn >= 1) { 182 $blend *= $nn; 183 $nn--; 184 if ($kn > 1) { 185 $blend /= (double) $kn; 186 $kn--; 187 } 188 if ($nkn > 1) { 189 $blend /= (double) $nkn; 190 $nkn--; 191 } 192 } 193 $newx += $this->datax[$k] * $blend; 194 $newy += $this->datay[$k] * $blend; 195 } 196 197 return array($newx, $newy); 211 198 } 212 199 } -
trunk/client/modules/Elezioni/grafici/jpgraph_rgb.inc.php
r265 r267 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 1893 2009-10-02 23:15:25Z 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 1049 2008-08-01 19:58:07Z ljp $ 8 8 // 9 // Copyright (c) A sial Corporation. All rights reserved.9 // Copyright (c) Aditus Consulting. 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 19 17 class RGB { 20 public $rgb_table; 18 public $rgb_table; 21 19 public $img; 22 20 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)); 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)); 469 462 } 470 471 472 //---------------- 473 // PUBLIC METHODS 463 //---------------- 464 // PUBLIC METHODS 474 465 // Colors can be specified as either 475 // 1. #xxxxxx 476 // 2. "colorname" 477 // 3. array(r,g,b) 478 // This function translates this to a native RGB format and returns an 466 // 1. #xxxxxx HTML style 467 // 2. "colorname" as a named color 468 // 3. array(r,g,b) RGB triple 469 // This function translates this to a native RGB format and returns an 479 470 // RGB triple. 480 481 471 function Color($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 } 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)); 540 542 } 541 543 542 544 // Compare two colors 543 545 // return true if equal 544 546 function Equal($aCol1,$aCol2) { 545 $c1 = $this->Color($aCol1); 546 $c2 = $this->Color($aCol2); 547 return $c1[0]==$c2[0] && $c1[1]==$c2[1] && $c1[2]==$c2[2] ; 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; 548 553 } 549 554 550 555 // Allocate a new color in the current image 551 556 // Return new color index, -1 if no more colors could be allocated 552 557 function Allocate($aColor,$aAlpha=0.0) { 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)); 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)); 563 567 } 564 565 // Try to convert an array with three valid numbers to the corresponding hex array566 // This is currenly only used in processing the colors for barplots in order to be able567 // 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 as569 // 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 spectrum586 // The argumen values is in the range [0, 1] where a value of 0 correponds to blue and587 // a value of 1 corresponds to red. Values in betwen is mapped to a linear interpolation588 // of the constituting colors in the visible color spectra.589 // The $aDynamicRange specified how much of the dynamic range we shold use590 // a value of 1.0 give the full dyanmic range and a lower value give more dark591 // 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 black595 }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 613 568 } // Class 614 569 -
trunk/client/modules/Elezioni/grafici/jpgraph_scatter.php
r265 r267 1 <?php 1 <?php 2 2 /*======================================================================= 3 // File:JPGRAPH_SCATTER.PHP4 5 // Created:2001-02-116 // Ver: $Id: jpgraph_scatter.php 1397 2009-06-27 21:34:14Z ljp $7 8 // Copyright (c) Asial Corporation. 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 957 2007-12-01 14:00:29Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. 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 ); 24 function __construct() { 25 // Empty 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() { 26 24 } 27 25 28 26 function SetSize($aSize,$aArrowSize=2) { 29 30 27 $this->iSize = $aSize; 28 $this->iArrowSize = $aArrowSize; 31 29 } 32 30 33 31 function SetColor($aColor) { 34 32 $this->iColor = $aColor; 35 33 } 36 34 37 35 function Stroke($aImg,$x,$y,$a) { 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 36 // First rotate the center coordinates 37 list($x,$y) = $aImg->Rotate($x,$y); 38 39 $old_origin = $aImg->SetCenter($x,$y); 40 $old_a = $aImg->a; 41 $aImg->SetAngle(-$a+$old_a); 42 43 $dx = round($this->iSize/2); 44 $c = array($x-$dx,$y,$x+$dx,$y); 45 $x += $dx; 46 47 list($dx,$dy) = $this->isizespec[$this->iArrowSize]; 48 $ca = array($x,$y,$x-$dx,$y-$dy,$x-$dx,$y+$dy,$x,$y); 49 50 $aImg->SetColor($this->iColor); 51 $aImg->Polygon($c); 52 $aImg->FilledPolygon($ca); 53 54 $aImg->SetCenter($old_origin[0],$old_origin[1]); 55 $aImg->SetAngle($old_a); 58 56 } 59 57 } … … 67 65 private $iAngles = array(); 68 66 private $iCallback = ''; 69 70 function __construct($datay,$datax,$angles) {71 72 73 74 75 76 77 78 parent::__construct($datay,$datax);79 80 81 82 67 68 function FieldPlot($datay,$datax,$angles) { 69 if( (count($datax) != count($datay)) ) 70 JpGraphError::RaiseL(20001);//("Fieldplots must have equal number of X and Y points."); 71 if( (count($datax) != count($angles)) ) 72 JpGraphError::RaiseL(20002);//("Fieldplots must have an angle specified for each X and Y points."); 73 74 $this->iAngles = $angles; 75 76 $this->Plot($datay,$datax); 77 $this->value->SetAlign('center','center'); 78 $this->value->SetMargin(15); 79 80 $this->arrow = new FieldArrow(); 83 81 } 84 82 85 83 function SetCallback($aFunc) { 86 84 $this->iCallback = $aFunc; 87 85 } 88 86 89 87 function Stroke($img,$xscale,$yscale) { 90 88 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 $this->arrow->SetColor($cc); 109 110 111 112 113 $yt = $yscale->Translate($this->coords[0][$i]); 114 115 116 117 118 } 119 89 // Remeber base color and size 90 $bc = $this->arrow->iColor; 91 $bs = $this->arrow->iSize; 92 $bas = $this->arrow->iArrowSize; 93 94 for( $i=0; $i<$this->numpoints; ++$i ) { 95 // Skip null values 96 if( $this->coords[0][$i]==="" ) 97 continue; 98 99 $f = $this->iCallback; 100 if( $f != "" ) { 101 list($cc,$cs,$cas) = call_user_func($f,$this->coords[1][$i],$this->coords[0][$i],$this->iAngles[$i]); 102 // Fall back on global data if the callback isn't set 103 if( $cc == "" ) $cc = $bc; 104 if( $cs == "" ) $cs = $bs; 105 if( $cas == "" ) $cas = $bas; 106 $this->arrow->SetColor($cc); 107 $this->arrow->SetSize($cs,$cas); 108 } 109 110 $xt = $xscale->Translate($this->coords[1][$i]); 111 $yt = $yscale->Translate($this->coords[0][$i]); 112 113 $this->arrow->Stroke($img,$xt,$yt,$this->iAngles[$i]); 114 $this->value->Stroke($img,$this->coords[0][$i],$xt,$yt); 115 } 116 } 117 120 118 // Framework function 121 119 function Legend($aGraph) { 122 123 124 125 126 } 120 if( $this->legend != "" ) { 121 $aGraph->legend->Add($this->legend,$this->mark->fill_color,$this->mark,0, 122 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 123 } 124 } 127 125 } 128 126 … … 132 130 //=================================================== 133 131 class ScatterPlot extends Plot { 134 public $mark ,$link;132 public $mark = ''; 135 133 private $impuls = false; 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 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 154 150 function SetImpuls($f=true) { 155 $this->impuls = $f; 156 } 157 158 function SetStem($f=true) { 159 $this->impuls = $f; 160 } 151 $this->impuls = $f; 152 } 161 153 162 154 // Combine the scatter plot points with a line 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; 155 function SetLinkPoints($aFlag=true,$aColor="black",$aWeight=1) { 156 $this->linkpoints=$aFlag; 157 $this->linkpointcolor=$aColor; 158 $this->linkpointweight=$aWeight; 168 159 } 169 160 170 161 function Stroke($img,$xscale,$yscale) { 171 162 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 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 233 222 // Framework function 234 223 function Legend($aGraph) { 235 236 237 238 239 } 224 if( $this->legend != "" ) { 225 $aGraph->legend->Add($this->legend,$this->mark->fill_color,$this->mark,0, 226 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); 227 } 228 } 240 229 } // Class 241 230 /* EOF */ -
trunk/client/modules/Elezioni/grafici/jpgraph_stock.php
r265 r267 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 1364 2009-06-24 07:07:44Z ljp $7 8 // Copyright (c) Asial Corporation. 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 957 2007-12-01 14:00:29Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. 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 22 function __construct($datay,$datax=false) {23 24 25 26 27 parent::__construct($datay,$datax);28 20 //--------------- 21 // CONSTRUCTOR 22 function StockPlot($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 $this->Plot($datay,$datax); 28 $this->numpoints /= $this->iTupleSize; 29 29 } 30 31 32 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 } 70 else { 71 $exist_x = true; 72 } 73 } 74 else { 75 $exist_x = false; 76 } 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; 77 74 78 if( $exist_x ) { 79 $xs=$this->coords[1][0]; 80 } 81 else { 82 $xs=0; 83 } 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) { 84 83 85 $ts = $this->iTupleSize; 86 $this->csimareas = ''; 87 for( $i=0; $i<$n; ++$i) { 84 //If value is NULL, then don't draw a bar at all 85 if ($this->coords[0][$i] === null) continue; 88 86 89 //If value is NULL, then don't draw a bar at all 90 if ($this->coords[0][$i*$ts] === null) continue; 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]); 91 96 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); 97 $dx = floor($this->iWidth/2); 98 $xl = $xt - $dx; 99 $xr = $xt + $dx; 100 100 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]); 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); 106 113 107 $dx = floor($this->iWidth/2); 108 $xl = $xt - $dx; 109 $xr = $xt + $dx; 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); 110 125 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 } 126 if( $this->iEndLines ) { 127 $img->Line($xl,$ymax,$xr,$ymax); 128 $img->Line($xl,$ymin,$xr,$ymin); 129 } 125 130 126 $img->Rectangle($xl,$yopen,$xr,$yclose); 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); 127 134 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; 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; 163 149 } 164 150 … … 173 159 class BoxPlot extends StockPlot { 174 160 private $iPColor='black',$iNColor='white'; 175 176 function __construct($datay,$datax=false) { 177 $this->iTupleSize=5; 178 parent::__construct($datay,$datax); 161 function BoxPlot($datay,$datax=false) { 162 $this->iTupleSize=5; 163 parent::StockPlot($datay,$datax); 179 164 } 180 165 181 166 function SetMedianColor($aPos,$aNeg) { 182 183 167 $this->iPColor = $aPos; 168 $this->iNColor = $aNeg; 184 169 } 185 170 186 171 function ModBox($img,$xscale,$yscale,$i,$xl,$xr,$neg) { 187 if( $neg ) 188 189 190 191 192 193 172 if( $neg ) 173 $img->SetColor($this->iNColor); 174 else 175 $img->SetColor($this->iPColor); 176 177 $y = $yscale->Translate($this->coords[0][$i*5+4]); 178 $img->Line($xl,$y,$xr,$y); 194 179 } 195 180 } -
trunk/client/modules/Elezioni/grafici/jpgraph_text.inc.php
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // 6 // Created: 7 // Ver: $Id: jpgraph_text.inc.php 1844 2009-09-26 17:05:31Z 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 1048 2008-08-01 19:56:46Z ljp $ 8 8 // 9 // Copyright (c) A sial Corporation. All rights reserved.9 // Copyright (c) Aditus Consulting. All rights reserved. 10 10 //======================================================================== 11 11 … … 16 16 //=================================================== 17 17 class Text { 18 public $t ;18 public $t,$margin=0; 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_ DEFAULT,$font_style=FS_NORMAL; // old. FF_FONT124 protected $boxed=false; 23 public $font_family=FF_FONT1,$font_style=FS_NORMAL,$font_size=12; 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 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 29 30 //--------------- 31 // CONSTRUCTOR 37 32 38 33 // Create new text at absolute pixel coordinates 39 function __construct($aTxt="",$aXAbsPos=0,$aYAbsPos=0) {40 41 42 43 44 45 46 47 } 48 49 // PUBLIC METHODS 34 function Text($aTxt="",$aXAbsPos=0,$aYAbsPos=0) { 35 if( ! is_string($aTxt) ) { 36 JpGraphError::RaiseL(25050);//('First argument to Text::Text() must be s atring.'); 37 } 38 $this->t = $aTxt; 39 $this->x = round($aXAbsPos); 40 $this->y = round($aYAbsPos); 41 $this->margin = 0; 42 } 43 //--------------- 44 // PUBLIC METHODS 50 45 // Set the string in the text object 51 46 function Set($aTxt) { 52 53 } 54 47 $this->t = $aTxt; 48 } 49 55 50 // Alias for Pos() 56 51 function SetPos($aXAbsPos=0,$aYAbsPos=0,$aHAlign="left",$aVAlign="top") { 57 58 59 60 61 52 //$this->Pos($aXAbsPos,$aYAbsPos,$aHAlign,$aVAlign); 53 $this->x = $aXAbsPos; 54 $this->y = $aYAbsPos; 55 $this->halign = $aHAlign; 56 $this->valign = $aVAlign; 62 57 } 63 58 64 59 function SetScalePos($aX,$aY) { 65 66 67 } 68 60 $this->iScalePosX = $aX; 61 $this->iScalePosY = $aY; 62 } 63 69 64 // Specify alignment for the text 70 65 function Align($aHAlign,$aVAlign="top",$aParagraphAlign="") { 71 72 73 74 75 } 76 66 $this->halign = $aHAlign; 67 $this->valign = $aVAlign; 68 if( $aParagraphAlign != "" ) 69 $this->paragraph_align = $aParagraphAlign; 70 } 71 77 72 // Alias 78 73 function SetAlign($aHAlign,$aVAlign="top",$aParagraphAlign="") { 79 74 $this->Align($aHAlign,$aVAlign,$aParagraphAlign); 80 75 } 81 76 82 77 // Specifies the alignment for a multi line text 83 78 function ParagraphAlign($aAlign) { 84 79 $this->paragraph_align = $aAlign; 85 80 } 86 81 87 82 // Specifies the alignment for a multi line text 88 83 function SetParagraphAlign($aAlign) { 89 84 $this->paragraph_align = $aAlign; 90 85 } 91 86 92 87 function SetShadow($aShadowColor='gray',$aShadowWidth=3) { 93 94 95 88 $this->ishadowwidth=$aShadowWidth; 89 $this->shadow=$aShadowColor; 90 $this->boxed=true; 96 91 } 97 92 98 93 function SetWordWrap($aCol) { 99 100 } 101 94 $this->iWordwrap = $aCol ; 95 } 96 102 97 // Specify that the text should be boxed. fcolor=frame color, bcolor=border color, 103 98 // $shadow=drop shadow should be added around the text. 104 99 function SetBox($aFrameColor=array(255,255,255),$aBorderColor=array(0,0,0),$aShadowColor=false,$aCornerRadius=4,$aShadowWidth=3) { 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 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 127 114 // Hide the text 128 115 function Hide($aHide=true) { 129 130 } 131 132 // This looks ugly since it's not a very orthogonal design 116 $this->hide=$aHide; 117 } 118 119 // This looks ugly since it's not a very orthogonal design 133 120 // but I added this "inverse" of Hide() to harmonize 134 // with some classes which I designed more recently (especially) 121 // with some classes which I designed more recently (especially) 135 122 // jpgraph_gantt 136 123 function Show($aShow=true) { 137 138 } 139 124 $this->hide=!$aShow; 125 } 126 140 127 // Specify font 141 128 function SetFont($aFamily,$aStyle=FS_NORMAL,$aSize=10) { 142 143 144 145 } 146 129 $this->font_family=$aFamily; 130 $this->font_style=$aStyle; 131 $this->font_size=$aSize; 132 } 133 147 134 // Center the text between $left and $right coordinates 148 135 function Center($aLeft,$aRight,$aYAbsPos=false) { 149 $this->x = $aLeft + ($aRight-$aLeft)/2;150 151 152 $this->y = $aYAbsPos; 153 } 154 136 $this->x = $aLeft + ($aRight-$aLeft )/2; 137 $this->halign = "center"; 138 if( is_numeric($aYAbsPos) ) 139 $this->y = $aYAbsPos; 140 } 141 155 142 // Set text color 156 143 function SetColor($aColor) { 157 158 } 159 144 $this->color = $aColor; 145 } 146 160 147 function SetAngle($aAngle) { 161 162 } 163 148 $this->SetOrientation($aAngle); 149 } 150 164 151 // Orientation of text. Note only TTF fonts can have an arbitrary angle 165 152 function SetOrientation($aDirection=0) { 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 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 176 162 // Total width of text 177 163 function GetWidth($aImg) { 178 $aImg->SetFont($this->font_family,$this->font_style,$this->raw_font_size);179 180 return $w; 181 } 182 164 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 165 $w = $aImg->GetTextWidth($this->t,$this->dir); 166 return $w; 167 } 168 183 169 // Hight of font 184 170 function GetFontHeight($aImg) { 185 $aImg->SetFont($this->font_family,$this->font_style,$this->raw_font_size);186 187 171 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 172 $h = $aImg->GetFontHeight(); 173 return $h; 188 174 189 175 } 190 176 191 177 function GetTextHeight($aImg) { 192 $aImg->SetFont($this->font_family,$this->font_style,$this->raw_font_size); 193 194 178 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 179 $h = $aImg->GetTextHeight($this->t,$this->dir); 180 return $h; 195 181 } 196 182 197 183 function GetHeight($aImg) { 198 199 $aImg->SetFont($this->font_family,$this->font_style,$this->raw_font_size); 200 201 184 // Synonym for GetTextHeight() 185 $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); 186 $h = $aImg->GetTextHeight($this->t,$this->dir); 187 return $h; 202 188 } 203 189 … … 205 191 // on the context. 206 192 function SetMargin($aMarg) { 207 193 $this->margin = $aMarg; 208 194 } 209 195 210 196 function StrokeWithScale($aImg,$axscale,$ayscale) { 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 } 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 } 219 206 } 220 207 221 208 function SetCSIMTarget($aURITarget,$aAlt='',$aWinTarget='') { 222 223 224 209 $this->iCSIMtarget = $aURITarget; 210 $this->iCSIMalt = $aAlt; 211 $this->iCSIMWinTarget = $aWinTarget; 225 212 } 226 213 227 214 function GetCSIMareas() { 228 if( $this->iCSIMtarget !== '' ) { 229 return $this->iCSIMarea; 230 } 231 else { 232 return ''; 233 } 215 if( $this->iCSIMtarget !== '' ) 216 return $this->iCSIMarea; 217 else 218 return ''; 234 219 } 235 220 … … 237 222 function Stroke($aImg,$x=null,$y=null) { 238 223 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; 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 323 267 } 324 268 } // Class -
trunk/client/modules/Elezioni/grafici/jpgraph_ttf.inc.php
r265 r267 1 1 <?php 2 2 //======================================================================= 3 // File: 4 // Description: 5 // Created: 6 // Ver: $Id: jpgraph_ttf.inc.php 1858 2009-09-28 14:39:51Z 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 1091 2009-01-18 22:57:40Z ljp $ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. All rights reserved. 9 9 //======================================================================== 10 10 … … 27 27 define("FF_SIMSUN",30); 28 28 define("FF_CHINESE",31); 29 define("FF_BIG5",3 2);29 define("FF_BIG5",31); 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 // 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 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 60 58 61 59 define("FF_USERFONT",90); … … 80 78 define("FF_FONT2",4); 81 79 82 //------------------------------------------------------------------------83 // Defines for font setup84 //------------------------------------------------------------------------85 86 // Actual name of the TTF file used together with FF_CHINESE aka FF_BIG587 // This is the TTF file being used when the font family is specified as88 // either FF_CHINESE or FF_BIG589 define('CHINESE_TTF_FONT','bkai00mp.ttf');90 91 // Special unicode greek language support92 define("LANGUAGE_GREEK",false);93 94 // If you are setting this config to true the conversion of greek characters95 // will assume that the input text is windows 125196 define("GREEK_FROM_WINDOWS",false);97 98 // Special unicode cyrillic language support99 define("LANGUAGE_CYRILLIC",false);100 101 // If you are setting this config to true the conversion102 // will assume that the input text is windows 1251, if103 // false it will assume koi8-r104 define("CYRILLIC_FROM_WINDOWS",false);105 106 // The following constant is used to auto-detect107 // whether cyrillic conversion is really necessary108 // if enabled. Just replace 'windows-1251' with a variable109 // containing the input character encoding string110 // 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-user117 // multi-language environments where a cyrillic conversion118 // could be needed for some cyrillic people119 // and resulting in just erraneous conversions120 // for not-cyrillic language based people.121 //122 // Example: In the free project management123 // software dotproject.net $locale_char_set is dynamically124 // 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) variable129 // 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_PGOTHIC134 // 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 done143 // automatically in the library using the mbstring module in PHP.144 define('ASSUME_EUCJP_ENCODING',false);145 146 147 // Default font family148 define('FF_DEFAULT', FF_DV_SANSSERIF);149 150 151 152 80 //================================================================= 153 81 // CLASS LanguageConv 154 // Description: 82 // Description: 155 83 // Converts various character encoding into proper 156 84 // UTF-8 depending on how the library have been configured and … … 161 89 162 90 function Convert($aTxt,$aFF) { 163 164 165 $unistring = LanguageConv::gr_win2uni($aTxt); 166 167 168 169 170 171 172 $aTxt = convert_cyr_string($aTxt, "w", "k"); 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 elseif( $aFF === FF_BIG5) {192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 else 209 91 if( LANGUAGE_GREEK ) { 92 if( GREEK_FROM_WINDOWS ) { 93 $unistring = LanguageConv::gr_win2uni($aTxt); 94 } else { 95 $unistring = LanguageConv::gr_iso2uni($aTxt); 96 } 97 return $unistring; 98 } elseif( LANGUAGE_CYRILLIC ) { 99 if( CYRILLIC_FROM_WINDOWS && (!defined('LANGUAGE_CHARSET') || stristr(LANGUAGE_CHARSET, 'windows-1251')) ) { 100 $aTxt = convert_cyr_string($aTxt, "w", "k"); 101 } 102 if( !defined('LANGUAGE_CHARSET') || stristr(LANGUAGE_CHARSET, 'koi8-r') || stristr(LANGUAGE_CHARSET, 'windows-1251')) { 103 $isostring = convert_cyr_string($aTxt, "k", "i"); 104 $unistring = LanguageConv::iso2uni($isostring); 105 } 106 else { 107 $unistring = $aTxt; 108 } 109 return $unistring; 110 } 111 elseif( $aFF === FF_SIMSUN ) { 112 // Do Chinese conversion 113 if( $this->g2312 == null ) { 114 include_once 'jpgraph_gb2312.php' ; 115 $this->g2312 = new GB2312toUTF8(); 116 } 117 return $this->g2312->gb2utf8($aTxt); 118 } 119 elseif( $aFF === FF_CHINESE ) { 120 if( !function_exists('iconv') ) { 121 JpGraphError::RaiseL(25006); 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 return iconv('BIG5','UTF-8',$aTxt); 125 } 126 elseif( ASSUME_EUCJP_ENCODING && 127 ($aFF == FF_MINCHO || $aFF == FF_GOTHIC || $aFF == FF_PMINCHO || $aFF == FF_PGOTHIC) ) { 128 if( !function_exists('mb_convert_encoding') ) { 129 JpGraphError::RaiseL(25127); 130 } 131 return mb_convert_encoding($aTxt, 'UTF-8','EUC-JP'); 132 } 133 elseif( $aFF == FF_DAVID || $aFF == FF_MIRIAM || $aFF == FF_AHRON ) { 134 return LanguageConv::heb_iso2uni($aTxt); 135 } 136 else 137 return $aTxt; 210 138 } 211 139 212 140 // Translate iso encoding to unicode 213 141 public static function iso2uni ($isoline){ 214 215 216 217 218 219 220 142 $uniline=''; 143 for ($i=0; $i < strlen($isoline); $i++){ 144 $thischar=substr($isoline,$i,1); 145 $charcode=ord($thischar); 146 $uniline.=($charcode>175) ? "&#" . (1040+($charcode-176)). ";" : $thischar; 147 } 148 return $uniline; 221 149 } 222 150 223 151 // Translate greek iso encoding to unicode 224 152 public static function gr_iso2uni ($isoline) { 225 226 for ($i=0; $i < strlen($isoline); $i++){227 228 229 230 231 153 $uniline=''; 154 for ($i=0; $i < strlen($isoline); $i++) { 155 $thischar=substr($isoline,$i,1); 156 $charcode=ord($thischar); 157 $uniline.=($charcode>179 && $charcode!=183 && $charcode!=187 && $charcode!=189) ? "&#" . (900+($charcode-180)). ";" : $thischar; 158 } 159 return $uniline; 232 160 } 233 161 234 162 // Translate greek win encoding to unicode 235 163 public static function gr_win2uni ($winline) { 236 237 238 239 240 241 242 243 244 245 246 247 164 $uniline=''; 165 for ($i=0; $i < strlen($winline); $i++) { 166 $thischar=substr($winline,$i,1); 167 $charcode=ord($thischar); 168 if ($charcode==161 || $charcode==162) { 169 $uniline.="&#" . (740+$charcode). ";"; 170 } 171 else { 172 $uniline.=(($charcode>183 && $charcode!=187 && $charcode!=189) || $charcode==180) ? "&#" . (900+($charcode-180)). ";" : $thischar; 173 } 174 } 175 return $uniline; 248 176 } 249 177 250 178 public static function heb_iso2uni($isoline) { 251 252 253 254 255 256 257 258 259 179 $isoline = hebrev($isoline); 180 $o = ''; 181 182 $n = strlen($isoline); 183 for($i=0; $i < $n; $i++) { 184 $c=ord( substr($isoline,$i,1) ); 185 $o .= ($c > 223) && ($c < 251) ? '&#'.(1264+$c).';' : chr($c); 186 } 187 return utf8_encode($o); 260 188 } 261 189 } … … 263 191 //============================================================= 264 192 // CLASS TTF 265 // Description: Handle TTF font names and mapping and loading of 193 // Description: Handle TTF font names and mapping and loading of 266 194 // font files 267 195 //============================================================= … … 269 197 private $font_files,$style_names; 270 198 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 =>'' ) , 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 =>'' ) , 322 251 323 252 /* Chinese fonts */ 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 =>'' ), 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 =>'' ), 339 261 340 262 /* Japanese fonts */ 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 =>'' ), 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 =>'' ), 364 283 365 284 /* Hebrew fonts */ 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 =>'' ), 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 =>'' ), 383 299 384 300 /* Misc fonts */ 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 =>'' ), 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 =>'' ), 410 317 411 318 /* Dejavu fonts */ 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 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 467 366 // Create the TTF file from the font specification 468 367 function File($family,$style=FS_NORMAL) { 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; 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; 515 390 } 516 391 517 392 function SetUserFont($aNormal,$aBold='',$aItalic='',$aBoldIt='') { 518 $this->font_files[FF_USERFONT] = 519 array(FS_NORMAL => $aNormal, 520 FS_BOLD => $aBold, 521 FS_ITALIC => $aItalic, 522 FS_BOLDITALIC=> $aBoldIt ) ;393 $this->font_files[FF_USERFONT] = 394 array(FS_NORMAL => $aNormal, 395 FS_BOLD => $aBold, 396 FS_ITALIC => $aItalic, 397 FS_BOLDITALIC => $aBoldIt ) ; 523 398 } 524 399 525 400 function SetUserFont1($aNormal,$aBold='',$aItalic='',$aBoldIt='') { 526 $this->font_files[FF_USERFONT1] = 527 array(FS_NORMAL => $aNormal, 528 FS_BOLD => $aBold, 529 FS_ITALIC => $aItalic, 530 FS_BOLDITALIC=> $aBoldIt ) ;401 $this->font_files[FF_USERFONT1] = 402 array(FS_NORMAL => $aNormal, 403 FS_BOLD => $aBold, 404 FS_ITALIC => $aItalic, 405 FS_BOLDITALIC => $aBoldIt ) ; 531 406 } 532 407 533 408 function SetUserFont2($aNormal,$aBold='',$aItalic='',$aBoldIt='') { 534 $this->font_files[FF_USERFONT2] = 535 array(FS_NORMAL => $aNormal, 536 FS_BOLD => $aBold, 537 FS_ITALIC => $aItalic, 538 FS_BOLDITALIC=> $aBoldIt ) ;409 $this->font_files[FF_USERFONT2] = 410 array(FS_NORMAL => $aNormal, 411 FS_BOLD => $aBold, 412 FS_ITALIC => $aItalic, 413 FS_BOLDITALIC => $aBoldIt ) ; 539 414 } 540 415 541 416 function SetUserFont3($aNormal,$aBold='',$aItalic='',$aBoldIt='') { 542 $this->font_files[FF_USERFONT3] = 543 array(FS_NORMAL => $aNormal, 544 FS_BOLD => $aBold, 545 FS_ITALIC => $aItalic, 546 FS_BOLDITALIC=> $aBoldIt ) ;417 $this->font_files[FF_USERFONT3] = 418 array(FS_NORMAL => $aNormal, 419 FS_BOLD => $aBold, 420 FS_ITALIC => $aItalic, 421 FS_BOLDITALIC => $aBoldIt ) ; 547 422 } 548 423 … … 550 425 551 426 552 //=============================================================================553 // CLASS SymChar554 // Description: Code values for some commonly used characters that555 // normally isn't available directly on the keyboard, for example556 // 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 else622 $s = $ca[1];623 return sprintf('&#%04d;',hexdec($s));624 }625 else626 return '';627 }628 }629 630 427 631 428 ?> -
trunk/client/modules/Elezioni/grafici/jpgraph_utils.inc.php
r265 r267 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 1777 2009-08-23 17:34:36Z ljp $7 8 // Copyright (c) Asial Corporation. 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 1091 2009-01-18 22:57:40Z ljp $ 7 // 8 // Copyright (c) Aditus Consulting. 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 __construct($aFunc,$aXFunc='') {21 22 23 } 24 19 20 function FuncGenerator($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); 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 ''; 45 120 } 46 121 } … … 76 151 77 152 static function UseWeekFormat($aFlg) { 78 153 self::$iUseWeeks = $aFlg; 79 154 } 80 155 81 156 static function doYearly($aType,$aMinor=false) { 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); 105 106 107 108 $y=self::$startyear; 109 110 self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); 111 for($k=0; $k < 1; ++$k ) { 112 113 114 115 116 117 118 119 120 121 $y=self::$startyear; 122 123 self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); 124 for($k=0; $k < 4; ++$k ) { 125 126 127 128 129 130 131 132 133 157 $i=0; $j=0; 158 $m = self::$startmonth; 159 $y = self::$startyear; 160 161 if( self::$startday == 1 ) { 162 self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); 163 } 164 ++$m; 165 166 167 switch( $aType ) { 168 case DSUTILS_YEAR1: 169 for($y=self::$startyear; $y <= self::$endyear; ++$y ) { 170 if( $aMinor ) { 171 while( $m <= 12 ) { 172 if( !($y == self::$endyear && $m > self::$endmonth) ) { 173 self::$minTickPositions[$j++] = mktime(0,0,0,$m,1,$y); 174 } 175 ++$m; 176 } 177 $m=1; 178 } 179 self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); 180 } 181 break; 182 case DSUTILS_YEAR2: 183 $y=self::$startyear; 184 while( $y <= self::$endyear ) { 185 self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); 186 for($k=0; $k < 1; ++$k ) { 187 ++$y; 188 if( $aMinor ) { 189 self::$minTickPositions[$j++] = mktime(0,0,0,1,1,$y); 190 } 191 } 192 ++$y; 193 } 194 break; 195 case DSUTILS_YEAR5: 196 $y=self::$startyear; 197 while( $y <= self::$endyear ) { 198 self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); 199 for($k=0; $k < 4; ++$k ) { 200 ++$y; 201 if( $aMinor ) { 202 self::$minTickPositions[$j++] = mktime(0,0,0,1,1,$y); 203 } 204 } 205 ++$y; 206 } 207 break; 208 } 134 209 } 135 210 136 211 static function doDaily($aType,$aMinor=false) { 137 138 139 140 141 142 143 144 145 146 $t = mktime(0,0,0,$m,$d,$y); 147 148 149 150 151 152 153 154 self::$minTickPositions[$j++] = strtotime('+12 hours',$t); 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 212 $m = self::$startmonth; 213 $y = self::$startyear; 214 $d = self::$startday; 215 $h = self::$starthour; 216 $i=0;$j=0; 217 218 if( $h == 0 ) { 219 self::$tickPositions[$i++] = mktime(0,0,0,$m,$d,$y); 220 } 221 $t = mktime(0,0,0,$m,$d,$y); 222 223 switch($aType) { 224 case DSUTILS_DAY1: 225 while( $t <= self::$iMax ) { 226 $t = strtotime('+1 day',$t); 227 self::$tickPositions[$i++] = $t; 228 if( $aMinor ) { 229 self::$minTickPositions[$j++] = strtotime('+12 hours',$t); 230 } 231 } 232 break; 233 case DSUTILS_DAY2: 234 while( $t <= self::$iMax ) { 235 $t = strtotime('+1 day',$t); 236 if( $aMinor ) { 237 self::$minTickPositions[$j++] = $t; 238 } 239 $t = strtotime('+1 day',$t); 240 self::$tickPositions[$i++] = $t; 241 } 242 break; 243 case DSUTILS_DAY4: 244 while( $t <= self::$iMax ) { 245 for($k=0; $k < 3; ++$k ) { 246 $t = strtotime('+1 day',$t); 247 if( $aMinor ) { 248 self::$minTickPositions[$j++] = $t; 249 } 250 } 251 $t = strtotime('+1 day',$t); 252 self::$tickPositions[$i++] = $t; 253 } 254 break; 255 } 181 256 } 182 257 183 258 static function doWeekly($aType,$aMinor=false) { 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 222 223 224 225 226 259 $hpd = 3600*24; 260 $hpw = 3600*24*7; 261 // Find out week number of min date 262 $thursday = self::$iMin + $hpd * (3 - (date('w', self::$iMin) + 6) % 7); 263 $week = 1 + (date('z', $thursday) - (11 - date('w', mktime(0, 0, 0, 1, 1, date('Y', $thursday)))) % 7) / 7; 264 $daynumber = date('w',self::$iMin); 265 if( $daynumber == 0 ) $daynumber = 7; 266 $m = self::$startmonth; 267 $y = self::$startyear; 268 $d = self::$startday; 269 $i=0;$j=0; 270 // The assumption is that the weeks start on Monday. If the first day 271 // is later in the week then the first week tick has to be on the following 272 // week. 273 if( $daynumber == 1 ) { 274 self::$tickPositions[$i++] = mktime(0,0,0,$m,$d,$y); 275 $t = mktime(0,0,0,$m,$d,$y) + $hpw; 276 } 277 else { 278 $t = mktime(0,0,0,$m,$d,$y) + $hpd*(8-$daynumber); 279 } 280 281 switch($aType) { 282 case DSUTILS_WEEK1: 283 $cnt=0; 284 break; 285 case DSUTILS_WEEK2: 286 $cnt=1; 287 break; 288 case DSUTILS_WEEK4: 289 $cnt=3; 290 break; 291 } 292 while( $t <= self::$iMax ) { 293 self::$tickPositions[$i++] = $t; 294 for($k=0; $k < $cnt; ++$k ) { 295 $t += $hpw; 296 if( $aMinor ) { 297 self::$minTickPositions[$j++] = $t; 298 } 299 } 300 $t += $hpw; 301 } 227 302 } 228 303 229 304 static function doMonthly($aType,$aMinor=false) { 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 case DSUTILS_MONTH1: 257 258 259 260 if( !($y==self::$endyear && $m==$stopmonth && self::$endday < 15) ) 261 262 263 264 // Major at month 265 266 267 268 269 case DSUTILS_MONTH2: 270 271 272 273 274 275 // Major at every second month 276 277 278 279 280 281 case DSUTILS_MONTH3: 282 283 284 285 286 // Major at every third month 287 288 289 290 291 292 case DSUTILS_MONTH6: 293 294 295 296 297 // Major at every third month 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 } 316 317 305 $monthcount=0; 306 $m = self::$startmonth; 307 $y = self::$startyear; 308 $i=0; $j=0; 309 310 // Skip the first month label if it is before the startdate 311 if( self::$startday == 1 ) { 312 self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); 313 $monthcount=1; 314 } 315 if( $aType == 1 ) { 316 if( self::$startday < 15 ) { 317 self::$minTickPositions[$j++] = mktime(0,0,0,$m,15,$y); 318 } 319 } 320 ++$m; 321 322 // Loop through all the years included in the scale 323 for($y=self::$startyear; $y <= self::$endyear; ++$y ) { 324 // Loop through all the months. There are three cases to consider: 325 // 1. We are in the first year and must start with the startmonth 326 // 2. We are in the end year and we must stop at last month of the scale 327 // 3. A year in between where we run through all the 12 months 328 $stopmonth = $y == self::$endyear ? self::$endmonth : 12; 329 while( $m <= $stopmonth ) { 330 switch( $aType ) { 331 case DSUTILS_MONTH1: 332 // Set minor tick at the middle of the month 333 if( $aMinor ) { 334 if( $m <= $stopmonth ) { 335 if( !($y==self::$endyear && $m==$stopmonth && self::$endday < 15) ) 336 self::$minTickPositions[$j++] = mktime(0,0,0,$m,15,$y); 337 } 338 } 339 // Major at month 340 // Get timestamp of first hour of first day in each month 341 self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); 342 343 break; 344 case DSUTILS_MONTH2: 345 if( $aMinor ) { 346 // Set minor tick at start of each month 347 self::$minTickPositions[$j++] = mktime(0,0,0,$m,1,$y); 348 } 349 350 // Major at every second month 351 // Get timestamp of first hour of first day in each month 352 if( $monthcount % 2 == 0 ) { 353 self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); 354 } 355 break; 356 case DSUTILS_MONTH3: 357 if( $aMinor ) { 358 // Set minor tick at start of each month 359 self::$minTickPositions[$j++] = mktime(0,0,0,$m,1,$y); 360 } 361 // Major at every third month 362 // Get timestamp of first hour of first day in each month 363 if( $monthcount % 3 == 0 ) { 364 self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); 365 } 366 break; 367 case DSUTILS_MONTH6: 368 if( $aMinor ) { 369 // Set minor tick at start of each month 370 self::$minTickPositions[$j++] = mktime(0,0,0,$m,1,$y); 371 } 372 // Major at every third month 373 // Get timestamp of first hour of first day in each month 374 if( $monthcount % 6 == 0 ) { 375 self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); 376 } 377 break; 378 } 379 ++$m; 380 ++$monthcount; 381 } 382 $m=1; 383 } 384 385 // For the case where all dates are within the same month 386 // we want to make sure we have at least two ticks on the scale 387 // since the scale want work properly otherwise 388 if(self::$startmonth == self::$endmonth && self::$startyear == self::$endyear && $aType==1 ) { 389 self::$tickPositions[$i++] = mktime(0 ,0 ,0, self::$startmonth + 1, 1, self::$startyear); 390 } 391 392 return array(self::$tickPositions,self::$minTickPositions); 318 393 } 319 394 320 395 static function GetTicks($aData,$aType=1,$aMinor=false,$aEndPoints=false) { 321 322 396 $n = count($aData); 397 return self::GetTicksFromMinMax($aData[0],$aData[$n-1],$aType,$aMinor,$aEndPoints); 323 398 } 324 399 325 400 static function GetAutoTicks($aMin,$aMax,$aMaxTicks=10,$aMinor=false) { 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 } 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 } 362 441 } 363 442 364 443 static function GetTicksFromMinMax($aMin,$aMax,$aType,$aMinor=false,$aEndPoints=false) { 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 } 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 402 482 } 403 483 … … 406 486 //============================================================================= 407 487 Class ReadFileData { 488 408 489 //---------------------------------------------------------------------------- 409 490 // Desciption: 410 // Read numeric data from a file. 411 // Each value should be separated by either a new line or by a specified 491 // Read numeric data from a file. 492 // Each value should be separated by either a new line or by a specified 412 493 // separator character (default is ','). 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 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 415 496 // file will be discarded. 416 497 // 417 // Returns: 498 // Returns: 418 499 // The number of data values read on success, FALSE on failure 419 500 //---------------------------------------------------------------------------- 420 501 static function FromCSV($aFile,&$aData,$aSepChar=',',$aMaxLineLength=1024) { 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 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 } 594 525 } 595 526 596 define('__LR_EPSILON', 1.0e-8);597 //=============================================================================598 // Class LinearRegression599 //=============================================================================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 685 527 ?> -
trunk/client/modules/Elezioni/grafici/lang/de.inc.php
r265 r267 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 // Johan Persson (ljp@localhost.nil) 8 // Ver: $Id: de.inc.php 1886 2009-10-01 23:30:16Z ljp $ 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 $ 9 8 // 10 9 // Copyright (c) … … 19 18 */ 20 19 10 => array('<table border="1"><tr><td style="color:darkred;font-size:1.2em;"><b>JpGraph Fehler:</b> 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),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), 22 21 23 22 /* 24 23 ** Setup Fehler 25 24 */ 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),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), 28 27 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), 29 28 … … 35 34 2002 => array('Unbekannte Vorlage im Aufruf von BarPlot::SetPattern().',0), 36 35 2003 => array('Anzahl der X- und Y-Koordinaten sind nicht identisch. Anzahl der X-Koordinaten: %d; Anzahl der Y-Koordinaten: %d.',2), 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),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), 40 39 2007 => array('Kann GroupBarPlot nicht aus einem leeren Vektor erzeugen.',0), 41 40 2008 => array('GroupBarPlot Element nbr %d wurde nicht definiert oder ist leer.',0), … … 44 43 2011 => array('AccBarPlot-Element nbr %d wurde nicht definiert oder ist leer.',1), 45 44 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), 46 2013 => array('Du hast einen leeren Vektor f ÃŒr die Schattierungsfarben im Balkendiagramm (barplot) angegeben.',0),45 2013 => array('Du hast einen leeren Vektor für die Schattierungsfarben im Balkendiagramm (barplot) angegeben.',0), 47 46 2014 => array('Die Anzahl der Datenpunkte jeder Datenreihe in AccBarPlot muss gleich sein.',0), 48 47 2015 => array('Individual bar plots in an AccBarPlot or GroupBarPlot can not have specified X-coordinates',0), … … 53 52 */ 54 53 55 3001 => array('Es ist nur m öglich, entweder SetDateAlign() oder SetTimeAlign() zu benutzen, nicht beides!',0),54 3001 => array('Es ist nur möglich, entweder SetDateAlign() oder SetTimeAlign() zu benutzen, nicht beides!',0), 56 55 57 56 /* … … 65 64 */ 66 65 67 5001 => array('Unbekannte Flaggen-Gr öÃe (%d).',1),66 5001 => array('Unbekannte Flaggen-Größe (%d).',1), 68 67 5002 => array('Der Flaggen-Index %s existiert nicht.',1), 69 5003 => array('Es wurde eine ung ÃŒltige Ordnungszahl (%d) fÃŒr den Flaggen-Index angegeben.',1),68 5003 => array('Es wurde eine ungültige Ordnungszahl (%d) für den Flaggen-Index angegeben.',1), 70 69 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), 71 70 … … 75 74 */ 76 75 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),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), 81 80 6005 => array('SetScale() ist nicht sinnvoll bei Gantt-Diagrammen.',0), 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),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), 85 84 6009 => array('Unbekannter Bedingungstyp von Reihe=%d bis Reihe=%d',2), 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),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), 88 87 6012 => array('Unbekannter Typ bei der Gantt-Objekt-Title-Definition.',0), 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),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), 91 90 6017 => array('Unbekannter Datumstyp in GanttScale (%s).',1), 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),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), 96 95 6022 => array('Die Gantt-Skala wurde nicht eingegeben.',0), 97 96 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), … … 99 98 6025 => array('Der CSIM-Alt-Text muss als String angegeben werden. Der Beginn des Alt-Textes ist: %d',1), 100 99 6027 => array('Der Fortschrittswert muss im Bereich [0, 1] liegen.',0), 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), 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), 107 105 108 106 /* … … 116 114 */ 117 115 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),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), 122 120 123 121 /* … … 125 123 */ 126 124 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),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), 128 126 129 127 /* … … 132 130 133 131 10001 => array('Die Methode LinePlot::SetFilled() sollte nicht mehr benutzt werden. Benutze lieber SetFillColor()',0), 134 10002 => array('Der Plot ist zu kompliziert f ÃŒr FastLineStroke. Benutze lieber den StandardStroke()',0),132 10002 => array('Der Plot ist zu kompliziert für FastLineStroke. Benutze lieber den StandardStroke()',0), 135 133 10003 => array('Each plot in an accumulated lineplot must have the same number of data points.',0), 136 134 /* … … 139 137 140 138 11001 => array('Deine Daten enthalten nicht-numerische Werte.',0), 141 11002 => array('Negative Werte k önnen nicht fÃŒr logarithmische Achsen verwendet werden.',0),139 11002 => array('Negative Werte können nicht für logarithmische Achsen verwendet werden.',0), 142 140 11003 => array('Deine Daten enthalten nicht-numerische Werte.',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),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), 145 143 146 144 /* … … 148 146 */ 149 147 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),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), 154 152 12005 => array('Das Hintergrundbild kann nicht gelesen werden: %s',1), 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),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), 162 160 163 161 /* … … 165 163 */ 166 164 167 14001 => array('Pie3D::ShowBorder(). Missbilligte Funktion. Benutze Pie3D::SetEdge(), um die Ecken der Tortenst ÃŒcke zu kontrollieren.',0),165 14001 => array('Pie3D::ShowBorder(). Missbilligte Funktion. Benutze Pie3D::SetEdge(), um die Ecken der Tortenstücke zu kontrollieren.',0), 168 166 14002 => array('PiePlot3D::SetAngle() 3D-Torten-Projektionswinkel muss zwischen 5 und 85 Grad sein.',0), 169 167 14003 => array('Interne Festlegung schlug fehl. Pie3D::Pie3DSlice',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),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), 174 172 175 173 /* … … 178 176 179 177 15001 => array('PiePLot::SetTheme() Unbekannter Stil: %s',1), 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),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), 183 181 15005 => array('PiePlot::SetFont() sollte nicht mehr verwendet werden. Benutze stattdessen PiePlot->value->SetFont().',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),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), 185 183 15007 => array('PiePlot::SetFontColor() sollte nicht mehr verwendet werden. Benutze stattdessen PiePlot->value->SetColor()..',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),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), 188 186 15010 => array('Die Summe aller Daten ist Null.',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), 187 15011 => array('Um Bildtransformationen benutzen zu können, muss die Datei jpgraph_imgtrans.php eingefügt werden (per include).',0), 191 188 192 189 /* … … 194 191 */ 195 192 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),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), 198 195 16003 => array('Unbekannte Pattern-Definition (%d)',0), 199 16004 => array('Der Mindeswert f ÃŒr das PlotBand ist gröÃer als der Maximalwert. Bitte korrigiere dies!',0),196 16004 => array('Der Mindeswert für das PlotBand ist größer als der Maximalwert. Bitte korrigiere dies!',0), 200 197 201 198 … … 204 201 */ 205 202 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),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), 210 207 211 208 /* … … 213 210 */ 214 211 215 18001 => array('ClientSideImageMaps werden f ÃŒr RadarPlots nicht unterstÃŒtzt.',0),212 18001 => array('ClientSideImageMaps werden für RadarPlots nicht unterstützt.',0), 216 213 18002 => array('RadarGraph::SupressTickMarks() sollte nicht mehr verwendet werden. Benutze stattdessen HideTickMarks().',0), 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),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), 220 217 18006 => array('Minimum Daten %f (RadarPlots sollten nur verwendet werden, wenn alle Datenpunkte einen Wert > 0 haben).',1), 221 218 18007 => array('Die Anzahl der Titel entspricht nicht der Anzahl der Datenpunkte.',0), … … 227 224 228 225 19001 => array('Spline: Anzahl der X- und Y-Koordinaten muss gleich sein.',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),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), 230 227 19003 => array('Bezier: Anzahl der X- und Y-Koordinaten muss gleich sein.',0), 231 228 … … 234 231 */ 235 232 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),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), 239 236 240 237 /* … … 242 239 */ 243 240 244 21001 => array('Die Anzahl der Datenwerte f ÃŒr Stock-Charts mÃŒssen ein Mehrfaches von %d Datenpunkten sein.',1),241 21001 => array('Die Anzahl der Datenwerte für Stock-Charts müssen ein Mehrfaches von %d Datenpunkten sein.',1), 245 242 246 243 /* … … 249 246 250 247 23001 => array('Der Marker "%s" existiert nicht in der Farbe: %d',2), 251 23002 => array('Der Farb-Index ist zu hoch f ÃŒr den Marker "%s"',1),248 23002 => array('Der Farb-Index ist zu hoch für den Marker "%s"',1), 252 249 23003 => array('Ein Dateiname muss angegeben werden, wenn Du den Marker-Typ auf MARK_IMG setzt.',0), 253 250 … … 259 256 24002 => array('FuncGenerator : Syntax-Fehler in der Funktionsdefinition ',0), 260 257 24003 => array('DateScaleUtils: Unknown tick type specified in call to GetTicks()',0), 261 24004 => array('ReadCSV2: Die anzahl der spalten fehler in %s reihe %d',2), 258 262 259 /* 263 260 ** jpgraph 264 261 */ 265 262 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),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), 268 265 25003 => array('Genereller PHP Fehler : Bei %s:%d : %s',3), 269 266 25004 => array('Genereller PHP Fehler : %s ',1), 270 267 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), 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),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), 274 271 25009 => array('Die Skalierung der Achsen muss angegeben werden mit Graph::SetScale()',0), 275 272 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),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), 299 296 25031 => array('Der Achsentyp muss mittels Graph::SetScale() angegeben werden.',0), 300 25032 => array('Es existieren keine Plots f ÃŒr die Y-Achse nbr:%d',1),297 25032 => array('Es existieren keine Plots für die Y-Achse nbr:%d',1), 301 298 25033 => array('',0), 302 299 25034 => array('Undefinierte X-Achse kann nicht gezeichnet werden. Es wurden keine Plots definiert.',0), 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),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), 304 301 25036 => array('Unbekannter Achsentyp AxisStyle() : %s',1), 305 25037 => array('Das Bildformat Deines Hintergrundbildes (%s) wird von Deiner System-Konfiguration nicht unterst ÃŒtzt. ',1),302 25037 => array('Das Bildformat Deines Hintergrundbildes (%s) wird von Deiner System-Konfiguration nicht unterstützt. ',1), 306 303 25038 => array('Das Hintergrundbild scheint von einem anderen Typ (unterschiedliche Dateierweiterung) zu sein als der angegebene Typ. Angegebenen: %s; Datei: %s',2), 307 304 25039 => array('Hintergrundbild kann nicht gelesen werden: "%s"',1), 308 305 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),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), 311 308 25042 => array('Unbekanntes Hintergrundbild-Layout',0), 312 309 25043 => array('Unbekannter Titelhintergrund-Stil.',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),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), 315 312 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), 316 25047 => array('Stil %s ist nicht verf ÃŒgbar fÃŒr Schriftfamilie %s',2),313 25047 => array('Stil %s ist nicht verfügbar für Schriftfamilie %s',2), 317 314 25048 => array('Unbekannte Schriftstildefinition [%s].',1), 318 315 25049 => array('Schriftdatei "%s" ist nicht lesbar oder existiert nicht.',1), 319 316 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),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), 324 321 25054 => array('Interner Fehler: Unbekannte Grid-Achse %s',1), 325 322 25055 => array('Axis::SetTickDirection() sollte nicht mehr verwendet werden. Benutze stattdessen Axis::SetTickSide().',0), … … 329 326 25059 => array('SetLabelPos() sollte nicht mehr verwendet werden. Benutze stattdessen Axis::SetLabelSide().',0), 330 327 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),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), 334 331 25063 => array('Ticks::SetPrecision() sollte nicht mehr verwendet werden. Benutze stattdessen Ticks::SetLabelFormat() (oder Ticks::SetFormatCallback()).',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),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), 337 334 25066 => array('Wenn die Tick-Positionen und -Label von Hand eingegeben werden, muss die Anzahl der Ticks und der Label gleich sein.',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),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), 341 338 342 339 25070 => array('Deine Daten enthalten nicht-numerische Werte.',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),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), 349 346 25078 => array('Unbekannte Farbe: %s',1), 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),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), 362 359 363 360 25090 => array('Unbekannte Richtung angegeben im Aufruf von StrokeBoxedText() [%s].',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),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), 366 363 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), 367 364 25094 => array('Die Textrichtung muss in einem Winkel zwischen 0 und 90 engegeben werden.',0), 368 365 25095 => array('Unbekannte Schriftfamilien-Definition. ',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),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), 370 367 25097 => array('Eine Farbe wurde als leerer String im Aufruf von PushColor() angegegeben.',0), 371 368 25098 => array('Negativer Farbindex. Unpassender Aufruf von PopColor().',0), 372 25099 => array('Die Parameter f ÃŒr Helligkeit und Kontrast sind auÃerhalb des zulÀssigen Bereichs [-1,1]',0),369 25099 => array('Die Parameter für Helligkeit und Kontrast sind außerhalb des zulässigen Bereichs [-1,1]',0), 373 370 374 371 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), 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),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), 378 375 25104 => array('Unbekannter Linientyp: %s',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),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), 387 384 25112 => array('Das Datum der gecacheten Datei (%s) liegt in der Zukunft.',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),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), 393 390 25118 => array('Verzeichnis %s kann nicht angelegt werden. Versichere Dich, dass PHP die Schreibrechte in diesem Verzeichnis hat.',1), 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),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), 398 395 25122 => array('Stroke() muss als Subklasse der Klasse Plot definiert sein.',0), 399 396 25123 => array('Du kannst keine Text-X-Achse mit X-Koordinaten verwenden. Benutze stattdessen eine "int" oder "lin" Achse.',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),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), 403 400 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), 404 401 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), 405 402 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 translate410 25133 => array('Use Graph::SetTheme() after Graph::SetScale().',0), // @todo translate411 412 /*413 ** jpgraph_led414 */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 419 403 /* 420 404 **--------------------------------------------------------------------------------------------- … … 427 411 */ 428 412 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),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), 437 421 27009 => array('GTextTable: Die Anzahl der Tabellenspalten oder -zeilen ist 0. Versichere Dich, dass die Methoden Init() oder Set() aufgerufen werden.',0), 438 422 27010 => array('GTextTable: Es wurde keine Ausrichtung beim Aufruf von SetAlign() angegeben.',0), 439 423 27011 => array('GTextTable: Es wurde eine unbekannte Ausrichtung beim Aufruf von SetAlign() abgegeben. Horizontal=%s, Vertikal=%s',2), 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),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), 442 426 27014 => array('GTextTable: Die Tabelle wurde weder mit einem Aufruf von Set() noch von Init() initialisiert.',0), 443 427 27015 => array('GTextTable: Der Zellenbildbedingungstyp muss entweder TIMG_WIDTH oder TIMG_HEIGHT sein.',0), … … 447 431 */ 448 432 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),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), 455 439 22008 => array('Interner Fehler: Versuch, eine freie Windrose zu plotten, obwohl der Typ keine freie Windrose ist.',0), 456 440 22009 => array('Du hast die gleiche Richtung zweimal angegeben, einmal mit einem Winkel und einmal mit einer Kompassrichtung (%f Grad).',0), 457 441 22010 => array('Die Richtung muss entweder ein numerischer Wert sein oder eine der 16 Kompassrichtungen',0), 458 442 22011 => array('Der Windrosenindex muss ein numerischer oder Richtungswert sein. Du hast angegeben Index=%d',1), 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),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), 462 446 22015 => array('Du hast einen unbekannten Windrosenplottyp angegeben.',0), 463 447 22016 => array('Der Windrosenarmindex muss ein numerischer oder ein Richtungswert sein.',0), 464 448 22017 => array('Die Windrosendaten enthalten eine Richtung, die nicht aktiviert ist. Bitte berichtige, welche Label angezeigt werden sollen.',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),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), 468 452 22021 => array('It is only possible to add Text, IconPlot or WindrosePlot to a Windrose Graph',0), 469 453 … … 473 457 474 458 13001 => array('Unbekannter Nadeltypstil (%d).',1), 475 13002 => array('Ein Wert f ÃŒr das Odometer (%f) ist auÃerhalb des angegebenen Bereichs [%f,%f]',3),459 13002 => array('Ein Wert für das Odometer (%f) ist außerhalb des angegebenen Bereichs [%f,%f]',3), 476 460 477 461 /* … … 481 465 1001 => array('Unbekannte Kodier-Specifikation: %s',1), 482 466 1002 => array('datenvalidierung schlug fehl. [%s] kann nicht mittels der Kodierung "%s" kodiert werden',2), 483 1003 => array('Interner Kodierfehler. Kodieren von %s ist nicht m öglich in Code 128',1),467 1003 => array('Interner Kodierfehler. Kodieren von %s ist nicht möglich in Code 128',1), 484 468 1004 => array('Interner barcode Fehler. Unbekannter UPC-E Kodiertyp: %s',1), 485 469 1005 => array('Interner Fehler. Das Textzeichen-Tupel (%s, %s) kann nicht im Code-128 Zeichensatz C kodiert werden.',2), 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),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), 492 476 493 477 /* … … 495 479 */ 496 480 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),498 481 26001 => array('PDF417: Die Anzahl der Spalten muss zwischen 1 und 30 sein.',0), 499 482 26002 => array('PDF417: Der Fehler-Level muss zwischen 0 und 8 sein.',0), 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),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), 505 488 26008 => array('PDF417: Interner Fehler. Modus wurde nicht in der Modusliste!! Modus %d',1), 506 26009 => array('PDF417: Kodierfehler: Ung ÃŒltiges Zeichen. Zeichen kann nicht mit ASCII-Code %d kodiert werden.',1),489 26009 => array('PDF417: Kodierfehler: Ungültiges Zeichen. Zeichen kann nicht mit ASCII-Code %d kodiert werden.',1), 507 490 26010 => array('PDF417: Interner Fehler: Keine Eingabedaten beim Dekodieren.',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),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), 510 493 26013 => array('PDF417: Interner Fehler. Checksum Fehler. Koeffiziententabellen sind fehlerhaft.',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), 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), 548 497 549 498 -
trunk/client/modules/Elezioni/grafici/lang/en.inc.php
r265 r267 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 1886 2009-10-01 23:30:16Z ljp $5 // Created: 2006-01-25 6 // Ver: $Id: en.inc.php 1017 2008-07-08 06:09:28Z ljp $ 7 7 // 8 // Copyright (c) A sial Corporation. All rights reserved.8 // Copyright (c) Aditus Consulting. 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),106 105 107 106 /* … … 188 187 15010 => array('Sum of all data is 0 for Pie.',0), 189 188 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),191 189 192 190 /* … … 259 257 24002 => array('FuncGenerator : Syntax error in function specification ',0), 260 258 24003 => array('DateScaleUtils: Unknown tick type specified in call to GetTicks()',0), 261 24004 => array('ReadCSV2: Column count mismatch in %s line %d',2),262 259 /* 263 260 ** jpgraph … … 275 272 276 273 25010 => array('Graph::Add() 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), 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), 279 276 25013 => array('You can only add standard plots to multiple Y-axis',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), 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), 282 279 25016 => array('Graph::AddBand() You tried to add a null band to the graph.',0), 283 280 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), … … 305 302 25037 => array('The image format of your background image (%s) is not supported in your system configuration. ',1), 306 303 25038 => array('Background image seems to be of different type (has different file extension) than specified imagetype. Specified: %s File: %s',2), 307 25039 => array('Can\'t read background image: "%s"',1), 304 25039 => array('Can\'t read background image: "%s"',1), 308 305 309 306 25040 => array('It is not possible to specify both a background image and a background country flag.',0), … … 325 322 25055 => array('Axis::SetTickDirection() is deprecated. Use Axis::SetTickSide() instead',0), 326 323 25056 => array('SetTickLabelMargin() is deprecated. Use Axis::SetLabelMargin() instead.',0), 327 25057 => array('SetTextTicks() is deprecated. Use SetTextTickInterval() instead.',0), 324 25057 => array('SetTextTicks() is deprecated. Use SetTextTickInterval() instead.',0), 328 325 25058 => array('Text label interval must be specified >= 1.',0), 329 326 25059 => array('SetLabelPos() is deprecated. Use Axis::SetLabelSide() instead.',0), … … 369 366 25097 => array('Color specified as empty string in PushColor().',0), 370 367 25098 => array('Negative Color stack index. Unmatched call to PopColor()',0), 371 25099 => array('Parameters for brightness and Contrast out of range [-1,1]',0), 368 25099 => array('Parameters for brightness and Contrast out of range [-1,1]',0), 372 369 373 370 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), … … 388 385 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), 389 386 25115 => array('Can\'t set permission for cached image "%s". Permission problem?',1), 390 25116 => array('Cant open file from cache "%s"',1), 387 25116 => array('Cant open file from cache "%s"',1), 391 388 25117 => array('Can\'t open cached image "%s" for reading.',1), 392 389 25118 => array('Can\'t create directory "%s". Make sure PHP has write permission to this directory.',1), … … 403 400 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), 404 401 25129 => array('Anti-alias can not be used with dashed lines. Please disable anti-alias or use solid lines.',0), 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), 402 416 403 417 404 /* … … 422 409 423 410 /* 424 ** jpgraph_table 411 ** jpgraph_table 425 412 */ 426 413 … … 491 478 ** PDF417 492 479 */ 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), 480 494 481 26001 => array('PDF417: Number of Columns must be >= 1 and <= 30',0), 495 482 26002 => array('PDF417: Error level must be between 0 and 8',0), … … 509 496 26016 => array('PDF417: Internal error: Unrecognized state transition mode in decode.',0), 510 497 511 /*512 ** jpgraph_contour513 */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 colormap525 */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_theme540 */541 30001 => array("Theme::%s() is not defined. \nPlease make %s(\$graph) function in your theme classs.",2),542 498 543 499 ); -
trunk/client/modules/Elezioni/grafici/lang/prod.inc.php
r265 r267 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 1886 2009-10-01 23:30:16Z ljp $7 // Ver: $Id: prod.inc.php 993 2008-03-30 21:17:41Z ljp $ 8 8 // 9 // Copyright (c) A sial Corporation. All rights reserved.9 // Copyright (c) Aditus Consulting. 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),79 78 7001 => array(DEFAULT_ERROR_MESSAGE.'7001',0), 80 79 8001 => array(DEFAULT_ERROR_MESSAGE.'8001',0), … … 121 120 15010 => array(DEFAULT_ERROR_MESSAGE.'15010',0), 122 121 15011 => array(DEFAULT_ERROR_MESSAGE.'15011',0), 123 15012 => array(DEFAULT_ERROR_MESSAGE.'15012',0),124 122 16001 => array(DEFAULT_ERROR_MESSAGE.'16001',0), 125 123 16002 => array(DEFAULT_ERROR_MESSAGE.'16002',0), … … 150 148 24002 => array(DEFAULT_ERROR_MESSAGE.'24002',0), 151 149 24003 => array(DEFAULT_ERROR_MESSAGE.'24003',0), 152 24004 => array(DEFAULT_ERROR_MESSAGE.'24004',0),153 150 25001 => array(DEFAULT_ERROR_MESSAGE.'25001',0), 154 151 25002 => array(DEFAULT_ERROR_MESSAGE.'25002',0), … … 279 276 25128 => array(DEFAULT_ERROR_MESSAGE.'25128',0), 280 277 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),286 278 24003 => array(DEFAULT_ERROR_MESSAGE.'24003',0), 287 279 24004 => array(DEFAULT_ERROR_MESSAGE.'24004',0), … … 329 321 1010 => array(DEFAULT_ERROR_MESSAGE.'1010',0), 330 322 1011 => array(DEFAULT_ERROR_MESSAGE.'1011',0), 331 26000 => array(DEFAULT_ERROR_MESSAGE.'26000',0),332 323 26001 => array(DEFAULT_ERROR_MESSAGE.'26001',0), 333 324 26002 => array(DEFAULT_ERROR_MESSAGE.'26002',0), … … 362 353 27014 => array(DEFAULT_ERROR_MESSAGE.'27014',0), 363 354 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 384 355 ); 385 356
Note:
See TracChangeset
for help on using the changeset viewer.