| [e4c61dd] | 1 | export default function(d) {
|
|---|
| 2 | if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points
|
|---|
| 3 |
|
|---|
| 4 | var parent,
|
|---|
| 5 | node = this._root,
|
|---|
| 6 | retainer,
|
|---|
| 7 | previous,
|
|---|
| 8 | next,
|
|---|
| 9 | x0 = this._x0,
|
|---|
| 10 | y0 = this._y0,
|
|---|
| 11 | x1 = this._x1,
|
|---|
| 12 | y1 = this._y1,
|
|---|
| 13 | x,
|
|---|
| 14 | y,
|
|---|
| 15 | xm,
|
|---|
| 16 | ym,
|
|---|
| 17 | right,
|
|---|
| 18 | bottom,
|
|---|
| 19 | i,
|
|---|
| 20 | j;
|
|---|
| 21 |
|
|---|
| 22 | // If the tree is empty, initialize the root as a leaf.
|
|---|
| 23 | if (!node) return this;
|
|---|
| 24 |
|
|---|
| 25 | // Find the leaf node for the point.
|
|---|
| 26 | // While descending, also retain the deepest parent with a non-removed sibling.
|
|---|
| 27 | if (node.length) while (true) {
|
|---|
| 28 | if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
|
|---|
| 29 | if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
|
|---|
| 30 | if (!(parent = node, node = node[i = bottom << 1 | right])) return this;
|
|---|
| 31 | if (!node.length) break;
|
|---|
| 32 | if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i;
|
|---|
| 33 | }
|
|---|
| 34 |
|
|---|
| 35 | // Find the point to remove.
|
|---|
| 36 | while (node.data !== d) if (!(previous = node, node = node.next)) return this;
|
|---|
| 37 | if (next = node.next) delete node.next;
|
|---|
| 38 |
|
|---|
| 39 | // If there are multiple coincident points, remove just the point.
|
|---|
| 40 | if (previous) return (next ? previous.next = next : delete previous.next), this;
|
|---|
| 41 |
|
|---|
| 42 | // If this is the root point, remove it.
|
|---|
| 43 | if (!parent) return this._root = next, this;
|
|---|
| 44 |
|
|---|
| 45 | // Remove this leaf.
|
|---|
| 46 | next ? parent[i] = next : delete parent[i];
|
|---|
| 47 |
|
|---|
| 48 | // If the parent now contains exactly one leaf, collapse superfluous parents.
|
|---|
| 49 | if ((node = parent[0] || parent[1] || parent[2] || parent[3])
|
|---|
| 50 | && node === (parent[3] || parent[2] || parent[1] || parent[0])
|
|---|
| 51 | && !node.length) {
|
|---|
| 52 | if (retainer) retainer[j] = node;
|
|---|
| 53 | else this._root = node;
|
|---|
| 54 | }
|
|---|
| 55 |
|
|---|
| 56 | return this;
|
|---|
| 57 | }
|
|---|
| 58 |
|
|---|
| 59 | export function removeAll(data) {
|
|---|
| 60 | for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]);
|
|---|
| 61 | return this;
|
|---|
| 62 | }
|
|---|