(function() { var categories, classes, colorify, data_url, geo_url, height, path_generator, projection, radius, svg, width, zoom, zoom_group; width = 960; height = 500; radius = 2; svg = d3.select('svg'); zoom_group = svg.append('g'); zoom = d3.behavior.zoom().scaleExtent([1, 4]).on('zoom', function() { zoom_group.attr('transform', "translate(" + (zoom.translate()) + ")scale(" + (zoom.scale()) + ")"); return zoom_group.selectAll('.place').attr('r', radius / zoom.scale()); }); svg.call(zoom); projection = d3.geo.azimuthalEqualArea().clipAngle(180 - 1e-3).scale(160000).rotate([-10.277475, -42.789034, 0]).translate([width / 2, height / 2]).precision(0.1); path_generator = d3.geo.path().projection(projection); categories = ['restaurant', 'attraction', 'poi', 'accommodation']; classes = categories.length; colorify = d3.scale.category10().domain(categories); data_url = 'http://wafi.iit.cnr.it/webvis/tmp/elba_places.json'; geo_url = 'http://wafi.iit.cnr.it/webvis/italiastat/data/istat/2011/reg2011.topo.json'; d3.json(geo_url, function(geo) { var regions; regions = topojson.feature(geo, geo.objects.reg2011); zoom_group.selectAll('.region').data(regions.features).enter().append('path').attr('class', 'region').attr('d', path_generator); return d3.json(data_url, function(points) { var angle, apothem, arc_generator, bins, hexbin, max, max_tot, pie_layout, pies, radius_scale, subplots; radius = 16; apothem = Math.sqrt(3) / 2 * radius; hexbin = d3.hexbin().size([width, height]).radius(radius).x(function(d) { return projection([d.lng, d.lat])[0]; }).y(function(d) { return projection([d.lng, d.lat])[1]; }); bins = _.chain(hexbin(points)).forEach(function(bin) { return bin.classes_count = _.chain(categories).map(function(klass) { var count; count = bin.filter(function(point) { return point.category === klass; }).length; return { count: count, "class": klass }; }).value(); }).value(); max_tot = d3.max(bins, function(bin) { return bin.length; }); max = d3.max(bins, function(bin) { return d3.max(bin.classes_count, function(count) { return count.count; }); }); angle = 2 * Math.PI / classes; subplots = zoom_group.selectAll('.subplot').data(bins); subplots.enter().append('g').attr({ "class": 'subplot', transform: function(bin) { return "translate(" + bin.x + "," + bin.y + ")"; } }); pie_layout = d3.layout.pie().sort(null).value(function(count) { return count.count; }); radius_scale = d3.scale.sqrt().domain([0, max_tot]).range([0, apothem]); arc_generator = d3.svg.arc().outerRadius(function(count) { return radius_scale(d3.select(this.parentNode).datum().length); }).innerRadius(0); pies = subplots.selectAll('.pie').data(function(bin) { return pie_layout(bin.classes_count); }); return pies.enter().append('path').attr({ "class": 'pie', d: arc_generator, fill: function(count) { return colorify(count.data["class"]); } }); }); }); }).call(this);