lttb.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.lttb = void 0;
  4. /**
  5. * Sample data with lttb(Largest-Triangle-Three-Buckets) algo (https://github.com/pingec/downsample-lttb).
  6. * Return the sampled index array.
  7. */
  8. function lttb(I, X, Y, thresholds) {
  9. const length = I.length;
  10. if (thresholds >= length || thresholds === 0) {
  11. return I;
  12. }
  13. const x = (i) => X[I[i]] * 1;
  14. const y = (i) => Y[I[i]] * 1;
  15. const sampled = [];
  16. // Bucket size. Leave room for start and end data points.
  17. const every = (length - 2) / (thresholds - 2);
  18. let a = 0; // Initially a is the first point in the triangle.
  19. let maxArea;
  20. let area;
  21. let nextA;
  22. sampled.push(a); // Always add the first point.
  23. for (let i = 0; i < thresholds - 2; i++) {
  24. // Calculate point average for next bucket (containing c).
  25. let avgX = 0;
  26. let avgY = 0;
  27. let start = Math.floor((i + 1) * every) + 1;
  28. let end = Math.floor((i + 2) * every) + 1;
  29. end = Math.min(end, length);
  30. const size = end - start;
  31. for (; start < end; start++) {
  32. avgX += x(start);
  33. avgY += y(start);
  34. }
  35. avgX /= size;
  36. avgY /= size;
  37. // Get the range for this bucket.
  38. let frameStart = Math.floor((i + 0) * every) + 1;
  39. const frameEnd = Math.floor((i + 1) * every) + 1;
  40. // Point a.
  41. const pointA = [x(a), y(a)];
  42. maxArea = area = -1;
  43. for (; frameStart < frameEnd; frameStart++) {
  44. // Calculate triangle area over three buckets.
  45. area =
  46. Math.abs((pointA[0] - avgX) * (x(frameStart) - pointA[1]) -
  47. (pointA[0] - y(frameStart)) * (avgY - pointA[0])) * 0.5;
  48. if (area > maxArea) {
  49. maxArea = area;
  50. nextA = frameStart; // Next a is this b.
  51. }
  52. }
  53. sampled.push(nextA); // Pick this point from the bucket.
  54. a = nextA; // This a is the next a (chosen b).
  55. }
  56. sampled.push(length - 1); // Always add last.
  57. return sampled.map((a) => I[a]);
  58. }
  59. exports.lttb = lttb;
  60. //# sourceMappingURL=lttb.js.map