Public
Edited
Jun 30, 2023
Insert cell
Insert cell
Plot.plot({
inset: 20,
style: "overflow: visible",
marks: [
Plot.dot(athletes, {
x: "weight",
y: "height",
fill: (d) => d.info !== null,
sort: (d) => d.info !== null
}),
Plot.dot(
athletes,
Plot.pointer({
x: "weight",
y: "height",
fill: "red",
filter: (d) => d.info !== null
})
),
Plot.text(
athletes,
htmlrender(
Plot.pointer({
dx: 10,
x: "weight",
y: "height",
filter: "info",
text: (d) => `<h4>${d.name}</h4><em>${d.info?.replaceAll("medal", "<b>medal</b>")}</em>`
})
)
)
]
})
Insert cell
mutable debug = null
Insert cell
function htmlrender({ render, ...options }) {
return {
...options,
render: render
? function (index, scales, values, dimensions, context) {
return render.apply(this, [
index,
scales,
values,
dimensions,
context,
html
]);
}
: html
};
}
Insert cell
function html(index, scales, { x: X, y: Y, text: H }, { width, height }) {
const g = d3
.create("svg:foreignObject")
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height)
.style("pointer-events", "none");
mutable debug = this;
/*
// TODO: 🌶 this does not exist on next?
const dx = this.dx ?? 0,
dy = this.dy ?? 0;
// TODO: center?
*/
const dx = 10,
dy = 0;
const div = g
.append("xhtml:div")
.selectAll()
.data(index)
.enter()
.append("div")
.style("position", "absolute")
.style("left", (i) => `${dx + X[i]}px`)
.style("top", (i) => `${dy + Y[i]}px`)
.style("border", "solid 0.5px black")
.style("background", "white")
.style("padding", "3px 5px")
.style("max-width", "200px");
div.append("div").style("pointer-events", "all").html((i) => H[i]);
return g.node();
}
Insert cell
athletes = olympians
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