Last active
December 14, 2015 12:38
-
-
Save vlandham/5087480 to your computer and use it in GitHub Desktop.
Simpler Force Directed Radial Layout
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> | |
<meta charset="utf-8"> | |
</style> | |
<body> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script> | |
D2R = Math.PI / 180; | |
var width = 960, | |
height = 500; | |
var node = []; | |
// here is the function that will | |
// determine the radial location for | |
// each node in the force layout. | |
// | |
// arbitrarily, it uses the nodes index in the | |
// the data array to pick out where it should | |
// land. In a real program, you might want to | |
// specify this by some grouping attribute | |
// | |
function radial(data, index, alpha) { | |
// check out the post | |
// http://macwright.org/2013/03/05/math-for-pictures.html | |
// for more info on how this works | |
var startAngle = 30; | |
var radius = 350; | |
var currentAngle = startAngle + (30 * index); | |
var currentAngleRadians = currentAngle * D2R; | |
// the 500 & 250 are to center the circle we are creating | |
var radialPoint = { | |
x: 500 + radius * Math.cos(currentAngleRadians), | |
y: 250 + radius * Math.sin(currentAngleRadians) | |
}; | |
// here we attenuate the effect of the centering | |
// by the alpha of the force layout. | |
// this gives other forces - like gravity - | |
// to have an effect on the nodes | |
var affectSize = alpha * 0.1; | |
// here we adjust the x / y coordinates stored in our | |
// data to move them closer to where we want them | |
// this doesn't move the visual circles yet - | |
// we will do that in moveToRadial | |
data.x += (radialPoint.x - data.x) * affectSize; | |
data.y += (radialPoint.y - data.y) * affectSize; | |
} | |
// this function gets called every 'tick' of the | |
// force layout | |
// first we call the above radial function on each | |
// node | |
// then we move each node based on its data's x/y | |
function moveToRadial(e) { | |
node.each(function(d,i) { radial(d,i,e.alpha); }); | |
node | |
.attr("cx", function(d) { return d.x; }) | |
.attr("cy", function(d) { return d.y; }); | |
} | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
// create some fake data | |
// each data element is an | |
// object with x & y attributes | |
var data = []; | |
for(var i = 0; i < 30; i++) { | |
var d = {x:0, y:0, i:i}; | |
data.push(d); | |
} | |
// create circle elements to | |
// represent our data | |
node = svg.selectAll("circle") | |
.data(data) | |
node.enter().append("circle") | |
.attr("r", 10) | |
.attr("fill", "steelblue"); | |
// create and startup force | |
var force = d3.layout.force() | |
.size([width, height]) | |
.nodes(data) | |
.charge(-20) | |
.on("tick", moveToRadial) | |
.start(); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment