zoukankan      html  css  js  c++  java
  • PHP实现动态生成饼状图、柱状图和折线图(转)

    简介:这是PHP实现动态生成饼状图、柱状图和折线图(转)的详细页面,介绍了和php,php, gd PHP实现动态生成饼状图、柱状图和折线图(转)有关的知识、技巧、经验,和一些php源码等。

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

    饼状图
    设计思路
    饼状图表对于查看一个值占总值的百分比是一个好的方法。我们就用PHP来实现一个饼形图表。
    它的设计思想是:
    1 接受参数,得到所有数值的和,得到每一个值占数值总和的比例。
    2 根据比例计算每一个色块在图中的圆周角度
    3 要产生立体效果,只需要用深颜色画出阴影就可以了

    实现过程
    <?
    //参数以a为参数名传入,a的文本形态应该是用“,”分割的若干数字连接的字符串 
    //这里首先判断a是否存在
    if($_GET["a"]=="") die("0");
    //将得到的数据分解,存入数组$shuju中
    $shuju=split(",",$_GET["a"]);
    //再次判断数据的合法性,返回错误代码
    if(count($shuju)==0) die("2");
    //定义整个图形的宽度和高度 
    //读者可以根据需要修改这两个变量的值
    $tukuan=300;
    $tugao=150;
    
    //定义一个数组,用来存放每一个色块的角度范围
    $jiaodu = array();
    //定义存贮数据和的变量
    $total=0;
    //遍历数组求和
    for ($i = 0; $i < count($shuju); $i++) {
    if(!is_numeric($shuju[$i])) die("1");
    $total+=$shuju[$i];
    }
    //再次遍历,计算色块角度并存入数组
    for ($i = 0; $i < count($shuju); $i++) {
    array_push ($jiaodu, round(360*$shuju[$i]/$total));
    }
    
    //创建图像
    $image = imagecreate($tukuan, $tugao);
    //定义一个灰色背景色,这个颜色其实就是大家很熟悉的页面色系16进制数字表示的#EEEEEE
    $white = imagecolorallocate($image, 0xEE, 0xEE, 0xEE);
    
    //再定义10对深浅对应的彩色,存入二维数组
    $yanse = array(
    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)
    ),
    array(
    imagecolorallocate($image, 0x4f, 0x66, 0x00),
    imagecolorallocate($image, 0x00, 0x33, 0x00),
    imagecolorallocate($image, 0x48, 0x10, 0x00),
    imagecolorallocate($image, 0x7d, 0x64, 0x00),
    imagecolorallocate($image, 0x17, 0x30, 0x64),
    imagecolorallocate($image, 0x1a, 0x6a, 0x1a),
    imagecolorallocate($image, 0x97, 0x4b, 0x00),
    imagecolorallocate($image, 0x78, 0x79, 0x3c),
    imagecolorallocate($image, 0x55, 0x7e, 0x27),
    imagecolorallocate($image, 0x00, 0x93, 0x37)
    )
    );
    
    //由下至上画10个像素高的深色饼图,作为阴影
    $yuanxin_x=$tukuan/2;
    for ($h = $tugao/2+5; $h > $tugao/2-5; $h--) {
    $kaishi=0;
    $jieshu=0;
    for ($i = 0; $i < count($shuju); $i++) {
    $kaishi=$kaishi+0;
    $jieshu=$kaishi+$jiaodu[$i];
    $yanse_i=fmod($i,10);
    imagefilledarc($image,$yuanxin_x,$h,$tukuan,$tugao-20,$kaishi,$jieshu,$yanse[1][$yanse_i],IMG_ARC_PIE);
    $kaishi+=$jiaodu[$i];
    $jieshu+=$jiaodu[$i];
    }
    }
    
    //在最高处(也就是$h最小时)画一个浅色饼图,这个浅色图跟先画上的深色饼图就能产生立体效果了
    for ($i = 0; $i < count($shuju); $i++) {
    $kaishi=$kaishi+0;
    $jieshu=$kaishi+$jiaodu[$i];
    $yanse_i=fmod($i,10);
    imagefilledarc($image, $yuanxin_x, $h, $tukuan, $tugao-20, $kaishi, $jieshu, $yanse[0][$yanse_i], IMG_ARC_PIE);
    $kaishi+=$jiaodu[$i];
    $jieshu+=$jiaodu[$i];
    }
    //设定文件头 
    header('Content-type: image/png');
    //输出图像
    imagepng($image);
    //释放资源 
    imagedestroy($image);
    ?>
    


    使用方法

    在需要显示图像的位置插入如下代码
    <img src="bing_img.php?a=3,2,3,4"/>
    a的文本格式是由“,”连接的若干个数据的字符串,get方式传入。

    折线图

    设计思路

    用折线图表查看某一数据在单位时段内的变化趋势是一个好的选择。我们就用PHP来实现一个动态折线图表。
    它的设计思想是:
    1 接受参数,得到所有数值的和,得到数据的最大值以确定纵轴的最大刻度值
    2 根据数据个数确定图像的宽度,并画出横轴和纵轴坐标及刻度
    3 画直线连接各点,为每个点填充一个2*2的矩形,突出点的位置
    4 在每个点的右上方标注每个点的数据值

    实现过程
    <?
    $img_gao=170;
    $img_kuan=0;
    $jiange=30;//横坐标点与点之间的间隔,生成的图片宽度会根据传入数据的多少而自动变化
    $zuo=20;//左侧留空
    $you=20;//右侧留空
    $shang=20;//上留空
    $xia=20;//下留空
    $zuidashujuzhi=1;
    $p_x = array();//点横坐标
    $p_y = array();//点纵坐标
    $y_name=split(",",$_GET["x_name"]);
    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+count($shuju)*$jiange;
    //然后创建图像资源 
    $image = imagecreate($img_kuan,$img_gao);
    //灰色背景
    $white = imagecolorallocate($image, 0xEE, 0xEE, 0xEE);
    //坐标轴用黑色显示
    $zuobiao_yanse = imagecolorallocate($image, 0x00, 0x00, 0x00);
    //折线用蓝色显示
    $xian_yanse = imagecolorallocate($image, 0x00, 0x00, 0xFF);
    //画坐标
    //横轴
    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);
    
    //得到每个点的坐标
    for($i=0;$i<count($shuju);$i++){
    array_push ($p_x, $zuo+$i*$jiange);
    array_push ($p_y, $shang+round(($img_gao-$shang-$xia)*(1-$shuju[$i]/$zuidashujuzhi)));
    }
    
    //纵轴刻度
    imageline ( $image, $zuo, $shang, $zuo+6, $shang, $zuobiao_yanse);
    imagestring ( $image, 1, $zuo/4, $shang,$zuidashujuzhi, $zuobiao_yanse);
    imageline ( $image, $zuo, $shang+($img_gao-$shang-$xia)*1/4, $zuo+6, $shang+($img_gao-$shang-$xia)*1/4, $zuobiao_yanse);
    imagestring ( $image, 1, $zuo/4, $shang+($img_gao-$shang-$xia)*1/4,$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, 1, $zuo/4, $shang+($img_gao-$shang-$xia)*2/4,$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, 1, $zuo/4, $shang+($img_gao-$shang-$xia)*3/4,$zuidashujuzhi*1/4, $zuobiao_yanse);
    
    //横轴刻度
    for($i=0;$i<count($shuju);$i++){
    imageline ( $image, $zuo+$i*$jiange, $img_gao-$xia, $zuo+$i*$jiange, $img_gao-$xia-6, $zuobiao_yanse);
    imagestring ( $image, 1, $zuo+$i*$jiange-$jiange/4, $shang+($img_gao-$shang-$xia)+2,$y_name[$i], $zuobiao_yanse);
    }
    
    
    //折线
    $shuju_yanse_int=0;
    for($i=0;$i<count($shuju);$i++){
    if($i+1<>count($shuju)){
    imageline ( $image, $p_x[$i], $p_y[$i], $p_x[$i+1], $p_y[$i+1], $xian_yanse);
    imagefilledrectangle($image, $p_x[$i]-1, $p_y[$i]-1, $p_x[$i]+1, $p_y[$i]+1, $xian_yanse);
    }
    }
    //上一个循环没有画出最后一个点效果,这里还要追加
    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);
    
    //标注数据值
    for($i=0;$i<count($shuju);$i++){
    imagestring ( $image, 3, $p_x[$i]+4, $p_y[$i]-12,$shuju[$i], $zuobiao_yanse);
    }
    //设定文件头 
    header('Content-type: image/png');
    //输出图像
    imagepng($image);
    //释放资源 
    imagedestroy($image);
    ?>
    


    使用方法

    在需要显示图像的位置插入如下代码
    <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解决方案,实用也很灵活:
    大家只需要根据数据个数的不同,动态生成一个表格放置横轴坐标刻度名称就行了,像这样
    <table width="550" border="0" cellspacing="0" cellpadding="0">
    <tr align="center"> 
    <?
    for($i=0;$i<12;$i++) {
    echo "<td width=\"30\">".$i."月</td>";
    }
    ?>
    </tr>
    </table> 
    


    柱状图

    设计思路

    还是要首先确定纵轴的刻度值,确定纵轴的刻度最大值
    然后根据得到的数据个数确定图像的宽度,这时就可以创建图像了
    计算每个色柱的高度,用高度可以计算出色柱的填充范围
    用直线画出坐标轴,标注刻度值
    用矩形填充色柱,并在色柱上方标注数据值
    用Html方式画出需要的横轴坐标名称

    实现过程
    <?
    $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);
    ?>
    


    使用方法

    在需要显示图像的位置插入如下代码
    <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解决方案,解决横轴刻度名称的问题:
    根据数据个数的不同,动态生成一个表格放置横轴坐标刻度名称就行了,像这样
    <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>
    

    爱J2EE关注Java迈克尔杰克逊视频站JSON在线工具

    http://biancheng.dnbcw.info/php/347699.html pageNo:3
  • 相关阅读:
    Java日期时间API系列16-----Jdk8中java.time包中的新的日期时间API类,java日期计算3,日期中年月日时分秒的属性值修改等
    Java日期时间API系列15-----Jdk8中java.time包中的新的日期时间API类,java日期计算2,年月日时分秒的加减等
    Java日期时间API系列14-----Jdk8中java.time包中的新的日期时间API类,java日期计算1,获取年月日时分秒等
    Java日期时间API系列12-----Jdk8中java.time包中的新的日期时间API类,日期格式化,常用日期格式大全
    Java日期时间API系列11-----Jdk8中java.time包中的新的日期时间API类,使用java8日期时间API重写农历LunarDate
    Java日期时间API系列10-----Jdk8中java.time包中的新的日期时间API类的DateTimeFormatter
    Java日期时间API系列9-----Jdk8中java.time包中的新的日期时间API类的Period和Duration的区别
    Java日期时间API系列8-----Jdk8中java.time包中的新的日期时间API类的LocalDate源码分析
    Java日期时间API系列7-----Jdk8中java.time包中的新的日期时间API类的优点
    MySql 小表驱动大表
  • 原文地址:https://www.cnblogs.com/ooooo/p/2238763.html
Copyright © 2011-2022 走看看