From faf0db41a2c986d47834fac796de603976db55ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lud=C4=9Bk=20Nov=C3=BD?= <13610612+ludeknovy@users.noreply.github.com> Date: Fri, 27 Sep 2024 16:33:00 +0200 Subject: [PATCH] Add date range to charts and refactor chart options Integrated start and end date parameters into the charts to allow for date range filtering. Refactored chart option handling by introducing the `ItemChartOption` class, improving code organization and readability. --- src/app/_services/comparison-chart.service.ts | 36 ++++--- src/app/graphs/item-detail.ts | 6 +- src/app/item-detail/item-chart-option.ts | 23 +++++ .../item-detail/item-detail.component.html | 22 +++-- src/app/item-detail/item-detail.component.ts | 97 ++++++++++--------- .../label-chart/label-chart.component.ts | 4 +- .../stats-compare/stats-compare.component.ts | 8 +- 7 files changed, 125 insertions(+), 71 deletions(-) create mode 100644 src/app/item-detail/item-chart-option.ts diff --git a/src/app/_services/comparison-chart.service.ts b/src/app/_services/comparison-chart.service.ts index 37f066cb..3174f414 100644 --- a/src/app/_services/comparison-chart.service.ts +++ b/src/app/_services/comparison-chart.service.ts @@ -1,19 +1,19 @@ import { Injectable } from "@angular/core"; import { BehaviorSubject } from "rxjs"; -import { ChartLines, getChartLines } from "./chart-service-utils"; +import { ChartLine, getChartLines } from "./chart-service-utils"; @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class ComparisonChartService { - private plot$ = new BehaviorSubject({ chartLines: null }); - private histogramPlot$ = new BehaviorSubject<{ responseTimePerLabelDistribution: []}>(null); + private plot$ = new BehaviorSubject({ chartLines: null, startDate: null, endDate: null }); + private histogramPlot$ = new BehaviorSubject<{ responseTimePerLabelDistribution: [] }>(null); private interval$ = new BehaviorSubject(null); selectedPlot$ = this.plot$.asObservable(); - histogram$ = this.histogramPlot$.asObservable() + histogram$ = this.histogramPlot$.asObservable(); setInterval(interval) { @@ -25,21 +25,31 @@ export class ComparisonChartService { } resetPlot() { - this.plot$.next(null) + this.plot$.next(null); } - setComparisonPlot(defaultPlot, extraPlots) { + setComparisonPlot(defaultPlot: ChartLine, extraPlots, startDate, endDate) { this.interval$.subscribe(interval => { - let comparisonPlot = null + let comparisonPlot: ChartLine = null; if (!interval || interval === "Auto") { - comparisonPlot = defaultPlot + comparisonPlot = defaultPlot; } else { - const extraPlotIntervalData = extraPlots?.find(extraPlot => extraPlot.interval === interval)?.data - comparisonPlot = extraPlotIntervalData || defaultPlot + const extraPlotIntervalData = extraPlots?.find(extraPlot => extraPlot.interval === interval)?.data; + comparisonPlot = extraPlotIntervalData || defaultPlot; } - this.plot$.next(comparisonPlot ? getChartLines(comparisonPlot): null) - }) + this.plot$.next({ + chartLines: comparisonPlot ? getChartLines(comparisonPlot).chartLines : null, + startDate: startDate ? new Date(startDate) : null, + endDate: endDate ? new Date(endDate) : null, + }); + }); } } + +export interface ComparisonChartLines { + chartLines?: ChartLine; + startDate: Date; + endDate: Date; +} diff --git a/src/app/graphs/item-detail.ts b/src/app/graphs/item-detail.ts index 232a720a..d5649c74 100644 --- a/src/app/graphs/item-detail.ts +++ b/src/app/graphs/item-detail.ts @@ -279,7 +279,7 @@ export const networkLineSettings: any = { name: Metrics.Network }; -export const scatterChart = { +export const scatterChart = () => ({ chart: { type: "scatter", zoomType: "xy", @@ -297,6 +297,8 @@ export const scatterChart = { }, xAxis: { showLastLabel: true, + min: null, + max: null, type: "datetime", legend: { enabled: false, @@ -339,4 +341,4 @@ export const scatterChart = { } } }, -}; +}); diff --git a/src/app/item-detail/item-chart-option.ts b/src/app/item-detail/item-chart-option.ts new file mode 100644 index 00000000..d1e8081c --- /dev/null +++ b/src/app/item-detail/item-chart-option.ts @@ -0,0 +1,23 @@ +export class ItemChartOption { + public overallChart = null + public threadsPerThreadGroup = null + public scatterChartOptions = null + public statusChartOptions = null + + setChartsOptions(options: { overallChart: any, threadsPerThreadGroup: any, scatterChartOptions: any, statusChartOptions: any }) { + if (!options) { + return + } + this.overallChart = options.overallChart + this.threadsPerThreadGroup = options.threadsPerThreadGroup + this.scatterChartOptions = options.scatterChartOptions + this.statusChartOptions = options.statusChartOptions + } + + resetChartOptions() { + this.overallChart = null + this.threadsPerThreadGroup = null + this.scatterChartOptions = null + this.statusChartOptions = null + } +} diff --git a/src/app/item-detail/item-detail.component.html b/src/app/item-detail/item-detail.component.html index 33699f65..d76e5db0 100644 --- a/src/app/item-detail/item-detail.component.html +++ b/src/app/item-detail/item-detail.component.html @@ -402,11 +402,11 @@
Overall Chart style="width: 100%; height: 350px; display: block;"> - + -
+
-
@@ -430,14 +430,18 @@
style="width: 100%; height: 350px; display: block;"> - -
- + + +
+ + +
@@ -458,12 +462,12 @@
Status Codes Chart
style="width: 100%; height: 350px; display: block;"> - + -
+
-
diff --git a/src/app/item-detail/item-detail.component.ts b/src/app/item-detail/item-detail.component.ts index 08536242..712f0490 100644 --- a/src/app/item-detail/item-detail.component.ts +++ b/src/app/item-detail/item-detail.component.ts @@ -18,7 +18,8 @@ import { AnalyzeChartService } from "../analyze-chart.service"; import { getValidationResults } from "../utils/showZeroErrorTolerance"; import { ItemChartService } from "../_services/item-chart.service"; import { ComparisonChartService } from "../_services/comparison-chart.service"; -import { ChartLines } from "../_services/chart-service-utils"; +import { ChartLine } from "../_services/chart-service-utils"; +import { ItemChartOption } from "./item-chart-option"; exporting(Highcharts); @@ -86,21 +87,13 @@ export class ItemDetailComponent implements OnInit, OnDestroy { zeroErrorValidation: null, minTestDurationValidation: null, }; - comparisonChartOptionsDefault = { - overallChart: null, - threadsPerThreadGroup: null, - scatterChartOptions: null, - statusChartOptions: null, - }; - comparisonLabelChartOptions = { - overallChart: null, - threadsPerThreadGroup: null, - scatterChartOptions: null, - statusChartOptions: null, - }; + comparisonItemChartOptions = new ItemChartOption() comparisonChart: Highcharts.Chart; - updateComparisonChartFlag; + scatterChart: Highcharts.Chart; + updateComparisonChartFlag = false; + updateComparisonScatterChartFlag = false; comparisonChartCallback; + comparisonScatterChartCallback constructor( private route: ActivatedRoute, @@ -119,6 +112,9 @@ export class ItemDetailComponent implements OnInit, OnDestroy { this.comparisonChartCallback = chart => { this.comparisonChart = chart; }; + this.comparisonScatterChartCallback = chart => { + this.scatterChart = chart; + }; } @@ -182,7 +178,7 @@ export class ItemDetailComponent implements OnInit, OnDestroy { private selectedPlotSubscription() { this.itemChartService.selectedPlot$.subscribe((value) => { this.chartLines = value.chartLines; - const chartOptions = this.prepareChartOptions(value) + const chartOptions = this.prepareChartOptions(value.chartLines) this.threadsPerThreadGroup = chartOptions.threadsPerThreadGroup this.overallChartOptions = chartOptions.overallChart this.statusChartOptions = chartOptions.statusChartOptions @@ -204,54 +200,67 @@ export class ItemDetailComponent implements OnInit, OnDestroy { private comparisonSubscription() { this.comparisonChartService.selectedPlot$.subscribe((plot) => { + this.comparisonItemChartOptions.resetChartOptions(); if (!plot) { - if (this.comparisonChart) { - this.comparisonLabelChartOptions = this.comparisonChartOptionsDefault; - this.comparisonChart = null; - } + this.comparisonChart = null; return; + } else { + this.comparisonItemChartOptions.setChartsOptions(this.prepareChartOptions(plot.chartLines, plot.startDate, plot.endDate)); } - this.comparisonLabelChartOptions = this.prepareChartOptions(plot) - this.updateChartFlag = true; - this.updateScatterChartFlag = true; + this.updateComparisonChartFlag = true; + this.updateComparisonScatterChartFlag = true }); } - private prepareChartOptions(plot: ChartLines) { - const chartOptions = this.comparisonChartOptionsDefault - if (plot.chartLines) { - const overallChartSeries = Array.from(this.chartLines?.overall?.values()); - if (plot.chartLines.threadsPerThreadGroup.has(Metrics.Threads)) { - chartOptions.threadsPerThreadGroup = plot.chartLines.threadsPerThreadGroup.get(Metrics.Threads); - } + private prepareChartOptions(plot: ChartLine, startDate?: Date, endDate?: Date) { + const chartOptions = { + overallChart: null, + threadsPerThreadGroup: null, + scatterChartOptions: null, + statusChartOptions: null, + } + if (plot) { + if(plot.overall) { + const overallChartSeries = Array.from(plot.overall?.values()); + if (plot.threadsPerThreadGroup.has(Metrics.Threads)) { + chartOptions.threadsPerThreadGroup = plot.threadsPerThreadGroup.get(Metrics.Threads); + } - chartOptions.overallChart = { - ...overallChartSettings("ms"), - series: JSON.parse(JSON.stringify(overallChartSeries)) - }; + chartOptions.overallChart = { + ...overallChartSettings("ms"), + series: JSON.parse(JSON.stringify(overallChartSeries)) + }; + } + const scatterResponseTimeData = plot.scatter.get(Metrics.ResponseTimeRaw); + if (scatterResponseTimeData) { + chartOptions.scatterChartOptions = { + ...scatterChart(), + series: [{ + data: scatterResponseTimeData, name: "Response Time", marker: { + radius: 1 + }, + }] + }; + if (startDate && endDate) { + chartOptions.scatterChartOptions.xAxis.min = startDate.getTime() + chartOptions.scatterChartOptions.xAxis.max = endDate.getTime() + } - const scatterResponseTimeData = plot.chartLines.scatter.get(Metrics.ResponseTimeRaw); - if (plot.chartLines?.scatter?.has(Metrics.ResponseTimeRaw)) { - chartOptions.scatterChartOptions = scatterChart; - chartOptions.scatterChartOptions.series = [{ - data: scatterResponseTimeData, name: "Response Time", marker: { - radius: 1 - }, - }]; } - if (plot.chartLines?.statusCodes?.has(Metrics.StatusCodeInTime)) { + if (plot?.statusCodes?.has(Metrics.StatusCodeInTime)) { // initialize the chart options only when there are the status codes data chartOptions.statusChartOptions = { ...commonGraphSettings("") }; - const statusCodesLines = plot.chartLines?.statusCodes.get(Metrics.StatusCodeInTime); + const statusCodesLines = plot?.statusCodes.get(Metrics.StatusCodeInTime); chartOptions.statusChartOptions.series = JSON.parse(JSON.stringify(statusCodesLines.data)); } - return chartOptions; } + + return chartOptions; } private updateMinMaxOfCharts(min, max) { diff --git a/src/app/item-detail/label-chart/label-chart.component.ts b/src/app/item-detail/label-chart/label-chart.component.ts index f0a0b76d..efe9d527 100644 --- a/src/app/item-detail/label-chart/label-chart.component.ts +++ b/src/app/item-detail/label-chart/label-chart.component.ts @@ -150,7 +150,9 @@ export class LabelChartComponent implements OnChanges { this.labelCharts.set("Histogram", responseTimeDistribution(histogram.values)); } else { const histogram = histogramData.find(data => data.label === this.label); - this.comparisonLabelCharts.set("Histogram", responseTimeDistribution(histogram.values)); + if (histogram && histogram.data) { + this.comparisonLabelCharts.set("Histogram", responseTimeDistribution(histogram.values)); + } } } diff --git a/src/app/item-detail/stats-compare/stats-compare.component.ts b/src/app/item-detail/stats-compare/stats-compare.component.ts index dc2904bf..bda48747 100644 --- a/src/app/item-detail/stats-compare/stats-compare.component.ts +++ b/src/app/item-detail/stats-compare/stats-compare.component.ts @@ -84,7 +84,9 @@ export class StatsCompareComponent implements OnInit { environment: _.environment, plot: _.plot, histogramPlotData: _.histogramPlotData, - extraPlotData: _.extraPlotData + extraPlotData: _.extraPlotData, + startDate: _.overview.startDate, + endDate: _.overview.endDate, }); this.page = 0; this.modalService.dismissAll(); @@ -103,13 +105,15 @@ export class StatsCompareComponent implements OnInit { plot: _.plot, histogramPlotData: _.histogramPlotData, extraPlotData: _.extraPlotData, + startDate: _.overview.startDate, + endDate: _.overview.endDate, id })); } itemToCompare(data) { this.resetStatsData(); - this.comparisonChartService.setComparisonPlot(data.plot, data.extraPlotData); + this.comparisonChartService.setComparisonPlot(data.plot, data.extraPlotData, data.startDate, data.endDate); this.comparisonChartService.setHistogramPlot(data.histogramPlotData); this.comparingData = data; this.comparedMetadata = { id: data.id, maxVu: data.maxVu };