Public
Edited
May 23, 2023
2 forks
15 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
sketch.draw(t)
Insert cell
minRadius = strokeWidth / 2
Insert cell
maxRadius = 4.5 * radius
Insert cell
function initSketch({ centres, w, h, debug, strokeWidth = 1 } = {}) {
const negativePadding = maxRadius;
const svg = htl.svg`<svg width=${w} height=${h} viewbox=${[
negativePadding,
negativePadding,
w - 2 * negativePadding,
h - 2 * negativePadding
]}>`;

d3.select(svg)
.append("rect")
.attr("width", w)
.attr("height", h)
.attr("fill", palette.bg);

const circles = d3
.select(svg)
.append("g")
.attr("class", "circles")
.style("mix-blend-mode", palette.blend ?? "normal")
.selectAll(".circle")
.data(centres)
.join("circle")
.attr("class", "circle")
.attr("r", 1)
.attr("fill", "none")
.attr("stroke", palette.fg)
.attr("cx", (d) => d[0])
.attr("cy", (d) => d[1]);

if (debug) {
const debugG = d3.select(svg).append("g").attr("class", "debug");

debugG
.selectAll("circle")
.data(centres)
.join("circle")
.attr("r", 1)
.attr("fill", palette.debug)
.attr("cx", (d) => d[0])
.attr("cy", (d) => d[1]);

debugG
.selectAll(".hexagon")
.data(centres)
.join("path")
.attr("class", "hexagon")
.attr("transform", (d) => `translate(${d[0]},${d[1]})`)
.attr("fill", "none")
.attr("stroke", palette.debug)
.attr("stroke-width", 1)
.attr("d", hexbin.hexagon());
}

function draw(T = 0) {
const t = eases.sineInOut(T);
const r = math.lerp(minRadius, maxRadius, t);
circles.attr("r", r);
}

return Object.assign(svg, { draw });
}
Insert cell
centres = hexbin.centers()
Insert cell
hexbin = HB()
.extent([
[0, 0],
[w, h]
])
.radius(radius)
Insert cell
w = Math.max(400, width)
Insert cell
h = Math.floor(w / aspectRatio)
Insert cell
aspectRatio = 640 / 400
Insert cell
// palette = ({
// bg: "hsl(0,0%,95%)",
// fg: "hsl(0,0%,5%)",
// debug: "#f0f"
// })

palette = ({
bg: "#0A005A",
fg: "#8B743D",
// blend: "multiply",
debug: "#f0f"
})
Insert cell
formatPercentage = d3.format(".2%")
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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