Created
August 3, 2011 18:05
-
-
Save ralphbean/1123338 to your computer and use it in GitHub Desktop.
test with force directed stuff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Force-Directed Layout (Dynamic)</title> | |
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.min.js"></script> | |
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.geom.min.js"></script> | |
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.layout.min.js"></script> | |
<style type="text/css"> | |
html, body { | |
width: 100%; | |
height: 100%; | |
margin: 0; | |
padding: 0; | |
} | |
rect { | |
fill: #9A036D; | |
} | |
.source { | |
fill: #CC2704; | |
} | |
.target { | |
fill: #3D108B; | |
} | |
.link { | |
stroke: #8FC204; | |
} | |
.cursor { | |
fill: none; | |
stroke: brown; | |
pointer-events: none; | |
} | |
</style> | |
</head> | |
<body> | |
<script type="text/javascript"> | |
var MAX_LIFE = 25000; | |
var bonus = 2; | |
var w = 960; | |
var h = 500; | |
var fill = d3.scale.category20(); | |
var targets = []; | |
var sources = []; | |
var nodes = []; | |
var links = []; | |
var vis = d3.select("body").append("svg:svg") | |
.attr("width", w) | |
.attr("height", h); | |
vis.append("svg:rect") | |
.attr("width", w) | |
.attr("height", h); | |
var force = d3.layout.force() | |
.nodes(nodes) | |
.links(links) | |
.size([w, h]); | |
force.on("tick", function() { | |
vis.selectAll("line.link") | |
.attr("x1", function(d) { return d.source.x; }) | |
.attr("y1", function(d) { return d.source.y; }) | |
.attr("x2", function(d) { return d.target.x; }) | |
.attr("y2", function(d) { return d.target.y; }); | |
vis.selectAll("circle.node") | |
.attr("cx", function(d) { return d.x; }) | |
.attr("cy", function(d) { return d.y; }); | |
}); | |
function remove_links_for_node(node) { | |
for ( var i=0; i < links.length; i++ ) { | |
if ( links[i].source == node || links[i].target == node ) { | |
links[i].source.r -= bonus; | |
links[i].target.r -= bonus; | |
links.splice(i, 1); | |
return true; | |
} | |
} | |
return false; | |
} | |
function remove_node(node) { | |
for ( var i=0; i < sources.length; i++ ) { | |
if ( sources[i] == node ) { | |
sources.splice(i, 1); | |
return true; | |
} | |
} | |
for ( var i=0; i < nodes.length; i++ ) { | |
if ( nodes[i] == node ) { | |
nodes.splice(i, 1); | |
return true; | |
} | |
} | |
while (remove_links_for_node(node)) {} | |
restart(); | |
return false; | |
} | |
counter = 0; | |
function make_node(x, y) { | |
// Add the node | |
var node = { | |
x: x, | |
y: y, | |
ttl: Math.random() * MAX_LIFE, | |
r: 3, | |
id: counter, | |
}; | |
var n = sources.push(node); | |
var m = nodes.push(node); | |
counter++; | |
// add links randomly | |
if ( Math.random() > 0.20 ) { | |
var i = Math.floor(Math.random()*sources.length); | |
var target = sources[i]; | |
if ( node == target ) { return; } | |
if ( node != target ) { | |
link = {source: node, target: target}; | |
links.push(link); | |
node.r += bonus; | |
target.r += bonus; | |
} | |
} | |
// schedule the removal of the node we just added | |
setTimeout(function(){while(remove_node(node)){}}, node.ttl); | |
return node; | |
} | |
restart(); | |
function restart() { | |
var p; | |
p = vis.selectAll("line.link") | |
.data(links, function(d) { return d.source.id + "_" + d.target.id }); | |
p.enter().insert("svg:line", "circle.node") | |
.attr("class", "link") | |
.attr("x1", function(d) { return d.source.x; }) | |
.attr("y1", function(d) { return d.source.y; }) | |
.attr("x2", function(d) { return d.target.x; }) | |
.attr("y2", function(d) { return d.target.y; }); | |
p.exit().remove(); | |
// TODO -- the radius attribute doesn't get updated like I thought it | |
// would. | |
p = vis.selectAll("circle.node") | |
.data(sources, function(d) { return d.id }); | |
p.enter().insert("svg:circle", "circle.cursor") | |
.attr("class", "node") | |
.attr("cx", function(d) { return d.x; }) | |
.attr("cy", function(d) { return d.y; }) | |
.attr("r", function(d) { return d.r; }) | |
.call(force.drag); | |
p.exit().remove(); | |
force.start(); | |
} | |
setInterval( | |
function() { | |
make_node(w/2, h/2); | |
restart(); | |
}, 100); | |
</script> | |
</body> | |
</html> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment