(function() { var new_hex; window.main = function() { var colorify, d, data, dx, dy, height, hexes, path_generator, radius, svg, vis, width; width = 960; height = 500; svg = d3.select('body').append('svg').attr('width', width).attr('height', height); vis = svg.append('g').attr('transform', 'translate(400,300)'); /* create the GeoJSON */ data = [ { x: 0, y: 0, z: 0, type: 'A' }, { x: 1, y: 0, z: -1, type: 'D' }, { x: 1, y: -1, z: 0, type: 'C' }, { x: 2, y: -2, z: 0, type: 'C' }, { x: 2, y: -1, z: -1, type: 'B' }, { x: -1, y: -1, z: 2, type: 'B' }, { x: -1, y: 0, z: 1, type: 'D' }, { x: -5, y: 1, z: 4, type: 'B' }, { x: 4, y: -7, z: 3, type: 'C' } ]; hexes = { type: 'FeatureCollection', features: (function() { var _i, _len, _results; _results = []; for (_i = 0, _len = data.length; _i < _len; _i++) { d = data[_i]; _results.push(new_hex(d)); } return _results; })() }; /* define a color scale */ colorify = d3.scale.category10().domain(['A', 'B', 'C', 'D']); /* custom projection to make hexagons appear regular (y axis is also flipped) */ radius = 32; dx = radius * 2 * Math.sin(Math.PI / 3); dy = radius * 1.5; path_generator = d3.geo.path().projection(d3.geo.transform({ point: function(x, y) { return this.stream.point(x * dx / 2, -(y - (2 - (y & 1)) / 3) * dy / 2); } })); /* draw the result */ vis.selectAll('.hex').data(hexes.features).enter().append('path').attr('class', 'hex').style('fill', function(d) { return colorify(d.properties.type); }).attr('d', path_generator); /* draw the origin */ return vis.append('circle').attr('cx', 0).attr('cy', 0).attr('r', 4); }; /* create a new hexagon */ new_hex = function(d) { /* conversion from hex coordinates to rect */ var x, y; x = 2 * (d.x + d.z / 2.0); y = 2 * d.z; return { type: 'Feature', geometry: { type: 'Polygon', coordinates: [[[x, y + 2], [x + 1, y + 1], [x + 1, y], [x, y - 1], [x - 1, y], [x - 1, y + 1], [x, y + 2]]] }, properties: { type: d.type } }; }; }).call(this);