使用PHP繪制統計圖


使用PHP畫統計圖的方法

第一種方法 

<?php
//最后一次修改:2004-6-21
//一個生成矩形圖,曲線圖的圖形分析類
//作者:tonera
//說明:
//任何人可在任何場合自由使用這個類。但由此所發生的損害跟作者無關。
//可根據數據自適應X和Y軸大小。
//在同一個圖形中可顯示多個曲線圖
//用戶可給出生成的圖的尺寸大小,數據參數。類根據數據的值來判斷生成的圖形的高(默認10格)和寬各分幾格。
//若用戶沒有給出圖的尺寸大小,則圖形高和寬為255像素
//數據參數通過一個方法add_data($array)來多次添加,每次一個數組。
//可自設定圖形邊框,矩形圖內線,深色邊框線,淺色邊框線,曲線,點的顏色。若用戶沒有指定,則為默認值
//set_colors方法設定不同曲線的不同色彩
//可進行圖形的疊加顯示:點,線,矩形
//注意:需要GD庫支持
/*
 //使用示例
 $gg=new build_graph();
 $d1=array(0,62,25,20,20,100,99);
 $d2=array(0,80,75,65,100,56,79);
 $d3=array(0,60,50,25,12,56,45);
 $gg->add_data($d1);
 $gg->add_data($d2);
 $gg->add_data($d3);
 $gg->set_colors("ee00ff,dd8800,00ff00");
 //生成曲線圖
 $gg->build("line",0);          //參數0表示顯示所有曲線,1為顯示第一條,依次類推
 //生成矩形圖
 //$gg->build("rectangle","2");    //參數0表示顯示第一個矩形,1也為顯示第一條,其余依次類推
 */

class build_graph {
        var $graphwidth = 300;
        var $graphheight = 300;
        var $width_num = 0;                //寬分多少等分
        var $height_num = 10;                //高分多少等分,默認為10
        var $height_var = 0;                //高度增量(用戶數據平均數)
        var $width_var=0;                //寬度增量(用戶數據平均數)
        var $height_max=0;                //最大數據值
        var $array_data=array();          //用戶待分析的數據的二維數組
        var $array_error=array();          //收集錯誤信息

        var $colorBg=array(255,255,255);    //圖形背景-白色
        var $colorGrey=array(192,192,192);    //灰色畫框
        var $colorBlue=array(0,0,255);       //藍色
        var $colorRed=array(255,0,0);       //紅色(點)
        var $colorDarkBlue=array(0,0,255);    //深色
        var $colorLightBlue=array(200,200,255);       //淺色
        var $colorLightBlack = array(138,138,120); //淺黑
        var $colorBlack = array(30,30,30); //
        var $rgbArray = array("ee00ff","dd8800","00ff00","104E8B");

        var $array_color;                //曲線着色(存儲十六進制數)
        var $image;                      //我們的圖像
        var $lineType = ''; //畫底線時標的數字值,則x的值,范圍為'day', 'hour'兩值
        var $beginDay = '';


        //方法:接受用戶數據
        function add_data($array_user_data, $dataKey = 0){
                if(!is_array($array_user_data)){
                        $array_user_data = array();
                }
                if(!is_array($array_user_data) or empty($array_user_data)){
                        $this->array_error['add_data']="沒有可供分析的數據";
                        return false;
                        exit();
                }
                if($dataKey == 0 || array_key_exists($dataKey, $this->array_data)){
                        $dataKey = count($this->array_data);
                }
                $this->array_data[$dataKey] = $array_user_data;
        }

        //方法:定義畫布寬和長
        function set_img($img_width,$img_height){
                $this->graphwidth = $img_width;
                $this->graphheight = $img_height;
        }

        //設定Y軸的增量等分,默認為10份
        function set_height_num($var_y){
                $this->height_num=$var_y;
        }

        //定義各圖形各部分色彩
        function get_RGB($color){             //得到十進制色彩
                $R=($color>>16) & 0xff;
                $G=($color>>8) & 0xff;
                $B=($color) & 0xff;
                return (array($R,$G,$B));
        }
        //---------------------------------------------------------------
        #定義背景色
        function set_color_bg($c1,$c2,$c3){
                $this->colorBg=array($c1,$c2,$c3);
        }
        #定義畫框色
        function set_color_Grey($c1,$c2,$c3){
                $this->colorGrey=array($c1,$c2,$c3);
        }
        #定義藍色
        function set_color_Blue($c1,$c2,$c3){
                $this->colorBlue=array($c1,$c2,$c3);
        }
        #定義色Red
        function set_color_Red($c1,$c2,$c3){
                $this->colorRed=array($c1,$c2,$c3);
        }
        #定義深色
        function set_color_DarkBlue($c1,$c2,$c3){
                $this->colorDarkBlue=array($c1,$c2,$c3);
        }
        #定義淺色
        function set_color_LightBlue($c1,$c2,$c3){
                $this->colorLightBlue=array($c1,$c2,$c3);
        }

        //設定畫底線時標的數字值,則x的值,范圍為'day', 'hour'兩值
        function  setLineStrinType($type){
                if(!in_array($type, array('day', 'hour'))){
                        return false;
                }
                $this->lineType = $type;
        }

        //---------------------------------------------------------------

        //方法:由用戶數據將畫布分成若干等份寬
        //並計算出每份多少像素
        function get_width_num(){
                $dataCount = array();
                foreach ($this->array_data as $key => $oneData){
                        $dataCount[] = count($oneData);
                }

                $this->width_num = max($dataCount);
        }
        function get_max_height(){
                //獲得用戶數據的最大值
                $tmpvar = array();
                foreach($this->array_data as $tmp_value){
                        $tmpvar[]= max($tmp_value);
                }
                if(isset($tmpvar[0])){
                        $more = $tmpvar[0];
                }
                $this->height_max = max($tmpvar) + $this->height_var;
                return max($tmpvar);
        }
        function get_height_length(){
                //計算出每格的增量長度(用戶數據,而不是圖形的像素值)
                $max_var = $this->get_max_height();
                $max_var = round($max_var/$this->height_num);
                $first_num = substr($max_var,0,1);
                if(substr($max_var,1,1)){
                        if(substr($max_var,1,1)>=5)
                        $first_num += 1;
                }
                for($i = 1; $i < strlen($max_var); $i++){
                        $first_num .= "0";
                }
                return (int)$first_num;
        }
        function get_var_wh(){          //得到高和寬的增量
                $this->get_width_num();
                //得到高度增量和寬度增量
                $this->height_var = $this->get_height_length();
                $this->width_var = round($this->graphwidth/$this->width_num, 3);
        }

        function set_colors($str_colors){
                //用於多條曲線的不同着色,如$str_colors="ee00ff,dd0000,cccccc"
                $this->array_color = split(",",$str_colors);
        }

        function set_begin_day($beginDay){
                if(!is_numeric($beginDay)){
                        return false;
                }
                $this->beginDay = $beginDay;
        }

        ######################################################################################################
        function build_line($var_num){
                if(!empty($var_num)){                   //如果用戶只選擇顯示一條曲線
                        $array_tmp[0] = $this->array_data[$var_num-1];
                        $this->array_data = $array_tmp;
                }

                for($j=0;$j<count($this->array_data);$j++){
                        list($R,$G,$B)=$this->get_RGB(hexdec($this->array_color[$j]));
                        $colorBlue=imagecolorallocate($this->image,$R,$G,$B);

                        for($i = 0;$i < $this->width_num - 1;$i++){
                                $height_pix = round(($this->array_data[$j][$i]/$this->height_max)*$this->graphheight);
                                $height_next_pix = round($this->array_data[$j][$i + 1]/$this->height_max*$this->graphheight);
                                imageline($this->image,$this->width_var*($i + 1),$this->graphheight-$height_pix,$this->width_var*($i + 2),$this->graphheight-$height_next_pix,$colorBlue);
                        }
                }
                //畫點
                $colorRed = imagecolorallocate($this->image, $this->colorBlue[0], $this->colorBlue[1], $this->colorBlue[2]);
                 
                for($j = 0; $j < count($this->array_data); $j++){
                        list($R,$G,$B) = $this->get_RGB(hexdec($this->array_color[$j]));
                        $colorPoint = imagecolorallocate($this->image,$R,$G,$B);

                        for($i = 0; $i < $this->width_num; $i++){
                                if(isset($this->array_data[$j][$i])){
                                        $height_pix = round(($this->array_data[$j][$i]/$this->height_max)*$this->graphheight);
                                        $arcRet = imagearc($this->image,$this->width_var*($i + 1),$this->graphheight-$height_pix,6,5,0,360,$colorPoint);
                                        $borderRet = imagefilltoborder($this->image,$this->width_var*($i + 1),$this->graphheight-$height_pix,$colorPoint,$colorPoint);
                                        if(!$arcRet || !$borderRet){
                                                break;
                                        }
                                }
                        }
                }

                for($j = 0; $j < count($this->array_data); $j++){
                        list($R,$G,$B) = $this->get_RGB(hexdec($this->array_color[$j]));
                        $colorPoint = imagecolorallocate($this->image,$R,$G,$B);
                        for($i = 0; $i < $this->width_num; $i++){
                                $height_pix = round(($this->array_data[$j][$i]/$this->height_max) * $this->graphheight);
                                $arcRet = imagearc($this->image,$this->width_var*($i + 1),$this->graphheight-$height_pix,6,5,0,360,$colorPoint);
                                $arcRet = imagefilltoborder($this->image,$this->width_var*($i + 1),$this->graphheight-$height_pix,$colorPoint,$colorPoint);
                                if(!$arcRet || !$borderRet){
                                        break;
                                }
                        }
                }
                 
        }

