tsichart-core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/LICENSE +22 -0
  2. package/README.MD +189 -0
  3. package/dist/AggregateExpression.d.ts +13 -0
  4. package/dist/AggregateExpression.js +70 -0
  5. package/dist/AvailabilityChart-i_efwXCX.js +488 -0
  6. package/dist/AvailabilityChart.d.ts +59 -0
  7. package/dist/AvailabilityChart.js +26 -0
  8. package/dist/ChartComponent-DTcc6aED.d.ts +80 -0
  9. package/dist/ChartComponent-DnKLTxWe.js +302 -0
  10. package/dist/ChartComponentData-D5wuQmmZ.d.ts +47 -0
  11. package/dist/ChartDataOptions-DBS28b1-.d.ts +38 -0
  12. package/dist/ChartDataOptions-DRd8NHra.js +49 -0
  13. package/dist/ChartVisualizationComponent-CG7e5xlc.js +23 -0
  14. package/dist/ChartVisualizationComponent-DBjiqR1n.d.ts +8 -0
  15. package/dist/ColorPicker-CH__K8xm.js +120 -0
  16. package/dist/ColorPicker.d.ts +28 -0
  17. package/dist/ColorPicker.js +6 -0
  18. package/dist/Component-CofgyEw0.js +401 -0
  19. package/dist/Component-Rp30sSAW.d.ts +226 -0
  20. package/dist/ContextMenu-DABSkTA2.js +197 -0
  21. package/dist/DateTimeButton-CMcCxc8x.d.ts +16 -0
  22. package/dist/DateTimeButton-Ca1487GR.js +38 -0
  23. package/dist/DateTimeButtonRange-DpgfhHQt.js +71 -0
  24. package/dist/DateTimeButtonRange.d.ts +19 -0
  25. package/dist/DateTimeButtonRange.js +15 -0
  26. package/dist/DateTimeButtonSingle-C6cTx5VO.js +48 -0
  27. package/dist/DateTimeButtonSingle.d.ts +17 -0
  28. package/dist/DateTimeButtonSingle.js +14 -0
  29. package/dist/DateTimePicker-BH6qiVfQ.js +532 -0
  30. package/dist/DateTimePicker.d.ts +69 -0
  31. package/dist/DateTimePicker.js +13 -0
  32. package/dist/EllipsisMenu-30FNqoIv.js +116 -0
  33. package/dist/EllipsisMenu.d.ts +20 -0
  34. package/dist/EllipsisMenu.js +6 -0
  35. package/dist/Enums-ChUuTtHV.d.ts +12 -0
  36. package/dist/EventsTable-a0XLbsMF.js +553 -0
  37. package/dist/EventsTable.d.ts +34 -0
  38. package/dist/EventsTable.js +10 -0
  39. package/dist/GeoProcessGraphic-AVAzyF7k.js +145 -0
  40. package/dist/GeoProcessGraphic.d.ts +34 -0
  41. package/dist/GeoProcessGraphic.js +7 -0
  42. package/dist/Grid-DfFAkeeV.js +874 -0
  43. package/dist/Grid.d.ts +43 -0
  44. package/dist/Grid.js +6 -0
  45. package/dist/GroupedBarChart-BspwM8r2.js +579 -0
  46. package/dist/GroupedBarChart.d.ts +22 -0
  47. package/dist/GroupedBarChart.js +17 -0
  48. package/dist/GroupedBarChartData-BRCyDxbA.js +121 -0
  49. package/dist/GroupedBarChartData-C0YQydrP.d.ts +20 -0
  50. package/dist/Heatmap-D8ET8Ue8.js +524 -0
  51. package/dist/Heatmap.d.ts +31 -0
  52. package/dist/Heatmap.js +14 -0
  53. package/dist/Hierarchy-QkWLHkxo.js +260 -0
  54. package/dist/Hierarchy.d.ts +39 -0
  55. package/dist/Hierarchy.js +6 -0
  56. package/dist/HierarchyNavigation-CR6YUilh.js +336 -0
  57. package/dist/HierarchyNavigation.d.ts +34 -0
  58. package/dist/HierarchyNavigation.js +6 -0
  59. package/dist/HistoryPlayback-BmA-54lT.d.ts +68 -0
  60. package/dist/HistoryPlayback-SjeQbAPq.js +175 -0
  61. package/dist/Interfaces-BKRQ685G.d.ts +6 -0
  62. package/dist/Legend-DlSXQXHF.js +497 -0
  63. package/dist/LineChart-CExEyjZa.js +3181 -0
  64. package/dist/LineChart.d.ts +163 -0
  65. package/dist/LineChart.js +18 -0
  66. package/dist/ModelAutocomplete-TRD16egq.js +100 -0
  67. package/dist/ModelAutocomplete.d.ts +12 -0
  68. package/dist/ModelAutocomplete.js +7 -0
  69. package/dist/ModelSearch-WEa7Ud20.js +189 -0
  70. package/dist/ModelSearch.d.ts +23 -0
  71. package/dist/ModelSearch.js +9 -0
  72. package/dist/PieChart-B1ZXk13Q.js +258 -0
  73. package/dist/PieChart.d.ts +26 -0
  74. package/dist/PieChart.js +17 -0
  75. package/dist/PlaybackControls-Dwt6dif9.js +195 -0
  76. package/dist/PlaybackControls.d.ts +39 -0
  77. package/dist/PlaybackControls.js +13 -0
  78. package/dist/ProcessGraphic-CixT-zZl.js +154 -0
  79. package/dist/ProcessGraphic.d.ts +31 -0
  80. package/dist/ProcessGraphic.js +7 -0
  81. package/dist/README.MD +189 -0
  82. package/dist/ScatterPlot-DrPoHNDJ.js +924 -0
  83. package/dist/ScatterPlot.d.ts +115 -0
  84. package/dist/ScatterPlot.js +17 -0
  85. package/dist/SingleDateTimePicker-7anflEq8.js +213 -0
  86. package/dist/SingleDateTimePicker.d.ts +45 -0
  87. package/dist/SingleDateTimePicker.js +12 -0
  88. package/dist/Slider-BtSdC4fj.js +186 -0
  89. package/dist/Slider.d.ts +31 -0
  90. package/dist/Slider.js +6 -0
  91. package/dist/TemporalXAxisComponent-CyiM5EH0.d.ts +23 -0
  92. package/dist/TemporalXAxisComponent-DkyVvASs.js +129 -0
  93. package/dist/TimezonePicker-ClfP1lBL.js +58 -0
  94. package/dist/TimezonePicker.d.ts +16 -0
  95. package/dist/TimezonePicker.js +10 -0
  96. package/dist/Tooltip-Fa-0Xekn.js +104 -0
  97. package/dist/TsqExpression.d.ts +36 -0
  98. package/dist/TsqExpression.js +89 -0
  99. package/dist/UXClient-DydSPZwM.js +230 -0
  100. package/dist/UXClient.d.ts +74 -0
  101. package/dist/UXClient.js +47 -0
  102. package/dist/Utils-BsPLzJBC.d.ts +104 -0
  103. package/dist/Utils-C_j8IgZh.js +1138 -0
  104. package/dist/Utils.d.ts +7 -0
  105. package/dist/Utils.js +7 -0
  106. package/dist/_tslib-5_9pMg1F.js +96 -0
  107. package/dist/package.json +106 -0
  108. package/dist/pikaday-DMSzaLH6.js +1252 -0
  109. package/dist/tsiclient.cjs.js +3 -0
  110. package/dist/tsiclient.cjs.js.LICENSE.txt +19 -0
  111. package/dist/tsiclient.cjs.js.map +1 -0
  112. package/dist/tsiclient.css +17323 -0
  113. package/dist/tsiclient.d.ts +46 -0
  114. package/dist/tsiclient.esm.js +3 -0
  115. package/dist/tsiclient.esm.js.LICENSE.txt +19 -0
  116. package/dist/tsiclient.esm.js.map +1 -0
  117. package/dist/tsiclient.js +58 -0
  118. package/dist/tsiclient.min.css +6 -0
  119. package/dist/tsiclient.min.css.map +1 -0
  120. package/dist/tsiclient.umd.js +3 -0
  121. package/dist/tsiclient.umd.js.LICENSE.txt +19 -0
  122. package/dist/tsiclient.umd.js.map +1 -0
  123. package/dist/tsiclient.umd.min.js +3 -0
  124. package/dist/tsiclient.umd.min.js.LICENSE.txt +19 -0
  125. package/dist/tsiclient.umd.min.js.map +1 -0
  126. package/package.json +106 -0
