Merge branch 'master' into shubham/Change-ZEUS-logo
This commit is contained in:
		
						commit
						602d7ce207
					
				@ -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,13 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, On
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      yAxis: {
 | 
			
		||||
        max: (value) => {
 | 
			
		||||
          if (!this.outlierCappingEnabled || value.max < this.medianVbytesPerSecond * OUTLIERS_MEDIAN_MULTIPLIER) {
 | 
			
		||||
            return undefined;
 | 
			
		||||
          } else {
 | 
			
		||||
            return Math.round(this.medianVbytesPerSecond * OUTLIERS_MEDIAN_MULTIPLIER);
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        type: 'value',
 | 
			
		||||
        axisLabel: {
 | 
			
		||||
          fontSize: 11,
 | 
			
		||||
 | 
			
		||||
@ -109,18 +109,26 @@
 | 
			
		||||
    <div>
 | 
			
		||||
      <div class="card mb-3">
 | 
			
		||||
        <div class="card-header">
 | 
			
		||||
          <div class="d-flex d-md-block align-items-baseline">
 | 
			
		||||
            <span i18n="statistics.transaction-vbytes-per-second">Transaction vBytes per second (vB/s)</span>
 | 
			
		||||
            <button class="btn p-0 pl-2" style="margin: 0 0 4px 0px" (click)="onSaveChart('incoming')">
 | 
			
		||||
              <fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
 | 
			
		||||
            </button>
 | 
			
		||||
          </div>  
 | 
			
		||||
          <div class="vbytes-title">
 | 
			
		||||
            <div>
 | 
			
		||||
              <span i18n="statistics.transaction-vbytes-per-second">Transaction vBytes per second (vB/s)</span>
 | 
			
		||||
              <button class="btn p-0 pl-2" style="margin: 0 0 4px 0px" (click)="onSaveChart('incoming')">
 | 
			
		||||
                <fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
 | 
			
		||||
              </button>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="form-check">
 | 
			
		||||
              <input style="margin-top: 9px" class="form-check-input" type="checkbox" [checked]="outlierCappingEnabled" id="hide-outliers" (change)="onOutlierToggleChange($event)">
 | 
			
		||||
              <label class="form-check-label" for="hide-outliers">
 | 
			
		||||
                <small i18n="statistics.cap-outliers">Cap outliers</small>
 | 
			
		||||
              </label>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card-body">
 | 
			
		||||
          <div class="incoming-transactions-graph">
 | 
			
		||||
            <app-incoming-transactions-graph #incominggraph [height]="500" [left]="65" [template]="'advanced'"
 | 
			
		||||
              [data]="mempoolTransactionsWeightPerSecondData"></app-incoming-transactions-graph>
 | 
			
		||||
              [data]="mempoolTransactionsWeightPerSecondData" [outlierCappingEnabled]="outlierCappingEnabled"></app-incoming-transactions-graph>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
@ -222,4 +222,13 @@
 | 
			
		||||
      border-top-right-radius: 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.vbytes-title {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: baseline;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
  @media (max-width: 767px) {
 | 
			
		||||
    display: block;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -35,7 +35,7 @@ export class StatisticsComponent implements OnInit {
 | 
			
		||||
  showCount = false;
 | 
			
		||||
  maxFeeIndex: number;
 | 
			
		||||
  dropDownOpen = false;
 | 
			
		||||
 | 
			
		||||
  outlierCappingEnabled = false;
 | 
			
		||||
  mempoolStats: OptimizedMempoolStats[] = [];
 | 
			
		||||
 | 
			
		||||
  mempoolVsizeFeesData: any;
 | 
			
		||||
@ -67,6 +67,7 @@ export class StatisticsComponent implements OnInit {
 | 
			
		||||
    this.seoService.setDescription($localize`:@@meta.description.bitcoin.graphs.mempool:See mempool size (in MvB) and transactions per second (in vB/s) visualized over time.`);
 | 
			
		||||
    this.stateService.networkChanged$.subscribe((network) => this.network = network);
 | 
			
		||||
    this.graphWindowPreference = this.storageService.getValue('graphWindowPreference') ? this.storageService.getValue('graphWindowPreference').trim() : '2h';
 | 
			
		||||
    this.outlierCappingEnabled = this.storageService.getValue('cap-outliers') === 'true';
 | 
			
		||||
 | 
			
		||||
    this.radioGroupForm = this.formBuilder.group({
 | 
			
		||||
      dateSpan: this.graphWindowPreference
 | 
			
		||||
@ -156,8 +157,6 @@ export class StatisticsComponent implements OnInit {
 | 
			
		||||
    }
 | 
			
		||||
    this.maxFeeIndex = maxTier;
 | 
			
		||||
 | 
			
		||||
    this.capExtremeVbytesValues();
 | 
			
		||||
 | 
			
		||||
    this.mempoolTransactionsWeightPerSecondData = {
 | 
			
		||||
      labels: labels,
 | 
			
		||||
      series: [mempoolStats.map((stats) => [stats.added * 1000, stats.vbytes_per_second])],
 | 
			
		||||
@ -211,36 +210,10 @@ export class StatisticsComponent implements OnInit {
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * All value higher that "median * capRatio" are capped
 | 
			
		||||
   */
 | 
			
		||||
  capExtremeVbytesValues() {
 | 
			
		||||
    if (this.stateService.network.length !== 0) {
 | 
			
		||||
      return; // Only cap on Bitcoin mainnet
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let capRatio = 10;
 | 
			
		||||
    if (['1m', '3m',  '6m', '1y', '2y', '3y', '4y'].includes(this.graphWindowPreference)) {
 | 
			
		||||
      capRatio = 4;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Find median value
 | 
			
		||||
    const vBytes: number[] = [];
 | 
			
		||||
    for (const stat of this.mempoolStats) {
 | 
			
		||||
      vBytes.push(stat.vbytes_per_second);
 | 
			
		||||
    }
 | 
			
		||||
    const sorted = vBytes.slice().sort((a, b) => a - b);
 | 
			
		||||
    const middle = Math.floor(sorted.length / 2);
 | 
			
		||||
    let median = sorted[middle];
 | 
			
		||||
    if (sorted.length % 2 === 0) {
 | 
			
		||||
      median = (sorted[middle - 1] + sorted[middle]) / 2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Cap
 | 
			
		||||
    for (const stat of this.mempoolStats) {
 | 
			
		||||
      stat.vbytes_per_second = Math.min(median * capRatio, stat.vbytes_per_second);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  onOutlierToggleChange(e): void {
 | 
			
		||||
    this.outlierCappingEnabled = e.target.checked;
 | 
			
		||||
    this.storageService.setValue('cap-outliers', e.target.checked);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onSaveChart(name) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user