<?
###############################
# #
# 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);
}
}
?>