function pointerMore(pointer) {
return ({ atrest = null, selector = "point", render, ...options } = {}) => {
const I = new WeakMap();
return pointer({
...options,
render(index, scales, values, dimensions, context, next) {
const facet = context.getMarkState(this).facets[index.fi ?? 0];
const { x, x1, x2, y, y1, y2, z, stroke, fill } = values.channels;
const X = x?.value ?? x2?.value ?? x1?.value;
const Y = y?.value ?? y2?.value ?? y1?.value;
const VX = values.x ?? values.x2 ?? values.x1;
const VY = values.y ?? values.y2 ?? values.y1;
const Z = z?.value ?? stroke?.value ?? fill?.value;
if (!I.has(facet)) {
let select;
switch (String(atrest).toLowerCase()) {
case "null":
select = () => [];
break;
case "minx":
if (!X) throw new Error("missing channel x");
select = (index) => [d3.least(index, (i) => X[i])];
break;
case "maxx":
if (!X) throw new Error("missing channel x");
select = (index) => [d3.greatest(index, (i) => X[i])];
break;
case "miny":
if (!Y) throw new Error("missing channel y");
select = (index) => [d3.least(index, (i) => Y[i])];
break;
case "maxy":
if (!Y) throw new Error("missing channel y");
select = (index) => [d3.greatest(index, (i) => Y[i])];
break;
case "first":
select = (index) => index.slice(0, 1);
break;
case "last":
select = (index) => index.slice(-1);
break;
// TODO top, bottom, left, right… ?
}
if (!select) throw new Error(`unsupported atrest method ${atrest}`);
I.set(facet, select(facet));
}
if (index.length === 0) index = I.get(facet);
// selector
switch (String(selector).toLowerCase()) {
case "point":
break;
case "before":
case "lte":
if (!VX) throw new Error("missing channel x");
index = facet.filter((i) => VX[i] <= VX[index[0]]);
break;
case "lt":
if (!VX) throw new Error("missing channel x");
index = facet.filter((i) => VX[i] < VX[index[0]]);
break;
case "after":
case "gte":
if (!VX) throw new Error("missing channel x");
index = facet.filter((i) => VX[i] >= VX[index[0]]);
break;
case "gt":
if (!VX) throw new Error("missing channel x");
index = facet.filter((i) => VX[i] > VX[index[0]]);
break;
case "eq":
case "x":
if (!VX) throw new Error("missing channel x");
index = facet.filter((i) => VX[i] == VX[index[0]]);
break;
case "y":
if (!VY) throw new Error("missing channel y");
index = facet.filter((i) => VY[i] == VY[index[0]]);
break;
case "z":
if (!Z) throw new Error("missing channel z");
index = facet.filter((i) => Z[i] == Z[index[0]]);
break;
default:
throw new Error(`unsupported selector ${selector}`);
}
return render
? render(index, scales, values, dimensions, context, next)
: next(index, scales, values, dimensions, context);
}
});
};
}