<?php
// DESARROLLADO POR CARLOS ZAVALA ARCE
// Especial server requeriment: GD library
// carloszavala@esfera.cl
// URL: http://www.cirilux.cl
// For commercial purpose, please write me!!.
// The "GRAFICO" (charts) class is compose or relantionship with 3 principals class in this eschema
//
//						     1  +--------+
//			  +---------------> | grilla |
//			  |1				+--------+
//      +--------+	1		oo	+------+
//		| charts |	----------> | bars |
//		+--------+				+------+
//			  |	1			  1	  +--------+
//      	  +-----------------> | series |
//								  +--------+
//
//
// 1. Bar class, draw in the charts->png_image a values from a array
// 2. Series class, draw draw in the charts->png_image a series values
// 3. Grilla, draw the charts lines in a determined width charts scale

class color  
		{
		var $rgb; //
			function color()
			{
				$this->rgb = array(0,0,0);
				return true;	
			}		
			function hex2rgb($hex) 
					{
					
				$color = str_replace('#','',$hex);
				$rgb = array('r' => hexdec(substr($color,0,2)),
					   'g' => hexdec(substr($color,2,2)),
					   'b' => hexdec(substr($color,4,2)));
					   
				return $rgb;
					}
		}
/******* Clase Grilla*********/
		
class grilla //clase que genera la grilla
{
var $min;		//mínimo valor del gráfico
var $max_value;		//máximo valor del gráfico
var $step;    // potencia de 10 orden de magnitud
var $pixel_step;  //pixeles x step
var $cant_pasos;
var $bg_color;
var $font_color;
var $g_color;
var $width;
var $x1;  //coordenada x1
var $y1;  //coordenada y1
var $x2;  //coordenada x2
var $y2;	//coordenada y2
var $height;
var $FONT_PATH;
	
	function grilla($width, $height,$hex_color,$img,$n)
	{
	$this->FONT_PATH = 'D:\wamp\www\wacorpcrm\modules\Home\arial.ttf';
	$color=new color();
	$bg_color=$color->hex2rgb($hex_color);
	$fill = ImageColorAllocate($img,$bg_color['r'],$bg_color['g'],$bg_color['b']);
	
	$a = $this->set_x1($width);
	$a = $this->set_x2($width);
	$a = $this->set_y1(50);
	$a = $this->set_y2($height,70);
	$a = $this->set_width();
	$a = $this->set_height();
	
	imagefilledrectangle($img, $this->x1, $this->y1, $this->x2, $this->y2,$fill);
	// borde de la grilla ************
	$fill = ImageColorAllocate($img,0,0,0);
	imageline($img, $this->x1, $this->y1,  $this->x2, $this->y1,$fill);
	imageline($img, $this->x1, $this->y2,  $this->x2, $this->y2,$fill);
	imageline($img, $this->x1, $this->y1, $this->x1, $this->y2,$fill);
	imageline($img, $this->x2, $this->y1, $this->x2, $this->y2,$fill);
	//*********************
	// Dibuja la grilla ****************************************
	$a = $this->draw_lines($n,$img);
	
	return true;
	}
	function set_max_value($n)
		{
		//$n=1536;
		//echo "N:".$n."<br>";
		$exp = floor(log10($n));
		//echo "exp ".$exp."<br>";
		$pot_10 = pow(10,$exp);
		//echo "pot ".$pot_10."<br>";
		$cuarto = $pot_10/4;
		$medio = $pot_10/2;
		//echo "cuarto ".$cuarto."<br>";
		if (($n%$pot_10)==0) $final = $n;
		else
		{
			$final = floor($n/$pot_10)*$pot_10 + $pot_10;
		//echo $final-$cuarto."<br>";
			if (($final-$medio)>$n) $final = $final-$medio;
			elseif (($final-$cuarto)>$n) $final = $final-$cuarto;
		}
		//echo $final;
		
		$this->max_value = $final;
		$this->step = $pot_10;
	return true;
		
		}

