JSFiddle - React, Tailwind, and code Playground

HTML

<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js"></script>
<script src="https://d3js.org/d3.v3.min.js"></script>
<!DOCTYPE html>
<body>
	<div class="sphere" id="sphere"></div>
</body>

CSS

body {
	padding: 0;
	margin: 0;
	background-color: #041A29
}
.link {
  stroke: #154361;
}
.node {
  fill: #2FB6D0;
  stroke: #000;
}
path.node {
	/*stroke-width: 1.5px;*/
	stroke: #041A29;
}
path.link {
stroke: #154361;
fill-opacity: 0
}
.sphere {
	margin: 0 auto;
	margin-top: 150px;
	width: 800px;
	height: 500px;
	transform: rotate(0deg);
	transform-origin: 0px 0px 0px;
}
.labels {
	fill: #fff;
	font-family:arial;
	font-size:9px;
	width: 100px;
	transform: rotate(0deg);
	transform-origin: 0px 0px 0px;
}
.labels textPath {
	transform-origin: none;
	transform: rotate(0deg);
}
div.tooltip {	
    position: absolute;			
    text-align: center;			
    width: 60px;					
    height: 28px;					
    padding: 2px;				
    font: 12px sans-serif;		
    background: lightsteelblue;	
    border: 0px;		
    border-radius: 8px;			
    pointer-events: none;			
}

JavaScript

var projections = {
	"Albers": d3.geo.albers(),
	"Azimuthal Equal Area": d3.geo.azimuthalEqualArea(),
	"Azimuthal Eqidistant": d3.geo.azimuthalEquidistant(),
	"Conic Conformal": d3.geo.conicConformal(),
	"Conic Equal Area": d3.geo.conicEqualArea(),
	"Conic Equidistant": d3.geo.conicEquidistant(),
	"Eqirectangular": d3.geo.equirectangular(),
	"Gnomonic": d3.geo.gnomonic(),
	"Mercator": d3.geo.mercator(),
	"Orthographic": d3.geo.orthographic(),
	"Stereographic": d3.geo.stereographic(),
	"Transverse Mercator": d3.geo.transverseMercator(),
	};
var config = { "projection": "Orthographic", "clip": true, "friction": .9, "linkStrength": 1, "linkDistance": 60, "charge": 300, "gravity": .1, "theta": .8 };
var gui = new dat.GUI();

var width = 700,
	height = 400,
	fill = d3.scale.category20(),
	nodes = [{x: width/2, y: height/2}],
	links = [];

for(x=0;x<200;x++) {
	source = nodes[~~(Math.random() * nodes.length)]
	target = {id: 'label-'+x, x: source.x + Math.random(), y: source.y + Math.random(), group: Math.random()}
	links.push({source: source, target: target})
	nodes.push(target)
}

var projection = projections[config["projection"]]
	.scale(height/2)
	.translate([(width/2)-125, height/2])
	.clipAngle(config["clip"] ? 90 : null)

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

// Define the div for the tooltip
var div = d3.select("body").append("div")	
    .attr("class", "tooltip")				
    .style("opacity", 0);

var svg = d3.select("#sphere").append("svg")
	.attr("width", width)
	.attr("height", height)
	.append("g")
	.attr("transform", "translate(" + width / 10 + "," + height / 200 + ")")
	.call(d3.behavior.drag()
	.origin(function() { var r = projection.rotate(); return {x: 2 * r[0], y: -2 * r[1]}; })
	.on("drag", function() { force.start(); var r = [d3.event.x / 2, -d3.event.y / 2, projection.rotate()[2]]; t0 = Date.now(); origin = r; projection.rotate(r); }))

var force =...