UNPKG

12.9 kBJavaScriptView Raw
1import { a as __extends, b as __awaiter, c as __generator } from './tslib.es6-863e3717.js';
2import { U as Utils } from './Utils-5f9f1f09.js';
3import { select } from 'd3';
4import { S as ServerClient } from './ServerClient-f4bd7870.js';
5import { C as Component } from './Component-5b66527b.js';
6import { P as PlaybackControls } from './PlaybackControls-9a839502.js';
7
8var TsqRange = /** @class */ (function () {
9 function TsqRange(from, to) {
10 this.from = from;
11 this.to = to;
12 }
13 TsqRange.prototype.setNeatBucketSizeByNumerOfBuckets = function (targetNumberOfBuckets) {
14 var timeRangeMs = Math.max(this.to.valueOf() - this.from.valueOf(), 1);
15 var roughBucketsize = Math.ceil(timeRangeMs / targetNumberOfBuckets);
16 this.setNeatBucketSizeByRoughBucketSize(roughBucketsize);
17 };
18 TsqRange.prototype.setNeatBucketSizeByRoughBucketSize = function (roughBucketSizeMillis) {
19 var neatIntervalIndex = 1;
20 for (; neatIntervalIndex < TsqRange.NeatIntervalsMs.length; neatIntervalIndex++) {
21 if (TsqRange.NeatIntervalsMs[neatIntervalIndex] > roughBucketSizeMillis) {
22 break;
23 }
24 }
25 this.bucketSizeMs = TsqRange.NeatIntervalsMs[neatIntervalIndex - 1];
26 };
27 TsqRange.prototype.alignWithServerEpoch = function () {
28 var fromMs = Utils.adjustStartMillisToAbsoluteZero(this.from.valueOf(), this.bucketSizeMs);
29 var toMs = Utils.roundToMillis(this.to.valueOf(), this.bucketSizeMs);
30 this.from = new Date(fromMs);
31 this.to = new Date(toMs);
32 };
33 Object.defineProperty(TsqRange.prototype, "fromMillis", {
34 get: function () {
35 return this.from.valueOf();
36 },
37 enumerable: false,
38 configurable: true
39 });
40 Object.defineProperty(TsqRange.prototype, "toMillis", {
41 get: function () {
42 return this.to.valueOf();
43 },
44 enumerable: false,
45 configurable: true
46 });
47 Object.defineProperty(TsqRange.prototype, "bucketSizeMillis", {
48 get: function () {
49 return this.bucketSizeMs;
50 },
51 enumerable: false,
52 configurable: true
53 });
54 Object.defineProperty(TsqRange.prototype, "bucketSizeStr", {
55 get: function () {
56 var bucketSize = TsqRange.millisToLargestUnit(this.bucketSizeMs);
57 return "" + bucketSize.value + bucketSize.unit;
58 },
59 enumerable: false,
60 configurable: true
61 });
62 TsqRange.millisToLargestUnit = function (interval) {
63 var value, unit;
64 if (interval < 1000) {
65 value = interval;
66 unit = 'ms';
67 }
68 else if (interval < 1000 * 60) {
69 value = Math.ceil(interval / 1000);
70 unit = 's';
71 }
72 else if (interval < 1000 * 60 * 60) {
73 value = Math.ceil(interval / (1000 * 60));
74 unit = 'm';
75 }
76 else if (interval < 1000 * 60 * 60 * 24) {
77 value = Math.ceil(interval / (1000 * 60 * 60));
78 unit = 'h';
79 }
80 else {
81 value = Math.ceil(interval / (1000 * 60 * 60 * 24));
82 unit = 'd';
83 }
84 return { value: value, unit: unit };
85 };
86 // List of interval values that would divide a time range neatly
87 TsqRange.NeatIntervals = [
88 '1ms', '2ms', '4ms', '5ms', '8ms', '10ms', '20ms', '25ms', '40ms', '50ms', '100ms', '125ms', '200ms', '250ms', '500ms',
89 '1s', '2s', '3s', '4s', '5s', '6s', '10s', '12s', '15s', '20s', '30s',
90 '1m', '2m', '3m', '4m', '5m', '6m', '10m', '12m', '15m', '20m', '30m',
91 '1h', '2h', '3h', '4h', '6h', '8h', '12h',
92 '1d', '2d', '3d', '4d', '5d', '6d', '7d'
93 ];
94 TsqRange.NeatIntervalsMs = [
95 1, 2, 4, 5, 8, 10, 20, 25, 40, 50, 100, 125, 200, 250, 500,
96 1000, 2000, 3000, 4000, 5000, 6000, 10000, 12000, 15000, 20000, 30000,
97 60000, 120000, 180000, 240000, 300000, 360000, 600000, 720000, 900000, 1200000, 1800000,
98 3600000, 7200000, 10800000, 14400000, 21600000, 28800000, 43200000,
99 86400000, 172800000, 259200000, 345600000, 432000000, 518400000, 604800000
100 ];
101 return TsqRange;
102}());
103
104var HistoryPlayback = /** @class */ (function (_super) {
105 __extends(HistoryPlayback, _super);
106 function HistoryPlayback(renderTarget) {
107 var _this = _super.call(this, renderTarget) || this;
108 _this.numberOfBuckets = 1000;
109 _this.defaultPlaybackRate = 3000; // 3 seconds
110 _this.fetchAvailabilityFrequency = 30000; // 30 seconds
111 _this.playbackSliderHeight = 88;
112 _this.previewApiFlag = '?api-version=2018-11-01-preview';
113 _this.serverClient = new ServerClient();
114 _this.currentCancelTrigger = null;
115 return _this;
116 }
117 HistoryPlayback.prototype.onGraphicLoaded = function () { };
118 HistoryPlayback.prototype.renderBase = function (environmentFqdn, getToken, data, chartOptions) {
119 var _this = this;
120 this.environmentFqdn = environmentFqdn;
121 this.getAuthToken = getToken;
122 this.tsqExpressions = data;
123 this.chartOptions.setOptions(chartOptions);
124 this.playbackRate = this.chartOptions.updateInterval || this.defaultPlaybackRate;
125 this.getAuthToken().then(function (authToken) {
126 _this.serverClient.getAvailability(authToken, _this.environmentFqdn, _this.previewApiFlag)
127 .then(function (availabilityResponse) {
128 if (!_this.availabilityInterval) {
129 _this.availabilityInterval = window.setInterval(_this.pollAvailability.bind(_this), _this.fetchAvailabilityFrequency);
130 }
131 var _a = _this.parseAvailabilityResponse(availabilityResponse), from = _a.from, to = _a.to;
132 _this.updateAvailability(from, to);
133 _this.targetElement = select(_this.renderTarget);
134 _this.targetElement.html('');
135 _this.targetElement.classed('tsi-process-graphic-target', true);
136 _super.prototype.themify.call(_this, _this.targetElement, _this.chartOptions.theme);
137 _this.componentContainer = _this.targetElement
138 .append('div')
139 .classed('tsi-process-graphic-container', true);
140 _this.component = _this.componentContainer
141 .append('div')
142 .classed('tsi-process-graphic', true);
143 _this.playbackControlsContainer = _this.targetElement
144 .append('div')
145 .classed('tsi-playback-controls-container', true);
146 _this.loadResources().then(function () {
147 var initialTimeStamp = _this.chartOptions.initialValue instanceof Date ? _this.chartOptions.initialValue : from;
148 _this.playbackControls = new PlaybackControls(_this.playbackControlsContainer.node(), initialTimeStamp);
149 _this.onSelecTimestamp(initialTimeStamp);
150 _this.draw();
151 if (initialTimeStamp) {
152 _this.playbackControls.play();
153 }
154 window.addEventListener('resize', function () {
155 _this.draw();
156 });
157 });
158 })
159 .catch(function (reason) {
160 console.error("Failed while fetching data availability: " + reason);
161 });
162 })
163 .catch(function (reason) {
164 console.error("Failed to acquire authentication token: " + reason);
165 });
166 };
167 HistoryPlayback.prototype.pauseAvailabilityUpdates = function () {
168 if (this.availabilityInterval) {
169 window.clearInterval(this.availabilityInterval);
170 }
171 };
172 HistoryPlayback.prototype.pollAvailability = function () {
173 return __awaiter(this, void 0, void 0, function () {
174 var _this = this;
175 return __generator(this, function (_a) {
176 return [2 /*return*/, this.getAuthToken().then(function (authToken) {
177 return _this.serverClient.getAvailability(authToken, _this.environmentFqdn, _this.previewApiFlag)
178 .then(function (availabilityResponse) {
179 var _a = _this.parseAvailabilityResponse(availabilityResponse), from = _a.from, to = _a.to;
180 if (from.valueOf() !== _this.availability.fromMillis ||
181 to.valueOf() !== _this.availability.toMillis) {
182 _this.updateAvailability(from, to);
183 _this.playbackControls.render(_this.availability.from, _this.availability.to, _this.onSelecTimestamp.bind(_this), _this.chartOptions, { intervalMillis: _this.playbackRate, stepSizeMillis: _this.availability.bucketSizeMillis });
184 return true;
185 }
186 return false;
187 })
188 .catch(function (reason) {
189 console.error("Failed to update data availability: " + reason);
190 return null;
191 });
192 })];
193 });
194 });
195 };
196 HistoryPlayback.prototype.onSelecTimestamp = function (timeStamp) {
197 var _this = this;
198 var queryWindow = this.calcQueryWindow(timeStamp);
199 var tsqArray = this.tsqExpressions.map(function (tsqExpression) {
200 tsqExpression.searchSpan = {
201 from: queryWindow.fromMillis,
202 to: queryWindow.toMillis,
203 bucketSize: queryWindow.bucketSize
204 };
205 return tsqExpression.toTsq();
206 });
207 this.getAuthToken().then(function (authToken) {
208 var _a = _this.serverClient.getCancellableTsqResults(authToken, _this.environmentFqdn, tsqArray), promise = _a[0], cancelTrigger = _a[1];
209 // We keep track of the last AJAX call we made to the server, and cancel it if it hasn't finished yet. This is
210 // a cheap way to avoid a scenario where we get out-of-order responses back from the server during 'play' mode.
211 // We can revisit this at a later time if we need to handle it in a more sophisticated way.
212 if (_this.currentCancelTrigger) {
213 _this.currentCancelTrigger();
214 }
215 _this.currentCancelTrigger = cancelTrigger;
216 promise.then(function (results) {
217 _this.getDataPoints(results);
218 });
219 });
220 };
221 HistoryPlayback.prototype.calcQueryWindow = function (timeStamp) {
222 var timelineOffset = this.availability.fromMillis;
223 var queryToMillis = Math.ceil((timeStamp.valueOf() - timelineOffset) / this.availability.bucketSizeMillis) * this.availability.bucketSizeMillis + timelineOffset;
224 return {
225 fromMillis: queryToMillis - this.availability.bucketSizeMillis,
226 toMillis: queryToMillis,
227 bucketSize: this.availability.bucketSizeStr
228 };
229 };
230 HistoryPlayback.prototype.drawBase = function () {
231 this.playbackControlsContainer
232 .style('width', this.renderTarget.clientWidth + "px")
233 .style('height', this.playbackSliderHeight + "px");
234 this.playbackControls.render(this.availability.from, this.availability.to, this.onSelecTimestamp.bind(this), this.chartOptions, { intervalMillis: this.playbackRate, stepSizeMillis: this.availability.bucketSizeMillis });
235 };
236 HistoryPlayback.prototype.updateAvailability = function (from, to) {
237 this.availability = new TsqRange(from, to);
238 if (this.chartOptions.bucketSizeMillis && this.chartOptions.bucketSizeMillis > 0) {
239 this.availability.setNeatBucketSizeByRoughBucketSize(this.chartOptions.bucketSizeMillis);
240 }
241 else {
242 this.availability.setNeatBucketSizeByNumerOfBuckets(this.numberOfBuckets);
243 }
244 this.availability.alignWithServerEpoch();
245 };
246 HistoryPlayback.prototype.parseAvailabilityResponse = function (response) {
247 var range = response && response.availability && response.availability.range;
248 var from = (range && range.from && new Date(range.from)) || null;
249 var to = (range && range.to && new Date(range.to)) || null;
250 if (from === null || to === null) {
251 throw 'Query to get availability returned a response with an unexpected structure';
252 }
253 return { from: from, to: to };
254 };
255 return HistoryPlayback;
256}(Component));
257
258export { HistoryPlayback as H };