D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
vlandham
Full window
Github gist
the illusion of links in a force
<!DOCTYPE html> <meta charset="utf-8"> </style> <body> <script src="https://d3js.org/d3.v3.min.js"></script> <script> D2R = Math.PI / 180; var width = 960, height = 500; var node = []; var link = []; // 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 // https://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; }); 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;}); } 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); } var link_data = []; for(var i = 0; i < 30; i++) { var d = {source:data[i], target:data[(i * 5 % 30)], i:i}; link_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"); link = svg.selectAll("line.link") .data(link_data); link.enter().append("line") .attr("class", "link") .attr("stroke", "#ddd") .attr("stroke-opacity", 0.8) .attr("stroke-width", 0.8); // create and startup force var force = d3.layout.force() .size([width, height]) .nodes(data) .charge(-20) .on("tick", moveToRadial) .start(); </script>
Modified
http://d3js.org/d3.v3.min.js
to a secure url
https://d3js.org/d3.v3.min.js