        ######################################################################################################
        function build_rectangle($select_gra){
                if(!empty($select_gra)){                   //用戶選擇顯示一個矩形
                        $select_gra-=1;
                }
                //畫矩形
                //配色
                $colorDarkBlue=imagecolorallocate($this->image, $this->colorDarkBlue[0], $this->colorDarkBlue[1], $this->colorDarkBlue[2]);
                $colorLightBlue=imagecolorallocate($this->image, $this->colorLightBlue[0], $this->colorLightBlue[1], $this->colorLightBlue[2]);

                if(empty($select_gra))
                $select_gra=0;
                for($i=0; $i<$this->width_num; $i++){
                        $height_pix=round(($this->array_data[$select_gra][$i]/$this->height_max)*$this->graphheight);
                        imagefilledrectangle($this->image,$this->width_var*$i,$this->graphheight-$height_pix,$this->width_var*($i+1),$this->graphheight, $colorDarkBlue);
                        imagefilledrectangle($this->image,($i*$this->width_var)+1,($this->graphheight-$height_pix)+1,$this->width_var*($i+1)-5,$this->graphheight-2, $colorLightBlue);
                }
        }

        ######################################################################################################
        function create_cloths(){
                //創建畫布
                $this->image = imagecreate($this->graphwidth+20,$this->graphheight+20);
        }
        function create_frame(){
                //創建畫框
                $this->get_var_wh();
                //配色
                $colorBg=imagecolorallocate($this->image, $this->colorBg[0], $this->colorBg[1], $this->colorBg[2]);
                $colorGrey=imagecolorallocate($this->image, $this->colorGrey[0], $this->colorGrey[1], $this->colorGrey[2]);
                //創建圖像周圍的框
                imageline($this->image, 0, 0, 0, $this->graphheight,$colorGrey);
                imageline($this->image, 0, 0, $this->graphwidth, 0,$colorGrey);
                //imageline($this->image, ($this->graphwidth-1),0,($this->graphwidth-1),($this->graphheight-1),$colorGrey);
                imageline($this->image, 0,($this->graphheight-1),($this->graphwidth-1),($this->graphheight-1),$colorGrey);
        }
        function create_line(){
                //創建網格。
                $this->get_var_wh();
                $colorBg = imagecolorallocate($this->image, $this->colorBg[0], $this->colorBg[1], $this->colorBg[2]);
                $colorGrey = imagecolorallocate($this->image, $this->colorGrey[0], $this->colorGrey[1], $this->colorGrey[2]);
                $colorRed = imagecolorallocate($this->image, $this->colorRed[0], $this->colorRed[1], $this->colorRed[2]);
                $colorLightBlack = imagecolorallocate($this->image, $this->colorLightBlack[0], $this->colorLightBlack[1], $this->colorLightBlack[2]);
                $colorBlack = imagecolorallocate($this->image, $this->colorBlack[0], $this->colorBlack[1], $this->colorBlack[2]);
                for($i = 1 ;$i <= $this->height_num + 5; $i++){
                        //畫橫線
                        imageline($this->image,0,$this->graphheight-($this->height_var/$this->height_max*$this->graphheight)*$i,$this->graphwidth,$this->graphheight-($this->height_var/$this->height_max*$this->graphheight)*$i,$colorGrey);
                        //標出數字
                        imagestring($this->image,2,0,$this->graphheight-($this->height_var/$this->height_max*$this->graphheight)*$i,$this->height_var*$i,$colorLightBlack);
                }
                $type = $this->lineType;
                if($type == "day"){
                        if($this->beginDay){
                                $j = $this->beginDay;
                        }else{
                                $j = 1;
                        }
                }elseif($type == "hour"){
                        $j = 0;
                }
                for($i = 1;$i <= $this->width_num; $i++){
                        //畫豎線
                        imageline($this->image,$this->width_var*$i,0,$this->width_var*$i,$this->graphwidth,$colorGrey);
                        //標出數字
                        if($type == 'day'){
                                if($i == 1){
                                        imagestring($this->image,2,$this->width_var*$i,$this->graphheight-15,$j,$colorBlack);
                                }
                                imagestring($this->image,2,$this->width_var*($i + 1),$this->graphheight-15,$j + 1,$colorBlack);
                        }elseif($type == 'hour'){
                                if($i == 1){
                                        imagestring($this->image,2,$this->width_var*$i,$this->graphheight-15,$j,$colorBlack);
                                }
                                imagestring($this->image,2,$this->width_var*($i + 1),$this->graphheight-15,$j + 1,$colorBlack);
                        }else{
                                imagestring($this->image,2,$this->width_var*($i + 1),$this->graphheight-15,$i,$colorBlack);
                        }
                        $j++;
                        if($type == "day" && $j == 31){
                                 $j = 1;
                        }elseif($type == "hour" && $j == 23){
                                $j = -1;
                        }
                }
        }

