var height = 800; var width = 1200; var radius = 50; var points_lattice = []; //vertical align is perfect.... //Horizontal align is slightly off var xSpacing = 51.96*radius/30; var ySpacing = 45*radius/30; for (x = 0; x < width; x+=xSpacing) { var alt = false; for (y = 0; y < height; y+=ySpacing) { if (alt) { points_lattice.push([x+xSpacing/2,y]); } else { points_lattice.push([x,y]); } alt = !alt } } var color = d3.scale.linear() .domain([0, 20]) .range(["white", "#6EA241"]) .interpolate(d3.interpolateLab); var hexbin = d3.hexbin() .size([width, height]) .radius(radius); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) svg.selectAll(".hexagon") .data(hexbin(points_lattice)) .enter().append("path") .attr("class", "hexagon") .attr("d", hexbin.hexagon()) .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) .style("fill", function(d) { return color(d.length); }) .each(function(d) { svg.append('circle') .attr("cx", d.x + Math.sin(Math.PI/3)*radius) .attr("cy", d.y - Math.cos(Math.PI/3)*radius) .attr("r", 2.9) .style('fill', 'grey') .style('stroke', 'lightgreen') svg.append('circle') .attr("cx", d.x + Math.sin(Math.PI/3)*radius) .attr("cy", d.y + Math.cos(Math.PI/3)*radius) .attr("r", 2.9) .style('fill', 'pink') .style('stroke', 'lightgreen') svg.append('circle') .attr("cx", d.x) .attr("cy", d.y) .attr("r", 30) //Math.sin(Math.PI/3)*radius -> touches edge perfectly .style('fill', 'black') }) //Drawing original points svg.selectAll('circle.data') .data(points_lattice) .enter().append('circle') .attr("cx", function(d) {return d[0]; }) .attr("cy", function(d) {return d[1]; }) .style('r', 28) .style('fill', 'maroon') .style('border-radius', 1) .style('stroke', 'orange')