PHP中利用GD實現的柱狀圖,自己寫的一個畫柱狀圖的類,上代碼。
1 <?php
2 Class Chart{
3 private $image; // 定義圖像
4 private $title; // 定義標題
5 private $ydata; // 定義Y軸數據
6 private $xdata; // 定義X軸數據
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 */
18 function __construct($title,$xdata,$ydata) {
19 $this->title = $title;
20 $this->xdata = $xdata;
21 $this->ydata = $ydata;
22 $this->color = array('#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4');
23 }
24
25 /*
26 * 公有方法,設置條形圖的顏色
27 * Array color 顏色數組,元素取值為'#058DC7'這種形式
28 */
29 function setBarColor($color){
30 $this->color = $color;
31 }
32
33 /*
34 * 公有方法,畫條形圖
35 */
36 function mkBarChart(){
37 $ydataNum = $this->arrayNum($this->ydata); // 取得數據分組的個數
38 $max = $this->arrayMax($this->ydata); // 取得所有呈現數據的最大值
39 $multi = ($max > 100)? $max/100 : 1; // 如果最大數據是大於100的則進行縮小處理,獲取
40 $barHeightMulti = 2.2; // 條形高縮放的比例
41 $barWidth = (16 - 2*($ydataNum - 1)) > 10 ? (16 - 2*($ydataNum - 1)) : 10; // 條的寬
42 $barSpace = 16; // 條之間的間距
43 $chartLeft = (1+strlen($max))*12; // 設置圖片左邊的margin
44
45 $barY = 250; // 初始化條形圖的Y的坐標
46 // 設置圖片的寬、高
47 $this->width = ($ydataNum*$barWidth + $barSpace)*count($this->xdata) + $chartLeft;
48 $this->height = 300;
49 $this->image = imagecreatetruecolor($this->width ,$this->height); // 准備畫布
50 $this->bgcolor = imagecolorallocate($this->image,255,255,255); // 圖片的背景顏色
51
52 // 設置條形圖的顏色
53 $color = array();
54 foreach($this->color as $col) {
55 $col = substr($col,1,strlen($col)-1);
56 $red = hexdec(substr($col,0,2));
57 $green = hexdec(substr($col,2,2));
58 $blue = hexdec(substr($col,4,2));
59 $color[] = imagecolorallocate($this->image ,$red, $green, $blue);
60 }
61
62 // 設置線段的顏色、字體的顏色、字體的路徑
63 $lineColor = imagecolorallocate($this->image ,0xcc,0xcc,0xcc);
64 $fontColor = imagecolorallocate($this->image, 0x95,0x8f,0x8f);
65 $fontPath = 'font/simsun.ttc';
66
67 imagefill($this->image,0,0,$this->bgcolor); // 繪畫背景
68
69 // 繪畫圖的分短線與左右邊線
70 for($i = 0; $i < 6; $i++ ) {
71 imageline($this->image,$chartLeft-10,$barY-$barHeightMulti*$max/5/$multi*$i,$this->width,$barY-$barHeightMulti*$max/5/$multi*$i,$lineColor);
72 imagestring($this->image,4,5,$barY-$barHeightMulti*$max/5/$multi*$i-8,floor($max/5*$i),$fontColor);
73 }
74 imageline($this->image,$chartLeft-10,30,$chartLeft-10,$barY,$lineColor);
75 imageline($this->image,$this->width-1,30,$this->width-1,$barY,$lineColor);
76
77 // 繪畫圖的條形
78 foreach($this->ydata as $key => $val) {
79 if($ydataNum == 1) {
80 // 一個系列數據時
81 $barX = $chartLeft + 3 + ($barWidth+$barSpace)*$key;
82 imagefilledrectangle($this->image,$barX,$barY-$barHeightMulti*$val/$multi,$barX+$barWidth,$barY,$color[$key%count($this->color)]);
83 }elseif($ydataNum > 1) {
84 // 多個系列的數據時
85 $cbarSpace = $barSpace + $barWidth*($ydataNum-1);
86 foreach($val as $ckey => $cval) {
87 $barX = $chartLeft + 3 + $barWidth*$key + $ckey*($cbarSpace+$barWidth);
88 imagefilledrectangle($this->image,$barX,$barY-$barHeightMulti*$cval/$multi,$barX+$barWidth,$barY,$color[$key%count($this->color)]);
89 }
90 }
91
92 }
93
94 // 繪畫條形圖的x坐標的值
95 foreach($this->xdata as $key => $val) {
96 $barX = $chartLeft + ($ydataNum*$barWidth+$barSpace)*$key + $ydataNum*$barWidth/3;
97 imagettftext($this->image,10,-45,$barX,$barY+15,$fontColor,$fontPath,$this->xdata[$key]);
98 }
99
100 // 繪畫標題
101 $titleStart = ($this->width - 5.5*strlen($this->title))/2;
102 imagettftext($this->image,11,0,$titleStart,20,$fontColor,$fontPath,$this->title);
103
104 // 輸出圖片
105 header("Content-Type:image/png");
106 imagepng ( $this->image );
107 }
108
109 /*
110 * 私有方法,當數組為二元數組時,統計數組的長度
111 * Array arr 要做統計的數組
112 */
113 private function arrayNum($arr) {
114 $num = 0;
115 if(is_array($arr)) {
116 $num++;
117 for($i = 0; $i < count($arr); $i++){
118 if(is_array($arr[$i])) {
119 $num = count($arr);
120 break;
121 }
122 }
123 }
124 return $num;
125 }
126
127 /*
128 * 私有方法,計算數組的深度
129 * Array arr 數組
130 */
131 private function arrayDepth($arr) {
132 $num = 0;
133 if(is_array($arr)) {
134 $num++;
135 for($i = 0; $i < count($arr); $i++){
136 if(is_array($arr[$i])) {
137 $num += $this->arrayDepth($arr[$i]);
138 break;
139 }
140 }
141 }
142 return $num;
143 }
144
145 /*
146 * 私有方法,找到一組中的最大值
147 * Array arr 數字數組
148 */
149 private function arrayMax($arr) {
150 $depth = $this->arrayDepth($arr);
151 $max = 0;
152 if($depth == 1) {
153 rsort($arr);
154 $max = $arr[0];
155 }elseif($depth > 1) {
156 foreach($arr as $val) {
157 if(is_array($val)) {
158 if($this->arrayMax($val) > $max) {
159 $max = $this->arrayMax($val);
160 }
161 }else{
162 if($val > $max){
163 $max = $val;
164 }
165 }
166 }
167 }
168 return $max;
169 }
170
171 function arrayAver($arr) {
172 $aver = array();
173 foreach($arr as $val) {
174 if(is_array($val)) {
175 $aver = array_merge($aver,$val);
176 }else{
177 $aver[] = $val;
178 }
179 }
180 return array_sum($aver)/count($aver);
181
182 }
183 // 析構函數
184 function __destruct(){
185 imagedestroy($this->image);
186 }
187 }
188 ?>
這個類可以實現畫一個系列的柱狀圖和多個系列的柱狀圖,如下:
一個系列的柱狀圖