Location: PHPKode > projects > Worldweather > worldweather/web/MyGraph.php
<?
###############################
#                             #
#      MyGraph Library        #
#                             #
#      Version 2.0            #
#                             #
#      Matthieu Bouthors      #
#                             #
###############################
# CAUTION : This library is under GPL
# Please contact me if you need new features ;)
# Version 2.0
# 02 Fev 2002
#

# WEBSITE http://mygraph.sourceforge.net
# Docs are available on that web site

#
# TODO
#   Improve the Caption_B to print better second line

/*function calc_gap($dur){
Calculate the gap between marks for the time caption
Give 12 marks maximum
	$dur : the total time to draw in second
	return the gap in second

Note : This function is independant from the Class
*/
function calc_gap($dur){
	if ($dur<=10) return 1; // -> 10s/1s
	if ($dur<=24) return 2;// -> 24s/2s
	if ($dur<=36) return 3;// -> 36s/3s
	if ($dur<=60) return 5;// -> 1m/5s
	if ($dur<=120) return 10;// -> 2m/10s
	if ($dur<=180) return 15;// -> 3m/15s
	if ($dur<=360) return 30;// -> 6m/30s
	if ($dur<=720) return 60;// -> 12m/1m
	if ($dur<=1440) return 120;// -> 24m/2m
	if ($dur<=2160) return 180;// -> 36m/3m
	if ($dur<=3600) return 300;// -> 1h/5m
	if ($dur<=7200) return 600;// -> 2h/10m
	if ($dur<=10800) return 900;// -> 3h/15m
	if ($dur<=21600) return 1800;// -> 6h/30m
	if ($dur<=43200) return 3600;// -> 12h/1h
	if ($dur<=86400) return 7200;// -> 1j/2h
	if ($dur<=172800) return 14400;// -> 2j/4h
	if ($dur<=259200) return 21600;// -> 3j/6h
	if ($dur<=432000) return 43200;// -> 6j/12h
	if ($dur<=1036800) return 86400;// -> 12j/1j
	if ($dur<=2073600) return 172800;// -> 24j/2j
	if ($dur<=3110400) return 259200;// -> 36j/3j
	if ($dur<=5184000) return 432000;// -> 2m/5j
	if ($dur<=10368000) return 864000;// -> 4m/10j
	if ($dur<=15552000) return 1296000;// -> 6m/15j
	if ($dur<=31104000) return 2592000;// -> 1a/1m
	if ($dur<=62208000) return 5270400;// -> 2a/2m
	if ($dur<=93312000) return 7862400;// -> 3a/3m
	if ($dur<=186624000) return 15811200;// -> 6a/6m
	if ($dur<=373248000) return 31536000;// -> 12a/1a
	return 63072000;// -> 24a/2a
}

/*function calc_gaptxt($dur){
Calculate the text to print on marks
similar to calc_gap
	$dur : the total time to draw in second
	return a text to use with the date() function

Note : This function is independant from the Class
*/
function calc_gaptxt($dur){
	if ($dur<=360) return "i\m s";// -> 6m/30s
	if ($dur<=21600) return "H\Hi";// -> 6h/30m
	if ($dur<=432000) return "H\H";// -> 6j/12h
	return "d\/m";// -> 24a/2a
}

//Constants : Trace modes :
// MYGRAPH_DOT : only put a dot on each point
// MYGRAPH_LINE : Draw a line between each point
// MYGRAPH_DASH : Draw a dashed line between each point
define("MYGRAPH_DOT",0);
define("MYGRAPH_LINE",1);
define("MYGRAPH_DASH",2);

