|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<svg width="960" height="500" viewBox="-480 -250 960 500"> |
|
<circle r="100" stroke="brown" stroke-opacity="0.5" fill="none"></circle> |
|
<circle r="200" stroke="steelblue" stroke-opacity="0.5" fill="none"></circle> |
|
</svg> |
|
<script src="https://d3js.org/d3-array.v1.min.js"></script> |
|
<script src="https://d3js.org/d3-collection.v1.min.js"></script> |
|
<script src="https://d3js.org/d3-dispatch.v1.min.js"></script> |
|
<script src="https://d3js.org/d3-quadtree.v1.min.js"></script> |
|
<script src="https://d3js.org/d3-selection.v1.min.js"></script> |
|
<script src="https://d3js.org/d3-timer.v1.min.js"></script> |
|
<script src="https://d3js.org/d3-force.v1.min.js"></script> |
|
<script> |
|
|
|
var width = d3.select("svg").attr("width") |
|
var height = d3.select("svg").attr("height") |
|
var radius1 = 100 |
|
var radius2 = 200 |
|
var offsetX = 50 |
|
var offsetY = -50 |
|
|
|
var nodes = [].concat( |
|
d3.range(80).map(function() { return {type: "a", x: Math.random()<0.5?offsetX + Math.random()*width/2 : offsetX-Math.random()*width/2, y:Math.random()<0.5?offsetY+Math.random()*height/2 : offsetY-Math.random()*height/2}; }), |
|
d3.range(160).map(function() { return {type: "b", x:Math.random()<0.5?offsetX+Math.random()*width/2 : offsetX-Math.random()*width/2, y:Math.random()<0.5?offsetY+Math.random()*height/2 : offsetY-Math.random()*height/2}; }) |
|
); |
|
|
|
// var nodes = [].concat( |
|
// d3.range(80).map(function() { return {type: "a", x: offsetX, y:offsetY}; }), |
|
// d3.range(160).map(function() { return {type: "b", x: offsetX, y:offsetY}; }) |
|
// ); |
|
|
|
var node = d3.select("svg") |
|
.append("g") |
|
.selectAll("circle") |
|
.data(nodes) |
|
.enter().append("circle") |
|
.attr("r", 2.5) |
|
.attr("fill", function(d) { return d.type === "a" ? "brown" : "steelblue"; }) |
|
|
|
var simulation = d3.forceSimulation(nodes) |
|
.force("charge", d3.forceCollide().radius(5)) |
|
.force("r", d3.forceRadial(function(d) { return d.type === "a" ? radius1 : radius2; }).x(offsetX).y(offsetY)) |
|
.on("tick", ticked); |
|
|
|
function ticked() { |
|
node |
|
.attr("cx", function(d) { return d.x; }) |
|
.attr("cy", function(d) { return d.y; }); |
|
} |
|
|
|
</script> |