HexTile Map

by sridhar reddy

HTML

<script src="https://d3js.org/d3.v5.js"></script>
<script src="https://d3js.org/d3-hexbin.v0.2.js"></script>
<div id="chart-container">

</div>
<svg class="chart"></svg>

SCSS

#chart-container {
  width: 900px;
  height: 400px;
  border: 0px solid black;
  margin: 2px auto;
}

JavaScript

var chartContainerEl = document.getElementById('chart-container');
var duration = 1500;


var {
  height,
  width
} = chartContainerEl.getBoundingClientRect();

// @todo: Implement the margin.
var margin = {
  top: 0,
  right: 0,
  bottom: 0,
  left: 0
};

//Create SVG element
var svgGroup = d3.select("#chart-container").append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g");

function getColors(d, i) {
  return d3.interpolateYlOrRd(Math.random()); // @todo: Pick the colors from the data instead.
}

function update(data) {
  var t = d3.transition()
    .duration(750);

  var MapColumns = Math.ceil(data.length / Math.floor(Math.sqrt(data.length)));
  var MapRows = Math.ceil(data.length / MapColumns);

  //The maximum radius the hexagons can have to still fit the screen
  var hexRadius = Math.floor(d3.min([width / ((MapColumns + 0.5) * Math.sqrt(3)),
    height / ((MapRows + 1 / 3) * 1.5)
  ]));

  var points = [];
  for (var i = 0, count = 0; i < MapRows; i++) {
    for (var j = 0; j < MapColumns && count <= data.length - 1; j++, count++) {
      const value = data[count];
      points.push([hexRadius * j * 1.75, hexRadius * i * 1.5]);
    }
  }

  var offSetX = hexRadius * Math.cos(30 * Math.PI / 180);
  var adjustedOffSetX = offSetX + ((width - (offSetX * 2 * MapColumns) - offSetX) / 2);
  var coverredHeight = (hexRadius * 2) + (MapRows * (3 * hexRadius / 4));
  var offSetY = hexRadius;

  //Set the hexagon radius
  var hexbin = d3.hexbin().radius(hexRadius);
  var zeroHexBin = d3.hexbin().radius(0);

  svgGroup
    .attr("transform", `translate(${adjustedOffSetX},${offSetY})`);

  //Draw the hexagons
  var hexagons = svgGroup
    .selectAll(".hexagon")
    .data(hexbin(points));

  hexagons
    .exit()
    .remove();

  hexagons
    .transition(t)
    .style("fill", getColors)
    .attr("d", function(d) {
      return "M" + d.x + "," + d.y + hexbin.hexagon();
    })

  hexagons
  ...