Skip to content

Instantly share code, notes, and snippets.

@mforando
Created February 10, 2020 19:09
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 mforando/35bbef0faa68200e12c550cbacec5add to your computer and use it in GitHub Desktop.
Save mforando/35bbef0faa68200e12c550cbacec5add to your computer and use it in GitHub Desktop.
fresh block
license: mit
We can make this file beautiful and searchable if this error is corrected: It looks like row 2 should actually have 3 columns, instead of 2. in line 1.
id,parentId,size
cars,
owned,cars, 10
traded,cars, 20
learned,cars, 30
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<title>Simple Circle Pack (d3 v4; CSV; 50 Lines)</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<style>
circle {
stroke: white;
fill: #05668D;
opacity: 0.3;
stroke-width: 2px;
}
</style>
<svg>
<g></g>
</svg>
<script>
var vWidth = 300;
var vHeight = 200;
// Prepare our physical space
var g = d3.select('svg').attr('width', vWidth).attr('height', vHeight).select('g');
// Get the data from our CSV file
d3.csv('data.csv', function(error, vCsvData) {
if (error) throw error;
vData = d3.stratify()(vCsvData);
drawViz(vData);
});
function drawViz(vData) {
// Declare d3 layout
var vLayout = d3.pack().size([vWidth, vHeight]);
// Layout + Data
var vRoot = d3.hierarchy(vData).sum(function (d) { return d.data.size; });
var vNodes = vRoot.descendants();
vLayout(vRoot);
var vSlices = g.selectAll('circle').data(vNodes).enter().append('circle');
// Draw on screen
vSlices.attr('cx', function (d) { return d.x; })
.attr('cy', function (d) { return d.y; })
.attr('r', function (d) { return d.r; });
// compute a quadtree for depth = 2 nodes.
var tree = d3.quadtree()
.x((d)=>{return d.x})
.y((d)=>{return d.y})
.extent([[0,0],[vWidth, vWidth]])
.addAll(vRoot.descendants().filter((d)=>{return d.depth ==1}));
console.log(tree);
//loop through quadtree sites
tree.visit(function(quad, x1, y1, x2, y2) {
console.log(quad, quad.point);
})
}
var maxRadius = 12, // maximum radius of circle
padding = 2, // padding between circles; also minimum radius
margin = {top: -maxRadius, right: -maxRadius, bottom: -maxRadius, left: -maxRadius},
width = 960 - margin.left - margin.right,
height = 700 - margin.top - margin.bottom,
bigRadius = (500 - margin.top - margin.bottom)/2;
function bestCircleGenerator(maxRadius, padding) {
var quadtree = d3.quadtree().extent([[0, 0], [width, height]])([]),
searchRadius = maxRadius * 2,
maxRadius2 = maxRadius * maxRadius;
return function(k) {
var bestX, bestY, bestDistance = 0;
for (var i = 0; i < k || bestDistance < padding; ++i) {
var angle = 2 * Math.PI * Math.random();
var rad = 300 * Math.random();
var x = 340 + Math.sin(angle) * (rad),
y = 340 + Math.cos(angle) * (rad),
rx1 = x - searchRadius,
rx2 = x + searchRadius,
ry1 = y - searchRadius,
ry2 = y + searchRadius,
minDistance = maxRadius; // minimum distance for this candidate
quadtree.visit(function(quad, x1, y1, x2, y2) {
if (p = quad.point) {
var p,
dx = x - p[0],
dy = y - p[1],
d2 = dx * dx + dy * dy,
r2 = p[2] * p[2];
if (d2 < r2) return minDistance = 0, true; // within a circle
var d = Math.sqrt(d2) - p[2];
if (d < minDistance) minDistance = d;
}
return !minDistance || x1 > rx2 || x2 < rx1 || y1 > ry2 || y2 < ry1; // or outside search radius
});
if (minDistance > bestDistance) bestX = x, bestY = y, bestDistance = minDistance;
}
var best = [bestX, bestY, bestDistance - padding];
quadtree.add(best);
return best;
};
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment