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

饼状图

设计思路

饼状图表对于查看一个值占总值的百分比是一个好的方法。我们就用PHP来实现一个饼形图表。

它的设计思想是:

1 接受参数,得到所有数值的和,得到每一个值占数值总和的比例。

2 根据比例计算每一个色块在图中的圆周角度

3 要产生立体效果,只需要用深颜色画出阴影就可以了

实现过程

  1. <?php
  2. //参数以a为参数名传入,a的文本形态应该是用“,”分割的若干数字连接的字符串
  3. //这里首先判断a是否存在
  4. if($_GET["a"]=="") die("0");
  5. //将得到的数据分解,存入数组$shuju中
  6. $shuju=split(",",$_GET["a"]);
  7. //再次判断数据的合法性,返回错误代码
  8. if(count($shuju)==0) die("2");
  9. //定义整个图形的宽度和高度
  10. //读者可以根据需要修改这两个变量的值
  11. $tukuan=300;
  12. $tugao=150;
  13.  
  14. //定义一个数组,用来存放每一个色块的角度范围
  15. $jiaodu = array();
  16. //定义存贮数据和的变量
  17. $total=0;
  18. //遍历数组求和
  19. for ($i = 0; $i < count($shuju); $i++) {
  20. if(!is_numeric($shuju[$i])) die("1");
  21. $total+=$shuju[$i];
  22. }
  23. //再次遍历,计算色块角度并存入数组
  24. for ($i = 0; $i < count($shuju); $i++) {
  25. array_push ($jiaodu, round(360*$shuju[$i]/$total));
  26. }
  27.  
  28. //创建图像
  29. $image = imagecreate($tukuan, $tugao);
  30. //定义一个灰色背景色,这个颜色其实就是大家很熟悉的页面色系16进制数字表示的#EEEEEE
  31. $white = imagecolorallocate($image, 0xEE, 0xEE, 0xEE);
  32.  
  33. //再定义10对深浅对应的彩色,存入二维数组
  34. $yanse = array(
  35. array(
  36. imagecolorallocate($image, 0x97, 0xbd, 0x00),
  37. imagecolorallocate($image, 0x00, 0x99, 0x00),
  38. imagecolorallocate($image, 0xcc, 0x33, 0x00),
  39. imagecolorallocate($image, 0xff, 0xcc, 0x00),
  40. imagecolorallocate($image, 0x33, 0x66, 0xcc),
  41. imagecolorallocate($image, 0x33, 0xcc, 0x33),
  42. imagecolorallocate($image, 0xff, 0x99, 0x33),
  43. imagecolorallocate($image, 0xcc, 0xcc, 0x99),
  44. imagecolorallocate($image, 0x99, 0xcc, 0x66),
  45. imagecolorallocate($image, 0x66, 0xff, 0x99)
  46. ),
  47. array(
  48. imagecolorallocate($image, 0x4f, 0x66, 0x00),
  49. imagecolorallocate($image, 0x00, 0x33, 0x00),
  50. imagecolorallocate($image, 0x48, 0x10, 0x00),
  51. imagecolorallocate($image, 0x7d, 0x64, 0x00),
  52. imagecolorallocate($image, 0x17, 0x30, 0x64),
  53. imagecolorallocate($image, 0x1a, 0x6a, 0x1a),
  54. imagecolorallocate($image, 0x97, 0x4b, 0x00),
  55. imagecolorallocate($image, 0x78, 0x79, 0x3c),
  56. imagecolorallocate($image, 0x55, 0x7e, 0x27),
  57. imagecolorallocate($image, 0x00, 0x93, 0x37)
  58. )
  59. );
  60.  
  61. //由下至上画10个像素高的深色饼图,作为阴影
  62. $yuanxin_x=$tukuan/2;
  63. for ($h = $tugao/2+5; $h > $tugao/2-5; $h--) {
  64. $kaishi=0;
  65. $jieshu=0;
  66. for ($i = 0; $i < count($shuju); $i++) {
  67. $kaishi=$kaishi+0;
  68. $jieshu=$kaishi+$jiaodu[$i];
  69. $yanse_i=fmod($i,10);
  70. imagefilledarc($image,$yuanxin_x,$h,$tukuan,$tugao-20,$kaishi,$jieshu,$yanse[1][$yanse_i],IMG_ARC_PIE);
  71. $kaishi+=$jiaodu[$i];
  72. $jieshu+=$jiaodu[$i];
  73. }
  74. }
  75.  
  76. //在最高处(也就是$h最小时)画一个浅色饼图,这个浅色图跟先画上的深色饼图就能产生立体效果了
  77. for ($i = 0; $i < count($shuju); $i++) {
  78. $kaishi=$kaishi+0;
  79. $jieshu=$kaishi+$jiaodu[$i];
  80. $yanse_i=fmod($i,10);
  81. imagefilledarc($image, $yuanxin_x, $h, $tukuan, $tugao-20, $kaishi, $jieshu, $yanse[0][$yanse_i], IMG_ARC_PIE);
  82. $kaishi+=$jiaodu[$i];
  83. $jieshu+=$jiaodu[$i];
  84. }
  85. //设定文件头
  86. header('Content-type: image/png');
  87. //输出图像
  88. imagepng($image);
  89. //释放资源
  90. imagedestroy($image);
  91. ?>

