From 94606d9a60837b414fcf6e37521525233dd96f99 Mon Sep 17 00:00:00 2001 From: edujgurjc <26252085+EduJGURJC@users.noreply.github.com> Date: Fri, 21 Feb 2020 14:15:32 +0100 Subject: [PATCH] GUI New Feature => On add 2 or more QoE VMAF charts, add an additional chart with the average --- .../etm-chart-group.component.ts | 83 ++++++++++- .../etm-monitoring-view.component.ts | 48 ++++++- .../models/es-rab-complex-metrics-model.ts | 130 +++++++++++++----- .../models/linechart-metric-model.ts | 4 +- 4 files changed, 221 insertions(+), 44 deletions(-) diff --git a/elastest-torm-gui/src/app/elastest-etm/etm-monitoring-view/etm-chart-group/etm-chart-group.component.ts b/elastest-torm-gui/src/app/elastest-etm/etm-monitoring-view/etm-chart-group/etm-chart-group.component.ts index 0cd2e34d1..f9a4bc2ad 100644 --- a/elastest-torm-gui/src/app/elastest-etm/etm-monitoring-view/etm-chart-group/etm-chart-group.component.ts +++ b/elastest-torm-gui/src/app/elastest-etm/etm-monitoring-view/etm-chart-group/etm-chart-group.component.ts @@ -73,6 +73,9 @@ export class EtmChartGroupComponent implements OnInit, AfterViewInit, AfterViewC startDate: Date; endDate: Date; + qoeVmafAvgChartName: string = 'QoE VMAF Average'; + qoeVmafMetrics: MetricsFieldModel[] = []; + constructor(private monitoringService: MonitoringService, private elastestRabbitmqService: ElastestRabbitmqService) {} ngOnInit(): void {} @@ -186,6 +189,8 @@ export class EtmChartGroupComponent implements OnInit, AfterViewInit, AfterViewC this.initAIO(); } + this.qoeVmafMetrics = []; + for (let metric of this.tJob.execDashboardConfigModel.allMetricsFields.fieldsList) { if (metric.activated) { let individualMetrics: ESRabComplexMetricsModel = this.initializeBasicAttrByMetric(metric); @@ -238,14 +243,20 @@ export class EtmChartGroupComponent implements OnInit, AfterViewInit, AfterViewC ); } } + + this.storeMetricIfIsQoEVmafActivated(metric); } } + this.createGroupedMetricList(); this.firstTimeInitialized = true; if (this.tJob.execDashboardConfigModel.combineMetricsInPairs) { this.initMetricsPairs(); } + + // QoE Vmaf average chart + this.initQoEVmafAverage(); } addChartToList(individualMetrics: ESRabComplexMetricsModel, isCombinedPair: boolean = false): number { @@ -257,6 +268,7 @@ export class EtmChartGroupComponent implements OnInit, AfterViewInit, AfterViewC if (this.tJob.execDashboardConfigModel.combineMetricsInPairs) { this.initMetricsPairs(); } + return pos; } } @@ -348,6 +360,62 @@ export class EtmChartGroupComponent implements OnInit, AfterViewInit, AfterViewC return individualMetrics; } + // If is qoe vmaf and is activated, add to list (for create average chart) + storeMetricIfIsQoEVmafActivated(metric: MetricsFieldModel): void { + if (metric.etType === 'vmaf' && metric.activated) { + this.qoeVmafMetrics.push(metric); + } + } + + initQoEVmafAverage(): void { + if (!this.live) { + let posIfExist: number = this.returnPositionIfExist(this.qoeVmafAvgChartName); + if (posIfExist > -1) { + this.removeAndUnsubscribeByListAndPos(posIfExist); + } + + if (this.qoeVmafMetrics && this.qoeVmafMetrics.length > 1) { + let ignoreComponent: string = this.getIgnoreComponent(); + let chart: ESRabComplexMetricsModel = new ESRabComplexMetricsModel(this.monitoringService, ignoreComponent); + chart.startDate = this.startDate; + chart.endDate = this.endDate; + chart.name = this.qoeVmafAvgChartName; + chart.hidePrevBtn = !this.live; + + let monitoringIndex: string = this.tJobExec.monitoringIndex; + + // If Multi Parent + if (this.tJobExec instanceof TJobExecModel && this.tJobExec.isParent()) { + monitoringIndex = this.tJobExec.getChildsMonitoringIndices(); + } + + chart.monitoringIndex = monitoringIndex; + + for (let chartLine of this.qoeVmafMetrics) { + chartLine.unit = chartLine.unit ? chartLine.unit : '%'; + chart.setUnits(chartLine.unit); + + chart.allMetricsFields.addMetricsFieldToList( + chartLine, + chartLine.component, + chart.stream, + chartLine.streamType, + chartLine.activated, + ); + } + chart.getAllMetrics().subscribe( + (loaded: boolean) => { + chart.convertChartToUniqueAxisAverage(this.qoeVmafAvgChartName); + + this.addChartToList(chart); + this.createGroupedMetricList(); + }, + (error: Error) => console.log(error), + ); + } + } + } + initMetricsPairs(): void { this.combinedPairChartsList = []; let metricsPairsList: MetricsFieldModel[][] = allArrayPairCombinations(this.getChartsListMetricFieldModels()); @@ -541,13 +609,20 @@ export class EtmChartGroupComponent implements OnInit, AfterViewInit, AfterViewC return component + ' ' + stream + ' ' + etType; } - alreadyExist(name: string): boolean { + returnPositionIfExist(name: string): number { + let currentPos: number = 0; for (let metric of this.chartsList) { - if (metric.name === name) { - return true; + if (metric.name.trim() === name.trim()) { + return currentPos; } + currentPos++; } - return false; + + return -1; + } + + alreadyExist(name: string): boolean { + return this.returnPositionIfExist(name) > -1; } createGroupedMetricList(): void { diff --git a/elastest-torm-gui/src/app/elastest-etm/etm-monitoring-view/etm-monitoring-view.component.ts b/elastest-torm-gui/src/app/elastest-etm/etm-monitoring-view/etm-monitoring-view.component.ts index 8bb6f89b8..9f5f8f86a 100644 --- a/elastest-torm-gui/src/app/elastest-etm/etm-monitoring-view/etm-monitoring-view.component.ts +++ b/elastest-torm-gui/src/app/elastest-etm/etm-monitoring-view/etm-monitoring-view.component.ts @@ -66,7 +66,12 @@ export class EtmMonitoringViewComponent implements OnInit { ngOnInit(): void {} - initView(tJob: AbstractTJobModel, tJobExec: AbstractTJobExecModel, customStartDate?: Date, customEndDate?: Date): void { + initView( + tJob: AbstractTJobModel, + tJobExec: AbstractTJobExecModel, + customStartDate?: Date, + customEndDate?: Date, + ): void { this.tJob = tJob; this.tJobExec = tJobExec; @@ -324,7 +329,11 @@ export class EtmMonitoringViewComponent implements OnInit { } else { // Disable from tjob object before save let logField: LogFieldModel = new LogFieldModel(log.component, log.stream); - this.tJob.execDashboardConfigModel.allLogsTypes.disableLogField(logField.name, logField.component, logField.stream); + this.tJob.execDashboardConfigModel.allLogsTypes.disableLogField( + logField.name, + logField.component, + logField.stream, + ); // Remove this.removeLogCard(log); } @@ -337,7 +346,12 @@ export class EtmMonitoringViewComponent implements OnInit { this.metricName = ''; // Enable in tjob object before save let logField: LogFieldModel = new LogFieldModel(log.component, log.stream); - this.tJob.execDashboardConfigModel.allLogsTypes.addLogFieldToList(logField.name, logField.component, logField.stream, true); + this.tJob.execDashboardConfigModel.allLogsTypes.addLogFieldToList( + logField.name, + logField.component, + logField.stream, + true, + ); this.addMore(showPopup, 'log'); } @@ -355,7 +369,11 @@ export class EtmMonitoringViewComponent implements OnInit { } else { // Disable from tjob object before save let logField: LogFieldModel = new LogFieldModel(log.component, log.stream); - this.tJob.execDashboardConfigModel.allLogsTypes.disableLogField(logField.name, logField.component, logField.stream); + this.tJob.execDashboardConfigModel.allLogsTypes.disableLogField( + logField.name, + logField.component, + logField.stream, + ); // Remove this.removeLogComparisonTab(logField); } @@ -369,9 +387,19 @@ export class EtmMonitoringViewComponent implements OnInit { // Enable in tjob object before save let logField: LogFieldModel = new LogFieldModel(log.component, log.stream); - this.tJob.execDashboardConfigModel.allLogsTypes.addLogFieldToList(logField.name, logField.component, logField.stream, true); + this.tJob.execDashboardConfigModel.allLogsTypes.addLogFieldToList( + logField.name, + logField.component, + logField.stream, + true, + ); - let added: boolean = this.logsGroup.addMoreLogsComparisons(this.tJobExec, logField.name, this.stream, this.component); + let added: boolean = this.logsGroup.addMoreLogsComparisons( + this.tJobExec, + logField.name, + this.stream, + this.component, + ); if (showPopup) { if (added) { @@ -388,6 +416,7 @@ export class EtmMonitoringViewComponent implements OnInit { updateMetricsFromList(metricsList: any[]): void { this.activatedMetrics = []; + this.metricsGroup.qoeVmafMetrics = []; // First, remove all metrics pairs cards this.metricsGroup.removeAllMetricsPairs(); @@ -411,6 +440,8 @@ export class EtmMonitoringViewComponent implements OnInit { this.removeMetricCard(metric); } } + + this.metricsGroup.initQoEVmafAverage(); } updateMetric(metric: any, showPopup: boolean = false): void { @@ -441,6 +472,9 @@ export class EtmMonitoringViewComponent implements OnInit { ); this.addMore(showPopup, 'metric'); + + // If is qoe vmaf and is activated, add to list (for create average chart) + this.metricsGroup.storeMetricIfIsQoEVmafActivated(metricField); } removeMetricCard(metric: any): void { @@ -481,7 +515,7 @@ export class EtmMonitoringViewComponent implements OnInit { } } }) - .catch((e) => { + .catch(e => { this.waitForUnlock(functionsToExec, parentTJobExec); }); } diff --git a/elastest-torm-gui/src/app/shared/metrics-view/metrics-chart-card/models/es-rab-complex-metrics-model.ts b/elastest-torm-gui/src/app/shared/metrics-view/metrics-chart-card/models/es-rab-complex-metrics-model.ts index 421e35875..edd3bc36d 100644 --- a/elastest-torm-gui/src/app/shared/metrics-view/metrics-chart-card/models/es-rab-complex-metrics-model.ts +++ b/elastest-torm-gui/src/app/shared/metrics-view/metrics-chart-card/models/es-rab-complex-metrics-model.ts @@ -6,6 +6,7 @@ import { ColorSchemeModel } from '../../models/color-scheme-model'; import { ComplexMetricsModel } from './complex-metrics-model'; import { defaultStreamMap } from '../../../defaultESData-model'; import { MonitoringService } from '../../../services/monitoring.service'; +import { Observable, Subject } from 'rxjs'; export class ESRabComplexMetricsModel extends ComplexMetricsModel { monitoringService: MonitoringService; @@ -112,11 +113,19 @@ export class ESRabComplexMetricsModel extends ComplexMetricsModel { this.yAxisLabelLeft = this.getFormatedKnownLabel(this.leftChartUnit); } - if (this.rightChartOneChartUnit && this.yAxisLabelRightOne && this.rightChartOneChartUnit === this.yAxisLabelRightOne) { + if ( + this.rightChartOneChartUnit && + this.yAxisLabelRightOne && + this.rightChartOneChartUnit === this.yAxisLabelRightOne + ) { this.yAxisLabelRightOne = this.getFormatedKnownLabel(this.rightChartOneChartUnit); } - if (this.rightChartTwoChartUnit && this.yAxisLabelRightTwo && this.rightChartTwoChartUnit === this.yAxisLabelRightTwo) { + if ( + this.rightChartTwoChartUnit && + this.yAxisLabelRightTwo && + this.rightChartTwoChartUnit === this.yAxisLabelRightTwo + ) { this.yAxisLabelRightTwo = this.getFormatedKnownLabel(this.rightChartTwoChartUnit); } } @@ -147,42 +156,60 @@ export class ESRabComplexMetricsModel extends ComplexMetricsModel { this.yRightTwoAxisTickFormatting = yRightTwoAxisTickFormatting; } - getAllMetrics(onlyActivated: boolean = true): void { + getAllMetrics(onlyActivated: boolean = true): Observable { + let _obs: Subject = new Subject(); + let obs: Observable = _obs.asObservable(); + + let candidates: MetricsFieldModel[] = []; for (let metric of this.allMetricsFields.fieldsList) { if (!onlyActivated || (onlyActivated && metric.activated)) { - this.monitoringService - .getAllMetrics(this.monitoringIndex, metric, undefined, this.startDate, this.endDate) - .subscribe((data: LineChartMetricModel[]) => { - switch (metric.unit) { - case this.rightChartOneChartUnit: - this.rightChartOneAllData = this.rightChartOneAllData.concat(data); - if (metric.activated) { - this.rightChartOne = this.rightChartOne.concat(data); - } - break; - case this.leftChartUnit: - this.leftChartAllData = this.leftChartAllData.concat(data); - if (metric.activated) { - this.leftChart = this.leftChart.concat(data); - } - break; - case this.rightChartTwoChartUnit: - this.rightChartTwoAllData = this.rightChartTwoAllData.concat(data); - if (metric.activated) { - this.rightChartTwo = this.rightChartTwo.concat(data); - } - break; - default: - break; - } - }); - // } + candidates.push(metric); } } + let total: number = candidates.length; + + for (let metric of candidates) { + this.monitoringService + .getAllMetrics(this.monitoringIndex, metric, undefined, this.startDate, this.endDate) + .subscribe((data: LineChartMetricModel[]) => { + switch (metric.unit) { + case this.rightChartOneChartUnit: + this.rightChartOneAllData = this.rightChartOneAllData.concat(data); + if (metric.activated) { + this.rightChartOne = this.rightChartOne.concat(data); + } + break; + case this.leftChartUnit: + this.leftChartAllData = this.leftChartAllData.concat(data); + if (metric.activated) { + this.leftChart = this.leftChart.concat(data); + } + break; + case this.rightChartTwoChartUnit: + this.rightChartTwoAllData = this.rightChartTwoAllData.concat(data); + if (metric.activated) { + this.rightChartTwo = this.rightChartTwo.concat(data); + } + break; + default: + break; + } + total--; + + if (total <= 0) { + _obs.next(true); + } + }); + } + return obs; } updateData(trace: any): void { - let positionsList: number[] = this.allMetricsFields.getPositionsList(trace['et_type'], trace.component, trace.stream); + let positionsList: number[] = this.allMetricsFields.getPositionsList( + trace['et_type'], + trace.component, + trace.stream, + ); for (let position of positionsList) { let metric: MetricsFieldModel = this.allMetricsFields.fieldsList[position]; let parsedData: SingleMetricModel = this.monitoringService.convertToMetricTrace(trace, metric); @@ -498,4 +525,45 @@ export class ESRabComplexMetricsModel extends ComplexMetricsModel { // this.monitoringService.getLastMetricTraces(this.monitoringIndex, metric, size); } // TODO } + + // Chart with only left axis can be converted to average of his lines + convertChartToUniqueAxisAverage(lineName: string, timeRangeMs: number = 1000): void { + let averageLineChart: LineChartMetricModel = new LineChartMetricModel(lineName); + let currentTime: Date = this.startDate; + while (currentTime.getTime() <= this.endDate.getTime()) { + let nextTime: Date = new Date(currentTime.getTime() + timeRangeMs); + + let newPoint: SingleMetricModel = new SingleMetricModel(); + newPoint.name = currentTime; + + let currentNewDateAverageSum: number = 0; + let currentNewDateAverageCandidates: number = 0; + + for (let currentLineChart of this.leftChartAllData) { + for (let point of currentLineChart.series) { + let currentPointDate: Date = new Date(point.timestamp); + + if (currentPointDate.getTime() >= currentTime.getTime()) { + if (currentPointDate.getTime() < nextTime.getTime()) { + currentNewDateAverageSum += point.value; + currentNewDateAverageCandidates++; + } else { + // Because points are sorted by time + break; + } + } + } + } + + if (currentNewDateAverageCandidates > 0) { + newPoint.value = currentNewDateAverageSum / currentNewDateAverageCandidates; + averageLineChart.series.push(newPoint); + } + + currentTime = nextTime; + } + this.clearData(); + this.leftChartAllData = [averageLineChart]; + this.leftChart = [averageLineChart]; + } } diff --git a/elastest-torm-gui/src/app/shared/metrics-view/models/linechart-metric-model.ts b/elastest-torm-gui/src/app/shared/metrics-view/models/linechart-metric-model.ts index 63ae14224..2cab7cf37 100644 --- a/elastest-torm-gui/src/app/shared/metrics-view/models/linechart-metric-model.ts +++ b/elastest-torm-gui/src/app/shared/metrics-view/models/linechart-metric-model.ts @@ -4,8 +4,8 @@ export class LineChartMetricModel implements MetricsDataModel { name: string; series: SingleMetricModel[]; - constructor() { - this.name = ''; + constructor(name: string = '') { + this.name = name; this.series = []; } }