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...