|
Using Plot, I would like to work with the coordinates under the pointer, but in data space. An example would be some kind of spatial point-based query of an external spatial database, the results of which I could use to draw a mark at the point location. Plot.pointer will do the screen to data transform under the hood, but as far as I can see, I can't extract the data-space coordinate values explicitly. Is there any way of doing this from within Plot? And if not, what might be a minimal way of doing this via an SVG/D3 route? |
Replies: 3 comments 2 replies
|
Plot.pointer sets the If you want to follow the pointer in a continuous way, it's a different story: basically you'd need to add your own event listener and use the Plot's x and y scales inverse functions. |
|
Thanks Fil and Mike. Good to know that is the preferred route. For anyone else looking at this discussion, here is a minimal custom dot mark that captures the continuous data space values under the pointer: class Dots extends Plot.Dot {
constructor(data, options = {}) {
super(data, options);
}
render(indices, scales, channels, dims, cxt) {
const g = super.render(indices, scales, channels, dims, cxt);
const move = (event) => {
const [screenX, screenY] = d3.pointer(event, g);
if (
screenX >= dims.marginLeft &&
screenX <= dims.width - dims.marginRight &&
screenY >= dims.marginTop &&
screenY <= dims.height - dims.marginBottom
) {
// Convert from pointer position in screen space to data space
const [dataX, dataY] = [
scales.x?.invert?.(screenX) ?? screenX,
scales.y?.invert?.(screenY) ?? screenY
];
// Do something here with the continuous data space values under the pointer
console.log("Data vals", dataX, dataY);
// Force redraw assuming we want the display to update in response to pointer data values
cxt.ownerSVGElement.dispatchEvent(new Event("input"));
}
};
// Register the pointer movement listener
cxt.ownerSVGElement.addEventListener("pointermove", move);
return g; // Currently just displays the dot mark, but could have customise SVG instead
}
} |
|
Thanks @Fil I've added a fuller example below that uses your suggested callback pattern and performs fast (k-d tree) point-based query as a Plot overlay: https://observablehq.com/@jwolondon/extending-mark-interaction-with-plot
|

Plot.pointer sets the
valueof the chart to the closest datum (within amaxRadiusdistance), and emits an "input" event when that datum changes.If you want to follow the pointer in a continuous way, it's a different story: basically you'd need to add your own event listener and use the Plot's x and y scales inverse functions.