JSFiddle - React, Tailwind, and code Playground

HTML

<script type='text/javascript' src='http://d3js.org/d3.v3.min.js'></script>
<div id='visualization'></div>

JavaScript

/*** START GLOBAL VARIABLES ***/
var NODE_ID_PREFIX = 'n';
var VIS_SVG_WIDTH = 500;
var VIS_SVG_HEIGHT = 500;
var nodes; //An object holding all the node objects
var edges; //An array holding all the edge objects
var force; //The actual force layout
var force_nodes; //The nodes in the layout - this is the data in nodes but now bound with visualization elements
var force_links; //The edges in the layout - this is the data in edges but now bound with visualization elements
			
//The SVG element, where the fun happens!
var visSVG = d3.select('#visualization')
	.append('svg:svg')
		.attr('id', 'visSVG')
		.attr('width', VIS_SVG_WIDTH)
		.attr('height', VIS_SVG_HEIGHT)
		.attr('pointer-events', 'all') //Needed to register events for zooming
	.append('svg:g')
		.call(d3.behavior.zoom().on('zoom', redraw))
	.append('svg:g');
			
//Set up a background image on the SVG to be used to register zoom events
visSVG.append('svg:rect')
	.attr('width', VIS_SVG_WIDTH)
	.attr('height', VIS_SVG_HEIGHT)
	.attr('fill', 'orange');
/*** END GLOBAL VARIABLES ***/
			
//Converts the edges array to hold index values of the source/target in nodes, rather than nodeIDs
function generateLinks() {
	for(var i = 0; i < edges.length; ++i) {
		edges[i].source = getNodeIndex(edges[i].source);
		edges[i].target = getNodeIndex(edges[i].target);
	}
};
			
//Returns the index of a node in the array of nodes. If it doesn't exist, returns -1
function getNodeIndex(id) {
	for(var i = 0; i < nodes.length; ++i) {
		if(nodes[i].nodeID == id) {
			return i;
		}
	}
	
	return -1;
};
			
//Redraws the visualization based on zoom level and location
function redraw() {
	visSVG.attr('transform', 'translate(' + d3.event.translate + ')' + ' scale(' + d3.event.scale + ')');
};
		
//Displays the force visualization of all the node groups
function force() {								
	//TODO: add arrows to show directions
	
	//Set up the force layout
	drawForce();
	
	//Update the layout with the data
	forceUpdate();
};

//Set up the force...