hyadijxp 发表于 2015-8-28 13:16:28

用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-$box);
                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-$box);
                  $texheight=abs($box-$box);
                  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-$box);
                  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,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,12) as $mon){
    $bardata=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);
?>
页: [1]
查看完整版本: 用PHP生成图表