JSFiddle - React, Tailwind, and code Playground
by justinbrown
HTML
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="https://raw.github.com/wycats/handlebars.js/1.0.0-rc.3/dist/handlebars.js"></script>
<script src="https://raw.github.com/emberjs/ember.js/release-builds/ember-1.0.0-rc.3.js"></script>
<script type="text/x-handlebars" data-template-name="application">
<input id="nodeName" type="search" placeholder="Search"></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>
<svg {{bindAttr height="App.height" width="App.width"}}></svg>
</script>
CSS
html, body, .ember-view {
margin: 0;
padding: 0;
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;
}
#tooltipEditor {
position: absolute;
right: 20px;
top: 10px;
}
}
JavaScript
var App = window.App = Ember.Application.create({
height: $('body').height(),
width: $('body').width()
});
App.ApplicationView = Em.View.extend({
nodes: Em.A(),
links: Em.A(),
didInsertElement: function () {
var self = this,
svg = d3.select('svg').on("mousemove", function () {
cursor.attr("transform", "translate(" + d3.mouse(this) + ")");
}).on("mousedown", function () {
console.log('add node to screen');
var nodes = self.get('nodes'),
links = self.get('links'),
nodeName = $('#nodeName').val(),
point = d3.mouse(this),
node = {
x: point[0],
y: point[1],
name: nodeName,
fixed: true
};
console.log('node', node);
if (nodeName.length) {
nodes.push(node);
// add links to any nearby nodes
nodes.forEach(function (target) {
var x = target.x - node.x,
y = target.y - node.y;
if (Math.sqrt(x * x + y * y) < 30) {
links.push({
source: node,
target: target,
tooltip: ''
});
}
});
$('#nodeName').val('');
self.restart();
}
}),
cursor = svg.append("circle")
.attr("r", 30)
.attr("transform", "translate(-100,-100)")
.attr("class", "cursor");
var force = d3.layout.force()
.size([App.get('width'), App.get('height')])
.nodes([])
.linkDistance(60)
...