首页 > 开发 > PHP > 正文

PHP中使用GD库绘制折线图 折线统计图的绘制方法

2024-05-04 22:34:08
字体:
来源:转载
供稿:网友

在PHP中,有一些简单的图像函数是可以直接使用的,但大多数要处理的图像,都需要在编译PHP时加上GD库。除了安装GD库之外,在PHP中还可能需要其他的库,这可以根据需要支持哪些图像格式而定。GD库可以在http://www.boutell.com/gd/免费下载,不同的GD版本支持的图像格式不完全一样,最新的GD库版本支持GIF、JPEG、PNG、WBMP、XBM等格式的图像文件,此外还支持一些如FreeType、Type 1等字体库。通过GD库中的函数可以完成各种点、线、几何图形、文本及颜色的操作和处理,也可以创建或读取多种格式的图像文件。

在PHP中,通过GD库处理图像的操作,都是先在内存中处理,操作完成以后再以文件流的方式,输出到浏览器或保存在服务器的磁盘中。创建一个图像应该完成如下所示的4个基本步骤。

(1)创建画布:所有的绘图设计都需要在一个背景图片上完成,而画布实际上就是在内存中开辟的一块临时区域,用于存储图像的信息。以后的图像操作都将基于这个背景画布,该画布的管理就类似于我们在画画时使用的画布。

(2)绘制图像:画布创建完成以后,就可以通过这个画布资源,使用各种画像函数设置图像的颜色、填充画布、画点、线段、各种几何图形,以及向图像中添加文本等。

(3)输出图像:完成整个图像的绘制以后,需要将图像以某种格式保存到服务器指定的文件中,或将图像直接输出到浏览器上显示给用户。但在图像输出之前,一定要使用header()函数发送Content-type通知浏览器,这次发送的是图片不是文本。

(4)释放资源:图像被输出以后,画布中的内容也不再有用。出于节约系统资源的考虑,需要及时清除画布占用的所有内存资源。

php中用GD绘制折线图,代码如下:

Class Chart{  private $image; // 定义图像  private $title; // 定义标题  private $ydata; // 定义Y轴数据  private $xdata; // 定义X轴数据  private $seriesName; // 定义每个系列数据的名称  private $color; // 定义条形图颜色  private $bgcolor; // 定义图片背景颜色  private $width; // 定义图片的宽  private $height; // 定义图片的长  /*  * 构造函数   * String title 图片标题  * Array xdata 索引数组,X轴数据  * Array ydata 索引数组,数字数组,Y轴数据  * Array series_name 索引数组,数据系列名称  */  function __construct($title,$xdata,$ydata,$seriesName) {     $this->title = $title;   $this->xdata = $xdata;   $this->ydata = $ydata;   $this->seriesName = $seriesName;   $this->color = array('#DC', '#B', '#EDB', '#DDDF', '#CBE', '#E', '#FF', '#FFF', '#AFC');  }  /*  * 公有方法,设置条形图的颜色   * Array color 颜色数组,元素取值为'#DC'这种形式  */  function setBarColor($color){   $this->color = $color;  } /*  * 绘制折线图  */  public function paintLineChart() {   $ydataNum = $this->arrayNum($this->ydata); // 取得数据分组的个数   $max = $this->arrayMax($this->ydata); // 取得所有呈现数据的最大值   $max = ($max > )? $max : ;   $multi = $max/; // 如果最大数据是大于的则进行缩小处理     $barHeightMulti = .; // 条形高缩放的比例   $lineWidth = ;   $chartLeft = (+strlen($max))*; // 设置图片左边的margin   $lineY = ; // 初始化条形图的Y的坐标   // 设置图片的宽、高   //$this->width = $lineWidth*count($this->xdata) + $chartLeft - $lineWidth/.;    $margin = ; // 小矩形描述右边margin   $recWidth = ; // 小矩形的宽   $recHeight = ; // 小矩形的高   $space = ; // 小矩形与条形图的间距   $tmpWidth = ;   // 设置图片的宽、高   $lineChartWidth = $lineWidth*count($this->xdata) + $chartLeft - $lineWidth/. ;   // 两个系列数据以上的加上小矩形的宽   if($ydataNum > ) {    $tmpWidth = $this->arrayLengthMax($this->seriesName)**/ + $space + $recWidth + + $margin;   }    $this->width = $lineChartWidth + $tmpWidth;    $this->height = ;    $this->image = imagecreatetruecolor($this->width ,$this->height); // 准备画布   $this->bgcolor = imagecolorallocate($this->image,,,); // 图片的背景颜色   // 设置条形图的颜色   $color = array();   foreach($this->color as $col) {    $col = substr($col,,strlen($col)-);    $red = hexdec(substr($col,,));    $green = hexdec(substr($col,,));    $blue = hexdec(substr($col,,));    $color[] = imagecolorallocate($this->image ,$red, $green, $blue);   }   // 设置线段的颜色、字体的颜色、字体的路径   $lineColor = imagecolorallocate($this->image ,xcc,xcc,xcc);   $fontColor = imagecolorallocate($this->image, x,xf,xf);   $fontPath = 'font/simsun.ttc';   imagefill($this->image,,,$this->bgcolor); // 绘画背景   // 绘画图的分短线与左右边线   for($i = ; $i < ; $i++ ) {    imageline($this->image,$chartLeft-,$lineY-$barHeightMulti*$max//$multi*$i,$lineChartWidth,$lineY-$barHeightMulti*$max//$multi*$i,$lineColor);    imagestring($this->image,,,$lineY-$barHeightMulti*$max//$multi*$i-,floor($max/*$i),$fontColor);   }     imageline($this->image,$chartLeft-,,$chartLeft-,$lineY,$lineColor);   imageline($this->image,$lineChartWidth-,,$lineChartWidth-,$lineY,$lineColor);   $style = array($lineColor,$lineColor,$lineColor,$lineColor,$lineColor,$this->bgcolor,$this->bgcolor,$this->bgcolor,$this->bgcolor,$this->bgcolor);   imagesetstyle($this->image,$style);   // 绘制折线图的分隔线(虚线)   foreach($this->xdata as $key => $val) {     $lineX = $chartLeft + + $lineWidth*$key;     imageline($this->image,$lineX,,$lineX,$lineY,IMG_COLOR_STYLED);   }   // 绘画图的折线   foreach($this->ydata as $key => $val) {    if($ydataNum == ) {     // 一个系列数据时     if($key == count($this->ydata) - ) break;     $lineX = $chartLeft + + $lineWidth*$key;     $lineY = $lineY-$barHeightMulti*($this->ydata[$key+])/$multi;     // 画折线     if($key == count($this->ydata) - ) {      imagefilledellipse($this->image,$lineX+$lineWidth,$lineY,,,$color[]);     }     imageline($this->image,$lineX,$lineY-$barHeightMulti*$val/$multi,$lineX+$lineWidth,$lineY,$color[]);     imagefilledellipse($this->image,$lineX,$lineY-$barHeightMulti*$val/$multi,,,$color[]);    }elseif($ydataNum > ) {     // 多个系列的数据时     foreach($val as $ckey => $cval) {      if($ckey == count($val) - ) break;       $lineX = $chartLeft + + $lineWidth*$ckey;      $lineY = $lineY-$barHeightMulti*($val[$ckey+])/$multi;      // 画折线      if($ckey == count($val) - ) {       imagefilledellipse($this->image,$lineX+$lineWidth,$lineY,,,$color[$key%count($this->color)]);      }      imageline($this->image,$lineX,$lineY-$barHeightMulti*$cval/$multi,$lineX+$lineWidth,$lineY,$color[$key%count($this->color)]);      imagefilledellipse($this->image,$lineX,$lineY-$barHeightMulti*$cval/$multi,,,$color[$key%count($this->color)]);     }    }   }   // 绘画条形图的x坐标的值   foreach($this->xdata as $key => $val) {    $lineX = $chartLeft + $lineWidth*$key + $lineWidth/ - ;    imagettftext($this->image,,-,$lineX,$lineY+,$fontColor,$fontPath,$this->xdata[$key]);   }     // 两个系列数据以上时绘制小矩形及之后文字说明   if($ydataNum > ) {    $x = $lineChartWidth + $space;    $y = ;    foreach($this->seriesName as $key => $val) {     imagefilledrectangle($this->image,$x,$y,$x+$recWidth,$y+$recHeight,$color[$key%count($this->color)]);       imagettftext($this->image,,,$x+$recWidth+,$y+$recHeight-,$fontColor,$fontPath,$this->seriesName[$key]);     $y += $recHeight + ;       }   }   // 绘画标题   $titleStart = ($this->width - .*strlen($this->title))/;   imagettftext($this->image,,,$titleStart,,$fontColor,$fontPath,$this->title);   // 输出图片   header("Content-Type:image/png");   imagepng ( $this->image );  }  /*  * 私有方法,当数组为二元数组时,统计数组的长度   * Array arr 要做统计的数组  */  private function arrayNum($arr) {   $num = ;   if(is_array($arr)) {    $num++;    for($i = ; $i < count($arr); $i++){     if(is_array($arr[$i])) {      $num = count($arr);      break;     }    }   }   return $num;  }  /*  * 私有方法,计算数组的深度   * Array arr 数组  */  private function arrayDepth($arr) {   $num = ;   if(is_array($arr)) {    $num++;    for($i = ; $i < count($arr); $i++){     if(is_array($arr[$i])) {      $num += $this->arrayDepth($arr[$i]);      break;     }    }   }   return $num;  }  /*  * 私有方法,找到一组中的最大值   * Array arr 数字数组  */  private function arrayMax($arr) {   $depth = $this->arrayDepth($arr);   $max = ;   if($depth == ) {    rsort($arr);    $max = $arr[];     }elseif($depth > ) {    foreach($arr as $val) {     if(is_array($val)) {      if($this->arrayMax($val) > $max) {       $max = $this->arrayMax($val);      }     }else{           if($val > $max){       $max = $val;      }     }     }      }   return $max;  }  /*  * 私有方法,求数组的平均值   * Array arr 数字数组  */  function arrayAver($arr) {   $aver = array();   foreach($arr as $val) {    if(is_array($val)) {     $aver = array_merge($aver,$val);    }else{     $aver[] = $val;    }   }   return array_sum($aver)/count($aver);  }  /*  * 私有方法,求数组中元素长度最大的值   * Array arr 字符串数组,必须是汉字  */  private function arrayLengthMax($arr) {   $length = ;   foreach($arr as $val) {    $length = strlen($val) > $length ? strlen($val) : $length;   }   return $length/;  }   // 析构函数  function __destruct(){   imagedestroy($this->image);  } }            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表