Function to create traffic graph in PHP with gd

Just finished a couple of projects in which this code came in useful.

You just pass in an array of traffic date of the format
arrayname[0]['date']=’15/06′;
arrayname[0]['data']=200;
arrayname[1]['date']=’16/06′;
arrayname[1]['data']=100;

I am Indian so the data code is in format d/m, but m/d should not matter either if you create the array in proper order. Also if the data is greater than 1024 for any of the array values, the graph switches to GB display.

Here is a sample image generated by this code.

Sample graph

Sample graph

Below is the code, enjoy! Let me know if it helped you.

<?php
function generategraph($traffic){
$days=count($traffic);
$imagewidth=700; $imageheight=300;
$yaxistextarea=35; 	$lefttextarea=30; $xaxistextarea=30; $bottomtextarea=30;
$topmargin=20; 	$rightmargin=20; $graphtop=10;
$yaxissplits=10;
$datascale=1;
$dataunit='MBs';

$graphwidth=$imagewidth-$yaxistextarea-$lefttextarea-$rightmargin;
$graphheight=$imageheight-$xaxistextarea-$bottomtextarea-$topmargin-$graphtop;

//xaxis is one greater because one line the start and end of the graph will not have any bars on them.
$xaxissplits=$days+1;
$barwidth=$graphwidth/($xaxissplits+1)/2;

if ($barwidth>30) $barwidth=30;
$i=0;
$maxvalue=0;$minvalue=0;$totaldata=0;
foreach($traffic as $value){
if ($maxvalue<$value&#91;'data'&#93;) $maxvalue=$value&#91;'data'&#93;;
$totaldata+=$value&#91;'data'&#93;;
}

if ($maxvalue>=1024) { $datascale=1024; $dataunit='GBs';}

//The y axis is for the amount of traffic. so we find the minimum of the incoming and the outcoming traffic and
//it will be the lower and upper bounds.

//Since we will have a graph of only 20 lines, we split the difference into 20 and find the linerange
$linerange=($maxvalue-$minvalue)/$yaxissplits;
$graphscale=$graphheight/($maxvalue-$minvalue);

//we now have a neat map of i => in and out
//remember that each linerange is equal to
$im = ImageCreate ($imagewidth,$imageheight);
if (!$im) echo "Error in gd library";

//some of these variables are not used in the current code, but nice to let it remain in case future coding requires additions like borders around bars, lines etc.
imagecolorallocatealpha($im,255,255,255,100);
$imagebackground=ImageColorAllocate($im, 255,255,255);
$graphbackground=ImageColorAllocate($im, 255,255,255);
$textcolor=ImageColorAllocate($im, 100,100,100);
$datalinecolor=ImageColorAllocate($im, 100, 255,100);
$databarcolor=ImageColorAllocate($im, 233,131,18);
$databarbordercolor=ImageColorAllocate($im, 100, 100,100);
$axiscolor=ImageColorAllocate($im, 50,50,50);
$axislinecolormajor=ImageColorAllocate($im, 186,180,24);
$axislinecolorminor=ImageColorAllocate($im, 255,255,255);

//create some frequently used variables
//these are the min and max values on the graph.
$xmin=$yaxistextarea + $lefttextarea;
$ymin=$imageheight-$bottomtextarea-$xaxistextarea;
$xmax=$imagewidth-$rightmargin;
$ymax=$topmargin;

//create the graph area
imagefilledrectangle($im, $xmin, $ymin, $xmax, $ymax, $graphbackground);
imagestringup($im, 3, 0+5, $ymin-30 , "Data Transmitted in ".$dataunit, $textcolor);

for ($i=1; $i<=$yaxissplits; $i++){
//each major y axis line locations
$ymajor = $ymin - ($i * ($graphheight/$yaxissplits));
imagestring($im, 2,  $lefttextarea,$ymajor -5, round(($minvalue + $i * $linerange)/$datascale,2), $textcolor);
$yminor = $ymajor + ($graphheight/$yaxissplits)/2;
imageline($im, $xmin, $ymajor, $xmax, $ymajor, $axislinecolormajor);
}

for ($i=1; $i<$xaxissplits; $i++){
//each major x axis line locations
$xmajor = $xmin + ($i * ($graphwidth/$xaxissplits));
$xminor = $xmajor - ($graphwidth/$xaxissplits)/2;
imageline($im, $xmajor, $ymin, $xmajor, $ymax, $axislinecolormajor);
imagestringup($im, 1,  $xmajor-3, $ymin+$xaxistextarea, $traffic&#91;$i-1&#93;&#91;'date'&#93;, $textcolor);
}

//plot the actual graph
$plotxold=$xmin; $plotyold=$ymin;
for($key=1; $key<=$xaxissplits-1; $key++){
$value=$traffic&#91;$key-1&#93;;
$plotx=$xmin + ($key) *($graphwidth/$xaxissplits);
$ploty= $ymin - ($value&#91;'data'&#93; - $minvalue) * $graphscale;
if ($plotx>$xmax) $plotx=$xmax; //to avoid bleed due to rounding off of graphscale
if ($ploty<$ymax) $ploty=$ymax; //to avoid bleed due to rounding off of graphscale
$plotxold=$plotx; $plotyold=$ploty;
if ($value&#91;'data'&#93;>0){
imagefilledrectangle($im, $plotx-$barwidth/2, $ymin, $plotx+$barwidth/2, $ploty, $databarcolor);
}
}
$plotxold=$xmin; $plotyold=$ymin;
imagestring($im, 2,  $yaxistextarea+$lefttextarea,$imageheight-$bottomtextarea*3/4, "Total Data: " . $totaldata . " ".$dataunit, $textcolor);
imagestring($im, 1,  $lefttextarea,5, "Image generated at " . date('d/m/y  H:i'), $textcolor);
imagerectangle($im, $xmin, $ymin, $xmax, $ymax, $axiscolor);
imagejpeg($im, "graph.jpg");
return "<div><img src='graph.jpg' /></div>";
?>

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>