使用方法

在需要显示图像的位置插入如下代码

<img src="bing_img.php?a=3,2,3,4"/>

a的文本格式是由“,”连接的若干个数据的字符串,get方式传入。

折线图

设计思路

用折线图表查看某一数据在单位时段内的变化趋势是一个好的选择。我们就用PHP来实现一个动态折线图表。

它的设计思想是:

1 接受参数,得到所有数值的和,得到数据的最大值以确定纵轴的最大刻度值

2 根据数据个数确定图像的宽度,并画出横轴和纵轴坐标及刻度

3 画直线连接各点,为每个点填充一个2*2的矩形,突出点的位置

4 在每个点的右上方标注每个点的数据值

实现过程

  1. <?php
  2. $img_gao=170;
  3. $img_kuan=0;
  4. $jiange=30;//横坐标点与点之间的间隔,生成的图片宽度会根据传入数据的多少而自动变化
  5. $zuo=20;//左侧留空
  6. $you=20;//右侧留空
  7. $shang=20;//上留空
  8. $xia=20;//下留空
  9. $zuidashujuzhi=1;
  10. $p_x = array();//点横坐标
  11. $p_y = array();//点纵坐标
  12. $y_name=split(",",$_GET["x_name"]);
  13. if ($_GET["a"]=="") die("error id:0");
  14. $shuju=split(",",$_GET["a"]);
  15. //得到纵轴最大值
  16. for($i=0;$i<count($shuju);$i++){
  17. if(!is_numeric($shuju[$i])) die("error id:1");
  18. if($shuju[$i]>$zuidashujuzhi) $zuidashujuzhi=$shuju[$i];
  19. }
  20. //得到图像宽度
  21. $img_kuan=$zuo+$you+count($shuju)*$jiange;
  22. //然后创建图像资源
  23. $image = imagecreate($img_kuan,$img_gao);
  24. //灰色背景
  25. $white = imagecolorallocate($image, 0xEE, 0xEE, 0xEE);
  26. //坐标轴用黑色显示
  27. $zuobiao_yanse = imagecolorallocate($image, 0x00, 0x00, 0x00);
  28. //折线用蓝色显示
  29. $xian_yanse = imagecolorallocate($image, 0x00, 0x00, 0xFF);
  30. //画坐标
  31. //横轴
  32. imageline ( $image, $zuo, $img_gao-$xia, $img_kuan-$you/2, $img_gao-$xia, $zuobiao_yanse);
  33. //纵轴
  34. imageline ( $image, $zuo, $shang/2, $zuo, $img_gao-$xia, $zuobiao_yanse);
  35.  
  36. //得到每个点的坐标
  37. for($i=0;$i<count($shuju);$i++){
  38. array_push ($p_x, $zuo+$i*$jiange);
  39. array_push ($p_y, $shang+round(($img_gao-$shang-$xia)*(1-$shuju[$i]/$zuidashujuzhi)));
  40. }
  41.  
  42. //纵轴刻度
  43. imageline ( $image, $zuo, $shang, $zuo+6, $shang, $zuobiao_yanse);
  44. imagestring ( $image, 1, $zuo/4, $shang,$zuidashujuzhi, $zuobiao_yanse);
  45. imageline ( $image, $zuo, $shang+($img_gao-$shang-$xia)*1/4, $zuo+6, $shang+($img_gao-$shang-$xia)*1/4, $zuobiao_yanse);
  46. imagestring ( $image, 1, $zuo/4, $shang+($img_gao-$shang-$xia)*1/4,$zuidashujuzhi*3/4, $zuobiao_yanse);
  47. imageline ( $image, $zuo, $shang+($img_gao-$shang-$xia)*2/4, $zuo+6, $shang+($img_gao-$shang-$xia)*2/4, $zuobiao_yanse);
  48. imagestring ( $image, 1, $zuo/4, $shang+($img_gao-$shang-$xia)*2/4,$zuidashujuzhi*2/4, $zuobiao_yanse);
  49. imageline ( $image, $zuo, $shang+($img_gao-$shang-$xia)*3/4, $zuo+6, $shang+($img_gao-$shang-$xia)*3/4, $zuobiao_yanse);
  50. imagestring ( $image, 1, $zuo/4, $shang+($img_gao-$shang-$xia)*3/4,$zuidashujuzhi*1/4, $zuobiao_yanse);
  51.  
  52. //横轴刻度
  53. for($i=0;$i<count($shuju);$i++){
  54. imageline ( $image, $zuo+$i*$jiange, $img_gao-$xia, $zuo+$i*$jiange, $img_gao-$xia-6, $zuobiao_yanse);
  55. imagestring ( $image, 1, $zuo+$i*$jiange-$jiange/4, $shang+($img_gao-$shang-$xia)+2,$y_name[$i], $zuobiao_yanse);
  56. }
  57.  
  58. //折线
  59. $shuju_yanse_int=0;
  60. for($i=0;$i<count($shuju);$i++){
  61. if($i+1<>count($shuju)){
  62. imageline ( $image, $p_x[$i], $p_y[$i], $p_x[$i+1], $p_y[$i+1], $xian_yanse);
  63. imagefilledrectangle($image, $p_x[$i]-1, $p_y[$i]-1, $p_x[$i]+1, $p_y[$i]+1, $xian_yanse);
  64. }
  65. }
  66. //上一个循环没有画出最后一个点效果,这里还要追加
  67. imagefilledrectangle($image, $p_x[count($shuju)-1]-1, $p_y[count($shuju)-1]-1, $p_x[count($shuju)-1]+1, $p_y[count($shuju)-1]+1, $xian_yanse);
  68.  
  69. //标注数据值
  70. for($i=0;$i<count($shuju);$i++){
  71. imagestring ( $image, 3, $p_x[$i]+4, $p_y[$i]-12,$shuju[$i], $zuobiao_yanse);
  72. }
  73. //设定文件头
  74. header('Content-type: image/png');
  75. //输出图像
  76. imagepng($image);
  77. //释放资源
  78. imagedestroy($image);
  79. ?>

