Development

Changeset 6910

You must first sign up to be able to contribute.

Changeset 6910

Show
Ignore:
Timestamp:
01/03/08 08:03:55 (11 months ago)
Author:
dwhittle
Message:

dwhittle: updated dwJpgraphPlugin, released 1.0 (updated jpgraph to 2.3) + fixed phpdoc + cleaned up

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • plugins/dwJpgraphPlugin/LICENSE

    r2817 r6910  
    1 Copyright (c) 2004-2006 Dustin Whittl
     1The MIT Licens
    22 
    3 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 
     3Permission is hereby granted, free of charge, to any person obtaining a copy 
     4of this software and associated documentation files (the "Software"), to deal 
     5in the Software without restriction, including without limitation the rights 
     6to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
     7copies of the Software, and to permit persons to whom the Software is 
     8furnished to do so, subject to the following conditions: 
    49 
    5 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 
     10The above copyright notice and this permission notice shall be included in 
     11all copies or substantial portions of the Software. 
    612 
    7 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
     13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
     14IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
     15FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
     16AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
     17LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
     18OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
     19THE SOFTWARE. 
    820 
    921The JPGRAPH library is licensed under THE Q PUBLIC LICENSE version 1.0, please see lib/jpgraph/QPL.txt for more information. 
  • plugins/dwJpgraphPlugin/README

    r2860 r6910  
    1 = sfJpGraphPlugin plugin = 
     1= dwJpgraphPlugin = 
    22 
    3 The `sfJpGraphPlugin` provides abstraction for the PHP JpGraph library. 
     3The `dwJpgraphPlugin` provides abstraction for the PHP Jpgraph library. 
    44 
    55== Installation == 
    66 
    77  * Install the plugin 
    8    
     8 
    99  {{{ 
    10     symfony plugin-install http://plugins.symfony-project.com/sfJpGraphPlugin 
     10    symfony plugin-install http://plugins.symfony-project.org/dwJpgraphPlugin 
    1111  }}} 
    1212 
     
    1818 
    1919  * You're done. 
     20 
     21== Using the plugin == 
     22 
     23See the example module/action: dwJpgraphPlugin/test. 
  • plugins/dwJpgraphPlugin/lib/jpgraph/jpg-config.inc.php

    r2817 r6910  
    5252// directory from where the image script is executed and store all files 
    5353// there. As ususal this directory must be writeable by the PHP process. 
    54  
    5554DEFINE("CSIMCACHE_DIR","csimcache/"); 
    5655DEFINE("CSIMCACHE_HTTP_DIR","csimcache/"); 
     
    198197// specified group since otherwise it is impossible for Apache 
    199198// to set the specified group. 
    200 DEFINE("CACHE_FILE_GROUP","www-data"); 
     199DEFINE("CACHE_FILE_GROUP","nobody"); 
    201200 
    202201// What permissions should the cached file have 
  • plugins/dwJpgraphPlugin/lib/jpgraph/jpgraph.php

    r2817 r6910  
    1010 
    1111require_once('jpg-config.inc.php'); 
    12 require_once 'jpgraph_gradient.php'; 
    13 require_once 'jpgraph_errhandler.inc.php'; 
     12require_once('jpgraph_gradient.php'); 
     13require_once('jpgraph_errhandler.inc.php'); 
     14require_once('jpgraph_ttf.inc.php'); 
    1415 
    1516// Version info 
    16 DEFINE('JPG_VERSION','2.2.1'); 
     17DEFINE('JPG_VERSION','2.3'); 
    1718 
    1819// Minimum required PHP version 
     
    2021 
    2122// Should the image be a truecolor image?  
    22 // Note 1: Has only effect with GD 2.0.1 and above. 
    23 // Note 2: GD 2.0.1 + PHP 4.0.6 on Win32 crashes when trying to use  
    24 // trucolor. 
    25 // Note 3: MUST be enabled to get background images working with GD2 
    2623DEFINE('USE_TRUECOLOR',true); 
    2724 
     
    7067//------------------------------------------------------------------ 
    7168 
    72 // TTF Font families 
    73 // Note: First font must be FF_COURIER and the last font family must 
    74 // be given to _LAST_FONT. This is used for error checking in the text 
    75 // handling routines. 
    76 DEFINE("FF_COURIER",10); 
    77 DEFINE("FF_VERDANA",11); 
    78 DEFINE("FF_TIMES",12); 
    79 DEFINE("FF_COMIC",14); 
    80 DEFINE("FF_ARIAL",15); 
    81 DEFINE("FF_GEORGIA",16); 
    82 DEFINE("FF_TREBUCHE",17); 
    83  
    84 // Gnome Vera font 
    85 // Available from http://www.gnome.org/fonts/ 
    86 DEFINE("FF_VERA",18); 
    87 DEFINE("FF_VERAMONO",19); 
    88 DEFINE("FF_VERASERIF",20); 
    89  
    90 // Chinese font 
    91 DEFINE("FF_SIMSUN",30); 
    92 DEFINE("FF_CHINESE",31); 
    93 DEFINE("FF_BIG5",31); 
    94  
    95 // Japanese font 
    96 DEFINE("FF_MINCHO",40); 
    97 DEFINE("FF_PMINCHO",41); 
    98 DEFINE("FF_GOTHIC",42); 
    99 DEFINE("FF_PGOTHIC",43); 
    100  
    101 // Limits for fonts 
    102 DEFINE("_FIRST_FONT",10); 
    103 DEFINE("_LAST_FONT",43); 
    104  
    105 // TTF Font styles 
    106 DEFINE("FS_NORMAL",9001); 
    107 DEFINE("FS_BOLD",9002); 
    108 DEFINE("FS_ITALIC",9003); 
    109 DEFINE("FS_BOLDIT",9004); 
    110 DEFINE("FS_BOLDITALIC",9004); 
    111  
    112 //Definitions for internal font, new style 
    113 DEFINE("FF_FONT0",1); 
    114 DEFINE("FF_FONT1",2); 
    115 DEFINE("FF_FONT2",4); 
    11669 
    11770// Tick density 
     
    297250    elseif( $supported & IMG_GIF ) $img_format="gif"; 
    298251    elseif( $supported & IMG_JPG ) $img_format="jpeg"; 
     252    elseif( $supported & IMG_WBMP ) $img_format="wbmp"; 
     253    elseif( $supported & IMG_XPM ) $img_format="xpm"; 
     254 
    299255 
    300256    if( !isset($_SERVER['PHP_SELF']) ) 
     
    312268} 
    313269 
    314 class LanguageConv { 
    315     private $g2312 = null ; 
    316  
    317     function Convert($aTxt,$aFF) { 
    318   if( LANGUAGE_GREEK ) { 
    319       if( GREEK_FROM_WINDOWS ) { 
    320     $unistring = LanguageConv::gr_win2uni($aTxt);  
    321       } else  { 
    322     $unistring = LanguageConv::gr_iso2uni($aTxt); 
    323       } 
    324       return $unistring; 
    325   } elseif( LANGUAGE_CYRILLIC ) { 
    326       if( CYRILLIC_FROM_WINDOWS && (!defined('LANGUAGE_CHARSET') || stristr(LANGUAGE_CHARSET, 'windows-1251')) ) { 
    327     $aTxt = convert_cyr_string($aTxt, "w", "k");  
    328       } 
    329       if( !defined('LANGUAGE_CHARSET') || stristr(LANGUAGE_CHARSET, 'koi8-r') || stristr(LANGUAGE_CHARSET, 'windows-1251')) { 
    330     $isostring = convert_cyr_string($aTxt, "k", "i"); 
    331     $unistring = LanguageConv::iso2uni($isostring); 
    332       } 
    333       else { 
    334     $unistring = $aTxt; 
    335       } 
    336       return $unistring; 
    337   } 
    338   elseif( $aFF === FF_SIMSUN ) { 
    339       // Do Chinese conversion 
    340       if( $this->g2312 == null ) { 
    341     include_once 'jpgraph_gb2312.php' ; 
    342     $this->g2312 = new GB2312toUTF8(); 
    343       } 
    344       return $this->g2312->gb2utf8($aTxt); 
    345   } 
    346   elseif( $aFF === FF_CHINESE ) { 
    347       if( !function_exists('iconv') ) { 
    348     JpGraphError::RaiseL(25006); 
    349 //('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).'); 
    350       } 
    351       return iconv('BIG5','UTF-8',$aTxt); 
    352   } 
    353   elseif( ASSUME_EUCJP_ENCODING && 
    354     ($aFF == FF_MINCHO || $aFF == FF_GOTHIC || $aFF == FF_PMINCHO || $aFF == FF_PGOTHIC) ) { 
    355       if( !function_exists('mb_convert_encoding') ) { 
    356     JpGraphError::RaiseL(25127); 
    357       } 
    358       return mb_convert_encoding($aTxt, 'UTF-8','EUC-JP'); 
    359   } 
    360   else  
    361       return $aTxt; 
    362     } 
    363  
    364     // Translate iso encoding to unicode 
    365     public static function iso2uni ($isoline){ 
    366   $uniline=''; 
    367   for ($i=0; $i < strlen($isoline); $i++){ 
    368       $thischar=substr($isoline,$i,1); 
    369       $charcode=ord($thischar); 
    370       $uniline.=($charcode>175) ? "&#" . (1040+($charcode-176)). ";" : $thischar; 
    371   } 
    372   return $uniline; 
    373     } 
    374  
    375     // Translate greek iso encoding to unicode 
    376     public static function gr_iso2uni ($isoline) { 
    377   $uniline=''; 
    378   for ($i=0; $i < strlen($isoline); $i++) { 
    379       $thischar=substr($isoline,$i,1); 
    380       $charcode=ord($thischar); 
    381       $uniline.=($charcode>179 && $charcode!=183 && $charcode!=187 && $charcode!=189) ? "&#" . (900+($charcode-180)). ";" : $thischar; 
    382   } 
    383   return $uniline; 
    384     } 
    385  
    386     // Translate greek win encoding to unicode 
    387     public static function gr_win2uni ($winline) { 
    388   $uniline=''; 
    389   for ($i=0; $i < strlen($winline); $i++) { 
    390       $thischar=substr($winline,$i,1); 
    391       $charcode=ord($thischar); 
    392       if ($charcode==161 || $charcode==162) { 
    393     $uniline.="&#" . (740+$charcode). ";"; 
    394       } 
    395       else { 
    396     $uniline.=(($charcode>183 && $charcode!=187 && $charcode!=189) || $charcode==180) ? "&#" . (900+($charcode-180)). ";" : $thischar; 
    397       } 
    398   } 
    399   return $uniline; 
    400     } 
    401 } 
    402270 
    403271//=================================================== 
     
    599467    public $title,$subtitle,$subsubtitle;   // Title and subtitle(s) text object 
    600468    public $axtype="linlin";  // Type of axis 
    601     public $xtick_factor;  // Factot to determine the maximum number of ticks depending on the plot with 
     469    public $xtick_factor,$ytick_factor;  // Factor to determine the maximum number of ticks depending on the plot width 
    602470    public $texts=null, $y2texts=null;    // Text object to ge shown in the graph 
    603471    public $lines=null, $y2lines=null; 
     
    613481    public $iCSIMdisplay=false,$iHasStroked = false; 
    614482    public $footer; 
    615     public $csimcachename = '', $csimcachetimeout = 0
     483    public $csimcachename = '', $csimcachetimeout = 0, $iCSIMImgAlt=''
    616484    public $iDoClipping = false; 
    617485    public $y2orderback=true; 
     
    640508  $iImgTransFillColor='white',$iImgTransHighQ=false, 
    641509  $iImgTransBorder=false,$iImgTransHorizonPos=0.5; 
     510    public $legend; 
    642511    protected $iYAxisDeltaPos=50; 
    643512    protected $iIconDepth=DEPTH_BACK; 
     
    991860    } 
    992861   
    993     // Adjust brightness and constrast for background image 
    994     function AdjBackgroundImage($aBright,$aContr=0,$aSat=0) { 
    995   $this->background_image_bright=$aBright; 
    996   $this->background_image_contr=$aContr; 
    997   $this->background_image_sat=$aSat; 
    998     } 
    999    
    1000     // Adjust brightness and constrast for image 
    1001     function AdjImage($aBright,$aContr=0,$aSat=0) { 
    1002   $this->image_bright=$aBright; 
    1003   $this->image_contr=$aContr; 
    1004   $this->image_sat=$aSat; 
    1005     } 
    1006  
    1007862    // Specify axis style (boxed or single) 
    1008863    function SetAxisStyle($aStyle) { 
     
    13121167    $n = count($value); 
    13131168    for( $i=0; $i < $n; ++$i ) { 
    1314         $urlarg .= '&'.$key.'%5B%5D='.urlencode($value[$i]); 
     1169        $urlarg .= '&amp;'.$key.'%5B%5D='.urlencode($value[$i]); 
    13151170    } 
    13161171      } 
    13171172      else { 
    1318     $urlarg .= '&'.$key.'='.urlencode($value); 
     1173    $urlarg .= '&amp;'.$key.'='.urlencode($value); 
    13191174      } 
    13201175  } 
     
    13281183    $n = count($value); 
    13291184    for( $i=0; $i < $n; ++$i ) { 
    1330         $urlarg .= '&'.$key.'%5B%5D='.urlencode($value[$i]); 
     1185        $urlarg .= '&amp;'.$key.'%5B%5D='.urlencode($value[$i]); 
    13311186    } 
    13321187      } 
    13331188      else { 
    1334     $urlarg .= '&'.$key.'='.urlencode($value); 
     1189    $urlarg .= '&amp;'.$key.'='.urlencode($value); 
    13351190      } 
    13361191  } 
    13371192 
    13381193  return $urlarg; 
     1194    } 
     1195 
     1196    function SetCSIMImgAlt($aAlt) { 
     1197  $this->iCSIMImgAlt = $aAlt; 
    13391198    } 
    13401199 
     
    13851244    $tmp = str_replace('?','%3f',$baseimg); 
    13861245    $htmlwrap = $this->GetHTMLImageMap($aCSIMName)."\n". 
    1387         '<img src="'.CSIMCACHE_HTTP_DIR.$tmp.'" ismap="ismap" usemap="#'.$aCSIMName.'" border="'.$aBorder.'" width="'.$this->img->width.'" height="'.$this->img->height."\" alt=\"\" />\n"; 
     1246        '<img src="'.CSIMCACHE_HTTP_DIR.$tmp.'" ismap="ismap" usemap="#'.$aCSIMName.'" border="'.$aBorder.'" width="'.$this->img->width.'" height="'.$this->img->height."\" alt=\"".$this->iCSIMImgAlt."\" />\n"; 
    13881247 
    13891248    if($fh =  @fopen($basecsim,'w') ) { 
     
    14011260    } 
    14021261    echo $this->GetHTMLImageMap($aCSIMName); 
    1403     echo "<img src=\"".$aScriptName.'?'.$urlarg."\" ismap=\"ismap\" usemap=\"#".$aCSIMName.'" border="'.$aBorder.'" width="'.$this->img->width.'" height="'.$this->img->height."\" alt=\"\" />\n"; 
     1262    echo "<img src=\"".$aScriptName.'?'.$urlarg."\" ismap=\"ismap\" usemap=\"#".$aCSIMName.'" border="'.$aBorder.'" width="'.$this->img->width.'" height="'.$this->img->height."\" alt=\"".$this->iCSIMImgAlt."\" />\n"; 
    14041263      } 
    14051264  } 
     
    20181877      for($i=0; $i < count($this->lines); ++$i) { 
    20191878    $this->lines[$i]->Stroke($this->img,$this->xscale,$this->yscale); 
     1879    $this->lines[$i]->DoLegend($this); 
    20201880      } 
    20211881  } 
     
    20241884      for($i=0; $i < count($this->y2lines); ++$i) { 
    20251885    $this->y2lines[$i]->Stroke($this->img,$this->xscale,$this->y2scale); 
     1886    $this->y2lines[$i]->DoLegend($this); 
    20261887      } 
    20271888  } 
     
    20591920      } 
    20601921       
    2061       // Adjust the appearance of the image 
    2062       $this->AdjustSaturationBrightnessContrast(); 
    2063  
    20641922      // Should we do any final image transformation 
    20651923      if( $this->iImgTrans ) { 
     
    22362094    $this->xaxis->SetLabelSide(SIDE_UP); 
    22372095    // No title for the top X-axis  
    2238     $this->title->Set(''); 
     2096    if( $aStrokeLabels ) { 
     2097        $this->xaxis->title->Set(''); 
     2098    } 
    22392099    $this->xaxis->scale->ticks->SetSide($toppos); 
    22402100    $this->xaxis->Stroke($this->yscale,$aStrokeLabels); 
     
    22502110      $this->yaxis->SetPos('max'); 
    22512111      // No title for the right side  
    2252       $this->title->Set(''); 
     2112      if( $aStrokeLabels ) { 
     2113    $this->yaxis->title->Set(''); 
     2114      } 
    22532115      $this->yaxis->SetLabelSide(SIDE_RIGHT); 
    22542116      $this->yaxis->scale->ticks->SetSide($rightpos); 
     
    22632125 
    22642126    // Private helper function for backgound image 
    2265     function LoadBkgImage($aImgFormat='',$aFile='',$aImgStr='') { 
     2127    static function LoadBkgImage($aImgFormat='',$aFile='',$aImgStr='') { 
    22662128  if( $aImgStr != '' ) { 
    22672129      return Image::CreateFromString($aImgStr); 
    22682130  } 
    2269   if( $aFile == '' ) 
    2270       $aFile = $this->background_image; 
     2131 
    22712132  // Remove case sensitivity and setup appropriate function to create image 
    22722133  // Get file extension. This should be the LAST '.' separated part of the filename 
     
    22882149  if( ( $ext == 'jpg' && !($supported & IMG_JPG) ) || 
    22892150      ( $ext == 'gif' && !($supported & IMG_GIF) ) || 
    2290       ( $ext == 'png' && !($supported & IMG_PNG) ) ) { 
     2151      ( $ext == 'png' && !($supported & IMG_PNG) ) || 
     2152      ( $ext == 'bmp' && !($supported & IMG_WBMP) ) || 
     2153      ( $ext == 'xpm' && !($supported & IMG_XPM) ) ) { 
     2154 
    22912155      JpGraphError::RaiseL(25037,$aFile);//('The image format of your background image ('.$aFile.') is not supported in your system configuration. '); 
    22922156  } 
     
    23532217  } 
    23542218  if( $this->background_image != "" ) { 
    2355       $bkgimg = $this->LoadBkgImage($this->background_image_format); 
    2356       $this->img->_AdjBrightContrast($bkgimg,$this->background_image_bright, 
    2357              $this->background_image_contr); 
    2358       $this->img->_AdjSat($bkgimg,$this->background_image_sat); 
     2219      $bkgimg = $this->LoadBkgImage($this->background_image_format,$this->background_image); 
    23592220  } 
    23602221  elseif( $this->background_cflag != "" ) { 
     
    27922653    } 
    27932654 
    2794     function AdjustSaturationBrightnessContrast() { 
    2795   // Adjust the brightness and contrast of the image 
    2796   if( $this->image_contr || $this->image_bright ) 
    2797       $this->img->AdjBrightContrast($this->image_bright,$this->image_contr); 
    2798   if( $this->image_sat )                        
    2799       $this->img->AdjSat($this->image_sat); 
    2800     } 
    2801  
    28022655    // Text scale offset in world coordinates 
    28032656    function SetTextScaleOff($aOff) { 
     
    28792732    } 
    28802733 
    2881 } // Class 
    2882  
    2883  
    2884 //=================================================== 
    2885 // CLASS TTF 
    2886 // Description: Handle TTF font names 
    2887 //=================================================== 
    2888 class TTF { 
    2889     private $font_files,$style_names; 
    2890 //--------------- 
    2891 // CONSTRUCTOR 
    2892     function TTF() { 
    2893   $this->style_names=array(FS_NORMAL=>'normal',FS_BOLD=>'bold',FS_ITALIC=>'italic',FS_BOLDITALIC=>'bolditalic'); 
    2894   // File names for available fonts 
    2895   $this->font_files=array( 
    2896       FF_COURIER => array(FS_NORMAL=>'cour.ttf', FS_BOLD=>'courbd.ttf', FS_ITALIC=>'couri.ttf', FS_BOLDITALIC=>'courbi.ttf' ), 
    2897       FF_GEORGIA => array(FS_NORMAL=>'georgia.ttf', FS_BOLD=>'georgiab.ttf', FS_ITALIC=>'georgiai.ttf', FS_BOLDITALIC=>'' ), 
    2898       FF_TREBUCHE =>array(FS_NORMAL=>'trebuc.ttf', FS_BOLD=>'trebucbd.ttf',   FS_ITALIC=>'trebucit.ttf', FS_BOLDITALIC=>'trebucbi.ttf' ), 
    2899       FF_VERDANA => array(FS_NORMAL=>'verdana.ttf', FS_BOLD=>'verdanab.ttf',  FS_ITALIC=>'verdanai.ttf', FS_BOLDITALIC=>'' ), 
    2900       FF_TIMES =>   array(FS_NORMAL=>'times.ttf',   FS_BOLD=>'timesbd.ttf',   FS_ITALIC=>'timesi.ttf',   FS_BOLDITALIC=>'timesbi.ttf' ), 
    2901       FF_COMIC =>   array(FS_NORMAL=>'comic.ttf',   FS_BOLD=>'comicbd.ttf',   FS_ITALIC=>'',         FS_BOLDITALIC=>'' ), 
    2902       FF_ARIAL =>   array(FS_NORMAL=>'arial.ttf',   FS_BOLD=>'arialbd.ttf',   FS_ITALIC=>'ariali.ttf',   FS_BOLDITALIC=>'arialbi.ttf' ) , 
    2903       FF_VERA =>    array(FS_NORMAL=>'Vera.ttf',   FS_BOLD=>'VeraBd.ttf',   FS_ITALIC=>'VeraIt.ttf',   FS_BOLDITALIC=>'VeraBI.ttf' ), 
    2904       FF_VERAMONO => array(FS_NORMAL=>'VeraMono.ttf', FS_BOLD=>'VeraMoBd.ttf', FS_ITALIC=>'VeraMoIt.ttf', FS_BOLDITALIC=>'VeraMoBI.ttf' ), 
    2905       FF_VERASERIF => array(FS_NORMAL=>'VeraSe.ttf', FS_BOLD=>'VeraSeBd.ttf', FS_ITALIC=>'', FS_BOLDITALIC=>'' ) , 
    2906       FF_SIMSUN =>  array(FS_NORMAL=>'simsun.ttc',  FS_BOLD=>'simhei.ttf',   FS_ITALIC=>'',   FS_BOLDITALIC=>'' ), 
    2907       FF_CHINESE => array(FS_NORMAL=>CHINESE_TTF_FONT, FS_BOLD=>'', FS_ITALIC=>'', FS_BOLDITALIC=>'' ), 
    2908       FF_MINCHO =>  array(FS_NORMAL=>MINCHO_TTF_FONT,  FS_BOLD=>'',   FS_ITALIC=>'',   FS_BOLDITALIC=>'' ), 
    2909       FF_PMINCHO => array(FS_NORMAL=>PMINCHO_TTF_FONT,  FS_BOLD=>'',   FS_ITALIC=>'',   FS_BOLDITALIC=>'' ),     
    2910       FF_GOTHIC  => array(FS_NORMAL=>GOTHIC_TTF_FONT,  FS_BOLD=>'',   FS_ITALIC=>'',   FS_BOLDITALIC=>'' ),     
    2911       FF_PGOTHIC => array(FS_NORMAL=>PGOTHIC_TTF_FONT,  FS_BOLD=>'',   FS_ITALIC=>'',   FS_BOLDITALIC=>'' ),     
    2912       FF_MINCHO =>  array(FS_NORMAL=>PMINCHO_TTF_FONT,  FS_BOLD=>'',   FS_ITALIC=>'',   FS_BOLDITALIC=>'' )    
    2913 ); 
    2914     } 
    2915  
    2916 //--------------- 
    2917 // PUBLIC METHODS  
    2918     // Create the TTF file from the font specification 
    2919     function File($family,$style=FS_NORMAL) { 
    2920   $fam = @$this->font_files[$family]; 
    2921   if( !$fam ) { 
    2922       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/"); 
    2923   } 
    2924   $f = @$fam[$style]; 
    2925  
    2926   if( $f==='' ) 
    2927       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].'.'); 
    2928   if( !$f ) { 
    2929       JpGraphError::RaiseL(25048,$fam);//("Unknown font style specification [$fam]."); 
    2930   } 
    2931  
    2932   if ($family >= FF_MINCHO && $family <= FF_PGOTHIC) { 
    2933       $f = MBTTF_DIR.$f; 
    2934   } else { 
    2935       $f = TTF_DIR.$f; 
    2936   } 
    2937  
    2938   if( file_exists($f) === false || is_readable($f) === false ) { 
    2939       JpGraphError::RaiseL(25049,$f);//("Font file \"$f\" is not readable or does not exist."); 
    2940   } 
    2941   return $f; 
    2942     } 
    29432734} // Class 
    29442735 
     
    30002791    protected $icornerradius=0,$ishadowwidth=3; 
    30012792    protected $fcolor='white',$bcolor='black',$shadow=false; 
    3002     protected $iCSIMarea='',$iCSIMalt='',$iCSIMtarget=''
     2793    protected $iCSIMarea='',$iCSIMalt='',$iCSIMtarget='',$iCSIMWinTarget=''
    30032794 
    30042795//--------------- 
     
    31802971    } 
    31812972 
    3182     function SetCSIMTarget($aTarget,$aAlt=null) { 
    3183   $this->iCSIMtarget = $aTarget; 
     2973    function SetCSIMTarget($aURITarget,$aAlt='',$aWinTarget='') { 
     2974  $this->iCSIMtarget = $aURITarget; 
    31842975  $this->iCSIMalt = $aAlt; 
     2976  $this->iCSIMWinTarget = $aWinTarget; 
    31852977    } 
    31862978 
     
    32263018  // Create CSIM targets 
    32273019  $coords = $bbox[0].','.$bbox[1].','.$bbox[2].','.$bbox[3].','.$bbox[4].','.$bbox[5].','.$bbox[6].','.$bbox[7]; 
    3228   $this->iCSIMarea = "<area shape=\"poly\" coords=\"$coords\" href=\"".htmlentities($this->iCSIMtarget)."\""; 
    3229   $this->iCSIMarea .= " alt=\"".$this->iCSIMalt."\" title=\"".$this->iCSIMalt."\" />\n"; 
     3020  $this->iCSIMarea = "<area shape=\"poly\" coords=\"$coords\" href=\"".htmlentities($this->iCSIMtarget)."\" "; 
     3021  if( trim($this->iCSIMalt) != '' ) { 
     3022      $this->iCSIMarea .= " alt=\"".$this->iCSIMalt."\" ";  
     3023      $this->iCSIMarea .= " title=\"".$this->iCSIMalt."\" "; 
     3024  } 
     3025  if( trim($this->iCSIMWinTarget) != '' ) { 
     3026      $this->iCSIMarea .= " target=\"".$this->iCSIMWinTarget."\" ";  
     3027  } 
     3028  $this->iCSIMarea .= " />\n"; 
    32303029 
    32313030  $aImg->PopColor($this->color);   
     
    35783377    // Display the grid 
    35793378    function Stroke() { 
    3580   if( $this->showMinor ) { 
     3379  if( $this->showMinor && !$this->scale->textscale ) { 
    35813380      $tmp = $this->grid_color; 
    35823381      $this->grid_color = $this->grid_mincolor; 
     
    36923491    public $tick_step=1; 
    36933492    public $pos = false; 
     3493    public $ticks_label = array(); 
     3494 
    36943495    protected $weight=1; 
    36953496    protected $color=array(0,0,0),$label_color=array(0,0,0); 
    3696     protected $ticks_label=false, $ticks_label_colors=null; 
     3497    protected $ticks_label_colors=null; 
    36973498    protected $show_first_label=true,$show_last_label=true; 
    36983499    protected $label_step=1; // Used by a text axis to specify what multiple of major steps 
     
    41563957    public $direction=1; // Should ticks be in(=1) the plot area or outside (=-1) 
    41573958    public $supress_last=false,$supress_tickmarks=false,$supress_minor_tickmarks=false; 
     3959    public $maj_ticks_pos = array(), $maj_ticklabels_pos = array(),  
     3960     $ticks_pos = array(), $maj_ticks_label = array(); 
    41583961 
    41593962    protected $minor_abs_size=3, $major_abs_size=5; 
     
    42804083    public $minor_step=1, $major_step=2; 
    42814084    public $xlabel_offset=0,$xtick_offset=0; 
    4282     public $maj_ticks_pos = array(), $maj_ticklabels_pos = array(),  
    4283   $ticks_pos = array(), $maj_ticks_label = array(); 
    42844085    private $label_offset=0; // What offset should the displayed label have 
    42854086    // i.e should we display 0,1,2 or 1,2,3,4 or 2,3,4 etc 
     
    43474148  $m=count($this->iManualMinTickPos); 
    43484149  $doLbl=count($this->iManualTickLabels) > 0; 
    4349   $this->use_manualtickpos=true; 
    43504150 
    43514151  $this->maj_ticks_pos = array(); 
     
    44484248        $this->ticks_pos[] = round($abs_pos); 
    44494249        $this->ticks_label[] = $label; 
    4450         if( $i % $step == 0 && $j < $nbrmajticks ) { 
     4250        if( $step== 0 || $i % $step == 0 && $j < $nbrmajticks ) { 
    44514251      $this->maj_ticks_pos[$j] = round($abs_pos); 
    44524252      $this->maj_ticklabels_pos[$j] = round($abs_pos); 
     
    44644264        $this->ticks_pos[$i] = round($abs_pos);  
    44654265        $this->ticks_label[$i]=$label; 
    4466         if( $i % $step == 0 && $j < $nbrmajticks) { 
     4266        if( $step== 0 || $i % $step == 0 && $j < $nbrmajticks) { 
    44674267      $this->maj_ticks_pos[$j] = round($abs_pos); 
    44684268      $this->maj_ticklabels_pos[$j] = round($abs_pos); 
     
    46364436    public $textscale=false; // Just a flag to let the Plot class find out if 
    46374437    // we are a textscale or not. This is a cludge since 
    4638     // this ionformatyion is availabale in Graph::axtype but 
     4438    // this information is available in Graph::axtype but 
    46394439    // we don't have access to the graph object in the Plots 
    46404440    // stroke method. So we let graph store the status here 
     
    46504450    public $auto_ticks=false; // When using manual scale should the ticks be automatically set? 
    46514451    public $world_abs_size; // Plot area size in pixels (Needed public in jpgraph_radar.php) 
    4652     private $world_size;  // Plot area size in world coordinates 
    4653     private $autoscale_min=false; // Forced minimum value, auto determine max 
    4654     private $autoscale_max=false; // Forced maximum value, auto determine min 
     4452    public $world_size; // Plot area size in world coordinates 
     4453    public $intscale=false; // Restrict autoscale to integers 
     4454    protected $autoscale_min=false; // Forced minimum value, auto determine max 
     4455    protected $autoscale_max=false; // Forced maximum value, auto determine min 
    46554456    private $gracetop=0,$gracebottom=0; 
    4656     private $intscale=false; // Restrict autoscale to integers 
    46574457//--------------- 
    46584458// CONSTRUCTOR 
     
    57715571    //--------------- 
    57725572    // CONSTRUCTOR 
    5773     function Image($aWidth,$aHeight,$aFormat=DEFAULT_GFORMAT) { 
     5573    function Image($aWidth,$aHeight,$aFormat=DEFAULT_GFORMAT,$aSetAutoMargin=true) { 
    57745574  $this->CreateImgCanvas($aWidth,$aHeight); 
    5775   $this->SetAutoMargin();    
     5575  if( $aSetAutoMargin ) 
     5576      $this->SetAutoMargin();    
    57765577 
    57775578  if( !$this->SetImgFormat($aFormat) ) { 
     
    57905591    function SetAntiAliasing($aFlg=true) { 
    57915592  $this->use_anti_aliasing = $aFlg; 
    5792   imageantialias($this->img,$aFlg); 
     5593  if( function_exists('imageantialias') ) { 
     5594      imageantialias($this->img,$aFlg); 
     5595  } 
     5596  else { 
     5597      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.') 
     5598  } 
    57935599    } 
    57945600 
     
    59395745    function SetAutoMargin() {   
    59405746  GLOBAL $gJpgBrandTiming; 
    5941   $min_bm=10
     5747  $min_bm=5
    59425748  /* 
    59435749  if( $gJpgBrandTiming ) 
     
    59465752  $lm = min(40,$this->width/7); 
    59475753  $rm = min(20,$this->width/10); 
    5948   $tm = max(20,$this->height/7); 
     5754  $tm = max(5,$this->height/7); 
    59495755  $bm = max($min_bm,$this->height/7); 
    59505756  $this->SetMargin($lm,$rm,$tm,$bm);     
     
    60915897  elseif( $this->text_valign=="center" ) $y -= $height/2; 
    60925898   
     5899  $olda = $this->SetAngle(0); 
     5900 
    60935901  if( $shadowcolor ) { 
    60945902      $this->PushColor($shadowcolor); 
     
    61295937        $x+$width,$y-$ymarg,$x-$xmarg,$y-$ymarg); 
    61305938  $this->SetTextAlign($h,$v); 
     5939 
     5940  $this->SetAngle($olda); 
     5941 
    61315942  return $bb; 
    61325943    } 
     
    65336344   
    65346345   
    6535     // Why this duplication? Because this way we can call this method 
    6536     // for any image and not only the current objsct 
    6537     function AdjSat($sat) {  
    6538   if( USE_TRUECOLOR ) 
    6539       return; 
    6540   $this->_AdjSat($this->img,$sat);   
    6541     }  
    6542    
    6543     function _AdjSat($img,$sat) { 
    6544   $nbr = imagecolorstotal ($img); 
    6545   for( $i=0; $i<$nbr; ++$i ) { 
    6546       $colarr = imagecolorsforindex ($img,$i); 
    6547       $rgb[0]=$colarr["red"]; 
    6548       $rgb[1]=$colarr["green"]; 
    6549       $rgb[2]=$colarr["blue"]; 
    6550       $rgb = $this->AdjRGBSat($rgb,$sat); 
    6551       imagecolorset ($img, $i, $rgb[0], $rgb[1], $rgb[2]); 
    6552   } 
    6553     } 
    6554    
    6555     function AdjBrightContrast($bright,$contr=0) { 
    6556   if( USE_TRUECOLOR ) 
    6557       return; 
    6558   $this->_AdjBrightContrast($this->img,$bright,$contr); 
    6559     } 
    6560  
    6561     function _AdjBrightContrast($img,$bright,$contr=0) { 
    6562   if( $bright < -1 || $bright > 1 || $contr < -1 || $contr > 1 ) 
    6563       JpGraphError::RaiseL(25099);//(" Parameters for brightness and Contrast out of range [-1,1]");     
    6564   $nbr = imagecolorstotal ($img); 
    6565   for( $i=0; $i<$nbr; ++$i ) { 
    6566       $colarr = imagecolorsforindex ($img,$i); 
    6567       $r = $this->AdjRGBBrightContrast($colarr["red"],$bright,$contr); 
    6568       $g = $this->AdjRGBBrightContrast($colarr["green"],$bright,$contr); 
    6569       $b = $this->AdjRGBBrightContrast($colarr["blue"],$bright,$contr);    
    6570       imagecolorset ($img, $i, $r, $g, $b); 
    6571   } 
    6572     } 
    6573    
    6574     // Private helper function for adj sat 
    6575     // Adjust saturation for RGB array $u. $sat is a value between -1 and 1 
    6576     // Note: Due to GD inability to handle true color the RGB values are only between 
    6577     // 8 bit. This makes saturation quite sensitive for small increases in parameter sat. 
    6578     //  
    6579     // Tip: To get a grayscale picture set sat=-100, values <-100 changes the colors 
    6580     // to it's complement. 
    6581     //  
    6582     // Implementation note: The saturation is implemented directly in the RGB space 
    6583     // by adjusting the perpendicular distance between the RGB point and the "grey" 
    6584     // line (1,1,1). Setting $sat>0 moves the point away from the line along the perp. 
    6585     // distance and a negative value moves the point closer to the line. 
    6586     // The values are truncated when the color point hits the bounding box along the 
    6587     // RGB axis. 
    6588     // DISCLAIMER: I'm not 100% sure this is he correct way to implement a color  
    6589     // saturation function in RGB space. However, it looks ok and has the expected effect. 
    6590     function AdjRGBSat($rgb,$sat) { 
    6591   // TODO: Should be moved to the RGB class 
    6592   // Grey vector 
    6593   $v=array(1,1,1); 
    6594  
    6595   // Dot product 
    6596   $dot = $rgb[0]*$v[0]+$rgb[1]*$v[1]+$rgb[2]*$v[2]; 
    6597  
    6598   // Normalize dot product 
    6599   $normdot = $dot/3;  // dot/|v|^2 
    6600  
    6601   // Direction vector between $u and its projection onto $v 
    6602   for($i=0; $i<3; ++$i) 
    6603       $r[$i] = $rgb[$i] - $normdot*$v[$i]; 
    6604  
    6605   // Adjustment factor so that sat==1 sets the highest RGB value to 255 
    6606   if( $sat > 0 ) { 
    6607       $m=0; 
    6608       for( $i=0; $i<3; ++$i) { 
    6609     if( sign($r[$i]) == 1 && $r[$i]>0) 
    6610         $m=max($m,(255-$rgb[$i])/$r[$i]); 
    6611       } 
    6612       $tadj=$m; 
    6613   } 
    6614   else 
    6615       $tadj=1; 
    6616      
    6617   $tadj = $tadj*$sat;  
    6618   for($i=0; $i<3; ++$i) { 
    6619       $un[$i] = round($rgb[$i] + $tadj*$r[$i]);    
    6620       if( $un[$i]<0 ) $un[$i]=0;    // Truncate color when they reach 0 
    6621       if( $un[$i]>255 ) $un[$i]=255;// Avoid potential rounding error 
    6622   }    
    6623   return $un;  
    6624     }  
    6625  
    6626     // Private helper function for AdjBrightContrast 
    6627     function AdjRGBBrightContrast($rgb,$bright,$contr) { 
    6628   // TODO: Should be moved to the RGB class 
    6629   // First handle contrast, i.e change the dynamic range around grey 
    6630   if( $contr <= 0 ) { 
    6631       // Decrease contrast 
    6632       $adj = abs($rgb-128) * (-$contr); 
    6633       if( $rgb < 128 ) $rgb += $adj; 
    6634       else $rgb -= $adj; 
    6635   } 
    6636   else { // $contr > 0 
    6637       // Increase contrast 
    6638       if( $rgb < 128 ) $rgb = $rgb - ($rgb * $contr); 
    6639       else $rgb = $rgb + ((255-$rgb) * $contr); 
    6640   } 
    6641    
    6642   // Add (or remove) various amount of white 
    6643   $rgb += $bright*255;   
    6644   $rgb=min($rgb,255); 
    6645   $rgb=max($rgb,0); 
    6646   return $rgb;   
    6647     } 
    6648    
    66496346    function SetLineWeight($weight) { 
    66506347  imagesetthickness($this->img,$weight); 
     
    66716368  if( $style=='' )  
    66726369      $style=IMG_ARC_PIE; 
    6673   imagefilledarc($this->img,round($xc),round($yc),round($w),round($h), 
    6674            round($s),round($e),$this->current_color,$style); 
     6370  if( abs($s-$e) > 0.001 ) { 
     6371      imagefilledarc($this->img,round($xc),round($yc),round($w),round($h), 
     6372         round($s),round($e),$this->current_color,$style); 
     6373  } 
    66756374    } 
    66766375 
     
    67356434    // Same as Line but take the line_style into account 
    67366435    function StyleLine($x1,$y1,$x2,$y2) { 
     6436  if( $this->line_weight <= 0 ) 
     6437      return; 
     6438 
    67376439  switch( $this->line_style ) { 
    67386440      case 1:// Solid 
     
    67566458    function DashedLine($x1,$y1,$x2,$y2,$dash_length=1,$dash_space=4) { 
    67576459 
     6460  if( $this->line_weight <= 0 ) 
     6461      return; 
     6462 
    67586463  $x1 = round($x1); 
    67596464  $x2 = round($x2); 
     
    67706475    function Line($x1,$y1,$x2,$y2) { 
    67716476 
     6477  if( $this->line_weight <= 0 ) 
     6478      return; 
     6479 
    67726480  $x1 = round($x1); 
    67736481  $x2 = round($x2); 
     
    67806488 
    67816489    function Polygon($p,$closed=FALSE,$fast=FALSE) { 
    6782   if( $this->line_weight==0 ) return; 
     6490 
     6491  if( $this->line_weight <= 0 )  
     6492      return; 
     6493 
    67836494  $n=count($p); 
    67846495  $oldx = $p[0]; 
     
    70486759      elseif( $supported & IMG_GIF ) 
    70496760    $this->img_format="gif"; 
     6761      elseif( $supported & IMG_WBMP ) 
     6762    $this->img_format="wbmp"; 
     6763      elseif( $supported & IMG_XPM ) 
     6764    $this->img_format="xpm"; 
    70506765      else 
    70516766    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."); 
     
    70606775        $tst=false; 
    70616776    elseif( $aFormat=="gif" && !($supported & IMG_GIF) )   
     6777        $tst=false; 
     6778    elseif( $aFormat=="wbmp" && !($supported & IMG_WBMP) )   
     6779        $tst=false; 
     6780    elseif( $aFormat=="xpm" && !($supported & IMG_XPM) )   
    70626781        $tst=false; 
    70636782    else { 
     
    70846803    private $m=array(); 
    70856804   
    7086     function RotImage($aWidth,$aHeight,$a=0,$aFormat=DEFAULT_GFORMAT) { 
    7087   $this->Image($aWidth,$aHeight,$aFormat); 
     6805    function RotImage($aWidth,$aHeight,$a=0,$aFormat=DEFAULT_GFORMAT,$aSetAutoMargin=true) { 
     6806  $this->Image($aWidth,$aHeight,$aFormat,$aSetAutoMargin); 
    70886807  $this->dx=$this->left_margin+$this->plotwidth/2; 
    70896808  $this->dy=$this->top_margin+$this->plotheight/2; 
     
    72116930   
    72126931    function Polygon($pnts,$closed=FALSE,$fast=FALSE) { 
    7213   //Polygon uses Line() so it will be rotated through that call 
    7214   parent::Polygon($pnts,$closed,$fast); 
     6932  // Polygon uses Line() so it will be rotated through that call unless 
     6933  // fast drawing routines are used in which case a rotate is needed 
     6934  if( $fast ) { 
     6935      parent::Polygon($this->ArrRotate($pnts)); 
     6936  } 
     6937  else 
     6938      parent::Polygon($pnts,$closed,$fast); 
    72156939    } 
    72166940   
     
    75217245    } 
    75227246   
    7523     function Add($aTxt,$aColor,$aPlotmark='',$aLinestyle=0,$csimtarget='',$csimalt='') { 
    7524   $this->txtcol[]=array($aTxt,$aColor,$aPlotmark,$aLinestyle,$csimtarget,$csimalt); 
     7247    function Add($aTxt,$aColor,$aPlotmark='',$aLinestyle=0,$csimtarget='',$csimalt='',$csimwintarget='') { 
     7248  $this->txtcol[]=array($aTxt,$aColor,$aPlotmark,$aLinestyle,$csimtarget,$csimalt,$csimwintarget); 
    75257249    } 
    75267250 
     
    76667390    // (As long as it is not an image mark ) 
    76677391    if( $p[2]->GetType() != MARK_IMG ) { 
     7392