How to Create a Real-Time Web Traffic Map for Your Site

I was exchanging email with Rob a few days ago, and he brought up that I might see a slight boost in traffic from Australia because he had spread the word (thanks!) at a statistics conference. I immediately went over to Google Analytics, and indeed, there was an increase in traffic from the land down under.

That’s when I created Visitr, a way to see where your site visitors are coming from in near real-time, and after plenty of hearty discussion – it’s complete with open source code, so you can customize Visitr for your own site or application.

What is Visitr?

Visitr is essentially a map that shows bubbles in places your site visitors are, um, visiting from. Bubble size represents the number of requests a particular visitor made recently. I call it Visitr, because it’s easier to say than map thing that shows web traffic. I also put some gibberish on the bottom right corner using the city name of where I think you are. That’s just me messing around.

How Visitr Works

The map is written in Actionscript 3.0 and makes use of Modest Maps and TweenFilterLite – two very useful libraries I keep coming back to. The data (i.e. IP addresses) come from my Apache log files and I map the IP addresses to location with the free version of MaxMind’s GeoCity database.

Alright, enough blubbering. So how can you customize Visitr for your own website? Well there’s two parts here:

  1. Get the data from server log files and geolocate IP addresses.
  2. Map data in a way that doesn’t look ugly.

Let’s start with the first part – the data.

Geolocating IP Addresses

MaxMind provides an easy-to-use service, GeoIP City that maps IP addresses to cities. There’s a non-free service, which is about 99.6% accurate, but more importantly, there’s a free version – GeoLite City. The free service is only 77% accurate, but that’s good enough for this application. If you want to switch to the more accurate later, it’s only a matter of replacing a single file.

I included the PHP code to geolocate IP addresses in the source, but here’s the part of interest in /log/_helper.php:

<?php
include_once("Net/geoipcity.inc");
include_once("Net/geoipregionvars.php");
$gi = geoip_open("GeoLiteCity.dat", GEOIP_STANDARD);

/* 
 * Get location of ip_address
 */
function getLocation($ip_address) {
    global $gi;
    
    $record = geoip_record_by_addr($gi, $ip_address);
    return $record;
}

The Net folder is from MaxMind, but I can’t remember where I got it from. I bundled it in the source though. Just stick an IP address in getLocation() and it returns an object that holds country, state, city, zip code, and even latitude and longitude. Could this get any easier?

Load and Map the Data

Modest Maps and TweenFilterLite do most of the work when it comes to displaying the data. I use PHP to generate an XML file that contains locations and read it in to my Actionscript with loadData() on line 60 of Visitr.as. I load 40 or so IPs at a time. When I’m running out, I ask PHP for more data and load up the queue.

Customize the Map

One of my favorite parts about Modest Maps is how easy it is to use map tiles from various services like Google, Yahoo, or Microsoft or you can even use your own map. I used OpenStreetMap tiles, but you can use whatever you want. I just wanted something really simple. I actually tried blacking out the map at first and just showing the circles, but FlowingData doesn’t get enough traffic (yet) for that to be interesting.

On line 85 of Visitr.as I applied a filter to the map to give that dark grayscale appearance. How great is it that I only have to change one line of code to completely change my map’s appearance? This color matrix tool from AdobeTutorialz helps you decide what filter to apply.

Here are the few lines of code it took to draw and customize the map:

// Draw the map
map = new TweenMap(stage.stageWidth-20, stage.stageHeight-20, false, new OpenStreetMapProvider());
map.setExtent(new MapExtent(69.345206, -44.222107, -139.921875, 163.125000));
var mat:Array = [0.12344,0.24376,0.0328,0,-1.9,0.12344,0.24376,0.0328,0,-1.9,0.12344,0.24376,0.0328,0,-1.9,0,0,0,1,0];
map.grid.filters = [new ColorMatrixFilter(mat)];

Those four lines of code creates the map with OpenStreetMap tiles, sets the boundaries to the world, and then applies a filter to grayscale.

Create the Markers

Now for the blue markers. Take a look at /com/flowingdata/visitr/Marker.as. The method names are pretty self-explanatory. On line 43, play() makes the animation with TweenFilterLite. I start the marker at scale zero, tell it to grow, and then make it fade away over a minute. You can pretty much do whatever you want here. Be creative!

Places for Improvement

The first thing I’d probably do is optimize the data loading process. I’m not keeping track of the IPs that have been mapped already, so there could be some overlap as Visitr polls the Apache logs for more data. I’d also like to put an initial progress bar at the beginning to show data is loading.

I’m sure all of you can think of plenty of ways to improve Visitr, so why not give it a try? Make the map interactive with pan and zoom functionality or display the cities as markers pop up. I tried moving the map like Twitter World, but after watching it for a little while I felt a kinda nauseous.

Visitr is Free

Anyways, all the code is free and BSD-licensed, so have fun with it. If you implement any optimizations or come up with your own versions, I’d love to hear about it. Ideas? Improvements? Let me know in the comments.

13 Comments