Function: nearestHover()
nearestHover<
R>(root,store,o):NearestHoverHandle
Defined in: packages/sdvplot/src/interact/nearest.ts:90
Hover the NEAREST mark of a d3-drawn (or any non-Plot) figure, within a radius, rather than the element under the
pointer: sparse or small marks stay easy to hit. "xy" finds it with a Delaunay triangulation (Delaunay.find,
as blazing-the-nets' hex chart does within 18 px); "x" / "y" bisect the points sorted along that axis (a 1-D
Voronoi, as its distance bars do). The pointer writes hover: [id], once per distinct mark; beyond radius, inside
the padding margin, on pointerleave / pointercancel or with no points, it writes hover: []. label shows a
tooltip at the mark, not at the pointer. Link the same figure with hover: false in linkSelection so
this is its only hover writer while highlight still follows the store. The pointer listeners capture,
so a handler registered earlier on the svg that stops the event (Plot's tip on pointerdown) cannot hide it.
A Plot figure hovers through its own tip instead (linkSelection's hover: { id }). Throws InputError on a
negative radius or padding or an unknown dimension, in Node too, and when root is not an <svg>. Returns a
HANDLE, not a teardown function, because it has more to do than tear down: update re-targets it and destroy
removes it (linkSelection and linkCursor, whose teardown is all they have, return a function). A no-op handle
without a DOM.
Type Parameters
R
R
Parameters
root
Element
store
o
Returns
Example
import { createSelection } from "@sportsdataverse/sdvplot";
import { linkSelection, nearestHover } from "@sportsdataverse/sdvplot/interact";
import * as d3 from "d3";
const rows = [
{ team: "KC", wins: 15, net_epa: 0.063 },
{ team: "BUF", wins: 13, net_epa: 0.19 },
{ team: "MIA", wins: 8, net_epa: -0.019 },
{ team: "LV", wins: 4, net_epa: -0.146 },
];
const x = d3.scaleLinear([0, 17], [30, 410]);
const y = d3.scaleLinear([-0.2, 0.2], [190, 10]);
const svg = d3.create("svg").attr("viewBox", "0 0 440 200").attr("width", 440);
svg
.selectAll("circle")
.data(rows)
.join("circle")
.attr("data-sdv-id", (d) => d.team) // the d3 way to stamp link ids
.attr("cx", (d) => x(d.wins))
.attr("cy", (d) => y(d.net_epa))
.attr("r", 5)
.attr("fill", "currentColor");
const node = svg.node() as SVGSVGElement;
const store = createSelection();
linkSelection(store, { figure: node, hover: false }); // highlight follows the store; nearestHover writes hover
nearestHover(node, store, {
points: rows.map((d) => ({ x: x(d.wins), y: y(d.net_epa), id: d.team })),
radius: 18,
label: (team) => ({ lines: [team, `net EPA/play ${rows.find((d) => d.team === team)?.net_epa}`] }),
});
node; // hover near a dot: within 18 px it lights and its tooltip shows