Skip to content

Instantly share code, notes, and snippets.

@iros
Last active August 17, 2017 18:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iros/e81d2f531feb732f336f74fb0a87dd76 to your computer and use it in GitHub Desktop.
Save iros/e81d2f531feb732f336f74fb0a87dd76 to your computer and use it in GitHub Desktop.
D3 v4 - circle re-packing stability
license: mit

D3 v4 - circle packing + data addition.

  • Click "Add data" to add a random circle.
  • Click "same size" to modify the nodes to be of the same size
  • Click "diff size" to modify the nodes back to being of different size
  • Adjust the sliders to control the size of the new circles.

Built with blockbuilder.org

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<input type="button" id="adddata" name="Add Data" value="Add Data" />
<input type="button" id="samesize" name="Same Size" value="Same Size" />
<input type="button" id="diffsize" name="Diff Size" value="Diff Size" />
<br>
Choose circle size:
Min:
<input id="circlemin" type="range" min="100" max="5000000" step="10000" value="100">
Max:
<input id="circlemax" type="range" min="100" max="5000000" step="10000" value="5000000">
<br>
<div id="vis"></div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script type="text/javascript" src="v4.js"></script>
</body>
</html>
var data =
[
{
"name": "Root",
"id": 0
},
{
"name": "Leaf",
"size": 2098629,
"id": 1,
"parent": 0
},
{
"name": "Leaf",
"size": 104720,
"id": 2,
"parent": 0
},
{
"name": "Leaf",
"size": 5430,
"id": 3,
"parent": 0
},
{
"name": "Leaf",
"size": 102096,
"id" : 4,
"parent": 0
},
{
"name": "Leaf",
"size": 986974,
"id": 5,
"parent": 0
},
{
"name": "Leaf",
"size": 59735,
"id": 6,
"parent": 0
},
{
"name": "Leaf",
"size": 1902,
"id": 7,
"parent": 0
},
];
var diameter = 500,
format = d3.format(",d"),
diffsize = true,
circleMin = 100,
circleMax = 5000000,
idCounter = data.length;
var svg = d3.select("#vis").append("svg")
.attr("width", diameter)
.attr("height", diameter);
var root;
var stratify = d3.stratify()
.id(function(d) { return d.id; })
.parentId(function(d) { return d.parent; });
var pack = d3.pack()
.size([diameter - 4, diameter - 4]);
var vis, titles, circles;
function getRoot(data) {
return stratify(data)
.sum(function(d) {
if (diffsize) {
return d.size;
} else {
return 1000;
}
})
.sort( function(a, b) {
return -(a.value - b.value);
});
}
// Munch some data into the children array
function updateData() {
data.push({
"name": "Leaf",
"synthetic": true,
"size": Math.floor(Math.random() * circleMax) + circleMin,
"id": idCounter++,
"parent": 0
});
};
// Visualization render
function render(root) {
var packedNodes = pack(root);
var children = packedNodes.leaves();
var circles = svg.selectAll("circle")
.data(children, function(d) {
return d.id;
});
// entering
var entering = circles.enter()
.append("circle");
// existing, before rest
circles.style("fill", "white");
entering
.style("fill", "yellow")
.style("stroke", "black")
.attr("r", 0);
circles.merge(entering)
.transition().duration(500)
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", function(d) {
return d.r;
});
}
// wire up button
d3.select("#adddata").on("click", function() {
updateData();
render(getRoot(data));
});
d3.select("#samesize").on("click", function() {
diffsize = false;
render(getRoot(data));
});
d3.select("#diffsize").on("click", function() {
diffsize = true;
render(getRoot(data));
});
d3.select("#circlemin").on("change", function() {
circleMin = parseInt(this.value, 10);
})
d3.select("#circlemax").on("change", function() {
circleMax = parseInt(this.value, 10);
})
render(getRoot(data));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment