You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
1.8 KiB
68 lines
1.8 KiB
export default function(d) {
|
|
const x = +this._x.call(null, d);
|
|
return add(this.cover(x), x, d);
|
|
}
|
|
|
|
function add(tree, x, d) {
|
|
if (isNaN(x)) return tree; // ignore invalid points
|
|
|
|
var parent,
|
|
node = tree._root,
|
|
leaf = {data: d},
|
|
x0 = tree._x0,
|
|
x1 = tree._x1,
|
|
xm,
|
|
xp,
|
|
right,
|
|
i,
|
|
j;
|
|
|
|
// If the tree is empty, initialize the root as a leaf.
|
|
if (!node) return tree._root = leaf, tree;
|
|
|
|
// Find the existing leaf for the new point, or add it.
|
|
while (node.length) {
|
|
if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
|
|
if (parent = node, !(node = node[i = +right])) return parent[i] = leaf, tree;
|
|
}
|
|
|
|
// Is the new point is exactly coincident with the existing point?
|
|
xp = +tree._x.call(null, node.data);
|
|
if (x === xp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree;
|
|
|
|
// Otherwise, split the leaf node until the old and new point are separated.
|
|
do {
|
|
parent = parent ? parent[i] = new Array(2) : tree._root = new Array(2);
|
|
if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
|
|
} while ((i = +right) === (j = +(xp >= xm)));
|
|
return parent[j] = node, parent[i] = leaf, tree;
|
|
}
|
|
|
|
export function addAll(data) {
|
|
if (!Array.isArray(data)) data = Array.from(data);
|
|
const n = data.length;
|
|
const xz = new Float64Array(n);
|
|
let x0 = Infinity,
|
|
x1 = -Infinity;
|
|
|
|
// Compute the points and their extent.
|
|
for (let i = 0, x; i < n; ++i) {
|
|
if (isNaN(x = +this._x.call(null, data[i]))) continue;
|
|
xz[i] = x;
|
|
if (x < x0) x0 = x;
|
|
if (x > x1) x1 = x;
|
|
}
|
|
|
|
// If there were no (valid) points, abort.
|
|
if (x0 > x1) return this;
|
|
|
|
// Expand the tree to cover the new points.
|
|
this.cover(x0).cover(x1);
|
|
|
|
// Add the new points.
|
|
for (let i = 0; i < n; ++i) {
|
|
add(this, xz[i], data[i]);
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|