From b19636111d0981a661c10a5b7475f538766e03fd Mon Sep 17 00:00:00 2001 From: rusikv Date: Wed, 10 Apr 2024 12:49:59 +0300 Subject: [PATCH 1/2] UI: fixed aggregation for entities table widget --- ui-ngx/src/app/core/api/data-aggregator.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ui-ngx/src/app/core/api/data-aggregator.ts b/ui-ngx/src/app/core/api/data-aggregator.ts index 61cb1f1a85..a0a09b2f60 100644 --- a/ui-ngx/src/app/core/api/data-aggregator.ts +++ b/ui-ngx/src/app/core/api/data-aggregator.ts @@ -18,6 +18,7 @@ import { AggKey, IndexedSubscriptionData, } from '@app/shared/models/telemetry/t import { AggregationType, calculateAggIntervalWithSubscriptionTimeWindow, + calculateInterval, calculateIntervalComparisonEndTime, calculateIntervalEndTime, calculateIntervalStartEndTime, @@ -27,7 +28,7 @@ import { SubscriptionTimewindow } from '@shared/models/time/time.models'; import { UtilsService } from '@core/services/utils.service'; -import { deepClone, isDefinedAndNotNull, isNumber, isNumeric } from '@core/utils'; +import { deepClone, isDefined, isDefinedAndNotNull, isNumber, isNumeric } from '@core/utils'; import { DataEntry, DataSet, IndexedData } from '@shared/models/widget.models'; import BTree from 'sorted-btree'; import Timeout = NodeJS.Timeout; @@ -63,9 +64,9 @@ class AggDataMap { this.map.delete(ts); } - findDataForTs(ts: number): AggData | undefined { + findDataForTs(ts: number, noAggregation: boolean): AggData | undefined { if (ts >= this.endTs) { - this.updateLastInterval(ts + 1); + this.updateLastInterval(ts + 1, noAggregation); } const pair = this.map.getPairOrNextLower(ts, this.reusePair); if (pair) { @@ -78,16 +79,17 @@ class AggDataMap { } calculateAggInterval(timestamp: number): [number, number] { - return calculateAggIntervalWithSubscriptionTimeWindow(this.subsTw, this.endTs, timestamp); + return calculateInterval(this.subsTw.startTs, this.endTs, this.subsTw.aggregation.interval, this.subsTw.tsOffset, this.subsTw.timezone, timestamp); } - updateLastInterval(endTs: number) { + updateLastInterval(endTs: number, noAggregation?: boolean) { if (endTs > this.endTs) { this.endTs = endTs; const lastTs = this.map.maxKey(); if (lastTs) { const data = this.map.get(lastTs); - const interval = calculateAggIntervalWithSubscriptionTimeWindow(this.subsTw, endTs, data.ts); + const interval = isDefined(noAggregation) && !noAggregation ? this.calculateAggInterval(data.ts) : + calculateAggIntervalWithSubscriptionTimeWindow(this.subsTw, endTs, data.ts); data.interval = interval; data.ts = interval[0] + Math.floor((interval[1] - interval[0]) / 2); } @@ -454,7 +456,7 @@ export class DataAggregator { keyData.forEach((kvPair) => { const timestamp = kvPair[0]; const value = DataAggregator.convertValue(kvPair[1], noAggregation); - let aggData = aggKeyData.findDataForTs(timestamp); + let aggData = aggKeyData.findDataForTs(timestamp, noAggregation); if (!aggData) { let interval: [number, number] = [timestamp, timestamp]; if (!noAggregation) { From 31276ddb42d4ac49e579cc1f4b91fe74ca4fff86 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Mon, 6 May 2024 13:59:11 +0300 Subject: [PATCH 2/2] UI: Refactor data aggregator to support time-series aggregation key processing in latest widgets --- ui-ngx/src/app/core/api/data-aggregator.ts | 23 +++++++++---------- .../src/app/shared/models/time/time.models.ts | 4 ++-- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/ui-ngx/src/app/core/api/data-aggregator.ts b/ui-ngx/src/app/core/api/data-aggregator.ts index 68baa7d04a..d437bd73d0 100644 --- a/ui-ngx/src/app/core/api/data-aggregator.ts +++ b/ui-ngx/src/app/core/api/data-aggregator.ts @@ -18,7 +18,6 @@ import { AggKey, IndexedSubscriptionData, } from '@app/shared/models/telemetry/t import { AggregationType, calculateAggIntervalWithSubscriptionTimeWindow, - calculateInterval, calculateIntervalComparisonEndTime, calculateIntervalEndTime, calculateIntervalStartEndTime, @@ -28,7 +27,7 @@ import { SubscriptionTimewindow } from '@shared/models/time/time.models'; import { UtilsService } from '@core/services/utils.service'; -import { deepClone, isDefined, isDefinedAndNotNull, isNumber, isNumeric } from '@core/utils'; +import { deepClone, isDefinedAndNotNull, isNumber, isNumeric } from '@core/utils'; import { DataEntry, DataSet, IndexedData } from '@shared/models/widget.models'; import BTree from 'sorted-btree'; import Timeout = NodeJS.Timeout; @@ -49,7 +48,8 @@ class AggDataMap { constructor( private subsTw: SubscriptionTimewindow, - private endTs: number + private endTs: number, + private aggType: AggregationType ){}; set(ts: number, data: AggData) { @@ -64,9 +64,9 @@ class AggDataMap { this.map.delete(ts); } - findDataForTs(ts: number, noAggregation: boolean): AggData | undefined { + findDataForTs(ts: number): AggData | undefined { if (ts >= this.endTs) { - this.updateLastInterval(ts + 1, noAggregation); + this.updateLastInterval(ts + 1); } const pair = this.map.getPairOrNextLower(ts, this.reusePair); if (pair) { @@ -79,17 +79,16 @@ class AggDataMap { } calculateAggInterval(timestamp: number): [number, number] { - return calculateInterval(this.subsTw.startTs, this.endTs, this.subsTw.aggregation.interval, this.subsTw.tsOffset, this.subsTw.timezone, timestamp); + return calculateAggIntervalWithSubscriptionTimeWindow(this.subsTw, this.endTs, timestamp, this.aggType); } - updateLastInterval(endTs: number, noAggregation?: boolean) { + updateLastInterval(endTs: number) { if (endTs > this.endTs) { this.endTs = endTs; const lastTs = this.map.maxKey(); if (lastTs) { const data = this.map.get(lastTs); - const interval = isDefined(noAggregation) && !noAggregation ? this.calculateAggInterval(data.ts) : - calculateAggIntervalWithSubscriptionTimeWindow(this.subsTw, endTs, data.ts); + const interval = calculateAggIntervalWithSubscriptionTimeWindow(this.subsTw, endTs, data.ts, this.aggType); data.interval = interval; data.ts = interval[0] + Math.floor((interval[1] - interval[0]) / 2); } @@ -417,7 +416,7 @@ export class DataAggregator { const noAggregation = aggType === AggregationType.NONE; let aggKeyData = aggregationMap.aggMap[id]; if (!aggKeyData) { - aggKeyData = new AggDataMap(this.subsTw, this.endTs); + aggKeyData = new AggDataMap(this.subsTw, this.endTs, aggType); aggregationMap.aggMap[id] = aggKeyData; } const keyData = data[id]; @@ -451,14 +450,14 @@ export class DataAggregator { const noAggregation = aggType === AggregationType.NONE; let aggKeyData = this.aggregationMap.aggMap[id]; if (!aggKeyData) { - aggKeyData = new AggDataMap(this.subsTw, this.endTs); + aggKeyData = new AggDataMap(this.subsTw, this.endTs, aggType); this.aggregationMap.aggMap[id] = aggKeyData; } const keyData = data[id]; keyData.forEach((kvPair) => { const timestamp = kvPair[0]; const value = DataAggregator.convertValue(kvPair[1], noAggregation); - let aggData = aggKeyData.findDataForTs(timestamp, noAggregation); + let aggData = aggKeyData.findDataForTs(timestamp); if (!aggData) { let interval: [number, number] = [timestamp, timestamp]; if (!noAggregation) { diff --git a/ui-ngx/src/app/shared/models/time/time.models.ts b/ui-ngx/src/app/shared/models/time/time.models.ts index deec2ee8f9..9336f47d90 100644 --- a/ui-ngx/src/app/shared/models/time/time.models.ts +++ b/ui-ngx/src/app/shared/models/time/time.models.ts @@ -1116,8 +1116,8 @@ export const endIntervalDate = (current: moment_.Moment, interval: IntervalType) }; export const calculateAggIntervalWithSubscriptionTimeWindow - = (subsTw: SubscriptionTimewindow, endTs: number, timestamp: number): [number, number] => { - if (subsTw.aggregation.type === AggregationType.NONE) { + = (subsTw: SubscriptionTimewindow, endTs: number, timestamp: number, aggType?: AggregationType): [number, number] => { + if ((aggType || subsTw.aggregation.type) === AggregationType.NONE) { return [timestamp, timestamp]; } else { return calculateInterval(subsTw.startTs, endTs, subsTw.aggregation.interval, subsTw.tsOffset, subsTw.timezone, timestamp);