JSFiddle - React, Tailwind, and code Playground

by Allen Sirolly

HTML

<script src="https://d3js.org/d3.v4.min.js"></script>
<body>
  <div id='viz'>
  </div>
</body>

CSS

.graticule {
  fill: none;
  stroke: #777;
  stroke-width: .5px;
  stroke-opacity: .5;
}

JavaScript

function createMap() {
	var width = 600,
      height = 400,
      scale = 100,
      origin = {x: 55, y:-40};
  
	var svg = d3.select('div').append('svg')
    .style('width', 600)
    .style('height', 400)
    .style('border', '1px lightgray solid')

  var projection = d3.geoOrthographic()
    .scale(scale)
    .translate([width/2, height/2])
    .rotate([origin.x, origin.y])
    .center([0,0])
    .clipAngle(90);

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

  var graticule = d3.geoGraticule();

	// zoom AND rotate
	svg.call(d3.zoom().on('zoom', zoomed))
     .call(d3.drag().on('drag', dragged));

	// code snippet from http://stackoverflow.com/questions/36614251
	var λ = d3.scaleLinear()
	  .domain([-width, width])
	  .range([-180, 180])

	var φ = d3.scaleLinear()
	  .domain([-height, height])
	  .range([90, -90]);

	svg.append('path')
	   .datum(graticule)
	   .attr('class','graticule')
	   .attr('d', geoPath);

	function dragged() {
		var transform = d3.event.transform;
		var r = {x: λ(transform.x), y: φ(transform.y)};
		projection.rotate([origin.x + r.x * k, origin.y + r.y]);
		updatePaths(svg, graticule, geoPath);
	};
  
	function zoomed() {
		var transform = d3.event.transform;
		var k = Math.sqrt(100/projection.scale());    
		projection.scale(scale*transform.k)
		updatePaths(svg, graticule, geoPath);
	};

};

function updatePaths(svg, graticule, geoPath) {
	svg.selectAll('path.graticule').datum(graticule).attr('d', geoPath);
};

createMap();