如何使用PHP的GD库动态生成柱状图

添加时间:10-07-05 所属分类:PHP工具与代码
  转载自http://hi.baidu.com/iamljj/blog/item/42dcbf2f878834301e308948.html

PHP在图像操作方面的表现非常出色,我们只需借助可以免费得到的GD库便可以轻松实现图、表勾画。下面将分别介绍笔者实现的饼状图、折线图和柱状图以及他们的使用方法,这几段代码的特点就是不需要再把它们复制到你的代码之中,只需要把计算得到的数据作为参数传入,即可得到相应的图形效果

柱状图
设计思路
还是要首先确定纵轴的刻度值,确定纵轴的刻度最大值
然后根据得到的数据个数确定图像的宽度,这时就可以创建图像了
计算每个色柱的高度,用高度可以计算出色柱的填充范围
用直线画出坐标轴,标注刻度值
用矩形填充色柱,并在色柱上方标注数据值
用Html方式画出需要的横轴坐标名称
实现过程
[code]<?
$kuan=30;//色柱宽
$jiange=20;//色柱间间隔
$zuo=20;//左侧留空
$you=20;//右侧留空
$shang=20;//上留空
$xia=10;//下留空
$zuidashujuzhi=1;//初始化纵轴最大数据值
if ($_GET["a"]=="") die("error id:0");
$shuju=split(",",$_GET["a"]);
//得到最大值
for($i=0;$i<count($shuju);$i++){
  if(!is_numeric($shuju[$i])) die("error id:1");
  if($shuju[$i]>$zuidashujuzhi) $zuidashujuzhi=$shuju[$i];
}
//计算图像宽度
$img_kuan=$zuo+$you+$jiange+count($shuju)*($kuan+$jiange);
//图像高
$img_gao=170;
//存储色柱高度的数组
$zhugaodu = array();
$image = imagecreate($img_kuan,$img_gao);
$white = imagecolorallocate($image, 0xEE, 0xEE, 0xEE);
//色柱颜色
$shuju_yanse =array(
  imagecolorallocate($image, 0x97, 0xbd, 0x00),
  imagecolorallocate($image, 0x00, 0x99, 0x00),
  imagecolorallocate($image, 0xcc, 0x33, 0x00),
  imagecolorallocate($image, 0xff, 0xcc, 0x00),
  imagecolorallocate($image, 0x33, 0x66, 0xcc),
  imagecolorallocate($image, 0x33, 0xcc, 0x33),
  imagecolorallocate($image, 0xff, 0x99, 0x33),
  imagecolorallocate($image, 0xcc, 0xcc, 0x99),
  imagecolorallocate($image, 0x99, 0xcc, 0x66),
  imagecolorallocate($image, 0x66, 0xff, 0x99)
);

//坐标轴颜色
$zuobiao_yanse = imagecolorallocate($image, 0x00, 0x00, 0x00);
//横轴
imageline ( $image, $zuo, $img_gao-$xia, $img_kuan-$you/2, $img_gao-$xia, $zuobiao_yanse);
//纵轴
imageline ( $image, $zuo, $shang/2, $zuo, $img_gao-$xia, $zuobiao_yanse);

//纵轴刻度,纵轴上共标注4个点,所以这里分别计算即可
imageline ( $image, $zuo, $shang, $zuo+6, $shang, $zuobiao_yanse);
imagestring ( $image, 3, $zuo/4, $shang,round($zuidashujuzhi), $zuobiao_yanse);
imageline ( $image, $zuo, $shang+($img_gao-$shang-$xia)*1/4, $zuo+6, round($shang+($img_gao-$shang-$xia)*1/4), $zuobiao_yanse);
imagestring ( $image, 3, $zuo/4, $shang+($img_gao-$shang-$xia)*1/4,round($zuidashujuzhi*3/4), $zuobiao_yanse);
imageline ( $image, $zuo, $shang+($img_gao-$shang-$xia)*2/4, $zuo+6, $shang+($img_gao-$shang-$xia)*2/4, $zuobiao_yanse);
imagestring ( $image, 3, $zuo/4, $shang+($img_gao-$shang-$xia)*2/4,round($zuidashujuzhi*2/4), $zuobiao_yanse);
imageline ( $image, $zuo, $shang+($img_gao-$shang-$xia)*3/4, $zuo+6, $shang+($img_gao-$shang-$xia)*3/4, $zuobiao_yanse);
imagestring ( $image, 3, $zuo/4, $shang+($img_gao-$shang-$xia)*3/4,round($zuidashujuzhi*1/4), $zuobiao_yanse);

//得到每个柱的高度
for($i=0;$i<count($shuju);$i++){
  array_push ($zhugaodu, round(($img_gao-$shang-$xia)*$shuju[$i]/$zuidashujuzhi));
}
//画数据柱
$shuju_yanse_int=0;
for($i=0;$i<count($shuju);$i++){
  imagefilledrectangle( $image,$zuo+$jiange+$i*($kuan+$jiange),$shang+($img_gao-$shang-$xia)-$zhugaodu[$i],$zuo+$jiange+$i*($kuan+$jiange)+$kuan,($img_gao-$xia)-1 ,$shuju_yanse[$shuju_yanse_int]);
//因为只定义了10种颜色,所以这里做一个循环  
  if($shuju_yanse_int==9){
    $shuju_yanse_int=0;
  }else{
    $shuju_yanse_int++;
  }
}
//标注数据柱上方数据值
for($i=0;$i<count($shuju);$i++){
  imagestring ( $image, 1, $zuo+$jiange+$i*($kuan+$jiange)+2,$shang+($img_gao-$shang-$xia)-$zhugaodu[$i]-10,$shuju[$i], $zuobiao_yanse);
}
header('Content-type: image/png');
imagepng($image);
imagedestroy($image);
?>[/code]

使用方法
[code]在需要显示图像的位置插入如下代码
<img src="zhu_img.php?a=5.4,2,30.2,4,0,6,7.7,3.8,2,3,4"/>[/code]
其中a的值由你自己计算得出
a的文本格式是由“,”连接的若干个数据的字符串,get方式传入。

同样使用一个html解决方案,解决横轴刻度名称的问题:
根据数据个数的不同,动态生成一个表格放置横轴坐标刻度名称就行了,像这样

[code]<table width="550" border="0" cellspacing="0" cellpadding="0">
<tr align="center">
<?
for($i=0;$i<12;$i++) {
  echo "<td width=\"50\">".$i."月</td>";
}
?>
</tr>
</table>[/code]
  • 2
  • 3

前篇:PHP实现gb2312、UTF-8等字符和unicode间的编... 后篇:MSN,QQ在线即时交谈网页嵌入代码
发表我的评论


推荐文章   北漂女拳手赚“血汗钱”   岛上小学”唯一老师:坚守28年,每天划...   妈妈爸爸带娃对比照 画面不忍直视   山东人这样过端午,最全的习俗活动和节...   老师为学生补鞋照走红
随机文章   检查目录是否存在,不存在则建立   php过滤替换输出的数字与非数字   PHP使用 $_GET获取传递值为空时的处理代...   编程从业五年的十四条经验   使用JSON实现数据的跨域调用
广告

其他推荐

因为本站所有内容均转载自其它媒体,本意为公众提供免费服务,但并不代表本网赞同其观点,也不能对其真实性验证负责,如稿件版权单位或个人不想在本网发布,请与我联系,本人会立即将其撤除,谢谢.联系方式:atseashawk@163.com QQ:99289555