d3 map

by Gopinath Kaliappan

HTML

<script src="//d3js.org/d3.v4.min.js"></script>
<script src="//d3js.org/d3-tile.v0.0.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<!DOCTYPE html>
<meta charset="utf-8">
<svg></svg>

CSS

body {
  margin: 0;
}

path {
  fill: none;
  stroke: red;
  stroke-linejoin: round;
  stroke-width: 1.5px;
}

JavaScript

var pi = Math.PI,
  tau = 2 * pi;

var width = Math.max(960, window.innerWidth),
  height = Math.max(500, window.innerHeight),
  active = d3.select(null);

// Initialize the projection to fit the world in a 1Ă—1 square centered at the origin.
var projection = d3
  .geoMercator()
  .scale(1 / tau)
  .translate([0, 0]);

var path = d3.geoPath().projection(projection);

var tile = d3.tile().size([width, height]);

var zoom = d3
  .zoom()
  .scaleExtent([1 << 11, 1 << 14])
  .on("zoom", zoomed);

var svg = d3
  .select("svg")
  .attr("width", width)
  .attr("height", height);

svg
  .append("rect")
  .attr("class", "background")
  .attr("width", width)
  .attr("height", height)
  .on("click", reset);

var g = svg.append("g").style("stroke-width", "1.5px");

var raster = g.append("g");

var vector = g.append("g").attr("id", "vector");

function clicked(d) {
  if (active.node() === this) return reset();
  active.classed("active", false);
  active = d3.select(this).classed("active", true);

  var bounds = path.bounds(d),
    dx = bounds[1][0] - bounds[0][0],
    dy = bounds[1][1] - bounds[0][1],
    x = (bounds[0][0] + bounds[1][0]) / 2,
    y = (bounds[0][1] + bounds[1][1]) / 2,
    scale = 0.9 / Math.max(dx / width, dy / height),
    translate = [width / 2 - scale * x, height / 2 - scale * y];
  console.log("bounds", bounds);

  g
    .transition()
    .duration(750)
    .style("stroke-width", 1.5 / scale + "px")
    .attr("transform", "translate(" + translate + ")scale(" + scale + ")");
}

function reset() {
  active.classed("active", false);
  active = d3.select(null);

  g
    .transition()
    .duration(750)
    .style("stroke-width", "1.5px")
    .attr("transform", "");
}

function stopped() {
  if (d3.event.defaultPrevented) d3.event.stopPropagation();
}

function zoomed() {
  var transform = d3.event.transform;

  var tiles = tile.scale(transform.k).translate([transform.x, transform.y])();

  projection.scale(transform.k / tau).translate([transform.x,...