        function build($graph,$str_var, $outpwd = ""){
                //$graph是用戶指定的圖形種類,$str_var是生成哪個數據的圖
                if(empty($outpwd)){
                        header("Content-type: image/jpeg");
                }
                $this->create_cloths();          //先要有畫布啊~~
                switch ($graph){
                        case "line":
                                $this->create_frame();          //畫個框先:)
                                $this->create_line();          //打上底格線
                                $this->build_line($str_var);          //畫曲線
                                break;
                        case "rectangle":
                                $this->create_frame();                   //畫個框先:)
                                $this->build_rectangle($str_var);          //畫矩形
                                $this->create_line();                   //打上底格線
                                break;
                }
                //輸出圖形並清除內存
                if(!empty($outpwd)){
                        imagepng($this->image, $outpwd);
                }else{
                        imagepng($this->image);
                }
                imagedestroy($this->image);
        }

        ######################################################################################################

}
View Code

 

 

第二種是用開源工具jpgraph,參見 http://jpgraph.net/features

 

Chart Gallery

 

General features

Below is a number of "one-liners" that describe some of the general features available in JpGraph.

  • Anti-aliasing for Pie charts.
  • More advanced formatting of graph titles including 3D Bevel effects.
  • Additional 3D Bevel formatting feature for the entire Graph
  • Gradient fills for bars are now also displayed in the legend
  • Improvements on legend formatting. It is now possible to have several columns in the legend
  • Improved callback capability for Plot marks. The new callbacks will provide both X and Y coordinates.
  • Footer text can now be used on all graph types
  • dded possibility to use the Freely available Vera TTF fonts. These fonts are available from http://www.gnome.org/fonts/
  • Built in rotation of graphs
  • Fine tuning of legend layout, size and positioning of individual legends and markers.
  • Added possibility to use object methods as callbacks and not only static global functions
  • Full support for color alpha blending
  • Automatic generation of client side image maps to make it possible to generate drill-down graphs.
  • Advanced interpolation with cubic splines to get smooth curves from just a few data points.
  • Several different fill styles for line plots
  • Advanced image 3D effects built-in without external image manipulation programs
  • Supports unlimited number of plots in each graph, makes it easy to compose complex graph which consists of several plot types
  • Additional built-in images for plot marks including 3D rendered markers like diamonds, squares, bevels, balls, pins etc
  • Text strings can now be added to the plot using scale coordinates
  • Support for all primitive URL parameter types with CSIM graphs.
  • Autoscaling will now also consider added lines and texts.
  • Hare/Niemeyer Integer compensation for Pie Plots
  • Added the possibility to use Vertical Gradient fill for line plots.
  • Improved error handling. The visual appearance of the error handling now tries to mimic any windows system window (in graphic)
  • Builtin support to display over 200 country flag and the possibility to use them as icons or markers in the graphs. All the flag images are builtin with JpGraph in an efficient pre-compiled data format.
  • Supports caching (with timeout) of generated graphs to lessen burden of a HTTP server.
  • Intelligent autoscaling which gravitates towards aesthetical values.
  • Fully supports manual scaling, with fine grain control of position of ticks
  • Supports color-gradient fill for bar graphs
  • Supports both vertical and horizontal grids (with image depth specification)
  • Supports both on-the fly image generation and batch processing.
  • Extensive documentation
  • Advanced text formatting using TTF fonts
  • Support for both Chinese and Japanes character sets 

非常多的例子,很好的。

 

第三種用 open flash chart,參見

http://teethgrinder.co.uk/open-flash-chart/gallery-data.php
http://www.helloweba.com/view-blog-41.html
http://www.phphi.cn/post/98/
http://blogold.chinaunix.net/u3/105169/showart_2322209.html
http://hi.baidu.com/duwuzhe722/blog/item/e11b2d2662b512038b82a175.html

 

第四種使用amcharts,參見http://www.amcharts.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM