From fc6badb88664a7f8b9f1c72f172356fb0dac4b13 Mon Sep 17 00:00:00 2001 From: Simon Lindh Date: Thu, 31 Oct 2019 13:55:25 +0800 Subject: [PATCH] Added virtual bytes pipe for mempool graph. Added decimals to mempool graph y-axis. fixes #14 fixes #12 --- .../shared/pipes/bytes-pipe/vbytes.pipe.ts | 63 +++++++++++++++++++ frontend/src/app/shared/shared.module.ts | 6 +- .../app/statistics/statistics.component.ts | 8 +-- 3 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 frontend/src/app/shared/pipes/bytes-pipe/vbytes.pipe.ts diff --git a/frontend/src/app/shared/pipes/bytes-pipe/vbytes.pipe.ts b/frontend/src/app/shared/pipes/bytes-pipe/vbytes.pipe.ts new file mode 100644 index 000000000..a693631c8 --- /dev/null +++ b/frontend/src/app/shared/pipes/bytes-pipe/vbytes.pipe.ts @@ -0,0 +1,63 @@ +/* tslint:disable */ +import { Pipe, PipeTransform } from '@angular/core'; +import { isNumberFinite, isPositive, isInteger, toDecimal } from './utils'; + +export type ByteUnit = 'vB' | 'kvB' | 'MvB' | 'GvB' | 'TvB'; + +@Pipe({ + name: 'vbytes' +}) +export class VbytesPipe implements PipeTransform { + + static formats: { [key: string]: { max: number, prev?: ByteUnit } } = { + 'vB': {max: 1000}, + 'kvB': {max: Math.pow(1000, 2), prev: 'vB'}, + 'MvB': {max: Math.pow(1000, 3), prev: 'kvB'}, + 'GvB': {max: Math.pow(1000, 4), prev: 'MvB'}, + 'TvB': {max: Number.MAX_SAFE_INTEGER, prev: 'GvB'} + }; + + transform(input: any, decimal: number = 0, from: ByteUnit = 'vB', to?: ByteUnit): any { + + if (!(isNumberFinite(input) && + isNumberFinite(decimal) && + isInteger(decimal) && + isPositive(decimal))) { + return input; + } + + let bytes = input; + let unit = from; + while (unit !== 'vB') { + bytes *= 1024; + unit = VbytesPipe.formats[unit].prev!; + } + + if (to) { + const format = VbytesPipe.formats[to]; + + const result = toDecimal(VbytesPipe.calculateResult(format, bytes), decimal); + + return VbytesPipe.formatResult(result, to); + } + + for (const key in VbytesPipe.formats) { + const format = VbytesPipe.formats[key]; + if (bytes < format.max) { + + const result = toDecimal(VbytesPipe.calculateResult(format, bytes), decimal); + + return VbytesPipe.formatResult(result, key); + } + } + } + + static formatResult(result: number, unit: string): string { + return `${result} ${unit}`; + } + + static calculateResult(format: { max: number, prev?: ByteUnit }, bytes: number) { + const prev = format.prev ? VbytesPipe.formats[format.prev] : undefined; + return prev ? bytes / prev.max : bytes; + } +} diff --git a/frontend/src/app/shared/shared.module.ts b/frontend/src/app/shared/shared.module.ts index 058b5d8a0..492dde3a8 100644 --- a/frontend/src/app/shared/shared.module.ts +++ b/frontend/src/app/shared/shared.module.ts @@ -3,6 +3,7 @@ import { CommonModule } from '@angular/common'; import { NgbButtonsModule, NgbModalModule } from '@ng-bootstrap/ng-bootstrap'; import { BytesPipe } from './pipes/bytes-pipe/bytes.pipe'; +import { VbytesPipe } from './pipes/bytes-pipe/vbytes.pipe'; import { RoundPipe } from './pipes/math-round-pipe/math-round.pipe'; import { CeilPipe } from './pipes/math-ceil/math-ceil.pipe'; import { ChartistComponent } from '../statistics/chartist.component'; @@ -18,17 +19,20 @@ import { ChartistComponent } from '../statistics/chartist.component'; RoundPipe, CeilPipe, BytesPipe, + VbytesPipe, ], exports: [ RoundPipe, CeilPipe, BytesPipe, + VbytesPipe, NgbButtonsModule, NgbModalModule, ChartistComponent, ], providers: [ - BytesPipe + BytesPipe, + VbytesPipe, ] }) export class SharedModule { } diff --git a/frontend/src/app/statistics/statistics.component.ts b/frontend/src/app/statistics/statistics.component.ts index fb5c969f2..9a479c92a 100644 --- a/frontend/src/app/statistics/statistics.component.ts +++ b/frontend/src/app/statistics/statistics.component.ts @@ -1,12 +1,12 @@ import { Component, OnInit, LOCALE_ID, Inject } from '@angular/core'; import { ApiService } from '../services/api.service'; import { formatDate } from '@angular/common'; -import { BytesPipe } from '../shared/pipes/bytes-pipe/bytes.pipe'; +import { VbytesPipe } from '../shared/pipes/bytes-pipe/vbytes.pipe'; import * as Chartist from 'chartist'; import { FormGroup, FormBuilder } from '@angular/forms'; import { IMempoolStats } from '../blockchain/interfaces'; -import { Subject, of, merge} from 'rxjs'; +import { of, merge} from 'rxjs'; import { switchMap, tap } from 'rxjs/operators'; import { ActivatedRoute } from '@angular/router'; import { MemPoolService } from '../services/mem-pool.service'; @@ -34,7 +34,7 @@ export class StatisticsComponent implements OnInit { constructor( private apiService: ApiService, @Inject(LOCALE_ID) private locale: string, - private bytesPipe: BytesPipe, + private vbytesPipe: VbytesPipe, private formBuilder: FormBuilder, private route: ActivatedRoute, private memPoolService: MemPoolService, @@ -77,7 +77,7 @@ export class StatisticsComponent implements OnInit { }, axisY: { labelInterpolationFnc: (value: number): any => { - return this.bytesPipe.transform(value); + return this.vbytesPipe.transform(value, 2); }, offset: 160 },