Published
Edited
Feb 18, 2019
9 stars
Insert cell
Insert cell
{
const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", `${-width / 2} ${-height / 2} ${width} ${height}`);

svg
.selectAll("path")
.data(triangles)
.enter()
.append("path")
.attr("fill", "#fff")
.attr("stroke", "#000")
.attr("stroke-width", 1)
.attr(
"d",
triangle =>
`
M${triangle[1]}
A${r} ${r} 0 0 1 ${triangle[2]}
A${r} ${r} 0 0 1 ${triangle[0]}
A${r} ${r} 0 0 1 ${triangle[1]}
Z
`
)
.attr("fill-opacity", 1);

return svg.node();
}
Insert cell
height = 540
Insert cell
radius = Math.min(width, height) / 5
Insert cell
r = radius * Math.sqrt(3)
Insert cell
Insert cell
function triangleCoords(i, [offsetX, offsetY]) {
return [
offsetX + radius * Math.cos((i / 3) * 2 * Math.PI - (Math.PI / 2) * angle),
offsetY + radius * Math.sin((i / 3) * 2 * Math.PI - (Math.PI / 2) * angle)
];
}
Insert cell
function triangle(n) {
const rowOffset = offset(n);
return Array.from({ length: 3 }, (_, i) => triangleCoords(i, rowOffset));
}
Insert cell
function offset(n) {
// only works for 5 triangles
const rowR = radius + radius / 2 - 2;
const alpha = (2 * Math.PI) / numTriangles;
return [
rowR * Math.cos(n * alpha + angle),
rowR * Math.sin(n * alpha + angle)
];
}
Insert cell
Insert cell
triangles = Array.from({ length: numTriangles }, (_, i) => triangle(i))
Insert cell
d3 = require("d3@5")
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