溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何在PHP中使用GD庫繪制一個折線統(tǒng)計(jì)圖

發(fā)布時間:2021-03-10 16:21:43 來源:億速云 閱讀:157 作者:Leah 欄目:開發(fā)技術(shù)

如何在PHP中使用GD庫繪制一個折線統(tǒng)計(jì)圖?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

(1)創(chuàng)建畫布:所有的繪圖設(shè)計(jì)都需要在一個背景圖片上完成,而畫布實(shí)際上就是在內(nèi)存中開辟的一塊臨時區(qū)域,用于存儲圖像的信息。以后的圖像操作都將基于這個背景畫布,該畫布的管理就類似于我們在畫畫時使用的畫布。

(2)繪制圖像:畫布創(chuàng)建完成以后,就可以通過這個畫布資源,使用各種畫像函數(shù)設(shè)置圖像的顏色、填充畫布、畫點(diǎn)、線段、各種幾何圖形,以及向圖像中添加文本等。

(3)輸出圖像:完成整個圖像的繪制以后,需要將圖像以某種格式保存到服務(wù)器指定的文件中,或?qū)D像直接輸出到瀏覽器上顯示給用戶。但在圖像輸出之前,一定要使用header()函數(shù)發(fā)送Content-type通知瀏覽器,這次發(fā)送的是圖片不是文本。

(4)釋放資源:圖像被輸出以后,畫布中的內(nèi)容也不再有用。出于節(jié)約系統(tǒng)資源的考慮,需要及時清除畫布占用的所有內(nèi)存資源。

php中用GD繪制折線圖,代碼如下:

