Published
Edited
Jan 6, 2022
Fork of Simple D3
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
chart = {
const xScale = d3.scaleLinear().domain([0, 1]).range([0, width]);
const yScale = d3.scaleLinear().domain([0, 1]).range([0, height]);
const rScale = d3.scaleLinear().domain([0, 1]).range([2, 5]);

const svg = d3.create("svg").attr("width", width).attr("height", height);

if (showPts) {
svg
.selectAll("circle")
.data(pts)
.join("circle")
.attr("class", "dot")
.attr("cx", (d) => xScale(d[0]))
.attr("cy", (d) => yScale(d[1]))
.attr("r", (d) => rScale(d[2]));
}

const delaunay = d3.Delaunay.from(
pts,
(d) => xScale(d[0]),
(d) => yScale(d[1])
);

const voronoi = delaunay.voronoi();
voronoi.xmax = width;
voronoi.ymax = height;

svg
.append("g")
.selectAll(".voronoi")
.data(pts)
.join("path")
.attr("class", "voronoi")
.attr("d", (d, i) => voronoi.renderCell(i))
.on("mouseenter", onMouseEnter)
.on("mouseleave", onMouseLeave);

function onMouseEnter(_, d) {
showPts &&
svg
.append("circle")
.attr("class", "dot--marker")
.attr("cx", xScale(d[0]))
.attr("cy", yScale(d[1]))
.attr("r", rScale(d[2]));
}
function onMouseLeave() {
svg.selectAll(".dot--marker").remove();
}

return svg.node();
}
Insert cell
htl.html`<style>
.dot {
stroke: white;
fill: hsl(197.4, 60%, 30%);
stroke-width: 1px;
}

.dot--marker {
fill: hsl(30, 75%, 50%);
stroke: white;
pointer-events: none;
}

.voronoi {
stroke: ${showVoronoi ? "hsl(197.4, 71.4%, 72.5%)" : "none"};
fill: ${showVoronoi ? "hsla(197.4, 71.4%, 72.5%, 0.05)" : "transparent"};
stroke-width: 1px;
}

.voronoi:hover {
fill: ${showVoronoi ? "hsla(30, 75%, 50%, 0.1)" : "transparent"};
}

</style>`
Insert cell
distributions = ({
"Inside a rectangle": (count) =>
math
.linspace(count, true)
.map(() => [random.value(), random.value(), random.value()]),
"Inside a circle": (count) =>
math.linspace(count, true).map(() => {
const [u, v] = random.insideCircle();

return [u * aspectRatio * 0.5 + 0.5, v * 0.5 + 0.5, random.value()];
}),
"On a circle": (count) =>
math.linspace(count, true).map(() => {
const [u, v] = random.onCircle();

return [u * aspectRatio * 0.5 + 0.5, v * 0.5 + 0.5, random.value()];
})
})
Insert cell
pts = {
randomize;
const dataGenerator = distributions[distribution];
return dataGenerator(numOfPoints);
}
Insert cell
height = width * aspectRatio
Insert cell
aspectRatio = 9 / 16
Insert cell
import { CSRandom as random, CSMath as math } from "@saneef/canvas-sketch-util"
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