(function() { var global, mousemoved; global = { area: 1 }; /* whenever the mouse moves, compute a new area parameter for the simplification, then draw again the regions */ mousemoved = function() { global.area = global.mouse_scale.invert(d3.mouse(this)[0]); return global.svg.selectAll('.region, .boundary').attr('d', global.path_generator); }; window.main = function() { var colorify, dx, dy, height, radius, vis, width; width = 960; height = 500; /* prepare a scale for the mouse input */ global.mouse_scale = d3.scale.sqrt().domain([0, 1e4]).range([0, width]); global.svg = d3.select('body').append('svg').attr('width', width).attr('height', height).on('mousemove', mousemoved); vis = global.svg.append('g').attr('transform', 'translate(640, 120)'); /* custom projection to make hexagons appear regular (y axis is also flipped) */ /* it also applies the Visvalingam simplification */ radius = 0.6; dx = radius * 2 * Math.sin(Math.PI / 3); dy = radius * 1.5; global.path_generator = d3.geo.path().projection(d3.geo.transform({ point: function(x, y, z) { /* draw only nodes that are "important" enough */ if (z >= global.area) { return this.stream.point(x * dx / 2, -(y - (2 - (y & 1)) / 3) * dy / 2); } } })); /* define a color scale (Colorbrewer's Set3) */ colorify = d3.scale.ordinal().domain(['A', 'B', 'C', 'D']).range(["#8dd3c7", "#ffffb3", "#bebada", "#fb8072"]); /* load topoJSON data */ return d3.json('readme.regions.topo.json', function(error, data) { /* presimplify the topology (compute the effective area (z) of each point) */ topojson.presimplify(data); /* draw the cells */ vis.selectAll('.region').data(topojson.feature(data, data.objects.regions).features).enter().append('path').attr('class', 'region').attr('d', global.path_generator).attr('fill', function(d) { return colorify(d.properties['class']); }); /* draw the boundaries */ vis.append('path').datum(topojson.mesh(data, data.objects.regions, function(a, b) { return a === b; })).attr('d', global.path_generator).attr('class', 'outer boundary'); return vis.append('path').datum(topojson.mesh(data, data.objects.regions, function(a, b) { return a !== b; })).attr('d', global.path_generator).attr('class', 'boundary'); }); }; }).call(this);