用PHP生成图表

功能还比较简单,有兴趣可以随便扩展
<?php
class MultiGraph{
    
public $border_color;
    
public $grid_color;
    
public $data_color;
    
public $g;
    
public $data;
    
public $draw_border=true;
    
public $horizontal_grid_segments=5;
    
public $vertical_grid_segments=0;
    
public $x=0;
    
public $y=0;
    
public $w=200;
    
public $h=100;
    
public $point_size=5;
    
public $y_axis_autolabel=true;
    
public $x_axis_autolabel=true;
    
public $font='arial.ttf';
    
public $fontsize=8;
    
public function __construct($graphics){
        
$this->g=$graphics;
        imageantialias(
$this->g,true);
    }
    
public function setDimensions($x,$y,$w,$h){
        
$this->x=$x;
        
$this->y=$y;
        
$this->w=$w;
        
$this->h=$h;
    }
    
public function drawLineGraph(){
        
$this->_drawborder();
        
$yscale=$this->_calcYscale();
        
$xscale=$this->_calcXscale();
        
$this->_drawHorizontal();
        
$this->_drawVertical();
        
$tmpdata=$this->data;
        
ksort($tmpdata);
        
list($ldx,$ldy)=each($tmpdata);
        
while (list($dx,$dy)=each($tmpdata)) {
            imageline(
$this->g,
                
$this->x+$ldx*$xscale,
                
$this->y+$this->y-$ldx*$yscale,
                
$this->x+$dx*$xscale,
                
$this_>y+$this->y-$dy*$yscale,
                
$this->data_color);
            
$ldx=$dx;
            
$ldy=$dy;
        }
    }
    
public function drawPointGraph(){
        
$this->_drawBorder();
        
$yscale=$this->_calcYscale();
        
$xscale=$this->_calcXscale();
        
$this->_drawHorizontal();
        
$this->_drawVertical();
        
foreach ($this->data as $dx=>$dy){
            imagefilledellipse(
$this->g,
                
$this->x+$dx*$xscale,
                
$this->y+$this->h-$dy*$yscale,
                
$this->point_size,
                
$this->point_size,
                
$this->data_color);
        }
    }
    
public function drawBarGraph(){
        
$this->_drawBorder();
        
$yscale=$this->_calcYscale();
        
$this->_drawHorizontal();
        
$section=(float)$this->w/count($this->data);
        
$bar=(int)($section*0.7);
        
$count=0;
        
foreach ($this->data as $label=>$val){
            
$count++;
            imagefilledrectangle(
$this->g,
                
$this->x+($section*$count)-$bar,
                
$this->y+$this->h,
                
$this->x+($section*$count),
                
$this->y+$this->h-$val*$yscale,
                
$this->data_color);
            imagerectangle(
$this->g,
                
$this-x+($section*$count)-$bar,
                
$this->y+$this->h,
                
$this->x+($section*$count),
                
$this->y+$this->h-$val*$yscale,
                
$this->border_color);
            
if ($this->x_axis_autolabel) {
                
$box=imagettfbbox($this->fontsize,270,$this->font,$label);
                
$texwidth=abs($box[4]-$box[0]);
                imagettftext(
$this->g,
                    
$this->fontsize,270,
                    (
$this->x+($section*$count)-($bar/2)-($texwidth/2)),
                    
$this->y+$this_>h+4,
                    
$this->border_color,
                    
$this->font,
                    
$label);
            }
        }
    }
    
private function _drawBorder(){
        
if ($this->draw_border) {
            imageline(
$this->g,
                
$this->x,
                
$this->y,
                
$this->x,
                
$this->h+$this->y,
                
$this->border_color);
            imageline(
$this->g,
                
$this->x,
                
$this->h+$this->y,
                
$this->w+$this->x,
                
$this->h+$this->y,
                
$this->border_color);
        }
    }
    
private function _calcYscale(){
        
return (float)$this->h/$this->_calcYMax();
    }
    
private function _calcXscale(){
        
return (float)$this->w/$this->_calcXMax();
    }
    
private function _calcYMax(){
        
$max=(float)max($this->data)*1.05;
        
$len=(float)((int)$max);
        
if ($len<2) {
            
return $max;
        }
else {
            
return intval(substr($max,0,2).str_repeat('0',$len-2));
        }
    }
    
private function _calcXMax(){
        
return max(array_keys($this->data));
    }
    
private function _drawHorizontal(){
        
if ($this->horizontal_grid_segments) {
            
foreach (range(1,$this->horizontal_grid_segments) as $hg){
                
$yheight=(int)$this->y+$this->h-($hg*($this->h/$this->horizontal_grid_segments));
                imageline(
$this->g,
                    
$this->x+1,
                    
$yheight,
                    
$this->w+$this-x,
                    
$yheight,
                    
$this->grid_color);
                
if ($this->y_axis_autolabel) {
                    
$ax_step=(int)($this->_calcYMax()/$this->horizontal_grid_segments)*$hg;
                    
$box=imagettfbbox($this->fontsize,0,
                        
$this->font,$ax_step);
                    
$texwidth=abs($box[4]-$box[0]);
                    
$texheight=abs($box[5]-$box[1]);
                    imagettftext(
$this->g,
                        
$this->fontsize,0,
                        
$this->x-3-$texwidth,
                        
$yheight+$texheight/2,
                        
$this->border_color,
                        
$this->font,
                        
$ax_step);
                }
            }
        }
    }
    
private function _drawVertical(){
        
if ($this->vertical_grid_segments) {
            
foreach (range(1,$this->vertical_grid_segments) as $vg){
                
$xloc=(int)($this->x+($vg*($this->w/$this->vertical_grid_segments)));
                imageline(
$this->g,
                    
$xloc,
                    
$this->y,
                    
$xloc,
                    
$this->y+$this->h-1,
                    
$this->grid_color);
                
if ($this->x_axis_autolabel) {
                    
$ax_step=(int)(($this->_calcXMax()/$this->vertical_grid_segments)*$vg);
                    
$box=imagettfbbox($this->fontsize,270,$this->font,$ax_step);
                    
$texwidth=abs($box[4]-$box[0]);
                    imagettftext(
$this->g,
                        
$this->fontsize,270,
                        
$xloc-$texwidth/2,
                        
$this->y+$this->h+3,
                        
$this->border_color,
                        
$this->font,
                        
$ax_step);
                }
            }
        }
    }
}
?>

