Public
Edited
Nov 6, 2023
Fork of Zoom (SVG)
Insert cell
Insert cell
chart = hexgrid((g, hexes) => {
hexes
.clone()
.attr("stroke", "#00fa")
.attr("transform", `rotate(30) scale(${ratio})`);

g.append("path")
.attr("d", d3.symbol(d3.symbolAsterisk))
.attr("stroke-width", "1")
.attr("stroke", "#00f")
.clone()
.attr("stroke", "#f00a")
.attr("transform", `rotate(30) scale(${ratio})`);
})
Insert cell
ratio = Math.sqrt(3) / 2
Insert cell
ratioInverse = 1 / ratio
Insert cell
Insert cell
Insert cell
chart1 = hexgrid((g, hexes) => {
const d = 2 * radius;
const line = (length) =>
d3.line()([
[0, 0],
[length, 0]
]);
g.append("path")
.attr("d", line(d * ratio))
.attr("stroke-width", "1")
.attr("stroke", "#f00")

.clone()
.attr("transform", "rotate(60)")
.clone()
.attr("transform", "rotate(-60)")

.clone()
.attr("d", line(d))
.attr("stroke", "#0f0a")
.attr("transform", "rotate(30)")

.clone()
.attr("transform", "rotate(90)")
.clone()
.attr("d", line(d * 0.75))
.attr("stroke", "#00fa")
.attr("transform", "rotate(-30)")
.clone()
.attr("transform", "rotate(-90)");
})
Insert cell
Insert cell
chart2 = hexgrid((g) => {
const d = 4 * radius;
const line = (length) =>
d3.line()([
[0, 0],
[length, 0]
]);
g.append("path")
.attr("d", line(d * ratio))
.attr("stroke-width", "1")
.attr("stroke", "#f80a")
.clone()
.attr("transform", "rotate(60)")
.clone()
.attr("transform", "rotate(-60)")
.clone()
.attr("d", line(d * 0.75))
.attr("stroke", "#00fa")
.attr("transform", "rotate(-30)")
.clone()
.attr("transform", "rotate(-90)");
})
Insert cell
Insert cell
hexgrid((g) => {
const r = radius,
w = r * ratio;
g.append("path")
.attr("stroke-width", "1")
.attr("stroke", "#f80")
.attr("fill", "none")
.attr(
"d",
`
M ${-w} 0
l ${w * 2} 0

M ${-w} 0
a ${1.5 * r} ${1.5 * r} 0 0 1
${w * 1.5}
${Math.cos(Math.PI / 6) * w}
`
)
.clone()
.attr("stroke", "#00fa")
.attr(
"d",
`
M ${-w} 0
a ${4 * r} ${4 * r} 0 0 1
${w * 2}
${r / 2}

M ${-w} 0
a ${w} ${w} 0 0 1
${w}
${w}
l 0 ${r - w}

`
)
.clone()
.attr("stroke-width", 0.3)
.attr("stroke", "#f80")
.attr(
"d",
`

`
);
})
Insert cell
Insert cell
radius = 10
Insert cell
function hexgrid(gFunc = () => {}) {
const extents = [
[-100, -100],
[100, 100]
];
const svg = d3.create("svg").attr("viewBox", [-100, -100, 200, 200]);

const g = svg.append("g");

const mesh = d3.hexbin().extent(extents).radius(radius).mesh();

const hexes = g
.append("path")
.attr("d", mesh)
.attr("fill", "none")
.attr("stroke-width", "1")
.attr("stroke", "#f00");
gFunc(g, hexes);

const zoomer = d3.zoom().extent(extents).scaleExtent([0.8, 8]);
svg.call(zoomer.on("zoom", zoomed));

function zoomed({ transform }) {
g.attr("transform", transform);
}

return svg.node();
}
Insert cell
d3 = require("d3", "d3-hexbin")
Insert cell
function percentChange(now, then = 1) {
const change = (now - then) / then;
return new Intl.NumberFormat(undefined, {
style: "percent",
signDisplay: "exceptZero",
maximumSignificantDigits: 4
}).format(change);
}
Insert cell
percentChange(0.853577)
Insert cell
function circlePath(r) {
return (
"m -" +
r +
", 0 a " +
r +
"," +
r +
" 0 1,1 " +
r * 2 +
",0 a " +
r +
"," +
r +
" 0 1,1 -" +
r * 2 +
",0"
);
}
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