UNPKG

50.2 kBJavaScriptView Raw
1import { a as __extends, _ as __assign } from './tslib.es6-f952ba6f.js';
2import { U as Utils } from './Utils-38a0872e.js';
3import { select, pointer } from 'd3';
4import { G as Grid } from './Grid-170eaa9c.js';
5import { E as EllipsisMenu } from './EllipsisMenu-7faacf35.js';
6import { C as ChartComponent } from './ChartComponent-ed6f3c6d.js';
7import { C as ChartDataOptions } from './ChartDataOptions-a8fe7914.js';
8import { L as LineChart } from './LineChart-5b1a9c9b.js';
9import { T as TimezonePicker } from './TimezonePicker-354a93a2.js';
10import { D as DateTimePicker } from './DateTimePicker-570b44a6.js';
11import { D as DateTimeButtonRange } from './DateTimeButtonRange-9801b88b.js';
12import { P as PieChart } from './PieChart-dca00393.js';
13import { S as Slider } from './Slider-e643fd4a.js';
14import { S as ScatterPlot } from './ScatterPlot-9415d373.js';
15import { G as GroupedBarChart } from './GroupedBarChart-46d306a8.js';
16import { H as Hierarchy } from './Hierarchy-336157a1.js';
17import { H as Heatmap } from './Heatmap-5fd6b1b1.js';
18import { E as EventsTable } from './EventsTable-c1da853f.js';
19import { M as ModelAutocomplete } from './ModelAutocomplete-31909926.js';
20import { M as ModelSearch } from './ModelSearch-3f0bdfee.js';
21import { H as HierarchyNavigation } from './HierarchyNavigation-41264496.js';
22import { S as SingleDateTimePicker } from './SingleDateTimePicker-3532265c.js';
23import { D as DateTimeButtonSingle } from './DateTimeButtonSingle-e875d7ec.js';
24import { P as PlaybackControls } from './PlaybackControls-6261fffc.js';
25import { P as ProcessGraphic } from './ProcessGraphic-5aa218c9.js';
26import { C as ColorPicker } from './ColorPicker-499f8df4.js';
27import { G as GeoProcessGraphic } from './GeoProcessGraphic-4092087c.js';
28
29var AvailabilityChart = /** @class */ (function (_super) {
30 __extends(AvailabilityChart, _super);
31 function AvailabilityChart(renderTarget) {
32 var _this = _super.call(this, renderTarget) || this;
33 _this.minBrushWidth = 5;
34 _this.minGhostWidth = 2;
35 _this.margins = {
36 left: 10,
37 right: 10
38 };
39 _this.uxClient = new UXClient();
40 return _this;
41 }
42 //the most zoomed in possible
43 AvailabilityChart.prototype.getMinZoomedRange = function () {
44 var maxZoomFactor = (this.sparkLineChart.x.range()[1] - this.sparkLineChart.x.range()[0]) / this.minBrushWidth;
45 var totalTimeRange = this.toMillis - this.fromMillis;
46 return totalTimeRange / maxZoomFactor;
47 };
48 AvailabilityChart.prototype.zoom = function (event, direction, xPos) {
49 if (this.chartOptions.isCompact)
50 return;
51 var range = Math.max(this.getMinZoomedRange(), (this.zoomedToMillis - this.zoomedFromMillis));
52 var percentile = (xPos - this.sparkLineChart.x.range()[0]) /
53 (this.sparkLineChart.x.range()[1] - this.sparkLineChart.x.range()[0]);
54 var leftImpact = percentile * .2 * range;
55 var rightImpact = (1 - percentile) * .2 * range;
56 if (direction == 'out') {
57 this.zoomedFromMillis = Math.max(this.zoomedFromMillis - leftImpact, this.fromMillis);
58 this.zoomedToMillis = Math.min(this.zoomedToMillis + rightImpact, this.toMillis);
59 }
60 else {
61 var prospectiveFromMillis = Math.max(this.zoomedFromMillis + leftImpact, this.fromMillis);
62 var prospectiveToMillis = Math.min(this.zoomedToMillis - rightImpact, this.toMillis);
63 if (prospectiveToMillis - prospectiveFromMillis >= this.getMinZoomedRange()) {
64 this.zoomedFromMillis = prospectiveFromMillis;
65 this.zoomedToMillis = prospectiveToMillis;
66 }
67 else {
68 var offBy = this.getMinZoomedRange() - (prospectiveToMillis - prospectiveFromMillis);
69 this.zoomedFromMillis = prospectiveFromMillis - (percentile * offBy);
70 this.zoomedToMillis = prospectiveToMillis + ((1 - percentile) * offBy);
71 }
72 }
73 this.setAvailabilityRange(this.zoomedFromMillis, this.zoomedToMillis);
74 this.sparkLineChart.setBrushEndTime(new Date(this.zoomedToMillis));
75 this.sparkLineChart.setBrushStartTime(new Date(this.zoomedFromMillis));
76 this.sparkLineChart.setBrush();
77 this.timePickerLineChart.drawBrushRange();
78 event.preventDefault && event.preventDefault();
79 };
80 AvailabilityChart.prototype.setChartOptions = function (chartOptions) {
81 this.chartOptions.setOptions(__assign(__assign({}, chartOptions), {
82 keepBrush: true,
83 isArea: true,
84 noAnimate: true,
85 minutesForTimeLabels: true,
86 aggTopMargin: 0,
87 yAxisHidden: true,
88 focusHidden: true,
89 singleLineXAxisLabel: false
90 }));
91 };
92 AvailabilityChart.prototype.dateTimePickerAction = function (fromMillis, toMillis) {
93 this.setBrush(fromMillis, toMillis, true);
94 this.chartOptions.brushMoveEndAction(new Date(fromMillis), new Date(toMillis), this.chartOptions.offset);
95 this.setTicks();
96 this.dateTimePickerContainer.style("display", "none");
97 };
98 //transformation of buckets created by the UX client to buckets for the availabilityChart
99 AvailabilityChart.prototype.createDisplayBuckets = function (fromMillis, toMillis) {
100 var _this = this;
101 var keysInRange = Object.keys(this.transformedAvailability[0].availabilityCount[""]).reduce(function (inRangeObj, timestamp, i, timestamps) {
102 var currTSMillis = (new Date(timestamp)).valueOf();
103 var nextTSMillis = currTSMillis + _this.bucketSize;
104 if (currTSMillis >= fromMillis && currTSMillis <= toMillis) {
105 inRangeObj[(new Date(currTSMillis)).toISOString()] = _this.transformedAvailability[0].availabilityCount[""][timestamp];
106 return inRangeObj;
107 }
108 if (currTSMillis < fromMillis && nextTSMillis > fromMillis) {
109 inRangeObj[(new Date(fromMillis)).toISOString()] = _this.transformedAvailability[0].availabilityCount[""][timestamp];
110 return inRangeObj;
111 }
112 return inRangeObj;
113 }, {});
114 var rawBucketCount = Math.ceil((toMillis - fromMillis) / this.bucketSize);
115 var bucketMultiplier = Math.ceil(rawBucketCount / this.maxBuckets);
116 var computedBucketSize = this.bucketSize * bucketMultiplier;
117 var createKey = function (millis) { return Math.round(Math.floor(millis / computedBucketSize) * computedBucketSize); };
118 var firstBucket = createKey(fromMillis);
119 var lastBucket = createKey(toMillis);
120 var buckets = [];
121 for (var i = firstBucket; i <= lastBucket; i += computedBucketSize) {
122 buckets[(new Date(i)).toISOString()] = { count: 0 };
123 }
124 Object.keys(keysInRange).sort().forEach(function (ts, i) {
125 var tsMillis = (new Date(ts)).valueOf();
126 var computedKey = createKey(tsMillis);
127 buckets[(new Date(computedKey)).toISOString()].count += (keysInRange[ts].count / bucketMultiplier);
128 });
129 if (fromMillis !== null && firstBucket !== null) {
130 buckets[(new Date(fromMillis)).toISOString()] = buckets[(new Date(firstBucket)).toISOString()];
131 }
132 if (toMillis !== null && lastBucket !== null) {
133 buckets[(new Date(toMillis)).toISOString()] = buckets[(new Date(lastBucket)).toISOString()];
134 }
135 // delete the bucket before the from time
136 if (firstBucket < fromMillis) {
137 delete buckets[(new Date(firstBucket)).toISOString()];
138 }
139 return [{ "availabilityCount": { "": buckets } }];
140 };
141 AvailabilityChart.prototype.setRangeVariables = function (rawAvailability) {
142 if (Utils.safeNotNullOrUndefined(function () { return rawAvailability.range.from || rawAvailability.range.to || rawAvailability.intervalSize; })) {
143 this.fromMillis = (new Date(rawAvailability.range.from)).valueOf();
144 this.toMillis = (new Date(rawAvailability.range.to)).valueOf();
145 this.bucketSize = Utils.parseTimeInput(rawAvailability.intervalSize);
146 }
147 else {
148 this.fromMillis = null;
149 this.toMillis = null;
150 this.bucketSize = null;
151 }
152 };
153 AvailabilityChart.prototype.render = function (transformedAvailability, chartOptions, rawAvailability) {
154 var _this = this;
155 if (rawAvailability === void 0) { rawAvailability = {}; }
156 this.setChartOptions(chartOptions);
157 this.rawAvailability = rawAvailability;
158 this.transformedAvailability = transformedAvailability;
159 this.color = this.chartOptions.color ? this.chartOptions.color : 'teal';
160 this.maxBuckets = (this.chartOptions.maxBuckets) ? this.chartOptions.maxBuckets : 500;
161 this.setRangeVariables(rawAvailability);
162 var startBucket = (this.fromMillis !== null && this.bucketSize !== null) ?
163 Math.round(Math.floor(this.fromMillis / this.bucketSize) * this.bucketSize) : null;
164 var endBucket = (this.toMillis !== null && this.bucketSize !== null) ?
165 Math.round(Math.floor(this.toMillis / this.bucketSize) * this.bucketSize) : null;
166 if (startBucket !== null && startBucket === endBucket) {
167 this.fromMillis = Math.floor(this.fromMillis / this.bucketSize) * this.bucketSize;
168 this.toMillis = this.fromMillis + this.bucketSize;
169 this.bucketSize = this.bucketSize / 60;
170 }
171 this.ae = [new this.uxClient.AggregateExpression({ predicateString: "" }, { property: 'Count', type: "Double" }, ['count'], { from: new Date(this.fromMillis), to: new Date(this.toMillis) }, null, 'grey', 'Availability')];
172 this.targetElement = select(this.renderTarget)
173 .classed("tsi-availabilityChart", true)
174 .classed("tsi-compact", this.chartOptions.isCompact)
175 .classed("tsi-withButton", this.chartOptions.persistDateTimeButtonRange);
176 this.chartOptions.yAxisHidden = true;
177 this.chartOptions.focusHidden = true;
178 this.chartOptions.singleLineXAxisLabel = true;
179 this.chartOptions.suppressResizeListener = true;
180 this.chartOptions.brushClearable = false;
181 this.chartOptions.minBrushWidth = 1;
182 this.chartOptions.brushHandlesVisible = true;
183 var brushMoveAction = this.chartOptions.brushMoveAction;
184 this.chartOptions.brushMoveAction = function (from, to) {
185 _this.setFromAndToTimes(from.valueOf(), to.valueOf());
186 _this.drawGhost();
187 if (_this.chartOptions.isCompact) {
188 _this.buildCompactFromAndTo();
189 }
190 if (brushMoveAction != null)
191 brushMoveAction(from, to);
192 };
193 _super.prototype.themify.call(this, this.targetElement, chartOptions.theme);
194 if (this.timePickerContainer == null) {
195 this.targetElement.html("");
196 this.timePickerContainer = this.targetElement.append("div")
197 .classed("tsi-timePickerContainer", true);
198 this.timePickerChart = this.timePickerContainer.append("div").classed("tsi-timePickerChart", true);
199 var sparkLineContainer = this.targetElement.append("div").classed("tsi-sparklineContainer", true);
200 this.timePickerTextContainer = this.targetElement.append("div").classed("tsi-timePickerTextContainer", true)
201 .style("margin-left", this.chartOptions.availabilityLeftMargin + this.margins.left);
202 this.timePickerLineChart = new LineChart(this.timePickerChart.node());
203 this.timePickerLineChart.chartMargins.left = (this.chartOptions.availabilityLeftMargin - this.margins.left);
204 this.buildFromAndToContainer();
205 this.sparkLineChart = new LineChart(sparkLineContainer.node());
206 this.sparkLineChart.chartMargins.left = (this.chartOptions.availabilityLeftMargin - this.margins.left);
207 this.dateTimePickerContainer = this.targetElement.append("div").classed("tsi-dateTimePickerContainer", true);
208 this.dateTimePicker = new DateTimePicker(this.dateTimePickerContainer.node());
209 window.addEventListener('resize', function () {
210 _this.timePickerLineChart.draw();
211 _this.setTicks();
212 _this.drawWarmRange();
213 if (_this.chartOptions.isCompact)
214 _this.buildCompactFromAndTo();
215 setTimeout(function () {
216 _this.drawGhost();
217 }, 100);
218 });
219 var pickerContainerAndContent = this.targetElement.selectAll(".tsi-dateTimePickerContainer, .tsi-dateTimePickerContainer *");
220 }
221 //clear the date time picker
222 this.dateTimePickerContainer.style("display", "none");
223 this.timePickerContainer.selectAll('.tsi-compactFromTo').remove();
224 if (this.chartOptions.isCompact) {
225 this.targetElement.select('.tsi-sparklineContainer').style("display", 'none');
226 if (!this.chartOptions.persistDateTimeButtonRange)
227 this.targetElement.select(".tsi-timePickerTextContainer").style('display', 'none');
228 this.targetElement.select('.tsi-zoomButtonContainer').style('display', 'none');
229 this.targetElement.select('.tsi-timePickerContainer').style('max-height', '68px').style('top', this.chartOptions.persistDateTimeButtonRange ? '6px' : '20px');
230 }
231 else {
232 this.targetElement.select('.tsi-sparklineContainer').style("display", 'flex');
233 this.targetElement.select(".tsi-timePickerTextContainer").style('display', 'inherit');
234 this.targetElement.select('.tsi-zoomButtonContainer').style('display', 'flex');
235 this.targetElement.select('.tsi-timePickerContainer').style('max-height', 'none').style('top', '0px');
236 }
237 var sparkLineOptions = this.createSparkLineOptions(chartOptions);
238 var visibileAvailability = this.createDisplayBuckets(this.fromMillis, this.toMillis);
239 this.sparkLineChart.render(visibileAvailability, sparkLineOptions, this.ae);
240 this.timePickerLineChart.render(visibileAvailability, this.chartOptions, this.ae);
241 this.setTicks();
242 this.drawWarmRange();
243 if (!this.chartOptions.preserveAvailabilityState) {
244 this.zoomedToMillis = this.toMillis;
245 this.zoomedFromMillis = this.chartOptions.defaultAvailabilityZoomRangeMillis ? Math.max(this.fromMillis, this.toMillis - this.chartOptions.defaultAvailabilityZoomRangeMillis) : this.fromMillis;
246 this.sparkLineChart.setBrushStartTime(new Date(this.zoomedFromMillis));
247 this.sparkLineChart.setBrushEndTime(new Date(this.zoomedToMillis));
248 this.setFromAndToTimes(Math.max(this.fromMillis, this.toMillis - (24 * 60 * 60 * 1000)), this.toMillis);
249 this.setBrush(Math.max(this.fromMillis, this.toMillis - (24 * 60 * 60 * 1000)), this.toMillis);
250 }
251 else {
252 if (this.zoomedFromMillis == null)
253 this.zoomedFromMillis = this.chartOptions.defaultAvailabilityZoomRangeMillis ? Math.max(this.fromMillis, this.toMillis - this.chartOptions.defaultAvailabilityZoomRangeMillis) : this.fromMillis;
254 if (this.zoomedToMillis == null)
255 this.zoomedToMillis = this.toMillis;
256 if (this.sparkLineChart.brushStartTime == null)
257 this.sparkLineChart.setBrushStartTime(new Date(this.zoomedFromMillis));
258 if (this.sparkLineChart.brushEndTime == null)
259 this.sparkLineChart.setBrushEndTime(new Date(this.zoomedToMillis));
260 if (this.selectedFromMillis == null || this.selectedToMillis == null)
261 this.setFromAndToTimes(this.toMillis - (24 * 60 * 60 * 1000), this.toMillis);
262 this.drawGhost();
263 this.setBrush(this.selectedFromMillis, this.selectedToMillis);
264 }
265 this.sparkLineChart.setBrush();
266 var self = this;
267 this.timePickerChart.select(".brushElem").on("wheel.zoom", function (event, d) {
268 var direction = event.deltaY > 0 ? 'out' : 'in';
269 var xPos = (pointer(event)[0]);
270 self.zoom(event, direction, xPos);
271 });
272 if (!this.chartOptions.isCompact) {
273 this.buildZoomButtons();
274 }
275 else {
276 this.timePickerChart.select('.brushElem').select('.selection');
277 }
278 this.setAvailabilityRange(this.zoomedFromMillis, this.zoomedToMillis);
279 if (this.chartOptions.isCompact) {
280 this.buildCompactFromAndTo();
281 }
282 this.timePickerLineChart.drawBrushRange();
283 };
284 AvailabilityChart.prototype.buildZoomButtons = function () {
285 var _this = this;
286 this.targetElement.selectAll(".tsi-zoomButtonContainer").remove();
287 var midpoint = (this.sparkLineChart.x.range()[1] - this.sparkLineChart.x.range()[0]) / 2;
288 var buttonsDiv = this.targetElement.append("div")
289 .classed("tsi-zoomButtonContainer", true);
290 buttonsDiv.append("button")
291 .attr("class", "tsi-zoomButton tsi-zoomButtonIn")
292 .attr('aria-label', this.getString('A line chart zoom in'))
293 .attr('title', this.getString('zoom in'))
294 .on("click", function (event) {
295 _this.zoom(event, "in", midpoint);
296 });
297 buttonsDiv.append("button")
298 .attr("class", "tsi-zoomButton tsi-zoomButtonOut")
299 .attr('aria-label', this.getString('A line chart zoom out'))
300 .attr('title', this.getString('zoom out'))
301 .on("click", function (event) {
302 _this.zoom(event, "out", midpoint);
303 });
304 };
305 AvailabilityChart.prototype.setSelectedMillis = function (fromMillis, toMillis) {
306 this.selectedFromMillis = fromMillis;
307 this.selectedToMillis = toMillis;
308 this.timePickerLineChart.drawBrushRange();
309 };
310 AvailabilityChart.prototype.renderDateTimeButton = function () {
311 var _this = this;
312 var minMillis = this.fromMillis + (Utils.getOffsetMinutes(this.chartOptions.offset, this.fromMillis) * 60 * 1000);
313 var maxMillis = this.toMillis + (Utils.getOffsetMinutes(this.chartOptions.offset, this.toMillis) * 60 * 1000);
314 var startMillis = this.selectedFromMillis + (Utils.getOffsetMinutes(this.chartOptions.offset, this.selectedFromMillis) * 60 * 1000);
315 var endMillis = this.selectedToMillis + (Utils.getOffsetMinutes(this.chartOptions.offset, this.selectedFromMillis) * 60 * 1000);
316 this.dateTimeButton.render(this.chartOptions, this.fromMillis, this.toMillis, this.selectedFromMillis, this.selectedToMillis, function (fromMillis, toMillis, offset) {
317 _this.chartOptions.offset = offset;
318 _this.timePickerLineChart.chartOptions.offset = offset;
319 _this.sparkLineChart.chartOptions.offset = offset;
320 _this.dateTimePickerAction(fromMillis, toMillis);
321 select(_this.renderTarget).select(".tsi-dateTimeContainer").node().focus();
322 }, function () {
323 _this.dateTimePickerContainer.style("display", "none");
324 select(_this.renderTarget).select(".tsi-dateTimeContainer").node().focus();
325 });
326 };
327 AvailabilityChart.prototype.setFromAndToTimes = function (fromMillis, toMillis, isFromButton) {
328 if (isFromButton === void 0) { isFromButton = false; }
329 var timezone = Utils.parseTimezoneName(this.chartOptions.offset);
330 var timezoneAbbreviation = Utils.timezoneAbbreviation(timezone);
331 this.setSelectedMillis(fromMillis, toMillis);
332 if (!isFromButton) {
333 this.renderDateTimeButton();
334 }
335 };
336 AvailabilityChart.prototype.drawGhost = function () {
337 var svgGroup = this.targetElement.select('.tsi-sparklineContainer').select(".tsi-lineChartSVG").select(".svgGroup");
338 svgGroup.selectAll(".ghostRect").remove();
339 svgGroup.append("rect")
340 .classed("ghostRect", true)
341 .attr("x", Math.max(this.sparkLineChart.x.range()[0], this.sparkLineChart.x(new Date(this.selectedFromMillis))))
342 .attr("y", 0)
343 .attr("width", Math.min(Math.max(this.minGhostWidth, this.sparkLineChart.x(new Date(this.selectedToMillis)) - this.sparkLineChart.x(new Date(this.selectedFromMillis))), this.sparkLineChart.x.range()[1] - this.sparkLineChart.x.range()[0]))
344 .attr("height", 8)
345 .attr("fill", this.chartOptions.color ? this.chartOptions.color : 'dark-grey')
346 .attr("fill-opacity", .3)
347 .attr("pointer-events", "none");
348 };
349 AvailabilityChart.prototype.drawWarmRange = function () {
350 var svgGroup = this.targetElement.select('.tsi-timePickerContainer').select(".tsi-lineChartSVG").select(".svgGroup");
351 if (svgGroup.select('.tsi-warmRect').empty()) {
352 svgGroup.append("rect")
353 .classed("tsi-warmRect", true);
354 svgGroup.select('.brushElem').raise();
355 }
356 var warmRect = svgGroup.select(".tsi-warmRect");
357 var outOfRange = true;
358 if (this.chartOptions.warmStoreRange) {
359 var warmStart = new Date(this.chartOptions.warmStoreRange[0]);
360 var boundedWarmStart = new Date(Math.max(warmStart.valueOf(), this.zoomedFromMillis));
361 var warmEnd = new Date(this.chartOptions.warmStoreRange.length === 2 ? this.chartOptions.warmStoreRange[1] : this.toMillis);
362 var boundedWarmEnd = new Date(Math.min(warmEnd.valueOf(), this.zoomedToMillis));
363 if (boundedWarmStart < boundedWarmEnd) {
364 outOfRange = false;
365 warmRect.attr("x", Math.max(this.timePickerLineChart.x(boundedWarmStart)))
366 .attr("y", this.chartOptions.isCompact ? 12 : -8)
367 .attr("width", this.timePickerLineChart.x(boundedWarmEnd) - this.timePickerLineChart.x(boundedWarmStart))
368 .attr("height", this.chartOptions.isCompact ? 4 : Math.max((this.targetElement.select('.tsi-timePickerContainer').select(".tsi-lineChartSVG").node().getBoundingClientRect().height - 44), 0))
369 .attr("fill-opacity", this.chartOptions.isCompact ? .8 : .08)
370 .attr('stroke-opacity', this.chartOptions.isCompact ? 0 : .5)
371 .attr("pointer-events", "none");
372 }
373 }
374 if (outOfRange || this.chartOptions.warmStoreRange === null) {
375 warmRect.style('display', 'none');
376 }
377 else {
378 warmRect.style('display', 'block');
379 }
380 };
381 AvailabilityChart.prototype.buildCompactFromAndTo = function () {
382 this.timePickerContainer.selectAll('.tsi-compactFromTo').remove();
383 // if the view is compact and there is a datetimebuttonrange present, we don't need compact from and to
384 if (this.chartOptions.persistDateTimeButtonRange)
385 return;
386 var brushPositions = this.timePickerLineChart.getBrushPositions();
387 var leftTimeText = null;
388 var rightTimeText = null;
389 if (this.selectedFromMillis != null && this.selectedToMillis != null) {
390 leftTimeText = this.timePickerContainer.append('div')
391 .classed('tsi-compactFromTo', true)
392 .style('left', (brushPositions.leftPos != null ? Math.max(brushPositions.leftPos, 5) : 5) + 'px')
393 .text(Utils.timeFormat(false, false, this.chartOptions.offset, this.chartOptions.is24HourTime, null, null, this.chartOptions.dateLocale)(new Date(this.selectedFromMillis)));
394 var timezoneAbbreviation = ' (' + Utils.createTimezoneAbbreviation(this.chartOptions.offset) + ')';
395 rightTimeText = this.timePickerContainer.append('div')
396 .attr('class', 'tsi-compactFromTo')
397 .style('right', brushPositions.rightPos != null ? 'calc(100% - ' + brushPositions.rightPos + 'px)' : '5px')
398 .style('left', 'auto')
399 .text(Utils.timeFormat(false, false, this.chartOptions.offset, this.chartOptions.is24HourTime, null, null, this.chartOptions.dateLocale)(new Date(this.selectedToMillis)) + timezoneAbbreviation);
400 }
401 if (leftTimeText && rightTimeText) {
402 var rightSideOfLeft = leftTimeText.node().getBoundingClientRect().left + leftTimeText.node().getBoundingClientRect().width;
403 var leftSideOfRight = rightTimeText.node().getBoundingClientRect().left;
404 var totalWidth = this.timePickerContainer.node().getBoundingClientRect().width;
405 var minOffset = 40;
406 if (leftSideOfRight - rightSideOfLeft < minOffset) { // if there is overlap (or near overlap), correction needed
407 var correction = (rightSideOfLeft - leftSideOfRight + minOffset) / 2;
408 //if the correction puts either side off the edge of the container, weight the correction to the other side
409 var leftWeight = 1;
410 var rightWeight = 1;
411 var padding = 32;
412 if ((brushPositions.leftPos - correction) < padding) {
413 leftWeight = 1 - ((padding - (brushPositions.leftPos - correction)) / correction);
414 rightWeight = 2 - leftWeight;
415 }
416 if ((brushPositions.rightPos + correction) > (totalWidth - padding)) {
417 rightWeight = 1 - (padding - (totalWidth - brushPositions.rightPos - correction)) / correction;
418 leftWeight = 2 - rightWeight;
419 }
420 rightTimeText.style('right', 'calc(100% - ' + Math.round((brushPositions.rightPos + (rightWeight * correction))) + 'px)')
421 .style('left', 'auto');
422 leftTimeText.style('left', (brushPositions.leftPos - (leftWeight * correction)) + 'px');
423 }
424 }
425 };
426 AvailabilityChart.prototype.offsetUTC = function (date) {
427 date.setTime(date.getTime() + date.getTimezoneOffset() * 60 * 1000);
428 return date;
429 };
430 AvailabilityChart.prototype.buildFromAndToContainer = function () {
431 var dateTimeContainer = this.timePickerTextContainer.append('div').classed('tsi-dateTimeContainer', true);
432 var timeframeLabel = dateTimeContainer.append("label").text(this.getString("Timeframe")).attr("id", "time-frame-label");
433 var dateTimeButtonContainer = dateTimeContainer.append("div")
434 .classed('tsi-dateTimeButtonContainer', true)
435 .attr("aria-labelledby", 'time-frame-label');
436 this.dateTimeButton = new DateTimeButtonRange(dateTimeButtonContainer.node());
437 };
438 AvailabilityChart.prototype.setTicks = function () {
439 this.timePickerLineChart.updateXAxis();
440 var forceFirst = (this.timePickerLineChart.zoomedFromMillis == this.timePickerLineChart.fromMillis) && (this.zoomedFromMillis == this.fromMillis);
441 var forceLast = (this.timePickerLineChart.zoomedToMillis == this.timePickerLineChart.toMillis) && (this.zoomedToMillis == this.toMillis);
442 this.timePickerLineChart.updateXAxis(forceFirst, forceLast);
443 var ticks = this.timePickerContainer.select('.tsi-timePickerChart')
444 .select('.xAxis')
445 .selectAll('.tick');
446 ticks.each(function (d, i) {
447 var elt = select(this);
448 elt.classed((i === 0 && forceFirst ? 'tsi-fromTick' : (i === ticks.size() - 1 && forceLast ? 'tsi-toTick' : '')), true);
449 });
450 };
451 AvailabilityChart.prototype.setAvailabilityRange = function (fromMillis, toMillis) {
452 this.zoomedFromMillis = fromMillis;
453 this.zoomedToMillis = toMillis;
454 var visibileAvailability = this.createDisplayBuckets(fromMillis, toMillis);
455 this.chartOptions.keepBrush = true;
456 var aeWithNewTimeSpan = __assign(__assign({}, this.ae[0]), { searchSpan: {
457 from: (new Date(fromMillis)),
458 to: (new Date(toMillis))
459 } });
460 this.timePickerLineChart.render(visibileAvailability, this.chartOptions, [aeWithNewTimeSpan]);
461 this.setTicks();
462 this.drawWarmRange();
463 this.timePickerLineChart.setBrush();
464 };
465 AvailabilityChart.prototype.setBrush = function (fromMillis, toMillis, isFromButton) {
466 if (isFromButton === void 0) { isFromButton = false; }
467 this.timePickerLineChart.setBrushEndTime(new Date(toMillis));
468 this.timePickerLineChart.setBrushStartTime(new Date(fromMillis));
469 this.timePickerLineChart.setBrush();
470 this.setFromAndToTimes(fromMillis, toMillis, isFromButton);
471 this.drawGhost();
472 if (this.chartOptions.isCompact)
473 this.buildCompactFromAndTo();
474 };
475 AvailabilityChart.prototype.createSparkLineOptions = function (chartOptions) {
476 var _this = this;
477 return {
478 aggTopMargin: 0,
479 theme: chartOptions.theme,
480 grid: false,
481 tooltip: false,
482 legend: "hidden",
483 brushContextMenuActions: [],
484 snapBrush: false,
485 keepBrush: false,
486 xAxisHidden: true,
487 yAxisHidden: true,
488 focusHidden: true,
489 minBrushWidth: 5,
490 color: null,
491 brushHandlesVisible: true,
492 brushMoveAction: function (from, to) {
493 _this.setAvailabilityRange(from.valueOf(), to.valueOf());
494 },
495 brushClearable: false,
496 hideChartControlPanel: true,
497 brushRangeVisible: false,
498 isArea: true
499 };
500 };
501 return AvailabilityChart;
502}(ChartComponent));
503
504var MAXCARD = 150000;
505var AggregateExpression = /** @class */ (function (_super) {
506 __extends(AggregateExpression, _super);
507 function AggregateExpression(predicateObject, measureObject, measureTypes, searchSpan, splitByObject, colorOrOptionsObject, alias, contextMenu) {
508 if (splitByObject === void 0) { splitByObject = null; }
509 var _this = _super.call(this, (typeof (colorOrOptionsObject) === 'object' && !!colorOrOptionsObject) ? __assign(__assign({}, colorOrOptionsObject), { searchSpan: searchSpan, measureTypes: measureTypes }) : { color: colorOrOptionsObject, searchSpan: searchSpan, measureTypes: measureTypes, alias: alias, contextMenu: contextMenu }) || this;
510 _this.visibleSplitByCap = 10;
511 _this.predicate = predicateObject;
512 _this.splitByObject = splitByObject;
513 _this.measureObject = ((measureTypes.length == 1 && measureTypes[0] == 'count') || measureObject.property == 'Events Count') ? { count: {} } : { input: measureObject };
514 return _this;
515 }
516 AggregateExpression.prototype.toTsx = function (roundFromTo) {
517 var _this = this;
518 if (roundFromTo === void 0) { roundFromTo = false; }
519 var tsx = {};
520 var shiftMillis = Utils.parseShift(this.timeShift, this.startAt, this.searchSpan);
521 var fromMillis = this.searchSpan.from.valueOf() + shiftMillis;
522 var toMillis = this.searchSpan.to.valueOf() + shiftMillis;
523 var bucketSizeInMillis = Utils.parseTimeInput(this.searchSpan.bucketSize);
524 var roundedFromMillis = Math.floor((fromMillis + 62135596800000) / (bucketSizeInMillis)) * (bucketSizeInMillis) - 62135596800000;
525 var roundedToMillis = Math.ceil((toMillis + 62135596800000) / (bucketSizeInMillis)) * (bucketSizeInMillis) - 62135596800000;
526 if (roundFromTo) {
527 fromMillis = roundedFromMillis;
528 toMillis = roundedToMillis;
529 }
530 tsx['searchSpan'] = { from: (new Date(fromMillis)).toISOString(), to: (new Date(toMillis)).toISOString() };
531 // create aggregates
532 var measures = (this.measureObject.hasOwnProperty('count')) ? [{ count: {} }]
533 : this.measureTypes.reduce(function (p, c) {
534 var measureObject = {};
535 if (c == 'count')
536 measureObject = { count: {} };
537 else
538 measureObject[c] = _this['measureObject'];
539 p.push(measureObject);
540 return p;
541 }, []);
542 var aggregateObject = {};
543 var dimensionObject = { dateHistogram: { input: { builtInProperty: "$ts" }, breaks: { size: this.searchSpan.bucketSize } } };
544 if (this.splitByObject != null) {
545 var bucketsCeil = Math.ceil((roundedToMillis - roundedFromMillis) / bucketSizeInMillis);
546 aggregateObject['dimension'] = { uniqueValues: { input: this.splitByObject, take: Math.floor(MAXCARD / bucketsCeil) } };
547 aggregateObject['aggregate'] = { dimension: dimensionObject, measures: measures };
548 }
549 else {
550 aggregateObject['dimension'] = dimensionObject;
551 aggregateObject['measures'] = measures;
552 }
553 var aggregates = [aggregateObject];
554 tsx['aggregates'] = aggregates;
555 // create predicate
556 var predicate;
557 if (!this.measureObject.hasOwnProperty('count'))
558 predicate = { and: [this.predicate, { not: { eq: { left: this.measureObject.input, right: { 'double': null } } } }] };
559 else
560 predicate = this.predicate;
561 tsx['predicate'] = predicate;
562 return tsx;
563 };
564 return AggregateExpression;
565}(ChartDataOptions));
566
567var TsqExpression = /** @class */ (function (_super) {
568 __extends(TsqExpression, _super);
569 function TsqExpression(instanceObject, variableObject, searchSpan, colorOrOptionsObject, alias, contextMenu) {
570 var _this = this;
571 // This constructor should be called with the following parameters:
572 // new TsqExpression(instanceObject, variableObject, searchSpan, optionsObject)
573 // where the optionsObject should contain properties for color, alias, and contextMenu.
574 //
575 // However, to maintain backwards compatibility with older code, the constructor still
576 // accepts the older set of parameters:
577 // new TsqExpression(instanceObject, variableObject, searchSpan, color, alias, contextMenu)
578 // Here we differentiate between both and call the parent class's constructor as appropriate.
579 var optionsObject = (typeof (colorOrOptionsObject) === 'object' && !!colorOrOptionsObject)
580 ? __assign(__assign({}, colorOrOptionsObject), { searchSpan: searchSpan, measureTypes: Object.keys(variableObject) }) : {
581 color: colorOrOptionsObject,
582 searchSpan: searchSpan,
583 measureTypes: Object.keys(variableObject),
584 alias: alias,
585 contextMenu: contextMenu
586 };
587 _this = _super.call(this, optionsObject) || this;
588 _this.instanceObject = instanceObject;
589 _this.variableObject = variableObject;
590 return _this;
591 }
592 TsqExpression.prototype.toTsq = function (roundFromTo, getEvents, getSeries) {
593 if (roundFromTo === void 0) { roundFromTo = false; }
594 if (getEvents === void 0) { getEvents = false; }
595 if (getSeries === void 0) { getSeries = false; }
596 var tsq = {};
597 var shiftMillis = Utils.parseShift(this.timeShift, this.startAt, this.searchSpan);
598 var fromMillis = this.searchSpan.from.valueOf() + shiftMillis;
599 var toMillis = this.searchSpan.to.valueOf() + shiftMillis;
600 if (roundFromTo) {
601 var bucketSizeInMillis = Utils.parseTimeInput(this.searchSpan.bucketSize);
602 var roundedFromMillis = Math.floor((fromMillis + 62135596800000) / (bucketSizeInMillis)) * (bucketSizeInMillis) - 62135596800000;
603 var roundedToMillis = Math.ceil((toMillis + 62135596800000) / (bucketSizeInMillis)) * (bucketSizeInMillis) - 62135596800000;
604 fromMillis = roundedFromMillis;
605 toMillis = roundedToMillis;
606 }
607 tsq['searchSpan'] = { from: (new Date(fromMillis)).toISOString(), to: (new Date(toMillis)).toISOString() };
608 tsq['timeSeriesId'] = this.instanceObject.timeSeriesId;
609 if (getEvents) {
610 return { getEvents: tsq };
611 }
612 else if (getSeries) {
613 tsq['inlineVariables'] = __assign({}, this.variableObject);
614 tsq['projectedVariables'] = Object.keys(this.variableObject);
615 return { getSeries: tsq };
616 }
617 else {
618 tsq['interval'] = Utils.bucketSizeToTsqInterval(this.searchSpan.bucketSize);
619 tsq['inlineVariables'] = __assign({}, this.variableObject);
620 tsq['projectedVariables'] = Object.keys(this.variableObject);
621 return { aggregateSeries: tsq };
622 }
623 };
624 // This method will create an API query payload for the variable statistics of the first inline variable
625 // of this object, for numeric dataTypes. Categorical types work as expected.
626 TsqExpression.prototype.toStatsTsq = function (fromMillis, toMillis) {
627 var tsq = this.toTsq();
628 var shiftMillis = Utils.parseShift(this.timeShift);
629 fromMillis += shiftMillis;
630 toMillis += shiftMillis;
631 tsq.aggregateSeries['searchSpan'] = { from: (new Date(fromMillis)).toISOString(), to: (new Date(toMillis)).toISOString() };
632 tsq.aggregateSeries['interval'] = 'P1000Y';
633 if (this.dataType === 'numeric') {
634 var inlineVariables_1 = { min: {}, max: {}, avg: {}, stDev: {} };
635 var firstVariable_1 = tsq.aggregateSeries['inlineVariables'][Object.keys(tsq.aggregateSeries['inlineVariables'])[0]];
636 Object.keys(inlineVariables_1).forEach(function (k) {
637 inlineVariables_1[k] = JSON.parse(JSON.stringify(firstVariable_1));
638 inlineVariables_1[k].aggregation.tsx = k + "($value)";
639 delete inlineVariables_1[k]['interpolation'];
640 });
641 tsq.aggregateSeries['inlineVariables'] = inlineVariables_1;
642 tsq.aggregateSeries['projectedVariables'] = Object.keys(inlineVariables_1);
643 }
644 return tsq;
645 };
646 return TsqExpression;
647}(ChartDataOptions));
648
649var transformTsqResultsForVisualization = function (tsqResults, options) {
650 var result = [];
651 tsqResults.forEach(function (tsqr, i) {
652 var transformedAggregate = {};
653 var aggregatesObject = {};
654 transformedAggregate[options[i].alias] = { '': aggregatesObject };
655 if (tsqr.hasOwnProperty('__tsiError__'))
656 transformedAggregate[''] = {};
657 else {
658 tsqr.timestamps.forEach(function (ts, j) {
659 aggregatesObject[ts] = tsqr.properties.reduce(function (p, c) {
660 p[c.name] = aggregatesObject[ts] && aggregatesObject[ts][c.name] !== null ? aggregatesObject[ts][c.name] : c['values'][j];
661 return p;
662 }, {});
663 });
664 }
665 result.push(transformedAggregate);
666 });
667 return result;
668};
669
670var UXClient = /** @class */ (function () {
671 function UXClient() {
672 // Public facing components have class constructors exposed as public UXClient members.
673 // This allows for typings to be bundled while maintaining 'new Component()' syntax
674 this.DateTimePicker = DateTimePicker;
675 this.PieChart = PieChart;
676 this.ScatterPlot = ScatterPlot;
677 this.BarChart = GroupedBarChart;
678 this.LineChart = LineChart;
679 this.AvailabilityChart = AvailabilityChart;
680 this.Grid = Grid;
681 this.Slider = Slider;
682 this.Hierarchy = Hierarchy;
683 this.AggregateExpression = AggregateExpression;
684 this.TsqExpression = TsqExpression;
685 this.Heatmap = Heatmap;
686 this.EventsTable = EventsTable;
687 this.ModelSearch = ModelSearch;
688 this.ModelAutocomplete = ModelAutocomplete;
689 this.HierarchyNavigation = HierarchyNavigation;
690 this.TimezonePicker = TimezonePicker;
691 this.EllipsisMenu = EllipsisMenu;
692 this.SingleDateTimePicker = SingleDateTimePicker;
693 this.DateTimeButtonSingle = DateTimeButtonSingle;
694 this.DateTimeButtonRange = DateTimeButtonRange;
695 this.ProcessGraphic = ProcessGraphic;
696 this.PlaybackControls = PlaybackControls;
697 this.ColorPicker = ColorPicker;
698 this.GeoProcessGraphic = GeoProcessGraphic;
699 this.transformTsqResultsForVisualization = transformTsqResultsForVisualization;
700 }
701 UXClient.prototype.UXClient = function () {
702 };
703 UXClient.prototype.transformTsxToEventsArray = function (events, options) {
704 var timezoneOffset = options.timezoneOffset ? options.timezoneOffset : 0;
705 var rows = [];
706 var eventSourceProperties = {};
707 var nameToStrippedPropName = {};
708 var valueToStrippedValueMap = {};
709 var _loop_1 = function () {
710 if (events[eventIdx].hasOwnProperty('schema')) {
711 eventSourceProperties[events[eventIdx].schema.rid] = {};
712 eventSourceProperties[events[eventIdx].schema.rid].propertyNames = events[eventIdx].schema.properties.reduce(function (prev, curr) {
713 prev.push({ name: curr.name, type: curr.type });
714 return prev;
715 }, []);
716 eventSourceProperties[events[eventIdx].schema.rid].eventSourceName = events[eventIdx].schema['$esn'];
717 eventSourceId = events[eventIdx].schema.rid;
718 }
719 else {
720 eventSourceId = events[eventIdx].schemaRid;
721 }
722 timeStamp = (new Date((new Date(events[eventIdx]['$ts'])).valueOf() - timezoneOffset)).toISOString().slice(0, -1).replace('T', ' ');
723 event = { 'timestamp ($ts)': timeStamp };
724 // lts logic
725 lts = events[eventIdx]['$lts'] ? events[eventIdx]['$lts'] : null;
726 if (lts) {
727 event['LocalTimestamp_DateTime'] = {
728 value: lts.replace('T', ' '),
729 name: 'LocalTimestamp',
730 type: 'DateTime'
731 };
732 }
733 event["EventSourceName_String"] = {
734 value: eventSourceProperties[eventSourceId].eventSourceName,
735 name: 'EventSourceName',
736 type: 'String'
737 };
738 for (var propIdx in eventSourceProperties[eventSourceId].propertyNames) {
739 name = eventSourceProperties[eventSourceId].propertyNames[propIdx].name;
740 if (!nameToStrippedPropName.hasOwnProperty(name))
741 nameToStrippedPropName[name] = Utils.stripForConcat(name);
742 strippedName = nameToStrippedPropName[name];
743 type = eventSourceProperties[eventSourceId].propertyNames[propIdx].type;
744 columnNameAndType = strippedName + "_" + type;
745 if (!valueToStrippedValueMap.hasOwnProperty(String(events[eventIdx].values[propIdx])))
746 valueToStrippedValueMap[String(events[eventIdx].values[propIdx])] = Utils.stripForConcat(String(events[eventIdx].values[propIdx]));
747 eventObject = {
748 value: valueToStrippedValueMap[String(events[eventIdx].values[propIdx])],
749 name: strippedName,
750 type: type
751 };
752 event[columnNameAndType] = eventObject;
753 }
754 if (events[eventIdx].hasOwnProperty('$op')) {
755 var defaultType_1 = 'String';
756 var otherProps_1 = JSON.parse(events[eventIdx]['$op']);
757 Object.keys(otherProps_1).forEach(function (propNameRaw) {
758 var strippedNameOP = Utils.stripForConcat(propNameRaw);
759 var columnNameAndTypeOP = strippedNameOP + '_String';
760 event[columnNameAndTypeOP] = {
761 value: otherProps_1[propNameRaw],
762 name: strippedNameOP,
763 type: defaultType_1
764 };
765 });
766 }
767 rows.push(event);
768 };
769 var eventSourceId, timeStamp, event, lts, name, strippedName, type, columnNameAndType, eventObject;
770 for (var eventIdx in events) {
771 _loop_1();
772 }
773 return rows;
774 };
775 UXClient.prototype.toISONoMillis = function (dateTime) {
776 return dateTime.toISOString().slice(0, -5) + "Z";
777 };
778 //specifiedRange gives the subset of availability buckets to be returned. If not included, will return all buckets
779 UXClient.prototype.transformAvailabilityForVisualization = function (availabilityTsx) {
780 var _this = this;
781 var from = new Date(availabilityTsx.range.from);
782 var to = new Date(availabilityTsx.range.to);
783 var rawBucketSize = Utils.parseTimeInput(availabilityTsx.intervalSize);
784 var buckets = {};
785 var startBucket = Math.round(Math.floor(from.valueOf() / rawBucketSize) * rawBucketSize);
786 var firstKey = this.toISONoMillis(new Date(startBucket));
787 var firstCount = availabilityTsx.distribution[firstKey] ? availabilityTsx.distribution[firstKey] : 0;
788 // reset first key if greater than the availability range from
789 if (startBucket < (new Date(availabilityTsx.range.from)).valueOf())
790 firstKey = this.toISONoMillis(new Date(availabilityTsx.range.from));
791 buckets[firstKey] = { count: firstCount };
792 Object.keys(availabilityTsx.distribution).forEach(function (key) {
793 var formattedISO = _this.toISONoMillis(new Date(key));
794 buckets[formattedISO] = { count: availabilityTsx.distribution[key] };
795 });
796 //set end time value
797 var lastBucket = Math.round(Math.floor(to.valueOf() / rawBucketSize) * rawBucketSize);
798 // pad out if range is less than one bucket;
799 if (startBucket == lastBucket) {
800 for (var i = startBucket; i <= startBucket + rawBucketSize; i += (rawBucketSize / 60)) {
801 if (buckets[this.toISONoMillis(new Date(i))] == undefined)
802 buckets[this.toISONoMillis(new Date(i))] = { count: 0 };
803 }
804 //reset startBucket to count 0 if not the start time
805 if (startBucket != from.valueOf()) {
806 buckets[this.toISONoMillis(new Date(startBucket))] = { count: 0 };
807 }
808 }
809 return [{ "availabilityCount": { "": buckets } }];
810 };
811 UXClient.prototype.transformAggregatesForVisualization = function (aggregates, options) {
812 var result = [];
813 aggregates.forEach(function (agg, i) {
814 var transformedAggregate = {};
815 var aggregatesObject = {};
816 transformedAggregate[options[i].alias] = aggregatesObject;
817 if (agg.hasOwnProperty('__tsiError__'))
818 transformedAggregate[''] = {};
819 else if (agg.hasOwnProperty('aggregate')) {
820 agg.dimension.forEach(function (d, j) {
821 var dateTimeToValueObject = {};
822 aggregatesObject[d] = dateTimeToValueObject;
823 agg.aggregate.dimension.forEach(function (dt, k) {
824 var measuresObject = {};
825 dateTimeToValueObject[dt] = measuresObject;
826 options[i].measureTypes.forEach(function (t, l) {
827 if (agg.aggregate.measures[j][k] != null && agg.aggregate.measures[j][k] != undefined &&
828 agg.aggregate.measures[j][k][l] != null && agg.aggregate.measures[j][k][l] != undefined)
829 measuresObject[t] = agg.aggregate.measures[j][k][l];
830 else
831 measuresObject[t] = null;
832 });
833 });
834 });
835 }
836 else {
837 var dateTimeToValueObject = {};
838 aggregatesObject[''] = dateTimeToValueObject;
839 agg.dimension.forEach(function (dt, j) {
840 var measuresObject = {};
841 dateTimeToValueObject[dt] = measuresObject;
842 options[i].measureTypes.forEach(function (t, l) {
843 measuresObject[t] = agg.measures[j][l];
844 });
845 });
846 }
847 result.push(transformedAggregate);
848 });
849 return result;
850 };
851 // exposed publicly to use for highlighting elements in the well on hover/focus
852 UXClient.prototype.createEntityKey = function (aggName, aggIndex) {
853 if (aggIndex === void 0) { aggIndex = 0; }
854 return Utils.createEntityKey(aggName, aggIndex);
855 };
856 UXClient.prototype.transformTsqResultsToEventsArray = function (results) {
857 var flattenedResults = [];
858 results.forEach(function (tsqr) {
859 tsqr.timestamps.forEach(function (ts, idx) {
860 var event = {};
861 event['timestamp ($ts)'] = ts;
862 tsqr.properties.forEach(function (p) {
863 event[p.name + "_" + p.type] = { name: p.name, type: p.type, value: p.values[idx] };
864 });
865 flattenedResults.push(event);
866 });
867 });
868 return flattenedResults.sort(function (a, b) { return (new Date(a['timestamp ($ts)'])).valueOf() < (new Date(b['timestamp ($ts)'])).valueOf() ? -1 : 1; });
869 };
870 return UXClient;
871}());
872
873export { AvailabilityChart as A, UXClient as U };