UNPKG

45.4 kBJavaScriptView Raw
1import { _ as __assign, a as __extends } from './tslib.es6-f952ba6f.js';
2import { D as DataTypes, U as Utils, S as ShiftTypes, v as valueTypes, G as GRIDCONTAINERCLASS } from './Utils-38a0872e.js';
3import { select } from 'd3';
4import { C as Component } from './Component-5173b5ea.js';
5
6var ChartComponentData = /** @class */ (function () {
7 function ChartComponentData() {
8 var _this = this;
9 this.data = {};
10 this.displayState = {};
11 this.timeArrays = [];
12 this.visibleTSCount = 0;
13 this.visibleTAs = [];
14 this.allValues = [];
15 this.allNumericValues = [];
16 this.usesSeconds = false;
17 this.usesMillis = false;
18 this.fromMillis = Infinity;
19 this.toMillis = 0;
20 this.stickiedKey = null;
21 this.isFromHeatmap = false;
22 this.getSwimlane = function (aggKey) {
23 return (_this.displayState[aggKey].aggregateExpression ? _this.displayState[aggKey].aggregateExpression.swimLane : null);
24 };
25 this.getVisibleType = function (aggKey, splitBy, defaultType, measures) {
26 if (_this.displayState[aggKey] && _this.displayState[aggKey].splitBys[splitBy]) {
27 var prospectiveVisible = _this.displayState[aggKey].splitBys[splitBy].visibleType;
28 if (measures.indexOf(prospectiveVisible) !== -1) {
29 return prospectiveVisible;
30 }
31 }
32 return defaultType;
33 };
34 }
35 ChartComponentData.prototype.setAllTimestampsArray = function () {
36 var allTimestamps = {};
37 this.data.forEach(function (ae) {
38 var aeObj = ae[Object.keys(ae)[0]];
39 Object.keys(aeObj).forEach(function (timeseries) {
40 Object.keys(aeObj[timeseries]).forEach(function (timestamp) {
41 allTimestamps[timestamp] = true;
42 });
43 });
44 });
45 this.allTimestampsArray = Object.keys(allTimestamps).sort();
46 };
47 ChartComponentData.prototype.getDataType = function (aggKey) {
48 return this.displayState[aggKey] ? this.displayState[aggKey].dataType : DataTypes.Numeric;
49 };
50 //add colors if none present
51 ChartComponentData.prototype.fillColors = function (aggregateExpressionOptions) {
52 if (aggregateExpressionOptions == null)
53 aggregateExpressionOptions = [];
54 // correct aEOs to add empty objects if the length doesn't match up with the data
55 if (aggregateExpressionOptions.length < this.data.length) {
56 for (var i = aggregateExpressionOptions.length; i < this.data.length; i++) {
57 aggregateExpressionOptions.push({});
58 }
59 }
60 var colorlessCount = aggregateExpressionOptions.reduce(function (colorlessCount, aEO) {
61 if (aEO.color != null)
62 return colorlessCount;
63 return colorlessCount + 1;
64 }, 0);
65 var colorI = 0;
66 var colors = Utils.generateColors(colorlessCount);
67 aggregateExpressionOptions.forEach(function (aEO) {
68 if (aEO.color == null) {
69 aEO.color = colors[colorI];
70 colorI++;
71 }
72 });
73 return aggregateExpressionOptions;
74 };
75 ChartComponentData.prototype.mergeDataToDisplayStateAndTimeArrays = function (data, aggregateExpressionOptions) {
76 var _this = this;
77 if (aggregateExpressionOptions === void 0) { aggregateExpressionOptions = null; }
78 this.data = data;
79 var newDisplayState = {};
80 this.timeArrays = {};
81 this.visibleTAs = {};
82 this.allValues = [];
83 this.allNumericValues = [];
84 this.visibleTSCount = 0;
85 this.fromMillis = Infinity;
86 this.toMillis = 0;
87 this.usesSeconds = false;
88 this.usesMillis = false;
89 aggregateExpressionOptions = this.fillColors(aggregateExpressionOptions);
90 var aggKeys = Utils.getAggKeys(this.data);
91 this.data = this.data.map(function (aggregate, i) {
92 var aggName = Object.keys(aggregate)[0];
93 var aggregateCopy = __assign({}, aggregate);
94 var aggKey = aggKeys[i];
95 _this.data[i].aggKey = aggKey;
96 aggregateCopy.aggKey = aggKey;
97 if (_this.displayState[aggKey]) {
98 newDisplayState[aggKey] = {
99 visible: (aggregateExpressionOptions[i] && aggregateExpressionOptions[i].visibilityState) ?
100 aggregateExpressionOptions[i].visibilityState[0] : _this.displayState[aggKey].visible,
101 name: _this.displayState[aggKey].name,
102 color: ((aggregateExpressionOptions[i] && aggregateExpressionOptions[i].color) ?
103 aggregateExpressionOptions[i].color : _this.displayState[aggKey].color),
104 interpolationFunction: aggregateExpressionOptions[i].interpolationFunction,
105 yExtent: aggregateExpressionOptions[i].yExtent,
106 includeEnvelope: aggregateExpressionOptions[i].includeEnvelope,
107 includeDots: aggregateExpressionOptions[i].includeDots,
108 splitBys: {},
109 dataType: aggregateExpressionOptions[i].dataType,
110 visibleSplitByCap: _this.displayState[aggKey].visibleSplitByCap,
111 shownSplitBys: 20
112 };
113 }
114 else {
115 newDisplayState[aggKey] = {
116 visible: (aggregateExpressionOptions[i] && aggregateExpressionOptions[i].visibilityState) ?
117 aggregateExpressionOptions[i].visibilityState[0] : true,
118 splitBys: {},
119 name: aggName,
120 color: ((aggregateExpressionOptions[i] && aggregateExpressionOptions[i].color) ?
121 aggregateExpressionOptions[i].color : "teal"),
122 interpolationFunction: aggregateExpressionOptions[i].interpolationFunction,
123 yExtent: aggregateExpressionOptions[i].yExtent,
124 includeEnvelope: aggregateExpressionOptions[i].includeEnvelope,
125 includeDots: aggregateExpressionOptions[i].includeDots,
126 dataType: aggregateExpressionOptions[i].dataType,
127 visibleSplitByCap: 10,
128 shownSplitBys: 20
129 };
130 }
131 if (aggregateExpressionOptions) {
132 newDisplayState[aggKey].contextMenuActions = aggregateExpressionOptions[i] ?
133 aggregateExpressionOptions[i].contextMenu : [];
134 newDisplayState[aggKey].aggregateExpression = aggregateExpressionOptions[i];
135 // impose cap on visible splitBys if relevant
136 if (aggregateExpressionOptions[i] && aggregateExpressionOptions[i].visibleSplitByCap) {
137 newDisplayState[aggKey].visibleSplitByCap = aggregateExpressionOptions[i].visibleSplitByCap;
138 }
139 }
140 else {
141 //revert to previous context menu actions if no new ones passed in and old ones exist
142 var oldContextMenuActions = (_this.displayState[aggKey] && _this.displayState[aggKey].contextMenuActions) ?
143 _this.displayState[aggKey].contextMenuActions : [];
144 newDisplayState[aggKey].contextMenuActions = oldContextMenuActions;
145 var oldAggregateExpression = (_this.displayState[aggKey] && _this.displayState[aggKey].aggregateExpression) ?
146 _this.displayState[aggKey].aggregateExpression : {};
147 newDisplayState[aggKey].aggregateExpression = oldAggregateExpression;
148 }
149 if (newDisplayState[aggKey].aggregateExpression && newDisplayState[aggKey].aggregateExpression.searchSpan) {
150 newDisplayState[aggKey].from = new Date(newDisplayState[aggKey].aggregateExpression.searchSpan.from);
151 newDisplayState[aggKey].to = new Date(newDisplayState[aggKey].aggregateExpression.searchSpan.to);
152 newDisplayState[aggKey].bucketSize = newDisplayState[aggKey].aggregateExpression.searchSpan.bucketSize ?
153 Utils.parseTimeInput(newDisplayState[aggKey].aggregateExpression.searchSpan.bucketSize) :
154 null;
155 }
156 var aggregateVisible = newDisplayState[aggKey].visible;
157 _this.timeArrays[aggKey] = [];
158 _this.visibleTAs[aggKey] = {};
159 Object.keys(data[i][aggName]).forEach(function (splitBy, splitByI) {
160 var shiftValue = Utils.parseShift(aggregateExpressionOptions[i].timeShift, aggregateExpressionOptions[i].startAt, aggregateExpressionOptions[i].searchSpan);
161 _this.timeArrays[aggKey][splitBy] = _this.convertAggregateToArray(data[i][aggName][splitBy], aggKey, aggName, splitBy, newDisplayState[aggKey].from, newDisplayState[aggKey].to, newDisplayState[aggKey].bucketSize, shiftValue);
162 if (newDisplayState[aggKey].dataType === DataTypes.Categorical && aggregateExpressionOptions[i].rollupCategoricalValues) {
163 _this.timeArrays[aggKey][splitBy] = Utils.rollUpContiguous(_this.timeArrays[aggKey][splitBy]);
164 }
165 var isVisible;
166 // first priority: set from passed in visibility state
167 if (aggregateExpressionOptions[i] && aggregateExpressionOptions[i].visibilityState && aggregateExpressionOptions[i].visibilityState.length === 2) {
168 isVisible = aggregateExpressionOptions[i].visibilityState[1].indexOf(splitBy) != -1;
169 }
170 //second priority: special case where solo split by and is ''
171 else if (aggregateExpressionOptions[i] && aggregateExpressionOptions[i].visibilityState && Object.keys(data[i][aggName]).length === 1 && splitBy === '') {
172 isVisible = aggregateExpressionOptions[i].visibilityState[0];
173 }
174 // third priority: already set value
175 else if (_this.displayState[aggKey] && _this.displayState[aggKey].splitBys[splitBy]) {
176 isVisible = _this.displayState[aggKey].splitBys[splitBy].visible;
177 }
178 // last priority: set isVisible based on visibleSplitByCap
179 else {
180 isVisible = (splitByI < newDisplayState[aggKey].visibleSplitByCap);
181 }
182 newDisplayState[aggKey].splitBys[splitBy] = {
183 visible: isVisible,
184 visibleType: newDisplayState[aggKey].splitBys[splitBy] ? newDisplayState[aggKey].splitBys[splitBy].visibleType : null,
185 types: newDisplayState[aggKey].splitBys[splitBy] ? newDisplayState[aggKey].splitBys[splitBy].types : [],
186 };
187 if (_this.timeArrays[aggKey][splitBy] && _this.timeArrays[aggKey][splitBy].length &&
188 newDisplayState[aggKey].aggregateExpression && newDisplayState[aggKey].aggregateExpression.measureTypes) {
189 newDisplayState[aggKey].splitBys[splitBy].types = newDisplayState[aggKey].aggregateExpression.measureTypes;
190 }
191 else {
192 newDisplayState[aggKey].splitBys[splitBy].types = _this.determineMeasureTypes(_this.timeArrays[aggKey][splitBy]);
193 }
194 if (!newDisplayState[aggKey].splitBys[splitBy].visibleType || (newDisplayState[aggKey].splitBys[splitBy].types.indexOf(newDisplayState[aggKey].splitBys[splitBy].visibleType) === -1)) {
195 var visibleMeasure = newDisplayState[aggKey].splitBys[splitBy].types.indexOf("avg") !== -1 ? "avg" :
196 newDisplayState[aggKey].splitBys[splitBy].types[0];
197 newDisplayState[aggKey].splitBys[splitBy].visibleType = _this.getVisibleType(aggKey, splitBy, visibleMeasure, newDisplayState[aggKey].splitBys[splitBy].types);
198 }
199 //add to visible display states if splitby is visible
200 if (newDisplayState[aggKey]["splitBys"][splitBy]["visible"] && aggregateVisible) {
201 _this.allValues = _this.allValues.concat(_this.timeArrays[aggKey][splitBy]);
202 if (newDisplayState[aggKey].dataType === DataTypes.Numeric) {
203 _this.allNumericValues = _this.allNumericValues.concat(_this.timeArrays[aggKey][splitBy]);
204 }
205 _this.usesSeconds = _this.usesSeconds || _this.doesTimeArrayUseSeconds(_this.timeArrays[aggKey][splitBy]);
206 _this.usesMillis = _this.usesMillis || _this.doesTimeArrayUseMillis(_this.timeArrays[aggKey][splitBy]);
207 _this.visibleTAs[aggKey][splitBy] = _this.timeArrays[aggKey][splitBy];
208 _this.visibleTSCount += 1;
209 }
210 });
211 return aggregateCopy;
212 });
213 //ensure that the stickied Key exists in the new data, otherwise revert to null
214 if (this.stickiedKey) {
215 var splitBy = this.stickiedKey.splitBy;
216 var aggKey = this.stickiedKey.aggregateKey;
217 if (!(newDisplayState[aggKey] && newDisplayState[aggKey].visible &&
218 newDisplayState[aggKey].splitBys[splitBy] && newDisplayState[aggKey].splitBys[splitBy].visible)) {
219 this.stickiedKey = null;
220 }
221 }
222 this.displayState = newDisplayState;
223 this.setAllTimestampsArray();
224 };
225 ChartComponentData.prototype.determineMeasureTypes = function (timeArray) {
226 var measureTypes = timeArray.reduce(function (measureTypes, curr) {
227 if (curr && curr.measures && Object.keys(curr.measures).length) {
228 Object.keys(curr.measures).forEach(function (measure) {
229 measureTypes[measure] = true;
230 });
231 }
232 return measureTypes;
233 }, {});
234 return Object.keys(measureTypes);
235 };
236 ChartComponentData.prototype.getTemporalShiftStringTuple = function (aggKey) {
237 var ae = this.displayState[aggKey].aggregateExpression;
238 if (ae) {
239 if (Utils.isStartAt(ae.startAt, ae.searchSpan)) {
240 return [ShiftTypes.startAt, ae.startAt];
241 }
242 if (ae.timeShift) {
243 return [ShiftTypes.shifted, ae.timeShift];
244 }
245 }
246 return null;
247 };
248 ChartComponentData.prototype.getTemporalShiftMillis = function (aggKey) {
249 var ae = this.displayState[aggKey].aggregateExpression;
250 if (ae) {
251 return Utils.parseShift(ae.timeShift, ae.startAt, ae.searchSpan);
252 }
253 return 0;
254 };
255 ChartComponentData.prototype.doesTimeArrayUseSeconds = function (timeArray) {
256 return timeArray.reduce(function (prev, curr) {
257 return curr.dateTime.getSeconds() != 0 || prev;
258 }, false);
259 };
260 ChartComponentData.prototype.doesTimeArrayUseMillis = function (timeArray) {
261 return timeArray.reduce(function (prev, curr) {
262 return curr.dateTime.getMilliseconds() != 0 || prev;
263 }, false);
264 };
265 //returns the from and to of all values
266 ChartComponentData.prototype.setAllValuesAndVisibleTAs = function () {
267 var _this = this;
268 var toMillis = 0;
269 var fromMillis = Infinity;
270 this.allValues = [];
271 this.allNumericValues = [];
272 this.visibleTAs = [];
273 this.visibleTSCount = 0;
274 Object.keys(this.timeArrays).forEach(function (aggKey) {
275 if (_this.getAggVisible(aggKey)) {
276 _this.visibleTAs[aggKey] = {};
277 Object.keys(_this.timeArrays[aggKey]).forEach(function (splitBy) {
278 if (_this.getSplitByVisible(aggKey, splitBy)) {
279 _this.allValues = _this.allValues.concat(_this.timeArrays[aggKey][splitBy]);
280 if (_this.displayState[aggKey].dataType === DataTypes.Numeric) {
281 _this.allNumericValues = _this.allNumericValues.concat(_this.timeArrays[aggKey][splitBy]);
282 }
283 _this.visibleTAs[aggKey][splitBy] = _this.timeArrays[aggKey][splitBy];
284 _this.visibleTSCount += 1;
285 _this.timeArrays[aggKey][splitBy].forEach(function (d) {
286 var millis = d.dateTime.valueOf();
287 var bucketSize = _this.displayState[aggKey].bucketSize;
288 if (millis < fromMillis)
289 fromMillis = millis;
290 var endValue = bucketSize ? millis + bucketSize : millis;
291 if (endValue > toMillis)
292 toMillis = endValue;
293 });
294 _this.usesSeconds = _this.usesSeconds || _this.doesTimeArrayUseSeconds(_this.timeArrays[aggKey][splitBy]);
295 _this.usesMillis = _this.usesMillis || _this.doesTimeArrayUseMillis(_this.timeArrays[aggKey][splitBy]);
296 }
297 });
298 }
299 });
300 //set this.toMillis and this.fromMillis if new values are more extreme
301 this.toMillis = (toMillis > this.toMillis) ? toMillis : this.toMillis;
302 this.fromMillis = (fromMillis < this.fromMillis) ? fromMillis : this.fromMillis;
303 if (this.fromMillis === Infinity) {
304 this.fromMillis = this.toMillis - 1;
305 }
306 return [new Date(this.fromMillis), new Date(this.toMillis)];
307 };
308 ChartComponentData.prototype.findLastTimestampWithValue = function (aggKey, splitBy) {
309 var timeArray = this.timeArrays[aggKey][splitBy];
310 var i = timeArray.length - 1;
311 var lastValue = null;
312 while (i >= 0 && lastValue === null) {
313 if (timeArray[i].measures && (timeArray[i].measures[this.getVisibleMeasure(aggKey, splitBy)] !== null)) {
314 lastValue = timeArray[i];
315 }
316 i += -1;
317 }
318 return lastValue;
319 };
320 ChartComponentData.prototype.findFirstBucket = function (agg, fromMillis, bucketSize) {
321 if (agg == null || Object.keys(agg).length == 0)
322 return null;
323 var possibleFirstKeys = Object.keys(agg).filter(function (a) {
324 return ((new Date(a)).valueOf() + bucketSize) > fromMillis;
325 });
326 if (possibleFirstKeys.length === 0) {
327 return null;
328 }
329 var firstPresentKey = possibleFirstKeys.sort(function (a, b) {
330 if ((new Date(a)).valueOf() < (new Date(b)).valueOf())
331 return -1;
332 if ((new Date(a)).valueOf() > (new Date(b)).valueOf())
333 return 1;
334 return 0;
335 })[0];
336 var firstMillis = (new Date(firstPresentKey)).valueOf();
337 while (firstMillis > fromMillis) {
338 firstMillis += -bucketSize;
339 }
340 return firstMillis;
341 };
342 ChartComponentData.prototype.getNumberOfPaddedBuckets = function (from, to, bucketSize) {
343 return Math.ceil((to - from) / bucketSize);
344 };
345 //aggregates object => array of objects containing timestamp and values. Pad with
346 ChartComponentData.prototype.convertAggregateToArray = function (agg, aggKey, aggName, splitBy, from, to, bucketSize, shiftValue) {
347 if (from === void 0) { from = null; }
348 if (to === void 0) { to = null; }
349 if (bucketSize === void 0) { bucketSize = null; }
350 var aggArray = [];
351 var isoStringAgg = {};
352 Object.keys(agg).forEach(function (dateString) {
353 var shiftedDate = new Date((new Date(dateString)).valueOf() - shiftValue);
354 var jsISOString = shiftedDate.toISOString();
355 isoStringAgg[jsISOString] = agg[dateString];
356 });
357 agg = isoStringAgg;
358 var createTimeValueObject = function () {
359 var timeValueObject = {};
360 timeValueObject["aggregateKey"] = aggKey;
361 timeValueObject["aggregateName"] = aggName;
362 timeValueObject["splitBy"] = splitBy;
363 timeValueObject["measures"] = {};
364 timeValueObject["bucketSize"] = bucketSize;
365 return timeValueObject;
366 };
367 if (from)
368 this.fromMillis = Math.min(from.valueOf(), this.fromMillis);
369 if (to)
370 this.toMillis = Math.max(to.valueOf(), this.toMillis);
371 if (from && to && bucketSize) {
372 var firstBucket = this.findFirstBucket(agg, from.valueOf(), bucketSize);
373 if (firstBucket !== null) {
374 var firstBucketMillis = firstBucket.valueOf();
375 var isExcessiveBucketCount = (this.getNumberOfPaddedBuckets(firstBucketMillis, to.valueOf(), bucketSize) > 10000);
376 // pad if not an excessive number of buckets
377 if (!isExcessiveBucketCount) {
378 for (var currTime = new Date(firstBucketMillis); (currTime.valueOf() < to.valueOf()); currTime = new Date(currTime.valueOf() + bucketSize)) {
379 var timeValueObject = createTimeValueObject();
380 timeValueObject["dateTime"] = currTime;
381 var currTimeString = currTime.toISOString();
382 if (agg[currTimeString]) {
383 var currMeasures = agg[currTimeString];
384 Object.keys(currMeasures).forEach(function (measure) {
385 timeValueObject["measures"][measure] = currMeasures[measure];
386 });
387 }
388 else {
389 timeValueObject["measures"] = null;
390 }
391 aggArray.push(timeValueObject);
392 this.fromMillis = Math.min(from.valueOf(), currTime.valueOf());
393 this.toMillis = Math.max(to.valueOf(), currTime.valueOf() + bucketSize);
394 }
395 }
396 else {
397 Object.keys(agg).forEach(function (currTimeString) {
398 var timeValueObject = createTimeValueObject();
399 timeValueObject["dateTime"] = new Date(currTimeString);
400 var currMeasures = agg[currTimeString];
401 Object.keys(currMeasures).forEach(function (measure) {
402 timeValueObject["measures"][measure] = currMeasures[measure];
403 });
404 aggArray.push(timeValueObject);
405 });
406 }
407 }
408 }
409 else {
410 Object.keys(agg).sort().forEach(function (dateTime) {
411 var timeValueObject = createTimeValueObject();
412 timeValueObject["dateTime"] = new Date(dateTime);
413 if (agg[dateTime]) {
414 Object.keys(agg[dateTime]).forEach(function (measure) {
415 timeValueObject["measures"][measure] = agg[dateTime][measure];
416 });
417 }
418 aggArray.push(timeValueObject);
419 });
420 }
421 return aggArray;
422 };
423 ChartComponentData.prototype.isSplitByVisible = function (aggI, splitBy) {
424 if (this.displayState[aggI] == undefined || !this.displayState[aggI].visible)
425 return false;
426 if (this.displayState[aggI].splitBys[splitBy] == undefined)
427 return false;
428 return this.displayState[aggI].splitBys[splitBy].visible;
429 };
430 ChartComponentData.prototype.isPossibleEnvelope = function (aggKey, splitBy) {
431 return (this.displayState[aggKey].splitBys[splitBy].visibleType == "avg") &&
432 (this.displayState[aggKey].splitBys[splitBy].types.indexOf("min") != -1) &&
433 (this.displayState[aggKey].splitBys[splitBy].types.indexOf("max") != -1);
434 };
435 ChartComponentData.prototype.getVisibleMeasure = function (aggI, splitBy) {
436 if (this.displayState[aggI] == undefined || this.displayState[aggI].splitBys[splitBy] == undefined)
437 return null;
438 return this.displayState[aggI].splitBys[splitBy].visibleType;
439 };
440 ChartComponentData.prototype.getAggVisible = function (aggKey) {
441 return this.displayState[aggKey].visible;
442 };
443 ChartComponentData.prototype.getSplitByVisible = function (aggKey, splitBy) {
444 return (this.getAggVisible(aggKey) && this.displayState[aggKey].splitBys[splitBy].visible);
445 };
446 ChartComponentData.prototype.aggHasVisibleSplitBys = function (aggKey) {
447 var _this = this;
448 if (!this.getAggVisible(aggKey))
449 return false;
450 var hasVisibleSplitBy = false;
451 Object.keys(this.displayState[aggKey].splitBys).forEach(function (splitBy) {
452 if (_this.isSplitByVisible(aggKey, splitBy))
453 hasVisibleSplitBy = true;
454 });
455 return hasVisibleSplitBy;
456 };
457 ChartComponentData.prototype.valueAtTS = function (aggKey, splitByName, ts) {
458 var splitBy = this.displayState[aggKey].splitBys[splitByName];
459 return this.data[aggKey][this.displayState[aggKey].name][splitByName][ts][splitBy.visibleType];
460 };
461 ChartComponentData.prototype.setFilteredAggregates = function () {
462 var _this = this;
463 this.filteredAggregates = Object.keys(this.displayState).filter(function (aggKey) {
464 return _this.displayState[aggKey].visible;
465 });
466 };
467 ChartComponentData.prototype.guessValueType = function (v) {
468 if (typeof v === 'number') {
469 return valueTypes.Double;
470 }
471 if (typeof v === 'string') {
472 return valueTypes.String;
473 }
474 return valueTypes.Dynamic;
475 };
476 ChartComponentData.prototype.generateCSVString = function (offset, dateLocale, spMeasures) {
477 var _this = this;
478 if (offset === void 0) { offset = 0; }
479 if (dateLocale === void 0) { dateLocale = 'en'; }
480 if (spMeasures === void 0) { spMeasures = null; }
481 //replace comma at end of line with end line character
482 var endLine = function (s) {
483 return s.slice(0, s.length - 1) + "\n";
484 };
485 var csvString = "";
486 var headerString = "Interval, Interval (UTC),";
487 var rowMap = {};
488 var rowOrder = [];
489 this.data.forEach(function (aggObj) {
490 var aggKey = aggObj.aggKey;
491 var splitByObject = _this.displayState[aggKey].aggregateExpression.splitByObject;
492 Object.keys(_this.timeArrays[aggKey]).forEach(function (splitBy) {
493 var splitByString = Utils.stripNullGuid(_this.displayState[aggKey].name);
494 if (splitByObject !== undefined && splitByObject !== null) {
495 splitByString += "/" + splitByObject.property + "/" + splitBy;
496 }
497 else if (splitBy !== '') {
498 splitByString += '/' + splitBy;
499 }
500 else if (_this.displayState[aggKey].aggregateExpression.variableAlias) {
501 splitByString += '/' + _this.displayState[aggKey].aggregateExpression.variableAlias;
502 }
503 var types = spMeasures ? spMeasures : _this.displayState[aggKey].splitBys[splitBy].types;
504 types.forEach(function (type) {
505 var rowKey = aggKey + "_" + splitBy + "_" + type;
506 rowMap[rowKey] = {};
507 rowOrder.push(rowKey);
508 headerString += Utils.sanitizeString(splitByString + "." + type, valueTypes.String) + ",";
509 });
510 });
511 });
512 csvString = endLine(headerString);
513 this.allValues.forEach(function (value) {
514 if (value.measures && Object.keys(value.measures).length != 0) {
515 Object.keys(value.measures).forEach(function (type) {
516 var rowKey = value.aggregateKey + "_" + value.splitBy + "_" + type;
517 if (rowKey in rowMap) {
518 rowMap[rowKey][value.dateTime.valueOf()] =
519 (value.measures[type] == null || value.measures[type] == undefined) ?
520 "" : Utils.sanitizeString(value.measures[type], _this.guessValueType(value.measures[type]));
521 }
522 });
523 }
524 });
525 this.allTimestampsArray.forEach(function (timeString) {
526 var millis = (new Date(timeString)).valueOf();
527 csvString += Utils.timeFormat(_this.usesSeconds, _this.usesMillis, offset, null, null, null, dateLocale)(new Date(millis)) + ",";
528 csvString += Utils.timeFormat(_this.usesSeconds, _this.usesMillis, 0, null, null, null, dateLocale)(new Date(millis)) + ",";
529 rowOrder.forEach(function (rowKey) {
530 csvString += (rowMap[rowKey][millis] != undefined ? rowMap[rowKey][millis] : "") + ",";
531 });
532 csvString = endLine(csvString);
533 });
534 return csvString;
535 };
536 ChartComponentData.prototype.getVisibilityState = function () {
537 var _this = this;
538 var visibilityStateArray = [];
539 Object.keys(this.displayState).forEach(function (aggKey) {
540 var aggDisplayState = _this.displayState[aggKey];
541 var visibleSplitBys = !aggDisplayState.visible ? [] :
542 Object.keys(aggDisplayState.splitBys).filter(function (splitByName) {
543 return aggDisplayState.splitBys[splitByName].visible;
544 });
545 var aggName = aggDisplayState.name;
546 var visibilityObject = {};
547 visibilityObject[aggName] = [aggDisplayState.visible, visibleSplitBys];
548 visibilityStateArray.push(visibilityObject);
549 });
550 return visibilityStateArray;
551 };
552 return ChartComponentData;
553}());
554
555var Grid = /** @class */ (function (_super) {
556 __extends(Grid, _super);
557 function Grid(renderTarget) {
558 var _this = _super.call(this, renderTarget) || this;
559 _this.rowLabelKey = "__tsiLabel__";
560 _this.colorKey = "__tsiColor__";
561 _this.aggIndexKey = '__tsiAggIndex__';
562 _this.chartComponentData = new ChartComponentData();
563 _this.closeButton = null;
564 _this.usesSeconds = false;
565 _this.usesMillis = false;
566 _this.cellClass = function (ridx, cidx) {
567 return "tsi-table-" + ridx + '-' + cidx;
568 };
569 _this.focus = function (rowIdx, colIdx) {
570 try {
571 _this.gridComponent.select('.' + _this.cellClass(rowIdx, colIdx)).node()
572 .focus();
573 }
574 catch (e) {
575 console.log(e);
576 }
577 };
578 _this.getFormattedDate = function (h) {
579 var hAsDate = (new Date(h));
580 if (hAsDate != _this.getString('Invalid Date'))
581 return Utils.timeFormat(_this.usesSeconds, _this.usesMillis, _this.chartOptions.offset, null, null, null, _this.chartOptions.dateLocale)(hAsDate);
582 return h;
583 };
584 _this.setFilteredTimestamps = function () {
585 if (_this.chartComponentData.fromMillis === Infinity) {
586 _this.filteredTimestamps = _this.chartComponentData.allTimestampsArray;
587 }
588 else {
589 _this.filteredTimestamps = _this.chartComponentData.allTimestampsArray.filter(function (ts) {
590 var currMillis = (new Date(ts)).valueOf();
591 return (currMillis >= _this.chartComponentData.fromMillis && currMillis < _this.chartComponentData.toMillis);
592 });
593 }
594 };
595 _this.arrowNavigate = function (d3event, rowIdx, colIdx) {
596 if (d3event.keyCode === 9) {
597 if (_this.closeButton) {
598 (_this.closeButton.node()).focus();
599 d3event.preventDefault();
600 }
601 return;
602 }
603 var codes = [37, 38, 39, 40];
604 var codeIndex = codes.indexOf(d3event.keyCode);
605 if (codeIndex == -1)
606 return;
607 switch (codeIndex) {
608 case 0:
609 // left
610 _this.focus(rowIdx, colIdx - 1);
611 d3event.preventDefault();
612 break;
613 case 1:
614 // up
615 _this.focus(rowIdx - 1, colIdx);
616 d3event.preventDefault();
617 break;
618 case 2:
619 // right
620 _this.focus(rowIdx, colIdx + 1);
621 d3event.preventDefault();
622 break;
623 case 3:
624 // down
625 _this.focus(rowIdx + 1, colIdx);
626 d3event.preventDefault();
627 break;
628 }
629 };
630 return _this;
631 }
632 Grid.hideGrid = function (renderTarget) {
633 select(renderTarget).selectAll("." + GRIDCONTAINERCLASS).remove();
634 };
635 Grid.showGrid = function (renderTarget, chartOptions, aggregateExpressionOptions, chartComponentData) {
636 chartOptions.fromChart = true;
637 select(renderTarget).selectAll("." + GRIDCONTAINERCLASS).remove();
638 var gridContainer = select(renderTarget).append('div')
639 .attr('class', GRIDCONTAINERCLASS)
640 .style('width', '100%')
641 .style('height', '100%');
642 var gridComponent = new Grid(gridContainer.node());
643 gridComponent.usesSeconds = chartComponentData.usesSeconds;
644 gridComponent.usesMillis = chartComponentData.usesMillis;
645 var grid = gridComponent.renderFromAggregates(chartComponentData.data, chartOptions, aggregateExpressionOptions, chartComponentData);
646 gridComponent.focus(0, 0);
647 };
648 Grid.createGridEllipsisOption = function (renderTarget, chartOptions, aggregateExpressionOptions, chartComponentData, labelText) {
649 var _this = this;
650 if (labelText === void 0) { labelText = 'Display Grid'; }
651 return {
652 iconClass: "grid",
653 label: labelText,
654 action: function () {
655 _this.showGrid(renderTarget, chartOptions, aggregateExpressionOptions, chartComponentData);
656 },
657 description: ""
658 };
659 };
660 Grid.prototype.Grid = function () {
661 };
662 Grid.prototype.renderFromAggregates = function (data, options, aggregateExpressionOptions, chartComponentData) {
663 var _this = this;
664 this.chartOptions.setOptions(options);
665 var dataAsJson = data.reduce(function (p, c, i) {
666 var aeName = Object.keys(c)[0];
667 Object.keys(c[aeName]).forEach(function (sbName) {
668 var row = {};
669 Object.keys(c[aeName][sbName]).forEach(function (dt) {
670 row[dt] = c[aeName][sbName][dt];
671 });
672 row[_this.rowLabelKey] = (Object.keys(c[aeName]).length == 1 && sbName == "" ? aeName : sbName);
673 if (aggregateExpressionOptions && aggregateExpressionOptions[i].color)
674 row[_this.colorKey] = aggregateExpressionOptions[i].color;
675 row[_this.aggIndexKey] = i;
676 p.push(row);
677 });
678 return p;
679 }, []);
680 return this.render(dataAsJson, options, aggregateExpressionOptions, chartComponentData);
681 };
682 Grid.prototype.getRowData = function () {
683 var _this = this;
684 var rowData = [];
685 Object.keys(this.chartComponentData.timeArrays).forEach(function (aggKey) {
686 Object.keys(_this.chartComponentData.timeArrays[aggKey]).forEach(function (sb, sbI) {
687 if (_this.chartComponentData.getSplitByVisible(aggKey, sb)) {
688 rowData.push([aggKey, sb]);
689 }
690 });
691 });
692 return rowData;
693 };
694 Grid.prototype.convertSeriesToGridData = function (allTimeStampMap, currSeries) {
695 Object.keys(allTimeStampMap).forEach(function (k) { return allTimeStampMap[k] = {}; });
696 currSeries = currSeries.filter(function (d) {
697 return d.measures !== null;
698 });
699 currSeries.map(function (dataPoint) {
700 allTimeStampMap[dataPoint.dateTime.toISOString()] = dataPoint;
701 });
702 return Object.keys(allTimeStampMap).map(function (ts) {
703 return allTimeStampMap[ts];
704 });
705 };
706 Grid.prototype.addHeaderCells = function () {
707 var _this = this;
708 var headerCellData = this.filteredTimestamps; // this.chartComponentData.allTimestampsArray;
709 var headerCells = this.tableHeaderRow.selectAll('.tsi-headerCell').data(headerCellData);
710 var headerCellsEntered = headerCells.enter()
711 .append('th')
712 .merge(headerCells)
713 .attr("class", function (d, i) { return _this.cellClass(0, i + 1) + ' tsi-headerCell'; })
714 .on("keydown", function (event, d) {
715 var e = headerCellsEntered.nodes();
716 var i = e.indexOf(event.currentTarget);
717 _this.arrowNavigate(event, 0, i + 1);
718 })
719 .text(this.getFormattedDate)
720 .attr('aria-label', function (h) {
721 return _this.getString('column header for date') + " " + _this.getFormattedDate(h);
722 });
723 headerCellsEntered.exit().remove();
724 };
725 Grid.prototype.addValueCells = function () {
726 var rowData = this.getRowData();
727 var rows = this.table.selectAll('.tsi-gridContentRow').data(rowData);
728 var self = this;
729 var allTimeStampMap = this.filteredTimestamps.reduce(function (tsMap, ts) {
730 tsMap[ts] = {};
731 return tsMap;
732 }, {});
733 var headerCellData = this.filteredTimestamps;
734 var rowsEntered = rows.enter()
735 .append('tr')
736 .classed('tsi-gridContentRow', true)
737 .each(function (d, i) {
738 var aggKey = d[0];
739 var splitBy = d[1];
740 var seriesData = self.convertSeriesToGridData(allTimeStampMap, self.chartComponentData.timeArrays[aggKey][splitBy]);
741 var cells = select(this).selectAll('.tsi-valueCell').data(seriesData);
742 var measuresData = self.chartOptions.spMeasures ? self.chartOptions.spMeasures : self.chartComponentData.displayState[aggKey].splitBys[splitBy].types;
743 //Row header with the name of the series
744 var headerCell = select(this).selectAll('tsi-rowHeaderCell').data([d]);
745 var getRowHeaderText = function (d) {
746 return "" + self.chartComponentData.displayState[aggKey].name + (splitBy !== '' ? (': ' + splitBy) : '');
747 };
748 headerCell.enter()
749 .append('td')
750 .merge(headerCell)
751 .attr('class', function (d, col) { return "tsi-rowHeaderCell " + self.cellClass(i + 1, 0); })
752 .on("keydown", function (event, d) {
753 self.arrowNavigate(event, i + 1, 0);
754 })
755 .attr('aria-label', function (d) {
756 return self.getString('row header for') + " " + Utils.stripNullGuid(getRowHeaderText());
757 })
758 .each(function (d) {
759 select(this).select('*').remove();
760 var container = select(this).append('div').attr('class', 'tsi-rowHeaderContainer');
761 var seriesName = container.append('div')
762 .attr('class', 'tsi-rowHeaderSeriesName');
763 Utils.appendFormattedElementsFromString(seriesName, getRowHeaderText());
764 var measureContainer = container.append('div')
765 .attr('class', 'tsi-rowHeaderMeasures');
766 var measureNames = measureContainer.selectAll('.tsi-measureName').data(measuresData);
767 measureNames.enter()
768 .append('div')
769 .attr('class', 'tsi-measureName')
770 .text(function (d) { return d; });
771 });
772 headerCell.exit().remove();
773 var cellsEntered = cells.enter()
774 .append('td')
775 .merge(cells)
776 .attr('class', function (d, col) { return "tsi-valueCell " + self.cellClass(i + 1, col + 1); })
777 .on("keydown", function (event, d) {
778 var e = cellsEntered.nodes();
779 var col = e.indexOf(event.currentTarget);
780 self.arrowNavigate(event, i + 1, col + 1);
781 })
782 .attr('aria-label', function (d, i) {
783 if (!d.measures || Object.keys(d.measures).length === 0) {
784 return self.getString('no values at') + " " + getRowHeaderText() + " and " + self.getFormattedDate(new Date(headerCellData[i]));
785 }
786 var formattedValues = Object.keys(d.measures).map(function (measureName) {
787 return measureName + ": " + d.measures[measureName];
788 }).join(', ');
789 return self.getString('values for cell at') + " " + getRowHeaderText() + " " + self.getString('and') + " " + self.getFormattedDate(d.dateTime) + " " + self.getString('are') + " " + formattedValues;
790 })
791 .each(function (d, i) {
792 var measures = select(this).selectAll('.tsi-measureValue').data(measuresData);
793 measures.enter()
794 .append('div')
795 .attr('class', 'tsi-measureValue')
796 .text(function (measure) { return d.measures ? d.measures[measure] : ''; });
797 measures.exit().remove();
798 });
799 cellsEntered.exit().remove();
800 });
801 rowsEntered.exit().remove();
802 };
803 Grid.prototype.render = function (data, options, aggregateExpressionOptions, chartComponentData) {
804 var _this = this;
805 if (chartComponentData === void 0) { chartComponentData = null; }
806 data = Utils.standardizeTSStrings(data);
807 this.chartOptions.setOptions(options);
808 this.gridComponent = select(this.renderTarget);
809 if (chartComponentData) {
810 this.chartComponentData = chartComponentData;
811 }
812 else {
813 this.chartComponentData.mergeDataToDisplayStateAndTimeArrays(data, aggregateExpressionOptions);
814 }
815 this.setFilteredTimestamps();
816 _super.prototype.themify.call(this, this.gridComponent, this.chartOptions.theme);
817 this.gridComponent
818 .classed("tsi-gridComponent", true)
819 .classed("tsi-fromChart", !!options.fromChart);
820 var grid = this.gridComponent
821 .append('div')
822 .attr("class", "tsi-gridWrapper")
823 .on("click", function () {
824 if (_this) {
825 _this.focus(0, 0);
826 }
827 });
828 var headers = Object.keys(data.reduce(function (p, c) {
829 Object.keys(c).forEach(function (k) {
830 if (k != _this.rowLabelKey && k != _this.colorKey)
831 p[k] = true;
832 });
833 return p;
834 }, {})).sort();
835 if (!this.table) {
836 this.table = grid.append('table').classed('tsi-gridTable', true);
837 this.tableHeaderRow = this.table.append('tr').classed('tsi-gridHeaderRow', true);
838 this.tableHeaderRow.append('th')
839 .attr("class", "tsi-topLeft " + this.cellClass(0, 0))
840 .on("keydown", function (event) {
841 _this.arrowNavigate(event, 0, 0);
842 });
843 }
844 this.addHeaderCells();
845 this.addValueCells();
846 if (this.chartOptions.fromChart) {
847 this.gridComponent.selectAll('.tsi-closeButton').remove();
848 this.closeButton = grid.append('button')
849 .attr("class", "tsi-closeButton")
850 .attr('aria-label', this.getString('close grid'))
851 .html('&times')
852 .on('keydown', function (event) {
853 if (event.keyCode === 9) {
854 _this.focus(0, 0);
855 event.preventDefault();
856 }
857 })
858 .on("click", function () {
859 if (!!options.fromChart) {
860 Utils.focusOnEllipsisButton(_this.renderTarget.parentNode);
861 _this.gridComponent.remove();
862 }
863 });
864 }
865 };
866 return Grid;
867}(Component));
868
869export { ChartComponentData as C, Grid as G };