php中用GD绘制折线图,代码如下:
1ClassChart{2PRivate$image;//定义图像3private$title;//定义标题4private$ydata;//定义Y轴数据5private$xdata;//定义X轴数据6private$seriesName;//定义每个系列数据的名称7private$color;//定义条形图颜色8private$bgcolor;//定义图片背景颜色9private$width;//定义图片的宽10private$height;//定义图片的长1112/*13* 构造函数14* String title 图片标题15* Array xdata 索引数组,X轴数据16* Array ydata 索引数组,数字数组,Y轴数据17* Array series_name 索引数组,数据系列名称18*/19function__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}2627/*28* 公有方法,设置条形图的颜色29* Array color 颜色数组,元素取值为'#058DC7'这种形式30*/31functionsetBarColor($color){32$this->color =$color;33}34/*35* 绘制折线图36*/37publicfunctionpaintLineChart() {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;//设置图片左边的margin4546$lineY= 250;//初始化条形图的Y的坐标47// 设置图片的宽、高48//$this->width = $lineWidth*count($this->xdata) + $chartLeft - $lineWidth/1.6;4950$margin= 10;//小矩形描述右边margin51$recWidth= 20;//小矩形的宽52$recHeight= 15;//小矩形的高53$space= 20;//小矩形与条形图的间距54$tmpWidth= 0;55//设置图片的宽、高56$lineChartWidth=$lineWidth*count($this->xdata) +$chartLeft-$lineWidth/1.6;57//两个系列数据以上的加上小矩形的宽58if($ydataNum> 1) {59$tmpWidth=$this->arrayLengthMax($this->seriesName)*10*4/3 +$space+$recWidth+ +$margin;60}61$this->width =$lineChartWidth+$tmpWidth;6263$this->height = 300;64$this->image = imagecreatetruecolor($this->width ,$this->height);//准备画布65$this->bgcolor = imagecolorallocate($this->image,255,255,255);//图片的背景颜色6667// 设置条形图的颜色68$color=array();69foreach($this->coloras$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}7677//设置线段的颜色、字体的颜色、字体的路径78$lineColor= imagecolorallocate($this->image ,0xcc,0xcc,0xcc);79$fontColor= imagecolorallocate($this->image, 0x95,0x8f,0x8f);80$fontPath= 'font/simsun.ttc';8182imagefill($this->image,0,0,$this->bgcolor);//绘画背景8384// 绘画图的分短线与左右边线85for($i= 0;$i< 6;$i++) {86imageline($this->image,$chartLeft-10,$lineY-$barHeightMulti*$max/5/$multi*$i,$lineChartWidth,$lineY-$barHeightMulti*$max/5/$multi*$i,$lineColor);87imagestring($this->image,4,5,$lineY-$barHeightMulti*$max/5/$multi*$i-8,floor($max/5*$i),$fontColor);88}89imageline($this->image,$chartLeft-10,30,$chartLeft-10,$lineY,$lineColor);90imageline($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);92imagesetstyle($this->image,$style);9394//绘制折线图的分隔线(虚线)95foreach($this->xdataas$key=>$val) {96$lineX=$chartLeft+ 3 +$lineWidth*$key;97imageline($this->image,$lineX,30,$lineX,$lineY,IMG_COLOR_STYLED);98}99100//绘画图的折线101foreach($this->ydataas$key=>$val) {102if($ydataNum== 1) {103//一个系列数据时104if($key==count($this->ydata) - 1 )
break;105$lineX=$chartLeft+ 3 +$lineWidth*$key;106$lineY2=$lineY-$barHeightMulti*($this->ydata[$key+1])/$multi;107108//画折线109if($key==count($this->ydata) - 2) {110imagefilledellipse($this->image,$lineX+$lineWidth,$lineY2,10,10,$color[0]);111}112imageline($this->image,$lineX,$lineY-$barHeightMulti*$val/$multi,$lineX+$lineWidth,$lineY2,$color[0]);113imagefilledellipse($this->image,$lineX,$lineY-$barHeightMulti*$val/$multi,10,10,$color[0]);114}elseif($ydataNum> 1) {115//多个系列的数据时116foreach($valas$ckey=>$cval) {117118if($ckey==count($val) - 1 )
break;119$lineX=$chartLeft+ 3 +$lineWidth*$ckey;120$lineY2=$lineY-$barHeightMulti*($val[$ckey+1])/$multi;121//画折线122if($ckey==count($val) - 2) {123imagefilledellipse($this->image,$lineX+$lineWidth,$lineY2,10,10,$color[$key%count($this->color)]);124}125imageline($this->image,$lineX,$lineY-$barHeightMulti*$cval/$multi,$lineX+$lineWidth,$lineY2,$color[$key%count($this->color)]);126imagefilledellipse($this->image,$lineX,$lineY-$barHeightMulti*$cval/$multi,10,10,$color[$key%count($this->color)]);127}128}129130}131132//绘画条形图的x坐标的值133foreach($this->xdataas$key=>$val) {134$lineX=$chartLeft+$lineWidth*$key+$lineWidth/3 - 20;135imagettftext($this->image,10,-65,$lineX,$lineY+15,$fontColor,$fontPath,$this->xdata[$key]);136}137138//两个系列数据以上时绘制小矩形及之后文字说明139if($ydataNum> 1) {140$x1=$lineChartWidth+$space;141$y1= 20;142foreach($this->seriesNameas$key=>$val) {143imagefilledrectangle($this->image,$x1,$y1,$x1+$recWidth,$y1+$recHeight,$color[$key%count($this->color)]);144imagettftext($this->image,10,0,$x1+$recWidth+5,$y1+$recHeight-2,$fontColor,$fontPath,$this->seriesName[$key]);145$y1+=$recHeight+ 10;146}147}148149//绘画标题150$titleStart= ($this->width - 5.5*strlen($this->title))/2;151imagettftext($this->image,11,0,$titleStart,20,$fontColor,$fontPath,$this->title);152153//输出图片154header("Content-Type:image/png");155imagepng ($this->image );156}157158159/*160* 私有方法,当数组为二元数组时,统计数组的长度161* Array arr 要做统计的数组162*/163privatefunctionarrayNum($arr) {164$num= 0;165if(is_array($arr)) {166$num++;167for($i= 0;$i<count($arr);$i++){168if(is_array($arr[$i])) {169$num=count($arr);170
break;171}172}173}174return$num;175}176177/*178* 私有方法,计算数组的深度179* Array arr 数组180*/181privatefunctionarrayDepth($arr) {182$num= 0;183if(is_array($arr)) {184$num++;185for($i= 0;$i<count($arr);$i++){186if(is_array($arr[$i])) {187$num+=$this->arrayDepth($arr[$i]);188
break;189}190}191}192return$num;193}194195/*196* 私有方法,找到一组中的最大值197* Array arr 数字数组198*/199privatefunctionarrayMax($arr) {200$depth=$this->arrayDepth($arr);201$max= 0;202if($depth== 1) {203rsort($arr);204$max=$arr[0];205}elseif($depth> 1) {206foreach($arras$val) {207if(is_array($val)) {208if($this->arrayMax($val) >$max) {209$max=$this->arrayMax($val);210}211}else{212if($val>$max){213$max=$val;214}215}216}217}218return$max;219}220221/*222* 私有方法,求数组的平均值223* Array arr 数字数组224*/225functionarrayAver($arr) {226$aver=array();227foreach($arras$val) {228if(is_array($val)) {229$aver=array_merge($aver,$val);230}else{231$aver[] =$val;232}233}234returnarray_sum($aver)/count($aver);235}236237/*238* 私有方法,求数组中元素长度最大的值239* Array arr 字符串数组,必须是汉字240*/241privatefunctionarrayLengthMax($arr) {242$length= 0;243foreach($arras$val) {244$length=strlen($val) >$length?strlen($val) :$length;245}246return$length/3;247}248249//析构函数250function__destruct(){251imagedestroy($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=newChart($title,$xdata,$ydata,$seriesName);7$Img->paintLineChart();
效果图如下: