Visitor Map for Piwik Web Analytics

If you’re using Piwik, the open source web analytics tool, then you probably already missed a map visualization of your visitors location, which is a standard feature of all major web analytics tools. As I really like the idea of open source and decentral web analytics and also gained some experiences on map visualizations, I decided to contribute a map plugin to the Piwik community.

Download

You can download the plugin here: UserCountryMap.zip

Update: the current version of my plugin relies on features, that are not available in Piwik 0.6.4 yet, so it doesn’t work now. You have to either wait for the final release of Piwik 1.0, which will be released in August 2010 and will include the map plugin by default, or checkout the current development version via svn.

Features

Interactive world map: The plugin provides a new dashboard widget showing an interactive world map. The countries are colored according to the selected data metric (like number of unique visitors). It is possible to zoom into certain regions to get a closer look at smaller countries. While moving the mouse over countries, tooltips show the exact value and its ratio.

Piwik API integration: The map is fully integrated into the new Piwik report API, so there is no limitation on the displayed data metrics.

Legend: Besides the map there is a small legend that helps to interpret the country colors. This is especially helpful, if you want to print out the map.

Fullscreen: You can set the map into fullscreen mode. This is very handy if you’re working on a smaller screen.

Image export: It is possible to download the current map view as PNG image, just like the other flash-based charts in Piwik. The exported map view will be resized to 1000px width. You can even export high-resolution images by using the image export while in fullscreen mode (accessible via context menu).

Screenshot

This is how the widget looks, after zooming into Europe:

Here is an example for the new fullscreen mode (click image to enlarge):

Current progress / Roadmap

The plugin is ready and waits for the release of Piwik 1.0.
Update: Since Piwik 0.9 the map plugin is one of the core plugins that are also activated by default.

Future versions
There are some more features, which I would like to implement in the future. One is to display vistitors cities as implemented in Google Analytics. This feature needs further improvement on the GeoIP plugin, because by now Piwik does only store the visitors country but not the city. Once this features makes it into Piwik core I’ll update the map plugin.

Donate

If you like the plugin, please support the developer with a small donation via paypal or flattr.


Flattr this

Simplification of Country Outlines

Simplification is a common task in vector-based map visualization. In some situations you don’t want to display a map in its full resolution for reasons like the overall filesize and the rendering time. One major class of simplification algorithms works by removing some vertices without moving the remaining ones. While there are already some good tutorials for implementation of line simplification algorithms online1, none of them takes into account the special requirements of map data simplifications. This gap will be closed by this post. Continue reading

Helper Class For Delayed Code Execution In AS3

This is a small class that I use very often. Its purpose is to simplify the execution of methods after a specific delay. Normally you would have to create a new Timer instance, attach an event listener for the TimerEvent.TIMER event and find a way to store the arguments that you want to pass to the event handler. Using the DelayedExecution class, this whole process goes in one line of code:

function helloWorld(name:String, message:String):void {
	trace( name + ' says "' + message +'"' );
}
 
new DelayedExecution(4000, this, helloWorld, "john", "hello world");
// will result in a 'john says "hello world"' trace after 4 seconds

That’s all. First parameter is the delay in milliseconds, second is the object on which you want to call the method, third is the method itself and any following parameters will be passed to the method. Here you can grep the source of the DelayedExecution class. Feel free to use it for whatever you like.

package net.vis4.utils
{
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
 
	public class DelayedExecution
	{
		private var
			_obj:Object,
			_func:Function,
			_args:Array;
		/*
		 *  new DelayedExecution(100, Math, round, 4.5);
		 *
		 *  parameters:
		 *  - delay
		 *  - object
		 *  - function
		 *  - parameters
		 */
		public function DelayedExecution(... arguments)
		{
			if (arguments.length < 3) {
				trace('DelayedExecution-Error: missing arguments');
			} else {
				if (arguments[0] is uint || arguments[0] is Number) {
					if (arguments[1] is Object) {
						if (arguments[2] is Function) {
							_obj = arguments[1];
							_func = arguments[2];
							_args = [];
							if (arguments.length > 3) {
								for (var i:uint = 3; i < arguments.length; i++) {
									_args.push(arguments[i]);
								}
							}
							var t:Timer = new Timer(arguments[0] as Number, 1);
							t.addEventListener(TimerEvent.TIMER, exec);
							t.start();
						} else trace('DelayedExecution-Error: third argument should be a function');
					} else trace('DelayedExecution-Error: seconds argument should be an object (this-context of function)');
				} else trace('DelayedExecution-Error: first argument should be a number (milliseconds delay)');
			}
		}
 
		private function exec(e:Event = null):void
		{
			_func.apply(_obj, _args);
		}
	}
}