Built with blockbuilder.org
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
line {stroke: black}
</style>
</head>
<body>
<script>
var height = 1000
var width = 1000
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + 0 + "," + 0 + ")");
var circle_size = 6
function flatten(root) {
var nodes = [],
i = 0;
function recurse(node) {
if (node.children) node.children.forEach(recurse);
if (!node.id) node.id = ++i;
nodes.push(node);
}
recurse(root);
return nodes;
}
d3.csv("data2.csv", function(csv_data) {
var root = d3.stratify()
.id(function(d) {
return d.id;
})
.parentId(function(d) {
return d.parent;
})
(csv_data);
var links = root.links()
var nodes = flatten(root)
var simulation = d3.forceSimulation(nodes)
.force("link",
d3.forceLink(links)
.distance(function(d) {
//We want the distance to be equal so they are spaced in a circle around the parent
return Math.pow(d.source.data.data, 0.5) * 12;
})
.strength(function(d) {
//Strength just needs to be enough so that length is uniform
return 0.1
})
)
.force("charge", d3.forceManyBody()
.strength(function(d) {
var force = -Math.pow(d.data.data,0.5)*10;
return force})
.distanceMin(0)
.distanceMax(200)
)
.force("center", d3.forceCenter(width / 2, height / 2))
.force("collide", d3.forceCollide(function(d) {return Math.pow(d.data.data,0.5)*12}))
.velocityDecay(0.05)
.alphaMin(0.0001)
.alphaDecay(0.05)
.on("tick", ticked)
function ticked() {
var selection = svg.selectAll(".my_links")
.data(links)
selection.enter()
.append("line")
.attr("class", "my_links")
.merge(selection)
.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;
});
selection.exit().remove();
// Update the nodes…
selection = svg.selectAll(".my_nodes")
.data(nodes, function(d) {
return d.id;
})
//Entering
enterSelection = selection
.enter()
.append("g")
.attr("class", "my_nodes")
circles = enterSelection.append("circle")
rectangles = enterSelection.append("foreignObject")
.attr("height", function(d) { return Math.pow(d.data.data, 0.5)*circle_size*2})
.attr("width", function(d) { return Math.pow(d.data.data, 0.5)*circle_size*2})
.attr("x", function(d) {return -Math.pow(d.data.data, 0.5)*circle_size})
.attr("y", function(d) {return -Math.pow(d.data.data, 0.5)*circle_size})
.append("xhtml:div")
.attr("class", "fo")
.style("font", "30px 'Helvetica Neue'")
.style("color", "lightblue")
.style("border-radius", function(d) {return Math.pow(d.data.data, 0.5)*circle_size*2 + "px"})
.style("padding" ,function(d) {
var r = Math.pow(d.data.data, 0.5)*circle_size;
var k = Math.pow(2,0.5)
var k2 = (2-k)*r/2
return k2*1
})
.style("height", function(d) { return Math.pow(d.data.data, 0.5)*circle_size*1.41})
.style("width", function(d) { return Math.pow(d.data.data, 0.5)*circle_size*1.41})
.style("margin", 0)
.style("overflow", "hidden")
.html(function(d) {return d.data.text})
//Update
enterSelection.merge(selection)
.attr("transform", function(d) {return "translate(" + d.x + "," + d.y + ")" });
enterSelection.merge(selection).select("circle")
.attr("r", function(d) {
return Math.pow(d.data.data, 0.5)*circle_size;
})
}
});
</script>
</body>
https://d3js.org/d3.v4.min.js