利用php绘制饼状图的实现代码


Posted in PHP onJune 07, 2013

drawPieImg()函数包含8个参数,$title为饼状图的标题;$dataArr为需要显示的数据数组;$labelArr为对应数据的标签分类数组;$colorArr为对应数据的绘图颜色数组,这4个参数是必须的,对于不同的系统应用传递相应的参数即可。接下来的4个参数,负责设置要生成的饼状图的大小,如果不设置则使用系统默认值。程序按照床底数组数据的大小,从0度开始绘制,方向按照顺时针方向依次绘制对应数据占据的扇面大小。

<?php
 //变量定义,画椭圆弧时的角度大小
 define("ANGLELENGTH",3);
 /**
  * 绘制图片
  * @param $title 3D图的标题
  * @param $dataArr 显示的数据数组
  * @param $labelArr 对应数据的标签分类数组
  * @param $colorArr 对应绘图颜色的数组
  * @param $a  画布的基准宽度
  * @param $b  画布的基准高度
  * @param $v  3D柱的高度
  * @param $font 字体大小
  * @return   绘制成功的图片访问路径
  */
 function drawPieImg($title, $dataArr, $labelArr, $colorArr, $a=250, $b=120, $v=20, $font=10){
  $ox = 5+$a;
  $oy = 5+$b;
  $fw = imagefontwidth($font);
  $fh = imagefontheight($font);
  $n = count($dataArr);//计算数组长度
  $w = 10+$a*2;
  $h = 10+$b*2+$v+($fh+2)*$n;
  //创建画板
  $img = imagecreate($w, $h);
  //转RGB为索引色
  for($i=0; $i<$n; $i++)
   $colorArr[$i] = drawIndexColor($img,$colorArr[$i]);//为图像$img分配颜色
  $clrbk = imagecolorallocate($img, 0xff, 0xff, 0xff);
  $clrt = imagecolorallocate($img, 0x00, 0x00, 0x00);
  //填充背景色
  imagefill($img, 0, 0, $clrbk);
  //求和
  $tot = 0;
  for($i=0; $i<$n; $i++)
   $tot += $dataArr[$i];
  //每个分类的起始角度大小
  $sd = 0;
  //每个分类所占据的角度大小
  $ed = 0;
  $ly = 10+$b*2+$v;
  for($i=0; $i<$n; $i++){
   $sd = $ed;
   $ed += $dataArr[$i]/$tot*360;
   //画3d扇面
   draw3DSector($img, $ox, $oy+20, $a, $b, $v, $sd, $ed, $colorArr[$i]);
   //画标签
   imagefilledrectangle($img, 5, $ly, 5+$fw, $ly+$fh, $colorArr[$i]);
   imagerectangle($img, 5, $ly, 5+$fw, $ly+$fh, $clrt);
   //中文转码
   $str = iconv("GB2312", "UTF-8", $labelArr[$i]);
   imagettftext($img, $font, 0, 5+2*$fw, $ly+13, $clrt, "D:/wamp/www/source/font/simhei.ttf", $str.":".$dataArr[$i]."(".(round(10000*($dataArr[$i]/$tot))/100)."%)");
   $ly += $fh+2;
  }
  //绘制图片标题
  imagettftext($img, 15, 0, 5, 15, $clrt, "D:/wamp/www/source/font/simhei.ttf", iconv("GB2312", "UTF-8",$title));
  //输出图形
  header("Content-type: image/png");
  //输出生成的图片
  $imgFileName = "./".time().".png";
  imagepng($img,$imgFileName);
  return $imgFileName;
 }
 /**
  * 绘制3d扇面
  */
 function draw3DSector($img, $ox, $oy, $a, $b, $v, $sd, $ed, $clr) {
  drawSector($img, $ox, $oy, $a, $b, $sd, $ed, $clr);
  if($sd<180){
   list($red, $green, $blue) = drawDarkColor($img, $clr);
   //为图像分配颜色
   $clr=imagecolorallocate($img, $red, $green, $blue);
   if($ed>180)
    $ed = 180;
   list($sx, $sy) = getExy($a,$b,$sd);
   $sx += $ox;
   $sy += $oy;
   list($ex, $ey) = getExy($a, $b, $ed);
   $ex += $ox;
   $ey += $oy;
   imageline($img, $sx, $sy, $sx, $sy+$v, $clr);
   imageline($img, $ex, $ey, $ex, $ey+$v, $clr);
   drawArc($img, $ox, $oy+$v, $a, $b, $sd, $ed, $clr);
   list($sx, $sy) = getExy($a, $b, ($sd+$ed)/2);
   $sy += $oy+$v/2;
   $sx += $ox;
   imagefill($img, $sx, $sy, $clr);
  }
 }
 /**
  * 绘制椭圆弧
  */
 function drawArc($img,$ox,$oy,$a,$b,$sd,$ed,$clr){
  $n = ANGLELENGTH >0 ? ceil(($ed-$sd)/ANGLELENGTH) : -1;
  $d = $sd;
  list($x0,$y0) = getExy($a,$b,$d);
  for($i=0; $i<$n; $i++){
   $d = ($d+ANGLELENGTH)>$ed?$ed:($d+ANGLELENGTH);
   list($x, $y) = getExy($a, $b, $d);
   imageline($img, $x0+$ox, $y0+$oy, $x+$ox, $y+$oy, $clr);
   $x0 = $x;
   $y0 = $y;
  }
 }
 /**
  * 绘制扇面
  */
 function drawSector($img, $ox, $oy, $a, $b, $sd, $ed, $clr) {
  $n = ANGLELENGTH > 0 ? ceil(($ed-$sd)/ANGLELENGTH) : -1;
  $d = $sd;
  list($x0,$y0) = getExy($a, $b, $d);
  imageline($img, $x0+$ox, $y0+$oy, $ox, $oy, $clr);
  for($i=0; $i<$n; $i++) {
   $d = ($d+ANGLELENGTH)>$ed?$ed:($d+ANGLELENGTH);
   list($x, $y) = getExy($a, $b, $d);
   imageline($img, $x0+$ox, $y0+$oy, $x+$ox, $y+$oy, $clr);
   $x0 = $x;
   $y0 = $y;
  }
  imageline($img, $x0+$ox, $y0+$oy, $ox, $oy, $clr);
  list($x, $y) = getExy($a/2, $b/2, ($d+$sd)/2);
  imagefill($img, $x+$ox, $y+$oy, $clr);
 }
 /**
  * 根据$clr颜色获取对应的柱的阴影色
  * @param $img  图像
  * @param $clr  颜色
  * @return rgb颜色数组
  */
 function drawDarkColor($img,$clr){
  $rgb = imagecolorsforindex($img,$clr);
  return array($rgb["red"]/2,$rgb["green"]/2,$rgb["blue"]/2);
 }
 /**
  * 求角度$d对应的椭圆上的点坐标
  *
  * @param $a 横坐标
  * @param $b 纵坐标
  * @param $d 角度
  * @return 对应椭圆点坐标
  */
 function getExy($a, $b, $d){
  $d = deg2rad($d);
  return array(round($a*cos($d)), round($b*sin($d)));
 }
 /**
  * 为图像分配RGB索引色
  */
 function drawIndexColor($img, $clr){
  $red = ($clr>>16) & 0xff;
  $green = ($clr>>8)& 0xff;
  $blue = ($clr) & 0xff;
  return imagecolorallocate($img, $red, $green, $blue);
 }
