<?php
/*
+-----------------------------------------------------------------------------+
| $Id: bwcurve.class.php 2008-10-16 13:14:20Z Bleakwind $
| Curve picture
| Copyright (c) 2003-2010 Bleakwind (www.weaverdream.com)
| http://www.weaverdream.com/
| Release under the GNU Lesser General Public License Version 3 (LGPLv3):
|   http://www.gnu.org/licenses/lgpl.html
+-----------------------------------------------------------------------------+
*/

Class bwcurve{

    var $image;

    var $image_width;
    var $image_height;
    var $image_type; // [jpg|gif|png]

    var $curve_width;
    var $curve_height;
    var $curve_top;
    var $curve_side;
    var $curve_which = "right"; // right,left
    var $curve_curvewidth;
    var $curve_bgcolor;
    var $curve_gridcolor;

    var $bgcolor;
    var $fontfamily;
    var $fontsize;
    var $fontcolor;

    var $return_type; // [column_erect:竖柱形图 | column_transverse:横柱形图 | line:折线图]

    var $label_offset_curve = 2;
    var $label_offset_x = 26;
    var $label_offset_y = 30;

    var $labeltype_curve; // 图标签类型 [number | percent | all | false]
    var $labeltype_x; // X轴标签类型 [number | true | false]
    var $labeltype_x_type; // X轴标签类型 [label | list]
    var $labeltype_y; // Y轴标签类型 [number | percent | all | false]

    var $number_sum;
    var $number_array;
    var $number_array_percent;
    var $number_array_all;
    var $number_array_y;
    var $number_array_percent_y;
    var $number_array_all_y;
    var $array_label;
    var $array_label_number;
    var $array_label_percent;
    var $array_label_all;
    var $array_color;

    var $chinese;
    var $chinese_fontfamily;
    var $chinese_color;
    var $chinese_size;
    var $chinese_left;
    var $chinese_top;

    var $english;
    var $english_fontfamily;
    var $english_color;
    var $english_left;
    var $english_top;

    var $copyimage;
    var $copyimage_width;
    var $copyimage_left;
    var $copyimage_top;

    var $curve_widthnumber;
    var $curve_heightnumber = 5;
    var $curve_perwidth;
    var $curve_perheight;

    var $data_max;
    var $x1;

    function Curve($image_width,$image_height)
    {
        $this->image_width  = $image_width;
        $this->image_height = $image_height;
    }

    /*
    +-----------------------------------------------------------------------------+
    | General
    +-----------------------------------------------------------------------------+
    */
    function set_curve($curve_width,$curve_height)
    {
        $this->curve_width  = $curve_width;
        $this->curve_height = $curve_height;
    }

    function set_imagetype($image_type)
    {
        if(preg_match("/^(jpg|gif|png)$/i",$image_type)){
            $this->image_type   = $image_type;
        } else {
            $this->image_type   = "png";
        }
    }

    function set_bgcolor($color)
    {
        if(strlen($color) == 7){
            $color = substr($color, 1);
        }
        if(!preg_match("/^[0-9a-f]{6}$/i",$color)){
            $color = "000000";
        }
        $this->bgcolor = $this->color_hexdec($color);
    }

    function set_font($fontfamily,$fontsize,$fontcolor)
    {
        $this->fontfamily = $fontfamily;
        $this->fontsize   = $fontsize;
        if(strlen($fontcolor) == 7){
            $fontcolor = substr($fontcolor, 1);
        }
        if(!preg_match("/^[0-9a-f]{6}$/i",$fontcolor)){
            $fontcolor = "000000";
        }
        $this->fontcolor  = $this->color_hexdec($fontcolor);
    }

    function set_chinese($chinese,$chinese_fontfamily,$chinese_color,$chinese_size,$chinese_left,$chinese_top)
    {
        $this->chinese[]            = $chinese;
        $this->chinese_fontfamily[] = $chinese_fontfamily;
        $this->chinese_color[]      = $this->color_hexdec($chinese_color);
        $this->chinese_size[]       = $chinese_size;
        $this->chinese_left[]       = $chinese_left;
        $this->chinese_top[]        = $chinese_top;
    }

    function set_english($english,$english_fontfamily,$english_color,$english_left,$english_top)
    {
        $this->english[]            = $english;
        $this->english_fontfamily[] = $english_fontfamily;
        $this->english_color[]      = $this->color_hexdec($english_color);
        $this->english_left[]       = $english_left;
        $this->english_top[]        = $english_top;
    }

    function set_copyimage($copyimage,$copyimage_width,$copyimage_left,$copyimage_top)
    {
        $this->copyimage[]        = $copyimage;
        $this->copyimage_width[]  = $copyimage_width;
        $this->copyimage_left[]   = $copyimage_left;
        $this->copyimage_top[]    = $copyimage_top;
    }

    function write_chinese()
    {
        if (count($this->chinese) > 0) {
            foreach($this->chinese as $key => $value){
                $color = imagecolorallocate($this->image,$this->chinese_color[$key]['r'],
                                                         $this->chinese_color[$key]['g'],
                                                         $this->chinese_color[$key]['b']);
                imagettftext($this->image,
                             $this->chinese_size[$key],
                             0,
                             $this->chinese_left[$key],
                             $this->chinese_top[$key],
                             $color,
                             $this->chinese_fontfamily[$key],
                             $this->chinese[$key]);
            }
        }
    }

    function write_english()
    {

        if (count($this->english) > 0) {
            foreach($this->english as $key => $value){

                $color = imagecolorallocate($this->image,$this->english_color[$key]['r'],
                                                         $this->english_color[$key]['g'],
                                                         $this->english_color[$key]['b']);
                if(preg_match("/^[1-5]{1}$/",$this->english_fontfamily[$key])) {
                    $font = $this->english_fontfamily[$key];
                }else{
                    $font = imageloadfont($this->english_fontfamily[$key]);
                }
                imagestring($this->image,
                    $font,
                    $this->english_left[$key],
                    $this->english_top[$key],
                    $this->english[$key],
                    $color);
            }
        }
    }

    function write_copyimage()
    {

        foreach($this->copyimage as $key => $value){
            list($copyimage_width, $copyimage_height, $copyimage_type, $copyimage_attr) = @getimagesize($this->copyimage[$key]);
            $height = (int)(($this->copyimage_width[$key] / $copyimage_width) * $copyimage_height);
            $thecopy_type   = getimagesize($this->copyimage[$key]);
            if ($thecopy_type[2] == "1") {
                $function_creat = "imagecreatefromgif";
            } elseif ($thecopy_type[2] == "2") {
                $function_creat = "imagecreatefromjpeg";
            } elseif ($thecopy_type[2] == "3") {
                $function_creat = "imagecreatefrompng";
            } else {
                $function_creat = "imagecreatefrompng";
            }
            $thecopy        = $function_creat($this->copyimage[$key]);
            imagecopyresampled($this->image, $thecopy, $this->copyimage_left[$key], $this->copyimage_top[$key], 0, 0, $this->copyimage_width[$key], $height, $copyimage_width, $copyimage_height);
        }
    }

    // Return a 16 color to a 10 color
    function color_hexdec($color)
    {
        if(!preg_match("/^[a-z0-9]{6}$/i",$color)) {
            return false;
        }
        $color_array['r'] = hexdec(substr($color,0,2));
        $color_array['g'] = hexdec(substr($color,2,2));
        $color_array['b'] = hexdec(substr($color,4,2));
        return $color_array;
    }
    //////

    /*
    +-----------------------------------------------------------------------------+
    | Curve
    +-----------------------------------------------------------------------------+
    */
    function set_curve_place($curve_top,$curve_side,$curve_which="right")
    {
        $this->curve_top   = $curve_top;
        $this->curve_side  = $curve_side;
        $this->curve_which = $curve_which;
    }

    function set_curve_curvewidth($curve_curvewidth)
    {
        $this->curve_curvewidth = $curve_curvewidth;
    }

    function set_curve_bgcolor($color)
    {
        if(strlen($color) == 7){
            $color = substr($color, 1);
        }
        if(!preg_match("/^[0-9a-f]{6}$/i",$color)){
            $color = "000000";
        }
        $this->curve_bgcolor = $this->color_hexdec($color);
    }

    function set_curve_gridcolor($color)
    {
        if(strlen($color) == 7){
            $color = substr($color, 1);
        }
        if(!preg_match("/^[0-9a-f]{6}$/i",$color)){
            $color = "000000";
        }
        $this->curve_gridcolor = $this->color_hexdec($color);
    }

    function set_data($array_data,$array_label,$array_color)
    {
        $number_sum           = array_sum($array_data);
        $number_max           = max($array_data);
        $number_array         = array();
        $number_array_percent = array();
        $number_array_all     = array();
        $array_label_number   = array();
        $array_label_percent  = array();
        $array_label_all      = array();
        foreach($array_data as $key => $value){
            $number_array[$key]         = $value;
            $number_array_percent[$key] = round($number_array[$key]/$number_sum*100)."%";
            $number_array_all[$key]     = $number_array[$key]."(".$number_array_percent[$key].")";
            $array_label_number[$key]   = $array_label[$key]." ".$number_array[$key];
            $array_label_percent[$key]  = $array_label[$key]." ".$number_array_percent[$key];
            $array_label_all[$key]      = $array_label[$key]." ".$number_array_all[$key];
        }
        $this->number_sum           = $number_sum;
        $this->number_max           = $number_max;
        $this->number_array         = $number_array;
        $this->number_array_percent = $number_array_percent;
        $this->number_array_all     = $number_array_all;
        $this->array_label          = $array_label;
        $this->array_label_number   = $array_label_number;
        $this->array_label_percent  = $array_label_percent;
        $this->array_label_all      = $array_label_all;
        $this->array_color          = $array_color;
    }

    // $return_type [column_erect:竖柱形图 | column_transverse:横柱形图 | line:折线图]
    // $labeltype_curve [number | percent | all | false]
    function set_returntype($return_type,$labeltype_curve,$space)
    {
        $this->return_type = $return_type;
        if($labeltype_curve == "number"){
            $this->labeltype_curve    = $this->number_array;
            $this->label_offset_curve = $space;
        }elseif($labeltype_curve == "percent"){
            $this->labeltype_curve    = $this->number_array_percent;
            $this->label_offset_curve = $space;
        }elseif($labeltype_curve == "all"){
            $this->labeltype_curve    = $this->number_array_all;
            $this->label_offset_curve = $space;
        }else{
            $this->labeltype_curve = false;
        }
    }

    // $labeltype_x [number | true | false]
    function set_labeltype_x($labeltype_x,$space,$type="percent")
    {
        if( $labeltype_x == "label"){
            $this->labeltype_x      = $this->array_label;
            $this->label_offset_x   = $space;
            $this->labeltype_x_type = "label";
        }elseif( $labeltype_x == "list"){
            if($type == "number"){
                $this->labeltype_x = $this->array_label_number;
            }elseif($type == "percent"){
                $this->labeltype_x = $this->array_label_percent;
            }elseif($type == "all"){
                $this->labeltype_x = $this->array_label_all;
            }else{
                $this->labeltype_x = $this->array_label;
            }
            $this->label_offset_x   = $space;
            $this->labeltype_x_type = "list";
        }else{
            $this->labeltype_x = false;
        }
    }

    // $labeltype_y [number | percent | all | false]
    function set_labeltype_y($labeltype_y,$space)
    {

        $number_array_y         = array();
        $number_array_percent_y = array();
        $number_array_all_y     = array();
        $height_per             = $this->number_max/($this->curve_heightnumber-1);
        $height_top             = $height_per*$this->curve_heightnumber;
        for($i=0;$i<=$this->curve_heightnumber;$i++){
            $number_array_y[$i]         = round($height_top - $height_per*$i);
            $number_array_percent_y[$i] = round($number_array_y[$i]/$this->number_sum*100)."%";
            $number_array_all_y[$i]     = $number_array_y[$i]."(".$number_array_percent_y[$i].")";
        }
        $this->number_array_y         = $number_array_y;
        $this->number_array_percent_y = $number_array_percent_y;
        $this->number_array_all_y     = $number_array_all_y;

        if($labeltype_y == "number"){
            $this->labeltype_y    = $this->number_array_y;
            $this->label_offset_y = $space;
        }elseif($labeltype_y == "percent"){
            $this->labeltype_y    = $this->number_array_percent_y;
            $this->label_offset_y = $space;
        }elseif($labeltype_y == "all"){
            $this->labeltype_y    = $this->number_array_all_y;
            $this->label_offset_y = $space;
        }else{
            $this->labeltype_y = false;
        }
    }

    function write_gridding()
    {
        if($this->curve_which == "right"){
            $this->x1 = $x1 = $this->image_width-$this->curve_side-$this->curve_width;
        }else{
            $this->x1 = $x1 = $this->curve_side;
        }
        $y1 = $this->curve_top;
        $x2 = $x1+$this->curve_width;
        $y2 = $y1+$this->curve_height;
        imagefilledrectangle($this->image,$x1+1,$y1+1,$x2-1,$y2-1,$this->curve_bgcolor);

        $this->curve_widthnumber = count($this->number_array)+1;
        $this->curve_perwidth    = $this->curve_width/$this->curve_widthnumber;
        $this->curve_perheight   = $this->curve_height/$this->curve_heightnumber;

        for($i=0;$i<=$this->curve_widthnumber;$i++){
            imageline($this->image,
                      $x1+$i*$this->curve_perwidth,
                      $y2-2,
                      $x1+$i*$this->curve_perwidth,
                      $y2+2,
                      $this->fontcolor);
            imageline($this->image,
                      $x1+$i*$this->curve_perwidth,
                      $y1,
                      $x1+$i*$this->curve_perwidth,
                      $y2,
                      $this->curve_gridcolor);
        }
        //func::fp($this->labeltype_x);
        for($i=0;$i<=$this->curve_heightnumber;$i++){
            imageline($this->image,
                      $x1-2,
                      $y1+$i*$this->curve_perheight,
                      $x1+2,
                      $y1+$i*$this->curve_perheight,
                      $this->fontcolor);
            imageline($this->image,
                      $x1,
                      $y1+$i*$this->curve_perheight,
                      $x2,
                      $y1+$i*$this->curve_perheight,
                      $this->curve_gridcolor);
            if($this->labeltype_y !== false){
                imagestring($this->image,
                            2,
                            $x1-$this->label_offset_y,
                            $y1+$i*$this->curve_perheight-7,
                            $this->labeltype_y[$i],
                            $this->fontcolor);
            }
        }
        imagerectangle($this->image,$x1,$y1,$x2,$y2,$this->fontcolor);
    }

    // 竖柱形图
    function write_column_erect()
    {

        for($i=0;$i<$this->curve_widthnumber-1;$i++){
            $color  = $this->color_hexdec($this->array_color[$i]);
            $color  = ImageColorAllocate($this->image,$color['r'],$color['g'],$color['b']);
            $x1 = $this->x1+($this->curve_perwidth-$this->curve_curvewidth/2)+$this->curve_perwidth*$i;
            $y1 = ($this->curve_top+$this->curve_height)-$this->curve_perheight*($this->curve_heightnumber-1)*($this->number_array[$i]/$this->number_max);
            $x2 = $this->x1+($this->curve_perwidth-$this->curve_curvewidth/2)+$this->curve_curvewidth+$this->curve_perwidth*$i;
            $y2 = $this->curve_top+$this->curve_height-1;
            imagefilledrectangle($this->image,$x1,$y1,$x2,$y2,$color);
            if($this->labeltype_curve !== false){
                imagestring($this->image,2,$x1,$y1-14,$this->labeltype_curve[$i],$this->fontcolor);
            }
            if($this->labeltype_x_type == "label"){
                $x1_label = $x1;
                $y1_label = $this->curve_top+$this->curve_height+$this->label_offset_x;
                imagettftext($this->image,$this->fontsize,0,$x1_label,$y1_label+12,$this->fontcolor,$this->fontfamily,$this->array_label[$i]);
            }elseif($this->labeltype_x_type == "list"){
                $x1_label = $this->x1;
                $y1_label = $this->curve_top+$this->curve_height+$this->label_offset_x+$i*15;
                $x2_label = $this->x1+6;
                $y2_label = $this->curve_top+$this->curve_height+$this->label_offset_x+$i*15+12;
                imagefilledrectangle($this->image,$x1_label,$y1_label,$x2_label,$y2_label,$color);
                imagettftext($this->image,$this->fontsize,0,$x1_label+9,$y1_label+12,$this->fontcolor,$this->fontfamily,$this->labeltype_x[$i]);
            }
        }
    }

    // 横柱形图
    function write_column_transverse()
    {
        $number_data=count($this->number_array);
        $item_max=0;
        for ($i=0;$i<$number_data;$i++){
            $item_max=Max($item_max,$this->number_array[$i]);
        }
        $yy=$this->image_height-$this->curve_side*2;
        for ($i=0;$i<$number_data;$i++){
            if($this->bgcolor['r']!=255 && $this->bgcolor['g']!=255 && $this->bgcolor['b']!=255){
                $R=Rand($this->bgcolor['r'],200);
                $G=Rand($this->bgcolor['g'],200);
                $B=Rand($this->bgcolor['b'],200);
            }else{
                $R=Rand(50,200);
                $G=Rand(50,200);
                $B=Rand(50,200);
            }
            $color=ImageColorAllocate($this->image,$R,$G,$B);
            $leight=($this->image_width-$this->curve_side*2)*($this->number_array[$i]/$item_max);
            ImageFilledRectangle($this->image,$this->curve_side,$yy-$this->curve_side,$leight,$yy,$color);
            ImageString($this->image,$this->fontsize,$leight+2,$yy-$this->curve_side,$this->number_array[$i],$this->fontcolor);
            $yy = $yy-$this->curve_side*2;
        }
    }

    // 折线图
    function write_line()
    {
        $number_data=count($this->number_array);
        $item_max=0;
        for ($i=0;$i<$number_data;$i++){
            $item_max=Max($item_max,$this->number_array[$i]);
        }
        for ($i=0;$i<$number_data;$i++){
            if($this->bgcolor['r']!=255 && $this->bgcolor['g']!=255 && $this->bgcolor['b']!=255){
                $R=Rand($this->bgcolor['r'],200);
                $G=Rand($this->bgcolor['g'],200);
                $B=Rand($this->bgcolor['b'],200);
            }else{
                $R=Rand(50,200);
                $G=Rand(50,200);
                $B=Rand(50,200);
            }
            $color=ImageColorAllocate($this->image,$R,$G,$B);
            $height_now=($this->image_height-$this->curve_side)-($this->image_height-$this->curve_side*2)*($this->number_array[$i]/$item_max);
            if($i!="0"){
                imageline($this->image,$xx,$height_next,$xx+$this->curve_side,$height_now,$color);
            }
            ImageString($this->image,$this->fontsize,$xx+$this->curve_side,$height_now-$this->curve_side/2,$this->number_array[$i],$this->fontcolor);
            $height_next=$height_now;
            $xx = $xx+$this->curve_side;
        }
    }
    //////

    /*
    +-----------------------------------------------------------------------------+
    | Output
    +-----------------------------------------------------------------------------+
    */
    function parse()
    {
        $this->image = imagecreatetruecolor($this->image_width,$this->image_height);

        $background  = imagecolorallocate($this->image,$this->bgcolor['r'],
                                                       $this->bgcolor['g'],
                                                       $this->bgcolor['b']);
        imagefilledrectangle($this->image,0,0,$this->image_width,$this->image_height,$background);
        $this->fontcolor = imagecolorallocate($this->image,$this->fontcolor['r'],
                                                           $this->fontcolor['g'],
                                                           $this->fontcolor['b']);
        $this->bgcolor = imagecolorallocate($this->image,$this->bgcolor['r'],
                                                         $this->bgcolor['g'],
                                                         $this->bgcolor['b']);
        $this->curve_bgcolor = imagecolorallocate($this->image,$this->curve_bgcolor['r'],
                                                               $this->curve_bgcolor['g'],
                                                               $this->curve_bgcolor['b']);
        $this->curve_gridcolor = imagecolorallocate($this->image,$this->curve_gridcolor['r'],
                                                                 $this->curve_gridcolor['g'],
                                                                 $this->curve_gridcolor['b']);

        $this->write_chinese();
        $this->write_english();
        $this->write_copyimage();
    }

    function parse_gridding()
    {
        $this->write_gridding();
        Switch ($this->return_type) {
            case "column_erect":
                $this->write_column_erect();
                break;
            case "column_transverse":
                $this->write_column_transverse();
                break;
            case "line":
                $this->write_line();
                break;
            default:
                $this->write_column_erect();
        }
    }

    function output($filename="")
    {
        //header( "content-type: image/png");
        if ($this->image_type == "gif") {
            $output_type = "imagegif";
        } elseif ($this->image_type == "jpg") {
            $output_type = "imagejpeg";
        } elseif ($this->image_type == "png") {
            $output_type = "imagepng";
        }
        if(empty($filename)){
            $output_type($this->image);
        }else{
            $output_type($this->image,$filename);
        }
        imagedestroy($this->image);
    }
    //////
}
?>