<?php

/**
  * PLChart - PHP轻量级图表工具 - PHP Light Chart
  *
  * ====================================================================  
  *    Filename :    plchart.php   
  *    Summary:      PLChart图表类文件 - PLChart class file 
  *    Author:       zeroleonhart ( msn:zeroleonhart@hotmail.com )
  *    Version:      0.061026
  *    Copyright (c)2006 zeroleonhart@hotmail.com
  * ====================================================================
  *
  *
  */
  
class plchart
{

    // ============================ 参数定义 - define parameters ============================
	
    // 图表变量 - chart object
    var $chart;
	
    // 图表类型 - chart type
    var $type;
	
    // 3D效果 - 3D effect
    var $d3d;
	
    // 图表宽度 - chart width
    var $width;
	
    // 图表高度 - chart height
    var $height;
	
    // 图表质量 - chart quality
    var $quality; 
    
    // 图表背景色 - array of image backgroundcolors
    var $bgcolor = array();
							
    // 图表参数 - array of data
    var $param = array(); 
		
		public  $param_titulo=array();
	
    // 保存为文件的路径 - saving file directory
    var $savefile;
	
    // 图形参数 - array of graphics references
    var $graphics = array();
	
    // 标题参数 - title references
    var $title = array();
	
    // 注释参数 - description references
    var $desc = array();
	
    // 图表颜色数组 - array of the colors
    var $colors = array();

    // 颜色定义 - define colors
    var $colordefine = array(
                             "lightgray" => array(192, 192, 192),
                             "darkgray" => array(144, 144, 144),
				 
                             "lightred" => array(255, 0, 0),
                             "darkred" => array(128, 0, 0),
				 
                             "lightgreen" => array(0, 255, 0),
                             "darkgreen" => array(0, 80, 0),
				 
                             "lightblue" => array(0, 0, 255),
                             "darkblue" => array(0, 0, 80),
				 
                             "lightyellow" => array(255, 255, 0),
                             "darkyellow" => array(200, 200, 50),
				 
                             "lightcyan" => array(0, 255, 255),
                             "darkcyan" => array(0, 90, 90),
							 
                             "lightbrown" => array(166, 124, 81),
                             "darkbrown" => array(117, 76, 35),
							 
                             "lightmagenta" => array(240, 110, 170),
                             "darkmagenta" => array(158, 0, 93),
							 
                             "lightviolet" => array(96, 92, 168),
                             "darkviolet" => array(26, 19, 100),
							 
                             "lightorange" => array(246, 142, 85),
                             "darkorange" => array(160, 65, 10),
							 
                             "lightygreen" => array(124, 197, 118),
                             "darkygreen" => array(23, 123, 47),
							 
                             "lightgcyan" => array(27, 187, 180),
                             "darkgcyan" => array(0, 115, 106)
                            );

     
	 
    // ============================ 设置函数 - setting functions ============================
	                
    /*
     * @todo  设置图像背景色 - set the backgroundcolor of the chart image
     *
     * @param  int $red     red color of the background     
     * @param  int $green     green color of the background   
     * @param  int $blue     blue color of the background    
     *
     */
    function setbgcolor($red = 0, $green = 0, $blue = 0)
    {
	     
        $this->bgcolor[0] = $red;
        $this->bgcolor[1] = $green;
        $this->bgcolor[2] = $blue;
	
    }
	
    /*
     * @todo  设置图像参数 - set the parameters of the chart image
     *
     * @param  string $type         the type of the chart
     * @param  int $d3d             whether use 3D or not
     * @param  int $width           width of the chart
     * @param  int $height          height of the chart
     * @param  int $quality         display quality of the chart jpg file
     * @param  array $data          source data array to make the chart
     * @param  string $savefile     filename to save
     *
     */
    function setchartdata($type = "pie", $d3d = 1, $width = 400, $height = 400, $quality = 70, $data = array(), $savefile = '')
    {
	     
        $this->type = $type;     // 图表类型 
        $this->d3d = $d3d;     // 3D效果  
        $this->width = $width;     // 图表宽度
        $this->height = $height;     // 图表高度
        $this->quality = $quality;     // 图表显示质量
        $this->param = $data;     // 源数据数组
        $this->savefile = $savefile;     // 保存文件路径
		
    }
	
	
	
    /*
     * @todo  设置图像标题 - set the title of the chart
     *
     * @param  string $tstring       title string    
     * @param  float $tfontsize      fontsize of the title
     * @param  float $tangle         angle of the title fonts
     * @param  int $tposx            lower-left corner of the first character
     * @param  int $tposy            the position of the fonts baseline
     * @param  string $tfontfile     the path to the TrueType font to use
     * @param  int $tfred            red color of the fonts      
     * @param  int $tfgreen          green color of the fonts    
     * @param  int $tfblue           blue color of the fonts     
     *
     */
    function settitle($tstring = '', $tfontsize = 20, $tangle = 0, $tposx = 10, $tposy = 20, $tfontfile = 'fonts/arial.ttf', $tfred = 0, $tfgreen = 0, $tfblue = 0)
    {

        $this->title = array($tfontsize, $tangle, $tposx, $tposy, $tfontfile, $tstring, $tfred, $tfgreen, $tfblue);
	
    }
	
	
	
    /*
     * @todo  设置图像注释 - set the decsription of the chart
     *
     * @param  int $dposx             x position of the upper-left point of the area
     * @param  int $dposy             y position of the upper-left point of the area            
     * @param  int $dwidth            width of the area
     * @param  int $dheight           height of the area
     * @param  int $dmargin           margin of the area
     * @param  int $dsize             fontsize of the description
     * @param  int $dangle            angle of the fonts
     * @param  string $dfontfile      TTF file of the fonts
     * @param  int $dfred             red color of the fonts 
     * @param  int $dfgreen           green color of the fonts  
     * @param  int $dfblue            blue color of the fonts    
     *
     */
  function setdesc($dposx =0, $dposy = 0, $dwidth = 100, $dheight = 300, $dmargin = 10, $dsize = 10, $dangle = 0, $dfontfile = "", $dfred = 0, $dfgreen = 0, $dfblue = 0)     {

        $this->desc = array($dposx, $dposy, $dwidth, $dheight, $dmargin, $dsize, $dangle, $dfontfile, $dfred, $dfgreen, $dfblue);
	
    }
	
	
	
    /*
     * @todo  设置图形 - set the graphics of the chart
     *
     * @param  int $gstartx       x position of the upper-left point of the area
     * @param  int $gstarty       y position of the upper-left point of the area
     * @param  int $gwidth        width of the area
     * @param  int $gheight       height of the area
     * @param  int $gmargin       margin of the area     
     * @param  float $shadow      shadow variable of the image   
     *
     */
    function setgraphics($gstartx = 0, $gstarty = 0, $gwidth = 100, $gheight = 100, $gmargin = 10, $shadow = 0.1)
    {

        $this->graphics = array($gstartx, $gstarty, $gwidth, $gheight, $gmargin, $shadow);
	
    }
	
	
	
    // ============================ 生成函数 - build functions ============================
	
    /*
     * @todo  生成图表实例 - build chart object
     *
     */ 
    function buildchart()
    {
        // 图像头信息 - header of the image file
        header("Content-type: image/jpeg");
	
        // 建立图像 - create image
        $this->chart = imagecreatetruecolor($this->width, $this->height);
		
        // 填充背景色 - set backgroundcolor
        $bgc = imagecolorallocate($this->chart, $this->bgcolor[0], $this->bgcolor[1], $this->bgcolor[2]);
        imagefill($this->chart, 0, 0, $bgc);
		
        // 定义颜色 - allocate colors in the graphics    
				$color = imagecolorallocate($this->chart, 0,0,0);
				array_push($this->colors, $color);
				for ($i=1;$i<255;$i++)
        //foreach($this->colordefine as $key => $value)
        {
              //$$key = imagecolorallocate($this->chart, $value[0], $value[1], $value[2]);
							$color = imagecolorallocate($this->chart, rand(0,255), rand(0,255), rand(0,255));
              array_push($this->colors, $color);    // 颜色变量入栈 - add color variables into array
		
        }
	
    }
	
	
	
