程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> php中用GD繪制折線圖,gd繪制折線

php中用GD繪制折線圖,gd繪制折線

編輯:關於PHP編程

php中用GD繪制折線圖,gd繪制折線


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

  1 Class Chart{
  2     private $image; // 定義圖像
  3     private $title; // 定義標題
  4     private $ydata; // 定義Y軸數據
  5     private $xdata; // 定義X軸數據
  6     private $seriesName; // 定義每個系列數據的名稱
  7     private $color; // 定義條形圖顏色
  8     private $bgcolor; // 定義圖片背景顏色
  9     private $width; // 定義圖片的寬
 10     private $height; // 定義圖片的長
 11     
 12     /*
 13      * 構造函數 
 14      * String title 圖片標題
 15      * Array xdata 索引數組,X軸數據
 16      * Array ydata 索引數組,數字數組,Y軸數據
 17      * Array series_name 索引數組,數據系列名稱
 18      */
 19     function __construct($title,$xdata,$ydata,$seriesName) {        
 20         $this->title = $title;
 21         $this->xdata = $xdata;
 22         $this->ydata = $ydata;
 23         $this->seriesName = $seriesName;
 24         $this->color = array('#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4');
 25     }
 26     
 27     /*
 28      * 公有方法,設置條形圖的顏色 
 29      * Array color 顏色數組,元素取值為'#058DC7'這種形式
 30      */
 31     function setBarColor($color){
 32         $this->color = $color;
 33     }
 34 /*
 35      * 繪制折線圖
 36      */
 37     public function paintLineChart() {
 38         $ydataNum = $this->arrayNum($this->ydata); // 取得數據分組的個數
 39         $max = $this->arrayMax($this->ydata); // 取得所有呈現數據的最大值
 40         $max = ($max > 100)? $max : 100;
 41         $multi = $max/100; // 如果最大數據是大於100的則進行縮小處理        
 42         $barHeightMulti = 2.2; // 條形高縮放的比例
 43         $lineWidth = 50;
 44         $chartLeft = (1+strlen($max))*12; // 設置圖片左邊的margin
 45         
 46         $lineY = 250; // 初始化條形圖的Y的坐標
 47         // 設置圖片的寬、高
 48         //$this->width = $lineWidth*count($this->xdata) + $chartLeft - $lineWidth/1.6; 
 49         
 50         $margin = 10; // 小矩形描述右邊margin
 51         $recWidth = 20; // 小矩形的寬
 52         $recHeight = 15; // 小矩形的高
 53         $space = 20; // 小矩形與條形圖的間距
 54         $tmpWidth = 0;
 55         // 設置圖片的寬、高
 56         $lineChartWidth =  $lineWidth*count($this->xdata) + $chartLeft - $lineWidth/1.6 ;
 57         // 兩個系列數據以上的加上小矩形的寬
 58         if($ydataNum > 1) {
 59             $tmpWidth = $this->arrayLengthMax($this->seriesName)*10*4/3 + $space + $recWidth + + $margin;
 60         } 
 61         $this->width = $lineChartWidth + $tmpWidth; 
 62         
 63         $this->height = 300; 
 64         $this->image = imagecreatetruecolor($this->width ,$this->height); // 准備畫布
 65         $this->bgcolor = imagecolorallocate($this->image,255,255,255); // 圖片的背景顏色
 66         
 67         // 設置條形圖的顏色
 68         $color = array();
 69         foreach($this->color as $col) {
 70             $col = substr($col,1,strlen($col)-1);
 71             $red = hexdec(substr($col,0,2));
 72             $green = hexdec(substr($col,2,2));
 73             $blue = hexdec(substr($col,4,2));
 74             $color[] = imagecolorallocate($this->image ,$red, $green, $blue);
 75         }
 76         
 77         // 設置線段的顏色、字體的顏色、字體的路徑
 78         $lineColor = imagecolorallocate($this->image ,0xcc,0xcc,0xcc);
 79         $fontColor = imagecolorallocate($this->image, 0x95,0x8f,0x8f);
 80         $fontPath = 'font/simsun.ttc';
 81         
 82         imagefill($this->image,0,0,$this->bgcolor); // 繪畫背景
 83         
 84         // 繪畫圖的分短線與左右邊線
 85         for($i = 0; $i < 6; $i++ ) {
 86             imageline($this->image,$chartLeft-10,$lineY-$barHeightMulti*$max/5/$multi*$i,$lineChartWidth,$lineY-$barHeightMulti*$max/5/$multi*$i,$lineColor);
 87             imagestring($this->image,4,5,$lineY-$barHeightMulti*$max/5/$multi*$i-8,floor($max/5*$i),$fontColor);
 88         }        
 89         imageline($this->image,$chartLeft-10,30,$chartLeft-10,$lineY,$lineColor);
 90         imageline($this->image,$lineChartWidth-1,30,$lineChartWidth-1,$lineY,$lineColor);
 91         $style = array($lineColor,$lineColor,$lineColor,$lineColor,$lineColor,$this->bgcolor,$this->bgcolor,$this->bgcolor,$this->bgcolor,$this->bgcolor);
 92         imagesetstyle($this->image,$style);
 93         
 94         // 繪制折線圖的分隔線(虛線)
 95         foreach($this->xdata as $key => $val) {
 96                 $lineX = $chartLeft + 3 + $lineWidth*$key;
 97                 imageline($this->image,$lineX,30,$lineX,$lineY,IMG_COLOR_STYLED);
 98         }
 99         
100         // 繪畫圖的折線
101         foreach($this->ydata as $key => $val) {
102             if($ydataNum == 1) {
103                 // 一個系列數據時
104                 if($key == count($this->ydata) - 1 ) break;
105                 $lineX = $chartLeft + 3 + $lineWidth*$key;
106                 $lineY2 = $lineY-$barHeightMulti*($this->ydata[$key+1])/$multi;
107                 
108                 // 畫折線
109                 if($key == count($this->ydata) - 2 ) {
110                     imagefilledellipse($this->image,$lineX+$lineWidth,$lineY2,10,10,$color[0]);
111                 }
112                 imageline($this->image,$lineX,$lineY-$barHeightMulti*$val/$multi,$lineX+$lineWidth,$lineY2,$color[0]);
113                 imagefilledellipse($this->image,$lineX,$lineY-$barHeightMulti*$val/$multi,10,10,$color[0]);
114             }elseif($ydataNum > 1) {
115                 // 多個系列的數據時
116                 foreach($val as $ckey => $cval) {
117                     
118                     if($ckey == count($val) - 1 ) break; 
119                     $lineX = $chartLeft + 3 + $lineWidth*$ckey;
120                     $lineY2 = $lineY-$barHeightMulti*($val[$ckey+1])/$multi;
121                     // 畫折線
122                     if($ckey == count($val) - 2 ) {
123                         imagefilledellipse($this->image,$lineX+$lineWidth,$lineY2,10,10,$color[$key%count($this->color)]);
124                     }
125                     imageline($this->image,$lineX,$lineY-$barHeightMulti*$cval/$multi,$lineX+$lineWidth,$lineY2,$color[$key%count($this->color)]);
126                     imagefilledellipse($this->image,$lineX,$lineY-$barHeightMulti*$cval/$multi,10,10,$color[$key%count($this->color)]);
127                 }
128             }
129             
130         }
131                 
132         // 繪畫條形圖的x坐標的值
133         foreach($this->xdata as $key => $val) {
134             $lineX = $chartLeft + $lineWidth*$key + $lineWidth/3 - 20;
135             imagettftext($this->image,10,-65,$lineX,$lineY+15,$fontColor,$fontPath,$this->xdata[$key]);
136         }        
137         
138         // 兩個系列數據以上時繪制小矩形及之後文字說明
139         if($ydataNum > 1) {
140             $x1 = $lineChartWidth + $space;
141             $y1 = 20 ;
142             foreach($this->seriesName as $key => $val) {
143                 imagefilledrectangle($this->image,$x1,$y1,$x1+$recWidth,$y1+$recHeight,$color[$key%count($this->color)]);        
144                 imagettftext($this->image,10,0,$x1+$recWidth+5,$y1+$recHeight-2,$fontColor,$fontPath,$this->seriesName[$key]);
145                 $y1 += $recHeight + 10;            
146             }
147         }
148         
149         // 繪畫標題
150         $titleStart = ($this->width - 5.5*strlen($this->title))/2;
151         imagettftext($this->image,11,0,$titleStart,20,$fontColor,$fontPath,$this->title);
152         
153         // 輸出圖片
154         header("Content-Type:image/png");
155         imagepng ( $this->image );
156     }
157     
158     
159     /*
160      * 私有方法,當數組為二元數組時,統計數組的長度 
161      * Array arr 要做統計的數組
162      */
163     private function arrayNum($arr) {
164          $num = 0;
165          if(is_array($arr)) {
166             $num++;
167             for($i = 0; $i < count($arr); $i++){
168                 if(is_array($arr[$i])) {
169                     $num = count($arr);
170                     break;
171                 }
172             }
173          }
174          return $num;
175     }
176     
177     /*
178      * 私有方法,計算數組的深度 
179      * Array arr 數組
180      */
181     private function arrayDepth($arr) {
182          $num = 0;
183          if(is_array($arr)) {
184             $num++;
185             for($i = 0; $i < count($arr); $i++){
186                 if(is_array($arr[$i])) {
187                     $num += $this->arrayDepth($arr[$i]);
188                     break;
189                 }
190             }
191          }
192          return $num;
193     }
194     
195     /*
196      * 私有方法,找到一組中的最大值 
197      * Array arr 數字數組
198      */
199      private function arrayMax($arr) {
200         $depth = $this->arrayDepth($arr);
201         $max = 0;
202         if($depth == 1) {
203             rsort($arr);
204             $max = $arr[0];        
205         }elseif($depth > 1) {
206             foreach($arr as $val) {
207                 if(is_array($val)) {
208                     if($this->arrayMax($val) > $max) {
209                         $max = $this->arrayMax($val);
210                     }
211                 }else{                    
212                     if($val > $max){
213                         $max = $val;
214                     }
215                 }    
216             }            
217         }
218         return $max;
219     }
220     
221     /*
222      * 私有方法,求數組的平均值 
223      * Array arr 數字數組
224      */
225     function arrayAver($arr) {
226         $aver = array();
227         foreach($arr as $val) {
228             if(is_array($val)) {
229                 $aver = array_merge($aver,$val);
230             }else{
231                 $aver[] = $val;
232             }
233         }
234         return array_sum($aver)/count($aver);
235     }
236     
237     /*
238      * 私有方法,求數組中元素長度最大的值 
239      * Array arr 字符串數組,必須是漢字
240      */
241     private function arrayLengthMax($arr) {
242         $length = 0;
243         foreach($arr as $val) {
244             $length = strlen($val) > $length ? strlen($val) : $length;
245         }
246         return $length/3;
247     } 
248     
249     // 析構函數
250     function __destruct(){
251         imagedestroy($this->image);
252     }
253  }

 

測試代碼如下:

1  $xdata = array('測試一','測試二','測試三','測試四','測試五','測試六','測試七','測試八','測試九');
2  $ydata = array(array(29,30,45,54,65,45,76,23,54),array(89,60,90,23,35,45,56,23,56));
3  $color = array();
4  $seriesName = array("七月","八月");
5  $title = "測試數據";
6  $Img = new Chart($title,$xdata,$ydata,$seriesName);
7  $Img->paintLineChart();

 

效果圖如下:

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved