Published
Edited
Jul 21, 2021
Fork of Occlusion
Importers
2 stars
Insert cell
Insert cell
Insert cell
svg = {
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]).attr("width", width).attr("height", height);

//return svg.node();
const n = 1000;
svg
.selectAll("text")
.data(rwg(n).sort(d3.ascending))
.join("text")
.classed("label-box", true)
.text(d => d)
.attr("x", () => (width * Math.random()) | 0)
.attr("y", () => (height * Math.random()) | 0);

// important! yield before calling occlusion()
yield svg.node();

// change the priority on mouseover
svg
.selectAll("text")
.on("mouseover", function () {
this.setAttribute("data-priority", 2);
occlusion(svg);
})
.on("mouseout", function () {
this.setAttribute("data-priority", 0);
occlusion(svg);
});

// maybe some changes are automatic
do {
const i = (Math.random() * n) | 0;
svg
.select(`text:nth-of-type(${i})`)
.attr("data-priority", Math.random() * 2);

occlusion(svg);

await Promises.delay(300);
} while (true);
}
Insert cell
html`<style>
svg { cursor: pointer; }
svg text.occluded { opacity: 0.1 }
svg text[data-priority="2"] { fill: red }
</style>`
Insert cell
function occlusion(svg) {
debugger;
const texts = [];
svg.selectAll(".label-box").each((d, i, e) => {
const bbox = e[i].getBoundingClientRect();
texts.push({
priority: +e[i].getAttribute("data-priority"),
node: e[i],
text: d,
bbox,
x: bbox.x,
y: bbox.y,
width: bbox.width,
height: bbox.height
});
});

texts.sort((a, b) => d3.descending(a.priority, b.priority));

const filled = [];

texts.forEach(d => {
const isOccluded = filled.some(e => intersect(d, e));
d3.select(d.node).classed("occluded", isOccluded);
if (!isOccluded) filled.push(d);
});

return filled;
}
Insert cell
function intersect(a, b) {
return !(
a.x + a.width < b.x ||
b.x + b.width < a.x ||
a.y + a.height < b.y ||
b.y + b.height < a.y
);
}
Insert cell
d3 = require("d3@6")
Insert cell
height = 400
Insert cell
// https://www.npmjs.com/package/random-words
rwg = require("random-words@1.1.0").catch(() => window.words)
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