Location: PHPKode > projects > Worldweather > worldweather/web/MyGraph.php
```<?
###############################
#                             #
#      MyGraph Library        #
#                             #
#      Version 2.0            #
#                             #
#      Matthieu Bouthors      #
#                             #
###############################
# CAUTION : This library is under GPL
# 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
//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(){
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');";
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;";
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);
}

}
?>
```