block by gka 1771315

Map of Italy

Full Screen

Map of Italy

Based on Kartograph.js, RaphaelJS, jQuery and chroma.js.

see it in action

index.html

<!DOCTYPE html>
<html>
<head>
	<title>YourTopia 2.0 – Map of Italy</title>
	<script src="jquery-1.7.1.min.js"></script>	
	<script src="jquery.qtip.min.js"></script>	
	<script src="raphael-min.js" type="text/javascript"></script>
	<script src="kartograph.min.js"></script>	
	<script src="chroma.pack.min.js"></script>	
	<script src="app.js" type="text/javascript"></script>

	<link rel="stylesheet" href="style.css" />
	<link rel="stylesheet" href="tooltips.css" />

</head>
<body>
	<div id="wrap">
		<div id="map">
		
		</div>
		<div id="config">
			
			<h1>Hello Italy</h1>
			
			<p>Indicator: <select class="config" id="indicator"></select></p>
			<p>Color scale: <select class="config" id="colors"></select></p>
			<p>Scale type: <select class="config" id="scaletype">
				<option value="e">equidistant</option>
				<option value="q">quantiles</option>
				<option value="k">k-means cluster</option>
				<option value="c">continious</option>
			</select></p>
			
			<h3>Legend</h3>
			<div id="legend"></div>
			
			<p style="margin-top:2em">source: <a href="https://gist.github.com/1771315">this app</a>, <a href="https://gist.github.com/1779771">svg map</a></p>
		</div>
	</div>
</body>
</html>

app.js

$(function() {
	
	function fmt_amount(a) {
		a*=1000000;
		if (a > 1000000000) a = Math.round(a/100000000)/10 + ' bio';		
		else if (a > 1000000) a = Math.round(a/100000)/10 + ' mio';
		else if (a > 1000) a = Math.round(a/100)/10 + ' k';
		else a = Math.round(a*10)/10;
		return '€ '+a;
	};
	
	function fmt_percent(a) {
		return Math.round(a*10)/10 + '%';
	}
	
	var indicators = {
		'gdp_ppp': ['GDP in PPP', fmt_amount],
		'empl': ['Employment', fmt_percent],
		'youth_unempl': ['Youth Unemployment', fmt_percent],
		'lt_unempl': ['Long-term unemployment', fmt_percent],
		'ren_energy': ['Renewable Energy Share', fmt_percent]
	},
	
	colorscales = [
		'Oranges','Reds','Blues','Greens','Purples','Greys',
		'OrRd','PuBu','BuPu','BuGn','YlOrBr','GnBu','PuRd','PuBuGn'];
	
	$.each(indicators, function(k,v) {
		$('#indicator').append('<option value="'+k+'">'+v[0]+'</option>');
	});
	
	$.each(colorscales, function(i,v) {
		$('#colors').append('<option>'+v+'</option>');
	});
	
	
	$.ajax({
		url: 'data.json',		
		success: function(data) {
			
			var map, colsc, tt, i, values, prop, prop_fmt;

			// make sure the map fits inside browser window
			$('#map').height(Math.max(500, $(window).height()-60));
			
			/*
			 * updates the map after changing display properties
			 */
			function updateMap() {			
				prop = $('#indicator').val();	
				prop_fmt = indicators[prop][1]
			
				map.clear(); // remove everything from the map
				
				// first map layer for colored fills
				map.addLayer({
					id: 'regions',
					key: 'nuts2'
				});
				
				// populate tooltip contents
				tt = {};
				$.each(data, function(i,d) {
					d[prop] = Number(d[prop]);
					tt[d.nuts] = [d.nuts, indicators[prop][0]+': '+prop_fmt(d[prop])];
				});
				
				// initialise color scale
				colsc = new chroma.ColorScale({
					colors: chroma.brewer[$('#colors').val()],
					limits: chroma.limits(data, $('#scaletype').val(), 9, prop)
				});
	
				// update legend
				var i,v,c,r,leg = $('#legend');
				leg.html('');					
				if ($('#scaletype').val() != 'c') {
					for (i=0;i<colsc.classLimits.length-1;i++) {
						v=colsc.classLimits[i]+(colsc.classLimits[i+1]-colsc.classLimits[i])*.5;
						c = colsc.getColor(v);
						r = $('<div class="row" />');
						r.append('<div class="col" style="background:'+c+'" />');
						r.append('<label>'+prop_fmt(colsc.classLimits[i])+' &nbsp;–&nbsp; '+prop_fmt(colsc.classLimits[i+1])+'</label>');
						leg.append(r);
					}
				} else {
					
					for (i=0;i<100;i++) {
						v = colsc.min + (i/99)* (colsc.max-colsc.min);
						c = colsc.getColor(v);
						r = $('<div style="width:40px;height:3px;background:'+c+'" />');
						leg.append(r);
					}
					leg.append('<label style="position: absolute; left: 50px; top: 0px">'+prop_fmt(colsc.min)+'</label>');
					leg.append('<label style="position: absolute; left: 50px; bottom: 0px">'+prop_fmt(colsc.max)+'</label>');					
				}
				
				// color map polygons
				map.choropleth({
					data: data,
					key: 'nuts',
					colors: function(d) {
						if (d == null) return '#ccc';
						return colsc.getColor(d[prop]);
					}
				});
				
				// add another map layer on top for showing black outline on mouse hover
				map.addLayer({
					id: 'regions',
					className: 'outline',
					key: 'nuts2'
				});
				
				// and apply tooltips to this layer
				map.tooltips({
					content: tt
				});
			}
						
			$('.config').click(updateMap);
			$('.config').change(updateMap);
					
			map = $K.map('#map');
			map.loadMap('italy.svg', function(map) {
				updateMap();	
			});
		}
	});
});