    /*
     * @todo  生成图表标题 - build title of the chart
     *
     */ 
    function buildtitle()
    {
         // 设置标题颜色 - set title color
         //$titlecolor = imagecolorallocate($this->chart, $this->title[6], $this->title[7], $this->title[8]);
				 $titlecolor = imagecolorallocate($this->chart, rand(0,255), rand(0,255), rand(0,255));
         
		 // 写标题 - write title
         imagettftext($this->chart, $this->title[0], $this->title[1], $this->title[2], $this->title[3], $titlecolor, $this->title[4], $this->title[5]);
		 
    }
	
	
	
    /*
     * @todo  生成图表说明 - build description of the chart
     *
     */ 
    function builddesc()
    {
         // 注释位置变量 - image position variables
         $dposx = $this->desc[0];
         $dposy = $this->desc[1];     // 注释起始坐标 - the start position of the description
         $w = $this->desc[2];     // 注释部分宽度 - width of all description
         $h = $this->desc[3];     // 注释部分高度 - height of all description
	     $num = count($this->param);     // 注释数量 - number of description lines
         $perh = round($h / $num);      // 每行注释的平均高度 - height of each description line
         $margin = $this->desc[4];     // 注释的间距 - margin between square and font
         $dsize = $this->desc[5];     // 注释的字体大小 - font size of description
         $dangle = $this->desc[6];     // 注释的字体角度 - font display angle of description
         $dfontfile = $this->desc[7];     // 注释的字体文件 - font file of description
         $dfcolor = imagecolorallocate($this->chart, $this->desc[8], $this->desc[9], $this->desc[10]);     // 注释的字体颜色 - font color of description
		 
         // 写注释 - write description
         //$dstring = array_keys($this->param);
				 $dstring=$this->param_titulo;
				 //echo var_dump($dstring);
				 $num=count($dstring);
         for($i = 0; $i < $num; $i++)
         {
              // 矩形色块 - colorful square
               imagefilledrectangle($this->chart, $dposx, $dposy, $dposx + $dsize, $dposy + $dsize, $this->colors[$i * 2]);
							//imagefilledrectangle($this->chart, $dposx, $dposy, $dposx + $dsize, $dposy + $dsize, 0);
			  
              // 写文字 - write string
//              if($this->type == "line" && $this->d3d == 1 || $this->type == "radar" || $this->type == "groupcolumn")
//              {
                    imagettftext($this->chart, $dsize, $dangle, $dposx + $dsize + $margin,
										$dposy + $dsize, $dfcolor, $dfontfile, $dstring[$i]);
//              }
//              else
//              {
//                    imagettftext($this->chart, $dsize, $dangle, $dposx + $dsize + $margin, $dposy + $dsize, $dfcolor, $dfontfile, $dstring[$i] . " - " . $this->param[$dstring[$i]]);
//              }
              // 下移 - move down to write next description
              $dposy += $perh;
		 
         }

    }


    
    /*
     * @todo  生成图形 - build graphics of the chart
     *
     * @param  source $chart
     * @param  int $d3d
     * @param  array $param
     * @param  array $colordefine
     *
     */  
    function buildgraphics()
    {
        // 定义生成图形函数 - define make graphics function 
        // ====================   饼状图 - pie   ====================
		
             // 取得图形位置 - get the positoin of the graphics
             $posx = $this->graphics[0];
             $posy = $this->graphics[1];
			 
             // 取得图形宽度和高度 - get width and height of the graphics
             $w = $this->graphics[2];
             $h = $this->graphics[3];
	  
             // 图形边距 - graphics margin
             $margin = $this->graphics[4];
			 
             // 每个点的直径 - diameter of each point
             $pointsize = $this->graphics[5] * 20;
			 
             // 线条粗细比例 - percent of line thickness
			 $shadow = $this->graphics[5];

             // 图形位置变量 - image position variables
             $startx = round($posx + $margin);
             $starty = round($posy + $h - $margin);     // 图形左下角坐标 - the left-bottom position of the graphics         
 
             // 数据处理 - data process
             if($this->d3d == 0)     // 单线条 - single line
             {
                  $maxvalue = max($this->param);    // 取得最大值 - get max value
                  $minvalue = min($this->param);    // 取得最小值 - get min value
                  $num = count($this->param);     // 取得点个数 - get number of points
                  $fieldnumber = $num;     // 数据区域数量 - number of data fields
                  
             }
             else     // 多线条 - multiple lines
             {
                  $xdesc = array_shift($this->param);
                  foreach($this->param as $value)
                  {
                       $maxvalue = isset($maxvalue) ? ($maxvalue > max($value) ? $maxvalue : max($value)) : max($value);     // 取得最大值 - get max value
                       $minvalue = isset($minvalue) ? ($minvalue < min($value) ? $minvalue : min($value)) : min($value);     // 取得最小值 - get min value
                       $num = count($value);     // 取得点个数 - get number of points
                  }
                  $fieldnumber = count($this->param);     // 数据区域数量 - number of data fields
             }
             $fielddata = $maxvalue - $minvalue;     // 取得数据区间 - get data field
             $unitdata = $fielddata / $fieldnumber;     // 取得单位区间数值 - get unit field data value
             $unitx = ($w - $margin * 2) / ($num - 1);     // 取得x单位长度 - get x unit length
             $unity = ($h - $margin * 2) / $fieldnumber;     // 取得y单位长度 - get y unit length
			 
             // 初始化坐标系 - initialize reference frame
             imageline($this->chart, $startx, $starty, $posx + $w, $starty, $this->colors[1]);     // x
             imageline($this->chart, $startx, $starty, $startx, $posy, $this->colors[1]);     // y
             $paramkeys = array_keys($this->param);     
			 
             // 纵轴标识 - declare y fields
             for($i = 0; $i <= $fieldnumber; $i++)     
             {
                     // 纵轴标识线 - declaring y fields line
                     imageline($this->chart, $startx, $starty - $unity * $i, $posx + $w, $starty - $unity * $i, $this->colors[0]);      
                     
					 // 纵轴区间说明 - y field description
                     imagettftext($this->chart, $this->desc[5], $this->desc[6], $posx, $starty - $unity * $i, $this->colors[0], $this->desc[7], round($minvalue + $unitdata * $i, 1));     
             }
             // 横轴标识 - declare x fields
						 $maximo_ejes=10;
						 $salto=floor($num/$maximo_ejes);
						 
             for($i = 0; $i < $num; $i=$i+$salto)     
             {
                     // 横轴标识线 - declaring x fields line
                     imageline($this->chart, $startx + $unitx * $i, $starty, $startx + $unitx * $i, $posy, $this->colors[0]); 
					 
                     // 横轴区间说明 - x field description
                     if($this->d3d == 0)     // 单线条 - single line
                     {                         
                          imagettftext($this->chart, $this->desc[5], $this->desc[6], $startx + $unitx * $i, $starty + $margin, $this->colors[$i * 2], $this->desc[7], $paramkeys[$i]); 
                     }
                     else     // 多线条 - multi line  (eje ex) ****
                     {
                          imagettftext($this->chart, $this->desc[5], $this->desc[6], $startx + $unitx * $i, $starty + $margin, $this->colors[0], $this->desc[7], $xdesc[$i]);
                     }  
             }
			 
             // 定义线条宽度 - define line thickness
             imagesetthickness($this->chart, round($unity * $shadow));
	 
             // 生成线条 - make line
             $loca = array();     // 保存轨迹的数组 - array to save locas
			 
             // 单线条 - single line
             if($this->d3d == 0)     
             {
                  for($i = 0; $i < $num; $i++)     // 得到轨迹数组 - get loca array
                  {
                        // 点x坐标 - x coordinate of the point
                        $pointx = $startx + $unitx * $i;
                    
					    // 点y坐标 - y coordinate of the point     
                        $pointy = $starty - $unity * $fieldnumber * (($this->param[$paramkeys[$i]] - $minvalue) / $fielddata);
                    
					    // 坐标数据入栈 - push coordinates into array     
                        $loca[$i * 2] = $pointx;
                        $loca[$i * 2 + 1] = $pointy;
                    
					    // 画点 - draw point
                        imagefilledellipse($this->chart, $pointx, $pointy, $pointsize, $pointsize, $this->colors[$i * 2]);
                  }
                  $linecolor = imagecolorallocate($this->chart, $this->title[6], $this->title[7], $this->title[8]);     // 定义线条颜色 - define line color
                  for($i = 0; $i < $num * 2 - 3; )
                  {
                        // 画线条 - draw line
                        imageline($this->chart, $loca[$i], $loca[$i + 1], $loca[$i + 2], $loca[$i + 3], $linecolor);
                        $i += 2;
                  }
             }
             // 多线条 - multiple lines
             else     
             {
                  for($i = 0; $i < $fieldnumber; $i++)     // 得到轨迹数组 - get loca array
                  {
                        for($j = 0; $j < $num; $j++)
                        {
                             // 点x坐标 - x coordinate of the point
                             $pointx = $startx + $unitx * $j;
                    
					         // 点y坐标 - y coordinate of the point     
                             $pointy = $starty - $unity * $fieldnumber * (($this->param[$paramkeys[$i]][$j] - $minvalue) / $fielddata);
                    
					         // 坐标数据入栈 - push coordinates into array     
                             $loca[$i][$j *  2] = $pointx;
                             $loca[$i][$j * 2 + 1] = $pointy;
                    
                        }
                  }
									if ($num<20) {
										$salto=2;
									}
									if ($num>=20 and $num<40) {
										$salto=4;
									}
									if ($num>=40 ) {
										$salto=8;
									}									
									$salto=4;
									$num2=$num*2-($salto+1);
                  for($i = 0; $i < $fieldnumber; $i++)
                  {
											//$maximo_ejes=50;
											
											//$num2=$num*2-3;
											//$salto=floor(($num2)/$maximo_ejes);
											//$salto=2;
											//for($i = 0; $i < $num; $i=$i+$salto)   									
                        for($j = 0; $j < $num2;)
                        {
                             // draw line
                              imageline($this->chart, $loca[$i][$j], $loca[$i][$j + 1], $loca[$i][$j +$salto], $loca[$i][$j + $salto+1], $this->colors[$i * 2]);
														 //imageline($this->chart, $loca[$i][$j], $loca[$i][$j + 1], $loca[$i][$j + $salto], $loca[$i][$j + $salto+1], 0);
                             $j += $salto;
                        }
                  }
 
 		 
             }


    }
	
	
	
    /*
     * @todo  输出图像至浏览器或文件 - output the chart image to browser or file
     */
    function outputchart()
    {
	    
        // 建立图标 - build chart
        $this->buildchart();

        // 写入图形 - build graphics
        $this->buildgraphics();
		
        // 写入注释 - build description
        $this->builddesc();
        
        // 写入标题 - build title
        $this->buildtitle();	
		
        // 输出图像 - flush image
        imagejpeg($this->chart, $this->savefile, $this->quality);
        imagedestroy($this->chart);
		
    }


}


?>
