remove.js 1.6 KB

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