Commit 0ebbee02db9a981715bc774f2d99b7aa10be4470
1 parent
f1193c1d
UI: Added new timewindow type - realtime interval
Showing
8 changed files
with
230 additions
and
85 deletions
... | ... | @@ -15,7 +15,12 @@ |
15 | 15 | /// |
16 | 16 | |
17 | 17 | import { SubscriptionData, SubscriptionDataHolder } from '@app/shared/models/telemetry/telemetry.models'; |
18 | -import { AggregationType } from '@shared/models/time/time.models'; | |
18 | +import { | |
19 | + AggregationType, | |
20 | + calculateIntervalEndTime, | |
21 | + calculateIntervalStartTime, | |
22 | + QuickTimeInterval | |
23 | +} from '@shared/models/time/time.models'; | |
19 | 24 | import { UtilsService } from '@core/services/utils.service'; |
20 | 25 | import { deepClone } from '@core/utils'; |
21 | 26 | import Timeout = NodeJS.Timeout; |
... | ... | @@ -92,7 +97,8 @@ export class DataAggregator { |
92 | 97 | private interval: number, |
93 | 98 | private stateData: boolean, |
94 | 99 | private utils: UtilsService, |
95 | - private ignoreDataUpdateOnIntervalTick: boolean) { | |
100 | + private ignoreDataUpdateOnIntervalTick: boolean, | |
101 | + private quickInterval: QuickTimeInterval) { | |
96 | 102 | this.tsKeyNames.forEach((key) => { |
97 | 103 | this.dataBuffer[key] = []; |
98 | 104 | }); |
... | ... | @@ -138,7 +144,8 @@ export class DataAggregator { |
138 | 144 | this.startTs = startTs; |
139 | 145 | this.timeWindow = timeWindow; |
140 | 146 | this.interval = interval; |
141 | - this.endTs = this.startTs + this.timeWindow; | |
147 | + const endTs = this.startTs + this.timeWindow; | |
148 | + this.endTs = calculateIntervalEndTime(this.quickInterval, endTs); | |
142 | 149 | this.elapsed = 0; |
143 | 150 | this.aggregationTimeout = Math.max(this.interval, 1000); |
144 | 151 | this.resetPending = true; |
... | ... | @@ -161,7 +168,8 @@ export class DataAggregator { |
161 | 168 | if (!this.dataReceived) { |
162 | 169 | this.elapsed = 0; |
163 | 170 | this.dataReceived = true; |
164 | - this.endTs = this.startTs + this.timeWindow; | |
171 | + const endTs = this.startTs + this.timeWindow; | |
172 | + this.endTs = calculateIntervalEndTime(this.quickInterval, endTs); | |
165 | 173 | } |
166 | 174 | if (this.resetPending) { |
167 | 175 | this.resetPending = false; |
... | ... | @@ -197,8 +205,11 @@ export class DataAggregator { |
197 | 205 | if (!history) { |
198 | 206 | const delta = Math.floor(this.elapsed / this.interval); |
199 | 207 | if (delta || !this.data) { |
200 | - this.startTs += delta * this.interval; | |
201 | - this.endTs += delta * this.interval; | |
208 | + const tickTs = delta * this.interval; | |
209 | + const startTS = this.startTs + tickTs; | |
210 | + this.startTs = calculateIntervalStartTime(this.quickInterval, startTS); | |
211 | + const endTs = this.endTs + tickTs; | |
212 | + this.endTs = calculateIntervalEndTime(this.quickInterval, endTs); | |
202 | 213 | this.data = this.updateData(); |
203 | 214 | this.elapsed = this.elapsed - delta * this.interval; |
204 | 215 | } | ... | ... |
... | ... | @@ -752,7 +752,8 @@ export class EntityDataSubscription { |
752 | 752 | subsTw.aggregation.interval, |
753 | 753 | subsTw.aggregation.stateData, |
754 | 754 | this.utils, |
755 | - this.entityDataSubscriptionOptions.ignoreDataUpdateOnIntervalTick | |
755 | + this.entityDataSubscriptionOptions.ignoreDataUpdateOnIntervalTick, | |
756 | + subsTw.quickInterval | |
756 | 757 | ); |
757 | 758 | } |
758 | 759 | ... | ... |
... | ... | @@ -37,6 +37,8 @@ import { |
37 | 37 | } from '@app/shared/models/widget.models'; |
38 | 38 | import { HttpErrorResponse } from '@angular/common/http'; |
39 | 39 | import { |
40 | + calculateIntervalEndTime, | |
41 | + calculateIntervalStartTime, | |
40 | 42 | createSubscriptionTimewindow, |
41 | 43 | createTimewindowForComparison, |
42 | 44 | SubscriptionTimewindow, |
... | ... | @@ -1081,8 +1083,10 @@ export class WidgetSubscription implements IWidgetSubscription { |
1081 | 1083 | private updateTimewindow() { |
1082 | 1084 | this.timeWindow.interval = this.subscriptionTimewindow.aggregation.interval || 1000; |
1083 | 1085 | if (this.subscriptionTimewindow.realtimeWindowMs) { |
1084 | - this.timeWindow.maxTime = moment().valueOf() + this.timeWindow.stDiff; | |
1085 | - this.timeWindow.minTime = this.timeWindow.maxTime - this.subscriptionTimewindow.realtimeWindowMs; | |
1086 | + this.timeWindow.maxTime = calculateIntervalEndTime( | |
1087 | + this.subscriptionTimewindow.quickInterval, moment().valueOf() + this.timeWindow.stDiff); | |
1088 | + this.timeWindow.minTime = calculateIntervalStartTime( | |
1089 | + this.subscriptionTimewindow.quickInterval, this.timeWindow.maxTime - this.subscriptionTimewindow.realtimeWindowMs); | |
1086 | 1090 | } else if (this.subscriptionTimewindow.fixedWindow) { |
1087 | 1091 | this.timeWindow.maxTime = this.subscriptionTimewindow.fixedWindow.endTimeMs; |
1088 | 1092 | this.timeWindow.minTime = this.subscriptionTimewindow.fixedWindow.startTimeMs; |
... | ... | @@ -1105,7 +1109,7 @@ export class WidgetSubscription implements IWidgetSubscription { |
1105 | 1109 | this.comparisonTimeWindow.interval = this.timewindowForComparison.aggregation.interval || 1000; |
1106 | 1110 | if (this.timewindowForComparison.realtimeWindowMs) { |
1107 | 1111 | this.comparisonTimeWindow.maxTime = moment(this.timeWindow.maxTime).subtract(1, this.timeForComparison).valueOf(); |
1108 | - this.comparisonTimeWindow.minTime = this.comparisonTimeWindow.maxTime - this.timewindowForComparison.realtimeWindowMs; | |
1112 | + this.comparisonTimeWindow.minTime = moment(this.timeWindow.minTime).subtract(1, this.timeForComparison).valueOf(); | |
1109 | 1113 | } else if (this.timewindowForComparison.fixedWindow) { |
1110 | 1114 | this.comparisonTimeWindow.maxTime = this.timewindowForComparison.fixedWindow.endTimeMs; |
1111 | 1115 | this.comparisonTimeWindow.minTime = this.timewindowForComparison.fixedWindow.startTimeMs; | ... | ... |
... | ... | @@ -50,7 +50,7 @@ export class QuickTimeIntervalComponent implements OnInit, ControlValueAccessor |
50 | 50 | |
51 | 51 | get intervals() { |
52 | 52 | if (this.onlyCurrentInterval) { |
53 | - return this.allIntervals.filter(interval => interval.startsWith('TODAY_') || interval.startsWith('CURRENT_')); | |
53 | + return this.allIntervals.filter(interval => interval.startsWith('TODAY') || interval.startsWith('CURRENT_')); | |
54 | 54 | } |
55 | 55 | return this.allIntervals; |
56 | 56 | } |
... | ... | @@ -71,7 +71,6 @@ export class QuickTimeIntervalComponent implements OnInit, ControlValueAccessor |
71 | 71 | |
72 | 72 | writeValue(interval: QuickTimeInterval): void { |
73 | 73 | this.modelValue = interval; |
74 | - this.rendered = true; | |
75 | 74 | } |
76 | 75 | |
77 | 76 | onIntervalChange() { | ... | ... |
... | ... | @@ -21,16 +21,43 @@ |
21 | 21 | <mat-tab-group dynamicHeight [ngClass]="{'tb-headless': historyOnly}" |
22 | 22 | (selectedIndexChange)="timewindowForm.markAsDirty()" [(selectedIndex)]="timewindow.selectedTab"> |
23 | 23 | <mat-tab label="{{ 'timewindow.realtime' | translate }}"> |
24 | - <div formGroupName="realtime" class="mat-content mat-padding" fxLayout="column"> | |
25 | - <tb-timeinterval | |
26 | - [(hideFlag)]="timewindow.hideInterval" | |
27 | - (hideFlagChange)="onHideIntervalChanged()" | |
28 | - [isEdit]="isEdit" | |
29 | - formControlName="timewindowMs" | |
30 | - predefinedName="timewindow.last" | |
31 | - [required]="timewindow.selectedTab === timewindowTypes.REALTIME" | |
32 | - style="padding-top: 8px;"></tb-timeinterval> | |
33 | - </div> | |
24 | + <section fxLayout="row"> | |
25 | + <section *ngIf="isEdit" fxLayout="column" style="padding-top: 8px; padding-left: 16px;"> | |
26 | + <label class="tb-small hide-label" translate>timewindow.hide</label> | |
27 | + <mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="timewindow.hideInterval" | |
28 | + (ngModelChange)="onHideIntervalChanged()"></mat-checkbox> | |
29 | + </section> | |
30 | + <section fxLayout="column" fxFlex [fxShow]="isEdit || !timewindow.hideInterval"> | |
31 | + <div formGroupName="realtime" class="mat-content mat-padding" style="padding-top: 8px;"> | |
32 | + <mat-radio-group formControlName="realtimeType"> | |
33 | + <mat-radio-button [value]="realtimeTypes.LAST_INTERVAL" color="primary"> | |
34 | + <section fxLayout="column"> | |
35 | + <span translate>timewindow.last</span> | |
36 | + <tb-timeinterval | |
37 | + formControlName="timewindowMs" | |
38 | + predefinedName="timewindow.last" | |
39 | + [fxShow]="timewindowForm.get('realtime.realtimeType').value === realtimeTypes.LAST_INTERVAL" | |
40 | + [required]="timewindow.selectedTab === timewindowTypes.REALTIME && | |
41 | + timewindowForm.get('realtime.realtimeType').value === realtimeTypes.LAST_INTERVAL" | |
42 | + style="padding-top: 8px;"></tb-timeinterval> | |
43 | + </section> | |
44 | + </mat-radio-button> | |
45 | + <mat-radio-button [value]="realtimeTypes.INTERVAL" color="primary"> | |
46 | + <section fxLayout="column"> | |
47 | + <span translate>timewindow.interval</span> | |
48 | + <tb-quick-time-interval | |
49 | + formControlName="quickInterval" | |
50 | + onlyCurrentInterval="true" | |
51 | + [fxShow]="timewindowForm.get('realtime.realtimeType').value === realtimeTypes.INTERVAL" | |
52 | + [required]="timewindow.selectedTab === timewindowTypes.HISTORY && | |
53 | + timewindowForm.get('realtime.realtimeType').value === realtimeTypes.INTERVAL" | |
54 | + style="padding-top: 8px; min-width: 364px"></tb-quick-time-interval> | |
55 | + </section> | |
56 | + </mat-radio-button> | |
57 | + </mat-radio-group> | |
58 | + </div> | |
59 | + </section> | |
60 | + </section> | |
34 | 61 | </mat-tab> |
35 | 62 | <mat-tab label="{{ 'timewindow.history' | translate }}"> |
36 | 63 | <section fxLayout="row"> | ... | ... |
... | ... | @@ -19,7 +19,9 @@ import { |
19 | 19 | aggregationTranslations, |
20 | 20 | AggregationType, |
21 | 21 | DAY, |
22 | - HistoryWindowType, quickTimeIntervalPeriod, | |
22 | + HistoryWindowType, | |
23 | + quickTimeIntervalPeriod, | |
24 | + RealtimeWindowType, | |
23 | 25 | Timewindow, |
24 | 26 | TimewindowType |
25 | 27 | } from '@shared/models/time/time.models'; |
... | ... | @@ -60,6 +62,8 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit { |
60 | 62 | |
61 | 63 | historyTypes = HistoryWindowType; |
62 | 64 | |
65 | + realtimeTypes = RealtimeWindowType; | |
66 | + | |
63 | 67 | timewindowTypes = TimewindowType; |
64 | 68 | |
65 | 69 | aggregationTypes = AggregationType; |
... | ... | @@ -89,6 +93,11 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit { |
89 | 93 | this.timewindowForm = this.fb.group({ |
90 | 94 | realtime: this.fb.group( |
91 | 95 | { |
96 | + realtimeType: this.fb.control({ | |
97 | + value: this.timewindow.realtime && typeof this.timewindow.realtime.realtimeType !== 'undefined' | |
98 | + ? this.timewindow.realtime.realtimeType : RealtimeWindowType.LAST_INTERVAL, | |
99 | + disabled: hideInterval | |
100 | + }), | |
92 | 101 | timewindowMs: [ |
93 | 102 | this.timewindow.realtime && typeof this.timewindow.realtime.timewindowMs !== 'undefined' |
94 | 103 | ? this.timewindow.realtime.timewindowMs : null |
... | ... | @@ -96,7 +105,12 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit { |
96 | 105 | interval: [ |
97 | 106 | this.timewindow.realtime && typeof this.timewindow.realtime.interval !== 'undefined' |
98 | 107 | ? this.timewindow.realtime.interval : null |
99 | - ] | |
108 | + ], | |
109 | + quickInterval: this.fb.control({ | |
110 | + value: this.timewindow.realtime && typeof this.timewindow.realtime.quickInterval !== 'undefined' | |
111 | + ? this.timewindow.realtime.quickInterval : null, | |
112 | + disabled: hideInterval | |
113 | + }) | |
100 | 114 | } |
101 | 115 | ), |
102 | 116 | history: this.fb.group( |
... | ... | @@ -124,7 +138,7 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit { |
124 | 138 | value: this.timewindow.history && typeof this.timewindow.history.quickInterval !== 'undefined' |
125 | 139 | ? this.timewindow.history.quickInterval : null, |
126 | 140 | disabled: hideInterval |
127 | - }), | |
141 | + }) | |
128 | 142 | } |
129 | 143 | ), |
130 | 144 | aggregation: this.fb.group( |
... | ... | @@ -147,7 +161,9 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit { |
147 | 161 | update() { |
148 | 162 | const timewindowFormValue = this.timewindowForm.getRawValue(); |
149 | 163 | this.timewindow.realtime = { |
164 | + realtimeType: timewindowFormValue.realtime.realtimeType, | |
150 | 165 | timewindowMs: timewindowFormValue.realtime.timewindowMs, |
166 | + quickInterval: timewindowFormValue.realtime.quickInterval, | |
151 | 167 | interval: timewindowFormValue.realtime.interval |
152 | 168 | }; |
153 | 169 | this.timewindow.history = { |
... | ... | @@ -180,11 +196,23 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit { |
180 | 196 | } |
181 | 197 | |
182 | 198 | minRealtimeAggInterval() { |
183 | - return this.timeService.minIntervalLimit(this.timewindowForm.get('realtime.timewindowMs').value); | |
199 | + return this.timeService.minIntervalLimit(this.currentRealtimeTimewindow()); | |
184 | 200 | } |
185 | 201 | |
186 | 202 | maxRealtimeAggInterval() { |
187 | - return this.timeService.maxIntervalLimit(this.timewindowForm.get('realtime.timewindowMs').value); | |
203 | + return this.timeService.maxIntervalLimit(this.currentRealtimeTimewindow()); | |
204 | + } | |
205 | + | |
206 | + currentRealtimeTimewindow(): number { | |
207 | + const timeWindowFormValue = this.timewindowForm.getRawValue(); | |
208 | + switch (timeWindowFormValue.realtime.realtimeType) { | |
209 | + case RealtimeWindowType.LAST_INTERVAL: | |
210 | + return timeWindowFormValue.realtime.timewindowMs; | |
211 | + case RealtimeWindowType.INTERVAL: | |
212 | + return quickTimeIntervalPeriod(timeWindowFormValue.realtime.quickInterval); | |
213 | + default: | |
214 | + return DAY; | |
215 | + } | |
188 | 216 | } |
189 | 217 | |
190 | 218 | minHistoryAggInterval() { |
... | ... | @@ -215,11 +243,17 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit { |
215 | 243 | this.timewindowForm.get('history.timewindowMs').disable({emitEvent: false}); |
216 | 244 | this.timewindowForm.get('history.fixedTimewindow').disable({emitEvent: false}); |
217 | 245 | this.timewindowForm.get('history.quickInterval').disable({emitEvent: false}); |
246 | + this.timewindowForm.get('realtime.realtimeType').disable({emitEvent: false}); | |
247 | + this.timewindowForm.get('realtime.timewindowMs').disable({emitEvent: false}); | |
248 | + this.timewindowForm.get('realtime.quickInterval').disable({emitEvent: false}); | |
218 | 249 | } else { |
219 | 250 | this.timewindowForm.get('history.historyType').enable({emitEvent: false}); |
220 | 251 | this.timewindowForm.get('history.timewindowMs').enable({emitEvent: false}); |
221 | 252 | this.timewindowForm.get('history.fixedTimewindow').enable({emitEvent: false}); |
222 | 253 | this.timewindowForm.get('history.quickInterval').enable({emitEvent: false}); |
254 | + this.timewindowForm.get('realtime.realtimeType').enable({emitEvent: false}); | |
255 | + this.timewindowForm.get('realtime.timewindowMs').enable({emitEvent: false}); | |
256 | + this.timewindowForm.get('realtime.quickInterval').enable({emitEvent: false}); | |
223 | 257 | } |
224 | 258 | this.timewindowForm.markAsDirty(); |
225 | 259 | } | ... | ... |
... | ... | @@ -34,6 +34,7 @@ import { |
34 | 34 | HistoryWindowType, |
35 | 35 | initModelFromDefaultTimewindow, |
36 | 36 | QuickTimeIntervalTranslationMap, |
37 | + RealtimeWindowType, | |
37 | 38 | Timewindow, |
38 | 39 | TimewindowType |
39 | 40 | } from '@shared/models/time/time.models'; |
... | ... | @@ -273,9 +274,13 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces |
273 | 274 | |
274 | 275 | updateDisplayValue() { |
275 | 276 | if (this.innerValue.selectedTab === TimewindowType.REALTIME && !this.historyOnly) { |
276 | - this.innerValue.displayValue = this.translate.instant('timewindow.realtime') + ' - ' + | |
277 | - this.translate.instant('timewindow.last-prefix') + ' ' + | |
278 | - this.millisecondsToTimeStringPipe.transform(this.innerValue.realtime.timewindowMs); | |
277 | + this.innerValue.displayValue = this.translate.instant('timewindow.realtime') + ' - '; | |
278 | + if (this.innerValue.realtime.realtimeType === RealtimeWindowType.INTERVAL) { | |
279 | + this.innerValue.displayValue += this.translate.instant(QuickTimeIntervalTranslationMap.get(this.innerValue.realtime.quickInterval)); | |
280 | + } else { | |
281 | + this.innerValue.displayValue += this.translate.instant('timewindow.last-prefix') + ' ' + | |
282 | + this.millisecondsToTimeStringPipe.transform(this.innerValue.realtime.timewindowMs); | |
283 | + } | |
279 | 284 | } else { |
280 | 285 | this.innerValue.displayValue = !this.historyOnly ? (this.translate.instant('timewindow.history') + ' - ') : ''; |
281 | 286 | if (this.innerValue.history.historyType === HistoryWindowType.LAST_INTERVAL) { | ... | ... |
... | ... | @@ -15,7 +15,7 @@ |
15 | 15 | /// |
16 | 16 | |
17 | 17 | import { TimeService } from '@core/services/time.service'; |
18 | -import { deepClone, isDefined, isUndefined } from '@app/core/utils'; | |
18 | +import { deepClone, isDefined, isDefinedAndNotNull, isUndefined } from '@app/core/utils'; | |
19 | 19 | import * as moment_ from 'moment'; |
20 | 20 | import { Observable } from 'rxjs/internal/Observable'; |
21 | 21 | import { from, of } from 'rxjs'; |
... | ... | @@ -35,6 +35,11 @@ export enum TimewindowType { |
35 | 35 | HISTORY |
36 | 36 | } |
37 | 37 | |
38 | +export enum RealtimeWindowType { | |
39 | + LAST_INTERVAL, | |
40 | + INTERVAL | |
41 | +} | |
42 | + | |
38 | 43 | export enum HistoryWindowType { |
39 | 44 | LAST_INTERVAL, |
40 | 45 | FIXED, |
... | ... | @@ -47,6 +52,10 @@ export interface IntervalWindow { |
47 | 52 | quickInterval?: QuickTimeInterval; |
48 | 53 | } |
49 | 54 | |
55 | +export interface RealtimeWindow extends IntervalWindow{ | |
56 | + realtimeType?: RealtimeWindowType; | |
57 | +} | |
58 | + | |
50 | 59 | export interface FixedWindow { |
51 | 60 | startTimeMs: number; |
52 | 61 | endTimeMs: number; |
... | ... | @@ -89,7 +98,7 @@ export interface Timewindow { |
89 | 98 | hideAggregation?: boolean; |
90 | 99 | hideAggInterval?: boolean; |
91 | 100 | selectedTab?: TimewindowType; |
92 | - realtime?: IntervalWindow; | |
101 | + realtime?: RealtimeWindow; | |
93 | 102 | history?: HistoryWindow; |
94 | 103 | aggregation?: Aggregation; |
95 | 104 | } |
... | ... | @@ -102,6 +111,7 @@ export interface SubscriptionAggregation extends Aggregation { |
102 | 111 | |
103 | 112 | export interface SubscriptionTimewindow { |
104 | 113 | startTs?: number; |
114 | + quickInterval?: QuickTimeInterval; | |
105 | 115 | realtimeWindowMs?: number; |
106 | 116 | fixedWindow?: FixedWindow; |
107 | 117 | aggregation?: SubscriptionAggregation; |
... | ... | @@ -168,8 +178,10 @@ export function defaultTimewindow(timeService: TimeService): Timewindow { |
168 | 178 | hideAggInterval: false, |
169 | 179 | selectedTab: TimewindowType.REALTIME, |
170 | 180 | realtime: { |
181 | + realtimeType: RealtimeWindowType.LAST_INTERVAL, | |
171 | 182 | interval: SECOND, |
172 | - timewindowMs: MINUTE | |
183 | + timewindowMs: MINUTE, | |
184 | + quickInterval: QuickTimeInterval.TODAY | |
173 | 185 | }, |
174 | 186 | history: { |
175 | 187 | historyType: HistoryWindowType.LAST_INTERVAL, |
... | ... | @@ -208,7 +220,20 @@ export function initModelFromDefaultTimewindow(value: Timewindow, timeService: T |
208 | 220 | if (isDefined(value.realtime.interval)) { |
209 | 221 | model.realtime.interval = value.realtime.interval; |
210 | 222 | } |
211 | - model.realtime.timewindowMs = value.realtime.timewindowMs; | |
223 | + if (isUndefined(value.realtime.realtimeType)) { | |
224 | + if (isDefined(value.realtime.quickInterval)) { | |
225 | + model.realtime.realtimeType = RealtimeWindowType.INTERVAL; | |
226 | + } else { | |
227 | + model.realtime.realtimeType = RealtimeWindowType.LAST_INTERVAL; | |
228 | + } | |
229 | + } else { | |
230 | + model.realtime.realtimeType = value.realtime.realtimeType; | |
231 | + } | |
232 | + if (model.realtime.realtimeType === RealtimeWindowType.INTERVAL) { | |
233 | + model.realtime.quickInterval = value.realtime.quickInterval; | |
234 | + } else { | |
235 | + model.realtime.timewindowMs = value.realtime.timewindowMs; | |
236 | + } | |
212 | 237 | } else { |
213 | 238 | if (isDefined(value.history.interval)) { |
214 | 239 | model.history.interval = value.history.interval; |
... | ... | @@ -309,14 +334,27 @@ export function createSubscriptionTimewindow(timewindow: Timewindow, stDiff: num |
309 | 334 | selectedTab = isDefined(timewindow.realtime) ? TimewindowType.REALTIME : TimewindowType.HISTORY; |
310 | 335 | } |
311 | 336 | if (selectedTab === TimewindowType.REALTIME) { |
312 | - subscriptionTimewindow.realtimeWindowMs = timewindow.realtime.timewindowMs; | |
337 | + let realtimeType = timewindow.realtime.realtimeType; | |
338 | + if (isUndefined(realtimeType)) { | |
339 | + if (isDefined(timewindow.realtime.quickInterval)) { | |
340 | + realtimeType = RealtimeWindowType.INTERVAL; | |
341 | + } else { | |
342 | + realtimeType = RealtimeWindowType.LAST_INTERVAL; | |
343 | + } | |
344 | + } | |
345 | + if (realtimeType === RealtimeWindowType.INTERVAL) { | |
346 | + subscriptionTimewindow.realtimeWindowMs = getSubscriptionRealtimeWindowFromTimeInterval(timewindow.realtime.quickInterval); | |
347 | + subscriptionTimewindow.quickInterval = timewindow.realtime.quickInterval; | |
348 | + } else { | |
349 | + subscriptionTimewindow.realtimeWindowMs = timewindow.realtime.timewindowMs; | |
350 | + } | |
313 | 351 | subscriptionTimewindow.aggregation.interval = |
314 | 352 | timeService.boundIntervalToTimewindow(subscriptionTimewindow.realtimeWindowMs, timewindow.realtime.interval, |
315 | 353 | subscriptionTimewindow.aggregation.type); |
316 | 354 | subscriptionTimewindow.startTs = Date.now() + stDiff - subscriptionTimewindow.realtimeWindowMs; |
317 | 355 | const startDiff = subscriptionTimewindow.startTs % subscriptionTimewindow.aggregation.interval; |
318 | 356 | aggTimewindow = subscriptionTimewindow.realtimeWindowMs; |
319 | - if (startDiff) { | |
357 | + if (startDiff && realtimeType !== RealtimeWindowType.INTERVAL) { | |
320 | 358 | subscriptionTimewindow.startTs -= startDiff; |
321 | 359 | aggTimewindow += subscriptionTimewindow.aggregation.interval; |
322 | 360 | } |
... | ... | @@ -339,7 +377,11 @@ export function createSubscriptionTimewindow(timewindow: Timewindow, stDiff: num |
339 | 377 | }; |
340 | 378 | aggTimewindow = timewindow.history.timewindowMs; |
341 | 379 | } else if (historyType === HistoryWindowType.INTERVAL) { |
342 | - subscriptionTimewindow.fixedWindow = createSubscriptionTimeWindowFromQuickKTimeInterval(timewindow.history.quickInterval); | |
380 | + const currentDate = moment(); | |
381 | + subscriptionTimewindow.fixedWindow = { | |
382 | + startTimeMs: calculateIntervalStartTime(timewindow.history.quickInterval, null, currentDate), | |
383 | + endTimeMs: calculateIntervalEndTime(timewindow.history.quickInterval, null, currentDate) | |
384 | + }; | |
343 | 385 | aggTimewindow = subscriptionTimewindow.fixedWindow.endTimeMs - subscriptionTimewindow.fixedWindow.startTimeMs; |
344 | 386 | } else { |
345 | 387 | subscriptionTimewindow.fixedWindow = { |
... | ... | @@ -360,77 +402,99 @@ export function createSubscriptionTimewindow(timewindow: Timewindow, stDiff: num |
360 | 402 | return subscriptionTimewindow; |
361 | 403 | } |
362 | 404 | |
363 | -export function createSubscriptionTimeWindowFromQuickKTimeInterval(interval: QuickTimeInterval): FixedWindow { | |
405 | +function getSubscriptionRealtimeWindowFromTimeInterval(interval: QuickTimeInterval): number { | |
364 | 406 | const currentDate = moment(); |
365 | - const timeWindow = { | |
366 | - startTimeMs: 0, | |
367 | - endTimeMs: 0 | |
368 | - }; | |
407 | + switch (interval) { | |
408 | + case QuickTimeInterval.TODAY: | |
409 | + case QuickTimeInterval.TODAY_SO_FAR: | |
410 | + return currentDate.diff(currentDate.clone().startOf('day')); | |
411 | + case QuickTimeInterval.CURRENT_WEEK: | |
412 | + case QuickTimeInterval.CURRENT_WEEK_SO_FAR: | |
413 | + return currentDate.diff(currentDate.clone().startOf('week')); | |
414 | + case QuickTimeInterval.CURRENT_MONTH: | |
415 | + case QuickTimeInterval.CURRENT_MONTH_SO_FAR: | |
416 | + return currentDate.diff(currentDate.clone().startOf('month')); | |
417 | + case QuickTimeInterval.CURRENT_YEAR: | |
418 | + case QuickTimeInterval.CURRENT_YEAR_SO_FAR: | |
419 | + return currentDate.diff(currentDate.clone().startOf('year')); | |
420 | + } | |
421 | +} | |
422 | + | |
423 | +export function calculateIntervalEndTime(interval: QuickTimeInterval, endTs = 0, nowDate?: moment_.Moment): number { | |
424 | + const currentDate = isDefinedAndNotNull(nowDate) ? nowDate.clone() : moment(); | |
425 | + switch (interval) { | |
426 | + case QuickTimeInterval.YESTERDAY: | |
427 | + currentDate.subtract(1, 'days'); | |
428 | + return currentDate.endOf('day').valueOf(); | |
429 | + case QuickTimeInterval.DAY_BEFORE_YESTERDAY: | |
430 | + currentDate.subtract(2, 'days'); | |
431 | + return currentDate.endOf('day').valueOf(); | |
432 | + case QuickTimeInterval.THIS_DAY_LAST_WEEK: | |
433 | + currentDate.subtract(1, 'weeks'); | |
434 | + return currentDate.endOf('day').valueOf(); | |
435 | + case QuickTimeInterval.PREVIOUS_WEEK: | |
436 | + currentDate.subtract(1, 'weeks'); | |
437 | + return currentDate.endOf('week').valueOf(); | |
438 | + case QuickTimeInterval.PREVIOUS_MONTH: | |
439 | + currentDate.subtract(1, 'months'); | |
440 | + return currentDate.endOf('month').valueOf(); | |
441 | + case QuickTimeInterval.PREVIOUS_YEAR: | |
442 | + currentDate.subtract(1, 'years'); | |
443 | + return currentDate.endOf('year').valueOf(); | |
444 | + case QuickTimeInterval.TODAY: | |
445 | + return currentDate.endOf('day').valueOf(); | |
446 | + case QuickTimeInterval.CURRENT_WEEK: | |
447 | + return currentDate.endOf('week').valueOf(); | |
448 | + case QuickTimeInterval.CURRENT_MONTH: | |
449 | + return currentDate.endOf('month').valueOf(); | |
450 | + case QuickTimeInterval.CURRENT_YEAR: | |
451 | + return currentDate.endOf('year').valueOf(); | |
452 | + case QuickTimeInterval.TODAY_SO_FAR: | |
453 | + case QuickTimeInterval.CURRENT_WEEK_SO_FAR: | |
454 | + case QuickTimeInterval.CURRENT_MONTH_SO_FAR: | |
455 | + case QuickTimeInterval.CURRENT_YEAR_SO_FAR: | |
456 | + return currentDate.valueOf(); | |
457 | + default: | |
458 | + return endTs; | |
459 | + } | |
460 | +} | |
461 | + | |
462 | +export function calculateIntervalStartTime(interval: QuickTimeInterval, startTS = 0, nowDate?: moment_.Moment): number { | |
463 | + const currentDate = isDefinedAndNotNull(nowDate) ? nowDate.clone() : moment(); | |
369 | 464 | switch (interval) { |
370 | 465 | case QuickTimeInterval.YESTERDAY: |
371 | 466 | currentDate.subtract(1, 'days'); |
372 | - timeWindow.startTimeMs = currentDate.startOf('day').valueOf(); | |
373 | - timeWindow.endTimeMs = currentDate.endOf('day').valueOf(); | |
374 | - break; | |
467 | + return currentDate.startOf('day').valueOf(); | |
375 | 468 | case QuickTimeInterval.DAY_BEFORE_YESTERDAY: |
376 | 469 | currentDate.subtract(2, 'days'); |
377 | - timeWindow.startTimeMs = currentDate.startOf('day').valueOf(); | |
378 | - timeWindow.endTimeMs = currentDate.endOf('day').valueOf(); | |
379 | - break; | |
470 | + return currentDate.startOf('day').valueOf(); | |
380 | 471 | case QuickTimeInterval.THIS_DAY_LAST_WEEK: |
381 | 472 | currentDate.subtract(1, 'weeks'); |
382 | - timeWindow.startTimeMs = currentDate.startOf('day').valueOf(); | |
383 | - timeWindow.endTimeMs = currentDate.endOf('day').valueOf(); | |
384 | - break; | |
473 | + return currentDate.startOf('day').valueOf(); | |
385 | 474 | case QuickTimeInterval.PREVIOUS_WEEK: |
386 | 475 | currentDate.subtract(1, 'weeks'); |
387 | - timeWindow.startTimeMs = currentDate.startOf('week').valueOf(); | |
388 | - timeWindow.endTimeMs = currentDate.endOf('week').valueOf(); | |
389 | - break; | |
476 | + return currentDate.startOf('week').valueOf(); | |
390 | 477 | case QuickTimeInterval.PREVIOUS_MONTH: |
391 | 478 | currentDate.subtract(1, 'months'); |
392 | - timeWindow.startTimeMs = currentDate.startOf('month').valueOf(); | |
393 | - timeWindow.endTimeMs = currentDate.endOf('month').valueOf(); | |
394 | - break; | |
479 | + return currentDate.startOf('month').valueOf(); | |
395 | 480 | case QuickTimeInterval.PREVIOUS_YEAR: |
396 | 481 | currentDate.subtract(1, 'years'); |
397 | - timeWindow.startTimeMs = currentDate.startOf('year').valueOf(); | |
398 | - timeWindow.endTimeMs = currentDate.endOf('year').valueOf(); | |
399 | - break; | |
482 | + return currentDate.startOf('year').valueOf(); | |
400 | 483 | case QuickTimeInterval.TODAY: |
401 | - timeWindow.startTimeMs = currentDate.startOf('day').valueOf(); | |
402 | - timeWindow.endTimeMs = currentDate.endOf('day').valueOf(); | |
403 | - break; | |
404 | 484 | case QuickTimeInterval.TODAY_SO_FAR: |
405 | - timeWindow.endTimeMs = currentDate.valueOf(); | |
406 | - timeWindow.startTimeMs = currentDate.startOf('day').valueOf(); | |
407 | - break; | |
485 | + return currentDate.startOf('day').valueOf(); | |
408 | 486 | case QuickTimeInterval.CURRENT_WEEK: |
409 | - timeWindow.startTimeMs = currentDate.startOf('week').valueOf(); | |
410 | - timeWindow.endTimeMs = currentDate.endOf('week').valueOf(); | |
411 | - break; | |
412 | 487 | case QuickTimeInterval.CURRENT_WEEK_SO_FAR: |
413 | - timeWindow.endTimeMs = currentDate.valueOf(); | |
414 | - timeWindow.startTimeMs = currentDate.startOf('week').valueOf(); | |
415 | - break; | |
488 | + return currentDate.startOf('week').valueOf(); | |
416 | 489 | case QuickTimeInterval.CURRENT_MONTH: |
417 | - timeWindow.startTimeMs = currentDate.startOf('month').valueOf(); | |
418 | - timeWindow.endTimeMs = currentDate.endOf('month').valueOf(); | |
419 | - break; | |
420 | 490 | case QuickTimeInterval.CURRENT_MONTH_SO_FAR: |
421 | - timeWindow.endTimeMs = currentDate.valueOf(); | |
422 | - timeWindow.startTimeMs = currentDate.startOf('month').valueOf(); | |
423 | - break; | |
491 | + return currentDate.startOf('month').valueOf(); | |
424 | 492 | case QuickTimeInterval.CURRENT_YEAR: |
425 | - timeWindow.startTimeMs = currentDate.startOf('year').valueOf(); | |
426 | - timeWindow.endTimeMs = currentDate.endOf('year').valueOf(); | |
427 | - break; | |
428 | 493 | case QuickTimeInterval.CURRENT_YEAR_SO_FAR: |
429 | - timeWindow.endTimeMs = currentDate.valueOf(); | |
430 | - timeWindow.startTimeMs = currentDate.startOf('year').valueOf(); | |
431 | - break; | |
494 | + return currentDate.startOf('year').valueOf(); | |
495 | + default: | |
496 | + return startTS; | |
432 | 497 | } |
433 | - return timeWindow; | |
434 | 498 | } |
435 | 499 | |
436 | 500 | export function quickTimeIntervalPeriod(interval: QuickTimeInterval): number { | ... | ... |