data.json

[{"gdp_ppp": "113204.888888889", "empl": "67.1090909090909", "nuts": "ITC1", "id": "1", "youth_unempl": "16.7909090909091", "ren_energy": "0.871", "lt_unempl": "41.1363636363636"}, {"gdp_ppp": "3414.11111111111", "empl": "71.4636363636364", "nuts": "ITC2", "id": "2", "youth_unempl": "10", "ren_energy": "0.236", "lt_unempl": "26.3454545454545"}, {"gdp_ppp": "38750.8888888889", "empl": "65.3545454545455", "nuts": "ITC3", "id": "3", "youth_unempl": "18.3545454545455", "ren_energy": "0.703", "lt_unempl": "36.4363636363636"}, {"gdp_ppp": "292618.222222222", "empl": "69.1818181818182", "nuts": "ITC4", "id": "4", "youth_unempl": "13.1909090909091", "ren_energy": "2.284", "lt_unempl": "35.7272727272727"}, {"gdp_ppp": "14738", "empl": "72.8272727272727", "nuts": "ITD1", "id": "5", "youth_unempl": "6.80909090909091", "ren_energy": "NA", "lt_unempl": "16.9818181818182"}, {"gdp_ppp": "13980.8888888889", "empl": "70.1454545454545", "nuts": "ITD2", "id": "6", "youth_unempl": "11.5090909090909", "ren_energy": "NA", "lt_unempl": "22.0181818181818"}, {"gdp_ppp": "131244.222222222", "empl": "68.4181818181818", "nuts": "ITD3", "id": "7", "youth_unempl": "11.4181818181818", "ren_energy": "1.076", "lt_unempl": "26.6363636363636"}, {"gdp_ppp": "31973.8888888889", "empl": "67", "nuts": "ITD4", "id": "8", "youth_unempl": "13.6909090909091", "ren_energy": "1.243", "lt_unempl": "30.4909090909091"}, {"gdp_ppp": "122009.222222222", "empl": "72.5909090909091", "nuts": "ITD5", "id": "9", "youth_unempl": "11.9909090909091", "ren_energy": "2.804", "lt_unempl": "27.0363636363636"}, {"gdp_ppp": "93421.7777777778", "empl": "67.7727272727273", "nuts": "ITE1", "id": "10", "youth_unempl": "15.0818181818182", "ren_energy": "24.505", "lt_unempl": "42.5818181818182"}, {"gdp_ppp": "19217.4444444444", "empl": "66.8090909090909", "nuts": "ITE2", "id": "11", "youth_unempl": "15.9363636363636", "ren_energy": "1.709", "lt_unempl": "41.4272727272727"}, {"gdp_ppp": "36234.6666666667", "empl": "67.8090909090909", "nuts": "ITE3", "id": "12", "youth_unempl": "14.1636363636364", "ren_energy": "0.66", "lt_unempl": "38.1636363636364"}, {"gdp_ppp": "149662.666666667", "empl": "61.7090909090909", "nuts": "ITE4", "id": "13", "youth_unempl": "27.6636363636364", "ren_energy": "1.154", "lt_unempl": "48.4545454545455"}, {"gdp_ppp": "25550.4444444444", "empl": "61.7090909090909", "nuts": "ITF1", "id": "14", "youth_unempl": "24.8", "ren_energy": "2.481", "lt_unempl": "50.1545454545455"}, {"gdp_ppp": "5647.88888888889", "empl": "56.7181818181818", "nuts": "ITF2", "id": "15", "youth_unempl": "26.4454545454545", "ren_energy": "11.519", "lt_unempl": "52.7272727272727"}, {"gdp_ppp": "53482.4814814815", "empl": "50.1454545454545", "nuts": "ITF3", "id": "16", "youth_unempl": "36.9939393939394", "ren_energy": "5.30033333333333", "lt_unempl": "55.6242424242424"}, {"gdp_ppp": "30307.3333333333", "empl": "48.6636363636364", "nuts": "ITF6", "id": "17", "youth_unempl": "38.4454545454545", "ren_energy": "8.891", "lt_unempl": "57.1545454545455"}, {"gdp_ppp": "75925.8888888889", "empl": "47.5909090909091", "nuts": "ITG1", "id": "18", "youth_unempl": "42.9272727272727", "ren_energy": "2.138", "lt_unempl": "60.7"}, {"gdp_ppp": "29702.7777777778", "empl": "55.3", "nuts": "ITG2", "id": "19", "youth_unempl": "34.4818181818182", "ren_energy": "3.418", "lt_unempl": "52.0272727272727"}]

