
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 ?>
这个类可以实现画一个系列的柱状图和多个系列的柱状图,如下:
一个系列的柱状图
多个系列的柱状图