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>";
?>

Python script to get links from yahoo search

This was a quick script I made to pull links from yahoo search using the boss search api, and then list the unique domains.

If you want the entire links, just modify so that the whole links are appended to the list. Yahoo does not allow to get all the results, but only a certain predefined number so this code only extracts about 800 domains. But it is still good enough for a start and for most uses.

I am also working on getting citation values for google scholar for a friend. I will post that soon here. Heres the code for now.

#! /usr/bin/python
import urllib,json
from urlparse import urlparse

yahoo_application_id="Ht18VqTV34EMRWTJKOOh4rNBWTqkrjTSSQj9JwWlsqTMK41_3oFWFnhivJipX0wnvU4qzXc9VAw-"
nextresult=0;
links=list()
linksdump=list()
#print yahoo_application_id

#print "http://boss.yahooapis.com/ysearch/web/v1/Jeba+Singh+Emmanuel?appid="+yahoo_application_id+"&format=xml"
while(True):
	print "trying result from " + str(nextresult)
	f = urllib.urlopen("http://boss.yahooapis.com/ysearch/web/v1/search+engine+optimization+software?appid="+yahoo_application_id+"&format=json&count=100&start="+str(nextresult))
	ss=json.JSONDecoder()
	ssjson= ss.decode(f.read())
	#count=ssjson["ysearchresponse"]["count"]
	#start=ssjson["ysearchresponse"]["start"]
	totalhits=int(ssjson["ysearchresponse"]["totalhits"])
	print totalhits
	for x in ssjson["ysearchresponse"]["resultset_web"]:
		url= x["url"]
		o = urlparse(url)
		linksdump.append(url)
		link = o[0]+"://"+o[1]
		if link not in links:
			links.append(link)
		nextresult=nextresult+1
	if (nextresult>10000):
		break
print "Obtained results: " + str(nextresult) + " of which " + str(len(links)) + " were unique."
for x in links:
	print x

Cool huh? If you want any help modifying this, drop me a line.

Positioning text vertically and horizontally using gd

I was working on a PHP script yesterday for creating a couple of graphs which required lots of text in various places aligned to text on the same line. Some on the x axix and some on y. Finding no inbuilt function in gd on php, I created this simple function to align text vertically and horizontally as required based on the parameters passed to it.

[sourcecode language="php"]

function positiontextinimage($img, $font, $size, $color, $string, $x,$y, $horiz, $vert)
{
$bounds=imageftbbox  ( $size  , 0  , $font  , $string);
switch($horiz){
case “left”:
break;
case “right”:
$x=$x-$bounds[4];
break;
case “center”:
case “centre”:
$x=$x-($bounds[4] -$bounds[0])/2;
break;
}
switch($vert){
case “top”:
$y=$y-$bounds[5];
break;
case “bottom”:
break;
case “middle”:
$y=$y+($bounds[1]-$bounds[5])/2;

break;

}
imagefttext  ( $img  , $size  , 0  , $x, $y, $color, $font  , $string);
}

[/sourcecode]

PHP Proxy script to solve javascript and jquery cross domain issues

I just finished a project in which a jquery dialog used a jquery.ajax call using get to obtain details of a transaction from a url on another domain, effectively a cross domain ajax request. Since firefox 3.0 does not allow itself to be set to allow cross domain requests, I had to use some other way. I could have just used an iframe, but that is another story in itself.

Here is the bit of javascript code.

[sourcecode language="js"]

function refaxorder(){
//idfield=$(“#idfield”).val();
query=”urlid=1&inOID=” + idfield + “&inKey=” + key + “&inAction=reFax”;
$(“#actiondiv”).html(“

Loading…

“);
$(“#actiondivin”).dialog({autoOpen:false, modal:true, title:”ReFax”, buttons:{OK: function(){$(this).dialog(‘destroy’).remove(); }}});;
$(“#actiondivin”).dialog(“open”);

$.ajax({type:”GET”, url: “proxy.php”, data: query,  dataType:”html”, success:function(msg){
$(“#actiondivin”).html(msg);
}
});
}

[/sourcecode]

To get around this, I implemented a couple of lines as proxy.php to act as a proxy. Please note that I am only allowing it to be passed the urlid instead of a url to prevent it from becoming an open proxy. Also IP based filtering could be implemented to make it more safer. Have a look, maybe it will come in useful for you too.

[sourcecode language='php']

$value){
if ($key!=’url’) $query[]=$key.”=”.$value;
}
if (count($query)) $querystring=implode(“&”,$query);
$fullurl=$url[$urlid].”?”.$querystring;

$fp=fopen($fullurl,’rb’);
$page = ”;
if ($fp===false) die(“Unable to open”);
while (!feof($fp)) {
$page .= fread($fp, 8192);
}
fclose($fp);
print $page;
?>

[/sourcecode]