	function draw_lines($n,$img)
	{
	$a = $this->set_max_value($n);
	$min_number_grid = 8;
	$pot_10=$this->step;
	$n_pasos = $this->max_value/$this->step;
	if ($n_pasos<$min_number_grid) $this->step=$pot_10/2;  //el paso queda de 5 en 5
	$n_pasos = $this->max_value/$this->step;
	if ($n_pasos<$min_number_grid) $this->step=$pot_10/5;  // el paso queda de 2 en 2
	//echo $this->step;
	$fill2 = ImageColorAllocate($img,0,0,0);
	$num = $this->max_value/$this->step;	
	$this->pixel_step = $this->height*$this->step/$this->max_value;
	//echo $this->step;
	//echo log10($this->step);
	if (log10($this->step)<0) $decimal_symbol = 1;
	
	for($i=1;$i<=$num;++$i)
		{
			$p = $i*$this->step;
			//imageline($img, $this->x1-2, $this->y2-$i*$this->pixel_step,  $this->x2 -1,  $this->y2-$i*$this->pixel_step, $fill2);
			imagettftext($img,7, 0, $this->x1-35, $this->y2-$i*$this->pixel_step + 3 , $fill2, $this->FONT_PATH, number_format($p, $decimal_symbol, ',' , '.'));
			//if ($p>$this->max_value) return true;
		}
	return true;
	}

	function set_width()
		{
		$this->width = $this->x2 - $this->x1;
		return true;
		}
	function set_height()
		{
		$this->height = $this->y2 - $this->y1;
		return true;
		}
	function set_x1($width)
		{
		$this->x1 = ceil(0.1*$width);
		return true;
		}
	function set_x2($width)
		{
		$this->x2 = ceil(0.8*$width);
		return true;
		}
	
	function set_y1($n)  // margen derecho
		{
		$this->y1 = $n;
		return true;
		}
	function set_y2($n,$m)
		{
		$this->y2 = max($n-$m,0); //M=70 70 pixeles margen inferior
		return true;
		}
}
//********************************* CLASE SERIE *****************************************************

class serie
{
var $FONT_PATH;
var $m;
var $tot;
var $nombre_serie;

	function serie()
	{
	$this->FONT_PATH = 'D:\wamp\www\wacorpcrm\modules\Home\arial.ttf';
	if (!isset($this->tot)) $this->tot=0;
	return $this->m;
	}
	function add_serie($nombre,$color)
	{
	$this->m[$nombre] =$color;
	$this->clave[$tot] = $nombre;
	++$this->tot;
	return true;
	}
	function draw_serie($img,$x,$y)
	{
	$color=new color();
	$fill = ImageColorAllocate($img,0,0,0);
	$cod_serie = array_keys($this->m);
	for ($i=$this->tot-1;$i>=0;--$i)
		{ 
		$hex = $this->m[$cod_serie[$i]]; // color en hex
		$bg_color=$color->hex2rgb($hex);
		$fill2 = ImageColorAllocate($img,$bg_color['r'],$bg_color['g'],$bg_color['b']);
		imagefilledrectangle($img, $x, $y-20*$i, $x+10, $y+20-20*$i,$fill2);
		//echo $i."<br>";
		imagettftext($img,7, 0, $x+15, $y-20*$i+15, $fill, $this->FONT_PATH, "-".$cod_serie[$i]);
		
		}return true;
	}
}
//************************************CLASE BARRA********************************************

class bar
{
var $width;
var $value;
var $color;
var $x_right;

	function bar($img,$hex_color,$x,$y,$width,$value,$rel)
	{
	$fill = ImageColorAllocate($img,0,0,0);
	$color=new color();
	$bg_color=$color->hex2rgb($hex_color);
	$xr =  $x+$this->width/2;
	$this->value = $value;
	$this->width = $width;
	$this->x_right = $x+$this->width;
	$this->color = ImageColorAllocate($img,$bg_color['r'],$bg_color['g'],$bg_color['b']);
	$value2 = $this->value*$rel;
	$d=imagefilledrectangle($img, $x, $y-$value2+1, $x+$this->width, $y,$this->color);
	if ($value!=0) imagettftext($img,8, 0, $this->x_right+2, $y-$value2+8, $fill, $this->FONT_PATH, $value);
	return true;
	}
}
//*********************** CLASE STACKED BAR ***********************************************

class stacked_bar extends bar
{
     var $x;
	 var $FONT_PATH;
   
     function stacked_bar ($img,$x,$y,$width,$rel,$values,$serie,$tot_series) 
	 {	 
	 	 $fill = ImageColorAllocate($img,0,0,0);
	 	 $this->FONT_PATH = 'D:\wamp\www\wacorpcrm\modules\Home\arial.ttf';
         $this->x = $x;
		 $xr =  $x+$width/2;
		 $cod_serie = array_keys($serie);
		 for ($i=1;$i<=$tot_series;++$i) 
		 {
		 $color = $serie[$cod_serie[$i-1]];
		 $b = $this->bar($img,$color,$x, $y-$tot*$rel-1 ,$width,$values[$i],$rel);
		 $tot = $tot + $values[$i];
		 }
		imagettftext($img,9, 270, $xr, $y + 10 , $fill, $this->FONT_PATH,$values[0]);
		 return true;
     }
 }