使用方法

在需要显示图像的位置插入如下代码

<img src="zhexian_img.php?a=5.4,2,30.2,4,0,6,7.7,3.8,2,3,4"/>

其中a的值由你自己计算得出

a的文本格式是由“,”连接的若干个数据的字符串,get方式传入。

由于往图形里写入中文需要更多PHP环境配置,所以这里给出一个html解决方案,实用也很灵活:

大家只需要根据数据个数的不同,动态生成一个表格放置横轴坐标刻度名称就行了,像这样

  1. <tr align="center">
  2. <?php
  3. for($i=0;$i<12;$i++) {
  4. echo "<td width=\"30\">".$i."月</td>";
  5. }
  6. ?>
  7. <table width="550" border="0" cellspacing="0" cellpadding="0">
  8. </tr>
  9. </table>

柱状图

设计思路

还是要首先确定纵轴的刻度值,确定纵轴的刻度最大值

然后根据得到的数据个数确定图像的宽度,这时就可以创建图像了

计算每个色柱的高度,用高度可以计算出色柱的填充范围

用直线画出坐标轴,标注刻度值

用矩形填充色柱,并在色柱上方标注数据值

用Html方式画出需要的横轴坐标名称

实现过程

  1. <?php
  2. $kuan=30;//色柱宽
  3. $jiange=20;//色柱间间隔
  4. $zuo=20;//左侧留空
  5. $you=20;//右侧留空
  6. $shang=20;//上留空
  7. $xia=10;//下留空
  8. $zuidashujuzhi=1;//初始化纵轴最大数据值
  9. if ($_GET["a"]=="") die("error id:0");
  10. $shuju=split(",",$_GET["a"]);
  11. //得到最大值
  12. for($i=0;$i<count($shuju);$i++){
  13. if(!is_numeric($shuju[$i])) die("error id:1");
  14. if($shuju[$i]>$zuidashujuzhi) $zuidashujuzhi=$shuju[$i];
  15. }
  16. //计算图像宽度
  17. $img_kuan=$zuo+$you+$jiange+count($shuju)*($kuan+$jiange);
  18. //图像高
  19. $img_gao=170;
  20. //存储色柱高度的数组
  21. $zhugaodu = array();
  22. $image = imagecreate($img_kuan,$img_gao);
  23. $white = imagecolorallocate($image, 0xEE, 0xEE, 0xEE);
  24. //色柱颜色
  25. $shuju_yanse =array(
  26. imagecolorallocate($image, 0x97, 0xbd, 0x00),
  27. imagecolorallocate($image, 0x00, 0x99, 0x00),
  28. imagecolorallocate($image, 0xcc, 0x33, 0x00),
  29. imagecolorallocate($image, 0xff, 0xcc, 0x00),
  30. imagecolorallocate($image, 0x33, 0x66, 0xcc),
  31. imagecolorallocate($image, 0x33, 0xcc, 0x33),
  32. imagecolorallocate($image, 0xff, 0x99, 0x33),
  33. imagecolorallocate($image, 0xcc, 0xcc, 0x99),
  34. imagecolorallocate($image, 0x99, 0xcc, 0x66),
  35. imagecolorallocate($image, 0x66, 0xff, 0x99)
  36. );
  37.  
  38. //坐标轴颜色
  39. $zuobiao_yanse = imagecolorallocate($image, 0x00, 0x00, 0x00);
  40. //横轴
  41. imageline ( $image, $zuo, $img_gao-$xia, $img_kuan-$you/2, $img_gao-$xia, $zuobiao_yanse);
  42. //纵轴
  43. imageline ( $image, $zuo, $shang/2, $zuo, $img_gao-$xia, $zuobiao_yanse);
  44.  
  45. //纵轴刻度,纵轴上共标注4个点,所以这里分别计算即可
  46. imageline ( $image, $zuo, $shang, $zuo+6, $shang, $zuobiao_yanse);
  47. imagestring ( $image, 3, $zuo/4, $shang,round($zuidashujuzhi), $zuobiao_yanse);
  48. imageline ( $image, $zuo, $shang+($img_gao-$shang-$xia)*1/4, $zuo+6, round($shang+($img_gao-$shang-$xia)*1/4), $zuobiao_yanse);
  49. imagestring ( $image, 3, $zuo/4, $shang+($img_gao-$shang-$xia)*1/4,round($zuidashujuzhi*3/4), $zuobiao_yanse);
  50. imageline ( $image, $zuo, $shang+($img_gao-$shang-$xia)*2/4, $zuo+6, $shang+($img_gao-$shang-$xia)*2/4, $zuobiao_yanse);
  51. imagestring ( $image, 3, $zuo/4, $shang+($img_gao-$shang-$xia)*2/4,round($zuidashujuzhi*2/4), $zuobiao_yanse);
  52. imageline ( $image, $zuo, $shang+($img_gao-$shang-$xia)*3/4, $zuo+6, $shang+($img_gao-$shang-$xia)*3/4, $zuobiao_yanse);
  53. imagestring ( $image, 3, $zuo/4, $shang+($img_gao-$shang-$xia)*3/4,round($zuidashujuzhi*1/4), $zuobiao_yanse);
  54.  
  55. //得到每个柱的高度
  56. for($i=0;$i<count($shuju);$i++){
  57. array_push ($zhugaodu, round(($img_gao-$shang-$xia)*$shuju[$i]/$zuidashujuzhi));
  58. }
  59. //画数据柱
  60. $shuju_yanse_int=0;
  61. for($i=0;$i<count($shuju);$i++){
  62. 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]);
  63. //因为只定义了10种颜色,所以这里做一个循环  
  64. if($shuju_yanse_int==9){
  65. $shuju_yanse_int=0;
  66. }else{
  67. $shuju_yanse_int++;
  68. }
  69. }
  70. //标注数据柱上方数据值
  71. for($i=0;$i<count($shuju);$i++){
  72. imagestring ( $image, 1, $zuo+$jiange+$i*($kuan+$jiange)+2,$shang+($img_gao-$shang-$xia)-$zhugaodu[$i]-10,$shuju[$i], $zuobiao_yanse);
  73. }
  74. header('Content-type: image/png');
  75. imagepng($image);
  76. imagedestroy($image);
  77. ?>