@@ -0,0 +1,3181 @@
1
+ import { _ as __extends, a as __assign } from './_tslib-5_9pMg1F.js';
2
+ import * as d3 from 'd3';
3
+ import * as d3Voronoi from 'd3-voronoi';
4
+ import { U as Utils, D as DataTypes, Y as YAxisStates, L as LINECHARTTOPPADDING, N as NONNUMERICTOPMARGIN, E as EventElementTypes, S as ShiftTypes, K as KeyCodes, M as MARKERVALUENUMERICHEIGHT, b as LINECHARTXOFFSET, c as LINECHARTCHARTMARGINS, s as swimlaneLabelConstants, T as TooltipMeasureFormat, V as VALUEBARHEIGHT, d as SERIESLABELWIDTH } from './Utils-C_j8IgZh.js';
5
+ import { L as Legend } from './Legend-DlSXQXHF.js';
6
+ import { T as TemporalXAxisComponent } from './TemporalXAxisComponent-DkyVvASs.js';
7
+ import { C as ChartComponentData } from './Grid-DfFAkeeV.js';
8
+ import { C as ContextMenu } from './ContextMenu-DABSkTA2.js';
9
+ import { T as Tooltip } from './Tooltip-Fa-0Xekn.js';
10
+ import { interpolatePath } from 'd3-interpolate-path';
11
+ import { C as Component } from './Component-CofgyEw0.js';
12
+
13
+ var LineChartData = /** @class */ (function (_super) {
14
+ __extends(LineChartData, _super);
15
+ function LineChartData() {
16
+ var _this = _super.call(this) || this;
17
+ _this.timeMap = {};
18
+ _this._yExtents = [];
19
+ return _this;
20
+ }
21
+ Object.defineProperty(LineChartData.prototype, "yExtents", {
22
+ get: function () {
23
+ return this._yExtents;
24
+ },
25
+ enumerable: false,
26
+ configurable: true
27
+ });
28
+ LineChartData.prototype.setYExtents = function (idx, value) {
29
+ this._yExtents[idx] = value;
30
+ };
31
+ LineChartData.prototype.resetYExtents = function () {
32
+ this._yExtents = [];
33
+ for (var i = 0; i < this.data.length; i++) {
34
+ this._yExtents.push(null);
35
+ }
36
+ };
37
+ LineChartData.prototype.setTimeMap = function () {
38
+ this.timeMap = this.allValues.reduce(function (timeMap, currVal) {
39
+ var millis = currVal.dateTime.valueOf();
40
+ if (currVal.bucketSize != undefined) {
41
+ millis += (currVal.bucketSize / 2);
42
+ }
43
+ if (currVal.measures != null) {
44
+ if (timeMap[millis] == undefined) {
45
+ timeMap[millis] = [currVal];
46
+ }
47
+ else {
48
+ timeMap[millis].push(currVal);
49
+ }
50
+ }
51
+ return timeMap;
52
+ }, {});
53
+ };
54
+ LineChartData.prototype.mergeDataToDisplayStateAndTimeArrays = function (data, aggregateExpressionOptions) {
55
+ if (aggregateExpressionOptions === void 0) { aggregateExpressionOptions = null; }
56
+ _super.prototype.mergeDataToDisplayStateAndTimeArrays.call(this, data, aggregateExpressionOptions);
57
+ };
58
+ return LineChartData;
59
+ }(ChartComponentData));
60
+
61
+ var Plot = /** @class */ (function (_super) {
62
+ __extends(Plot, _super);
63
+ function Plot(renderTarget) {
64
+ var _this = _super.call(this, renderTarget) || this;
65
+ _this.backdropRect = null;
66
+ return _this;
67
+ }
68
+ Plot.prototype.getVisibleSeries = function (aggKey) {
69
+ var _this = this;
70
+ return Object.keys(this.chartComponentData.timeArrays[aggKey]).filter(function (s) {
71
+ return _this.chartComponentData.isSplitByVisible(aggKey, s);
72
+ });
73
+ };
74
+ Plot.prototype.createGradientKey = function (d, splitByIndex, i) {
75
+ return d.aggregateKey.replace(/^[^a-z]+|[^\w:.-]+/gi, "") + '_' + splitByIndex + '_' + i;
76
+ };
77
+ Plot.prototype.addGradientStops = function (d, gradient) {
78
+ var _this = this;
79
+ gradient.selectAll('stop').remove();
80
+ this.chartDataOptions.valueMap;
81
+ if (!d.measures) {
82
+ return;
83
+ }
84
+ //behavior if numeric measures
85
+ var allMeasuresNumeric = Object.keys(d.measures).reduce(function (p, currMeasure) {
86
+ return (typeof d.measures[currMeasure]) === 'number' && p;
87
+ }, true);
88
+ var sumOfMeasures;
89
+ if (allMeasuresNumeric) {
90
+ sumOfMeasures = Object.keys(d.measures).reduce(function (p, currMeasure) {
91
+ return p + d.measures[currMeasure];
92
+ }, 0);
93
+ if (sumOfMeasures <= 0) {
94
+ return;
95
+ }
96
+ }
97
+ var numMeasures = Object.keys(d.measures).length;
98
+ Object.keys(d.measures).reduce(function (p, currMeasure, i) {
99
+ var currFraction = allMeasuresNumeric ? (d.measures[currMeasure] / sumOfMeasures) : (i / numMeasures);
100
+ gradient.append('stop')
101
+ .attr("offset", (p * 100) + "%")
102
+ .attr("stop-color", _this.getColorForValue(currMeasure))
103
+ .attr("stop-opacity", 1);
104
+ var newFraction = allMeasuresNumeric ? (p + currFraction) : ((i + 1) / numMeasures);
105
+ gradient.append('stop')
106
+ .attr("offset", (newFraction * 100) + "%")
107
+ .attr("stop-color", _this.getColorForValue(currMeasure))
108
+ .attr("stop-opacity", 1);
109
+ return newFraction;
110
+ }, 0);
111
+ };
112
+ Plot.prototype.createBackdropRect = function (isVisible) {
113
+ this.backdropRect = this.aggregateGroup.selectAll('.tsi-backdropRect')
114
+ .data([isVisible]);
115
+ this.backdropRect.enter().append('rect')
116
+ .attr('class', 'tsi-backdropRect')
117
+ .attr('x', 0)
118
+ .attr('y', 0)
119
+ .merge(this.backdropRect)
120
+ .attr('visibility', function (d) { return d ? 'visible' : 'hidden'; })
121
+ .attr('width', this.x.range()[1])
122
+ .attr('height', this.height);
123
+ this.backdropRect.exit().remove();
124
+ };
125
+ Plot.prototype.getColorForValue = function (value) {
126
+ return Utils.getColorForValue(this.chartDataOptions, value);
127
+ };
128
+ Plot.prototype.getVisibleMeasures = function (measures) {
129
+ return Object.keys(measures).filter(function (measure) {
130
+ return measures[measure] !== 0;
131
+ });
132
+ };
133
+ Plot.prototype.hasData = function (d) {
134
+ return d.measures && (Object.keys(d.measures).length !== 0);
135
+ };
136
+ return Plot;
137
+ }(Component));
138
+
139
+ var LinePlot = /** @class */ (function (_super) {
140
+ __extends(LinePlot, _super);
141
+ function LinePlot(svgSelection) {
142
+ var _this = _super.call(this, svgSelection) || this;
143
+ _this.plotDataType = DataTypes.Numeric;
144
+ return _this;
145
+ }
146
+ LinePlot.prototype.getXPosition = function (d, x) {
147
+ var bucketSize = this.chartComponentData.displayState[d.aggregateKey].bucketSize;
148
+ if (bucketSize) {
149
+ return (x(d.dateTime) + x((new Date(d.dateTime.valueOf() + bucketSize)))) / 2;
150
+ }
151
+ return x(d.dateTime);
152
+ };
153
+ LinePlot.prototype.createAreaPath = function (y) {
154
+ var _this = this;
155
+ this.areaPath = d3.area()
156
+ .curve(this.chartOptions.interpolationFunction)
157
+ .defined(function (d) {
158
+ return (d.measures !== null) &&
159
+ (d.measures[_this.chartComponentData.getVisibleMeasure(d.aggregateKey, d.splitBy)] !== null);
160
+ })
161
+ .x(function (d) {
162
+ return _this.getXPosition(d, _this.x);
163
+ })
164
+ .y0(function (d) {
165
+ return d.measures ? y(d.measures[_this.chartComponentData.getVisibleMeasure(d.aggregateKey, d.splitBy)]) : 0;
166
+ })
167
+ .y1(this.chartHeight);
168
+ };
169
+ // returns the next visibleAggI
170
+ LinePlot.prototype.render = function (chartOptions, visibleAggI, agg, aggVisible, aggregateGroup, chartComponentData, yAxisState, chartHeight, visibleAggCount, colorMap, previousAggregateData, x, areaPath, strokeOpacity, y, yMap, defs, chartDataOptions, previousIncludeDots, yTopAndHeight, svgSelection, categoricalMouseover, categoricalMouseout, yAxisOnClick) {
171
+ var _this = this;
172
+ this.previousIncludeDots = previousIncludeDots;
173
+ this.defs = defs;
174
+ this.chartOptions = chartOptions;
175
+ this.chartHeight = chartHeight;
176
+ this.visibleAggCount = visibleAggCount;
177
+ this.chartComponentData = chartComponentData;
178
+ this.x = x;
179
+ this.y = y;
180
+ var aggKey = agg.aggKey;
181
+ this.aggregateGroup = aggregateGroup;
182
+ var yAxisHasOnClick = yAxisOnClick && typeof yAxisOnClick === "function";
183
+ visibleAggI = yAxisState.positionInGroup;
184
+ this.yTop = yTopAndHeight[0];
185
+ this.height = yTopAndHeight[1];
186
+ var aggY;
187
+ var aggLine;
188
+ var aggEnvelope;
189
+ this.yAxisState = yAxisState;
190
+ var yExtent = this.yAxisState.yExtent;
191
+ aggY = d3.scaleLinear();
192
+ aggY.range([this.height, this.chartOptions.aggTopMargin]);
193
+ if (this.chartComponentData.aggHasVisibleSplitBys(aggKey)) {
194
+ var yRange = (yExtent[1] - yExtent[0]) > 0 ? yExtent[1] - yExtent[0] : 1;
195
+ var yOffsetPercentage = 10 / (this.chartHeight / ((this.yAxisState.axisType === YAxisStates.Overlap) ? 1 : this.visibleAggCount));
196
+ var yDomainMin = this.chartOptions.isArea ?
197
+ (Math.max(yExtent[0] - (yRange * yOffsetPercentage), 0)) :
198
+ (yExtent[0] - (yRange * yOffsetPercentage));
199
+ aggY.domain([yDomainMin, yExtent[1] + (yRange * (10 / this.chartHeight))]);
200
+ }
201
+ else {
202
+ aggY.domain([0, 1]);
203
+ yExtent = [0, 1];
204
+ }
205
+ aggLine = d3.line()
206
+ .curve(this.chartComponentData.displayState[aggKey].interpolationFunction ? d3[this.chartComponentData.displayState[aggKey].interpolationFunction] : this.chartOptions.interpolationFunction)
207
+ .defined(function (d) {
208
+ return (d.measures !== null) &&
209
+ (d.measures[_this.chartComponentData.getVisibleMeasure(d.aggregateKey, d.splitBy)] !== null);
210
+ })
211
+ .x(function (d) { return _this.getXPosition(d, _this.x); })
212
+ .y(function (d) {
213
+ return d.measures ? aggY(d.measures[_this.chartComponentData.getVisibleMeasure(d.aggregateKey, d.splitBy)]) : null;
214
+ });
215
+ aggEnvelope = d3.area()
216
+ .curve(this.chartComponentData.displayState[aggKey].interpolationFunction ? d3[this.chartComponentData.displayState[aggKey].interpolationFunction] : this.chartOptions.interpolationFunction)
217
+ .defined(function (d) { return (d.measures !== null) && (d.measures['min'] !== null) && (d.measures['max'] !== null); })
218
+ .x(function (d) { return _this.getXPosition(d, _this.x); })
219
+ .y0(function (d) { return d.measures ? aggY(d.measures['max']) : 0; })
220
+ .y1(function (d) { return d.measures ? aggY(d.measures['min']) : 0; });
221
+ var localY = aggY.copy();
222
+ localY.range([this.yTop + this.height, this.yTop + this.chartOptions.aggTopMargin]);
223
+ yMap[aggKey] = localY;
224
+ var yAxis = this.aggregateGroup.selectAll(".yAxis")
225
+ .data([aggKey]);
226
+ var visibleYAxis = (aggVisible && (this.yAxisState.axisType !== YAxisStates.Shared || visibleAggI === 0));
227
+ yAxis = yAxis.enter()
228
+ .append("g")
229
+ .attr("class", "yAxis ".concat(yAxisHasOnClick ? "tsi-clickableYAxis tsi-swimLaneAxis-".concat(this.chartComponentData.displayState[aggKey].aggregateExpression.swimLane) : ''))
230
+ .merge(yAxis)
231
+ .style("visibility", ((visibleYAxis && !this.chartOptions.yAxisHidden) ? "visible" : "hidden"));
232
+ if (this.yAxisState.axisType === YAxisStates.Overlap) {
233
+ yAxis.call(d3.axisLeft(aggY).tickFormat(Utils.formatYAxisNumber).tickValues(yExtent))
234
+ .selectAll("text")
235
+ .attr("y", function (d, j) { return (j == 0) ? (-visibleAggI * 16) : (visibleAggI * 16); })
236
+ .style("fill", this.chartComponentData.displayState[aggKey].color);
237
+ }
238
+ else {
239
+ yAxis.call(d3.axisLeft(aggY).tickFormat(Utils.formatYAxisNumber)
240
+ .ticks(Math.max(2, Math.ceil(this.height / (this.yAxisState.axisType === YAxisStates.Stacked ? this.visibleAggCount : 1) / 90))))
241
+ .selectAll("text").classed("standardYAxisText", true);
242
+ }
243
+ // If yAxisOnClick present, attach to yAxis
244
+ if (yAxisHasOnClick) {
245
+ yAxis.on("click", function () {
246
+ yAxisOnClick();
247
+ });
248
+ var label_1 = document.getElementsByClassName("tsi-swimLaneLabel-".concat(agg.swimLane))[0];
249
+ if (label_1) {
250
+ yAxis.on("mouseover", function () {
251
+ label_1.classList.add("tsi-axisHover");
252
+ yAxis.selectAll("text").classed("tsi-boldYAxisText", true);
253
+ });
254
+ yAxis.on("mouseout", function () {
255
+ label_1.classList.remove("tsi-axisHover");
256
+ yAxis.selectAll("text").classed("tsi-boldYAxisText", false);
257
+ });
258
+ }
259
+ }
260
+ yAxis.exit().remove();
261
+ ({
262
+ x: this.x});
263
+ var splitByColors = Utils.createSplitByColors(this.chartComponentData.displayState, aggKey, this.chartOptions.keepSplitByColor);
264
+ var includeDots = this.chartOptions.includeDots || this.chartComponentData.displayState[aggKey].includeDots;
265
+ var self = this;
266
+ var splitByGroups = this.aggregateGroup.selectAll(".tsi-splitByGroup")
267
+ .data(Object.keys(this.chartComponentData.timeArrays[aggKey]));
268
+ splitByGroups.enter()
269
+ .append("g")
270
+ .attr("class", "tsi-splitByGroup " + agg.aggKey)
271
+ .merge(splitByGroups)
272
+ .each(function (splitBy, j) {
273
+ var _this = this;
274
+ colorMap[aggKey + "_" + splitBy] = splitByColors[j];
275
+ // creation of segments between each gap in the data
276
+ var segments = [];
277
+ var lineData = self.chartComponentData.timeArrays[aggKey][splitBy];
278
+ var visibleMeasure = self.chartComponentData.getVisibleMeasure(aggKey, splitBy);
279
+ for (var i = 0; i < lineData.length - 1; i++) {
280
+ if (lineData[i].measures !== null && lineData[i].measures[visibleMeasure] !== null) {
281
+ var scannerI = i + 1;
282
+ while (scannerI < lineData.length && ((lineData[scannerI].measures == null) ||
283
+ lineData[scannerI].measures[visibleMeasure] == null)) {
284
+ scannerI++;
285
+ }
286
+ if (scannerI < lineData.length && scannerI != i + 1) {
287
+ segments.push([lineData[i], lineData[scannerI]]);
288
+ }
289
+ i = scannerI - 1;
290
+ }
291
+ }
292
+ var durationFunction = function (d) {
293
+ var previousUndefined = previousAggregateData.get(_this) === undefined;
294
+ return (self.chartOptions.noAnimate || previousUndefined) ? 0 : self.TRANSDURATION;
295
+ };
296
+ var gapPath = d3.select(this).selectAll(".tsi-gapLine")
297
+ .data(segments.map(function (d) {
298
+ d.inTransition = true;
299
+ return d;
300
+ }));
301
+ gapPath.enter()
302
+ .append("path")
303
+ .attr("class", "tsi-valueElement tsi-gapLine")
304
+ .merge(gapPath)
305
+ .style("visibility", function (d) {
306
+ return (self.chartComponentData.isSplitByVisible(aggKey, splitBy)) ? "visible" : "hidden";
307
+ })
308
+ .transition()
309
+ .duration(durationFunction)
310
+ .ease(d3.easeExp)
311
+ .attr("stroke-dasharray", "5,5")
312
+ .attr("stroke", splitByColors[j])
313
+ .attrTween('d', function (d) {
314
+ var previous = d3.select(this).attr('d');
315
+ var current = aggLine(d);
316
+ return interpolatePath(previous, current);
317
+ })
318
+ .on('end', function (d) {
319
+ d.inTransition = false;
320
+ });
321
+ var path = d3.select(this).selectAll(".tsi-valueLine")
322
+ .data([self.chartComponentData.timeArrays[aggKey][splitBy]].map(function (d) {
323
+ d.inTransition = true;
324
+ return d;
325
+ }));
326
+ path.enter()
327
+ .append("path")
328
+ .attr("class", "tsi-valueElement tsi-valueLine")
329
+ .merge(path)
330
+ .style("visibility", function (d) {
331
+ return (self.chartComponentData.isSplitByVisible(aggKey, splitBy)) ? "visible" : "hidden";
332
+ })
333
+ .transition()
334
+ .duration(durationFunction)
335
+ .ease(d3.easeExp)
336
+ .attr("stroke", splitByColors[j])
337
+ .attr("stroke-opacity", self.strokeOpacity)
338
+ .attrTween('d', function (d) {
339
+ var previous = d3.select(this).attr('d');
340
+ var current = aggLine(d);
341
+ return interpolatePath(previous, current);
342
+ })
343
+ .on('end', function (d) {
344
+ d.inTransition = false;
345
+ });
346
+ if (self.chartOptions.includeDots || self.chartComponentData.displayState[aggKey].includeDots) {
347
+ var dots = d3.select(this).selectAll(".tsi-valueDot")
348
+ .data(self.chartComponentData.timeArrays[aggKey][splitBy].filter(function (d) {
349
+ return d && d.measures && d.measures[self.chartComponentData.getVisibleMeasure(d.aggregateKey, d.splitBy)] !== null;
350
+ }), function (d, i) {
351
+ return d.dateTime.toString();
352
+ });
353
+ dots.enter()
354
+ .append('circle')
355
+ .attr('class', 'tsi-valueElement tsi-valueDot')
356
+ .attr('r', 3)
357
+ .merge(dots)
358
+ .style("visibility", function (d) {
359
+ return (self.chartComponentData.isSplitByVisible(aggKey, splitBy) && d.measures) ? "visible" : "hidden";
360
+ })
361
+ .transition()
362
+ .duration(function (d, i) {
363
+ return (self.previousIncludeDots.get(this) === true) ? durationFunction() : 0;
364
+ })
365
+ .ease(d3.easeExp)
366
+ .attr("fill", splitByColors[j])
367
+ .attr('cx', function (d) { return self.getXPosition(d, self.x); })
368
+ .attr('cy', function (d) {
369
+ return d.measures ? aggY(d.measures[self.chartComponentData.getVisibleMeasure(d.aggregateKey, d.splitBy)]) : null;
370
+ })
371
+ .each(function () {
372
+ self.previousIncludeDots.set(this, includeDots);
373
+ });
374
+ dots.exit().remove();
375
+ }
376
+ else {
377
+ d3.select(this).selectAll(".tsi-valueDot").remove();
378
+ }
379
+ var envelopeData = {};
380
+ if ((self.chartComponentData.displayState[aggKey].includeEnvelope || self.chartOptions.includeEnvelope) && self.chartComponentData.isPossibleEnvelope(aggKey, splitBy)) {
381
+ envelopeData = self.chartComponentData.timeArrays[aggKey][splitBy].map(function (d) { return (__assign(__assign({}, d), { isEnvelope: true })); });
382
+ }
383
+ var envelope = d3.select(this).selectAll(".tsi-valueEnvelope")
384
+ .data([envelopeData]);
385
+ envelope.enter()
386
+ .append("path")
387
+ .attr("class", "tsi-valueElement tsi-valueEnvelope")
388
+ .merge(envelope)
389
+ .style("visibility", function (d) {
390
+ return (self.chartComponentData.isSplitByVisible(aggKey, splitBy)) ? "visible" : "hidden";
391
+ })
392
+ .transition()
393
+ .duration(durationFunction)
394
+ .ease(d3.easeExp)
395
+ .style("fill", splitByColors[j])
396
+ .attr("fill-opacity", .2)
397
+ .attr("d", aggEnvelope);
398
+ if (self.chartOptions.isArea) {
399
+ self.createAreaPath(aggY);
400
+ var area = d3.select(this).selectAll(".tsi-valueArea")
401
+ .data([self.chartComponentData.timeArrays[aggKey][splitBy]]);
402
+ // logic for shiny gradient fill via url()
403
+ var svgId = Utils.guid();
404
+ var lg = self.defs.selectAll('linearGradient')
405
+ .data([self.chartComponentData.timeArrays[aggKey][splitBy]]);
406
+ var gradient = lg.enter()
407
+ .append('linearGradient');
408
+ gradient.merge(lg)
409
+ .attr('id', svgId).attr('x1', '0%').attr('x2', '0%').attr('y1', '0%').attr('y2', '100%');
410
+ gradient.append('stop').attr('offset', '0%').attr('style', function () { return 'stop-color:' + splitByColors[j] + ';stop-opacity:.2'; });
411
+ gradient.append('stop').attr('offset', '100%').attr('style', function () { return 'stop-color:' + splitByColors[j] + ';stop-opacity:.03'; });
412
+ lg.exit().remove();
413
+ area.enter()
414
+ .append("path")
415
+ .attr("class", "tsi-valueArea")
416
+ .merge(area)
417
+ .style("fill", 'url(#' + (svgId) + ')')
418
+ .style("visibility", function (d) {
419
+ return (self.chartComponentData.isSplitByVisible(aggKey, splitBy)) ? "visible" : "hidden";
420
+ })
421
+ .transition()
422
+ .duration(durationFunction)
423
+ .ease(d3.easeExp)
424
+ .attr("d", self.areaPath);
425
+ area.exit().remove();
426
+ }
427
+ gapPath.exit().remove();
428
+ path.exit().remove();
429
+ previousAggregateData.set(this, splitBy);
430
+ });
431
+ splitByGroups.exit().remove();
432
+ };
433
+ return LinePlot;
434
+ }(Plot));
435
+
436
+ var TOPMARGIN = 4;
437
+ var CategoricalPlot = /** @class */ (function (_super) {
438
+ __extends(CategoricalPlot, _super);
439
+ function CategoricalPlot(svgSelection) {
440
+ var _this = _super.call(this, svgSelection) || this;
441
+ _this.plotDataType = DataTypes.Categorical;
442
+ return _this;
443
+ }
444
+ CategoricalPlot.prototype.onMouseover = function (d, rectWidth) {
445
+ var _this = this;
446
+ var visibleMeasures = this.getVisibleMeasures(d.measures);
447
+ this.hoverRect.attr('visibility', 'visible')
448
+ .attr('x', function () {
449
+ return _this.x(new Date(d.dateTime));
450
+ })
451
+ .attr('width', rectWidth)
452
+ .attr('height', Math.max(0, this.chartHeight + 1 - LINECHARTTOPPADDING))
453
+ .attr('fill', function () {
454
+ return visibleMeasures.length === 1 ? _this.getColorForValue(visibleMeasures[0]) : 'none';
455
+ });
456
+ };
457
+ CategoricalPlot.prototype.onMouseout = function () {
458
+ this.hoverRect.attr('visibility', 'hidden');
459
+ this.categoricalMouseout();
460
+ };
461
+ CategoricalPlot.prototype.createHoverRect = function () {
462
+ if (!this.hoverRect) {
463
+ this.hoverRect = this.chartGroup.append('rect')
464
+ .attr('class', 'tsi-categoricalHoverRect')
465
+ .attr('y', LINECHARTTOPPADDING)
466
+ .attr('height', this.chartHeight + 1);
467
+ }
468
+ else {
469
+ this.hoverRect.raise();
470
+ }
471
+ };
472
+ CategoricalPlot.prototype.getSeriesEndDate = function () {
473
+ if (this.chartDataOptions.searchSpan) {
474
+ return new Date(this.chartDataOptions.searchSpan.to);
475
+ }
476
+ return new Date(this.chartComponentData.toMillis);
477
+ };
478
+ CategoricalPlot.prototype.getBucketEndDate = function (d, i) {
479
+ var _this = this;
480
+ var data = this.chartComponentData.timeArrays[d.aggregateKey][d.splitBy];
481
+ if (i + 1 < data.length) {
482
+ return data[i + 1].dateTime;
483
+ }
484
+ else {
485
+ var shouldRoundEnd = Utils.safeNotNullOrUndefined(function () { return _this.chartDataOptions.searchSpan; }) && Utils.safeNotNullOrUndefined(function () { return _this.chartDataOptions.searchSpan.bucketSize; });
486
+ return shouldRoundEnd ? Utils.roundToMillis(this.getSeriesEndDate().valueOf(), Utils.parseTimeInput(this.chartDataOptions.searchSpan.bucketSize)) : this.getSeriesEndDate();
487
+ }
488
+ };
489
+ CategoricalPlot.prototype.render = function (chartOptions, visibleAggI, agg, aggVisible, aggregateGroup, chartComponentData, yExtent, chartHeight, visibleAggCount, colorMap, previousAggregateData, x, areaPath, strokeOpacity, y, yMap, defs, chartDataOptions, previousIncludeDots, yTopAndHeight, chartGroup, categoricalMouseover, categoricalMouseout) {
490
+ var _this = this;
491
+ this.chartOptions = chartOptions;
492
+ this.yTop = yTopAndHeight[0];
493
+ this.height = yTopAndHeight[1];
494
+ this.x = x;
495
+ this.chartComponentData = chartComponentData;
496
+ var aggKey = agg.aggKey;
497
+ this.chartDataOptions = chartDataOptions;
498
+ this.chartHeight = chartHeight;
499
+ this.chartGroup = chartGroup;
500
+ this.categoricalMouseover = categoricalMouseover;
501
+ this.aggregateGroup = aggregateGroup;
502
+ this.categoricalMouseout = categoricalMouseout;
503
+ this.createBackdropRect(true);
504
+ if (this.aggregateGroup.selectAll('defs').empty()) {
505
+ this.defs = this.aggregateGroup.append('defs');
506
+ }
507
+ if (this.aggregateGroup.selectAll('.tsi-splitBysGroup').empty()) {
508
+ this.splitBysGroup = this.aggregateGroup.append('g').classed('tsi-splitBysGroup', true);
509
+ }
510
+ var gradientData = [];
511
+ var durationFunction = function (d) {
512
+ var previousUndefined = previousAggregateData.get(_this) === undefined;
513
+ return (self.chartOptions.noAnimate || previousUndefined) ? 0 : self.TRANSDURATION;
514
+ };
515
+ var self = this;
516
+ this.createHoverRect();
517
+ var series = this.getVisibleSeries(aggKey);
518
+ var heightPerSeries = Math.max((self.chartDataOptions.height - (series.length * TOPMARGIN)) / series.length, 0);
519
+ var splitByGroups = this.splitBysGroup.selectAll(".tsi-splitByGroup")
520
+ .data(series, function (d) {
521
+ return d.splitBy;
522
+ });
523
+ splitByGroups.enter()
524
+ .append("g")
525
+ .attr("class", "tsi-splitByGroup " + agg.aggKey)
526
+ .merge(splitByGroups)
527
+ .attr('transform', function (d, i) {
528
+ return 'translate(0,' + (NONNUMERICTOPMARGIN + (i * (_this.chartDataOptions.height / series.length))) + ')';
529
+ })
530
+ .each(function (splitBy, j) {
531
+ var data = self.chartComponentData.timeArrays[aggKey][splitBy];
532
+ var categoricalBuckets = d3.select(this).selectAll(".tsi-categoricalBucket")
533
+ .data(data);
534
+ var getWidth = function (d, i) {
535
+ self.x.range()[1] - self.x.range()[0];
536
+ var xPos1 = Math.max(self.x(new Date(d.dateTime)), 0);
537
+ var xPos2 = self.x(self.getBucketEndDate(d, i));
538
+ return Math.max(xPos2 - xPos1, 1);
539
+ };
540
+ var categoricalBucketsEntered = categoricalBuckets.enter()
541
+ .append("rect")
542
+ .attr("class", "tsi-valueElement tsi-categoricalBucket")
543
+ .merge(categoricalBuckets)
544
+ .style("visibility", function (d) {
545
+ return (self.chartComponentData.isSplitByVisible(aggKey, splitBy) && self.hasData(d)) ? "visible" : "hidden";
546
+ })
547
+ .on('mouseover', function (event, d) {
548
+ var e = categoricalBucketsEntered.nodes();
549
+ var i = e.indexOf(event.currentTarget);
550
+ var y = self.yTop + (j * (self.chartDataOptions.height / series.length));
551
+ var x = self.x(new Date(d.dateTime)) + (getWidth(d, i));
552
+ var shouldMouseover = self.categoricalMouseover(d, x, y + NONNUMERICTOPMARGIN, self.getBucketEndDate(d, i), getWidth(d, i));
553
+ if (shouldMouseover) {
554
+ self.onMouseover(d, getWidth(d, i));
555
+ }
556
+ })
557
+ .on('mouseout', function () {
558
+ self.onMouseout();
559
+ })
560
+ .attr('cursor', (self.chartDataOptions.onElementClick ? 'pointer' : 'inherit'))
561
+ .on('click', function (event, d) {
562
+ if (self.chartDataOptions.onElementClick) {
563
+ self.chartDataOptions.onElementClick(d.aggregateKey, d.splitBy, d.dateTime.toISOString(), d.measures);
564
+ }
565
+ })
566
+ .transition()
567
+ .duration(durationFunction)
568
+ .ease(d3.easeExp)
569
+ .attr('height', heightPerSeries)
570
+ .attr('width', getWidth)
571
+ .attr('x', function (d) {
572
+ return self.x(new Date(d.dateTime));
573
+ })
574
+ .each(function (d, i) {
575
+ var gradientKey = self.createGradientKey(d, j, i);
576
+ gradientData.push([gradientKey, d]);
577
+ d3.select(this)
578
+ .attr('fill', "url(#" + gradientKey + ")");
579
+ });
580
+ categoricalBuckets.exit().remove();
581
+ });
582
+ splitByGroups.exit().remove();
583
+ //corresponding linear gradients
584
+ var gradients = this.defs.selectAll('linearGradient')
585
+ .data(gradientData, function (d) {
586
+ return d[1].splitBy;
587
+ });
588
+ var enteredGradients = gradients.enter()
589
+ .append('linearGradient')
590
+ .attr("x2", "0%")
591
+ .attr("y2", "100%")
592
+ .merge(gradients)
593
+ .attr("id", function (d) { return d[0]; });
594
+ enteredGradients
595
+ .each(function (d) {
596
+ self.addGradientStops(d[1], d3.select(this));
597
+ });
598
+ gradients.exit().remove();
599
+ };
600
+ return CategoricalPlot;
601
+ }(Plot));
602
+
603
+ var EventsPlot = /** @class */ (function (_super) {
604
+ __extends(EventsPlot, _super);
605
+ function EventsPlot(svgSelection) {
606
+ var _this = _super.call(this, svgSelection) || this;
607
+ _this.gradientArray = {};
608
+ _this.eventOnClick = function (d) {
609
+ if (_this.chartDataOptions.onElementClick) {
610
+ _this.chartDataOptions.onElementClick(d.aggregateKey, d.splitBy, d.dateTime.toISOString(), d.measures);
611
+ }
612
+ };
613
+ _this.colorFunction = function (d) {
614
+ if (d.measures) {
615
+ if (Object.keys(d.measures).length === 1) {
616
+ return _this.getColorForValue(Object.keys(d.measures)[0]);
617
+ }
618
+ else {
619
+ return 'grey';
620
+ }
621
+ }
622
+ return 'none';
623
+ };
624
+ _this.createDateStringFunction = function (shiftMillis) {
625
+ return Utils.timeFormat(_this.chartComponentData.usesSeconds, _this.chartComponentData.usesMillis, _this.chartOptions.offset, _this.chartOptions.is24HourTime, shiftMillis, null, _this.chartOptions.dateLocale);
626
+ };
627
+ _this.createEventElements = function (splitBy, g, splitByIndex) {
628
+ var sortEvents = function () {
629
+ enteredEvents.sort(function (a, b) {
630
+ if (a.dateTime < b.dateTime) {
631
+ return -1;
632
+ }
633
+ else if (a.dateTime > b.dateTime) {
634
+ return 1;
635
+ }
636
+ return 0;
637
+ });
638
+ };
639
+ var data = _this.chartComponentData.timeArrays[_this.aggKey][splitBy];
640
+ var discreteEvents = g.selectAll(".tsi-discreteEvent")
641
+ .data(data, function (d) { return d.dateTime; });
642
+ var self = _this;
643
+ var enteredEvents;
644
+ var shiftMillis = _this.chartComponentData.getTemporalShiftMillis(_this.aggKey);
645
+ var dateStringFn = _this.createDateStringFunction(shiftMillis);
646
+ switch (_this.chartDataOptions.eventElementType) {
647
+ case EventElementTypes.Teardrop:
648
+ if (discreteEvents.size() && discreteEvents.classed('tsi-discreteEventDiamond')) {
649
+ g.selectAll('.tsi-discreteEvent').remove();
650
+ discreteEvents = g.selectAll(".tsi-discreteEvent")
651
+ .data(data, function (d) { return d.dateTime; });
652
+ }
653
+ enteredEvents = discreteEvents.enter()
654
+ .append('path')
655
+ .attr('class', 'tsi-discreteEvent tsi-valueElement')
656
+ .merge(discreteEvents)
657
+ .classed('tsi-discreteEventDiamond', false)
658
+ .classed('tsi-discreteEventTeardrop', true)
659
+ .attr('transform', function (d) {
660
+ return 'translate(' + (_this.x(new Date(d.dateTime)) + _this.eventHeight / 2) + ',' + (_this.eventHeight * 1.4) + ') rotate(180)';
661
+ })
662
+ .attr('d', _this.teardropD(_this.eventHeight, _this.eventHeight))
663
+ .attr('stroke-width', Math.min(_this.eventHeight / 2.25, 8))
664
+ .attr('stroke', _this.colorFunction)
665
+ .attr('fill', 'none');
666
+ break;
667
+ case EventElementTypes.Diamond:
668
+ if (discreteEvents.size() && discreteEvents.classed('tsi-discreteEventTeardrop')) {
669
+ g.selectAll('.tsi-discreteEvent').remove();
670
+ discreteEvents = g.selectAll(".tsi-discreteEvent")
671
+ .data(data, function (d) { return d.dateTime; });
672
+ }
673
+ enteredEvents = discreteEvents.enter()
674
+ .append('rect')
675
+ .attr('class', 'tsi-discreteEvent tsi-valueElement')
676
+ .merge(discreteEvents)
677
+ .classed('tsi-discreteEventTeardrop', false)
678
+ .classed('tsi-discreteEventDiamond', true)
679
+ .attr('d', 'none')
680
+ .attr('transform', function (d) {
681
+ return 'translate(' + _this.x(new Date(d.dateTime)) + ',0) rotate(45)';
682
+ })
683
+ .attr('fill', _this.colorFunction)
684
+ .attr('stroke', 'none');
685
+ break;
686
+ }
687
+ enteredEvents
688
+ .attr('y', 0)
689
+ .attr('x', 0)
690
+ .attr('width', _this.eventHeight)
691
+ .attr('height', _this.eventHeight)
692
+ .on('mouseover', function (event, d) {
693
+ d3.select(this).raise();
694
+ self.onMouseover(d, splitByIndex);
695
+ })
696
+ .on('mouseout', function () {
697
+ _this.onMouseout();
698
+ })
699
+ .on('click', function (event, d) {
700
+ _this.eventOnClick(d);
701
+ })
702
+ .on('touchstart', function (event, d) {
703
+ _this.eventOnClick(d);
704
+ })
705
+ .on('keydown', function (event, d) {
706
+ if (event.keyCode === 9) {
707
+ sortEvents();
708
+ d3.select(this).node().focus();
709
+ }
710
+ if (event.keyCode === 32 || event.keyCode === 13) {
711
+ self.eventOnClick(d);
712
+ }
713
+ })
714
+ .attr('role', _this.chartDataOptions.onElementClick ? 'button' : null)
715
+ .attr('tabindex', _this.chartDataOptions.onElementClick ? '0' : null)
716
+ .attr('cursor', _this.chartDataOptions.onElementClick ? 'pointer' : 'inherit')
717
+ .attr('aria-label', function (d) {
718
+ if (_this.chartDataOptions.onElementClick) {
719
+ var dateString = dateStringFn(d);
720
+ var retString_1 = "".concat(_this.getString('event in series'), " ").concat(d.aggregateName, " ").concat(_this.getString('at time'), " ").concat(dateString, ".");
721
+ Object.keys(d.measures).forEach(function (mKey) {
722
+ retString_1 += " ".concat(_this.getString('measure with key'), " ").concat(mKey, " ").concat(_this.getString('and value'), " ").concat(d.measures[mKey], ".");
723
+ });
724
+ return retString_1;
725
+ }
726
+ return null;
727
+ })
728
+ .style('visibility', function (d) {
729
+ return (self.chartComponentData.isSplitByVisible(_this.aggKey, splitBy) && self.hasData(d)) ? 'visible' : 'hidden';
730
+ })
731
+ .each(function (d, i) {
732
+ if (Object.keys(d.measures).length > 1) {
733
+ var gradientKey = self.createGradientKey(d, splitByIndex, i);
734
+ self.gradientData.push([gradientKey, d]);
735
+ d3.select(this)
736
+ .attr(self.chartDataOptions.eventElementType === EventElementTypes.Teardrop ? 'stroke' : 'fill', "url(#" + gradientKey + ")");
737
+ }
738
+ });
739
+ discreteEvents.exit().remove();
740
+ };
741
+ _this.shouldDrawBackdrop = function () {
742
+ //check to see if this is the first aggregate within a collapsed swimlane.
743
+ var lane = _this.chartComponentData.getSwimlane(_this.aggKey);
744
+ if (!_this.chartOptions.swimLaneOptions || !_this.chartOptions.swimLaneOptions[lane] ||
745
+ !_this.chartOptions.swimLaneOptions[lane].collapseEvents) {
746
+ return true;
747
+ }
748
+ var eventSeriesInLane = Object.keys(_this.chartComponentData.displayState).filter(function (aggKey) {
749
+ return _this.chartComponentData.getSwimlane(aggKey) === lane;
750
+ });
751
+ return eventSeriesInLane.indexOf(_this.aggKey) === 0;
752
+ };
753
+ _this.plotDataType = DataTypes.Events;
754
+ return _this;
755
+ }
756
+ EventsPlot.prototype.onMouseover = function (d, seriesNumber) {
757
+ var _this = this;
758
+ var getX = function () {
759
+ return _this.x(new Date(d.dateTime));
760
+ };
761
+ var seriesWidth = Math.ceil(this.eventHeight * Math.sqrt(2));
762
+ var seriesTop = this.yTop + NONNUMERICTOPMARGIN + (seriesWidth * seriesNumber) + (seriesWidth / 2);
763
+ var shouldMouseover = this.discreteEventsMouseover(d, getX() + (seriesWidth / 2), seriesTop, seriesWidth);
764
+ if (!shouldMouseover) {
765
+ return;
766
+ }
767
+ var visibleMeasures = this.getVisibleMeasures(d.measures);
768
+ this.hoverLine.attr('visibility', 'visible')
769
+ .attr('x1', getX)
770
+ .attr('x2', getX)
771
+ .attr('y1', LINECHARTTOPPADDING)
772
+ .attr('y2', this.chartHeight + 1)
773
+ .attr('stroke', function () {
774
+ return visibleMeasures.length === 1 ? _this.getColorForValue(visibleMeasures[0]) : 'grey';
775
+ });
776
+ };
777
+ EventsPlot.prototype.onMouseout = function () {
778
+ this.hoverLine.attr('visibility', 'hidden');
779
+ this.discreteEventsMouseout();
780
+ };
781
+ EventsPlot.prototype.createHoverLine = function () {
782
+ if (!this.hoverLine) {
783
+ this.hoverLine = this.chartGroup.append('line')
784
+ .attr('class', 'tsi-discreteEventHoverLine')
785
+ .attr('y1', LINECHARTTOPPADDING)
786
+ .attr('y2', this.chartHeight + 1)
787
+ .attr('pointer-events', 'none')
788
+ .attr('visibility', 'hidden');
789
+ }
790
+ else {
791
+ this.hoverLine.raise();
792
+ }
793
+ };
794
+ EventsPlot.prototype.setEventHeight = function (visibleSeriesCount) {
795
+ var useableHeight = this.height - NONNUMERICTOPMARGIN;
796
+ this.eventHeight = Math.floor((useableHeight / visibleSeriesCount) / Math.sqrt(2));
797
+ };
798
+ EventsPlot.prototype.render = function (chartOptions, visibleAggI, agg, aggVisible, aggregateGroup, chartComponentData, yExtent, chartHeight, visibleAggCount, colorMap, previousAggregateData, x, areaPath, strokeOpacity, y, yMap, defs, chartDataOptions, previousIncludeDots, yTopAndHeight, chartGroup, discreteEventsMouseover, discreteEventsMouseout) {
799
+ var _this = this;
800
+ this.chartOptions = chartOptions;
801
+ this.yTop = yTopAndHeight[0];
802
+ this.height = yTopAndHeight[1];
803
+ this.x = x;
804
+ this.chartComponentData = chartComponentData;
805
+ this.aggKey = agg.aggKey;
806
+ this.chartDataOptions = chartDataOptions;
807
+ this.chartHeight = chartHeight;
808
+ this.chartGroup = chartGroup;
809
+ this.aggregateGroup = aggregateGroup;
810
+ this.discreteEventsMouseover = discreteEventsMouseover;
811
+ this.discreteEventsMouseout = discreteEventsMouseout;
812
+ this.createBackdropRect(this.shouldDrawBackdrop());
813
+ if (this.aggregateGroup.selectAll('defs').empty()) {
814
+ this.defs = this.aggregateGroup.append('defs');
815
+ }
816
+ this.createHoverLine();
817
+ var series = this.getVisibleSeries(agg.aggKey);
818
+ this.setEventHeight(series.length);
819
+ if (this.aggregateGroup.selectAll('.tsi-splitBysGroup').empty()) {
820
+ this.splitBysGroup = this.aggregateGroup.append('g').classed('tsi-splitBysGroup', true);
821
+ }
822
+ var self = this;
823
+ var splitByGroups = this.splitBysGroup.selectAll(".tsi-splitByGroup")
824
+ .data(series, function (d) {
825
+ return d.splitBy;
826
+ });
827
+ this.gradientData = [];
828
+ splitByGroups.enter()
829
+ .append("g")
830
+ .attr("class", "tsi-eventsGroup tsi-splitByGroup " + this.aggKey)
831
+ .merge(splitByGroups)
832
+ .attr('transform', function (d, i) {
833
+ return 'translate(0,' + (+(i * (_this.chartDataOptions.height / series.length))) + ')';
834
+ })
835
+ .each(function (splitBy, j) {
836
+ self.createEventElements(splitBy, d3.select(this), j);
837
+ }).each(function () {
838
+ self.themify(d3.select(this), self.chartOptions.theme);
839
+ });
840
+ splitByGroups.exit().remove();
841
+ var gradients = this.defs.selectAll('linearGradient')
842
+ .data(this.gradientData, function (d) {
843
+ return d[1].splitBy;
844
+ });
845
+ var enteredGradients = gradients.enter()
846
+ .append('linearGradient')
847
+ .attr("x2", "0%")
848
+ .attr("y2", "100%")
849
+ .merge(gradients)
850
+ .attr("id", function (d) { return d[0]; });
851
+ enteredGradients
852
+ .each(function (d) {
853
+ self.addGradientStops(d[1], d3.select(this));
854
+ });
855
+ gradients.exit().remove();
856
+ };
857
+ return EventsPlot;
858
+ }(Plot));
859
+
860
+ var AxisState = /** @class */ (function () {
861
+ function AxisState(axisType, yExtent, positionInGroup) {
862
+ this.axisType = axisType;
863
+ this.yExtent = yExtent;
864
+ this.positionInGroup = positionInGroup;
865
+ }
866
+ return AxisState;
867
+ }());
868
+
869
+ var MARKERSTRINGMAXLENGTH = 250;
870
+ var MARKERVALUEMAXWIDTH = 80;
871
+ var Marker = /** @class */ (function (_super) {
872
+ __extends(Marker, _super);
873
+ function Marker(renderTarget) {
874
+ var _this = _super.call(this, renderTarget) || this;
875
+ _this.tooltipMap = {};
876
+ _this.labelText = '';
877
+ _this.markerIsDragging = false;
878
+ _this.isSeriesLabels = false;
879
+ _this.ADDITIONALRIGHTSIDEOVERHANG = 12;
880
+ _this.guid = Utils.guid();
881
+ return _this;
882
+ }
883
+ Marker.prototype.getGuid = function () {
884
+ return this.guid;
885
+ };
886
+ Marker.prototype.setMillis = function (millis) {
887
+ this.timestampMillis = millis;
888
+ };
889
+ Marker.prototype.getMillis = function () {
890
+ return this.timestampMillis;
891
+ };
892
+ // returns whether the string was trimmed to the max length
893
+ Marker.prototype.setLabelText = function (labelText) {
894
+ if (labelText.length > MARKERSTRINGMAXLENGTH) {
895
+ this.labelText = labelText.slice(0, MARKERSTRINGMAXLENGTH);
896
+ return true;
897
+ }
898
+ this.labelText = labelText;
899
+ return false;
900
+ };
901
+ Marker.prototype.getLabelText = function () {
902
+ return this.labelText;
903
+ };
904
+ Marker.prototype.setSeriesLabelText = function (d, text, isSeriesLabelInFocus) {
905
+ text.classed('tsi-isExpanded', false);
906
+ var title = text.append('h4')
907
+ .attr('class', 'tsi-seriesLabelGroupName tsi-tooltipTitle');
908
+ Utils.appendFormattedElementsFromString(title, d.aggregateName);
909
+ var shiftTuple = this.chartComponentData.getTemporalShiftStringTuple(d.aggregateKey);
910
+ var shiftString = '';
911
+ if (shiftTuple !== null) {
912
+ shiftString = shiftTuple[0] === ShiftTypes.startAt ? this.timeFormat(new Date(shiftTuple[1])) : shiftTuple[1];
913
+ }
914
+ var labelDatum = {
915
+ splitBy: d.splitBy,
916
+ variableAlias: this.chartComponentData.displayState[d.aggregateKey].aggregateExpression.variableAlias,
917
+ timeShift: shiftString,
918
+ };
919
+ var subtitle = text.selectAll('.tsi-seriesLabelSeriesName').data([labelDatum]);
920
+ var enteredSubtitle = subtitle.enter()
921
+ .append('div')
922
+ .attr('class', 'tsi-seriesLabelSeriesName tsi-tooltipSubtitle');
923
+ if (labelDatum.splitBy && labelDatum.splitBy !== '') {
924
+ enteredSubtitle.append('span')
925
+ .classed('tsi-splitBy', true);
926
+ }
927
+ if (labelDatum.timeShift) {
928
+ enteredSubtitle.append('span')
929
+ .classed('tsi-timeShift', true);
930
+ }
931
+ if (labelDatum.variableAlias) {
932
+ enteredSubtitle.append('span')
933
+ .classed('tsi-variableAlias', true);
934
+ }
935
+ subtitle.exit().remove();
936
+ Utils.setSeriesLabelSubtitleText(enteredSubtitle, false);
937
+ };
938
+ Marker.prototype.tooltipFormat = function (d, text, measureFormat, xyrMeasures, isSeriesLabelInFocus) {
939
+ if (isSeriesLabelInFocus === void 0) { isSeriesLabelInFocus = false; }
940
+ var tooltipHeight = MARKERVALUENUMERICHEIGHT;
941
+ // revert to default text format if none specified
942
+ if (!this.isSeriesLabels) {
943
+ text.text(Utils.formatYAxisNumber(this.getValueOfVisible(d)))
944
+ .style('height', tooltipHeight + 'px')
945
+ .style('line-height', ((tooltipHeight - 2) + 'px')); // - 2 to account for border height
946
+ }
947
+ else {
948
+ this.setSeriesLabelText(d, text, isSeriesLabelInFocus);
949
+ }
950
+ text.classed('tsi-markerValueTooltipInner', true)
951
+ .style('border-color', this.colorMap[d.aggregateKey + "_" + d.splitBy]);
952
+ };
953
+ Marker.prototype.getLeft = function (d) {
954
+ return Math.round(this.x(d.timestamp) + this.marginLeft);
955
+ };
956
+ // check to see if any marker is being dragged
957
+ Marker.prototype.isMarkerDragOccuring = function () {
958
+ return this.markerIsDragging;
959
+ };
960
+ Marker.prototype.bumpMarker = function () {
961
+ var _this = this;
962
+ d3.select(this.renderTarget).selectAll('.tsi-markerContainer')
963
+ .style('animation', 'none')
964
+ .sort(function (a, b) {
965
+ if (a.timestamp === _this.timestampMillis) {
966
+ return 1;
967
+ }
968
+ if (b.timestamp === _this.timestampMillis) {
969
+ return -1;
970
+ }
971
+ return a.timestamp < b.timestamp ? 1 : -1;
972
+ });
973
+ };
974
+ Marker.prototype.renderMarker = function () {
975
+ var _this = this;
976
+ var self = this;
977
+ var marker = d3.select(this.renderTarget).selectAll(".tsi-markerContainer")
978
+ .filter(function (d) { return d.guid === _this.guid; })
979
+ .data([{ guid: this.guid, timestamp: this.timestampMillis }]);
980
+ this.markerContainer = marker.enter()
981
+ .append('div')
982
+ .attr('class', 'tsi-markerContainer')
983
+ .classed('tsi-isSeriesLabels', this.isSeriesLabels)
984
+ .merge(marker)
985
+ .style('top', "".concat(this.chartMargins.top + this.chartOptions.aggTopMargin, "px"))
986
+ .style('height', "".concat(this.chartHeight - (this.chartMargins.top + this.chartMargins.bottom + this.chartOptions.aggTopMargin), "px"))
987
+ .style('left', function (d) {
988
+ return "".concat(_this.getLeft(d), "px");
989
+ })
990
+ .classed('tsi-isFlipped', function (d) {
991
+ if (_this.isSeriesLabels) {
992
+ return false;
993
+ }
994
+ return (_this.chartOptions.labelSeriesWithMarker && _this.x(d.timestamp) > (_this.x.range()[1] - MARKERVALUEMAXWIDTH));
995
+ })
996
+ .each(function (markerD) {
997
+ if (self.isSeriesLabels) {
998
+ return;
999
+ }
1000
+ if (d3.select(this).selectAll('.tsi-markerLine').empty()) {
1001
+ d3.select(this).append('div')
1002
+ .attr('class', 'tsi-markerLine');
1003
+ self.markerLabel = d3.select(this).append('div')
1004
+ .attr('class', 'tsi-markerLabel')
1005
+ .on('mouseleave', function () {
1006
+ d3.select(this).classed('tsi-markerLabelHovered', false);
1007
+ });
1008
+ self.markerLabel.append('div')
1009
+ .attr('class', 'tsi-markerGrabber')
1010
+ .on('mouseenter', function () {
1011
+ self.bumpMarker();
1012
+ });
1013
+ self.markerLabel.append('div')
1014
+ .attr('class', 'tsi-markerLabelText')
1015
+ .attr('contenteditable', 'true')
1016
+ .text(self.labelText)
1017
+ .on('keydown', function (event) {
1018
+ if (event.keyCode === KeyCodes.Enter && !event.shiftKey) {
1019
+ event.preventDefault();
1020
+ self.closeButton.node().focus();
1021
+ }
1022
+ })
1023
+ .on('input', function () {
1024
+ var didTrim = self.setLabelText(d3.select(this).text());
1025
+ if (didTrim) {
1026
+ d3.select(this).text(self.labelText);
1027
+ }
1028
+ })
1029
+ .on('focus', function () {
1030
+ d3.select(this.parentNode).classed('tsi-markerLabelTextFocused', true);
1031
+ })
1032
+ .on('blur', function () {
1033
+ d3.select(this.parentNode).classed('tsi-markerLabelTextFocused', false);
1034
+ self.onChange(false, false, false);
1035
+ })
1036
+ .on('mousedown', function (event) {
1037
+ event.stopPropagation();
1038
+ })
1039
+ .on('mouseover', function () {
1040
+ if (!self.isMarkerDragOccuring()) {
1041
+ d3.select(d3.select(this).node().parentNode).classed('tsi-markerLabelHovered', true);
1042
+ self.bumpMarker();
1043
+ }
1044
+ });
1045
+ self.closeButton = self.markerLabel.append("button")
1046
+ .attr("aria-label", self.getString('Delete marker'))
1047
+ .classed("tsi-closeButton", true)
1048
+ .on("click", function () {
1049
+ self.onChange(true, false);
1050
+ d3.select(d3.select(this).node().parentNode.parentNode).remove();
1051
+ });
1052
+ self.timeLabel = d3.select(this).append("div")
1053
+ .attr('class', 'tsi-markerTimeLabel');
1054
+ }
1055
+ d3.select(this).selectAll('.tsi-markerTimeLabel,.tsi-markerLine,.tsi-markerLabel')
1056
+ .call(d3.drag()
1057
+ .on('start', function (event, d) {
1058
+ d.isDragging = true;
1059
+ self.markerIsDragging = true;
1060
+ self.bumpMarker();
1061
+ })
1062
+ .on('drag', function (event, d) {
1063
+ if (d3.select(event.sourceEvent.target).classed('tsi-closeButton')) {
1064
+ return;
1065
+ }
1066
+ d3.select(d3.select(this).node().parentNode);
1067
+ var startPosition = self.x(new Date(self.timestampMillis));
1068
+ var newPosition = startPosition + event.x;
1069
+ self.timestampMillis = Utils.findClosestTime(self.x.invert(newPosition).valueOf(), self.chartComponentData.timeMap);
1070
+ self.setPositionsAndLabels(self.timestampMillis);
1071
+ })
1072
+ .on('end', function (event, d) {
1073
+ if (!d3.select(event.sourceEvent.target).classed('tsi-closeButton')) {
1074
+ self.onChange(false, false);
1075
+ }
1076
+ d.isDragging = false;
1077
+ self.markerIsDragging = false;
1078
+ }));
1079
+ });
1080
+ marker.exit().remove();
1081
+ };
1082
+ Marker.prototype.getValueOfVisible = function (d) {
1083
+ return Utils.getValueOfVisible(d, this.chartComponentData.getVisibleMeasure(d.aggregateKey, d.splitBy));
1084
+ };
1085
+ Marker.prototype.getTooltipKey = function (d) {
1086
+ return d.aggregateKey + '_' + d.splitBy;
1087
+ };
1088
+ Marker.prototype.findYatX = function (x, path) {
1089
+ path.parentNode;
1090
+ var length_end = path.getTotalLength();
1091
+ var length_start = 0;
1092
+ var point = path.getPointAtLength((length_end + length_start) / 2);
1093
+ var bisection_iterations_max = 100;
1094
+ var bisection_iterations = 0;
1095
+ var error = 0.01;
1096
+ while (x < point.x - error || x > point.x + error) {
1097
+ point = path.getPointAtLength((length_end + length_start) / 2);
1098
+ if (x < point.x) {
1099
+ length_end = (length_start + length_end) / 2;
1100
+ }
1101
+ else {
1102
+ length_start = (length_start + length_end) / 2;
1103
+ }
1104
+ if (bisection_iterations_max < ++bisection_iterations) {
1105
+ break;
1106
+ }
1107
+ }
1108
+ var offset = path.parentNode.parentNode.transform.baseVal[0].matrix.f; // roundabout way of getting the y transform of the agg group
1109
+ return point.y + offset;
1110
+ };
1111
+ Marker.prototype.positionToValue = function (yPos, aggKey) {
1112
+ var yScale = this.yMap[aggKey];
1113
+ return yScale.invert(yPos);
1114
+ };
1115
+ Marker.prototype.bisectionInterpolateValue = function (millis, aggKey, splitBy, path) {
1116
+ if (path === null) {
1117
+ return null;
1118
+ }
1119
+ var yPosition = this.findYatX(this.x(millis), path);
1120
+ var interpolatedValue = this.positionToValue(yPosition, aggKey);
1121
+ var newDatum = this.createNewDatum(aggKey, splitBy, interpolatedValue);
1122
+ newDatum.isInterpolated = true;
1123
+ return newDatum;
1124
+ };
1125
+ Marker.prototype.getPath = function (aggKey, splitBy) {
1126
+ var selectedPaths = d3.select(this.renderTarget).selectAll('.tsi-valueLine').filter(function (d) {
1127
+ if (d.length) {
1128
+ return d[0].aggregateKey === aggKey && d[0].splitBy === splitBy;
1129
+ }
1130
+ return false;
1131
+ });
1132
+ if (selectedPaths.size() === 0) {
1133
+ return null;
1134
+ }
1135
+ return selectedPaths.nodes()[0];
1136
+ };
1137
+ Marker.prototype.createNewDatum = function (aggKey, splitBy, valueOfVisible) {
1138
+ var newDatum = {};
1139
+ newDatum.aggregateKey = aggKey;
1140
+ newDatum.splitBy = splitBy;
1141
+ newDatum.measures = {};
1142
+ newDatum.measures[this.chartComponentData.getVisibleMeasure(aggKey, splitBy)] = valueOfVisible;
1143
+ return newDatum;
1144
+ };
1145
+ Marker.prototype.findGapPath = function (aggKey, splitBy, millis) {
1146
+ var gapPath = d3.select(this.renderTarget).selectAll('.tsi-gapLine')
1147
+ .filter(function (d) {
1148
+ if (d.length === 2 && aggKey === d[0].aggregateKey && splitBy === d[0].splitBy) {
1149
+ return (millis > d[0].dateTime.valueOf() && millis < d[1].dateTime.valueOf());
1150
+ }
1151
+ return false;
1152
+ });
1153
+ if (gapPath.size() === 0) {
1154
+ return null;
1155
+ }
1156
+ return gapPath.nodes()[0];
1157
+ };
1158
+ //check if a value is within the time constrained bounds of a path
1159
+ Marker.prototype.inBounds = function (path, millis) {
1160
+ var _this = this;
1161
+ var filteredData = path.data()[0].filter(function (d) {
1162
+ return d.measures && _this.getValueOfVisible(d) !== null;
1163
+ });
1164
+ if (filteredData.length > 0) {
1165
+ var lowerBound = filteredData[0].dateTime.valueOf();
1166
+ var upperBound = filteredData[filteredData.length - 1].dateTime.valueOf();
1167
+ return millis >= lowerBound && millis <= upperBound;
1168
+ }
1169
+ return false;
1170
+ };
1171
+ Marker.prototype.getIntersectingPath = function (aggKey, splitBy, millis) {
1172
+ if (this.chartComponentData.displayState[aggKey].bucketSize) {
1173
+ millis = millis - (this.chartComponentData.displayState[aggKey].bucketSize / 2);
1174
+ }
1175
+ var gapPath = this.findGapPath(aggKey, splitBy, millis);
1176
+ if (gapPath) {
1177
+ return gapPath;
1178
+ }
1179
+ else {
1180
+ return this.inBounds(d3.select(this.getPath(aggKey, splitBy)), millis) ? this.getPath(aggKey, splitBy) : null;
1181
+ }
1182
+ };
1183
+ Marker.prototype.interpolateValue = function (millis, aggKey, splitBy) {
1184
+ var path = this.getIntersectingPath(aggKey, splitBy, millis);
1185
+ if (path === null) {
1186
+ return null;
1187
+ }
1188
+ return this.bisectionInterpolateValue(millis, aggKey, splitBy, path);
1189
+ };
1190
+ Marker.prototype.getValuesAtTime = function (closestTime) {
1191
+ var _this = this;
1192
+ var valueArray = [];
1193
+ var values = this.chartComponentData.timeMap[closestTime] != undefined ? this.chartComponentData.timeMap[closestTime] : [];
1194
+ Object.keys(this.chartComponentData.visibleTAs).forEach(function (aggKey) {
1195
+ Object.keys(_this.chartComponentData.visibleTAs[aggKey]).forEach(function (splitBy) {
1196
+ if (_this.chartComponentData.displayState[aggKey].dataType !== DataTypes.Numeric) {
1197
+ return;
1198
+ }
1199
+ var filteredValues = values.filter(function (v) {
1200
+ return (v.aggregateKey === aggKey && v.splitBy === splitBy && _this.getValueOfVisible(v) !== null);
1201
+ });
1202
+ if (filteredValues.length === 1 && (_this.getValueOfVisible(filteredValues[0]) !== null)) {
1203
+ valueArray.push(filteredValues[0]);
1204
+ }
1205
+ else {
1206
+ var interpolatedValue = _this.interpolateValue(closestTime, aggKey, splitBy);
1207
+ if (interpolatedValue !== null || !_this.isSeriesLabels) {
1208
+ valueArray.push(interpolatedValue);
1209
+ }
1210
+ else {
1211
+ var lastValue = _this.chartComponentData.findLastTimestampWithValue(aggKey, splitBy);
1212
+ if (lastValue !== null) {
1213
+ valueArray.push(lastValue);
1214
+ }
1215
+ }
1216
+ }
1217
+ });
1218
+ });
1219
+ return valueArray;
1220
+ };
1221
+ Marker.prototype.setValueLabels = function (closestTime) {
1222
+ var _this = this;
1223
+ var values = this.getValuesAtTime(closestTime);
1224
+ values = values.filter(function (d) {
1225
+ return d && _this.chartComponentData.getDataType(d.aggregateKey) === DataTypes.Numeric;
1226
+ });
1227
+ var self = this;
1228
+ var valueLabels = this.markerContainer.selectAll(".tsi-markerValue").data(values, function (d) {
1229
+ return d.aggregateKey + "_" + d.splitBy;
1230
+ });
1231
+ valueLabels.enter()
1232
+ .append("div")
1233
+ .classed("tsi-markerValue", true)
1234
+ .classed('tsi-seriesLabelValue', this.isSeriesLabels)
1235
+ .merge(valueLabels)
1236
+ .classed('tsi-isInterpolated', function (d) {
1237
+ return d.isInterpolated;
1238
+ })
1239
+ .style('top', function (d) { return _this.calcTopOfValueLabel(d) + 'px'; })
1240
+ .each(function (d) {
1241
+ var tooltipKey = self.getTooltipKey(d);
1242
+ var tooltip;
1243
+ if (self.tooltipMap[tooltipKey]) {
1244
+ tooltip = self.tooltipMap[tooltipKey];
1245
+ }
1246
+ else {
1247
+ tooltip = new Tooltip(d3.select(this));
1248
+ self.tooltipMap[tooltipKey] = tooltip;
1249
+ }
1250
+ tooltip.render(self.chartOptions.theme);
1251
+ tooltip.draw(d, self.chartComponentData, 0, MARKERVALUENUMERICHEIGHT / 2, { right: 0, left: 0, top: 0, bottom: 0 }, function (tooltipTextElement) {
1252
+ self.tooltipFormat(d, tooltipTextElement, null, null);
1253
+ }, null, 0, 0, self.colorMap[d.aggregateKey + "_" + d.splitBy], true);
1254
+ var markerValueCaret = d3.select(this).selectAll('.tsi-markerValueCaret')
1255
+ .data([d]);
1256
+ markerValueCaret.enter().append('div')
1257
+ .attr('class', 'tsi-markerValueCaret')
1258
+ .merge(markerValueCaret)
1259
+ .style("border-right-color", function () { return self.colorMap[d.aggregateKey + "_" + d.splitBy]; });
1260
+ markerValueCaret.exit().remove();
1261
+ });
1262
+ var valueLabelsExit = valueLabels.exit();
1263
+ valueLabelsExit.each(function (d) {
1264
+ delete _this.tooltipMap[_this.getTooltipKey(d)];
1265
+ });
1266
+ valueLabelsExit.remove();
1267
+ };
1268
+ Marker.prototype.calcTopOfValueLabel = function (d) {
1269
+ var yScale = this.yMap[d.aggregateKey];
1270
+ return Math.round(yScale(this.getValueOfVisible(d)) - this.chartOptions.aggTopMargin);
1271
+ };
1272
+ Marker.prototype.getTimeFormat = function () {
1273
+ return Utils.timeFormat(this.chartComponentData.usesSeconds, this.chartComponentData.usesMillis, this.chartOptions.offset, this.chartOptions.is24HourTime, 0, null, this.chartOptions.dateLocale);
1274
+ };
1275
+ Marker.prototype.setTimeLabel = function (closestTime) {
1276
+ if (this.isSeriesLabels) {
1277
+ return;
1278
+ }
1279
+ var values = this.chartComponentData.timeMap[closestTime];
1280
+ if (values == undefined || values.length == 0) {
1281
+ return;
1282
+ }
1283
+ var firstValue = values[0].dateTime;
1284
+ var secondValue = new Date(values[0].dateTime.valueOf() + (values[0].bucketSize != null ? values[0].bucketSize : 0));
1285
+ this.timeLabel.text('');
1286
+ this.timeLabel.append('div')
1287
+ .attr('class', 'tsi-markerTimeLine')
1288
+ .text(this.timeFormat(firstValue));
1289
+ if (values[0].bucketSize !== null) {
1290
+ this.timeLabel.append('div')
1291
+ .attr('class', 'tsi-markerTimeLine')
1292
+ .text(this.timeFormat(secondValue));
1293
+ }
1294
+ var markerLeft = Number(this.markerContainer.style("left").replace("px", ""));
1295
+ var timeLabelWidth = Math.round(this.timeLabel.node().getBoundingClientRect().width);
1296
+ var minLeftPosition = this.marginLeft + LINECHARTXOFFSET;
1297
+ var width = this.x.range()[1] - this.x.range()[0];
1298
+ var maxRightPosition = width + this.marginLeft + LINECHARTXOFFSET + this.ADDITIONALRIGHTSIDEOVERHANG;
1299
+ var calculatedLeftPosition = markerLeft - (timeLabelWidth / 2);
1300
+ var calculatedRightPosition = markerLeft + (timeLabelWidth / 2);
1301
+ var translate = "translateX(calc(-50% + 1px))";
1302
+ if (calculatedLeftPosition < minLeftPosition) {
1303
+ translate = "translateX(-" + Math.max(0, markerLeft - minLeftPosition) + "px)";
1304
+ }
1305
+ if (calculatedRightPosition > maxRightPosition) {
1306
+ translate = "translateX(calc(-50% + " + (maxRightPosition - calculatedRightPosition) + "px))";
1307
+ }
1308
+ this.timeLabel
1309
+ .style("-webkit-tranform", translate)
1310
+ .style("transform", translate);
1311
+ };
1312
+ Marker.prototype.focusCloseButton = function () {
1313
+ if (this.closeButton) {
1314
+ this.closeButton.node().focus();
1315
+ }
1316
+ };
1317
+ Marker.prototype.isMarkerInRange = function (millis) {
1318
+ if (millis === void 0) { millis = this.timestampMillis; }
1319
+ var domain = this.x.domain();
1320
+ return !(millis < domain[0].valueOf() || millis > domain[1].valueOf());
1321
+ };
1322
+ Marker.prototype.destroyMarker = function () {
1323
+ if (this.markerContainer) {
1324
+ this.markerContainer.remove();
1325
+ }
1326
+ this.tooltipMap = {};
1327
+ this.markerContainer = null;
1328
+ };
1329
+ Marker.prototype.render = function (timestampMillis, chartOptions, chartComponentData, additionalMarkerFields) {
1330
+ this.chartMargins = Object.assign({}, additionalMarkerFields.chartMargins);
1331
+ this.chartHeight = additionalMarkerFields.chartHeight;
1332
+ this.timestampMillis = timestampMillis;
1333
+ this.chartOptions = chartOptions;
1334
+ this.x = additionalMarkerFields.x;
1335
+ this.chartComponentData = chartComponentData;
1336
+ this.marginLeft = additionalMarkerFields.marginLeft;
1337
+ this.colorMap = additionalMarkerFields.colorMap;
1338
+ this.timeFormat = this.getTimeFormat();
1339
+ this.isSeriesLabels = additionalMarkerFields.isSeriesLabels;
1340
+ if (additionalMarkerFields.labelText) {
1341
+ this.labelText = additionalMarkerFields.labelText;
1342
+ }
1343
+ this.yMap = additionalMarkerFields.yMap;
1344
+ if (additionalMarkerFields.onChange) { // only update onChange if passed in, otherwise maintain previous
1345
+ this.onChange = additionalMarkerFields.onChange;
1346
+ }
1347
+ if (!this.isMarkerInRange(this.timestampMillis)) {
1348
+ this.destroyMarker();
1349
+ return;
1350
+ }
1351
+ this.renderMarker();
1352
+ var closestTime = Utils.findClosestTime(this.timestampMillis, this.chartComponentData.timeMap);
1353
+ this.setPositionsAndLabels(closestTime);
1354
+ _super.prototype.themify.call(this, this.markerContainer, this.chartOptions.theme);
1355
+ };
1356
+ Marker.prototype.setPositionsAndLabels = function (millis) {
1357
+ if (!this.isMarkerInRange(millis)) {
1358
+ this.destroyMarker();
1359
+ return;
1360
+ }
1361
+ this.renderMarker();
1362
+ this.setTimeLabel(millis);
1363
+ this.setValueLabels(millis);
1364
+ };
1365
+ return Marker;
1366
+ }(Component));
1367
+
1368
+ var LineChart = /** @class */ (function (_super) {
1369
+ __extends(LineChart, _super);
1370
+ function LineChart(renderTarget) {
1371
+ var _this = _super.call(this, renderTarget) || this;
1372
+ _this.minBrushWidth = 1;
1373
+ _this.strokeOpacity = 1;
1374
+ _this.nonFocusStrokeOpactiy = .3;
1375
+ _this.chartComponentData = new LineChartData();
1376
+ _this.surpressBrushTimeSet = false;
1377
+ _this.hasStackedButton = false;
1378
+ _this.stackedButton = null;
1379
+ _this.horizontalLabelOffset = LINECHARTCHARTMARGINS.left + swimlaneLabelConstants.leftMarginOffset;
1380
+ _this.markers = {};
1381
+ _this.seriesLabelsMarker = null;
1382
+ _this.markerGuidMap = {};
1383
+ _this.isDroppingMarker = false;
1384
+ _this.brushStartPosition = null;
1385
+ _this.brushEndPosition = null;
1386
+ _this.hasBrush = false;
1387
+ _this.isClearingBrush = false;
1388
+ _this.previousAggregateData = d3.local();
1389
+ _this.previousIncludeDots = d3.local();
1390
+ _this.mx = null;
1391
+ _this.my = null;
1392
+ _this.focusedAggKey = null;
1393
+ _this.focusedSplitby = null;
1394
+ _this.plotComponents = {};
1395
+ _this.isFirstMarkerDrop = true;
1396
+ _this.xOffset = 8;
1397
+ _this.swimlaneYExtents = {}; // mapping of swimlanes to the y extents of that swimlane
1398
+ _this.swimLaneContents = {};
1399
+ _this.resetValueElementsFocus = function () {
1400
+ _this.svgSelection.selectAll(".tsi-valueElement")
1401
+ .attr("stroke-opacity", _this.strokeOpacity)
1402
+ .filter(function () {
1403
+ return !d3.select(this).classed("tsi-valueEnvelope");
1404
+ })
1405
+ .attr("fill-opacity", 1);
1406
+ _this.svgSelection.selectAll(".tsi-valueEnvelope")
1407
+ .attr("fill-opacity", .2);
1408
+ Utils.revertAllSubtitleText(d3.select(_this.renderTarget).selectAll('.tsi-markerValue'));
1409
+ _this.focusedAggKey = null;
1410
+ _this.focusedSplitby = null;
1411
+ };
1412
+ _this.triggerLineFocus = function (aggKey, splitBy) {
1413
+ _this.focusedAggKey = null;
1414
+ _this.focusedSplitby = null;
1415
+ _this.focusOnlyHoveredSeries(aggKey, splitBy, true);
1416
+ };
1417
+ _this.focusOnlyHoveredSeries = function (aggKey, splitBy, shouldSetFocusedValues) {
1418
+ if (aggKey !== _this.focusedAggKey || splitBy !== _this.focusedSplitby) {
1419
+ var selectedFilter = Utils.createValueFilter(aggKey, splitBy);
1420
+ _this.focusMarkerLabel(selectedFilter, aggKey, splitBy);
1421
+ _this.svgSelection.selectAll(".tsi-valueElement")
1422
+ .attr("stroke-opacity", _this.nonFocusStrokeOpactiy)
1423
+ .attr("fill-opacity", .3);
1424
+ _this.svgSelection.selectAll(".tsi-valueEnvelope")
1425
+ .attr("fill-opacity", .1);
1426
+ _this.svgSelection.selectAll(".tsi-valueElement")
1427
+ .filter(selectedFilter)
1428
+ .attr("stroke-opacity", _this.strokeOpacity)
1429
+ .attr("fill-opacity", 1);
1430
+ _this.svgSelection.selectAll(".tsi-valueEnvelope")
1431
+ .filter(selectedFilter)
1432
+ .attr("fill-opacity", .3);
1433
+ if (shouldSetFocusedValues) {
1434
+ _this.focusedAggKey = aggKey;
1435
+ _this.focusedSplitby = splitBy;
1436
+ }
1437
+ }
1438
+ };
1439
+ _this.discreteEventsMouseover = function (d, x, y, width) {
1440
+ if (_this.isDroppingMarker) {
1441
+ return false;
1442
+ }
1443
+ _this.legendObject.triggerSplitByFocus(d.aggregateKey, d.splitBy);
1444
+ _this.focusOnlyHoveredSeries(d.aggregateKey, d.splitBy, true);
1445
+ var xPos = x;
1446
+ y + _this.chartMargins.top;
1447
+ _this.getValueOfVisible(d);
1448
+ if (_this.chartOptions.tooltip) {
1449
+ _this.tooltip.render(_this.chartOptions.theme);
1450
+ _this.tooltip.draw(d, _this.chartComponentData, xPos, y, _this.chartMargins, function (text) {
1451
+ _this.tooltipFormat(d, text, TooltipMeasureFormat.SingleValue);
1452
+ }, width, 0, 0);
1453
+ }
1454
+ else
1455
+ _this.tooltip.hide();
1456
+ return true;
1457
+ };
1458
+ _this.discreteEventsMouseout = function () {
1459
+ _this.legendObject.legendElement.selectAll('.tsi-splitByLabel').classed("inFocus", false);
1460
+ _this.resetValueElementsFocus();
1461
+ _this.tooltip.hide();
1462
+ };
1463
+ //returns false if supressed via isDroppingMarker, true otherwise
1464
+ _this.categoricalMouseover = function (d, x, y, endDate, width) {
1465
+ if (_this.isDroppingMarker) {
1466
+ return false;
1467
+ }
1468
+ _this.legendObject.triggerSplitByFocus(d.aggregateKey, d.splitBy);
1469
+ _this.focusOnlyHoveredSeries(d.aggregateKey, d.splitBy, true);
1470
+ var xPos = x;
1471
+ y + _this.chartMargins.top;
1472
+ _this.getValueOfVisible(d);
1473
+ if (_this.chartOptions.tooltip) {
1474
+ _this.tooltip.render(_this.chartOptions.theme);
1475
+ _this.tooltip.draw(d, _this.chartComponentData, xPos, y, _this.chartMargins, function (text) {
1476
+ d.endDate = endDate;
1477
+ _this.tooltipFormat(d, text, TooltipMeasureFormat.SingleValue);
1478
+ }, width, 0, 0);
1479
+ }
1480
+ else
1481
+ _this.tooltip.hide();
1482
+ return true;
1483
+ };
1484
+ _this.categoricalMouseout = function () {
1485
+ _this.legendObject.legendElement.selectAll('.tsi-splitByLabel').classed("inFocus", false);
1486
+ _this.resetValueElementsFocus();
1487
+ _this.tooltip.hide();
1488
+ };
1489
+ _this.voronoiMouseover = function (d) {
1490
+ //supress if the context menu is visible
1491
+ if (_this.contextMenu && _this.contextMenu.contextMenuVisible)
1492
+ return;
1493
+ var shiftMillis = _this.chartComponentData.getTemporalShiftMillis(d.aggregateKey);
1494
+ var yScale = _this.yMap[d.aggregateKey];
1495
+ var xValue = d.dateTime;
1496
+ var xPos = _this.getXPosition(d, _this.x);
1497
+ var yValue = _this.getValueOfVisible(d);
1498
+ var yPos = yScale(yValue);
1499
+ _this.focus.style("display", "block");
1500
+ _this.focus.attr("transform", "translate(" + xPos + "," + yPos + ")");
1501
+ _this.focus.select('.tsi-hLine').attr("transform", "translate(" + (-xPos) + ",0)");
1502
+ _this.focus.select('.tsi-vLine').attr("transform", "translate(0," + (-yPos) + ")");
1503
+ _this.setHorizontalValuePosAndText(d, xPos + _this.getSVGLeftOffset() + _this.chartMargins.left, xValue, shiftMillis);
1504
+ _this.setVerticalValueAndPosition(yValue, yPos + _this.chartMargins.top);
1505
+ var bucketSize = _this.chartComponentData.displayState[d.aggregateKey].bucketSize;
1506
+ var endValue = bucketSize ? (new Date(xValue.valueOf() + bucketSize)) : null;
1507
+ if (endValue) {
1508
+ var barWidth = _this.x(endValue) - _this.x(xValue);
1509
+ _this.horizontalValueBar
1510
+ .style('display', 'block')
1511
+ .attr("x1", (-barWidth / 2))
1512
+ .attr("x2", (barWidth / 2))
1513
+ .attr('y1', _this.chartHeight - yPos + 2)
1514
+ .attr('y2', _this.chartHeight - yPos + 2);
1515
+ }
1516
+ else {
1517
+ _this.horizontalValueBar.style('display', 'none');
1518
+ }
1519
+ if (_this.chartOptions.tooltip) {
1520
+ _this.tooltip.render(_this.chartOptions.theme);
1521
+ _this.tooltip.draw(d, _this.chartComponentData, xPos, yPos, _this.chartMargins, function (text) {
1522
+ _this.tooltipFormat(d, text, TooltipMeasureFormat.Enveloped);
1523
+ }, null, 20, 20, _this.colorMap[d.aggregateKey + "_" + d.splitBy]);
1524
+ }
1525
+ else
1526
+ _this.tooltip.hide();
1527
+ _this.focus.node().parentNode.appendChild(_this.focus.node());
1528
+ _this.legendObject.triggerSplitByFocus(d.aggregateKey, d.splitBy);
1529
+ /** update the y axis for in focus aggregate */
1530
+ if (_this.chartOptions.yAxisState === YAxisStates.Overlap) {
1531
+ _this.svgSelection.selectAll(".yAxis")
1532
+ .selectAll("text")
1533
+ .style("fill-opacity", .5)
1534
+ .classed("standardYAxisText", true);
1535
+ _this.svgSelection.selectAll(".yAxis")
1536
+ .filter(function (yAxisAggKey) {
1537
+ return yAxisAggKey == d.aggregateKey;
1538
+ })
1539
+ .selectAll("text")
1540
+ .style("fill-opacity", 1)
1541
+ .classed("standardYAxisText", false)
1542
+ .style("font-weight", "bold");
1543
+ }
1544
+ if (_this.chartOptions.yAxisHidden) {
1545
+ _this.svgSelection.selectAll(".yAxis").style("display", "hidden");
1546
+ }
1547
+ if (_this.chartOptions.xAxisHidden) {
1548
+ _this.svgSelection.selectAll(".xAxis").style("display", "none");
1549
+ }
1550
+ _this.chartOptions.onMouseover(d.aggregateKey, d.splitBy);
1551
+ };
1552
+ _this.stickyOrUnstickySeries = function (aggKey, splitBy) {
1553
+ if (_this.chartComponentData.stickiedKey && _this.chartComponentData.stickiedKey.aggregateKey === aggKey &&
1554
+ _this.chartComponentData.stickiedKey.splitBy === splitBy) {
1555
+ _this.unstickySeries(aggKey, splitBy);
1556
+ }
1557
+ else {
1558
+ _this.stickySeries(aggKey, splitBy);
1559
+ }
1560
+ };
1561
+ _this.unstickySeries = function (aggKey, splitby) {
1562
+ if (splitby === void 0) { splitby = null; }
1563
+ if (_this.getDataType(aggKey) !== DataTypes.Numeric || !_this.chartOptions.shouldSticky) {
1564
+ return;
1565
+ }
1566
+ _this.chartComponentData.stickiedKey = null;
1567
+ _this.legendObject.legendElement.selectAll('.tsi-splitByLabel').classed("stickied", false);
1568
+ // recompute voronoi with no sticky
1569
+ _this.voronoiDiagram = _this.voronoi(_this.getFilteredAndSticky(_this.chartComponentData.allValues));
1570
+ _this.chartOptions.onUnsticky(aggKey, splitby);
1571
+ };
1572
+ _this.stickySeries = function (aggregateKey, splitBy) {
1573
+ if (splitBy === void 0) { splitBy = null; }
1574
+ if (_this.getDataType(aggregateKey) !== DataTypes.Numeric || !_this.chartOptions.shouldSticky) {
1575
+ return;
1576
+ }
1577
+ var filteredValues = _this.getFilteredAndSticky(_this.chartComponentData.allValues);
1578
+ if (filteredValues == null || filteredValues.length == 0)
1579
+ return;
1580
+ _this.focusedAggKey = null;
1581
+ _this.focusedSplitby = null;
1582
+ _this.chartComponentData.stickiedKey = {
1583
+ aggregateKey: aggregateKey,
1584
+ splitBy: (splitBy == null ? null : splitBy)
1585
+ };
1586
+ _this.legendObject.legendElement.selectAll('.tsi-splitByLabel').filter(function (filteredSplitBy) {
1587
+ return (d3.select(this.parentNode).datum() == aggregateKey) && (filteredSplitBy == splitBy);
1588
+ }).classed("stickied", true);
1589
+ _this.voronoiDiagram = _this.voronoi(_this.getFilteredAndSticky(_this.chartComponentData.allValues));
1590
+ _this.chartOptions.onSticky(aggregateKey, splitBy);
1591
+ };
1592
+ _this.filteredValueExist = function () {
1593
+ var filteredValues = _this.getFilteredAndSticky(_this.chartComponentData.allValues);
1594
+ return !(filteredValues == null || filteredValues.length == 0);
1595
+ };
1596
+ _this.addMarker = function () {
1597
+ if (_this.isFirstMarkerDrop) {
1598
+ _this.isFirstMarkerDrop = false;
1599
+ _this.createMarkerInstructions();
1600
+ }
1601
+ _this.isDroppingMarker = !_this.isDroppingMarker;
1602
+ if (!_this.isDroppingMarker) {
1603
+ _this.destroyMarkerInstructions();
1604
+ return;
1605
+ }
1606
+ Utils.focusOnEllipsisButton(_this.renderTarget);
1607
+ var marker = new Marker(_this.renderTarget);
1608
+ var markerUID = Utils.guid();
1609
+ var onChange = _this.createOnMarkerChange(markerUID, marker);
1610
+ _this.activeMarker = marker;
1611
+ _this.markerGuidMap[markerUID] = marker;
1612
+ _this.renderMarker(marker, Infinity, onChange, "".concat(_this.getString('Marker'), " ").concat(Object.keys(_this.markerGuidMap).length));
1613
+ };
1614
+ _this.labelMouseout = function () {
1615
+ if (_this.svgSelection) {
1616
+ Utils.revertAllSubtitleText(d3.select(_this.renderTarget).selectAll('.tsi-markerValue'));
1617
+ _this.svgSelection.selectAll(".tsi-valueElement")
1618
+ .filter(function () { return !d3.select(this).classed("tsi-valueEnvelope"); })
1619
+ .attr("stroke-opacity", 1)
1620
+ .attr("fill-opacity", 1);
1621
+ _this.svgSelection.selectAll(".tsi-valueEnvelope")
1622
+ .attr("fill-opacity", .3);
1623
+ }
1624
+ };
1625
+ _this.labelMouseover = function (aggregateKey, splitBy) {
1626
+ if (splitBy === void 0) { splitBy = null; }
1627
+ _this.focusOnlyHoveredSeries(aggregateKey, splitBy, false);
1628
+ };
1629
+ _this.nextStackedState = function () {
1630
+ if (_this.chartOptions.yAxisState === YAxisStates.Stacked)
1631
+ return "shared";
1632
+ else if (_this.chartOptions.yAxisState === YAxisStates.Shared)
1633
+ return "overlap";
1634
+ else
1635
+ return "stacked";
1636
+ };
1637
+ _this.MINHEIGHT = 26;
1638
+ _this.chartMargins = Object.assign({}, LINECHARTCHARTMARGINS);
1639
+ return _this;
1640
+ }
1641
+ LineChart.prototype.LineChart = function () {
1642
+ };
1643
+ //get the left and right positions of the brush
1644
+ LineChart.prototype.getBrushPositions = function () {
1645
+ var leftPos = null;
1646
+ var rightPos = null;
1647
+ if (this.brushStartTime) {
1648
+ var rawLeft = this.x(this.brushStartTime);
1649
+ if (rawLeft >= 0 && rawLeft <= this.chartWidth)
1650
+ leftPos = Math.round(rawLeft + this.chartMargins.left);
1651
+ }
1652
+ if (this.brushEndTime) {
1653
+ var rawRight = this.x(this.brushEndTime);
1654
+ if (rawRight >= 0 && rawRight <= this.chartWidth)
1655
+ rightPos = Math.round(rawRight + this.chartMargins.left);
1656
+ }
1657
+ return {
1658
+ leftPos: leftPos,
1659
+ rightPos: rightPos
1660
+ };
1661
+ };
1662
+ LineChart.prototype.hideFocusElements = function () {
1663
+ this.focus.style('display', 'none');
1664
+ this.verticalValueBox.style('display', 'none');
1665
+ this.horizontalValueBox.style('display', 'none');
1666
+ };
1667
+ LineChart.prototype.voronoiMouseout = function (event, d) {
1668
+ //supress if the context menu is visible
1669
+ if (this.contextMenu && this.contextMenu.contextMenuVisible)
1670
+ return;
1671
+ this.hideFocusElements();
1672
+ this.tooltip.hide();
1673
+ this.legendObject.legendElement.selectAll('.tsi-splitByLabel').classed("inFocus", false);
1674
+ if (event && event.type != 'end') {
1675
+ event.stopPropagation();
1676
+ }
1677
+ this.resetValueElementsFocus();
1678
+ /** Update y Axis */
1679
+ if (this.chartOptions.yAxisState == YAxisStates.Overlap) {
1680
+ this.svgSelection.selectAll(".yAxis")
1681
+ .selectAll("text")
1682
+ .style("fill-opacity", 1)
1683
+ .classed("standardYAxisText", false)
1684
+ .style("font-weight", "normal");
1685
+ }
1686
+ };
1687
+ LineChart.prototype.createMarkerInstructions = function () {
1688
+ this.targetElement.selectAll(".tsi-markerInstructions").remove();
1689
+ this.targetElement.append("div")
1690
+ .classed("tsi-markerInstructions", true)
1691
+ .attr('role', 'alert')
1692
+ .attr('aria-live', 'assertive')
1693
+ .text(this.getString("Click to drop marker") + "," + this.getString("drag to reposition") + ".");
1694
+ };
1695
+ LineChart.prototype.destroyMarkerInstructions = function () {
1696
+ this.targetElement.selectAll(".tsi-markerInstructions").remove();
1697
+ };
1698
+ LineChart.prototype.getMouseoverFunction = function (chartType) {
1699
+ if (chartType === void 0) { chartType = DataTypes.Numeric; }
1700
+ switch (chartType) {
1701
+ case DataTypes.Categorical:
1702
+ return this.categoricalMouseover;
1703
+ case DataTypes.Events:
1704
+ return this.discreteEventsMouseover;
1705
+ default:
1706
+ return function () { };
1707
+ }
1708
+ };
1709
+ LineChart.prototype.getMouseoutFunction = function (chartType) {
1710
+ if (chartType === void 0) { chartType = DataTypes.Numeric; }
1711
+ switch (chartType) {
1712
+ case DataTypes.Categorical:
1713
+ return this.categoricalMouseout;
1714
+ case DataTypes.Events:
1715
+ return this.discreteEventsMouseout;
1716
+ default:
1717
+ return function () { };
1718
+ }
1719
+ };
1720
+ LineChart.prototype.mismatchingChartType = function (aggKey) {
1721
+ if (!this.plotComponents[aggKey]) {
1722
+ return false;
1723
+ }
1724
+ var typeOfPlot = this.plotComponents[aggKey].plotDataType;
1725
+ return typeOfPlot !== this.getDataType(aggKey);
1726
+ };
1727
+ LineChart.prototype.setHorizontalValuePosAndText = function (d, xPos, xValue, shiftMillis) {
1728
+ var bucketSize = this.chartComponentData.displayState[d.aggregateKey].bucketSize;
1729
+ var endValue = bucketSize ? (new Date(xValue.valueOf() + bucketSize)) : null;
1730
+ this.horizontalValueBox.text('')
1731
+ .style('left', "".concat(xPos, "px"))
1732
+ .style('top', "".concat((this.chartMargins.top + this.chartHeight + VALUEBARHEIGHT), "px"))
1733
+ .style('display', 'block');
1734
+ this.horizontalValueBox.append('div')
1735
+ .attr('class', 'tsi-valueBoxText')
1736
+ .text(Utils.timeFormat(this.chartComponentData.usesSeconds, this.chartComponentData.usesMillis, this.chartOptions.offset, this.chartOptions.is24HourTime, shiftMillis, null, this.chartOptions.dateLocale)(xValue));
1737
+ if (endValue !== null) {
1738
+ this.horizontalValueBox.append('div')
1739
+ .attr('class', 'tsi-valueBoxText')
1740
+ .text(Utils.timeFormat(this.chartComponentData.usesSeconds, this.chartComponentData.usesMillis, this.chartOptions.offset, this.chartOptions.is24HourTime, shiftMillis, null, this.chartOptions.dateLocale)(endValue));
1741
+ }
1742
+ };
1743
+ LineChart.prototype.setVerticalValueAndPosition = function (yValue, yPos) {
1744
+ this.verticalValueBox.style('top', "".concat(yPos, "px"))
1745
+ .style('right', "".concat((this.chartMargins.right + this.chartWidth), "px"))
1746
+ .style('display', 'block')
1747
+ .text(Utils.formatYAxisNumber(yValue));
1748
+ };
1749
+ //get the extent of an array of timeValues
1750
+ LineChart.prototype.getYExtent = function (aggValues, isEnvelope, aggKey) {
1751
+ var _this = this;
1752
+ if (aggKey === void 0) { aggKey = null; }
1753
+ var extent;
1754
+ if (aggKey !== null && (this.chartComponentData.displayState[aggKey].yExtent !== null)) {
1755
+ return this.chartComponentData.displayState[aggKey].yExtent;
1756
+ }
1757
+ if (this.chartOptions.yExtent !== null) {
1758
+ return this.chartOptions.yExtent;
1759
+ }
1760
+ if (isEnvelope) {
1761
+ var filteredValues = this.getFilteredValues(aggValues);
1762
+ var flatValuesList = [];
1763
+ filteredValues.forEach(function (d) {
1764
+ if (_this.chartComponentData.isPossibleEnvelope(d.aggregateKey, d.splitBy)) {
1765
+ if (d.measures['min'] != undefined && d.measures['min'] != null) {
1766
+ flatValuesList.push(d.measures['min']);
1767
+ }
1768
+ if (d.measures['avg'] != undefined && d.measures['avg'] != null) {
1769
+ flatValuesList.push(d.measures['avg']);
1770
+ }
1771
+ if (d.measures['max'] != undefined && d.measures['max'] != null) {
1772
+ flatValuesList.push(d.measures['max']);
1773
+ }
1774
+ }
1775
+ else {
1776
+ var visibleMeasure = _this.chartComponentData.getVisibleMeasure(d.aggregateKey, d.splitBy);
1777
+ if (d.measures[visibleMeasure] != undefined && d.measures[visibleMeasure] != null) {
1778
+ flatValuesList.push(d.measures[visibleMeasure]);
1779
+ }
1780
+ }
1781
+ });
1782
+ extent = d3.extent(flatValuesList);
1783
+ }
1784
+ else {
1785
+ extent = d3.extent(this.getFilteredValues(aggValues), function (d) {
1786
+ var visibleMeasure = _this.chartComponentData.getVisibleMeasure(d.aggregateKey, d.splitBy);
1787
+ if (d.measures[visibleMeasure] != undefined && d.measures[visibleMeasure] != null) {
1788
+ return d.measures[visibleMeasure];
1789
+ }
1790
+ return null;
1791
+ });
1792
+ }
1793
+ if (extent[0] == undefined || extent[1] == undefined)
1794
+ return [0, 1];
1795
+ return extent;
1796
+ };
1797
+ LineChart.prototype.getFilteredValues = function (aggValues) {
1798
+ var _this = this;
1799
+ return aggValues.filter(function (d) {
1800
+ return (d.measures && _this.getValueOfVisible(d) !== null);
1801
+ });
1802
+ };
1803
+ LineChart.prototype.getFilteredAndSticky = function (aggValues) {
1804
+ var _this = this;
1805
+ var filteredValues = this.getFilteredValues(aggValues);
1806
+ var numericFiltered = filteredValues.filter(function (d) {
1807
+ return (_this.getDataType(d.aggregateKey) === DataTypes.Numeric);
1808
+ });
1809
+ if (this.chartComponentData.stickiedKey == null)
1810
+ return numericFiltered;
1811
+ return numericFiltered.filter(function (d) {
1812
+ return d.aggregateKey == _this.chartComponentData.stickiedKey.aggregateKey &&
1813
+ ((_this.chartComponentData.stickiedKey.splitBy == null) ? true :
1814
+ d.splitBy == _this.chartComponentData.stickiedKey.splitBy);
1815
+ });
1816
+ };
1817
+ LineChart.prototype.getHandleHeight = function () {
1818
+ return Math.min(Math.max(this.chartHeight / 2, 24), this.chartHeight + 8);
1819
+ };
1820
+ LineChart.prototype.getXPosition = function (d, x) {
1821
+ var bucketSize = this.chartComponentData.displayState[d.aggregateKey].bucketSize;
1822
+ if (bucketSize)
1823
+ return (x(d.dateTime) + x((new Date(d.dateTime.valueOf() + bucketSize)))) / 2;
1824
+ return x(d.dateTime);
1825
+ };
1826
+ LineChart.prototype.setBrushStartTime = function (startTime) {
1827
+ this.brushStartTime = startTime;
1828
+ };
1829
+ LineChart.prototype.setBrushEndTime = function (endTime) {
1830
+ this.brushEndTime = endTime;
1831
+ };
1832
+ LineChart.prototype.setBrush = function () {
1833
+ if (this.brushStartTime && this.brushEndTime && this.brushElem && this.brush) {
1834
+ var rawLeftSide = this.x(this.brushStartTime);
1835
+ var rawRightSide = this.x(this.brushEndTime);
1836
+ //if selection is out of range of brush. clear brush
1837
+ this.brushElem.call(this.brush.move, null);
1838
+ if ((rawRightSide < this.xOffset) || (rawLeftSide > (this.chartWidth - (2 * this.xOffset)))) {
1839
+ this.isClearingBrush = true;
1840
+ this.brushElem.call(this.brush.move, null);
1841
+ return;
1842
+ }
1843
+ var leftSide = Math.min(this.chartWidth - (2 * this.xOffset), Math.max(this.xOffset, this.x(this.brushStartTime)));
1844
+ var rightSide = Math.min(this.chartWidth - (2 * this.xOffset), Math.max(this.xOffset, this.x(this.brushEndTime)));
1845
+ this.surpressBrushTimeSet = true;
1846
+ this.brushStartPosition = leftSide;
1847
+ this.brushEndPosition = rightSide;
1848
+ //small adjusetment so that width is always at least 1 pixel
1849
+ if (rightSide - leftSide < 1) {
1850
+ if (rightSide + 1 > this.chartWidth - (2 * this.xOffset)) {
1851
+ leftSide += -1;
1852
+ }
1853
+ else {
1854
+ rightSide += 1;
1855
+ }
1856
+ }
1857
+ this.brushElem.call(this.brush.move, [leftSide, rightSide]);
1858
+ }
1859
+ };
1860
+ LineChart.prototype.findClosestValidTime = function (rawMillis) {
1861
+ var minDiff = Infinity;
1862
+ return Object.keys(this.chartComponentData.timeMap).reduce(function (closestValue, currValue) {
1863
+ var diff = Math.abs(Number(currValue) - rawMillis);
1864
+ if (diff < minDiff) {
1865
+ minDiff = diff;
1866
+ return Number(currValue);
1867
+ }
1868
+ return closestValue;
1869
+ }, Infinity);
1870
+ };
1871
+ LineChart.prototype.getMarkerMarginLeft = function () {
1872
+ var legendWidth = this.legendObject.legendElement.node().getBoundingClientRect().width;
1873
+ return this.chartMargins.left + (this.chartOptions.legend === "shown" || this.chartOptions.legend === "hidden" ? legendWidth : 0) +
1874
+ (this.chartOptions.legend === "shown" ? this.GUTTERWIDTH : 0);
1875
+ };
1876
+ LineChart.prototype.exportMarkers = function () {
1877
+ var _this = this;
1878
+ this.chartOptions.markers = Object.keys(this.markerGuidMap)
1879
+ .filter(function (markerGuid) { return !_this.activeMarker || _this.activeMarker.getGuid() !== markerGuid; })
1880
+ .map(function (markerGuid) { return [_this.markerGuidMap[markerGuid].getMillis(), _this.markerGuidMap[markerGuid].getLabelText()]; });
1881
+ this.chartOptions.onMarkersChange(this.chartOptions.markers);
1882
+ };
1883
+ LineChart.prototype.createOnMarkerChange = function (markerGuid, marker) {
1884
+ var _this = this;
1885
+ return function (isDeleting, droppedMarker, shouldSort) {
1886
+ if (shouldSort === void 0) { shouldSort = true; }
1887
+ if (droppedMarker) {
1888
+ _this.markerGuidMap[markerGuid] = marker;
1889
+ }
1890
+ else if (isDeleting) {
1891
+ delete _this.markerGuidMap[markerGuid];
1892
+ //set focus to first marker if markers exist on delete
1893
+ var visibleMarkers = Object.values(_this.markerGuidMap).filter(function (marker) {
1894
+ return marker.isMarkerInRange();
1895
+ });
1896
+ if (visibleMarkers.length !== 0) {
1897
+ visibleMarkers[0].focusCloseButton();
1898
+ }
1899
+ else {
1900
+ _this.focusOnEllipsis();
1901
+ }
1902
+ }
1903
+ _this.exportMarkers();
1904
+ if (shouldSort)
1905
+ _this.sortMarkers();
1906
+ };
1907
+ };
1908
+ LineChart.prototype.renderMarker = function (marker, millis, onChange, labelText, isSeriesLabels) {
1909
+ if (onChange === void 0) { onChange = null; }
1910
+ if (labelText === void 0) { labelText = null; }
1911
+ if (isSeriesLabels === void 0) { isSeriesLabels = false; }
1912
+ marker.render(millis, this.chartOptions, this.chartComponentData, {
1913
+ chartMargins: this.chartMargins,
1914
+ x: this.x,
1915
+ marginLeft: this.getMarkerMarginLeft() + (isSeriesLabels ? this.getAdditionalOffsetFromHorizontalMargin() : 0),
1916
+ colorMap: this.colorMap,
1917
+ yMap: this.yMap,
1918
+ onChange: onChange,
1919
+ chartHeight: this.height,
1920
+ isDropping: false,
1921
+ labelText: labelText,
1922
+ isSeriesLabels: isSeriesLabels
1923
+ });
1924
+ };
1925
+ LineChart.prototype.sortMarkers = function () {
1926
+ d3.select(this.renderTarget).selectAll(".tsi-markerContainer").sort(function (a, b) {
1927
+ return (a.timestamp < b.timestamp) ? 1 : -1;
1928
+ });
1929
+ };
1930
+ LineChart.prototype.getAllLinesTransitionsComplete = function () {
1931
+ var _this = this;
1932
+ return new Promise(function (resolve, reject) {
1933
+ var checkAllLines = function (numberOfAttempts) {
1934
+ if (numberOfAttempts === void 0) { numberOfAttempts = 0; }
1935
+ if (numberOfAttempts < 5) {
1936
+ setTimeout(function () {
1937
+ var allOutOfTransition = true;
1938
+ d3.select(_this.renderTarget).selectAll('.tsi-gapLine').data().forEach(function (d) {
1939
+ allOutOfTransition = allOutOfTransition && !d.inTransition;
1940
+ });
1941
+ d3.select(_this.renderTarget).selectAll('.tsi-valueLine').data().forEach(function (d) {
1942
+ allOutOfTransition = allOutOfTransition && !d.inTransition;
1943
+ });
1944
+ if (allOutOfTransition) {
1945
+ resolve(null);
1946
+ }
1947
+ else {
1948
+ checkAllLines(numberOfAttempts + 1);
1949
+ }
1950
+ }, Math.max(_this.TRANSDURATION, 250));
1951
+ }
1952
+ else {
1953
+ reject();
1954
+ }
1955
+ };
1956
+ checkAllLines(0);
1957
+ });
1958
+ };
1959
+ LineChart.prototype.importMarkers = function () {
1960
+ var _this = this;
1961
+ if (this.chartOptions.markers && this.chartOptions.markers.length > 0) {
1962
+ // delete all the old markers
1963
+ if (Object.keys(this.markerGuidMap).length) {
1964
+ Object.keys(this.markerGuidMap).forEach(function (guid) {
1965
+ _this.markerGuidMap[guid].destroyMarker();
1966
+ delete _this.markerGuidMap[guid];
1967
+ });
1968
+ }
1969
+ this.markerGuidMap = {};
1970
+ this.chartOptions.markers.forEach(function (markerValueTuples, markerIndex) {
1971
+ if (markerValueTuples === null || markerValueTuples === undefined) {
1972
+ return;
1973
+ }
1974
+ var marker = new Marker(_this.renderTarget);
1975
+ var markerUID = Utils.guid();
1976
+ var markerMillis;
1977
+ if (typeof markerValueTuples === 'number') {
1978
+ markerMillis = markerValueTuples;
1979
+ marker.setLabelText("".concat(_this.getString('Marker'), " ").concat(markerIndex + 1));
1980
+ }
1981
+ else {
1982
+ marker.setLabelText(markerValueTuples[1]);
1983
+ markerMillis = markerValueTuples[0];
1984
+ }
1985
+ marker.setMillis(markerMillis);
1986
+ _this.markerGuidMap[markerUID] = marker;
1987
+ });
1988
+ this.renderAllMarkers();
1989
+ this.sortMarkers();
1990
+ }
1991
+ };
1992
+ LineChart.prototype.createSeriesLabelsMarker = function () {
1993
+ this.seriesLabelsMarker = new Marker(this.renderTarget);
1994
+ };
1995
+ LineChart.prototype.renderSeriesLabelsMarker = function () {
1996
+ if (this.chartOptions.labelSeriesWithMarker) {
1997
+ this.renderMarker(this.seriesLabelsMarker, this.x.domain()[1], function () { }, null, true);
1998
+ }
1999
+ };
2000
+ LineChart.prototype.renderAllMarkers = function () {
2001
+ var _this = this;
2002
+ this.getAllLinesTransitionsComplete().then(function () {
2003
+ Object.keys(_this.markerGuidMap).forEach(function (guid) {
2004
+ var marker = _this.markerGuidMap[guid];
2005
+ var onChange = _this.createOnMarkerChange(guid, marker);
2006
+ _this.renderMarker(marker, marker.getMillis(), onChange);
2007
+ });
2008
+ if (_this.seriesLabelsMarker) {
2009
+ _this.renderSeriesLabelsMarker();
2010
+ }
2011
+ });
2012
+ };
2013
+ LineChart.prototype.focusOnEllipsis = function () {
2014
+ if (this.ellipsisContainer !== null) {
2015
+ this.ellipsisContainer.select(".tsi-ellipsisButton").node().focus();
2016
+ }
2017
+ };
2018
+ LineChart.prototype.voronoiExists = function () {
2019
+ return (this.getVisibleNumerics() !== 0);
2020
+ };
2021
+ LineChart.prototype.voronoiMousemove = function (mouseEvent) {
2022
+ if (!this.filteredValueExist() || !this.voronoiExists())
2023
+ return;
2024
+ this.mx = mouseEvent[0];
2025
+ this.my = mouseEvent[1];
2026
+ var mx = mouseEvent[0]; mouseEvent[1];
2027
+ var site = this.voronoiDiagram.find(this.mx, this.my);
2028
+ if (!this.isDroppingMarker) {
2029
+ this.voronoiMouseover(site.data);
2030
+ }
2031
+ else {
2032
+ var rawTime = this.x.invert(mx);
2033
+ var closestTime = Utils.findClosestTime(rawTime.valueOf(), this.chartComponentData.timeMap);
2034
+ this.renderMarker(this.activeMarker, closestTime);
2035
+ return;
2036
+ }
2037
+ if (site.data.aggregateKey !== this.focusedAggKey || site.data.splitBy !== this.focusedSplitby) {
2038
+ var selectedFilter = Utils.createValueFilter(site.data.aggregateKey, site.data.splitBy);
2039
+ this.focusMarkerLabel(selectedFilter, site.data.aggregateKey, site.data.splitBy);
2040
+ this.focusOnlyHoveredSeries(site.data.aggregateKey, site.data.splitBy, true);
2041
+ }
2042
+ };
2043
+ LineChart.prototype.voronoiContextMenu = function (d3Event, mouseEvent) {
2044
+ if (!this.filteredValueExist() || !this.voronoiExists())
2045
+ return;
2046
+ var _a = d3.pointer(d3Event, mouseEvent), mx = _a[0], my = _a[1];
2047
+ var site = this.voronoiDiagram.find(mx, my);
2048
+ if (this.chartComponentData.displayState[site.data.aggregateKey].contextMenuActions &&
2049
+ this.chartComponentData.displayState[site.data.aggregateKey].contextMenuActions.length) {
2050
+ var mousePosition = d3.pointer(d3Event, this.targetElement.node());
2051
+ var sitePageCoords = void 0;
2052
+ if (this.hasBrush) {
2053
+ sitePageCoords = this.brushElem.node().getBoundingClientRect();
2054
+ }
2055
+ else {
2056
+ sitePageCoords = this.voronoiRegion.node().getBoundingClientRect();
2057
+ }
2058
+ var eventSite = { pageX: sitePageCoords.left + site[0], pageY: sitePageCoords.top + site[1] - 12 };
2059
+ d3Event.preventDefault();
2060
+ this.contextMenu.draw(this.chartComponentData, this.renderTarget, this.chartOptions, mousePosition, site.data.aggregateKey, site.data.splitBy, null, site.data.dateTime, null, eventSite);
2061
+ if (this.brushContextMenu) {
2062
+ this.brushContextMenu.hide();
2063
+ }
2064
+ this.voronoiMouseover(site.data);
2065
+ }
2066
+ };
2067
+ LineChart.prototype.voronoiClick = function (d3Event, mouseEvent) {
2068
+ var _this = this;
2069
+ //supress if the context menu is visible
2070
+ if (this.contextMenu && this.contextMenu.contextMenuVisible)
2071
+ return;
2072
+ if (!this.filteredValueExist() || !this.voronoiExists())
2073
+ return;
2074
+ if (this.brushElem && !this.isDroppingMarker)
2075
+ return;
2076
+ var _a = d3.pointer(d3Event, mouseEvent), mx = _a[0], my = _a[1];
2077
+ var site = this.voronoiDiagram.find(mx, my);
2078
+ var cDO = this.getCDOFromAggKey(site.data.aggregateKey);
2079
+ if (!this.isDroppingMarker) {
2080
+ if (site.data && cDO.onElementClick !== null) {
2081
+ cDO.onElementClick(site.data.aggregateKey, site.data.splitBy, site.data.dateTime.toISOString(), site.data.measures);
2082
+ }
2083
+ else {
2084
+ if (this.chartComponentData.stickiedKey !== null) {
2085
+ site = this.voronoiDiagram.find(mx, my);
2086
+ this.voronoiMousemove(site.data);
2087
+ this.unstickySeries(site.data.aggregateKey, site.data.splitBy);
2088
+ return;
2089
+ }
2090
+ this.stickySeries(site.data.aggregateKey, site.data.splitBy);
2091
+ }
2092
+ }
2093
+ else {
2094
+ if (!this.hasBrush) {
2095
+ this.isDroppingMarker = false;
2096
+ }
2097
+ }
2098
+ this.destroyMarkerInstructions();
2099
+ if (Utils.safeNotNullOrUndefined(function () { return _this.activeMarker; })) {
2100
+ this.activeMarker.onChange(false, true);
2101
+ this.exportMarkers();
2102
+ this.activeMarker = null;
2103
+ }
2104
+ };
2105
+ LineChart.prototype.getValueOfVisible = function (d) {
2106
+ return Utils.getValueOfVisible(d, this.chartComponentData.getVisibleMeasure(d.aggregateKey, d.splitBy));
2107
+ };
2108
+ LineChart.prototype.brushBrush = function (event) {
2109
+ var handleHeight = this.getHandleHeight();
2110
+ this.brushElem.selectAll('.handle')
2111
+ .attr('height', handleHeight)
2112
+ .attr('y', (this.chartHeight - handleHeight) / 2);
2113
+ if (!event.sourceEvent) {
2114
+ return;
2115
+ }
2116
+ if (event.sourceEvent && event.sourceEvent.type === 'mousemove') {
2117
+ this.brushElem.select(".selection").attr("visibility", "visible");
2118
+ //check boundary conditions for width of the brush
2119
+ if (event.selection[1] - event.selection[0] < this.minBrushWidth) {
2120
+ return;
2121
+ }
2122
+ else {
2123
+ this.brushElem.selectAll(".handle").attr("visibility", "visible");
2124
+ }
2125
+ }
2126
+ if (this.surpressBrushTimeSet == true) {
2127
+ this.surpressBrushTimeSet = false;
2128
+ return;
2129
+ }
2130
+ if (!event.selection)
2131
+ return;
2132
+ if (this.contextMenu)
2133
+ this.contextMenu.hide();
2134
+ if (this.brushContextMenu)
2135
+ this.brushContextMenu.hide();
2136
+ var newBrushStartPosition = event.selection[0];
2137
+ var newBrushEndPosition = event.selection[1];
2138
+ if (newBrushStartPosition != this.brushStartPosition) {
2139
+ this.brushStartTime = this.x.invert(event.selection[0]);
2140
+ this.brushStartPosition = newBrushStartPosition;
2141
+ }
2142
+ if (newBrushEndPosition != this.brushEndPosition) {
2143
+ this.brushEndTime = this.x.invert(event.selection[1]);
2144
+ this.brushEndPosition = newBrushEndPosition;
2145
+ }
2146
+ if (this.chartOptions.brushMoveAction) {
2147
+ this.chartOptions.brushMoveAction(this.brushStartTime, this.brushEndTime);
2148
+ }
2149
+ };
2150
+ LineChart.prototype.brushEnd = function (d3Event, mouseEvent) {
2151
+ var _this = this;
2152
+ if (this.isClearingBrush) {
2153
+ this.isClearingBrush = false;
2154
+ if (this.brushContextMenu) {
2155
+ this.brushContextMenu.hide();
2156
+ }
2157
+ return;
2158
+ }
2159
+ if (d3Event && d3Event.selection == null && d3Event.sourceEvent && d3Event.sourceEvent.type == "mouseup" && this.chartOptions.minBrushWidth == 0) {
2160
+ if (this.brushContextMenu) {
2161
+ this.brushContextMenu.hide();
2162
+ }
2163
+ var _a = d3.pointer(d3Event, mouseEvent), mx = _a[0], my = _a[1];
2164
+ var site = this.voronoiDiagram.find(mx, my);
2165
+ var isClearingBrush = (this.brushStartPosition !== null) && (this.brushEndPosition !== null);
2166
+ if (this.chartComponentData.stickiedKey !== null && !this.isDroppingMarker && !isClearingBrush) {
2167
+ this.chartComponentData.stickiedKey = null;
2168
+ this.legendObject.legendElement.selectAll('.tsi-splitByLabel').classed("stickied", false);
2169
+ // recompute voronoi with no sticky
2170
+ this.voronoiDiagram = this.voronoi(this.getFilteredAndSticky(this.chartComponentData.allValues));
2171
+ site = this.voronoiDiagram.find(mx, my);
2172
+ this.voronoiMousemove(site.data);
2173
+ this.chartOptions.onUnsticky(site.data.aggregateKey, site.data.splitBy);
2174
+ return;
2175
+ }
2176
+ this.brushStartTime = null;
2177
+ this.brushEndTime = null;
2178
+ this.brushStartPosition = null;
2179
+ this.brushEndPosition = null;
2180
+ if (!this.isDroppingMarker && !isClearingBrush && !(this.contextMenu && this.contextMenu.contextMenuVisible)) {
2181
+ this.stickySeries(site.data.aggregateKey, site.data.splitBy);
2182
+ }
2183
+ else {
2184
+ this.isDroppingMarker = false;
2185
+ }
2186
+ return;
2187
+ }
2188
+ if (d3Event.selection == null) {
2189
+ if (!this.chartOptions.brushClearable) {
2190
+ d3.select(mouseEvent).transition().call(d3Event.target.move, [this.x(this.brushStartTime), this.x(this.brushEndTime)]);
2191
+ }
2192
+ return;
2193
+ }
2194
+ var transformCall = null; //if the brush needs to be transformed due to snap brush or it being too small, this is envoked
2195
+ var isZeroWidth = false; //clear the brush context menu if the brush has 0 width
2196
+ if (this.chartOptions.snapBrush) {
2197
+ //find the closest possible value and set to that
2198
+ if (this.possibleTimesArray.length > 0) {
2199
+ var findClosestTime = function (rawXValue) {
2200
+ var closestDate = null;
2201
+ _this.possibleTimesArray.reduce(function (prev, curr) {
2202
+ var prospectiveDiff = Math.abs(rawXValue - _this.x(curr));
2203
+ var currBestDiff = Math.abs(rawXValue - prev);
2204
+ if (prospectiveDiff < currBestDiff) {
2205
+ closestDate = curr;
2206
+ return _this.x(curr);
2207
+ }
2208
+ return prev;
2209
+ }, Infinity);
2210
+ return closestDate;
2211
+ };
2212
+ var newBrushStartTime = findClosestTime(d3Event.selection[0]);
2213
+ var newBrushEndTime = findClosestTime(d3Event.selection[1]);
2214
+ if (newBrushStartTime != this.brushStartTime || newBrushEndTime != this.brushEndTime) {
2215
+ this.brushStartTime = newBrushStartTime;
2216
+ this.brushEndTime = newBrushEndTime;
2217
+ this.brushStartPosition = this.x(this.brushStartTime);
2218
+ this.brushEndPosition = this.x(this.brushEndTime);
2219
+ transformCall = function () { return d3.select(mouseEvent).transition().call(d3Event.target.move, [_this.x(_this.brushStartTime), _this.x(_this.brushEndTime)]); };
2220
+ isZeroWidth = this.x(this.brushStartTime) == this.x(this.brushEndTime);
2221
+ }
2222
+ }
2223
+ }
2224
+ if (d3Event.selection[1] - d3Event.selection[0] < this.minBrushWidth) {
2225
+ var rightSide_1 = Math.min(d3Event.selection[0] + this.minBrushWidth, this.x.range()[1]);
2226
+ transformCall = function () { return d3.select(mouseEvent).transition().call(d3Event.target.move, [rightSide_1 - _this.minBrushWidth, rightSide_1]); };
2227
+ isZeroWidth = (rightSide_1 - this.minBrushWidth == rightSide_1);
2228
+ }
2229
+ if (this.chartOptions.brushMoveEndAction && (d3Event.sourceEvent && d3Event.sourceEvent.type == 'mouseup')) {
2230
+ this.chartOptions.brushMoveEndAction(this.brushStartTime, this.brushEndTime);
2231
+ }
2232
+ if (this.chartOptions.brushContextMenuActions && this.chartOptions.autoTriggerBrushContextMenu &&
2233
+ (d3Event.sourceEvent && d3Event.sourceEvent.type == 'mouseup')) {
2234
+ if (!this.chartOptions.brushContextMenuActions || this.chartOptions.brushContextMenuActions.length == 0)
2235
+ return;
2236
+ var mousePosition = d3.pointer(d3Event, this.targetElement.node());
2237
+ //constrain the mouse position to the renderTarget
2238
+ var boundingCRect = this.targetElement.node().getBoundingClientRect();
2239
+ var correctedMousePositionX = Math.min(boundingCRect.width, Math.max(mousePosition[0], 0));
2240
+ var correctedMousePositionY = Math.min(boundingCRect.height, Math.max(mousePosition[1], 0));
2241
+ var correctedMousePosition = [correctedMousePositionX, correctedMousePositionY];
2242
+ this.brushContextMenu.draw(this.chartComponentData, this.renderTarget, this.chartOptions, correctedMousePosition, null, null, null, this.brushStartTime, this.brushEndTime);
2243
+ }
2244
+ if (transformCall) {
2245
+ transformCall();
2246
+ if (this.brushContextMenu && isZeroWidth) {
2247
+ this.brushContextMenu.hide();
2248
+ }
2249
+ }
2250
+ };
2251
+ LineChart.prototype.focusMarkerLabel = function (filterFunction, aggKey, splitBy) {
2252
+ Utils.revertAllSubtitleText(d3.select(this.renderTarget).selectAll(".tsi-markerValue"), .2);
2253
+ d3.select(this.renderTarget).selectAll(".tsi-markerValue")
2254
+ .filter(filterFunction)
2255
+ .style("opacity", 1)
2256
+ .classed('tsi-isExpanded', true)
2257
+ .each(function () {
2258
+ Utils.setSeriesLabelSubtitleText(d3.select(this).selectAll('.tsi-tooltipSubtitle'), true);
2259
+ });
2260
+ d3.select(this.renderTarget).selectAll(".tsi-markerContainer").each(function () {
2261
+ d3.select(this).selectAll(".tsi-markerValue").sort(function (a, b) {
2262
+ return (a.aggregateKey == aggKey && (splitBy == null || splitBy == a.splitBy)) ? 1 : -1;
2263
+ });
2264
+ });
2265
+ };
2266
+ LineChart.prototype.drawBrushRange = function () {
2267
+ if (this.chartOptions.brushRangeVisible) {
2268
+ if (this.targetElement.select('.tsi-rangeTextContainer').empty() && (this.brushStartTime || this.brushEndTime)) {
2269
+ this.targetElement.append("div")
2270
+ .attr("class", "tsi-rangeTextContainer");
2271
+ }
2272
+ this.updateBrushRange();
2273
+ }
2274
+ };
2275
+ LineChart.prototype.getSVGLeftOffset = function () {
2276
+ return this.chartOptions.legend === 'shown' ? (this.width - this.svgSelection.node().getBoundingClientRect().width) : 0;
2277
+ };
2278
+ LineChart.prototype.updateBrushRange = function () {
2279
+ var svgLeftOffset = this.getSVGLeftOffset();
2280
+ if (!(this.brushStartTime || this.brushEndTime)) {
2281
+ this.deleteBrushRange();
2282
+ return;
2283
+ }
2284
+ var rangeText = Utils.rangeTimeFormat(this.brushEndTime.valueOf() - this.brushStartTime.valueOf());
2285
+ var rangeTextContainer = this.targetElement.select('.tsi-rangeTextContainer');
2286
+ var leftPos = this.chartMargins.left +
2287
+ Math.min(Math.max(0, this.x(this.brushStartTime)), this.x.range()[1]) + svgLeftOffset;
2288
+ var rightPos = this.chartMargins.left +
2289
+ Math.min(Math.max(0, this.x(this.brushEndTime)), this.x.range()[1]) + svgLeftOffset;
2290
+ rangeTextContainer
2291
+ .text(rangeText)
2292
+ .style("left", Math.max(8, Math.round((leftPos + rightPos) / 2)) + "px")
2293
+ .style("top", (this.chartMargins.top + this.chartOptions.aggTopMargin) + 'px');
2294
+ if (this.chartOptions.color) {
2295
+ rangeTextContainer
2296
+ .style('background-color', this.chartOptions.color)
2297
+ .style('color', 'white');
2298
+ }
2299
+ var calcedWidth = rangeTextContainer.node().getBoundingClientRect().width;
2300
+ if (this.chartOptions.isCompact && (rightPos - leftPos) < calcedWidth) {
2301
+ rangeTextContainer.style('visibility', 'hidden');
2302
+ }
2303
+ else {
2304
+ rangeTextContainer.style('visibility', 'visible');
2305
+ }
2306
+ };
2307
+ LineChart.prototype.deleteBrushRange = function () {
2308
+ this.targetElement.select('.tsi-rangeTextContainer').remove();
2309
+ };
2310
+ LineChart.prototype.getYExtents = function () {
2311
+ return this.chartComponentData.yExtents;
2312
+ };
2313
+ LineChart.prototype.clearBrush = function () {
2314
+ this.svgSelection.select('.svgGroup').select(".brushElem").call(this.brush.move, null);
2315
+ this.deleteBrushRange();
2316
+ if (this.brushContextMenu) {
2317
+ this.brushContextMenu.hide();
2318
+ }
2319
+ };
2320
+ LineChart.prototype.getVisibleNumerics = function () {
2321
+ var _this = this;
2322
+ var visibleGroups = this.data.filter(function (agg) { return _this.chartComponentData.displayState[agg.aggKey]["visible"]; });
2323
+ var visibleCDOs = this.aggregateExpressionOptions.filter(function (cDO) { return _this.chartComponentData.displayState[cDO.aggKey]["visible"]; });
2324
+ return visibleGroups.filter(function (aggKey, i) {
2325
+ return visibleCDOs[i].dataType === DataTypes.Numeric;
2326
+ }).length;
2327
+ };
2328
+ LineChart.prototype.getSwimlaneOffsets = function (linechartTopPadding, visibleGroups, visibleCDOs, heightPerNumeric, swimLaneSet) {
2329
+ var _this = this;
2330
+ var cumulativeOffset = LINECHARTTOPPADDING;
2331
+ //initialize to null and set while going through swimLanes
2332
+ var visibleGroupEndValues = visibleGroups.map(function () { return null; });
2333
+ Object.keys(swimLaneSet).sort(function (a, b) { return (Number(a) <= Number(b) ? -1 : 1); }).forEach(function (swimLaneStr) {
2334
+ // find all numerics and set to cumulative offset/height per non numeric
2335
+ var swimlane = Number(swimLaneStr);
2336
+ var hasNumeric = false;
2337
+ visibleCDOs.forEach(function (aggGroup, i) {
2338
+ if (aggGroup.swimLane === swimlane && aggGroup.dataType === DataTypes.Numeric) {
2339
+ hasNumeric = true;
2340
+ visibleGroupEndValues[i] = [cumulativeOffset, heightPerNumeric];
2341
+ }
2342
+ });
2343
+ // find all non-numerics and set their offset/heights
2344
+ var swimLaneOffset = hasNumeric ? heightPerNumeric : 0;
2345
+ if (_this.chartOptions.swimLaneOptions && _this.chartOptions.swimLaneOptions[swimlane] && _this.chartOptions.swimLaneOptions[swimlane].collapseEvents) {
2346
+ swimLaneOffset += _this.getEventsCollapsedSwimlaneHeight(visibleCDOs, swimlane);
2347
+ visibleCDOs.forEach(function (aggGroup, i) {
2348
+ if (aggGroup.swimLane === swimlane) {
2349
+ visibleGroupEndValues[i] = [cumulativeOffset, _this.getEventsCollapsedSwimlaneHeight(visibleCDOs, swimlane)];
2350
+ }
2351
+ });
2352
+ }
2353
+ else {
2354
+ visibleCDOs.forEach(function (aggGroup, i) {
2355
+ if (aggGroup.swimLane === swimlane && aggGroup.dataType !== DataTypes.Numeric) {
2356
+ var currGroupsHeight_1 = Utils.getNonNumericHeight(aggGroup.height);
2357
+ visibleGroupEndValues[i] = [swimLaneOffset + cumulativeOffset, currGroupsHeight_1];
2358
+ swimLaneOffset += currGroupsHeight_1;
2359
+ }
2360
+ });
2361
+ }
2362
+ cumulativeOffset += swimLaneOffset;
2363
+ });
2364
+ return visibleGroupEndValues;
2365
+ };
2366
+ LineChart.prototype.setSwimLaneYExtents = function (visibleGroups, visibleCDOs, swimLanes, swimLaneOptions) {
2367
+ var _this = this;
2368
+ var extents = {};
2369
+ swimLanes.forEach(function (lane) {
2370
+ var extent = [];
2371
+ // Check if swim lane options sets y-axis extents for this lane. If so use that
2372
+ // value for yExtents.
2373
+ if (swimLaneOptions && swimLaneOptions[lane] && swimLaneOptions[lane].yExtent) {
2374
+ extents[lane] = swimLaneOptions[lane].yExtent;
2375
+ return;
2376
+ }
2377
+ visibleGroups.forEach(function (aggGroup, i) {
2378
+ var cDO = visibleCDOs[i];
2379
+ if (cDO.dataType !== DataTypes.Numeric) {
2380
+ return;
2381
+ }
2382
+ var aggValues = [];
2383
+ if (cDO.swimLane === lane) {
2384
+ var aggKey_1 = cDO.aggKey;
2385
+ Object.keys(_this.chartComponentData.visibleTAs[aggKey_1]).forEach(function (splitBy) {
2386
+ aggValues = aggValues.concat(_this.chartComponentData.visibleTAs[aggKey_1][splitBy]);
2387
+ });
2388
+ var yExtent = _this.getYExtent(aggValues, _this.chartComponentData.displayState[aggKey_1].includeEnvelope ?
2389
+ _this.chartComponentData.displayState[aggKey_1].includeEnvelope :
2390
+ _this.chartOptions.includeEnvelope, aggKey_1);
2391
+ extent = d3.extent(yExtent.concat(extent));
2392
+ extents[lane] = extent;
2393
+ }
2394
+ });
2395
+ });
2396
+ this.swimlaneYExtents = extents;
2397
+ };
2398
+ LineChart.prototype.getEventsCollapsedSwimlaneHeight = function (visibleCDOs, swimlane) {
2399
+ // if a swimlane has collapsed events, the events height impact is the largest height of a visible events group in the swimlane
2400
+ var rawHeight = visibleCDOs.reduce(function (tallest, currGroup) {
2401
+ if (currGroup.dataType === DataTypes.Events && currGroup.swimLane === swimlane) {
2402
+ return Math.max(tallest, currGroup.height);
2403
+ }
2404
+ return tallest;
2405
+ }, 0);
2406
+ return rawHeight !== 0 ? Utils.getNonNumericHeight(rawHeight) : 0;
2407
+ };
2408
+ //returns an array of tuples of y offset and height for each visible aggregate group
2409
+ LineChart.prototype.createYOffsets = function () {
2410
+ var _this = this;
2411
+ var visibleGroups = this.data.filter(function (agg) { return _this.chartComponentData.displayState[agg.aggKey]["visible"]; });
2412
+ var visibleCDOs = this.aggregateExpressionOptions.filter(function (cDO) { return _this.chartComponentData.displayState[cDO.aggKey]["visible"]; });
2413
+ var visibleNumericCount;
2414
+ var swimLaneSet = {};
2415
+ visibleCDOs.forEach(function (aEO, i) {
2416
+ if (aEO.swimLane === null) {
2417
+ aEO.swimLane = i + 1;
2418
+ }
2419
+ });
2420
+ visibleCDOs.forEach(function (cDO) {
2421
+ swimLaneSet[cDO.swimLane] = swimLaneSet[cDO.swimLane] || (cDO.dataType === DataTypes.Numeric);
2422
+ });
2423
+ visibleNumericCount = Object.keys(swimLaneSet).reduce(function (visibleCount, swimLane) {
2424
+ return visibleCount + (swimLaneSet[swimLane] ? 1 : 0);
2425
+ }, 0);
2426
+ var countNumericLanes = visibleNumericCount;
2427
+ var linechartTopPadding = this.chartOptions.isArea ? 0 : LINECHARTTOPPADDING;
2428
+ var useableHeight = this.chartHeight - linechartTopPadding;
2429
+ var fixedEventsHeight = 0;
2430
+ if (this.chartOptions.swimLaneOptions) {
2431
+ Object.keys(this.chartOptions.swimLaneOptions).forEach(function (swimlaneKey) {
2432
+ var swimlane = Number(swimlaneKey);
2433
+ var sLO = _this.chartOptions.swimLaneOptions[swimlane];
2434
+ if (sLO.collapseEvents) {
2435
+ var swimlaneHeight = _this.getEventsCollapsedSwimlaneHeight(visibleCDOs, swimlane);
2436
+ fixedEventsHeight += swimlaneHeight;
2437
+ }
2438
+ });
2439
+ }
2440
+ var heightNonNumeric = visibleCDOs.reduce(function (sumPrevious, currGroup, i) {
2441
+ if (currGroup.dataType === DataTypes.Events && _this.chartOptions.swimLaneOptions && _this.chartOptions.swimLaneOptions[currGroup.swimLane] && _this.chartOptions.swimLaneOptions[currGroup.swimLane].collapseEvents) {
2442
+ return sumPrevious;
2443
+ }
2444
+ return sumPrevious + (currGroup.dataType !== DataTypes.Numeric ? Utils.getNonNumericHeight(currGroup.height) : 0);
2445
+ }, 0);
2446
+ heightNonNumeric += fixedEventsHeight;
2447
+ var heightPerNumeric = (useableHeight - heightNonNumeric) / countNumericLanes;
2448
+ this.setSwimLaneYExtents(visibleGroups, visibleCDOs, Object.keys(swimLaneSet)
2449
+ .filter(function (lane) { return swimLaneSet[lane]; })
2450
+ .map(function (stringLane) { return Number(stringLane); }), this.chartOptions.swimLaneOptions);
2451
+ return this.getSwimlaneOffsets(linechartTopPadding, visibleGroups, visibleCDOs, heightPerNumeric, swimLaneSet);
2452
+ };
2453
+ LineChart.prototype.heightNonNumeric = function () {
2454
+ var _this = this;
2455
+ var visibleCDOs = this.aggregateExpressionOptions.filter(function (agg) { return _this.chartComponentData.displayState[agg.aggKey]["visible"]; });
2456
+ return visibleCDOs.reduce(function (sumPrevious, currGroup) {
2457
+ return sumPrevious + (currGroup.dataType !== DataTypes.Numeric ? Utils.getNonNumericHeight(currGroup.height) : 0);
2458
+ }, 0);
2459
+ };
2460
+ LineChart.prototype.getGroupYExtent = function (aggKey, aggVisible, aggValues, yExtent) {
2461
+ if ((this.chartOptions.yAxisState === YAxisStates.Shared) || (Object.keys(this.chartComponentData.timeArrays)).length < 2 || !aggVisible) {
2462
+ yExtent = this.getYExtent(this.chartComponentData.allNumericValues, this.chartComponentData.displayState[aggKey].includeEnvelope ?
2463
+ this.chartComponentData.displayState[aggKey].includeEnvelope :
2464
+ this.chartOptions.includeEnvelope, null);
2465
+ }
2466
+ else if (this.chartComponentData.aggHasVisibleSplitBys(aggKey)) {
2467
+ yExtent = this.getYExtent(aggValues, this.chartComponentData.displayState[aggKey].includeEnvelope ?
2468
+ this.chartComponentData.displayState[aggKey].includeEnvelope :
2469
+ this.chartOptions.includeEnvelope, aggKey);
2470
+ }
2471
+ else {
2472
+ yExtent = [0, 1];
2473
+ }
2474
+ return yExtent;
2475
+ };
2476
+ LineChart.prototype.getAggAxisType = function (agg) {
2477
+ if (this.chartOptions.yAxisState === YAxisStates.Stacked) {
2478
+ if (this.chartOptions.swimLaneOptions && this.chartOptions.swimLaneOptions[agg.swimLane] && this.chartOptions.swimLaneOptions[agg.swimLane].yAxisType) {
2479
+ return this.chartOptions.swimLaneOptions[agg.swimLane].yAxisType;
2480
+ }
2481
+ else {
2482
+ return YAxisStates.Shared;
2483
+ }
2484
+ }
2485
+ return this.chartOptions.yAxisState;
2486
+ };
2487
+ LineChart.prototype.adjustSwimLanes = function () {
2488
+ if (this.chartOptions.yAxisState === YAxisStates.Shared || this.chartOptions.yAxisState === YAxisStates.Overlap) {
2489
+ this.aggregateExpressionOptions.forEach(function (aEO) {
2490
+ aEO.swimLane = 0;
2491
+ });
2492
+ // consolidate horizontal markers
2493
+ if (this.chartOptions.swimLaneOptions) {
2494
+ var horizontalMarkers_1 = [];
2495
+ Object.values(this.chartOptions.swimLaneOptions).forEach(function (lane) {
2496
+ horizontalMarkers_1.push.apply(horizontalMarkers_1, lane.horizontalMarkers);
2497
+ });
2498
+ this.chartOptions.swimLaneOptions = { 0: { yAxisType: this.chartOptions.yAxisState, horizontalMarkers: horizontalMarkers_1 } };
2499
+ }
2500
+ }
2501
+ else {
2502
+ var minimumPresentSwimLane_1 = this.aggregateExpressionOptions.reduce(function (currMin, aEO) {
2503
+ return Math.max(aEO.swimLane, currMin);
2504
+ }, 0);
2505
+ this.aggregateExpressionOptions.forEach(function (aEO) {
2506
+ if (aEO.swimLane === null) {
2507
+ aEO.swimLane = ++minimumPresentSwimLane_1;
2508
+ }
2509
+ });
2510
+ }
2511
+ };
2512
+ LineChart.prototype.overwriteSwimLanes = function () {
2513
+ var _this = this;
2514
+ this.aggregateExpressionOptions.forEach(function (aEO, i) {
2515
+ _this.aggregateExpressionOptions[i].swimLane = _this.originalSwimLanes[i];
2516
+ });
2517
+ this.chartOptions.swimLaneOptions = this.originalSwimLaneOptions;
2518
+ };
2519
+ LineChart.prototype.getHorizontalMarkersWithYScales = function () {
2520
+ var _this = this;
2521
+ var visibleCDOs = this.aggregateExpressionOptions.filter(function (cDO) { return _this.chartComponentData.displayState[cDO.aggKey]["visible"]; });
2522
+ var markerList = [];
2523
+ var pushMarker = function (cDO, marker, markerList) {
2524
+ var _a, _b;
2525
+ if (_this.chartOptions.yAxisState === YAxisStates.Overlap) {
2526
+ return;
2527
+ }
2528
+ var domain = _this.chartOptions.yAxisState === YAxisStates.Stacked ?
2529
+ _this.swimlaneYExtents[cDO.swimLane] :
2530
+ _this.swimlaneYExtents[0];
2531
+ // filter out markers not in the y range of that lane and in lanes that have overlap axis
2532
+ if (domain &&
2533
+ ((_b = (_a = _this.chartOptions.swimLaneOptions) === null || _a === void 0 ? void 0 : _a[cDO.swimLane]) === null || _b === void 0 ? void 0 : _b.yAxisType) !== YAxisStates.Overlap &&
2534
+ marker.value >= domain[0] &&
2535
+ marker.value <= domain[1]) {
2536
+ markerList.push(__assign({ yScale: _this.yMap[cDO.aggKey] }, marker));
2537
+ }
2538
+ };
2539
+ visibleCDOs.forEach(function (cDO) {
2540
+ cDO.horizontalMarkers.forEach(function (horizontalMarkerParams) {
2541
+ pushMarker(cDO, horizontalMarkerParams, markerList);
2542
+ });
2543
+ });
2544
+ // find a visible CDO for a swimlane
2545
+ var findFirstVisibleCDO = function (swimlaneNumber) {
2546
+ return visibleCDOs.find(function (cDO) {
2547
+ return (cDO.swimLane === swimlaneNumber);
2548
+ });
2549
+ };
2550
+ if (this.chartOptions.yAxisState !== YAxisStates.Overlap && this.chartOptions.swimLaneOptions) {
2551
+ Object.keys(this.chartOptions.swimLaneOptions).forEach(function (swimlaneNumber) {
2552
+ var _a;
2553
+ var swimlaneOptions = _this.chartOptions.swimLaneOptions[swimlaneNumber];
2554
+ (_a = swimlaneOptions.horizontalMarkers) === null || _a === void 0 ? void 0 : _a.forEach(function (horizontalMarkerParams) {
2555
+ var firstVisibleCDO = findFirstVisibleCDO(Number(swimlaneNumber));
2556
+ if (firstVisibleCDO) {
2557
+ pushMarker(firstVisibleCDO, horizontalMarkerParams, markerList);
2558
+ }
2559
+ });
2560
+ });
2561
+ }
2562
+ return markerList;
2563
+ };
2564
+ // having horizontal markers present should add additional right hand margin to allow space for series labels
2565
+ LineChart.prototype.getAdditionalOffsetFromHorizontalMargin = function () {
2566
+ return this.getHorizontalMarkersWithYScales().length ? 16 : 0;
2567
+ };
2568
+ LineChart.prototype.drawHorizontalMarkers = function () {
2569
+ var markerList = this.getHorizontalMarkersWithYScales();
2570
+ var self = this;
2571
+ var markerContainers = this.svgSelection.select('.svgGroup').selectAll('.tsi-horizontalMarker')
2572
+ .data(markerList);
2573
+ markerContainers
2574
+ .enter()
2575
+ .append('g')
2576
+ .merge(markerContainers)
2577
+ .attr('class', 'tsi-horizontalMarker')
2578
+ .attr("transform", function (marker) {
2579
+ return "translate(" + 0 + "," + marker.yScale(marker.value) + ")";
2580
+ })
2581
+ .each(function (marker) {
2582
+ var valueText = d3.select(this)
2583
+ .selectAll('.tsi-horizontalMarkerText')
2584
+ .data([marker.value]);
2585
+ valueText
2586
+ .enter()
2587
+ .append('text')
2588
+ .merge(valueText)
2589
+ .attr('class', 'tsi-horizontalMarkerText')
2590
+ .attr('x', self.chartWidth)
2591
+ .attr('y', -4)
2592
+ .text(function (value) { return value; });
2593
+ valueText.exit().remove();
2594
+ var valueLine = d3.select(this)
2595
+ .selectAll('.tsi-horizontalMarkerLine')
2596
+ .data([marker]);
2597
+ valueLine
2598
+ .enter()
2599
+ .append('line')
2600
+ .merge(valueLine)
2601
+ .attr('class', 'tsi-horizontalMarkerLine')
2602
+ .attr('stroke', function (marker) { return marker.color; })
2603
+ .attr('x1', 0)
2604
+ .attr('y1', 0)
2605
+ .attr('x2', self.chartWidth)
2606
+ .attr('y2', 0);
2607
+ valueLine.exit().remove();
2608
+ });
2609
+ markerContainers.exit().remove();
2610
+ };
2611
+ LineChart.prototype.createSwimlaneLabels = function (offsetsAndHeights, visibleCDOs) {
2612
+ var _this = this;
2613
+ // swimLaneLabels object contains data needed to render each lane label
2614
+ var swimLaneLabels = {};
2615
+ /*
2616
+ The logic below constructs swimlane labels. The first aggregate found in each
2617
+ lane is used to position that lanes label. Numeric aggs are prioritized first,
2618
+ as they share a y-Axis, meaning only the first numeric in each lane needs to be
2619
+ considered. Next, non-numerics are checked, if they are the first agg found in
2620
+ their lane, their position data is used, otherwise, their height is added to the
2621
+ current height of the lane.
2622
+ */
2623
+ var useAggForLaneLabel = function (aggGroup) {
2624
+ var _a, _b, _c, _d, _e, _f;
2625
+ var swimLane = aggGroup.swimLane;
2626
+ var aggIndex = visibleCDOs.findIndex(function (el) { return el.aggKey === aggGroup.aggKey; });
2627
+ var onClick = null;
2628
+ if (typeof ((_c = (_b = (_a = _this.chartOptions) === null || _a === void 0 ? void 0 : _a.swimLaneOptions) === null || _b === void 0 ? void 0 : _b[swimLane]) === null || _c === void 0 ? void 0 : _c.onClick) === 'function') {
2629
+ onClick = function () { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = _this.chartOptions) === null || _a === void 0 ? void 0 : _a.swimLaneOptions) === null || _b === void 0 ? void 0 : _b[swimLane]) === null || _c === void 0 ? void 0 : _c.onClick) === null || _d === void 0 ? void 0 : _d.call(_c, swimLane); };
2630
+ }
2631
+ swimLaneLabels[swimLane] = {
2632
+ offset: offsetsAndHeights[aggIndex][0],
2633
+ height: offsetsAndHeights[aggIndex][1],
2634
+ label: (_f = (_e = (_d = _this.chartOptions) === null || _d === void 0 ? void 0 : _d.swimLaneOptions) === null || _e === void 0 ? void 0 : _e[swimLane]) === null || _f === void 0 ? void 0 : _f.label,
2635
+ onClick: onClick
2636
+ };
2637
+ };
2638
+ // First add numeric dataTypes (share Y-Axis) to label map
2639
+ visibleCDOs.filter(function (aggGroup) { return aggGroup.dataType === DataTypes.Numeric; }).forEach(function (aggGroup) {
2640
+ if (!(aggGroup.swimLane in swimLaneLabels)) { // Only add swimlanes once to swimLaneLabels map
2641
+ useAggForLaneLabel(aggGroup);
2642
+ }
2643
+ });
2644
+ // Then, map over any non-numeric dataType and increment heights if they're sharing a lane
2645
+ visibleCDOs.filter(function (aggGroup) { return aggGroup.dataType !== DataTypes.Numeric; }).forEach(function (aggGroup) {
2646
+ var _a, _b, _c;
2647
+ var aggIndex = visibleCDOs.findIndex(function (el) { return el.aggKey === aggGroup.aggKey; });
2648
+ if (!(aggGroup.swimLane in swimLaneLabels)) { // Only add swimlanes once to swimLaneLabels map
2649
+ useAggForLaneLabel(aggGroup);
2650
+ }
2651
+ else { // if lane contains non-numeric data and is being added to another lane
2652
+ if (!((_c = (_b = (_a = _this.chartOptions) === null || _a === void 0 ? void 0 : _a.swimLaneOptions) === null || _b === void 0 ? void 0 : _b[aggGroup.swimLane]) === null || _c === void 0 ? void 0 : _c.collapseEvents)) { // Only increment event heights if collapseEvents === false
2653
+ swimLaneLabels[aggGroup.swimLane].height += offsetsAndHeights[aggIndex][1]; // add heights (non-numerics don't share Y axis)
2654
+ }
2655
+ }
2656
+ });
2657
+ // Clear prior labels
2658
+ this.swimLaneLabelGroup.selectAll('*').remove();
2659
+ // Function to trim labels to max height
2660
+ var truncateLabel = function (labelRef, data) {
2661
+ var maxHeight = data.height - swimlaneLabelConstants.swimLaneLabelHeightPadding; // padding on actual lane height
2662
+ if (data.label) {
2663
+ var labelClientRect = labelRef.getBoundingClientRect();
2664
+ var labelText = labelRef.textContent;
2665
+ while (labelClientRect.height > maxHeight && labelText.length > 0) {
2666
+ labelText = labelText.slice(0, -1);
2667
+ labelRef.textContent = labelText + '...';
2668
+ labelClientRect = labelRef.getBoundingClientRect();
2669
+ }
2670
+ }
2671
+ };
2672
+ var boldYAxisText = function (enabled, lane) {
2673
+ _this.svgSelection.select('.svgGroup')
2674
+ .selectAll(".tsi-swimLaneAxis-".concat(lane))
2675
+ .selectAll('text')
2676
+ .classed('tsi-boldYAxisText', enabled);
2677
+ };
2678
+ var onClickPresentAndValid = function (dp) { return dp.onClick && typeof dp.onClick === 'function'; };
2679
+ // Map over swimLanes and create labels
2680
+ Object.keys(swimLaneLabels).forEach(function (lane) {
2681
+ var labelData = [swimLaneLabels[lane]];
2682
+ var label = _this.swimLaneLabelGroup.selectAll("tsi-swimLaneLabel-".concat(lane)).data(labelData);
2683
+ label.enter()
2684
+ .append("text")
2685
+ .attr("class", function (d) { return "tsi-swimLaneLabel-".concat(lane, " tsi-swimLaneLabel ").concat(onClickPresentAndValid(d) ? 'tsi-boldOnHover' : ''); })
2686
+ .merge(label)
2687
+ .style("text-anchor", "middle")
2688
+ .attr("transform", function (d) { return "translate(".concat((-_this.horizontalLabelOffset + swimlaneLabelConstants.labelLeftPadding), ",").concat((d.offset + d.height / 2), ") rotate(-90)"); })
2689
+ .text(function (d) { return d.label; })
2690
+ .each(function (d) { truncateLabel(this, d); })
2691
+ .on("click", function (event, d) {
2692
+ if (onClickPresentAndValid(d)) {
2693
+ d.onClick();
2694
+ }
2695
+ })
2696
+ .on("mouseover", function (event, d) {
2697
+ if (onClickPresentAndValid(d)) {
2698
+ boldYAxisText(true, lane);
2699
+ }
2700
+ })
2701
+ .on("mouseout", function () {
2702
+ boldYAxisText(false, lane);
2703
+ })
2704
+ .append("svg:title")
2705
+ .text(function (d) { return d.label; });
2706
+ label.exit().remove();
2707
+ });
2708
+ };
2709
+ LineChart.prototype.render = function (data, options, aggregateExpressionOptions) {
2710
+ var _this = this;
2711
+ _super.prototype.render.call(this, data, options, aggregateExpressionOptions);
2712
+ this.originalSwimLanes = this.aggregateExpressionOptions.map(function (aEO) {
2713
+ return aEO.swimLane;
2714
+ });
2715
+ this.originalSwimLaneOptions = options.swimLaneOptions;
2716
+ this.hasBrush = options && (options.brushMoveAction || options.brushMoveEndAction || options.brushContextMenuActions);
2717
+ this.chartOptions.setOptions(options);
2718
+ this.chartMargins.right = this.chartOptions.labelSeriesWithMarker ? (SERIESLABELWIDTH + 8) : LINECHARTCHARTMARGINS.right;
2719
+ this.width = this.getWidth();
2720
+ this.height = Math.max(d3.select(this.renderTarget).node().clientHeight, this.MINHEIGHT);
2721
+ if (this.chartOptions.legend == "compact")
2722
+ this.chartMargins.top = 72;
2723
+ else
2724
+ this.chartMargins.top = 40;
2725
+ if (this.chartOptions.hideChartControlPanel) {
2726
+ this.chartMargins.top += -28;
2727
+ }
2728
+ if (!this.chartOptions.brushRangeVisible && this.targetElement) {
2729
+ this.deleteBrushRange();
2730
+ }
2731
+ if (this.seriesLabelsMarker && !this.chartOptions.labelSeriesWithMarker) {
2732
+ this.seriesLabelsMarker.destroyMarker();
2733
+ this.seriesLabelsMarker = null;
2734
+ }
2735
+ this.strokeOpacity = this.chartOptions.isArea ? .55 : 1;
2736
+ this.nonFocusStrokeOpactiy = this.chartOptions.isArea ? .55 : .3;
2737
+ this.chartComponentData.mergeDataToDisplayStateAndTimeArrays(this.data, this.aggregateExpressionOptions);
2738
+ this.chartComponentData.data.forEach(function (d, i) {
2739
+ _this.aggregateExpressionOptions[i].aggKey = d.aggKey;
2740
+ });
2741
+ if (this.chartOptions.xAxisHidden && this.chartOptions.focusHidden) {
2742
+ this.chartMargins.bottom = 5;
2743
+ }
2744
+ this.chartHeight = Math.max(1, this.height - this.chartMargins.bottom - this.chartMargins.top);
2745
+ this.chartWidth = this.getChartWidth();
2746
+ if (this.brush && this.svgSelection.select('.svgGroup').select(".brushElem") && !this.chartOptions.keepBrush) {
2747
+ this.brushStartTime = null;
2748
+ this.brushEndTime = null;
2749
+ this.brushStartPosition = null;
2750
+ this.brushEndPosition = null;
2751
+ this.clearBrush();
2752
+ }
2753
+ if (!this.chartOptions.hideChartControlPanel && this.chartControlsPanel === null) {
2754
+ this.chartControlsPanel = Utils.createControlPanel(this.renderTarget, this.legendWidth + (this.GUTTERWIDTH / 2), Math.max((this.chartMargins.top + 12), 0), this.chartOptions);
2755
+ var self = this;
2756
+ this.hasStackedButton = true;
2757
+ this.stackedButton = this.chartControlsPanel.append("button")
2758
+ .style("left", "60px")
2759
+ .attr("class", "tsi-stackedButton")
2760
+ .attr("aria-label", function () { return _this.getString("set axis state to") + ' ' + _this.nextStackedState(); })
2761
+ .attr("title", function () { return _this.getString("Change y-axis type"); })
2762
+ .attr("type", "button")
2763
+ .on("click", function () {
2764
+ var _this = this;
2765
+ self.overwriteSwimLanes();
2766
+ self.render(self.data, __assign(__assign({}, self.chartOptions), { yAxisState: self.nextStackedState() }), self.aggregateExpressionOptions);
2767
+ d3.select(this).attr("aria-label", function () { return self.getString("set axis state to") + ' ' + self.nextStackedState(); });
2768
+ setTimeout(function () { return d3.select(_this).node().focus(); }, 200);
2769
+ });
2770
+ }
2771
+ else if (this.chartOptions.hideChartControlPanel && this.chartControlsPanel !== null) {
2772
+ this.hasStackedButton = false;
2773
+ this.removeControlPanel();
2774
+ }
2775
+ if (this.chartControlsPanel !== null) {
2776
+ this.drawEllipsisMenu([{
2777
+ iconClass: "flag",
2778
+ label: this.getString("Drop a Marker"),
2779
+ action: this.addMarker,
2780
+ description: ""
2781
+ }]);
2782
+ this.chartControlsPanel.style("top", Math.max((this.chartMargins.top - 24), 0) + 'px');
2783
+ }
2784
+ this.adjustSwimLanes();
2785
+ if (this.svgSelection == null) {
2786
+ /******************** Static Elements *********************************/
2787
+ this.targetElement = d3.select(this.renderTarget)
2788
+ .classed("tsi-lineChart", true);
2789
+ this.svgSelection = this.targetElement.append("svg")
2790
+ .attr("class", "tsi-lineChartSVG tsi-chartSVG")
2791
+ .attr('title', this.getString('Line chart'))
2792
+ .attr("height", this.height);
2793
+ var g = this.svgSelection.append("g")
2794
+ .classed("svgGroup", true)
2795
+ .attr("transform", "translate(" + this.chartMargins.left + "," + this.chartMargins.top + ")");
2796
+ var defs = this.svgSelection.append('defs');
2797
+ this.brushElem = null;
2798
+ if (this.hasBrush) {
2799
+ this.brushElem = g.append("g")
2800
+ .attr("class", "brushElem");
2801
+ this.brushElem.classed("hideBrushHandles", !this.chartOptions.brushHandlesVisible);
2802
+ }
2803
+ else {
2804
+ //if there is no brushElem, the voronoi lives here
2805
+ this.voronoiRegion = g.append("rect").classed("voronoiRect", true);
2806
+ }
2807
+ this.focus = g.append("g")
2808
+ .attr("transform", "translate(-200,-100)")
2809
+ .attr("class", "tsi-focus");
2810
+ this.focus.append("line")
2811
+ .attr("class", "tsi-focusLine tsi-vLine")
2812
+ .attr("x1", 0)
2813
+ .attr("x2", 0)
2814
+ .attr("y1", this.chartOptions.aggTopMargin)
2815
+ .attr("y2", this.chartHeight);
2816
+ this.focus.append("line")
2817
+ .attr("class", "tsi-focusLine tsi-hLine")
2818
+ .attr("x1", 0)
2819
+ .attr("x2", this.chartWidth)
2820
+ .attr("y1", 0)
2821
+ .attr("y2", 0);
2822
+ this.focus.append("circle")
2823
+ .attr("r", 4);
2824
+ this.horizontalValueBox = d3.select(this.renderTarget)
2825
+ .append('div')
2826
+ .attr('class', 'tsi-horizontalValueBox tsi-chartValueTextBox')
2827
+ .style('display', 'none')
2828
+ .attr('pointer-events', 'none');
2829
+ this.verticalValueBox = d3.select(this.renderTarget)
2830
+ .append('div')
2831
+ .attr('class', 'tsi-verticalValueBox')
2832
+ .style('display', 'none');
2833
+ this.horizontalValueBar = this.focus.append('line')
2834
+ .attr('y1', 0)
2835
+ .attr('y2', 0)
2836
+ .attr('class', 'tsi-horizontalValueBar')
2837
+ .style('display', 'none');
2838
+ this.swimLaneLabelGroup = g.append("g").
2839
+ attr("class", "tsi-swimLaneLabels");
2840
+ if (!this.tooltip) {
2841
+ this.tooltip = new Tooltip(d3.select(this.renderTarget));
2842
+ }
2843
+ this.draw = function (isFromResize, event) {
2844
+ if (isFromResize === void 0) { isFromResize = false; }
2845
+ _this.minBrushWidth = (_this.chartOptions.minBrushWidth) ? _this.chartOptions.minBrushWidth : _this.minBrushWidth;
2846
+ _this.focus.attr("visibility", (_this.chartOptions.focusHidden) ? "hidden" : "visible");
2847
+ _this.verticalValueBox.style("visibility", (_this.chartOptions.focusHidden) ? "hidden" : "visible");
2848
+ _this.horizontalValueBox.style("visibility", (_this.chartOptions.focusHidden) ? "hidden" : "visible");
2849
+ if (_this.chartOptions.xAxisHidden && _this.chartOptions.focusHidden) {
2850
+ _this.chartMargins.bottom = 5;
2851
+ }
2852
+ // Check if any swimlane labels present & modify left margin if so
2853
+ var isLabelVisible = false;
2854
+ _this.aggregateExpressionOptions.filter(function (aggExpOpt) {
2855
+ return _this.chartComponentData.displayState[aggExpOpt.aggKey]["visible"];
2856
+ }).forEach(function (visibleAgg) {
2857
+ var _a, _b;
2858
+ if ((_b = (_a = _this.originalSwimLaneOptions) === null || _a === void 0 ? void 0 : _a[visibleAgg.swimLane]) === null || _b === void 0 ? void 0 : _b.label) {
2859
+ isLabelVisible = true;
2860
+ }
2861
+ });
2862
+ if (isLabelVisible) {
2863
+ _this.chartMargins.left = _this.horizontalLabelOffset;
2864
+ }
2865
+ else if (_this.chartMargins.left === _this.horizontalLabelOffset) {
2866
+ _this.chartMargins.left = LINECHARTCHARTMARGINS.left;
2867
+ }
2868
+ _this.width = Math.max(d3.select(_this.renderTarget).node().clientWidth, _this.MINWIDTH);
2869
+ if (!isFromResize) {
2870
+ _this.chartWidth = _this.getChartWidth();
2871
+ }
2872
+ _this.height = Math.max(d3.select(_this.renderTarget).node().clientHeight, _this.MINHEIGHT);
2873
+ _this.chartHeight = Math.max(1, _this.height - _this.chartMargins.bottom - _this.chartMargins.top);
2874
+ g.attr("transform", "translate(" + _this.chartMargins.left + "," + _this.chartMargins.top + ")");
2875
+ if (_this.brushElem) {
2876
+ _this.brushElem.classed("hideBrushHandles", !_this.chartOptions.brushHandlesVisible);
2877
+ }
2878
+ _this.focus.select('.tsi-hLine').attr("x2", _this.chartWidth);
2879
+ _this.focus.select('.tsi-vLine').attr("y2", _this.chartHeight);
2880
+ _this.svgSelection
2881
+ .style("width", _this.getSVGWidth() + "px")
2882
+ .style("height", _this.height + "px");
2883
+ _super.prototype.themify.call(_this, _this.targetElement, _this.chartOptions.theme);
2884
+ if (!isFromResize) {
2885
+ _this.legendObject.draw(_this.chartOptions.legend, _this.chartComponentData, function (aggKey, splitBy) { _this.labelMouseover(aggKey, splitBy); }, _this.svgSelection, _this.chartOptions, function () {
2886
+ Utils.revertAllSubtitleText(d3.select(_this.renderTarget).selectAll('.tsi-markerValue'));
2887
+ }, _this.stickySeries, event);
2888
+ }
2889
+ _this.svgSelection.selectAll(".yAxis").style("visibility", "hidden");
2890
+ _this.x = d3.scaleTime()
2891
+ .rangeRound([_this.xOffset, Math.max(_this.xOffset, _this.chartWidth - (2 * _this.xOffset))]);
2892
+ _this.y = d3.scaleLinear()
2893
+ .range([Math.max(_this.chartHeight - _this.heightNonNumeric(), _this.chartOptions.aggTopMargin) - LINECHARTTOPPADDING, _this.chartOptions.aggTopMargin]);
2894
+ var fromAndTo = _this.chartComponentData.setAllValuesAndVisibleTAs();
2895
+ var xExtent = (_this.chartComponentData.allValues.length != 0) ? d3.extent(_this.chartComponentData.allValues, function (d) { return d.dateTime; }) : [0, 1];
2896
+ (_this.chartComponentData.allValues.length != 0) ? Math.max(2, (xExtent[1].valueOf() - xExtent[0].valueOf())) : 2;
2897
+ var xOffsetPercentage = _this.xOffset / _this.chartWidth;
2898
+ if (_this.chartOptions.timeFrame) {
2899
+ fromAndTo = [new Date(_this.chartOptions.timeFrame[0]), new Date(_this.chartOptions.timeFrame[1])];
2900
+ }
2901
+ _this.x.domain(fromAndTo);
2902
+ _this.xLowerBound = _this.x(fromAndTo[0]);
2903
+ _this.xUpperBound = _this.x(fromAndTo[1]);
2904
+ //allPossibleTimes -> a combination of the beginning and end of buckets
2905
+ _this.chartComponentData.setTimeMap();
2906
+ var startOfBuckets = _this.chartComponentData.allValues.map(function (d) { return d.dateTime; });
2907
+ var endOfBuckets = _this.chartComponentData.allValues.filter(function (d) { return d.bucketSize != null; })
2908
+ .map(function (d) { return new Date(d.dateTime.valueOf() + d.bucketSize); });
2909
+ var allPossibleTimes = startOfBuckets.concat(endOfBuckets);
2910
+ var timeSet = new Set(allPossibleTimes);
2911
+ _this.possibleTimesArray = Array.from(timeSet.values()).sort().map(function (ts) {
2912
+ return new Date(ts);
2913
+ });
2914
+ if (_this.voronoiRegion) {
2915
+ _this.voronoiRegion.attr("x", xOffsetPercentage * _this.chartWidth)
2916
+ .attr("y", _this.chartOptions.aggTopMargin)
2917
+ .attr("width", _this.chartWidth - (xOffsetPercentage * _this.chartWidth * 2))
2918
+ .attr("height", _this.chartHeight);
2919
+ }
2920
+ if (_this.brushElem) {
2921
+ var self = _this;
2922
+ _this.brush = d3.brushX()
2923
+ .extent([[_this.xLowerBound, Math.min(_this.chartHeight, _this.chartOptions.aggTopMargin)],
2924
+ [_this.xUpperBound, _this.chartHeight]])
2925
+ .on("start", function (event) {
2926
+ if (self.activeMarker !== null && self.isDroppingMarker) {
2927
+ self.voronoiClick(event, this);
2928
+ }
2929
+ var handleHeight = self.getHandleHeight();
2930
+ self.brushElem.selectAll('.handle')
2931
+ .attr('height', handleHeight)
2932
+ .attr('y', (self.chartHeight - handleHeight) / 2)
2933
+ .attr('rx', '4px')
2934
+ .attr('ry', '4px');
2935
+ })
2936
+ .on("brush", function (event) {
2937
+ self.brushBrush(event);
2938
+ self.drawBrushRange();
2939
+ })
2940
+ .on("end", function (event) {
2941
+ self.brushEnd(event, this);
2942
+ self.drawBrushRange();
2943
+ });
2944
+ _this.brushElem.call(_this.brush);
2945
+ _this.setBrush();
2946
+ }
2947
+ var yExtent = _this.getYExtent(_this.chartComponentData.allValues, false, null);
2948
+ var yRange = (yExtent[1] - yExtent[0]) > 0 ? yExtent[1] - yExtent[0] : 1;
2949
+ var yOffsetPercentage = _this.chartOptions.isArea ? (1.5 / _this.chartHeight) : (10 / _this.chartHeight);
2950
+ _this.y.domain([yExtent[0] - (yRange * yOffsetPercentage), yExtent[1] + (yRange * (10 / _this.chartHeight))]);
2951
+ if (_this.chartOptions.isArea) {
2952
+ _this.areaPath = d3.area()
2953
+ .curve(_this.chartOptions.interpolationFunction)
2954
+ .defined(function (d) {
2955
+ return (d.measures !== null) &&
2956
+ (d.measures[_this.chartComponentData.getVisibleMeasure(d.aggregateKey, d.splitBy)] !== null);
2957
+ })
2958
+ .x(function (d) {
2959
+ return _this.getXPosition(d, _this.x);
2960
+ })
2961
+ .y0(function (d) {
2962
+ return d.measures ? _this.y(d.measures[_this.chartComponentData.getVisibleMeasure(d.aggregateKey, d.splitBy)]) : 0;
2963
+ })
2964
+ .y1(_this.chartHeight);
2965
+ }
2966
+ if (!_this.chartOptions.xAxisHidden) {
2967
+ _this.xAxis = g.selectAll(".xAxis").data([_this.x]);
2968
+ _this.drawXAxis(_this.chartHeight);
2969
+ _this.xAxis.exit().remove();
2970
+ var xAxisBaseline = g.selectAll(".xAxisBaseline").data([_this.x]);
2971
+ xAxisBaseline.enter().append("line")
2972
+ .attr("class", "xAxisBaseline")
2973
+ .attr("x1", .5)
2974
+ .merge(xAxisBaseline)
2975
+ .attr("y2", _this.chartHeight + .5)
2976
+ .attr("y1", _this.chartHeight + .5)
2977
+ .attr("x2", _this.chartWidth - _this.xOffset);
2978
+ xAxisBaseline.exit().remove();
2979
+ }
2980
+ if (g.selectAll(".xAxis").size() !== 0) {
2981
+ g.selectAll(".xAxis").style("visibility", ((!_this.chartOptions.xAxisHidden) ? "visible" : "hidden"));
2982
+ }
2983
+ /******************** Draw Line and Points ************************/
2984
+ _this.visibleAggCount = Object.keys(_this.chartComponentData.timeArrays).reduce(function (count, aggKey) {
2985
+ return count + (_this.chartComponentData.displayState[aggKey]['visible'] ? 1 : 0);
2986
+ }, 0);
2987
+ _this.yMap = {};
2988
+ _this.colorMap = {};
2989
+ _this.svgSelection.selectAll(".yAxis").remove();
2990
+ _this.chartComponentData.data.filter(function (agg) { return _this.chartComponentData.displayState[agg.aggKey]["visible"]; });
2991
+ var visibleCDOs = _this.aggregateExpressionOptions.filter(function (cDO) {
2992
+ return _this.chartComponentData.displayState[cDO.aggKey]["visible"];
2993
+ });
2994
+ var offsetsAndHeights = _this.createYOffsets();
2995
+ // Add swimlane labels to SVG
2996
+ _this.createSwimlaneLabels(offsetsAndHeights, visibleCDOs);
2997
+ var swimLaneCounts = {};
2998
+ // Reset public facing yExtents
2999
+ _this.chartComponentData.resetYExtents();
3000
+ var aggregateGroups = _this.svgSelection.select('.svgGroup').selectAll('.tsi-aggGroup')
3001
+ .data(visibleCDOs, function (agg) { return agg.aggKey; });
3002
+ var self = _this;
3003
+ var visibleNumericI = 0;
3004
+ aggregateGroups.enter()
3005
+ .append('g')
3006
+ .classed('tsi-aggGroup', true)
3007
+ .merge(aggregateGroups)
3008
+ .transition()
3009
+ .duration((_this.chartOptions.noAnimate) ? 0 : self.TRANSDURATION)
3010
+ .ease(d3.easeExp)
3011
+ .attr('transform', function (agg, i) {
3012
+ return self.chartOptions.isArea ? null : 'translate(0,' + offsetsAndHeights[i][0] + ')';
3013
+ })
3014
+ .each(function (agg, i) {
3015
+ var _a, _b, _c;
3016
+ var yExtent;
3017
+ var aggVisible = true;
3018
+ var aggValues = [];
3019
+ var aggKey = agg.aggKey;
3020
+ Object.keys(self.chartComponentData.visibleTAs[aggKey]).forEach(function (splitBy) {
3021
+ aggValues = aggValues.concat(self.chartComponentData.visibleTAs[aggKey][splitBy]);
3022
+ });
3023
+ yExtent = self.getGroupYExtent(aggKey, aggVisible, aggValues, yExtent);
3024
+ if (self.plotComponents[aggKey] === undefined || self.mismatchingChartType(aggKey)) {
3025
+ var g_1 = d3.select(this);
3026
+ delete self.plotComponents[aggKey];
3027
+ g_1.selectAll('*').remove();
3028
+ self.plotComponents[aggKey] = self.createPlot(g_1, i, visibleCDOs);
3029
+ }
3030
+ var mouseoverFunction = self.getMouseoverFunction(visibleCDOs[i].dataType);
3031
+ var mouseoutFunction = self.getMouseoutFunction(visibleCDOs[i].dataType);
3032
+ var positionInGroup = visibleNumericI;
3033
+ if (self.getAggAxisType(agg) === YAxisStates.Shared) {
3034
+ yExtent = self.swimlaneYExtents[agg.swimLane];
3035
+ }
3036
+ // Update yExtent index in LineChartData after all local yExtent updates (this is public facing yExtent)
3037
+ // Only update if dataType is numeric
3038
+ if (agg.dataType === 'numeric') {
3039
+ var idx = self.aggregateExpressionOptions.findIndex(function (el) { return el.aggKey === aggKey; });
3040
+ self.chartComponentData.setYExtents(idx, yExtent);
3041
+ }
3042
+ //should count all as same swim lane when not in stacked.
3043
+ var swimLane = agg.swimLane;
3044
+ var offsetImpact = (agg.dataType === DataTypes.Numeric) ? 1 : 0;
3045
+ if (swimLaneCounts[swimLane]) {
3046
+ positionInGroup = swimLaneCounts[swimLane];
3047
+ swimLaneCounts[swimLane] += offsetImpact;
3048
+ }
3049
+ else {
3050
+ positionInGroup = 0;
3051
+ swimLaneCounts[swimLane] = offsetImpact;
3052
+ }
3053
+ var axisState = new AxisState(self.getAggAxisType(agg), yExtent, positionInGroup);
3054
+ var yAxisOnClick = null;
3055
+ if (typeof ((_c = (_b = (_a = self.chartOptions) === null || _a === void 0 ? void 0 : _a.swimLaneOptions) === null || _b === void 0 ? void 0 : _b[swimLane]) === null || _c === void 0 ? void 0 : _c.onClick) === 'function') {
3056
+ yAxisOnClick = function () { var _a, _b; return (_b = (_a = self.chartOptions.swimLaneOptions[swimLane]).onClick) === null || _b === void 0 ? void 0 : _b.call(_a, swimLane); };
3057
+ }
3058
+ self.plotComponents[aggKey].render(self.chartOptions, visibleNumericI, agg, true, d3.select(this), self.chartComponentData, axisState, self.chartHeight, self.visibleAggCount, self.colorMap, self.previousAggregateData, self.x, self.areaPath, self.strokeOpacity, self.y, self.yMap, defs, visibleCDOs[i], self.previousIncludeDots, offsetsAndHeights[i], g, mouseoverFunction, mouseoutFunction, yAxisOnClick);
3059
+ //increment index of visible numerics if appropriate
3060
+ visibleNumericI += (visibleCDOs[i].dataType === DataTypes.Numeric ? 1 : 0);
3061
+ });
3062
+ aggregateGroups.exit().remove();
3063
+ /******************** Voronoi diagram for hover action ************************/
3064
+ _this.voronoi = d3Voronoi.voronoi()
3065
+ .x(function (d) {
3066
+ return (d.bucketSize != undefined ? self.x(new Date(d.dateTime.valueOf() + (d.bucketSize / 2))) : self.x(d.dateTime));
3067
+ })
3068
+ .y(function (d) {
3069
+ if (d.measures) {
3070
+ return self.yMap[d.aggregateKey] ? self.yMap[d.aggregateKey](self.getValueOfVisible(d)) : null;
3071
+ }
3072
+ return null;
3073
+ })
3074
+ .extent([[0, 0], [_this.chartWidth, _this.chartHeight]]);
3075
+ //if brushElem present then use the overlay, otherwise create a rect to put the voronoi on
3076
+ var voronoiSelection = (_this.brushElem ? _this.brushElem.select(".overlay") : _this.voronoiRegion);
3077
+ voronoiSelection.on("mousemove", function (event) {
3078
+ var mouseEvent = d3.pointer(event);
3079
+ self.voronoiMousemove(mouseEvent);
3080
+ })
3081
+ .on("mouseout", function (event, d) {
3082
+ if (!self.filteredValueExist() || !self.voronoiExists())
3083
+ return;
3084
+ var _a = d3.pointer(event), mx = _a[0], my = _a[1];
3085
+ var site = self.voronoiDiagram.find(mx, my);
3086
+ self.voronoiMouseout(event, site.data);
3087
+ self.chartOptions.onMouseout();
3088
+ if (self.tooltip)
3089
+ self.tooltip.hide();
3090
+ })
3091
+ .on("contextmenu", function (event, d) {
3092
+ self.voronoiContextMenu(event, this);
3093
+ })
3094
+ .on("click", function (event, d) {
3095
+ self.voronoiClick(event, this);
3096
+ });
3097
+ if (_this.brushElem) {
3098
+ _this.brushElem.selectAll(".selection, .handle").on("contextmenu", function (event, d) {
3099
+ if (!self.chartOptions.brushContextMenuActions || self.chartOptions.brushContextMenuActions.length == 0 || self.chartOptions.autoTriggerBrushContextMenu)
3100
+ return;
3101
+ var mousePosition = d3.pointer(event, self.targetElement.node());
3102
+ event.preventDefault();
3103
+ self.brushContextMenu.draw(self.chartComponentData, self.renderTarget, self.chartOptions, mousePosition, null, null, null, self.brushStartTime, self.brushEndTime);
3104
+ });
3105
+ _this.brushElem.selectAll('.selection')
3106
+ .attr('stroke', _this.chartOptions.color ? _this.chartOptions.color : 'none')
3107
+ .attr('fill', _this.chartOptions.color ? _this.chartOptions.color : 'grey');
3108
+ var handleHeight = self.getHandleHeight();
3109
+ _this.brushElem.selectAll('.handle')
3110
+ .attr('fill', _this.chartOptions.color ? _this.chartOptions.color : 'grey')
3111
+ .attr('height', handleHeight)
3112
+ .attr('y', (_this.chartHeight - handleHeight) / 2);
3113
+ }
3114
+ /******************** Stack/Unstack button ************************/
3115
+ if (_this.hasStackedButton) {
3116
+ _this.stackedButton.style("opacity", function () {
3117
+ if (_this.chartOptions.yAxisState === YAxisStates.Stacked)
3118
+ return 1;
3119
+ if (_this.chartOptions.yAxisState === YAxisStates.Shared)
3120
+ return .6;
3121
+ return .3;
3122
+ })
3123
+ .style("display", _this.visibleAggCount < 2 ? "none" : "block")
3124
+ .classed('tsi-lightTheme', _this.chartOptions.theme == 'light')
3125
+ .classed('tsi-darkTheme', _this.chartOptions.theme == 'dark');
3126
+ }
3127
+ (_this.chartOptions.timeFrame) ? _this.chartOptions.timeFrame : _this.x.domain();
3128
+ if (!_this.chartOptions.hideChartControlPanel && _this.chartControlsPanel !== null) {
3129
+ _this.chartControlsPanel.style("width", _this.calcSVGWidth() + "px");
3130
+ }
3131
+ _this.renderAllMarkers();
3132
+ _this.drawHorizontalMarkers();
3133
+ _this.voronoiDiagram = _this.voronoi(_this.getFilteredAndSticky(_this.chartComponentData.allValues));
3134
+ };
3135
+ this.legendObject = new Legend(this.draw, this.renderTarget, this.legendWidth);
3136
+ this.contextMenu = new ContextMenu(this.draw, this.renderTarget);
3137
+ this.brushContextMenu = new ContextMenu(this.draw, this.renderTarget);
3138
+ window.addEventListener("resize", function (event) {
3139
+ if (!_this.chartOptions.suppressResizeListener) {
3140
+ _this.draw(true, event);
3141
+ _this.renderAllMarkers();
3142
+ }
3143
+ });
3144
+ }
3145
+ this.chartComponentData.mergeDataToDisplayStateAndTimeArrays(this.data, this.aggregateExpressionOptions);
3146
+ this.draw();
3147
+ this.gatedShowGrid();
3148
+ this.chartOptions.noAnimate = false; // ensure internal renders are always animated, overriding the users noAnimate option
3149
+ if (this.chartOptions.labelSeriesWithMarker && this.seriesLabelsMarker === null) {
3150
+ this.createSeriesLabelsMarker();
3151
+ }
3152
+ this.renderSeriesLabelsMarker();
3153
+ if (this.chartOptions.markers && this.chartOptions.markers.length > 0) {
3154
+ this.importMarkers();
3155
+ }
3156
+ d3.select("html").on("click." + Utils.guid(), function (event) {
3157
+ if (_this.ellipsisContainer && event.target != _this.ellipsisContainer.select(".tsi-ellipsisButton").node()) {
3158
+ _this.ellipsisMenu.setMenuVisibility(false);
3159
+ }
3160
+ });
3161
+ this.legendPostRenderProcess(this.chartOptions.legend, this.svgSelection, true, function () {
3162
+ _this.updateBrushRange();
3163
+ });
3164
+ };
3165
+ LineChart.prototype.createPlot = function (svgGroup, i, cDO) {
3166
+ var chartType = cDO[i].dataType;
3167
+ if (chartType === DataTypes.Numeric) {
3168
+ return new LinePlot(svgGroup);
3169
+ }
3170
+ else if (chartType === DataTypes.Categorical) {
3171
+ return new CategoricalPlot(svgGroup);
3172
+ }
3173
+ else if (chartType === DataTypes.Events) {
3174
+ return new EventsPlot(svgGroup);
3175
+ }
3176
+ return null;
3177
+ };
3178
+ return LineChart;
3179
+ }(TemporalXAxisComponent));
3180
+
3181
+ export { LineChart as L };