实例:

<?php
require_once('MultiGraph.php');
$gfx=imagecreatetruecolor(950,650);
$red=imagecolorallocate($gfx,255,0,0);
$manilla=imagecolorallocate($gfx,255,255,245);
$black=imagecolorallocate($gfx,0,0,0);
$lgray=imagecolorallocate($gfx,200,200,200);
imagefill(
$gfx,0,0,$manilla);
$graph=new MultiGraph($gfx);
$graph->border_color=$black;
$graph->grid_color=$lgray;
$graph->data_color=$red;
$graph->vertical_grid_segments=10;
$graph->font='MSYH.ttf';
$chartdata=array();
for ($i=0;$i<50;$i++){
    
$chartdata[rand(1,200)]=rand(1,1000);
}
$graph->data=$chartdata;
$graph->setDimensions(50,50,300,200);
$graph->drawLineGraph();
$graph->horizontal_grid_segments=9;
$graph->vertical_grid_segments=15;
$graph->setDimensions(50,350,300,200);
$graph->drawPointGraph();
$bardata=array();
foreach (range(1,12as $mon){
    
$bardata[date('F',mktime(0,0,0,$mon))]=rand(1,5000);
}
$cyan=imagecolorallocate($gfx,0,255,255);
$graph->data_color=$cyan;
$graph->fontsize=11;
$graph->horizontal_grid_segments=12;
$graph->setDimensions(450,40,400,500);
$graph->data=$bardata;
$graph->drawBarGraph();
header('Content-type:image/png');
imagepng(
$gfx);
?>
posted @ 2008-06-17 09:22  !星期八  阅读(1970)  评论(0编辑  收藏  举报