Published
Edited
Aug 13, 2020
Insert cell
Insert cell
d3 = require("d3@5")
Insert cell
data = { return { width: 1000, height: 500, countBefore: 2239, countAfter: 913 } }
Insert cell
getHexPositions = (x, y, radius) => {
const rXtrans = (radius * Math.sqrt(3)) / 2;
const yHalf = radius / 2;
return [
[x, y + radius],
[x - rXtrans, y + yHalf],
[x - rXtrans, y - yHalf],
[x, y - radius],
[x + rXtrans, y - yHalf],
[x + rXtrans, y + yHalf],
];
}
Insert cell
getCoordsAtDepth = (depth, radius) => {
if (depth === 0) return [[0,0]];
var coords = [];
var currentPoint = [radius * depth * Math.sqrt(3), 0];
var xFactor;
var yFactor;
for (var i = 0; i < depth * 6; i++) {
if (i % depth === 0) {
switch (i / depth) {
case 0:
xFactor = (-radius * Math.sqrt(3)) / 2;
yFactor = (3 * radius) / 2;
break;
case 1:
xFactor = -radius * Math.sqrt(3);
yFactor = 0;
break;
case 2:
xFactor = (-radius * Math.sqrt(3)) / 2;
yFactor = (-3 * radius) / 2;
break;
case 3:
xFactor = (radius * Math.sqrt(3)) / 2;
yFactor = (-3 * radius) / 2;
break;
case 4:
xFactor = radius * Math.sqrt(3);
yFactor = 0;
break;
case 5:
xFactor = (radius * Math.sqrt(3)) / 2;
yFactor = (3 * radius) / 2;
}
}
currentPoint = [currentPoint[0] + xFactor, currentPoint[1] + yFactor];
coords.push(currentPoint);
}
return coords
}
Insert cell
getNCoords = (nCoords, radius) => {
var coords = [];
var curDepth = 0;
while (coords.length < nCoords) {
var nextBatch = getCoordsAtDepth(curDepth, radius);
if (coords.length + nextBatch.length > nCoords) {
nextBatch = nextBatch.slice(0, nCoords - coords.length);
}
coords = coords.concat(nextBatch);
curDepth ++;
}
return coords;
}
Insert cell
getRadius = (height, itemWidth, numItems) => {
function maxDepth(depth=0, processedItems=1) {
if (processedItems >= numItems) return depth;
const numProcessed = processedItems + (6 * depth);
return maxDepth(depth=depth + 1, processedItems=numProcessed);
}
// size of hex from 1 to next is 1.5
const hexHeightWidth = maxDepth() * 3;
return (Math.min(height, itemWidth) / (hexHeightWidth + 1));
}
Insert cell
import {color} from "@jashkenas/inputs"
Insert cell
Insert cell
Insert cell
{
const svg = d3.select(DOM.svg(width, data.height)).attr("background-color", "#dfe2eb");
const centerX = width / 2;
const centerY = data.height / 2;
const radius = getRadius(data.height, width, data.countBefore);
const grouping = svg.append("g")
.attr("transform", "translate(" + centerX + "," + centerY + ")");
grouping.selectAll("polygon")
.data(getNCoords(data.countBefore, radius))
.enter()
.append("polygon")
.attr("points", (d) => getHexPositions(d[0], d[1], radius).map(item => item.join(",")).join(" "))
.attr("class", (_, i) => i > data.countAfter ? "hex-remove" : "hex-keep")
.attr("stroke", hexStroke)
.attr("fill", hexFill);
grouping.selectAll("polygon.hex-remove")
.transition()
.ease(d3.easeQuad)
.duration(3000)
.delay(3000)
.style("opacity", 0.1)
.attr("stroke", hexFill);
return svg.node()
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more