2016/04/16

【教學】使用PHP GD 畫長條圖


在做資料統計的時候很常會遇到要畫長條圖,其方法有很多種,這篇就來紀錄一下怎麼畫長條圖。


我的資料庫為20160416
資料表person
欄位id,nme,bg
目前有五筆資料
Array
(
    [id] => 1
    [nme] => 小火龍
    [bg] => 火
)
Array
(
    [id] => 2
    [nme] => 傑尼龜
    [bg] => 水
)
Array
(
    [id] => 3
    [nme] => 皮卡丘
    [bg] => 電
)
Array
(
    [id] => 4
    [nme] => 皮丘
    [bg] => 電
)
Array
(
    [id] => 5
    [nme] => 火恐龍
    [bg] => 火
)


要嵌入GD圖片使用html的src開啟
<img src="image.php" style="border:1px #000 solid;" />


我用1px的框線,讓我們可以看到目前的範圍,在image.php裡面,我們須重新在連接資料庫一次,故我把連結資料庫的檔名設為conn.php嵌入
<?php
        $db = new PDO("mysql:host=127.0.0.1;dbname=20160416","admin","1234");
        $db -> exec("set names utf8");
        $db -> setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
?>


在image.php裡,先畫出長條圖的縱軸及橫軸
<?php
        include 'conn.php';
        $img=imagecreate(800,500);                      //建構圖片
        $w=imagecolorallocate($img,255,255,255);        //配置白色
        $bl=imagecolorallocate($img,0,0,0);             //配置黑色
        $bw=imagecolorallocate($img,150,150,150);       //配置灰色
        $red=imagecolorallocate($img,255,0,0);          //配置紅色
        
        imagefill($img,0,0,$w);                         //背景填滿白色
        imageline($img,70,20,70,470,$bw);               //畫縱軸
        imageline($img,70,470,700,470,$bw);             //畫橫軸
        
        imagepng($img);                                 //製成png
        imagedestroy($img);                             //銷毀圖片
?>

$img = imagesreate(寬,高) 建構一個圖片,設定寬及高,這裡設定圖片為$img
imagecolorallocate($img,R,G,B) 配置一個顏色給變數
imagefill($img,X,Y,顏色) 對相近色填滿顏色,會從X,Y位置從旁找相近色直接填滿
imageline($img,X1,Y1,X2,Y2,顏色) 從X1,Y1到X2,Y2畫一條給定顏色的直線

以下兩個一定要打在尾部,類似於輸出
imagepng($img) 把圖片製成png
imagedestroy($img) 銷毀圖片


可得到已畫好縱軸及橫軸的圖片


計算三個屬性的個別數量
<?php
        $bg[0]=0;        //火
        $bg[1]=0;        //水
        $bg[2]=0;        //電
        $row= $db -> query("select * from person");
        foreach($row as $ret){
                switch($ret['bg']){
                        case "火":
                                $bg[0]++;
                                break;
                        case "水":
                                $bg[1]++;
                                break;
                        case "電":
                                $bg[2]++;
                                break;
                }
        }
?>


再來找最大值
<?php
        if($bg[0]>=$bg[1] && $bg[0]>=$bg[2]){
                $sp = $bg[0];
        }else if($bg[1]>= $bg[2]){
                $sp = $bg[1];
        }else{
                $sp = $bg[2];
        }
?>


找到最大值後,以10的次方為最高值,畫上縱軸的補助線
<?php
        $allsp = pow(10,strlen($sp));
        $exsp = $allsp / 100;
 
        for($i=0;$i<=10;$i++){
                imageline($img,68,20+45*$i,700,20+45*$i,$bw);
                imagefttext($img,10,0,10,25+45*$i,$bl,'DFTT_NM9.TTC',$allsp/10*(10-$i));
        }
?>

imagefttext($img,大小,角度,X,Y,顏色,字體,文字) 在圖片上加上文字



加上橫軸標籤
<?php
     $nme1 = "屬性";
     imagefttext($img,15,0,720,480,$bl,'DFTT_NM9.TTC',$nme1);
?>



畫上長條圖,並加上橫軸文字
<?php
    for($i = 0; $i <= 2; $i++){
        imageline($img,280+($i*210),468,280+($i*210),472,$bw);
        imagefilledrectangle($img,165+210*$i,470,185+210*$i,470-$bg[$i]/$exsp*4.5,$red);
        imagefttext($img,10,0,165+210*$i,465-$bg[$i]/$exsp*4.5,$bl,'DFTT_NM9.TTC',$bg[$i]);
        switch($i){
            case 0:
                $nme2 = "火";
                break;
            case 1:
                $nme2 = "水";
                break;
            case 2:
                $nme2 = "電";
        }
        imagefttext($img,17,0,165+210*$i,492,$bl,'DFTT_NM9.TTC',$nme2);
    }
?>

imagefilledrectangle($img,X1,Y1,X2,Y2,顏色) 畫一個矩形



圖片總程式碼也沒有很長,只是要計算位置,如果位置錯誤就會畫錯
<?php
        include 'conn.php';
        $img=imagecreate(800,500);                                        //建構圖片
        $w=imagecolorallocate($img,255,255,255);        //配置白色
        $bl=imagecolorallocate($img,0,0,0);                        //配置黑色
        $bw=imagecolorallocate($img,150,150,150);        //配置灰色
        $red=imagecolorallocate($img,255,0,0);                //配置紅色
        
        imagefill($img,0,0,$w);                                                //背景填滿白色
        imageline($img,70,20,70,470,$bw);                        //畫縱軸
        imageline($img,70,470,700,470,$bw);                        //畫橫軸
        
        $bg[0]=0;        //火
        $bg[1]=0;        //水
        $bg[2]=0;        //電
        $row= $db -> query("select * from person");
        foreach($row as $ret){
                switch($ret['bg']){
                        case "火":
                                $bg[0]++;
                                break;
                        case "水":
                                $bg[1]++;
                                break;
                        case "電":
                                $bg[2]++;
                                break;
                }
        }
        if($bg[0]>=$bg[1] && $bg[0]>=$bg[2]){
                $sp = $bg[0];
        }else if($bg[1]>= $bg[2]){
                $sp = $bg[1];
        }else{
                $sp = $bg[2];
        }
        $allsp = pow(10,strlen($sp));
        $exsp = $allsp / 100;
        
        for($i=0;$i<=10;$i++){
                imageline($img,68,20+45*$i,700,20+45*$i,$bw);
                imagefttext($img,10,0,10,25+45*$i,$bl,'DFTT_NM9.TTC',$allsp/10*(10-$i));
        }
        
        $nme1 = "屬性";
        imagefttext($img,15,0,720,480,$bl,'DFTT_NM9.TTC',$nme1);
        
        for($i = 0; $i <= 2; $i++){
                imageline($img,280+($i*210),468,280+($i*210),472,$bw);
                imagefilledrectangle($img,165+210*$i,470,185+210*$i,470-$bg[$i]/$exsp*4.5,$red);
                imagefttext($img,10,0,165+210*$i,465-$bg[$i]/$exsp*4.5,$bl,'DFTT_NM9.TTC',$bg[$i]);
                switch($i){
                        case 0:
                                $nme2 = "火";
                                break;
                        case 1:
                                $nme2 = "水";
                                break;
                        case 2:
                                $nme2 = "電";
                }
                imagefttext($img,17,0,165+210*$i,492,$bl,'DFTT_NM9.TTC',$nme2);
        }
        
        imagepng($img);                                                                //製成png
        imagedestroy($img);                                                        //銷毀圖片
?>


沒有留言:

張貼留言