UI: Added comparison support timezone
This commit is contained in:
		
							parent
							
								
									0a27101e1f
								
							
						
					
					
						commit
						f4b6798a16
					
				@ -18,8 +18,10 @@ import { SubscriptionData, SubscriptionDataHolder } from '@app/shared/models/tel
 | 
			
		||||
import {
 | 
			
		||||
  AggregationType,
 | 
			
		||||
  calculateIntervalEndTime,
 | 
			
		||||
  calculateIntervalStartTime, getCurrentTime,
 | 
			
		||||
  QuickTimeInterval, SubscriptionTimewindow
 | 
			
		||||
  calculateIntervalStartTime,
 | 
			
		||||
  getCurrentTime,
 | 
			
		||||
  getCurrentTimeForComparison,
 | 
			
		||||
  SubscriptionTimewindow
 | 
			
		||||
} from '@shared/models/time/time.models';
 | 
			
		||||
import { UtilsService } from '@core/services/utils.service';
 | 
			
		||||
import { deepClone } from '@core/utils';
 | 
			
		||||
@ -139,7 +141,8 @@ export class DataAggregator {
 | 
			
		||||
    this.intervalScheduledTime = this.utils.currentPerfTime();
 | 
			
		||||
    this.startTs = this.subsTw.startTs + this.subsTw.tsOffset;
 | 
			
		||||
    if (this.subsTw.quickInterval) {
 | 
			
		||||
      this.endTs = calculateIntervalEndTime(this.subsTw.quickInterval, null, this.subsTw.timezone) + this.subsTw.tsOffset;
 | 
			
		||||
      const currentDate = this.getCurrentTime();
 | 
			
		||||
      this.endTs = calculateIntervalEndTime(this.subsTw.quickInterval, currentDate) + this.subsTw.tsOffset;
 | 
			
		||||
    } else {
 | 
			
		||||
      this.endTs = this.startTs + this.subsTw.aggregation.timeWindow;
 | 
			
		||||
    }
 | 
			
		||||
@ -166,7 +169,8 @@ export class DataAggregator {
 | 
			
		||||
        this.elapsed = 0;
 | 
			
		||||
        this.dataReceived = true;
 | 
			
		||||
        if (this.subsTw.quickInterval) {
 | 
			
		||||
          this.endTs = calculateIntervalEndTime(this.subsTw.quickInterval, null, this.subsTw.timezone) + this.subsTw.tsOffset;
 | 
			
		||||
          const currentDate = this.getCurrentTime();
 | 
			
		||||
          this.endTs = calculateIntervalEndTime(this.subsTw.quickInterval, currentDate) + this.subsTw.tsOffset;
 | 
			
		||||
        } else {
 | 
			
		||||
          this.endTs = this.startTs + this.subsTw.aggregation.timeWindow;
 | 
			
		||||
        }
 | 
			
		||||
@ -207,7 +211,7 @@ export class DataAggregator {
 | 
			
		||||
      if (delta || !this.data) {
 | 
			
		||||
        const tickTs = delta * this.subsTw.aggregation.interval;
 | 
			
		||||
        if (this.subsTw.quickInterval) {
 | 
			
		||||
          const currentDate = getCurrentTime(this.subsTw.timezone);
 | 
			
		||||
          const currentDate = this.getCurrentTime();
 | 
			
		||||
          this.startTs = calculateIntervalStartTime(this.subsTw.quickInterval, currentDate) + this.subsTw.tsOffset;
 | 
			
		||||
          this.endTs = calculateIntervalEndTime(this.subsTw.quickInterval, currentDate) + this.subsTw.tsOffset;
 | 
			
		||||
        } else {
 | 
			
		||||
@ -356,5 +360,13 @@ export class DataAggregator {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private getCurrentTime() {
 | 
			
		||||
    if (this.subsTw.timeForComparison) {
 | 
			
		||||
      return getCurrentTimeForComparison(this.subsTw.timeForComparison, this.subsTw.timezone);
 | 
			
		||||
    } else {
 | 
			
		||||
      return getCurrentTime(this.subsTw.timezone);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -36,18 +36,6 @@ import {
 | 
			
		||||
  widgetType
 | 
			
		||||
} from '@app/shared/models/widget.models';
 | 
			
		||||
import { HttpErrorResponse } from '@angular/common/http';
 | 
			
		||||
import {
 | 
			
		||||
  calculateIntervalEndTime,
 | 
			
		||||
  calculateIntervalStartTime,
 | 
			
		||||
  calculateTsOffset,
 | 
			
		||||
  createSubscriptionTimewindow,
 | 
			
		||||
  createTimewindowForComparison,
 | 
			
		||||
  getCurrentTime,
 | 
			
		||||
  SubscriptionTimewindow,
 | 
			
		||||
  Timewindow,
 | 
			
		||||
  toHistoryTimewindow,
 | 
			
		||||
  WidgetTimewindow
 | 
			
		||||
} from '@app/shared/models/time/time.models';
 | 
			
		||||
import { forkJoin, Observable, of, ReplaySubject, Subject, throwError } from 'rxjs';
 | 
			
		||||
import { CancelAnimationFrame } from '@core/services/raf.service';
 | 
			
		||||
import { EntityType } from '@shared/models/entity-type.models';
 | 
			
		||||
@ -68,6 +56,19 @@ import {
 | 
			
		||||
} from '@shared/models/query/query.models';
 | 
			
		||||
import { map } from 'rxjs/operators';
 | 
			
		||||
import { AlarmDataListener } from '@core/api/alarm-data.service';
 | 
			
		||||
import {
 | 
			
		||||
  calculateIntervalEndTime,
 | 
			
		||||
  calculateIntervalStartTime,
 | 
			
		||||
  calculateTsOffset,
 | 
			
		||||
  createSubscriptionTimewindow,
 | 
			
		||||
  createTimewindowForComparison,
 | 
			
		||||
  getCurrentTime,
 | 
			
		||||
  isHistoryTypeTimewindow,
 | 
			
		||||
  SubscriptionTimewindow,
 | 
			
		||||
  Timewindow,
 | 
			
		||||
  toHistoryTimewindow,
 | 
			
		||||
  WidgetTimewindow
 | 
			
		||||
} from '@app/shared/models/time/time.models';
 | 
			
		||||
 | 
			
		||||
const moment = moment_;
 | 
			
		||||
 | 
			
		||||
@ -387,7 +388,7 @@ export class WidgetSubscription implements IWidgetSubscription {
 | 
			
		||||
      this.notifyDataLoaded();
 | 
			
		||||
      return of(null);
 | 
			
		||||
    }
 | 
			
		||||
    if (this.comparisonEnabled) {
 | 
			
		||||
    if (this.comparisonEnabled && isHistoryTypeTimewindow(this.timeWindowConfig)) {
 | 
			
		||||
      const additionalDatasources: Datasource[] = [];
 | 
			
		||||
      this.configuredDatasources.forEach((datasource, datasourceIndex) => {
 | 
			
		||||
        const additionalDataKeys: DataKey[] = [];
 | 
			
		||||
@ -420,14 +421,14 @@ export class WidgetSubscription implements IWidgetSubscription {
 | 
			
		||||
        initialPageDataChanged: this.initialPageDataChanged.bind(this),
 | 
			
		||||
        dataUpdated: this.dataUpdated.bind(this),
 | 
			
		||||
        updateRealtimeSubscription: () => {
 | 
			
		||||
          if (this.comparisonEnabled && datasource.isAdditional) {
 | 
			
		||||
          if (this.comparisonEnabled && datasource.isAdditional && isHistoryTypeTimewindow(this.timeWindowConfig)) {
 | 
			
		||||
            return this.updateSubscriptionForComparison();
 | 
			
		||||
          } else {
 | 
			
		||||
            return this.updateRealtimeSubscription();
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        setRealtimeSubscription: (subscriptionTimewindow) => {
 | 
			
		||||
          if (this.comparisonEnabled && datasource.isAdditional) {
 | 
			
		||||
          if (this.comparisonEnabled && datasource.isAdditional && isHistoryTypeTimewindow(this.timeWindowConfig)) {
 | 
			
		||||
            this.updateSubscriptionForComparison(subscriptionTimewindow);
 | 
			
		||||
          } else {
 | 
			
		||||
            this.updateRealtimeSubscription(deepClone(subscriptionTimewindow));
 | 
			
		||||
@ -888,7 +889,7 @@ export class WidgetSubscription implements IWidgetSubscription {
 | 
			
		||||
    if (!this.hasDataPageLink) {
 | 
			
		||||
      if (this.type === widgetType.timeseries && this.timeWindowConfig) {
 | 
			
		||||
        this.updateRealtimeSubscription();
 | 
			
		||||
        if (this.comparisonEnabled) {
 | 
			
		||||
        if (this.comparisonEnabled && isHistoryTypeTimewindow(this.timeWindowConfig)) {
 | 
			
		||||
          this.updateSubscriptionForComparison();
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@ -904,7 +905,7 @@ export class WidgetSubscription implements IWidgetSubscription {
 | 
			
		||||
      const forceUpdate = !this.datasources.length;
 | 
			
		||||
      const notifyDataLoaded = !this.entityDataListeners.filter((listener) => listener.subscription ? true : false).length;
 | 
			
		||||
      this.entityDataListeners.forEach((listener) => {
 | 
			
		||||
        if (this.comparisonEnabled && listener.configDatasource.isAdditional) {
 | 
			
		||||
        if (this.comparisonEnabled && listener.configDatasource.isAdditional && isHistoryTypeTimewindow(this.timeWindowConfig)) {
 | 
			
		||||
          listener.subscriptionTimewindow = this.timewindowForComparison;
 | 
			
		||||
        } else {
 | 
			
		||||
          listener.subscriptionTimewindow = this.subscriptionTimewindow;
 | 
			
		||||
@ -1147,8 +1148,8 @@ export class WidgetSubscription implements IWidgetSubscription {
 | 
			
		||||
      this.comparisonTimeWindow.maxTime = moment(this.timeWindow.maxTime).subtract(1, this.timeForComparison).valueOf();
 | 
			
		||||
      this.comparisonTimeWindow.minTime = moment(this.timeWindow.minTime).subtract(1, this.timeForComparison).valueOf();
 | 
			
		||||
    } else if (this.timewindowForComparison.fixedWindow) {
 | 
			
		||||
      this.comparisonTimeWindow.maxTime = this.timewindowForComparison.fixedWindow.endTimeMs + this.timewindowForComparison.tsOffset;
 | 
			
		||||
      this.comparisonTimeWindow.minTime = this.timewindowForComparison.fixedWindow.startTimeMs + this.timewindowForComparison.tsOffset;
 | 
			
		||||
      this.comparisonTimeWindow.maxTime = this.timewindowForComparison.fixedWindow.endTimeMs;
 | 
			
		||||
      this.comparisonTimeWindow.minTime = this.timewindowForComparison.fixedWindow.startTimeMs;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1261,7 +1262,7 @@ export class WidgetSubscription implements IWidgetSubscription {
 | 
			
		||||
        index++;
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    if (this.comparisonEnabled) {
 | 
			
		||||
    if (this.comparisonEnabled && isHistoryTypeTimewindow(this.timeWindowConfig)) {
 | 
			
		||||
      this.datasourcePages.forEach(datasourcePage => {
 | 
			
		||||
        datasourcePage.data.forEach((datasource, dIndex) => {
 | 
			
		||||
          if (datasource.isAdditional) {
 | 
			
		||||
 | 
			
		||||
@ -57,7 +57,7 @@ import {
 | 
			
		||||
} from './flot-widget.models';
 | 
			
		||||
import * as moment_ from 'moment';
 | 
			
		||||
import * as tinycolor_ from 'tinycolor2';
 | 
			
		||||
import { AggregationType } from '@shared/models/time/time.models';
 | 
			
		||||
import { AggregationType, isHistoryTypeTimewindow } from '@shared/models/time/time.models';
 | 
			
		||||
import { CancelAnimationFrame } from '@core/services/raf.service';
 | 
			
		||||
import { UtilsService } from '@core/services/utils.service';
 | 
			
		||||
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
 | 
			
		||||
@ -92,6 +92,8 @@ export class TbFlot {
 | 
			
		||||
  private readonly tooltipCumulative: boolean;
 | 
			
		||||
  private readonly hideZeros: boolean;
 | 
			
		||||
 | 
			
		||||
  private comparisonEnabled: boolean;
 | 
			
		||||
 | 
			
		||||
  private readonly defaultBarWidth: number;
 | 
			
		||||
 | 
			
		||||
  private thresholdsSourcesSubscription: IWidgetSubscription;
 | 
			
		||||
@ -158,6 +160,9 @@ export class TbFlot {
 | 
			
		||||
    this.tooltipCumulative = isDefined(this.settings.tooltipCumulative) ? this.settings.tooltipCumulative : false;
 | 
			
		||||
    this.hideZeros = isDefined(this.settings.hideZeros) ? this.settings.hideZeros : false;
 | 
			
		||||
 | 
			
		||||
    this.comparisonEnabled = this.settings.comparisonEnabled &&
 | 
			
		||||
      isHistoryTypeTimewindow(this.ctx.defaultSubscription.timeWindowConfig);
 | 
			
		||||
 | 
			
		||||
    const font = {
 | 
			
		||||
      color: this.settings.fontColor || '#545454',
 | 
			
		||||
      size: this.settings.fontSize || 10,
 | 
			
		||||
@ -263,7 +268,7 @@ export class TbFlot {
 | 
			
		||||
        };
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (this.settings.comparisonEnabled) {
 | 
			
		||||
      if (this.comparisonEnabled) {
 | 
			
		||||
        const xaxis = deepClone(this.xaxis);
 | 
			
		||||
        xaxis.position = 'top';
 | 
			
		||||
        if (this.settings.xaxisSecond) {
 | 
			
		||||
@ -425,7 +430,7 @@ export class TbFlot {
 | 
			
		||||
        fill: keySettings.fillLines === true
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      if (this.settings.stack && !this.settings.comparisonEnabled) {
 | 
			
		||||
      if (this.settings.stack && !this.comparisonEnabled) {
 | 
			
		||||
        series.stack = !keySettings.excludeFromStacking;
 | 
			
		||||
      } else {
 | 
			
		||||
        series.stack = false;
 | 
			
		||||
@ -557,7 +562,7 @@ export class TbFlot {
 | 
			
		||||
      }
 | 
			
		||||
      this.options.xaxes[0].min = this.subscription.timeWindow.minTime;
 | 
			
		||||
      this.options.xaxes[0].max = this.subscription.timeWindow.maxTime;
 | 
			
		||||
      if (this.settings.comparisonEnabled) {
 | 
			
		||||
      if (this.comparisonEnabled) {
 | 
			
		||||
        this.options.xaxes[1].min = this.subscription.comparisonTimeWindow.minTime;
 | 
			
		||||
        this.options.xaxes[1].max = this.subscription.comparisonTimeWindow.maxTime;
 | 
			
		||||
      }
 | 
			
		||||
@ -636,7 +641,7 @@ export class TbFlot {
 | 
			
		||||
 | 
			
		||||
          this.options.xaxes[0].min = this.subscription.timeWindow.minTime;
 | 
			
		||||
          this.options.xaxes[0].max = this.subscription.timeWindow.maxTime;
 | 
			
		||||
          if (this.settings.comparisonEnabled) {
 | 
			
		||||
          if (this.comparisonEnabled) {
 | 
			
		||||
            this.options.xaxes[1].min = this.subscription.comparisonTimeWindow.minTime;
 | 
			
		||||
            this.options.xaxes[1].max = this.subscription.comparisonTimeWindow.maxTime;
 | 
			
		||||
          }
 | 
			
		||||
@ -654,7 +659,7 @@ export class TbFlot {
 | 
			
		||||
          } else {
 | 
			
		||||
            this.plot.getOptions().xaxes[0].min = this.subscription.timeWindow.minTime;
 | 
			
		||||
            this.plot.getOptions().xaxes[0].max = this.subscription.timeWindow.maxTime;
 | 
			
		||||
            if (this.settings.comparisonEnabled) {
 | 
			
		||||
            if (this.comparisonEnabled) {
 | 
			
		||||
              this.plot.getOptions().xaxes[1].min = this.subscription.comparisonTimeWindow.minTime;
 | 
			
		||||
              this.plot.getOptions().xaxes[1].max = this.subscription.comparisonTimeWindow.maxTime;
 | 
			
		||||
            }
 | 
			
		||||
@ -1293,7 +1298,7 @@ export class TbFlot {
 | 
			
		||||
    const results: TbFlotHoverInfo[] = [{
 | 
			
		||||
      seriesHover: []
 | 
			
		||||
    }];
 | 
			
		||||
    if (this.settings.comparisonEnabled) {
 | 
			
		||||
    if (this.comparisonEnabled) {
 | 
			
		||||
      results.push({
 | 
			
		||||
        seriesHover: []
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
@ -118,6 +118,7 @@ export interface SubscriptionTimewindow {
 | 
			
		||||
  realtimeWindowMs?: number;
 | 
			
		||||
  fixedWindow?: FixedWindow;
 | 
			
		||||
  aggregation?: SubscriptionAggregation;
 | 
			
		||||
  timeForComparison?: moment_.unitOfTime.DurationConstructor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface WidgetTimewindow {
 | 
			
		||||
@ -208,6 +209,14 @@ export function defaultTimewindow(timeService: TimeService): Timewindow {
 | 
			
		||||
  return timewindow;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getTimewindowType(timewindow: Timewindow): TimewindowType {
 | 
			
		||||
  if (isUndefined(timewindow.selectedTab)) {
 | 
			
		||||
    return isDefined(timewindow.realtime) ? TimewindowType.REALTIME : TimewindowType.HISTORY;
 | 
			
		||||
  } else {
 | 
			
		||||
    return timewindow.selectedTab;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function initModelFromDefaultTimewindow(value: Timewindow, timeService: TimeService): Timewindow {
 | 
			
		||||
  const model = defaultTimewindow(timeService);
 | 
			
		||||
  if (value) {
 | 
			
		||||
@ -215,15 +224,7 @@ export function initModelFromDefaultTimewindow(value: Timewindow, timeService: T
 | 
			
		||||
    model.hideAggregation = value.hideAggregation;
 | 
			
		||||
    model.hideAggInterval = value.hideAggInterval;
 | 
			
		||||
    model.hideTimezone = value.hideTimezone;
 | 
			
		||||
    if (isUndefined(value.selectedTab)) {
 | 
			
		||||
      if (value.realtime) {
 | 
			
		||||
        model.selectedTab = TimewindowType.REALTIME;
 | 
			
		||||
      } else {
 | 
			
		||||
        model.selectedTab = TimewindowType.HISTORY;
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      model.selectedTab = value.selectedTab;
 | 
			
		||||
    }
 | 
			
		||||
    model.selectedTab = getTimewindowType(value);
 | 
			
		||||
    if (model.selectedTab === TimewindowType.REALTIME) {
 | 
			
		||||
      if (isDefined(value.realtime.interval)) {
 | 
			
		||||
        model.realtime.interval = value.realtime.interval;
 | 
			
		||||
@ -328,6 +329,10 @@ export function calculateTsOffset(timezone?: string): number {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function isHistoryTypeTimewindow(timewindow: Timewindow): boolean {
 | 
			
		||||
  return getTimewindowType(timewindow) === TimewindowType.HISTORY;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function createSubscriptionTimewindow(timewindow: Timewindow, stDiff: number, stateData: boolean,
 | 
			
		||||
                                             timeService: TimeService): SubscriptionTimewindow {
 | 
			
		||||
  const subscriptionTimewindow: SubscriptionTimewindow = {
 | 
			
		||||
@ -352,10 +357,7 @@ export function createSubscriptionTimewindow(timewindow: Timewindow, stDiff: num
 | 
			
		||||
      limit: timewindow.aggregation.limit || timeService.getMaxDatapointsLimit()
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
  let selectedTab = timewindow.selectedTab;
 | 
			
		||||
  if (isUndefined(selectedTab)) {
 | 
			
		||||
    selectedTab = isDefined(timewindow.realtime) ? TimewindowType.REALTIME : TimewindowType.HISTORY;
 | 
			
		||||
  }
 | 
			
		||||
  const selectedTab = getTimewindowType(timewindow);
 | 
			
		||||
  if (selectedTab === TimewindowType.REALTIME) {
 | 
			
		||||
    let realtimeType = timewindow.realtime.realtimeType;
 | 
			
		||||
    if (isUndefined(realtimeType)) {
 | 
			
		||||
@ -558,10 +560,15 @@ export function createTimewindowForComparison(subscriptionTimewindow: Subscripti
 | 
			
		||||
  const timewindowForComparison: SubscriptionTimewindow = {
 | 
			
		||||
    fixedWindow: null,
 | 
			
		||||
    realtimeWindowMs: null,
 | 
			
		||||
    aggregation: subscriptionTimewindow.aggregation
 | 
			
		||||
    aggregation: subscriptionTimewindow.aggregation,
 | 
			
		||||
    tsOffset: subscriptionTimewindow.tsOffset
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  if (subscriptionTimewindow.realtimeWindowMs) {
 | 
			
		||||
    if (subscriptionTimewindow.quickInterval) {
 | 
			
		||||
      timewindowForComparison.quickInterval = subscriptionTimewindow.quickInterval;
 | 
			
		||||
      timewindowForComparison.timeForComparison = timeUnit;
 | 
			
		||||
    }
 | 
			
		||||
    timewindowForComparison.startTs = moment(subscriptionTimewindow.startTs).subtract(1, timeUnit).valueOf();
 | 
			
		||||
    timewindowForComparison.realtimeWindowMs = subscriptionTimewindow.realtimeWindowMs;
 | 
			
		||||
  } else if (subscriptionTimewindow.fixedWindow) {
 | 
			
		||||
@ -797,3 +804,7 @@ export function getCurrentTime(tz?: string): moment_.Moment {
 | 
			
		||||
export function getTimezone(tz: string): moment_.Moment {
 | 
			
		||||
    return moment.tz(tz);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getCurrentTimeForComparison(timeForComparison: moment_.unitOfTime.DurationConstructor, tz?: string): moment_.Moment {
 | 
			
		||||
  return getCurrentTime(tz).subtract(1, timeForComparison);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user