使用方法

在需要显示图像的位置插入如下代码

<img src="zhu_img.php?a=5.4,2,30.2,4,0,6,7.7,3.8,2,3,4"/>

其中a的值由你自己计算得出

a的文本格式是由“,”连接的若干个数据的字符串,get方式传入。

同样使用一个html解决方案,解决横轴刻度名称的问题:

根据数据个数的不同,动态生成一个表格放置横轴坐标刻度名称就行了,像这样

  1. <table width="550" border="0" cellspacing="0" cellpadding="0">
  2. <tr align="center">
  3. <?php
  4. for($i=0;$i<12;$i++) {
  5. echo "<td width=\"50\">".$i."月</td>";
  6. }
  7. ?>
  8. </tr>
  9. </table>

PHP实现动态生成饼状图、柱状图和折线图(转载)的更多相关文章

  1. JFreeChart 图表生成实例(饼图、柱状图、折线图、时序图)

    import java.awt.BasicStroke; import java.awt.Color; import java.io.FileOutputStream; import java.io. ...

  2. echar图柱状图和折线图混合加双侧y轴坐

    代码如下: floorSalesBar(){//方法名====这个方法应该放在methods中并在mounted中调用哦 methods let _this = this; let myChart = ...

  3. PHP实现动态生成饼状图 (转载)

    <?php //变量定义,画椭圆弧时的角度大小 define("ANGLELENGTH", 10); /** * 绘制图片 * @param $title 3D图的标题 * ...

  4. 使用jfreechart生成柱状图、折线图、和饼状图

    JFreeChart是JAVA平台上的一个开放的图表绘制类库.它完全使用JAVA语言编写,是为applications, applets, servlets 以及JSP等使用所设计.下面我就详细介绍如 ...

  5. JFreeChart框架中生成饼状图上怎样显示数据 [问题点数:40分,结帖人GreenLawn]

    我用JFreeChart框架生成饼状图,但想把数据信息在饼图上显示,是在饼图内部(即圆内)显示!怎样实现啊??  去掉lablepieplot.setLabelGenerator(null);去掉线p ...

  6. FusionCharts数据展示成饼状图、柱状图和折线图

    FusionCharts数据展示成饼状图.柱状图和折线图 本文以展示柱状图为例进行介绍,当然这仅仅是一种方法而已:还有很多方法可以用于展示图表,例如echarts,自定义图表标签.使用jfreecha ...

  7. php 生成饼状图,折线图,条形图 通用类 2

    生成饼状图,折线图,条形图通用的php类,这里使用的是国外的 HighCharts,前台页面别忘了调用HighCahrt  js HighCharts中文网站  http://www.hcharts. ...

  8. php 生成饼状图,折线图,条形图 通用类

    生成饼状图,折线图,条形图通用的php类,这里使用的是百度 Echart. Echart 官方网站  http://echarts.baidu.com/ <?php class Echarts ...

  9. 数据可视化(Echart) :柱状图、折线图、饼图等六种基本图表的特点及适用场合

    数据可视化(Echart) 柱状图.折线图.饼图等六种基本图表的特点及适用场合 参考网址 效果图 源码 <!DOCTYPE html> <html> <head> ...

随机推荐

  1. dll文件已经引用,但using找不到命名空间

    一:问题截图 二:解决办法 1.没看到lz的代码中有Vancl.Server的dll. 2.确实有编译不过的问题,是Vancl.WindowsServices这个工程的target framework ...

  2. HDU2059(龟兔赛跑)

    龟兔赛跑 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  3. poj 1556 The door

    题目链接:http://poj.org/problem?id=1556 #include<cstdio> #include<cstring> #include<cmath ...

  4. 函数调用和给对象发消息(Runtime理解)

    在写代码的时候这个差距其实是不打看的出得,很多时候也就无所谓叫什么,很多人为了便于理解,干脆就叫函数调用.这个其实应该是oc的一个特色,消息发送.具体的类typedef struct objc_cla ...

  5. Android中 判断是平板还是手机

    //是平板返回true 不是平板返回false public  boolean isTablet(Context context) { return (context.getResources().g ...

  6. easyUI属性总结

    1.div easyui-window        生成一个window窗口样式.      属性如下:                   1)modal:是否生成模态窗口.true[是] fal ...

  7. Git 中README.md中MarkDown语法示例

    转 http://blog.csdn.net/brokge/article/details/38388757 简介 Markdown的语法简洁明了.学习容易,而且功能比纯文本更强,因此有很多人用它写博 ...

  8. erlang mnesia数据库设置主键自增

    Mnesia是erlang/otp自带的分布式数据库管理系统.mnesia配合erlang的实现近乎理想,但在实际使用当中差强人意,总会有一些不足.mnesia数据表没有主键自增的功能,但在mnesi ...

  9. android scrollview组件禁止滑动的方法

    xml配置:           android:id="@+id/sc_freement"             android:layout_width="fill ...

  10. Android 网络框架--Retrofit

    1.导入Jar包 compile 'com.google.code.gson:gson:2.8.0' compile 'com.squareup.retrofit2:retrofit:2.1.0' c ...