Skip to content

Commit

Permalink
UI: Time window history add aggregation, advanced. Charts minor corsa…
Browse files Browse the repository at this point in the history
…ir plugin improvement.
  • Loading branch information
deaflynx committed Dec 12, 2024
1 parent 3a5e38f commit 913ad59
Show file tree
Hide file tree
Showing 18 changed files with 522 additions and 774 deletions.
4 changes: 2 additions & 2 deletions ui-ngx/src/app/core/http/client-session.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ export class ClientSessionService {
return this.http.get<ClientSessionCredentials>(`/api/client-session/details?clientId=${encodeURIComponent(clientId)}`, defaultHttpOptionsFromConfig(config));
}

public getSessionMetrics(clientId: string, config?: RequestConfig): Observable<PageData<SessionMetrics>> {
return this.statsService.getLatestTimeseries(clientId, SessionMetricsList, true, config).pipe(
public getSessionMetrics(clientId: string): Observable<PageData<SessionMetrics>> {
return this.statsService.getLatestTimeseries(clientId, SessionMetricsList, true).pipe(
map((metrics) => {
const data = [];
for (const [key, value] of Object.entries(metrics)) {
Expand Down
10 changes: 5 additions & 5 deletions ui-ngx/src/app/core/http/stats.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import { defaultHttpOptionsFromConfig, RequestConfig } from './http-utils';
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { isDefinedAndNotNull } from '@core/utils';
import { AggregationType } from '@shared/models/time/time.models';
import { AggregationType, Interval } from '@shared/models/time/time.models';
import { Direction } from '@shared/models/page/sort-order';
import { CHART_ALL, TimeseriesData, timeseriesDataLimit } from '@shared/models/chart.model';
import { CHART_ALL, TimeseriesData, MAX_DATAPOINTS_LIMIT } from '@shared/models/chart.model';

@Injectable({
providedIn: 'root'
Expand All @@ -32,8 +32,8 @@ export class StatsService {
}

public getEntityTimeseries(entityId: string, startTs: number, endTs: number, keys: Array<string> = CHART_ALL,
limit: number = timeseriesDataLimit, agg: AggregationType = AggregationType.NONE, interval?: number,
orderBy: Direction = Direction.DESC, useStrictDataTypes: boolean = false): Observable<TimeseriesData> {
limit: number = MAX_DATAPOINTS_LIMIT, agg: AggregationType = AggregationType.NONE, interval?: Interval,
orderBy: Direction = Direction.DESC, useStrictDataTypes: boolean = true): Observable<TimeseriesData> {
let url = `/api/timeseries/${encodeURIComponent(entityId)}/values?keys=${keys.join(',')}&startTs=${startTs}&endTs=${endTs}`;
if (isDefinedAndNotNull(limit)) {
url += `&limit=${limit}`;
Expand All @@ -58,7 +58,7 @@ export class StatsService {
}

public getLatestTimeseries(entityId: string, keys: Array<string> = CHART_ALL,
useStrictDataTypes: boolean = false, config?: RequestConfig): Observable<TimeseriesData> {
useStrictDataTypes: boolean = true): Observable<TimeseriesData> {
let url = `/api/timeseries/latest?entityId=${encodeURIComponent(entityId)}&keys=${keys.join(',')}`;
if (isDefinedAndNotNull(useStrictDataTypes)) {
url += `&useStrictDataTypes=${useStrictDataTypes}`;
Expand Down
108 changes: 41 additions & 67 deletions ui-ngx/src/app/core/services/time.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,19 @@ import {
AggregationType,
DAY,
defaultTimeIntervals,
defaultTimewindow, HOUR, MINUTE,
SECOND,
defaultTimewindow,
Interval,
IntervalMath,
MINUTE,
TimeInterval,
Timewindow
} from '@shared/models/time/time.models';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { defaultHttpOptions } from '@core/http/http-utils';
import { map } from 'rxjs/operators';
import { isDefined } from '@core/utils';

export interface TimeInterval {
name: string;
translateParams: { [key: string]: any };
value: number;
}
import { MAX_DATAPOINTS_LIMIT } from '@app/shared/models/chart.model';

const MIN_INTERVAL = MINUTE;
const MAX_INTERVAL = 365 * 20 * DAY;

const MIN_LIMIT = 7;

const MAX_DATAPOINTS_LIMIT = 500;
const MIN_LIMIT = 1;

@Injectable({
providedIn: 'root'
Expand All @@ -49,32 +40,18 @@ export class TimeService {

private maxDatapointsLimit = MAX_DATAPOINTS_LIMIT;

constructor(
private http: HttpClient
) {}

public loadMaxDatapointsLimit(): Observable<number> {
return this.http.get<number>('/api/dashboard/maxDatapointsLimit',
defaultHttpOptions(true)).pipe(
map((limit) => {
this.maxDatapointsLimit = limit;
if (!this.maxDatapointsLimit || this.maxDatapointsLimit <= MIN_LIMIT) {
this.maxDatapointsLimit = MIN_LIMIT + 1;
}
return this.maxDatapointsLimit;
})
);
}
constructor() {}

public matchesExistingInterval(min: number, max: number, intervalMs: number): boolean {
const intervals = this.getIntervals(min, max);
return intervals.findIndex(interval => interval.value === intervalMs) > -1;
public matchesExistingInterval(min: number, max: number, interval: Interval, useCalendarIntervals = false): boolean {
const intervals = this.getIntervals(min, max, useCalendarIntervals);
return intervals.findIndex(timeInterval => timeInterval.value === interval) > -1;
}

public getIntervals(min: number, max: number): Array<TimeInterval> {
public getIntervals(min: number, max: number, useCalendarIntervals = false): Array<TimeInterval> {
min = this.boundMinInterval(min);
max = this.boundMaxInterval(max);
return defaultTimeIntervals.filter((interval) => interval.value >= min && interval.value <= max);
return defaultTimeIntervals.filter((interval) => (useCalendarIntervals || typeof interval.value === 'number') &&
IntervalMath.numberValue(interval.value) >= min && IntervalMath.numberValue(interval.value) <= max);
}

public boundMinInterval(min: number): number {
Expand All @@ -91,35 +68,26 @@ export class TimeService {
return this.toBound(max, MIN_INTERVAL, MAX_INTERVAL, MAX_INTERVAL);
}

public boundToPredefinedInterval(min: number, max: number, intervalMs: number): number {
const intervals = this.getIntervals(min, max);
public boundToPredefinedInterval(min: number, max: number, interval: Interval, useCalendarIntervals = false): Interval {
const intervals = this.getIntervals(min, max, useCalendarIntervals);
let minDelta = MAX_INTERVAL;
const boundedInterval = intervalMs || min;
const boundedInterval = interval || min;
if (!intervals.length) {
return boundedInterval;
}
let matchedInterval: TimeInterval = intervals[0];
intervals.forEach((interval) => {
const delta = Math.abs(interval.value - boundedInterval);
if (delta < minDelta) {
matchedInterval = interval;
minDelta = delta;
}
});
return matchedInterval.value;
}

public boundIntervalToTimewindow(timewindow: number, intervalMs: number, aggType: AggregationType): number {
if (aggType === AggregationType.NONE) {
return HOUR;
const found = intervals.find(timeInterval => timeInterval.value === boundedInterval);
if (found) {
return found.value;
} else {
const min = this.minIntervalLimit(timewindow);
const max = this.maxIntervalLimit(timewindow);
if (intervalMs) {
return this.toBound(intervalMs, min, max, intervalMs);
} else {
return this.boundToPredefinedInterval(min, max, this.avgInterval(timewindow));
}
let matchedInterval: TimeInterval = intervals[0];
intervals.forEach((timeInterval) => {
const delta = Math.abs(IntervalMath.numberValue(timeInterval.value) - IntervalMath.numberValue(boundedInterval));
if (delta <= minDelta) {
matchedInterval = timeInterval;
minDelta = delta;
}
});
return matchedInterval.value;
}
}

Expand All @@ -131,11 +99,6 @@ export class TimeService {
return MIN_LIMIT;
}

public avgInterval(timewindow: number): number {
const avg = timewindow / 200;
return this.boundMinInterval(avg);
}

public minIntervalLimit(timewindowMs: number): number {
const min = timewindowMs / 500;
return this.boundMinInterval(min);
Expand All @@ -150,6 +113,18 @@ export class TimeService {
return defaultTimewindow(this);
}

public timewindowGroupingInterval(timewindow: Timewindow): Interval {
if (timewindow.aggregation.type === AggregationType.NONE) {
return 0;
}
if (isDefined(timewindow.realtime)) {
return timewindow.realtime.interval;
}
if (isDefined(timewindow.history)) {
return timewindow.history.interval;
}
}

private toBound(value: number, min: number, max: number, defValue: number): number {
if (isDefined(value)) {
value = Math.max(value, min);
Expand All @@ -159,5 +134,4 @@ export class TimeService {
return defValue;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
/// limitations under the License.
///

// @ts-nocheck

import { Component, OnInit } from '@angular/core';
import { Observable, of } from 'rxjs';
import { InstructionsService } from '@core/http/instructions.service';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
asButton
flatButton
tooltipPosition="left"
aggregation="false"
timezone="false">
aggregation="true">
</tb-timewindow>
</mat-toolbar>
<div class="mat-padding" fxFlex fxLayout="column" fxLayoutGap="16px">
Expand Down
Loading

0 comments on commit 913ad59

Please sign in to comment.