//Starting here the class Definition
class MyGraph
{
//Image Object
	var $img;		//Image
//Database
	var $db_link;		//Database link
//Size of the Graph
	var $width=0;		//total width
	var $height=0;		//total height
	var $g_width=0;		//witdh of graph
	var $g_height=0;	//height of graph
	var $b_left=0;		//size of the left border
	var $b_top=0;		//size of the top borber
//Colors
	var $color_r=0;		//color Red
	var $color_g=0;		//color Green
	var $color_b=0;		//color Blue
//Draw mode
	var $draw_mode=MYGRAPH_LINE; //Default is line draw
//Name of the time column
	var $time_col="date";	//name of the col where the time is
//The time limits
	var $date_start=0;
	var $date_stop=0;
//The data limits
	var $min=0;
	var $max=0;


/*Initiate the MyGraph object
Usage function MyGraph($w,$h,$g_w,$g_h,$b_l,$b_t,$back_r=255,$back_g=255,$back_b=255,$graph_r=240,$graph_g=240,$graph_b=240)
Parameters :
	$w	:	Total Width of the image (pixel)
	$h	:	Total Heigt of the image (pixel)
	$g_w	:	With of the graph (pixel)
	$g_h	:	Height of the graph (pixel)
	$b_l	:	size of the left border (pixel)
	$b_t	:	size of the top border (pixel)
Optional parameters :
	$back_r,$back_g,$back_b : RGB color of the image background (3 values 0..255)
	$graph_r,$graph_g,$graph_b : RGB color of the graph background (3 values 0..255)

*/
	function MyGraph($w,$h,$g_w,$g_h,$b_l,$b_t,$back_r=255,$back_g=255,$back_b=255,$graph_r=240,$graph_g=240,$graph_b=240){
	//verify dimensions
		if(($w<=0)|($h<=0)|($g_w>$w)|($g_h>$h)|(($g_w+$b_l)>$w)|(($g_h+$b_t)>$h))
			die("Error : incoherent graph definition");
	//store new dimensions
		$this->width=$w;
		$this->height=$h;
		$this->g_width=$g_w;
		$this->g_height=$g_h;
		$this->b_left=$b_l;
		$this->b_top=$b_t;
	//Initiate the image
		$this->img=ImageCreate($w,$h);
	//Put the background color
		$fond=ImageColorAllocate($this->img,$back_r,$back_g,$back_b);
	//Draw the background of the graph
		$fond_graph=ImageColorAllocate($this->img,$graph_r,$graph_g,$graph_b);
		ImageFilledRectangle($this->img,$this->b_left,$this->b_top,$this->b_left+$this->g_width,$this->b_top+$this->g_height,$fond_graph);

	//Draw the logo
		$txt="Generated by MyGraph";
	//find the better contrast
		if (($back_r+$back_g+$back_b)>384)
			$color=ImageColorAllocate($this->img,0,0,0);
		else
			$color=ImageColorAllocate($this->img,255,255,255);
	//print the text
		ImageString($this->img,2,$this->width-strlen($txt)*ImageFontWidth(2)-2,$this->height-ImageFontHeight(2)-2,$txt,$color);
	}


/*link the MyGraph object to mysql
Usage : function ConnectMySQL($Host,$Name,$Pass){
	$Host	:	location of the MySQL server (string)
	$Name	:	name of a authorized user (string)
	$Pass	:	password for that user (string)
Note 1 : Should only work with MySQL
Note 2 : You should create a special account with read-only privilege, so the password don't need protection
*/
	function ConnectMySQL($Host,$Name,$Pass){
		$this->db_link=mysql_connect($Host,$Name,$Pass) or die ("Error on MySQL database connexion");
	}

/*Change the current color
Usage : function Color($new_r,$new_g,$new_b){
	$new_r,$new_g,$new_b : Define the new RGB color for every new drawing on the image (3 values 0..255)
*/
	function Color($new_r,$new_g,$new_b){
		$this->color_r=$new_r;
		$this->color_g=$new_g;
		$this->color_b=$new_b;
	}

/*Change the name of the time column in the table
Usage : function TimeCol($new_val){
	$new_val	:	New column name for the date values (string)
Note : If you don't call that function the library will automatically try to read the column named "time"
*/
	function TimeCol($new_val){
		$this->time_col=$new_val;
	}

/*Change the drawing mode of the "Draw" function
	function Mode($new_mode){
		$new_mode	:	One of the defined constants
			- MYGRAPH_DOT : only put a dot on each point
			- MYGRAPH_LINE : Draw a line between each point
			- MYGRAPH_DASH : Draw a dashed line between each point
*/
	function Mode($new_mode){
		$this->draw_mode=$new_mode;
	}

/*Put a title on the top of the graph
	function Title($txt,$size=5,$blanc=10){
		$txt	:	String to put as title (string)
Optional :
		$size	:	Size of the string
		$blanc:	Space between the top and the title
*/
	function Title($txt,$size=5,$blanc=10){
		$color=ImageColorAllocate($this->img,$this->color_r,$this->color_g,$this->color_b);
		ImageString($this->img,$size,$this->width/2-strlen($txt)*ImageFontWidth($size)/2,$blanc,$txt,$color);
	}

//Put a line around the picture
	function Contour(){
		$color=ImageColorAllocate($this->img,$this->color_r,$this->color_g,$this->color_b);
		ImageRectangle($this->img,0,0,$this->width-1,$this->height-1,$color);
	}

//Produce the picture
//Use that function to directly show the picture without save it to a file
	function ImagePNG(){
		Header("Content-Type: image/png");
		ImagePNG($this->img);
	}

/*save the image into a file
	function SaveImage($filename){
		$filename	:	Name of the file (string)
Note : don't forget to verify that Apache can create the file
*/
	function SaveImage($filename){
		ImagePNG($this->img,$filename);
	}


/*Draw the graph
	function Draw($Database,$Table,$Col,$Date_Start,$Date_End,$floor=0,$ceiling=0){
		$Database	:	Name of the database inside the server (string)
		$Table	:	Name of the table inside the database (string)
		$Col		:	Name of the column to use for data (string)
		$Date_Start	:	Start date of the period you want to plot (date in string, ex : "2002-01-16 03:02:59")
		$Date_End	:	End date of the period you want to plot (date in string, ex : "2002-02-16 20:25:03")
Optional :
		$floor	:	the lower value of the data (real)
		$ceiling	:	the higher value of the data (real)
*/
	function Draw($Database,$Table,$Col,$Date_Start,$Date_End,$floor=0,$ceiling=0){
	//store dates to draw scales
		$this->date_start=strtotime($Date_Start);
		$this->date_end=strtotime($Date_End);

	//calculate min and max if they are now given
		if (($floor==0)&($ceiling==0)){
			$query="SELECT max($Col) as maxi,min($Col) as mini FROM $Table WHERE ($this->time_col>='$Date_Start') AND ($this->time_col<='$Date_End') AND ($Col != 'NULL');";
			$result=mysql_db_query($Database,$query,$this->db_link);
			if (mysql_error()!="")
				die(mysql_error());
	//if ok
			$row=mysql_fetch_object($result);
			$floor=floor($row->mini);
			$ceiling=ceil($row->maxi);
			if($floor==$ceiling){
				$floor-=1;
				$ceiling+=1;
			}
			mysql_free_result($result);
		}
	//store values to draw scales
		$this->min=$floor;
		$this->max=$ceiling;
	//Now draw the graph
		$Date_Ref=strtotime($Date_Start); //reference date
	//calculate Coefs to convert values into pixels
		$Coef_Date=(double)($this->g_width/(strtotime($Date_End)-strtotime($Date_Start)));
		$Coef_Val=(double)($this->g_height/($ceiling-$floor));
	//get the data from the database
		$query="SELECT $this->time_col,$Col FROM $Table WHERE ($this->time_col>='$Date_Start') AND ($this->time_col<='$Date_End') AND ($Col != 'NULL') ORDER BY $this->time_col;";
		$result=mysql_db_query($Database,$query,$this->db_link);
		if (mysql_error()!="")
			die(mysql_error());
	//Create the color
		$color=ImageColorAllocate($this->img,$this->color_r,$this->color_g,$this->color_b);

		$row=mysql_fetch_row($result);

		$last_x=(int)((strtotime($row[0])-$Date_Ref)*$Coef_Date+$this->b_left);
		$last_y=(int)(($ceiling-$row[1])*$Coef_Val+$this->b_top);
		while($row!=false){
			$x=(int)((strtotime($row[0])-$Date_Ref)*$Coef_Date+$this->b_left);
			$y=(int)(($ceiling-$row[1])*$Coef_Val+$this->b_top);
	//switch between modes
			switch($this->draw_mode){
			case MYGRAPH_DOT:
		//one dot on each point
				ImageLine($this->img,$x,$y,$x,$y,$color);
				break;
			case MYGRAPH_LINE:
		//one line between points
				ImageLine($this->img,$last_x,$last_y,$x,$y,$color);
				break;
			case MYGRAPH_DASH:
		//one dashed line between points
				ImageDashedLine($this->img,$last_x,$last_y,$x,$y,$color);
				break;
			}
			$last_x=$x;
			$last_y=$y;
	//get the next line
			$row=mysql_fetch_row($result);
		}
		mysql_free_result($result);
	}


/*draw the bottom caption (for time)
	function Caption_B($gap=21600,$format="H\H",$line=0,$format2="d/m"){
Optional :
		$gap		:	gap between 2 printed dates (seconds)
		$format	:	format to present data (string used for the "date" function)
		$line		:	indicate to draw or not a vertical line
		$format2	:	format to present second ligne data used on each 0 value
					by default print the day/month on each new day
					(string like $format)
examples of formats :
	"H\H" print hours : "00H" "01H" "02H" ...
	"i\m" print minutes : "01m" "02m" ...

Note : use the limits of the last call of Draw
*/
	function Caption_B($gap=0,$format="",$line=0,$format2="d/m"){
	if ($gap<=0) $gap=calc_gap($this->date_end-$this->date_start);
	if ($format<=0) $format=calc_gaptxt($this->date_end-$this->date_start);

	//Initiate color and line
		$color=ImageColorAllocate($this->img,$this->color_r,$this->color_g,$this->color_b);
		ImageLine($this->img,$this->b_left,$this->b_top+$this->g_height,$this->b_left+$this->g_width,$this->b_top+$this->g_height,$color);
	//Coef used to convert date in pixels
		$Coef_Date=(double)($this->g_width/($this->date_end-$this->date_start));

	//start
		$mark=($this->date_start);
		while ($mark<=$this->date_end){
	//Calculate positions
			$horiz=(int)($this->b_left+($mark-$this->date_start-($this->date_start % $gap))*$Coef_Date);
			if ($horiz<$this->b_left) {
				$mark+=($gap);
				continue;
			}
			if ($horiz>($this->b_left+$this->g_width)) break;
			$vert=(int)($this->b_top+$this->g_height);
	//draw the little line
			ImageLine($this->img,$horiz,$vert,$horiz,$vert+5,$color);
	//Draw the full vertical line
			if ($line) ImageDashedLine($this->img,$horiz,$this->b_top,$horiz,$this->b_top+$this->g_height,$color);
	//print the text
			$txt_heure=date($format,$mark);
			ImageString($this->img,2,$horiz-strlen($txt_heure)*ImageFontWidth(2)/2,$vert+10,$txt_heure,$color);
	//print the day if it's 0
			if ($txt_heure==0){
				$txt_heure=date($format2,$mark);
				ImageString($this->img,2,$horiz-strlen($txt_heure)/2*ImageFontWidth(2),$vert+20,$txt_heure,$color);
			}
	//increase the mark
			$mark+=($gap);
		}
	}

/*draw the left caption
Usage : function Caption_L($nb_mark=5,$line=1){
Optional :
	$nb_mark	:	number of interval
	$line		:	indicate to draw or not a vertical line
Note : use the limits of the last call of Draw
*/
	function Caption_L($nb_mark=5,$line=1){
	//calculate the gap between values
		$gap=(double)(($this->max-$this->min)/$nb_mark);
	//Calculate the Coef to convert value into pixel
		$Coef_Val=(double)($this->g_height/($this->max-$this->min));
	//Initiate color and line
		$color=ImageColorAllocate($this->img,$this->color_r,$this->color_g,$this->color_b);
		ImageLine($this->img,$this->b_left,$this->b_top,$this->b_left,$this->b_top+$this->g_height,$color);
	//start
		$mark=$this->min;
		while($mark<=$this->max){
	//calculate the vert pos
			$vert=$this->b_top+($this->max-$mark)*$Coef_Val;
	//draw a little line
			ImageLine($this->img,$this->b_left-2,$vert,$this->b_left,$vert,$color);
	//draw a total dashed line
			if ($line) ImageDashedLine($this->img,$this->b_left,$vert,$this->b_left+$this->g_width,$vert,$color);
	//print the text
			$txt=sprintf("%.1f",$mark);
			ImageString($this->img,2,$this->b_left-strlen($txt)*ImageFontWidth(2)-5,$this->b_top+($this->max-$mark)*$Coef_Val-ImageFontHeight(2)/2,$txt,$color);
	//increase the mark
			$mark+=$gap;
		}
	}

/*draw the right caption
	function Caption_R($nb_mark=5,$line=1){
Optional :
	$nb_mark	:	number of interval
	$line		:	indicate to draw or not a vertical line
Note : use the limits of the last call of Draw
*/
	function Caption_R($nb_mark=5,$line=1){
	//calculate the gap between values
		$gap=(double)(($this->max-$this->min)/$nb_mark);
	//Calculate the Coef to convert value into pixel
		$Coef_Val=(double)($this->g_height/($this->max-$this->min));
	//Initiate color and line
		$color=ImageColorAllocate($this->img,$this->color_r,$this->color_g,$this->color_b);
		ImageLine($this->img,$this->b_left+$this->g_width,$this->b_top,$this->b_left+$this->g_width,$this->b_top+$this->g_height,$color);
	//start
		$mark=$this->min;
		while($mark<=$this->max){
	//calculate the vert pos
			$vert=$this->b_top+($this->max-$mark)*$Coef_Val;
	//draw a little line
			ImageLine($this->img,$this->b_left+$this->g_width+2,$vert,$this->b_left+$this->g_width,$vert,$color);
	//draw a total dashed line
			if ($line) ImageDashedLine($this->img,$this->b_left,$vert,$this->b_left+$this->g_width,$vert,$color);
	//print the text
			$txt=sprintf("%.1f",$mark);
			ImageString($this->img,2,$this->b_left+$this->g_width+5,$this->b_top+($this->max-$mark)*$Coef_Val-ImageFontHeight(2)/2,$txt,$color);
	//increase the mark
			$mark+=$gap;
		}
	}

/*function Unit_L($text){
Print the unit of the left caption
	$text : the text to print
*/
function Unit_L($text){
	$color=ImageColorAllocate($this->img,$this->color_r,$this->color_g,$this->color_b);
	ImageString($this->img,2,$this->b_left-ImageFontWidth(2)*strlen($text)/2,$this->b_top-20,$text,$color);
}

/*function Unit_R($text){
Print the unit of the right caption
	$text : the text to print
*/
function Unit_R($text){
	$color=ImageColorAllocate($this->img,$this->color_r,$this->color_g,$this->color_b);
	ImageString($this->img,2,$this->b_left+$this->g_width-ImageFontWidth(2)*strlen($text)/2,$this->b_top-20,$text,$color);
}

}
?>
Return current item: Worldweather