style.css

#map {
	width: 600px;
	margin-left: 400px;
}

#map svg path {
	stroke-width: .4px;
	stroke: #666;
	stroke-linecap: round;
	stroke-linejoin: round;
}

#map svg .outline {
	stroke: none;
	fill: #fff;
	fill-opacity: 0;
}


#map svg .outline:hover {
	stroke: #000;
	stroke-width: 2px;
}

#map svg circle{
	stroke: #000;
	stroke-width: 0px;
}

#wrap {
	width: 1000px;
	margin: 2em auto;
	position: relative;
}

#config {
	position: absolute;
	top: 0px;
	left: 0px;
	line-height: 2em;
}

body {
	font-weight: 300;
	font-family: Palatino, Georgia, Helvetica Neue, sans-serif;
}
select { padding: 4px; font-size:9pt;}

h1 {
	font-size: 40px;
}

#legend { position: relative; }
#legend .row { margin-bottom: 5px;}
#legend .col { width: 40px; height: 30px; float: left; margin-right: 10px;}

p { margin: 5px 0; }

tooltips.css

/*
* qTip2 - Pretty powerful tooltips
* http://craigsworks.com/projects/qtip2/
*
* Version: nightly
* Copyright 2009-2010 Craig Michael Thompson - http://craigsworks.com
*
* Dual licensed under MIT or GPLv2 licenses
*   http://en.wikipedia.org/wiki/MIT_License
*   http://en.wikipedia.org/wiki/GNU_General_Public_License
*
* Date: Mon Nov 21 13:18:18.0000000000 2011
*/




/* Core qTip styles */
.ui-tooltip, .qtip{
	position: absolute;
	left: -28000px;
	top: -28000px;
	display: none;

	max-width: 280px;
	min-width: 50px;
	
	font-size: 12px;
	line-height: 15px;
	font-family: Helvetica Neue;
	font-weight: 300;
	line-height: 1.5em;
	z-index: 15000;
}

	/* Fluid class for determining actual width in IE */
	.ui-tooltip-fluid{
		display: block;
		visibility: hidden;
		position: static !important;
		float: left !important;
	}

	.ui-tooltip-content{
		position: relative;
		padding: 5px 9px;
		overflow: hidden;
		
		border-width: 1px;
		border-style: solid;
		
		text-align: left;
		word-wrap: break-word;
		overflow: hidden;
	}

	.ui-tooltip-titlebar{
		position: relative;
		min-height: 14px;
		padding: 5px 35px 5px 10px;
		overflow: hidden;
		
		border-width: 1px 1px 0;
		border-style: solid;

		font-weight: bold;
	}

	.ui-tooltip-titlebar + .ui-tooltip-content{ border-top-width: 0px !important; }

		/*! Default close button class */
		.ui-tooltip-titlebar .ui-state-default{
			position: absolute;
			right: 4px;
			top: 50%;
			margin-top: -9px;

			cursor: pointer;
			outline: medium none;

			border-width: 1px;
			border-style: solid;
		}
		
		* html .ui-tooltip-titlebar .ui-state-default{ top: 16px; } /* IE fix */

		.ui-tooltip-titlebar .ui-icon,
		.ui-tooltip-icon .ui-icon{
			display: block;
			text-indent: -1000em;
		}

		.ui-tooltip-icon, .ui-tooltip-icon .ui-icon{
			-moz-border-radius: 3px;
			-webkit-border-radius: 3px;
			border-radius: 3px;
		}

			.ui-tooltip-icon .ui-icon{
				width: 18px;
				height: 14px;

				text-align: center;
				text-indent: 0;
				font: normal bold 10px/13px Tahoma,sans-serif;

				color: inherit;
				background: transparent none no-repeat -100em -100em;
			}


/* Applied to 'focused' tooltips e.g. most recently displayed/interacted with */
.ui-tooltip-focus{

}

/* Applied on hover of tooltips i.e. added/removed on mouseenter/mouseleave respectively */
.ui-tooltip-hover{
	
}


/*! Default tooltip style */
.ui-tooltip-default .ui-tooltip-titlebar,
.ui-tooltip-default .ui-tooltip-content{
	border-color: #777;
	background-color: #fff;
	color: #000;
	border-radius: 0 0 5px 5px;
	box-shadow: 3px 3px 5px rgba(0,0,0,.3);
}

	.ui-tooltip-default .ui-tooltip-titlebar{
		background-color: #222;
		color: #fff;
		border-radius: 5px 5px 0 0;
		font-size: 12px;
		font-weight: 300;
		text-transform: uppercase;
	}

	.ui-tooltip-default .ui-tooltip-icon{
		border-color: #CCC;
		background: #F1F1F1;
		color: #777;
		
	}
	
	.ui-tooltip-default .ui-tooltip-titlebar .ui-state-hover{
		border-color: #AAA;
		color: #111;
	}