//测试示例
$title = "动物园动物种类分布情况";
$dataArr = array(20, 10, 20, 20, 10, 20, 30, 10); //测试数据数组
$labelArr = array("大象", "长颈鹿", "鳄鱼", "鸵鸟", "老虎", "狮子", "猴子", "斑马");//标签
$colorArr = array(0x99ff00, 0xff6666, 0x0099ff, 0xff99ff, 0xffff99, 0x99ffff, 0xff3333, 0x009999); //对应颜色数组
$result = drawPieImg($title, $dataArr,$labelArr,$colorArr);
echo "<img src=".$result." mce_src=".$result.">";
?>

PHP 相关文章推荐
使用adodb lite解决问题
Dec 31 PHP
php中json_decode()和json_encode()的使用方法
Jun 04 PHP
一个显示效果非常不错的PHP错误、异常处理类
Mar 21 PHP
PHP中exec函数和shell_exec函数的区别
Aug 20 PHP
微信公众平台开发之天气预报功能
Aug 31 PHP
php数据访问之查询关键字
May 09 PHP
php实现生成带二维码图片并强制下载功能
Feb 24 PHP
PHP中soap用法示例【SoapServer服务端与SoapClient客户端编写】
Dec 25 PHP
tp5(thinkPHP5)框架数据库Db增删改查常见操作总结
Jan 10 PHP
PHP7 mongoDB扩展使用的方法分享
May 02 PHP
分享8个Laravel模型时间戳使用技巧小结
Feb 12 PHP
关于PHP数组迭代器的使用方法实例
Nov 17 PHP
PHP自定义大小验证码的方法详解
Jun 07 #PHP
如何用php生成扭曲及旋转的验证码图片
Jun 07 #PHP
利用php获取服务器时间的实现代码
Jun 07 #PHP
探讨PHP中OO之静态关键字以及类常量的详解
Jun 07 #PHP
PHP5常用函数列表(分享)
Jun 07 #PHP
深入理解php的MySQL连接类
Jun 07 #PHP
PHP之生成GIF动画的实现方法
Jun 07 #PHP
You might like
php+mysqli预处理技术实现添加、修改及删除多条数据的方法
2015/01/30 PHP
php实现上传图片保存到数据库的方法
2015/02/11 PHP
php curl 上传文件代码实例
2015/04/27 PHP
解决Laravel无法使用COOKIE和SESSION的问题
2019/10/16 PHP
基于jquery的使ListNav兼容中文首字拼音排序的实现代码
2011/07/10 Javascript
JS 对输入框进行限制(常用的都有)
2013/07/30 Javascript
jquery 倒计时效果实现秒杀思路
2013/09/11 Javascript
js使用post 方式打开新窗口
2015/02/26 Javascript
Jquery时间轴特效(三种不同类型)
2015/11/02 Javascript
jQuery中的each()详细介绍(推荐)
2016/05/25 Javascript
node.js cookie-parser之parser.js
2016/06/06 Javascript
Bootstrap中的表单验证插件bootstrapValidator使用方法整理(推荐)
2016/06/21 Javascript
jQuery属性选择器用法示例
2016/09/09 Javascript
js实现点击每个li节点,都弹出其文本值及修改
2016/12/15 Javascript
详解Vue改变数组中对象的属性不重新渲染View的解决方案
2018/09/21 Javascript
js实现json数组分组合并操作示例
2019/02/12 Javascript
[04:29]2014DOTA2国际邀请赛 主赛事第三日TOPPLAY
2014/07/21 DOTA
python通过urllib2获取带有中文参数url内容的方法
2015/03/13 Python
python模块smtplib实现纯文本邮件发送功能
2018/05/22 Python
Django实现跨域的2种方法
2019/07/31 Python
TensorFlow索引与切片的实现方法
2019/11/20 Python
Python注释、分支结构、循环结构、伪“选择结构”用法实例分析
2020/01/09 Python
PyQt5的相对布局管理的实现
2020/08/07 Python
ALLSAINTS英国官网:伦敦新锐潮流品牌
2016/09/19 全球购物
英国美发和美容产品商城:HQhair
2019/02/08 全球购物
计算机专业职业生涯规划范文
2014/01/19 职场文书
培训主管岗位职责
2014/02/01 职场文书
应聘护理专业毕业自荐书范文
2014/02/12 职场文书
材料员岗位职责
2014/03/13 职场文书
廉洁自律承诺书
2014/03/27 职场文书
2014年企业党支部工作总结
2014/12/04 职场文书
承诺书范本大全
2015/05/04 职场文书
企业文化学习心得体会
2016/01/21 职场文书
2016机关干部作风建设心得体会
2016/01/21 职场文书
JavaScript利用html5新方法操作元素类名详解
2021/11/27 Javascript
使用CSS定位HTML元素的实现方法
2022/07/07 HTML / CSS