Built with blockbuilder.org
xxxxxxxxxx
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tree Demo</title>
<!-- load D3 //-->
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<!-- load custom CSS //-->
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,900|Source+Code+Pro:300" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="style.css">
<!-- load custom JavaScript //-->
<script src="helpers.js"></script>
<script src="tooltip.js"></script>
</head>
<body>
<h2>Circle Packing</h2>
<svg id="circle_packing"></svg>
<script>
// used to color node by depth
var color = d3.scaleOrdinal();
// accessor functions for x and y
var x = function(d) { return d.x; };
var y = function(d) { return d.y; };
// normal line generator
var line = d3.line()
.curve(d3.curveLinear)
.x(x)
.y(y);
// configure size, margin, and circle radius
var config = {
w: 900,
h: 450,
r: 4,
pad: 10
};
// maximum diameter of circle is minimum dimension
config.d = Math.min(config.w, config.h);
var file = "java8.csv";
d3.csv(file, convert, callback);
function convert(row) {
var parts = row.name.split(".");
row.id = row.name;
row.name = parts[parts.length - 1];
row.value = +row.value;
return row;
}
function callback(error, data) {
if (error) {
console.warn(file, error);
return;
}
var stratify = d3.stratify().id(function(d) {
return d.id;
})
.parentId(function(d) {
return d.id.substring(0,d.id.lastIndexOf("."));
});
var nested = d3.nest()
.key(function(d){return d.parent}).sortKeys(d3.ascending).entries(data);
nested = nested[0].values;
var root = stratify(nested);
root.sort(function(a, b) {
if (a.height != b.height) {
return d3.ascending(a.height, b.height);
}
else {
return d3.ascending(a.value, b.value);
}
});
color.domain(d3.range(root.height + 1));
color.range(d3.schemeRdYlGn[root.height + 1]);
drawCirclePacking("circle_packing", root.copy());
}
function drawNodes(g, nodes, raise) {
g.selectAll("circle")
.data(nodes)
.enter()
.append("circle")
.attr("r", function(d) { return d.r ? d.r : config.r; })
.attr("cx", x)
.attr("cy", y)
.attr("id", function(d) { return d.data.name; })
.attr("class", "node")
.style("fill", function(d) {return color(d.depth)})
.on("mouseover.tooltip", function(d) {
show_tooltip(g, d3.select(this));
d3.select(this).classed("selected", true);
if (raise) {
d3.select(this).raise();
}
})
.on("mouseout.tooltip", function(d) {
g.select("#tooltip").remove();
d3.select(this).classed("selected", false);
});
}
function drawLinks(g, links, generator) {
var paths = g.selectAll("path")
.data(links)
.enter()
.append("path")
.attr("d", generator)
.attr("class", "link");
}
function drawCirclePacking(id, root) {
var svg = d3.select("body").select("#" + id);
svg.attr("width", config.w);
svg.attr("height", config.h);
var g = svg.append("g");
g.attr("id", "plot");
var xshift = config.pad + (config.w - config.d) / 2;
var yshift = config.pad + (config.h - config.d) / 2;
g.attr("transform", translate(xshift, yshift));
root.sum(function(d) { return d.value; });
// setup circle packing layout
var diameter = config.d - 2 * config.pad;
var pack = d3.pack().size([diameter, diameter]).padding(1);
// run layout to calculate x, y, and r attributes
pack(root);
// draw nested circles
drawNodes(g, root.descendants(), false);
// TODO
}
</script>
</body>
https://d3js.org/d3.v4.min.js
https://d3js.org/d3-scale-chromatic.v1.min.js