source: trip-planner-front/node_modules/hdr-histogram-js/src/PercentileIterator.ts@ 188ee53

Last change on this file since 188ee53 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 3.9 KB
Line 
1import JsHistogram from "./JsHistogram";
2import JsHistogramIterator from "./JsHistogramIterator";
3
4const { pow, floor, log2 } = Math;
5
6/**
7 * Used for iterating through histogram values according to percentile levels. The iteration is
8 * performed in steps that start at 0% and reduce their distance to 100% according to the
9 * <i>percentileTicksPerHalfDistance</i> parameter, ultimately reaching 100% when all recorded histogram
10 * values are exhausted.
11 */
12class PercentileIterator extends JsHistogramIterator {
13 percentileTicksPerHalfDistance: number;
14 percentileLevelToIterateTo: number;
15 percentileLevelToIterateFrom: number;
16 reachedLastRecordedValue: boolean;
17
18 /**
19 * @param histogram The histogram this iterator will operate on
20 * @param percentileTicksPerHalfDistance The number of equal-sized iteration steps per half-distance to 100%.
21 */
22 public constructor(
23 histogram: JsHistogram,
24 percentileTicksPerHalfDistance: number
25 ) {
26 super();
27 this.percentileTicksPerHalfDistance = 0;
28 this.percentileLevelToIterateTo = 0;
29 this.percentileLevelToIterateFrom = 0;
30 this.reachedLastRecordedValue = false;
31 this.doReset(histogram, percentileTicksPerHalfDistance);
32 }
33
34 /**
35 * Reset iterator for re-use in a fresh iteration over the same histogram data set.
36 *
37 * @param percentileTicksPerHalfDistance The number of iteration steps per half-distance to 100%.
38 */
39 reset(percentileTicksPerHalfDistance: number) {
40 this.doReset(this.histogram, percentileTicksPerHalfDistance);
41 }
42
43 private doReset(
44 histogram: JsHistogram,
45 percentileTicksPerHalfDistance: number
46 ) {
47 super.resetIterator(histogram);
48 this.percentileTicksPerHalfDistance = percentileTicksPerHalfDistance;
49 this.percentileLevelToIterateTo = 0;
50 this.percentileLevelToIterateFrom = 0;
51 this.reachedLastRecordedValue = false;
52 }
53
54 public hasNext(): boolean {
55 if (super.hasNext()) return true;
56 if (!this.reachedLastRecordedValue && this.arrayTotalCount > 0) {
57 this.percentileLevelToIterateTo = 100;
58 this.reachedLastRecordedValue = true;
59 return true;
60 }
61 return false;
62 }
63
64 incrementIterationLevel() {
65 this.percentileLevelToIterateFrom = this.percentileLevelToIterateTo;
66
67 // The choice to maintain fixed-sized "ticks" in each half-distance to 100% [starting
68 // from 0%], as opposed to a "tick" size that varies with each interval, was made to
69 // make the steps easily comprehensible and readable to humans. The resulting percentile
70 // steps are much easier to browse through in a percentile distribution output, for example.
71 //
72 // We calculate the number of equal-sized "ticks" that the 0-100 range will be divided
73 // by at the current scale. The scale is detemined by the percentile level we are
74 // iterating to. The following math determines the tick size for the current scale,
75 // and maintain a fixed tick size for the remaining "half the distance to 100%"
76 // [from either 0% or from the previous half-distance]. When that half-distance is
77 // crossed, the scale changes and the tick size is effectively cut in half.
78
79 // percentileTicksPerHalfDistance = 5
80 // percentileReportingTicks = 10,
81
82 const percentileReportingTicks =
83 this.percentileTicksPerHalfDistance *
84 pow(2, floor(log2(100 / (100 - this.percentileLevelToIterateTo))) + 1);
85
86 this.percentileLevelToIterateTo += 100 / percentileReportingTicks;
87 }
88
89 reachedIterationLevel(): boolean {
90 if (this.countAtThisValue === 0) {
91 return false;
92 }
93 const currentPercentile =
94 (100 * this.totalCountToCurrentIndex) / this.arrayTotalCount;
95 return currentPercentile >= this.percentileLevelToIterateTo;
96 }
97
98 getPercentileIteratedTo(): number {
99 return this.percentileLevelToIterateTo;
100 }
101
102 getPercentileIteratedFrom(): number {
103 return this.percentileLevelToIterateFrom;
104 }
105}
106
107export default PercentileIterator;
Note: See TracBrowser for help on using the repository browser.