PHP實現動態生成餅狀圖、柱狀圖和折線圖(轉載)

PHP在圖像操做方面的表現很是出色,咱們只需藉助能夠免費獲得的GD庫即可以輕鬆實現圖、表勾畫。下面將分別介紹PHP實現的餅狀圖、折線圖和柱狀圖以 及他們的使用方法,這幾段代碼的特色就是不須要再把它們複製到你的代碼之中,只須要把計算獲得的數據做爲參數傳入,便可獲得相應的圖形效果
代碼中全部使用的函數的說明,請參見php開發文檔

餅狀圖
設計思路
餅狀圖表對於查看一個值佔總值的百分比是一個好的方法。咱們就用PHP來實現一個餅形圖表。
它的設計思想是:
1 接受參數,獲得全部數值的和,獲得每個值佔數值總和的比例。
2 根據比例計算每個色塊在圖中的圓周角度
3 要產生立體效果,只須要用深顏色畫出陰影就能夠了

實現過程 php

Php代碼   收藏代碼
    <?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 在每一個點的右上方標註每一個點的數據值

實現過程 html

Php代碼   收藏代碼
    <?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解決方案,實用也很靈活:
你們只須要根據數據個數的不一樣,動態生成一個表格放置橫軸座標刻度名稱就好了,像這樣 數組

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方式畫出須要的橫軸座標名稱

實現過程 ide

Php代碼   收藏代碼
    <?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解決方案,解決橫軸刻度名稱的問題:
根據數據個數的不一樣,動態生成一個表格放置橫軸座標刻度名稱就好了,像這樣 函數

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>  
沒有平白無故的榮耀 
相關文章
相關標籤/搜索