//**************************************CLASE GRÄFICO****************************************

class grafico
{
var $png_image; //imagen que creará la clase
var $width;		//ancho del gráfico
var $height; 	//alto del gráfico
var $bg_color; //color del gráfico
var $FONT_PATH;
var $serie;  //clase serie del gráfico
var $grilla;  //clase grilla
var $supreme;  //máximo valor de la matriz
var $bar;		//barra
var $tot_bars;  // total de barras del gráfico
var $rel;   	// relación pixel x valor

	function draw_graph()
	{
	 header("Content-Type: image/png");
	 imagepng($this->png_image);

	}
	function grafico($titulo,$width, $height, $hex_color,$datos,$series_colores)  
		{
		$this->FONT_PATH = 'D:\wamp\www\wacorpcrm\modules\Home\arial.ttf';
		$a=$this->set_width($width);
		$b=$this->set_height($height);
		$c=$this->set_bg_color($hex_color);
		$rgb=$this->bg_color;
		$this->png_image = imagecreate($this->width, $this->height);
		$this->bg_color = imagecolorallocate($this->png_image, $rgb['r'], $rgb['g'], $rgb['b']);
		$this->set_supreme($datos);
		$this->set_grilla('ffffff');
		$this->set_serie($datos,$series_colores);
		$this->set_titulo($titulo,$this->grilla->x1, $this->grilla->y1-20);
		$this->set_rel();
		$this->serie->draw_serie($this->png_image,$this->grilla->x2+5,$this->grilla->y2-100);
		$this->draw_all_bars($datos);
		$fill = imagecolorallocate($this->png_image, 0, 0,0);  
		//imagettftext($this->png_image,10, 0, $this->grilla->width, $this->height-15 , $fill, $this->FONT_PATH, "AMA A DIOS");// You can delete it but don't forget it
		//imagettftext($this->png_image,8, 0, $this->grilla->width, $this->height , $fill, $this->FONT_PATH, "cirilux.cl"); 
		return $this->png_image;
		}
	
	function draw_all_bars($datos)
	{
		for ($j=1;$j<=$this->tot_bars;++$j)
		{
		$i=0;
		while (isset($datos[$i][$j]))
			{
			$values[$i] = $datos[$i][$j];
			++$i;
			}
		if (!isset($this->bar)) $x = $this->grilla->x1+15; else $x=$this->bar->x_right + 20;
		$this->bar = new stacked_bar($this->png_image,$x,$this->grilla->y2,12,$this->rel,$values,$this->serie->serie(),$this->serie->tot);
		}
	}
	
	function set_tot_bars($datos)
	{	$j=1;
	while (isset($datos[0][$j]))
		{++$j;	}
		$this->tot_bars = $j-1;
	return true;
	}
	
	function set_grilla($color)
		{
		$this->grilla = new grilla($this->width, $this->height,$color,$this->png_image,$this->supreme);
		return true;
		}
	function set_serie($datos,$series_colores)
		{
		$this->serie = new serie();
		$i=1;
		while (isset($datos[$i][0]))
			{
			$this->serie->add_serie($datos[$i][0],$series_colores[$i]);
			++$i;
			}
		return true;
		}
	function set_titulo($str,$x,$y)
		{
		$fill = imagecolorallocate($this->png_image, 0, 0,0);
		imagettftext($this->png_image,12, 0, $x, $y , $fill, $this->FONT_PATH, $str);
		return TRUE;
		}
	function set_width($width)
		{
		$this->width = $width;
		return true;
		}
	function set_height($height)
		{
		$this->height = $height;
		return true;
		}
	function set_bg_color($hex_color)
	{
		$rgb=new color();
		$this->bg_color=$rgb->hex2rgb($hex_color);
		return true;
	}
	function set_rel()
	{
	$this->rel = $this->grilla->height/$this->grilla->max_value;
	return true;
	}
	function set_supreme($datos)
	{
	$this->set_tot_bars($datos);
	$i=1;
	for ($j=1;$j<=$this->tot_bars;++$j)
		{	
		$sum=0;
		$i=1;
			while (isset($datos[$i][$j]))
			{
			$sum = $sum + $datos[$i][$j];
			++$i;
			}
	$this->supreme = max($sum,$this->supreme);
	}
	return true;
	}
}
?>