diff --git a/frontend/src/app/components/incoming-transactions-graph/incoming-transactions-graph.component.ts b/frontend/src/app/components/incoming-transactions-graph/incoming-transactions-graph.component.ts index 667ad1e28..82e3e77e7 100644 --- a/frontend/src/app/components/incoming-transactions-graph/incoming-transactions-graph.component.ts +++ b/frontend/src/app/components/incoming-transactions-graph/incoming-transactions-graph.component.ts @@ -7,6 +7,8 @@ import { formatNumber } from '@angular/common'; import { StateService } from '../../services/state.service'; import { Subscription } from 'rxjs'; +const OUTLIERS_MEDIAN_MULTIPLIER = 4; + @Component({ selector: 'app-incoming-transactions-graph', templateUrl: './incoming-transactions-graph.component.html', @@ -29,6 +31,7 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, On @Input() left: number | string = '0'; @Input() template: ('widget' | 'advanced') = 'widget'; @Input() windowPreferenceOverride: string; + @Input() outlierCappingEnabled: boolean = false; isLoading = true; mempoolStatsChartOption: EChartsOption = {}; @@ -40,6 +43,7 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, On MA: number[][] = []; weightMode: boolean = false; rateUnitSub: Subscription; + medianVbytesPerSecond: number | undefined; constructor( @Inject(LOCALE_ID) private locale: string, @@ -65,16 +69,35 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, On this.windowPreference = this.windowPreferenceOverride ? this.windowPreferenceOverride : this.storageService.getValue('graphWindowPreference'); const windowSize = Math.max(10, Math.floor(this.data.series[0].length / 8)); this.MA = this.calculateMA(this.data.series[0], windowSize); + if (this.outlierCappingEnabled === true) { + this.computeMedianVbytesPerSecond(this.data.series[0]); + } this.mountChart(); } rendered() { if (!this.data) { - return; + return; } this.isLoading = false; } + /** + * Calculate the median value of the vbytes per second chart to hide outliers + */ + computeMedianVbytesPerSecond(data: number[][]): void { + const vBytes: number[] = []; + for (const value of data) { + vBytes.push(value[1]); + } + const sorted = vBytes.slice().sort((a, b) => a - b); + const middle = Math.floor(sorted.length / 2); + this.medianVbytesPerSecond = sorted[middle]; + if (sorted.length % 2 === 0) { + this.medianVbytesPerSecond = (sorted[middle - 1] + sorted[middle]) / 2; + } + } + /// calculate the moving average of the provided data based on windowSize calculateMA(data: number[][], windowSize: number = 100): number[][] { //update const variables that are not changed @@ -232,6 +255,7 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, On } ], yAxis: { + max: this.outlierCappingEnabled ? Math.round(this.medianVbytesPerSecond * OUTLIERS_MEDIAN_MULTIPLIER) : undefined, type: 'value', axisLabel: { fontSize: 11, diff --git a/frontend/src/app/components/statistics/statistics.component.html b/frontend/src/app/components/statistics/statistics.component.html index 3f0ea61f5..c726e354e 100644 --- a/frontend/src/app/components/statistics/statistics.component.html +++ b/frontend/src/app/components/statistics/statistics.component.html @@ -128,7 +128,7 @@