PHP实现动态生成饼状图、柱状图和折线图(转载)
PHP在图像操作方面的表现非常出色,我们只需借助可以免费得到的GD库便可以轻松实现图、表勾画。下面将分别介绍PHP实现的饼状图、折线图和柱状图以 及他们的使用方法,这几段代码的特点就是不需要再把它们复制到你的代码之中,只需要把计算得到的数据作为参数传入,即可得到相应的图形效果
代码中所有使用的函数的说明,请参见php开发文档
饼状图
设计思路
饼状图表对于查看一个值占总值的百分比是一个好的方法。我们就用PHP来实现一个饼形图表。
它的设计思想是:
1 接受参数,得到所有数值的和,得到每一个值占数值总和的比例。
2 根据比例计算每一个色块在图中的圆周角度
3 要产生立体效果,只需要用深颜色画出阴影就可以了
实现过程
<?php
//参数以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 在每个点的右上方标注每个点的数据值
实现过程
<?php
$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解决方案,实用也很灵活:
大家只需要根据数据个数的不同,动态生成一个表格放置横轴坐标刻度名称就行了,像这样
<tr align="center">
<?php
for($i=0;$i<12;$i++) {
echo "<td width=\"30\">".$i."月</td>";
}
?>
<table width="550" border="0" cellspacing="0" cellpadding="0">
</tr>
</table>
柱状图
设计思路
还是要首先确定纵轴的刻度值,确定纵轴的刻度最大值
然后根据得到的数据个数确定图像的宽度,这时就可以创建图像了
计算每个色柱的高度,用高度可以计算出色柱的填充范围
用直线画出坐标轴,标注刻度值
用矩形填充色柱,并在色柱上方标注数据值
用Html方式画出需要的横轴坐标名称
实现过程
<?php
$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">
<?php
for($i=0;$i<12;$i++) {
echo "<td width=\"50\">".$i."月</td>";
}
?>
</tr>
</table>
PHP实现动态生成饼状图、柱状图和折线图(转载)的更多相关文章
- JFreeChart 图表生成实例(饼图、柱状图、折线图、时序图)
import java.awt.BasicStroke; import java.awt.Color; import java.io.FileOutputStream; import java.io. ...
- echar图柱状图和折线图混合加双侧y轴坐
代码如下: floorSalesBar(){//方法名====这个方法应该放在methods中并在mounted中调用哦 methods let _this = this; let myChart = ...
- PHP实现动态生成饼状图 (转载)
<?php //变量定义,画椭圆弧时的角度大小 define("ANGLELENGTH", 10); /** * 绘制图片 * @param $title 3D图的标题 * ...
- 使用jfreechart生成柱状图、折线图、和饼状图
JFreeChart是JAVA平台上的一个开放的图表绘制类库.它完全使用JAVA语言编写,是为applications, applets, servlets 以及JSP等使用所设计.下面我就详细介绍如 ...
- JFreeChart框架中生成饼状图上怎样显示数据 [问题点数:40分,结帖人GreenLawn]
我用JFreeChart框架生成饼状图,但想把数据信息在饼图上显示,是在饼图内部(即圆内)显示!怎样实现啊?? 去掉lablepieplot.setLabelGenerator(null);去掉线p ...
- FusionCharts数据展示成饼状图、柱状图和折线图
FusionCharts数据展示成饼状图.柱状图和折线图 本文以展示柱状图为例进行介绍,当然这仅仅是一种方法而已:还有很多方法可以用于展示图表,例如echarts,自定义图表标签.使用jfreecha ...
- php 生成饼状图,折线图,条形图 通用类 2
生成饼状图,折线图,条形图通用的php类,这里使用的是国外的 HighCharts,前台页面别忘了调用HighCahrt js HighCharts中文网站 http://www.hcharts. ...
- php 生成饼状图,折线图,条形图 通用类
生成饼状图,折线图,条形图通用的php类,这里使用的是百度 Echart. Echart 官方网站 http://echarts.baidu.com/ <?php class Echarts ...
- 数据可视化(Echart) :柱状图、折线图、饼图等六种基本图表的特点及适用场合
数据可视化(Echart) 柱状图.折线图.饼图等六种基本图表的特点及适用场合 参考网址 效果图 源码 <!DOCTYPE html> <html> <head> ...
随机推荐
- 【动态规划】Vijos P1104 采药(NOIP2005普及组第三题)
题目链接: https://vijos.org/p/1104 题目大意: T时间,n个物品,每个耗时ti,可获得收益ci,求最大收益. 题目思路: [动态规划] 01背包裸题.一维二维都过了,放个一维 ...
- [Audio processing] wav音频文件合并
合并多个文件,需要包含1.文件读取和写入功能,2.数组合并 package com.audioprocessingbox.myfunc; import java.io.File; import jav ...
- FZU 2113 Jason的特殊爱好
题意: 给定区间[a,b],求将区间中所有数写在黑板上,要写的数字‘1’的次数.(1 <= a,b <= 10^8) 解法: 将题转化成f(b+1) - f(a)的形式.普通的数位DP. ...
- java中字节流和字符流的区别
流分类: 1.Java的字节流 InputStream是所有字节输入流的祖先,而OutputStream是所有字节输出流的祖先.2.Java的字符流 Reader是所有读取字符串输入流的祖先,而 ...
- 小胖学PHP总结1-----PHP的数据类型
PHP一共支持8种原始类型.包含4中标量类型,即:boolean(布尔型).integer(整形).float/double(浮点型)和string(字符串型):两种复合类型,即:array(数组)和 ...
- Java基础知识强化18:抽象类、接口的区别 和 选择性实现接口方法
1.抽象类和接口的区别 抽象类里面可以有非抽象的方法(可以没有抽象方法),接口里只能有抽象方法. 抽象类中的抽象方法声明时不能有大括号,而接口中的所有方法都没有大括号. 抽象类(abstract c ...
- 如何解决eclipse上的Android程序“Please ensure that adb is correctly located at 'D:\eclipse\sdk\platform-tools\adb.exe' and can be executed.”小问题?
首先,把运行的Android模拟器和eclipse一块儿关了, 然后win+R,cmd, 下面输入adb kill_server 再输入adb start_server 之后重新运行项目,不出意外的话 ...
- 提升升级 强制更新 Download
Activity和广播 /** 下载APK细节 1.点击升级后对话框不消失,再次点击时不能重复下载 2.下载过程中退出APP,下次进入应用后要重新下载(因为可能不完整) 3.下载过程中退出APP(或下 ...
- 【开源java游戏框架libgdx专题】-14-系统控件-Skin类
Skin类主要用于存储用户界面的资源,该资源主要用于窗口部件.这些资源也包括纹理图片.位图画笔.颜色等内容.方便创建游戏组件,同时使用Skin也可以批量的粗略处理一些窗口部件. test.json { ...
- javascript中this的解析
在JavaScript中,this 的概念比较复杂.除了在面向对象编程中,this 还是随处可用的.这篇文章介绍了this 的工作原理,它会造成什么样的问题以及this 的相关例子. 要根据this ...