Unlisted
Edited
Aug 21, 2023
1 fork
Importers
12 stars
Insert cell
Insert cell
data = [
{ login: "A", count: 3 },
{ login: "B", count: 7 },
{ login: "C", count: 1 },
{ login: "D", count: 4 }
]
Insert cell
mutable debug = ({})
Insert cell
mutable out = ({})
Insert cell
Plot.plot({
_facet: { data, x: ["o", "o", "u", "u"] },
marks: [
Plot.frame(),
on(Plot.barX(data, { x: "count", y: "login" }), {
dblclick: function (event, { datum }) {
mutable out = datum;
mutable debug = arguments;
},
click: function (event, { datum }) {
d3.select(event.target).style("fill", "red");
mutable out = datum;
mutable debug = arguments;
},
pointerenter: function (event, { datum }) {
d3.select(event.target)
.style("cursor", "pointer")
.style("fill", "brown");
mutable out = datum;
mutable debug = arguments;
},
pointermove: function (event, { datum }) {
mutable out = datum;
mutable debug = arguments;
},
pointerout: function (event, { datum }) {
d3.select(event.target).style("cursor", "pointer").style("fill", null);
mutable debug = arguments;
}
})
]
})
Insert cell
// TODO revise with Plot’s render transform (0.6.10)
function on(mark, listeners = {}) {
const render = mark.render;
mark.render = function (facet, { x, y }, channels) {
// 🌶 I'd like to be allowed to read the facet
// … mutable debug = fx.domain()??

// 🌶 data[i] may or may not be the datum, depending on transforms
// (at this stage we only have access to the materialized channels we requested)
// but in simple cases it works
const data = this.data;

// 🌶 since a point or band scale doesn't have an inverse, create one from its domain and range
if (x && x.invert === undefined)
x.invert = d3.scaleQuantize(x.range(), x.domain());
if (y && y.invert === undefined)
y.invert = d3.scaleQuantize(y.range(), y.domain());

const g = render.apply(this, arguments);
const r = d3.select(g).selectChildren();
for (const [type, callback] of Object.entries(listeners)) {
r.on(type, function (event, i) {
const p = d3.pointer(event, g);
callback(event, {
type,
p,
datum: data[i],
i,
facet,
data,
...(x && { x: x.invert(p[0]) }),
...(y && { y: y.invert(p[1]) }),
...(x && channels.x2 && { x2: x.invert(channels.x2[i]) }),
...(y && channels.y2 && { y2: y.invert(channels.y2[i]) })
});
});
}
return g;
};
return mark;
}
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