JSFiddle - React, Tailwind, and code Playground
by justinbrown
HTML
<script src="http://d3js.org/d3.v3.min.js"></script>
<input id="nodeName" type="search" placeholder="Search"></input>
<button id="saveBtn">Save</button>
<textarea id="saveText"></textarea>
<input id="loadInput" type="text" placeholder="Paste to load"></input>
<div id="tooltipEditor" style="display:none">
<p><b>Tooltip Editor</b></p>
<textarea id="tooltipInput"></textarea>
<p>
<input id="tooltipSave" type="submit" value="Save" />
</p>
</div>
CSS
html, body {
height: 100%;
width: 100%;
position: relative;
}
rect {
fill: none;
pointer-events: all;
}
.node {
fill: #000;
}
.cursor {
fill: none;
stroke: brown;
pointer-events: none;
}
.link {
stroke: #999;
stroke-opacity: .4;
stroke-width: 3px;
}
text {
font: 10px sans-serif;
pointer-events: none;
}
text.shadow {
stroke: #fff;
stroke-width: 3px;
stroke-opacity: .8;
}
div.tooltip {
position: absolute;
text-align: center;
/*width: 60px;
height: 28px;*/
padding: 6px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
.linkTooltip {
text-align: center;
padding: 6px;
font: 12px sans-serif;
background: lightsteelblue;
border-radius: 8px;
pointer-events: none;
}
#tooltipEditor {
position: absolute;
right: 20px;
top: 10px;
}
}
JavaScript
var w = $('body').width(),
h = $('body').height(),
selectedLink,
selectedNodes = [],
key = function(d) { return d.key; };
var force = d3.layout.force()
.size([w, h])
.nodes([])
.linkDistance(60)
.charge(-60)
.on("tick", tick);
d3.select("body")
.on("keydown", function() {
if($('#nodeName').is(':focus') || $('#tooltipInput').is(':focus')) {return;}
if(d3.event.keyCode == 68) {
console.log('deleting', 'nodes', nodes.length, 'links', links.length);
if(selectedNodes.length) {
var nodeToRemove = selectedNodes.pop();
console.log(nodes.indexOf(nodeToRemove));
nodes.splice(nodes.indexOf(nodeToRemove), 1);
var linksToKeep = [];
for(var i=0; i < links.length; i++) {
var l = links[i];
console.log('checking link', l.source == nodeToRemove, l.target == nodeToRemove);
if(l.source != nodeToRemove && l.target != nodeToRemove) {
linksToKeep.push(l);
}
}
links = linksToKeep;
restart();
}
else if(selectedLink) {
console.log(links.indexOf(selectedLink));
links.splice(links.indexOf(selectedLink), 1);
selectedLink = null;
$('#tooltipEditor').fadeOut();
$('#tooltipInput').val('');
restart();
}
console.log('deleting done!', 'nodes', nodes.length, 'links', links.length);
}
});
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h)
.on("mousemove", mousemove)
.on("mousedown", mousedown);
var nodes = force.nodes(),
links = force.links();
var cursor = svg.append("circle")
.attr("r", 30)
.attr("transform",...