Skip to content

Commit

Permalink
label response time distribution chart (#306)
Browse files Browse the repository at this point in the history
  • Loading branch information
ludeknovy authored Feb 11, 2023
1 parent 5197a39 commit 1c22b12
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 22 deletions.
50 changes: 50 additions & 0 deletions src/app/graphs/item-detail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,56 @@ export const customChartSettings = () => {
};
};

export const responseTimeDistribution = (data) => {
return {
chart: {
type: "column"
},
title: {
text: ""
},
subtitle: {
text: ""
},
legend:{ enabled:false },
xAxis: {
crosshair: true,
type: "category",
min: 0,
categories: data.map((value, index) => index * 100)
},
yAxis: {
min: 0,
title: {
text: ""
}
},
tooltip: {
shared: true,
useHTML: true,
valueSuffix: "",
valueDecimals: 0,
formatter: function () {
return `${this.y} responses were between ${this.x} and ${this.x + 100} ms`;
}
},
plotOptions: {
column: {
pointPadding: 0,
borderWidth: 0,
groupPadding: 0,
shadow: false
}
},
series: [{
data,
type: "column",
id: "histogram",
name: "Response times"
}]
}
}


export const threadLineSettings: any = {
color: "grey",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ export class AnalyzeChartsComponent implements OnInit {
// hide all axis
this.customChartsOptions.yAxis.forEach(axis => axis.visible = false)
// display only actual axis
chartSeries.forEach(serie => {
this.customChartsOptions.yAxis[serie.yAxis].visible = true
chartSeries.forEach(series => {
this.customChartsOptions.yAxis[series.yAxis].visible = true
})
this.customChartsOptions.series = JSON.parse(JSON.stringify(chartSeries));
this.updateLabelChartFlag = true;
Expand Down
2 changes: 1 addition & 1 deletion src/app/item-detail/item-detail.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ <h6 class="card-header bg-transparent">Overall Chart</h6>
</div>
</div>
</div>
<div class="col tab-charts chart" *ngIf="statusChartOptions">
<div class="col tab-charts" *ngIf="statusChartOptions">
<div class="card overview-chart-card card-shadow">
<h6 class="card-header bg-transparent">Status Codes Chart</h6>
<div class="card-body">
Expand Down
6 changes: 1 addition & 5 deletions src/app/item-detail/item-detail.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
plot: null,
extraPlotData: null,
reportStatus: null,
histogramPlotData: null,
hostname: null,
statistics: [],
name: null,
Expand Down Expand Up @@ -121,11 +122,6 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
this.overallChartOptions = {
...overallChartSettings("ms")
};





}

ngOnDestroy() {
Expand Down
2 changes: 1 addition & 1 deletion src/app/item-detail/label-chart/label-chart.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ <h6 class="card-header bg-transparent">
</h6>
<div class="card-body">
<div class="chart">
<highcharts-chart [Highcharts]="Highcharts" [options]="labelChartOptions" [callbackFunction]="chartCallback" [oneToOne]="true" [(update)]="updateLabelChartFlag"
<highcharts-chart #labelChart [Highcharts]="Highcharts" [options]="labelChartOptions" [callbackFunction]="chartCallback" [(update)]="updateLabelChartFlag"
class="highchart-chart"
style="width: 100%; height: 100%; display: block;"></highcharts-chart>
</div>
Expand Down
44 changes: 32 additions & 12 deletions src/app/item-detail/label-chart/label-chart.component.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Component, Input, OnChanges, SimpleChanges } from "@angular/core";
import { Component, Input, OnChanges, SimpleChanges, ViewChild } from "@angular/core";
import * as Highcharts from "highcharts";
import { commonGraphSettings } from "src/app/graphs/item-detail";
import { commonGraphSettings, responseTimeDistribution } from "src/app/graphs/item-detail";
import * as deepmerge from "deepmerge";
import { ChartLine } from "src/app/_services/item-chart.service";
import { Metrics } from "../metrics";
import { ResponseTimePerLabelDistribution } from "../../items.service.model";

@Component({
selector: "app-label-chart",
Expand All @@ -15,17 +16,19 @@ export class LabelChartComponent implements OnChanges {
@Input() chartLines: ChartLine;
@Input() label: string;
@Input() activated: boolean;
@Input() histogramData: ResponseTimePerLabelDistribution[];
@ViewChild("labelChart") componentRef;

Highcharts: typeof Highcharts = Highcharts;
chartMetric = "Response Times";
labelCompareChartMetric;
labelChartOptions = commonGraphSettings("reqs/s");
labelChartOptions = commonGraphSettings("ms"); // default empty chart for rendering
updateLabelChartFlag = false;
chartKeys;
chartShouldExpand = false;
chart: Highcharts.Chart;
chartCallback;
labelCharts = new Map();
expanded = false
expanded = false;
private responseTimeMetricGroup: string[];

metricChartMap = new Map([
Expand Down Expand Up @@ -54,19 +57,19 @@ export class LabelChartComponent implements OnChanges {

// chart expanded
if (!changes.activated?.previousValue && changes.activated?.currentValue) {
this.setChartAggregation()
this.setChartAggregation();
this.getChartsKey();
this.setHistogramChart();
this.changeChart({ target: { innerText: this.chartMetric } });
this.chart.reflow();
this.expanded = true
this.expanded = true;
}
// aggregation changed, we need to refresh the data but only for opened charts
if (changes.chartLines?.currentValue && this.expanded) {
this.chartLines = changes.chartLines.currentValue
this.setChartAggregation()
this.chartLines = changes.chartLines.currentValue;
this.setChartAggregation();
this.changeChart({ target: { innerText: this.chartMetric } });
}

}

private setChartAggregation() {
Expand All @@ -77,23 +80,40 @@ export class LabelChartComponent implements OnChanges {
const labelMetricsData = this.chartLines.labels.get(metric).find(data => data.name === this.label);
const chartSettings = this.metricChartMap.get(metric);
if (this.responseTimeMetricGroup.includes(metric)) {
responseTimesSeries.push({ data: labelMetricsData.data, suffix: labelMetricsData.suffix, name: metric, yAxis: 0 });
responseTimesSeries.push({ data: labelMetricsData.data, suffix: labelMetricsData.suffix, name: metric, yAxis: 0, id: metric });
} else {
this.labelCharts.set(metric, { ...chartSettings, series: [{ data: labelMetricsData.data, suffix: labelMetricsData.suffix, name: metric }, threadLine] });
this.labelCharts.set(metric, {
...chartSettings,
series: [{ data: labelMetricsData.data, suffix: labelMetricsData.suffix, name: metric, id: metric }, threadLine]
});
}
});
this.labelCharts.set("Response Times", { ...commonGraphSettings("ms"), series: [...responseTimesSeries, threadLine] });
}

private setHistogramChart() {
if (this.histogramData) {
this.chartKeys.push("Histogram");
const histogram = this.histogramData.find(data => data.label === this.label);
this.labelCharts.set("Histogram", responseTimeDistribution(histogram.values));
}
}


private getChartsKey() {
this.chartKeys = Array.from(this.labelCharts.keys());

}


changeChart(event) {
this.chartMetric = event.target.innerText;
if(this.chart) {
this.chart.destroy();
this.componentRef.chart = null;
}
this.labelChartOptions = deepmerge(this.labelCharts.get(this.chartMetric), {});
console.log(this.labelChartOptions)
this.updateLabelChartFlag = true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ <h6 class="card-header bg-transparent">Request Statistics <span class="compare">
</td>
</tr>
<tr class="collapse-row collapse" #collapse="ngbCollapse" [(ngbCollapse)]="!collapsableSettings[i]" [attr.id]="'collapse-row-' + i">
<td colspan="100"><app-label-chart [chartLines]="chartLines" [label]="_.label" [activated]="collapsableSettings[i]"></app-label-chart></td>
<td colspan="100"><app-label-chart [chartLines]="chartLines" [histogramData]="itemData?.histogramPlotData?.responseTimePerLabelDistribution" [label]="_.label" [activated]="collapsableSettings[i]"></app-label-chart></td>
</tr>
</ng-container>

Expand Down
8 changes: 8 additions & 0 deletions src/app/items.service.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ export interface ItemDetail {
environment: string;
plot: ItemDataPlot;
extraPlotData: ItemExtraPlot[];
histogramPlotData?: {
responseTimePerLabelDistribution?: ResponseTimePerLabelDistribution[]
}
statistics: ItemStatistics[];
thresholds?: {
passed: boolean,
Expand Down Expand Up @@ -286,3 +289,8 @@ export interface UpsertItemChartSettings {
data: [number, number];
}];
}

export interface ResponseTimePerLabelDistribution {
label: string
values: number[]
}

0 comments on commit 1c22b12

Please sign in to comment.