delaunay = ({ x, y, ...options }) => {
const [X1, setX1] = Plot.channel(x);
const [X2, setX2] = Plot.channel(x);
const [Y1, setY1] = Plot.channel(y);
const [Y2, setY2] = Plot.channel(y);
options = Plot.transform(options, function (data, facets) {
const X = Plot.valueof(data, x);
const Y = Plot.valueof(data, y);
const normX = (([a, b]) => 1 / Math.max(1e-24, b - a))(d3.extent(X));
const normY = (([a, b]) => 1 / Math.max(1e-24, b - a))(d3.extent(Y));
const X1 = [];
const X2 = [];
const Y1 = [];
const Y2 = [];
setX1(X1);
setX2(X2);
setY1(Y1);
setY2(Y2);
let k = -1;
const newFacets = [];
const newData = [];
for (const I of facets) {
const f = [];
const delaunay = d3.Delaunay.from(
I,
(i) => X[i] * normX,
(i) => Y[i] * normY
);
for (let i = 0; i < delaunay.halfedges.length; ++i) {
const j = delaunay.halfedges[i];
if (j < i) continue;
const ti = delaunay.triangles[i];
const tj = delaunay.triangles[j];
f.push(++k);
newData.push({
source: data[I[ti]],
target: data[I[tj]],
index: k,
hull: false
});
X1.push(X[I[ti]]);
Y1.push(Y[I[ti]]);
X2.push(X[I[tj]]);
Y2.push(Y[I[tj]]);
}
for (let i = 0; i < delaunay.hull.length; ++i) {
const ti = delaunay.hull[i];
const tj = delaunay.hull[(i + 1) % delaunay.hull.length];
f.push(++k);
newData.push({
source: data[I[ti]],
target: data[I[tj]],
index: k,
hull: true
});
X1.push(X[I[ti]]);
Y1.push(Y[I[ti]]);
X2.push(X[I[tj]]);
Y2.push(Y[I[tj]]);
}
newFacets.push(f);
}
return { data: newData, facets: newFacets };
});
return { x1: X1, x2: X2, y1: Y1, y2: Y2, ...options };
}