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:
- Get the data from server log files and geolocate IP addresses.
- 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.
It looks nice Nathan, but why? A similar thing is available in google analytics. I assume you were just having some playtime?
btw, the spike from Oz might have been me! :)
@Tim – several reasons… i’m sick of online mapping being synonymous with google maps, so it’s good for people to know about what’s out there. Visitr is really just tip of the iceberg as far as what you can do functionally. Lastly, people who learn principles from this basic map can apply the same ideas to say, something like the Walmart map and then far beyond that.
So really the reasons go far beyond Visitr.
Great work!
Beautiful! And thanks for keeping it open.
@Chris – thanks!
@Ian – sure :) keep an eye out for plenty more open source code
just to mention that there is clustrmaps i that sounds similar too. prob already know.
Just sort of stumbled upon this and think it’s cool thing that I’d like to include on my website. I down loaded the code but I understand nothing. And when I say nothing I mean I haven’t even been able to find the GeoCitylite.data stuff, can anyone give me a hint on how to get started ??
I tried the sample code, but my hosting service has disabled the fopen() PHP function for security reasons.
I’m going to try modifying the geoip.inc file to use CURL instead, hopefully that will do the trick…
@Kevin – hopefully :). let me know if it does
Try this one out: http://www.populatetheweb.com
It’s supposed to be real-time not delayed. Not sure if it is or not.
Pingback: MungoSmash » Real-Time Earthquake Map
Thanks for the post Nathan. It got me motivated just enough to build an earthquake viewer using the same tools.
http://blog.mungosmash.com/2008/12/realtime-earthquake-map
I think it looks a lot prettier than the maps provided on the USGS page :)
Great work. Do you have a version witten for Groovy ? We are a Java shop with no PHP support in our Web App Container (Tomcat 6).