Free website click heatmap - DIY

What are the click heat maps?
Heat maps are places on your website where users mostly click or hover their mouse. They are also known as website hot spots.

Why do you need to know your website hotspots?

Once knowing their location you can reorder your important information, optimize your adverts to increase their CTR(click-through-rate) etc...

Remember that this type of click tracking is different from the simple web counters. Click heatmaps map the exact x,y clicks and mouse hover positions. That makes such statistics really great for those who look for usability improvements.

Of course there are free services such as Creazyegg.com and Clickdensity.com but the offered JavaScript actually slows down the user experience. So the following is a guide how to build your own heatmap tracking. I've combined 2 techniques so the AJAX script could work across multiple domains. Here are their respected versions urls:


for the heatmap:
http://blog.corunet.com/english/the-definitive-heatmap

for the cross-domain AJAX:
http://blog.cbciweb.com/articles/tag/asynchronousjavascriptacrossdomains

INSTRUCTIONS:
1. Create an empty readable and writeable file: clickcount.txt on your webserver.
2. Place the following javascript code in your website just above the ending tag:

var xOffset,yOffset;
var tempX = 0;
var tempY = 0;


//detect browser
var IE = document.all?true:false
if (!IE) {
document.captureEvents(Event.MOUSEMOVE)
}
//find the position of the first item on screen and store offsets
//find the first item on screen (after body)
var firstElement=document.getElementsByTagName('body')[0].childNodes[1];
//find the offset coordinates
xOffset=findPosX(firstElement);
yOffset=findPosY(firstElement);
if (IE){ // In IE there's a default margin in the page body. If margin's not defined, use defaults
var marginLeftExplorer  = parseInt(document.getElementsByTagName('body')[0].style.marginLeft);
var marginTopExplorer   = parseInt(document.getElementsByTagName('body')[0].style.marginTop);
/*assume default 10px/15px margin in explorer*/
if (isNaN(marginLeftExplorer)) {marginLeftExplorer=10;}
if (isNaN(marginTopExplorer)) {marginTopExplorer=15;}
xOffset=xOffset+marginLeftExplorer;
yOffset=yOffset+marginTopExplorer;
}
/*attach a handler to the onmousedown event that calls a function to store the values*/
document.onmousedown = getMouseXY;




/*Functions*/
/*Find positions*/
function findPosX(obj){
var curleft = 0;
if (obj.offsetParent){
while (obj.offsetParent){
curleft += obj.offsetLeft
obj = obj.offsetParent;
}
}else if (obj.x){
curleft += obj.x;
}
return curleft;
}


function findPosY(obj){
var curtop = 0;
if (obj.offsetParent){
while (obj.offsetParent){
curtop += obj.offsetTop
obj = obj.offsetParent;
}
}else if (obj.y){
curtop += obj.y;
}
return curtop;
}
function getMouseXY(e) {
if (IE) {
tempX = event.clientX + document.body.scrollLeft
tempY = event.clientY + document.body.scrollTop
} else {
tempX = e.pageX
tempY = e.pageY
}
tempX-=xOffset;
tempY-=yOffset;
var url='http://yourwebsite.com/empty.php?x='+tempX+'&y='+tempY; /* Type your website URL here*/


ajad_send(url);


return true;
}


var ajad_ndx_script = 0;


function ajad_do (u) {
// Create new JS element
var js = document.createElement('SCRIPT');
js.type = 'text/javascript';
ajad_ndx_script++;
js.id = 'ajad-' + ajad_ndx_script;
js.src = u;


// Append JS element (therefore executing the 'AJAX' call)
document.body.appendChild(js);


return true;
}


function ajad_get (r) {
// Create URL
var u = r;




// Do AJAD
return ajad_do(u);
}


function ajad_send(url) {
// referrer
// r = window.location;


var r = url;
// send it
ajad_get(r);


// remove the last script node.
document.body.removeChild(document.getElementById('ajad-' + ajad_ndx_script));
ajad_ndx_script--;
}


3. Create empty.php file and fill it with:
<?
$q=$REQUEST_URI;
include_once("functions.php");
save_file($q, "clickcount.txt");
?>


4. Statistics
Allow at least 2 days for the clicks to accumulate. If you open clickcount.txt in your browser you'll see the x,y coordinates of the user clicks.
In order to visualize the gathered data create file click_count.php with the following contents:

<?
Header("Content-Type: image/png" );
$width=1024;
$height=4300;
$im=ImageCreate($width,$height);
$red = ImageColorAllocate ( $im, 255, 0, 0 );
$white = ImageColorAllocate ( $im , 255, 255, 255 );
$black = ImageColorAllocate ( $im ,0, 0, 0 );
$blue = ImageColorAllocate ( $im , 0 , 0 , 255 );
$gray = ImageColorAllocate ( $im , 0xC0, 0xC0 , 0xC0 );
ImageFill ( $im , 0 , 0 , $black );
$file="clickcount.txt";
$fp = fopen ( $file, 'r' ) or die("error opening file");
$file=fread($fp,filesize($file));
$splitted  = explode ("\n", $file);

for ($i=0;$i<count($splitted); $i++){
if (! is_string($splitted[$i]))  return false;
$arr_query=NULL;
$url=parse_url($splitted[$i]);
$url=$url['query'];
parse_str($url,$vars);
$x = $vars['x'];
$y = $vars['y'];
imagesetpixel($im,$x,$y,$white);
}
Imagepng ($im);
imagedestroy($im);
?>

website heat map

Here is a sample generated heatmap screenshot: Click to see the whole image.
heat map

I know that the above mentioned code could be optimized so your suggestions are always welcome! by Nevyan Neykov



12 коментара :

Anonymous said...

where is the functions.php file ??!!

Nevyan said...

functions.php file defines the function save_file() that appends and saves string to a file.

save_file($q, "clickcount.txt");

Anonymous said...

Please can you check this script and perhaps comment it as it does not work! Many thanks.


Header("Content-Type: image/png" );
$width=1024;
$height=1000;
$im=ImageCreate($width,$height);
$red = ImageColorAllocate ( $im, 255, 0, 0 );
$white = ImageColorAllocate ( $im , 255, 255, 255 );
$black = ImageColorAllocate ( $im ,0, 0, 0 );
$blue = ImageColorAllocate ( $im , 0 , 0 , 255 );
$gray = ImageColorAllocate ( $im , 0xC0, 0xC0 , 0xC0 );
ImageFill ( $im , 0 , 0 , $black );
$file="clickcount.txt";
$fp = fopen ( $file, 'r' ) or die("error opening file");
$file=fread($fp,filesize($file));
$splitted = explode ("\n", $file);
for ($i=0;$i[count($splitted); $i++){
if (!is_string($splitted[$i])) return false;
$arr_query=NULL;
$url=parse_url($splitted[$i]);
$url=$url['query'];
parse_str($url,$vars);
$x = $vars["x"];
$y = $vars["y"];
imagesetpixel($im,$x,$y,$white);
}
Imagepng ($im);
imagedestroy($im);

Nevyan said...

In order to work you've got to have already created file clickcount.txt

second check whether your hosting provider has disabled some of the functions for example with:

ImageCreate($width,$height) or die("error ImageCreate not supported!");

for the save_file() function here it is:

function save_file($message, $filename) {
trim($message);
$message=str_replace(" ","",$message);
if ($message!=""){
$message="\n".$message;
$fp = fopen($filename, "a") or die("error opening");
$write = fputs($fp, $message);
fclose($fp);
}
}

Martin Terp Jensen said...

hmm, how do you get the big fanzy color thingies on the heat map?

Nevyan said...

These are just example screenshots from other services. Otherwise you can implement some graphical function to analyze the already gathered data.

Anonymous said...

please help i get this error "The image “http://XXXXXX.com/files/click_count.php” cannot be displayed, because it contains errors."

I would love to get this working..

Tensor said...

Hi,

You could also just sign up for a mouse eye tracking account (www.picnet.com.au/met/). This is free and comes with heat maps, click maps, etc

Website Value said...

Awesome! Thanks, good and very accurate.

Anonymous said...

I need some help
I can not get it to write to .txt
file
Using IIs 7.5
php 5.3.6
when I use firefox's web console I get
[00:22:58.694] GET http://www.mysite.co.cc/empty.php?x=79&y=80 [HTTP/1.1 500 Internal Server Error 11ms]

Anonymous said...

Good posting. Shouldn't the 'clickcount.txt' be updated any time there is a click, or does the information really need 2 days to be assimilated?

Nevyan said...

To resolve the writing problem, please chmod your file permissions to 644 and directory permissions to 755.

Post a Comment