UI: Added new timewindow type - realtime interval

This commit is contained in:
Vladyslav_Prykhodko 2021-03-16 12:33:45 +02:00
parent f1193c1d5b
commit 0ebbee02db
8 changed files with 233 additions and 88 deletions

View File

@ -15,7 +15,12 @@
/// ///
import { SubscriptionData, SubscriptionDataHolder } from '@app/shared/models/telemetry/telemetry.models'; import { SubscriptionData, SubscriptionDataHolder } from '@app/shared/models/telemetry/telemetry.models';
import { AggregationType } from '@shared/models/time/time.models'; import {
AggregationType,
calculateIntervalEndTime,
calculateIntervalStartTime,
QuickTimeInterval
} from '@shared/models/time/time.models';
import { UtilsService } from '@core/services/utils.service'; import { UtilsService } from '@core/services/utils.service';
import { deepClone } from '@core/utils'; import { deepClone } from '@core/utils';
import Timeout = NodeJS.Timeout; import Timeout = NodeJS.Timeout;
@ -92,7 +97,8 @@ export class DataAggregator {
private interval: number, private interval: number,
private stateData: boolean, private stateData: boolean,
private utils: UtilsService, private utils: UtilsService,
private ignoreDataUpdateOnIntervalTick: boolean) { private ignoreDataUpdateOnIntervalTick: boolean,
private quickInterval: QuickTimeInterval) {
this.tsKeyNames.forEach((key) => { this.tsKeyNames.forEach((key) => {
this.dataBuffer[key] = []; this.dataBuffer[key] = [];
}); });
@ -138,7 +144,8 @@ export class DataAggregator {
this.startTs = startTs; this.startTs = startTs;
this.timeWindow = timeWindow; this.timeWindow = timeWindow;
this.interval = interval; this.interval = interval;
this.endTs = this.startTs + this.timeWindow; const endTs = this.startTs + this.timeWindow;
this.endTs = calculateIntervalEndTime(this.quickInterval, endTs);
this.elapsed = 0; this.elapsed = 0;
this.aggregationTimeout = Math.max(this.interval, 1000); this.aggregationTimeout = Math.max(this.interval, 1000);
this.resetPending = true; this.resetPending = true;
@ -161,7 +168,8 @@ export class DataAggregator {
if (!this.dataReceived) { if (!this.dataReceived) {
this.elapsed = 0; this.elapsed = 0;
this.dataReceived = true; this.dataReceived = true;
this.endTs = this.startTs + this.timeWindow; const endTs = this.startTs + this.timeWindow;
this.endTs = calculateIntervalEndTime(this.quickInterval, endTs);
} }
if (this.resetPending) { if (this.resetPending) {
this.resetPending = false; this.resetPending = false;
@ -197,8 +205,11 @@ export class DataAggregator {
if (!history) { if (!history) {
const delta = Math.floor(this.elapsed / this.interval); const delta = Math.floor(this.elapsed / this.interval);
if (delta || !this.data) { if (delta || !this.data) {
this.startTs += delta * this.interval; const tickTs = delta * this.interval;
this.endTs += delta * this.interval; const startTS = this.startTs + tickTs;
this.startTs = calculateIntervalStartTime(this.quickInterval, startTS);
const endTs = this.endTs + tickTs;
this.endTs = calculateIntervalEndTime(this.quickInterval, endTs);
this.data = this.updateData(); this.data = this.updateData();
this.elapsed = this.elapsed - delta * this.interval; this.elapsed = this.elapsed - delta * this.interval;
} }

View File

@ -752,7 +752,8 @@ export class EntityDataSubscription {
subsTw.aggregation.interval, subsTw.aggregation.interval,
subsTw.aggregation.stateData, subsTw.aggregation.stateData,
this.utils, this.utils,
this.entityDataSubscriptionOptions.ignoreDataUpdateOnIntervalTick this.entityDataSubscriptionOptions.ignoreDataUpdateOnIntervalTick,
subsTw.quickInterval
); );
} }

View File

@ -37,6 +37,8 @@ import {
} from '@app/shared/models/widget.models'; } from '@app/shared/models/widget.models';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { import {
calculateIntervalEndTime,
calculateIntervalStartTime,
createSubscriptionTimewindow, createSubscriptionTimewindow,
createTimewindowForComparison, createTimewindowForComparison,
SubscriptionTimewindow, SubscriptionTimewindow,
@ -1081,8 +1083,10 @@ export class WidgetSubscription implements IWidgetSubscription {
private updateTimewindow() { private updateTimewindow() {
this.timeWindow.interval = this.subscriptionTimewindow.aggregation.interval || 1000; this.timeWindow.interval = this.subscriptionTimewindow.aggregation.interval || 1000;
if (this.subscriptionTimewindow.realtimeWindowMs) { if (this.subscriptionTimewindow.realtimeWindowMs) {
this.timeWindow.maxTime = moment().valueOf() + this.timeWindow.stDiff; this.timeWindow.maxTime = calculateIntervalEndTime(
this.timeWindow.minTime = this.timeWindow.maxTime - this.subscriptionTimewindow.realtimeWindowMs; this.subscriptionTimewindow.quickInterval, moment().valueOf() + this.timeWindow.stDiff);
this.timeWindow.minTime = calculateIntervalStartTime(
this.subscriptionTimewindow.quickInterval, this.timeWindow.maxTime - this.subscriptionTimewindow.realtimeWindowMs);
} else if (this.subscriptionTimewindow.fixedWindow) { } else if (this.subscriptionTimewindow.fixedWindow) {
this.timeWindow.maxTime = this.subscriptionTimewindow.fixedWindow.endTimeMs; this.timeWindow.maxTime = this.subscriptionTimewindow.fixedWindow.endTimeMs;
this.timeWindow.minTime = this.subscriptionTimewindow.fixedWindow.startTimeMs; this.timeWindow.minTime = this.subscriptionTimewindow.fixedWindow.startTimeMs;
@ -1105,7 +1109,7 @@ export class WidgetSubscription implements IWidgetSubscription {
this.comparisonTimeWindow.interval = this.timewindowForComparison.aggregation.interval || 1000; this.comparisonTimeWindow.interval = this.timewindowForComparison.aggregation.interval || 1000;
if (this.timewindowForComparison.realtimeWindowMs) { if (this.timewindowForComparison.realtimeWindowMs) {
this.comparisonTimeWindow.maxTime = moment(this.timeWindow.maxTime).subtract(1, this.timeForComparison).valueOf(); this.comparisonTimeWindow.maxTime = moment(this.timeWindow.maxTime).subtract(1, this.timeForComparison).valueOf();
this.comparisonTimeWindow.minTime = this.comparisonTimeWindow.maxTime - this.timewindowForComparison.realtimeWindowMs; this.comparisonTimeWindow.minTime = moment(this.timeWindow.minTime).subtract(1, this.timeForComparison).valueOf();
} else if (this.timewindowForComparison.fixedWindow) { } else if (this.timewindowForComparison.fixedWindow) {
this.comparisonTimeWindow.maxTime = this.timewindowForComparison.fixedWindow.endTimeMs; this.comparisonTimeWindow.maxTime = this.timewindowForComparison.fixedWindow.endTimeMs;
this.comparisonTimeWindow.minTime = this.timewindowForComparison.fixedWindow.startTimeMs; this.comparisonTimeWindow.minTime = this.timewindowForComparison.fixedWindow.startTimeMs;

View File

@ -50,7 +50,7 @@ export class QuickTimeIntervalComponent implements OnInit, ControlValueAccessor
get intervals() { get intervals() {
if (this.onlyCurrentInterval) { if (this.onlyCurrentInterval) {
return this.allIntervals.filter(interval => interval.startsWith('TODAY_') || interval.startsWith('CURRENT_')); return this.allIntervals.filter(interval => interval.startsWith('TODAY') || interval.startsWith('CURRENT_'));
} }
return this.allIntervals; return this.allIntervals;
} }
@ -71,7 +71,6 @@ export class QuickTimeIntervalComponent implements OnInit, ControlValueAccessor
writeValue(interval: QuickTimeInterval): void { writeValue(interval: QuickTimeInterval): void {
this.modelValue = interval; this.modelValue = interval;
this.rendered = true;
} }
onIntervalChange() { onIntervalChange() {

View File

@ -21,16 +21,43 @@
<mat-tab-group dynamicHeight [ngClass]="{'tb-headless': historyOnly}" <mat-tab-group dynamicHeight [ngClass]="{'tb-headless': historyOnly}"
(selectedIndexChange)="timewindowForm.markAsDirty()" [(selectedIndex)]="timewindow.selectedTab"> (selectedIndexChange)="timewindowForm.markAsDirty()" [(selectedIndex)]="timewindow.selectedTab">
<mat-tab label="{{ 'timewindow.realtime' | translate }}"> <mat-tab label="{{ 'timewindow.realtime' | translate }}">
<div formGroupName="realtime" class="mat-content mat-padding" fxLayout="column"> <section fxLayout="row">
<section *ngIf="isEdit" fxLayout="column" style="padding-top: 8px; padding-left: 16px;">
<label class="tb-small hide-label" translate>timewindow.hide</label>
<mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="timewindow.hideInterval"
(ngModelChange)="onHideIntervalChanged()"></mat-checkbox>
</section>
<section fxLayout="column" fxFlex [fxShow]="isEdit || !timewindow.hideInterval">
<div formGroupName="realtime" class="mat-content mat-padding" style="padding-top: 8px;">
<mat-radio-group formControlName="realtimeType">
<mat-radio-button [value]="realtimeTypes.LAST_INTERVAL" color="primary">
<section fxLayout="column">
<span translate>timewindow.last</span>
<tb-timeinterval <tb-timeinterval
[(hideFlag)]="timewindow.hideInterval"
(hideFlagChange)="onHideIntervalChanged()"
[isEdit]="isEdit"
formControlName="timewindowMs" formControlName="timewindowMs"
predefinedName="timewindow.last" predefinedName="timewindow.last"
[required]="timewindow.selectedTab === timewindowTypes.REALTIME" [fxShow]="timewindowForm.get('realtime.realtimeType').value === realtimeTypes.LAST_INTERVAL"
[required]="timewindow.selectedTab === timewindowTypes.REALTIME &&
timewindowForm.get('realtime.realtimeType').value === realtimeTypes.LAST_INTERVAL"
style="padding-top: 8px;"></tb-timeinterval> style="padding-top: 8px;"></tb-timeinterval>
</section>
</mat-radio-button>
<mat-radio-button [value]="realtimeTypes.INTERVAL" color="primary">
<section fxLayout="column">
<span translate>timewindow.interval</span>
<tb-quick-time-interval
formControlName="quickInterval"
onlyCurrentInterval="true"
[fxShow]="timewindowForm.get('realtime.realtimeType').value === realtimeTypes.INTERVAL"
[required]="timewindow.selectedTab === timewindowTypes.HISTORY &&
timewindowForm.get('realtime.realtimeType').value === realtimeTypes.INTERVAL"
style="padding-top: 8px; min-width: 364px"></tb-quick-time-interval>
</section>
</mat-radio-button>
</mat-radio-group>
</div> </div>
</section>
</section>
</mat-tab> </mat-tab>
<mat-tab label="{{ 'timewindow.history' | translate }}"> <mat-tab label="{{ 'timewindow.history' | translate }}">
<section fxLayout="row"> <section fxLayout="row">

View File

@ -19,7 +19,9 @@ import {
aggregationTranslations, aggregationTranslations,
AggregationType, AggregationType,
DAY, DAY,
HistoryWindowType, quickTimeIntervalPeriod, HistoryWindowType,
quickTimeIntervalPeriod,
RealtimeWindowType,
Timewindow, Timewindow,
TimewindowType TimewindowType
} from '@shared/models/time/time.models'; } from '@shared/models/time/time.models';
@ -60,6 +62,8 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit {
historyTypes = HistoryWindowType; historyTypes = HistoryWindowType;
realtimeTypes = RealtimeWindowType;
timewindowTypes = TimewindowType; timewindowTypes = TimewindowType;
aggregationTypes = AggregationType; aggregationTypes = AggregationType;
@ -89,6 +93,11 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit {
this.timewindowForm = this.fb.group({ this.timewindowForm = this.fb.group({
realtime: this.fb.group( realtime: this.fb.group(
{ {
realtimeType: this.fb.control({
value: this.timewindow.realtime && typeof this.timewindow.realtime.realtimeType !== 'undefined'
? this.timewindow.realtime.realtimeType : RealtimeWindowType.LAST_INTERVAL,
disabled: hideInterval
}),
timewindowMs: [ timewindowMs: [
this.timewindow.realtime && typeof this.timewindow.realtime.timewindowMs !== 'undefined' this.timewindow.realtime && typeof this.timewindow.realtime.timewindowMs !== 'undefined'
? this.timewindow.realtime.timewindowMs : null ? this.timewindow.realtime.timewindowMs : null
@ -96,7 +105,12 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit {
interval: [ interval: [
this.timewindow.realtime && typeof this.timewindow.realtime.interval !== 'undefined' this.timewindow.realtime && typeof this.timewindow.realtime.interval !== 'undefined'
? this.timewindow.realtime.interval : null ? this.timewindow.realtime.interval : null
] ],
quickInterval: this.fb.control({
value: this.timewindow.realtime && typeof this.timewindow.realtime.quickInterval !== 'undefined'
? this.timewindow.realtime.quickInterval : null,
disabled: hideInterval
})
} }
), ),
history: this.fb.group( history: this.fb.group(
@ -124,7 +138,7 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit {
value: this.timewindow.history && typeof this.timewindow.history.quickInterval !== 'undefined' value: this.timewindow.history && typeof this.timewindow.history.quickInterval !== 'undefined'
? this.timewindow.history.quickInterval : null, ? this.timewindow.history.quickInterval : null,
disabled: hideInterval disabled: hideInterval
}), })
} }
), ),
aggregation: this.fb.group( aggregation: this.fb.group(
@ -147,7 +161,9 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit {
update() { update() {
const timewindowFormValue = this.timewindowForm.getRawValue(); const timewindowFormValue = this.timewindowForm.getRawValue();
this.timewindow.realtime = { this.timewindow.realtime = {
realtimeType: timewindowFormValue.realtime.realtimeType,
timewindowMs: timewindowFormValue.realtime.timewindowMs, timewindowMs: timewindowFormValue.realtime.timewindowMs,
quickInterval: timewindowFormValue.realtime.quickInterval,
interval: timewindowFormValue.realtime.interval interval: timewindowFormValue.realtime.interval
}; };
this.timewindow.history = { this.timewindow.history = {
@ -180,11 +196,23 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit {
} }
minRealtimeAggInterval() { minRealtimeAggInterval() {
return this.timeService.minIntervalLimit(this.timewindowForm.get('realtime.timewindowMs').value); return this.timeService.minIntervalLimit(this.currentRealtimeTimewindow());
} }
maxRealtimeAggInterval() { maxRealtimeAggInterval() {
return this.timeService.maxIntervalLimit(this.timewindowForm.get('realtime.timewindowMs').value); return this.timeService.maxIntervalLimit(this.currentRealtimeTimewindow());
}
currentRealtimeTimewindow(): number {
const timeWindowFormValue = this.timewindowForm.getRawValue();
switch (timeWindowFormValue.realtime.realtimeType) {
case RealtimeWindowType.LAST_INTERVAL:
return timeWindowFormValue.realtime.timewindowMs;
case RealtimeWindowType.INTERVAL:
return quickTimeIntervalPeriod(timeWindowFormValue.realtime.quickInterval);
default:
return DAY;
}
} }
minHistoryAggInterval() { minHistoryAggInterval() {
@ -215,11 +243,17 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit {
this.timewindowForm.get('history.timewindowMs').disable({emitEvent: false}); this.timewindowForm.get('history.timewindowMs').disable({emitEvent: false});
this.timewindowForm.get('history.fixedTimewindow').disable({emitEvent: false}); this.timewindowForm.get('history.fixedTimewindow').disable({emitEvent: false});
this.timewindowForm.get('history.quickInterval').disable({emitEvent: false}); this.timewindowForm.get('history.quickInterval').disable({emitEvent: false});
this.timewindowForm.get('realtime.realtimeType').disable({emitEvent: false});
this.timewindowForm.get('realtime.timewindowMs').disable({emitEvent: false});
this.timewindowForm.get('realtime.quickInterval').disable({emitEvent: false});
} else { } else {
this.timewindowForm.get('history.historyType').enable({emitEvent: false}); this.timewindowForm.get('history.historyType').enable({emitEvent: false});
this.timewindowForm.get('history.timewindowMs').enable({emitEvent: false}); this.timewindowForm.get('history.timewindowMs').enable({emitEvent: false});
this.timewindowForm.get('history.fixedTimewindow').enable({emitEvent: false}); this.timewindowForm.get('history.fixedTimewindow').enable({emitEvent: false});
this.timewindowForm.get('history.quickInterval').enable({emitEvent: false}); this.timewindowForm.get('history.quickInterval').enable({emitEvent: false});
this.timewindowForm.get('realtime.realtimeType').enable({emitEvent: false});
this.timewindowForm.get('realtime.timewindowMs').enable({emitEvent: false});
this.timewindowForm.get('realtime.quickInterval').enable({emitEvent: false});
} }
this.timewindowForm.markAsDirty(); this.timewindowForm.markAsDirty();
} }

View File

@ -34,6 +34,7 @@ import {
HistoryWindowType, HistoryWindowType,
initModelFromDefaultTimewindow, initModelFromDefaultTimewindow,
QuickTimeIntervalTranslationMap, QuickTimeIntervalTranslationMap,
RealtimeWindowType,
Timewindow, Timewindow,
TimewindowType TimewindowType
} from '@shared/models/time/time.models'; } from '@shared/models/time/time.models';
@ -273,9 +274,13 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
updateDisplayValue() { updateDisplayValue() {
if (this.innerValue.selectedTab === TimewindowType.REALTIME && !this.historyOnly) { if (this.innerValue.selectedTab === TimewindowType.REALTIME && !this.historyOnly) {
this.innerValue.displayValue = this.translate.instant('timewindow.realtime') + ' - ' + this.innerValue.displayValue = this.translate.instant('timewindow.realtime') + ' - ';
this.translate.instant('timewindow.last-prefix') + ' ' + if (this.innerValue.realtime.realtimeType === RealtimeWindowType.INTERVAL) {
this.innerValue.displayValue += this.translate.instant(QuickTimeIntervalTranslationMap.get(this.innerValue.realtime.quickInterval));
} else {
this.innerValue.displayValue += this.translate.instant('timewindow.last-prefix') + ' ' +
this.millisecondsToTimeStringPipe.transform(this.innerValue.realtime.timewindowMs); this.millisecondsToTimeStringPipe.transform(this.innerValue.realtime.timewindowMs);
}
} else { } else {
this.innerValue.displayValue = !this.historyOnly ? (this.translate.instant('timewindow.history') + ' - ') : ''; this.innerValue.displayValue = !this.historyOnly ? (this.translate.instant('timewindow.history') + ' - ') : '';
if (this.innerValue.history.historyType === HistoryWindowType.LAST_INTERVAL) { if (this.innerValue.history.historyType === HistoryWindowType.LAST_INTERVAL) {

View File

@ -15,7 +15,7 @@
/// ///
import { TimeService } from '@core/services/time.service'; import { TimeService } from '@core/services/time.service';
import { deepClone, isDefined, isUndefined } from '@app/core/utils'; import { deepClone, isDefined, isDefinedAndNotNull, isUndefined } from '@app/core/utils';
import * as moment_ from 'moment'; import * as moment_ from 'moment';
import { Observable } from 'rxjs/internal/Observable'; import { Observable } from 'rxjs/internal/Observable';
import { from, of } from 'rxjs'; import { from, of } from 'rxjs';
@ -35,6 +35,11 @@ export enum TimewindowType {
HISTORY HISTORY
} }
export enum RealtimeWindowType {
LAST_INTERVAL,
INTERVAL
}
export enum HistoryWindowType { export enum HistoryWindowType {
LAST_INTERVAL, LAST_INTERVAL,
FIXED, FIXED,
@ -47,6 +52,10 @@ export interface IntervalWindow {
quickInterval?: QuickTimeInterval; quickInterval?: QuickTimeInterval;
} }
export interface RealtimeWindow extends IntervalWindow{
realtimeType?: RealtimeWindowType;
}
export interface FixedWindow { export interface FixedWindow {
startTimeMs: number; startTimeMs: number;
endTimeMs: number; endTimeMs: number;
@ -89,7 +98,7 @@ export interface Timewindow {
hideAggregation?: boolean; hideAggregation?: boolean;
hideAggInterval?: boolean; hideAggInterval?: boolean;
selectedTab?: TimewindowType; selectedTab?: TimewindowType;
realtime?: IntervalWindow; realtime?: RealtimeWindow;
history?: HistoryWindow; history?: HistoryWindow;
aggregation?: Aggregation; aggregation?: Aggregation;
} }
@ -102,6 +111,7 @@ export interface SubscriptionAggregation extends Aggregation {
export interface SubscriptionTimewindow { export interface SubscriptionTimewindow {
startTs?: number; startTs?: number;
quickInterval?: QuickTimeInterval;
realtimeWindowMs?: number; realtimeWindowMs?: number;
fixedWindow?: FixedWindow; fixedWindow?: FixedWindow;
aggregation?: SubscriptionAggregation; aggregation?: SubscriptionAggregation;
@ -168,8 +178,10 @@ export function defaultTimewindow(timeService: TimeService): Timewindow {
hideAggInterval: false, hideAggInterval: false,
selectedTab: TimewindowType.REALTIME, selectedTab: TimewindowType.REALTIME,
realtime: { realtime: {
realtimeType: RealtimeWindowType.LAST_INTERVAL,
interval: SECOND, interval: SECOND,
timewindowMs: MINUTE timewindowMs: MINUTE,
quickInterval: QuickTimeInterval.TODAY
}, },
history: { history: {
historyType: HistoryWindowType.LAST_INTERVAL, historyType: HistoryWindowType.LAST_INTERVAL,
@ -208,7 +220,20 @@ export function initModelFromDefaultTimewindow(value: Timewindow, timeService: T
if (isDefined(value.realtime.interval)) { if (isDefined(value.realtime.interval)) {
model.realtime.interval = value.realtime.interval; model.realtime.interval = value.realtime.interval;
} }
if (isUndefined(value.realtime.realtimeType)) {
if (isDefined(value.realtime.quickInterval)) {
model.realtime.realtimeType = RealtimeWindowType.INTERVAL;
} else {
model.realtime.realtimeType = RealtimeWindowType.LAST_INTERVAL;
}
} else {
model.realtime.realtimeType = value.realtime.realtimeType;
}
if (model.realtime.realtimeType === RealtimeWindowType.INTERVAL) {
model.realtime.quickInterval = value.realtime.quickInterval;
} else {
model.realtime.timewindowMs = value.realtime.timewindowMs; model.realtime.timewindowMs = value.realtime.timewindowMs;
}
} else { } else {
if (isDefined(value.history.interval)) { if (isDefined(value.history.interval)) {
model.history.interval = value.history.interval; model.history.interval = value.history.interval;
@ -309,14 +334,27 @@ export function createSubscriptionTimewindow(timewindow: Timewindow, stDiff: num
selectedTab = isDefined(timewindow.realtime) ? TimewindowType.REALTIME : TimewindowType.HISTORY; selectedTab = isDefined(timewindow.realtime) ? TimewindowType.REALTIME : TimewindowType.HISTORY;
} }
if (selectedTab === TimewindowType.REALTIME) { if (selectedTab === TimewindowType.REALTIME) {
let realtimeType = timewindow.realtime.realtimeType;
if (isUndefined(realtimeType)) {
if (isDefined(timewindow.realtime.quickInterval)) {
realtimeType = RealtimeWindowType.INTERVAL;
} else {
realtimeType = RealtimeWindowType.LAST_INTERVAL;
}
}
if (realtimeType === RealtimeWindowType.INTERVAL) {
subscriptionTimewindow.realtimeWindowMs = getSubscriptionRealtimeWindowFromTimeInterval(timewindow.realtime.quickInterval);
subscriptionTimewindow.quickInterval = timewindow.realtime.quickInterval;
} else {
subscriptionTimewindow.realtimeWindowMs = timewindow.realtime.timewindowMs; subscriptionTimewindow.realtimeWindowMs = timewindow.realtime.timewindowMs;
}
subscriptionTimewindow.aggregation.interval = subscriptionTimewindow.aggregation.interval =
timeService.boundIntervalToTimewindow(subscriptionTimewindow.realtimeWindowMs, timewindow.realtime.interval, timeService.boundIntervalToTimewindow(subscriptionTimewindow.realtimeWindowMs, timewindow.realtime.interval,
subscriptionTimewindow.aggregation.type); subscriptionTimewindow.aggregation.type);
subscriptionTimewindow.startTs = Date.now() + stDiff - subscriptionTimewindow.realtimeWindowMs; subscriptionTimewindow.startTs = Date.now() + stDiff - subscriptionTimewindow.realtimeWindowMs;
const startDiff = subscriptionTimewindow.startTs % subscriptionTimewindow.aggregation.interval; const startDiff = subscriptionTimewindow.startTs % subscriptionTimewindow.aggregation.interval;
aggTimewindow = subscriptionTimewindow.realtimeWindowMs; aggTimewindow = subscriptionTimewindow.realtimeWindowMs;
if (startDiff) { if (startDiff && realtimeType !== RealtimeWindowType.INTERVAL) {
subscriptionTimewindow.startTs -= startDiff; subscriptionTimewindow.startTs -= startDiff;
aggTimewindow += subscriptionTimewindow.aggregation.interval; aggTimewindow += subscriptionTimewindow.aggregation.interval;
} }
@ -339,7 +377,11 @@ export function createSubscriptionTimewindow(timewindow: Timewindow, stDiff: num
}; };
aggTimewindow = timewindow.history.timewindowMs; aggTimewindow = timewindow.history.timewindowMs;
} else if (historyType === HistoryWindowType.INTERVAL) { } else if (historyType === HistoryWindowType.INTERVAL) {
subscriptionTimewindow.fixedWindow = createSubscriptionTimeWindowFromQuickKTimeInterval(timewindow.history.quickInterval); const currentDate = moment();
subscriptionTimewindow.fixedWindow = {
startTimeMs: calculateIntervalStartTime(timewindow.history.quickInterval, null, currentDate),
endTimeMs: calculateIntervalEndTime(timewindow.history.quickInterval, null, currentDate)
};
aggTimewindow = subscriptionTimewindow.fixedWindow.endTimeMs - subscriptionTimewindow.fixedWindow.startTimeMs; aggTimewindow = subscriptionTimewindow.fixedWindow.endTimeMs - subscriptionTimewindow.fixedWindow.startTimeMs;
} else { } else {
subscriptionTimewindow.fixedWindow = { subscriptionTimewindow.fixedWindow = {
@ -360,77 +402,99 @@ export function createSubscriptionTimewindow(timewindow: Timewindow, stDiff: num
return subscriptionTimewindow; return subscriptionTimewindow;
} }
export function createSubscriptionTimeWindowFromQuickKTimeInterval(interval: QuickTimeInterval): FixedWindow { function getSubscriptionRealtimeWindowFromTimeInterval(interval: QuickTimeInterval): number {
const currentDate = moment(); const currentDate = moment();
const timeWindow = { switch (interval) {
startTimeMs: 0, case QuickTimeInterval.TODAY:
endTimeMs: 0 case QuickTimeInterval.TODAY_SO_FAR:
}; return currentDate.diff(currentDate.clone().startOf('day'));
case QuickTimeInterval.CURRENT_WEEK:
case QuickTimeInterval.CURRENT_WEEK_SO_FAR:
return currentDate.diff(currentDate.clone().startOf('week'));
case QuickTimeInterval.CURRENT_MONTH:
case QuickTimeInterval.CURRENT_MONTH_SO_FAR:
return currentDate.diff(currentDate.clone().startOf('month'));
case QuickTimeInterval.CURRENT_YEAR:
case QuickTimeInterval.CURRENT_YEAR_SO_FAR:
return currentDate.diff(currentDate.clone().startOf('year'));
}
}
export function calculateIntervalEndTime(interval: QuickTimeInterval, endTs = 0, nowDate?: moment_.Moment): number {
const currentDate = isDefinedAndNotNull(nowDate) ? nowDate.clone() : moment();
switch (interval) { switch (interval) {
case QuickTimeInterval.YESTERDAY: case QuickTimeInterval.YESTERDAY:
currentDate.subtract(1, 'days'); currentDate.subtract(1, 'days');
timeWindow.startTimeMs = currentDate.startOf('day').valueOf(); return currentDate.endOf('day').valueOf();
timeWindow.endTimeMs = currentDate.endOf('day').valueOf();
break;
case QuickTimeInterval.DAY_BEFORE_YESTERDAY: case QuickTimeInterval.DAY_BEFORE_YESTERDAY:
currentDate.subtract(2, 'days'); currentDate.subtract(2, 'days');
timeWindow.startTimeMs = currentDate.startOf('day').valueOf(); return currentDate.endOf('day').valueOf();
timeWindow.endTimeMs = currentDate.endOf('day').valueOf();
break;
case QuickTimeInterval.THIS_DAY_LAST_WEEK: case QuickTimeInterval.THIS_DAY_LAST_WEEK:
currentDate.subtract(1, 'weeks'); currentDate.subtract(1, 'weeks');
timeWindow.startTimeMs = currentDate.startOf('day').valueOf(); return currentDate.endOf('day').valueOf();
timeWindow.endTimeMs = currentDate.endOf('day').valueOf();
break;
case QuickTimeInterval.PREVIOUS_WEEK: case QuickTimeInterval.PREVIOUS_WEEK:
currentDate.subtract(1, 'weeks'); currentDate.subtract(1, 'weeks');
timeWindow.startTimeMs = currentDate.startOf('week').valueOf(); return currentDate.endOf('week').valueOf();
timeWindow.endTimeMs = currentDate.endOf('week').valueOf();
break;
case QuickTimeInterval.PREVIOUS_MONTH: case QuickTimeInterval.PREVIOUS_MONTH:
currentDate.subtract(1, 'months'); currentDate.subtract(1, 'months');
timeWindow.startTimeMs = currentDate.startOf('month').valueOf(); return currentDate.endOf('month').valueOf();
timeWindow.endTimeMs = currentDate.endOf('month').valueOf();
break;
case QuickTimeInterval.PREVIOUS_YEAR: case QuickTimeInterval.PREVIOUS_YEAR:
currentDate.subtract(1, 'years'); currentDate.subtract(1, 'years');
timeWindow.startTimeMs = currentDate.startOf('year').valueOf(); return currentDate.endOf('year').valueOf();
timeWindow.endTimeMs = currentDate.endOf('year').valueOf();
break;
case QuickTimeInterval.TODAY: case QuickTimeInterval.TODAY:
timeWindow.startTimeMs = currentDate.startOf('day').valueOf(); return currentDate.endOf('day').valueOf();
timeWindow.endTimeMs = currentDate.endOf('day').valueOf();
break;
case QuickTimeInterval.TODAY_SO_FAR:
timeWindow.endTimeMs = currentDate.valueOf();
timeWindow.startTimeMs = currentDate.startOf('day').valueOf();
break;
case QuickTimeInterval.CURRENT_WEEK: case QuickTimeInterval.CURRENT_WEEK:
timeWindow.startTimeMs = currentDate.startOf('week').valueOf(); return currentDate.endOf('week').valueOf();
timeWindow.endTimeMs = currentDate.endOf('week').valueOf();
break;
case QuickTimeInterval.CURRENT_WEEK_SO_FAR:
timeWindow.endTimeMs = currentDate.valueOf();
timeWindow.startTimeMs = currentDate.startOf('week').valueOf();
break;
case QuickTimeInterval.CURRENT_MONTH: case QuickTimeInterval.CURRENT_MONTH:
timeWindow.startTimeMs = currentDate.startOf('month').valueOf(); return currentDate.endOf('month').valueOf();
timeWindow.endTimeMs = currentDate.endOf('month').valueOf();
break;
case QuickTimeInterval.CURRENT_MONTH_SO_FAR:
timeWindow.endTimeMs = currentDate.valueOf();
timeWindow.startTimeMs = currentDate.startOf('month').valueOf();
break;
case QuickTimeInterval.CURRENT_YEAR: case QuickTimeInterval.CURRENT_YEAR:
timeWindow.startTimeMs = currentDate.startOf('year').valueOf(); return currentDate.endOf('year').valueOf();
timeWindow.endTimeMs = currentDate.endOf('year').valueOf(); case QuickTimeInterval.TODAY_SO_FAR:
break; case QuickTimeInterval.CURRENT_WEEK_SO_FAR:
case QuickTimeInterval.CURRENT_MONTH_SO_FAR:
case QuickTimeInterval.CURRENT_YEAR_SO_FAR: case QuickTimeInterval.CURRENT_YEAR_SO_FAR:
timeWindow.endTimeMs = currentDate.valueOf(); return currentDate.valueOf();
timeWindow.startTimeMs = currentDate.startOf('year').valueOf(); default:
break; return endTs;
}
}
export function calculateIntervalStartTime(interval: QuickTimeInterval, startTS = 0, nowDate?: moment_.Moment): number {
const currentDate = isDefinedAndNotNull(nowDate) ? nowDate.clone() : moment();
switch (interval) {
case QuickTimeInterval.YESTERDAY:
currentDate.subtract(1, 'days');
return currentDate.startOf('day').valueOf();
case QuickTimeInterval.DAY_BEFORE_YESTERDAY:
currentDate.subtract(2, 'days');
return currentDate.startOf('day').valueOf();
case QuickTimeInterval.THIS_DAY_LAST_WEEK:
currentDate.subtract(1, 'weeks');
return currentDate.startOf('day').valueOf();
case QuickTimeInterval.PREVIOUS_WEEK:
currentDate.subtract(1, 'weeks');
return currentDate.startOf('week').valueOf();
case QuickTimeInterval.PREVIOUS_MONTH:
currentDate.subtract(1, 'months');
return currentDate.startOf('month').valueOf();
case QuickTimeInterval.PREVIOUS_YEAR:
currentDate.subtract(1, 'years');
return currentDate.startOf('year').valueOf();
case QuickTimeInterval.TODAY:
case QuickTimeInterval.TODAY_SO_FAR:
return currentDate.startOf('day').valueOf();
case QuickTimeInterval.CURRENT_WEEK:
case QuickTimeInterval.CURRENT_WEEK_SO_FAR:
return currentDate.startOf('week').valueOf();
case QuickTimeInterval.CURRENT_MONTH:
case QuickTimeInterval.CURRENT_MONTH_SO_FAR:
return currentDate.startOf('month').valueOf();
case QuickTimeInterval.CURRENT_YEAR:
case QuickTimeInterval.CURRENT_YEAR_SO_FAR:
return currentDate.startOf('year').valueOf();
default:
return startTS;
} }
return timeWindow;
} }
export function quickTimeIntervalPeriod(interval: QuickTimeInterval): number { export function quickTimeIntervalPeriod(interval: QuickTimeInterval): number {