Class Chart{
  private $image; // 定義圖像
  private $title; // 定義標(biāo)題
  private $ydata; // 定義Y軸數(shù)據(jù)
  private $xdata; // 定義X軸數(shù)據(jù)
  private $seriesName; // 定義每個系列數(shù)據(jù)的名稱
  private $color; // 定義條形圖顏色
  private $bgcolor; // 定義圖片背景顏色
  private $width; // 定義圖片的寬
  private $height; // 定義圖片的長
  /*
  * 構(gòu)造函數(shù) 
  * String title 圖片標(biāo)題
  * Array xdata 索引數(shù)組,X軸數(shù)據(jù)
  * Array ydata 索引數(shù)組,數(shù)字?jǐn)?shù)組,Y軸數(shù)據(jù)
  * Array series_name 索引數(shù)組,數(shù)據(jù)系列名稱
  */
  function __construct($title,$xdata,$ydata,$seriesName) {  
   $this->title = $title;
   $this->xdata = $xdata;
   $this->ydata = $ydata;
   $this->seriesName = $seriesName;
   $this->color = array('#DC', '#B', '#EDB', '#DDDF', '#CBE', '#E', '#FF', '#FFF', '#AFC');
  }
  /*
  * 公有方法,設(shè)置條形圖的顏色 
  * Array color 顏色數(shù)組,元素取值為'#DC'這種形式
  */
  function setBarColor($color){
   $this->color = $color;
  }
 /*
  * 繪制折線圖
  */
  public function paintLineChart() {
   $ydataNum = $this->arrayNum($this->ydata); // 取得數(shù)據(jù)分組的個數(shù)
   $max = $this->arrayMax($this->ydata); // 取得所有呈現(xiàn)數(shù)據(jù)的最大值
   $max = ($max > )? $max : ;
   $multi = $max/; // 如果最大數(shù)據(jù)是大于的則進(jìn)行縮小處理  
   $barHeightMulti = .; // 條形高縮放的比例
   $lineWidth = ;
   $chartLeft = (+strlen($max))*; // 設(shè)置圖片左邊的margin
   $lineY = ; // 初始化條形圖的Y的坐標(biāo)
   // 設(shè)置圖片的寬、高
   //$this->width = $lineWidth*count($this->xdata) + $chartLeft - $lineWidth/.; 
   $margin = ; // 小矩形描述右邊margin
   $recWidth = ; // 小矩形的寬
   $recHeight = ; // 小矩形的高
   $space = ; // 小矩形與條形圖的間距
   $tmpWidth = ;
   // 設(shè)置圖片的寬、高
   $lineChartWidth = $lineWidth*count($this->xdata) + $chartLeft - $lineWidth/. ;
   // 兩個系列數(shù)據(jù)以上的加上小矩形的寬
   if($ydataNum > ) {
    $tmpWidth = $this->arrayLengthMax($this->seriesName)**/ + $space + $recWidth + + $margin;
   } 
   $this->width = $lineChartWidth + $tmpWidth; 
   $this->height = ; 
   $this->image = imagecreatetruecolor($this->width ,$this->height); // 準(zhǔn)備畫布
   $this->bgcolor = imagecolorallocate($this->image,,,); // 圖片的背景顏色
   // 設(shè)置條形圖的顏色
   $color = array();
   foreach($this->color as $col) {
    $col = substr($col,,strlen($col)-);
    $red = hexdec(substr($col,,));
    $green = hexdec(substr($col,,));
    $blue = hexdec(substr($col,,));
    $color[] = imagecolorallocate($this->image ,$red, $green, $blue);
   }
   // 設(shè)置線段的顏色、字體的顏色、字體的路徑
   $lineColor = imagecolorallocate($this->image ,xcc,xcc,xcc);
   $fontColor = imagecolorallocate($this->image, x,xf,xf);
   $fontPath = 'font/simsun.ttc';
   imagefill($this->image,,,$this->bgcolor); // 繪畫背景
   // 繪畫圖的分短線與左右邊線
   for($i = ; $i < ; $i++ ) {
    imageline($this->image,$chartLeft-,$lineY-$barHeightMulti*$max//$multi*$i,$lineChartWidth,$lineY-$barHeightMulti*$max//$multi*$i,$lineColor);
    imagestring($this->image,,,$lineY-$barHeightMulti*$max//$multi*$i-,floor($max/*$i),$fontColor);
   }  
   imageline($this->image,$chartLeft-,,$chartLeft-,$lineY,$lineColor);
   imageline($this->image,$lineChartWidth-,,$lineChartWidth-,$lineY,$lineColor);
   $style = array($lineColor,$lineColor,$lineColor,$lineColor,$lineColor,$this->bgcolor,$this->bgcolor,$this->bgcolor,$this->bgcolor,$this->bgcolor);
   imagesetstyle($this->image,$style);
   // 繪制折線圖的分隔線(虛線)
   foreach($this->xdata as $key => $val) {
     $lineX = $chartLeft + + $lineWidth*$key;
     imageline($this->image,$lineX,,$lineX,$lineY,IMG_COLOR_STYLED);
   }
   // 繪畫圖的折線
   foreach($this->ydata as $key => $val) {
    if($ydataNum == ) {
     // 一個系列數(shù)據(jù)時
     if($key == count($this->ydata) - ) break;
     $lineX = $chartLeft + + $lineWidth*$key;
     $lineY = $lineY-$barHeightMulti*($this->ydata[$key+])/$multi;
     // 畫折線
     if($key == count($this->ydata) - ) {
      imagefilledellipse($this->image,$lineX+$lineWidth,$lineY,,,$color[]);
     }
     imageline($this->image,$lineX,$lineY-$barHeightMulti*$val/$multi,$lineX+$lineWidth,$lineY,$color[]);
     imagefilledellipse($this->image,$lineX,$lineY-$barHeightMulti*$val/$multi,,,$color[]);
    }elseif($ydataNum > ) {
     // 多個系列的數(shù)據(jù)時
     foreach($val as $ckey => $cval) {
      if($ckey == count($val) - ) break; 
      $lineX = $chartLeft + + $lineWidth*$ckey;
      $lineY = $lineY-$barHeightMulti*($val[$ckey+])/$multi;
      // 畫折線
      if($ckey == count($val) - ) {
       imagefilledellipse($this->image,$lineX+$lineWidth,$lineY,,,$color[$key%count($this->color)]);
      }
      imageline($this->image,$lineX,$lineY-$barHeightMulti*$cval/$multi,$lineX+$lineWidth,$lineY,$color[$key%count($this->color)]);
      imagefilledellipse($this->image,$lineX,$lineY-$barHeightMulti*$cval/$multi,,,$color[$key%count($this->color)]);
     }
    }
   }
   // 繪畫條形圖的x坐標(biāo)的值
   foreach($this->xdata as $key => $val) {
    $lineX = $chartLeft + $lineWidth*$key + $lineWidth/ - ;
    imagettftext($this->image,,-,$lineX,$lineY+,$fontColor,$fontPath,$this->xdata[$key]);
   }  
   // 兩個系列數(shù)據(jù)以上時繪制小矩形及之后文字說明
   if($ydataNum > ) {
    $x = $lineChartWidth + $space;
    $y = ;
    foreach($this->seriesName as $key => $val) {
     imagefilledrectangle($this->image,$x,$y,$x+$recWidth,$y+$recHeight,$color[$key%count($this->color)]);  
     imagettftext($this->image,,,$x+$recWidth+,$y+$recHeight-,$fontColor,$fontPath,$this->seriesName[$key]);
     $y += $recHeight + ;   
    }
   }
   // 繪畫標(biāo)題
   $titleStart = ($this->width - .*strlen($this->title))/;
   imagettftext($this->image,,,$titleStart,,$fontColor,$fontPath,$this->title);
   // 輸出圖片
   header("Content-Type:image/png");
   imagepng ( $this->image );
  }
  /*
  * 私有方法,當(dāng)數(shù)組為二元數(shù)組時,統(tǒng)計(jì)數(shù)組的長度 
  * Array arr 要做統(tǒng)計(jì)的數(shù)組
  */
  private function arrayNum($arr) {
   $num = ;
   if(is_array($arr)) {
    $num++;
    for($i = ; $i < count($arr); $i++){
     if(is_array($arr[$i])) {
      $num = count($arr);
      break;
     }
    }
   }
   return $num;
  }
  /*
  * 私有方法,計(jì)算數(shù)組的深度 
  * Array arr 數(shù)組
  */
  private function arrayDepth($arr) {
   $num = ;
   if(is_array($arr)) {
    $num++;
    for($i = ; $i < count($arr); $i++){
     if(is_array($arr[$i])) {
      $num += $this->arrayDepth($arr[$i]);
      break;
     }
    }
   }
   return $num;
  }
  /*
  * 私有方法,找到一組中的最大值 
  * Array arr 數(shù)字?jǐn)?shù)組
  */
  private function arrayMax($arr) {
   $depth = $this->arrayDepth($arr);
   $max = ;
   if($depth == ) {
    rsort($arr);
    $max = $arr[];  
   }elseif($depth > ) {
    foreach($arr as $val) {
     if(is_array($val)) {
      if($this->arrayMax($val) > $max) {
       $max = $this->arrayMax($val);
      }
     }else{     
      if($val > $max){
       $max = $val;
      }
     } 
    }   
   }
   return $max;
  }
  /*
  * 私有方法,求數(shù)組的平均值 
  * Array arr 數(shù)字?jǐn)?shù)組
  */
  function arrayAver($arr) {
   $aver = array();
   foreach($arr as $val) {
    if(is_array($val)) {
     $aver = array_merge($aver,$val);
    }else{
     $aver[] = $val;
    }
   }
   return array_sum($aver)/count($aver);
  }
  /*
  * 私有方法,求數(shù)組中元素長度最大的值 
  * Array arr 字符串?dāng)?shù)組,必須是漢字
  */
  private function arrayLengthMax($arr) {
   $length = ;
   foreach($arr as $val) {
    $length = strlen($val) > $length ? strlen($val) : $length;
   }
   return $length/;
  } 
  // 析構(gòu)函數(shù)
  function __destruct(){
   imagedestroy($this->image);
  }
 }

測試代碼如下:

 $xdata = array('測試一','測試二','測試三','測試四','測試五','測試六','測試七','測試八','測試九');
 $ydata = array(array(,,,,,,,,),array(,,,,,,,,));
 $color = array();
 $seriesName = array("七月","八月");
 $title = "測試數(shù)據(jù)";
 $Img = new Chart($title,$xdata,$ydata,$seriesName);
 $Img->paintLineChart();

效果圖如下:

如何在PHP中使用GD庫繪制一個折線統(tǒng)計(jì)圖

到此代碼結(jié)束。

下面給大家介紹php中GD庫的一些簡單使用

今天了解了一些GD庫的簡單使用,現(xiàn)在稍微做一下總結(jié)!

GD庫是什么?,graphic device,圖像工具庫,gd庫是php處理圖形的擴(kuò)展庫,gd庫提供了一系列用來處理圖片的API,使用GD庫可以處理圖片,或者生成圖片。 在網(wǎng)站上 GD庫通常用來生成縮略圖或者用來對圖片加水印或者對網(wǎng)站數(shù)據(jù)生成報(bào)表。

php并不局限于輸出HTML文本。php通過使用GD擴(kuò)展庫還能用來動態(tài)輸出圖像,例如文字按鈕、驗(yàn)證碼、數(shù)據(jù)統(tǒng)計(jì)圖等。哈可以輕松地編輯圖像,力圖處理縮略圖和為圖片添加水印等,具有強(qiáng)大的圖像處理能力。

首先我們來說下GD庫,繪制個簡單圖形的一些步驟:

1、首先是創(chuàng)建畫布,此處我們利用imagecreatetruecolor函數(shù),也可以利用imagecreate,區(qū)別在于前者創(chuàng)建了一個真彩圖像,后者創(chuàng)建了一個基于調(diào)色板的圖像

$img=imagecreatetruecolor(100,100),其中有兩個參數(shù)分別對應(yīng),我們創(chuàng)建的圖像的寬和高

2、設(shè)置一些必要的"染料盒"

其實(shí)就是定義一些之后會用到的填充顏色,此處我們統(tǒng)一定義在這個位置,此處我們利用imagecolorallocate函數(shù)

$white=imagecolorallocate($img,0xFF,0xFF,0xFF)或者可以使用RGB的顏色命名方式 如$white=imagecolorallocate($img,255,255,255);

$gray = imagecolorallocate($img, 0xC0, 0xC0, 0xC0);
$darkgray = imagecolorallocate($img, 0x90, 0x90, 0x90);
$navy = imagecolorallocate($img, 0x00, 0x00, 0x80);
$darknavy = imagecolorallocate($img, 0x00, 0x00, 0x50);
$red = imagecolorallocate($img, 0xFF, 0x00, 0x00);
$darkred = imagecolorallocate($img, 0x90, 0x00, 0x00);
$black=imagecolorallocate($img,0x00,0x00,0x00);

此處我們定義多一些所需要的顏色

3、填充區(qū)域顏色,可以簡單的理解為填充圖片的背景顏色,利用imagefill函數(shù)

imagefill($img,0,0,$white),此處的0 0表示從坐標(biāo)x y處開始填充背景色

4、繪制圖形,例如繪制餅狀圖,所需要的是imagefilledarc函數(shù)

imagefilledarc()的參數(shù)相對來說較多,形如imagefilledarc($img,50,$i,100,50,0,45,$red,IMG_ARC_PIE);

其中分別表示以red顏色字img圖像上繪制一個以50,$i為起點(diǎn),以0 45角度這個范圍內(nèi)繪制弧線

5、期間我們還可以添加一些說明問題,比如水平的添加一個字符串,利用 imagestring($img,1,20,40,"hello,world!",$red),表示在img圖片中以20 40為坐標(biāo),寫上一個紅色的hello,world!字樣

6、就是講圖像輸出

首先要告之瀏覽器要以何種圖片格式輸出,例如以png輸出,則使用header("Content-type:image/png");

其次 將圖片輸出到瀏覽器中,imagepng($img);

最后,銷毀圖片,即釋放該圖片存儲所占用的內(nèi)存 imagedestroy(img);,

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI