mirror of
https://github.com/mempool/mempool.git
synced 2025-01-18 05:12:35 +01:00
TV full screen view.
This commit is contained in:
parent
b561137962
commit
85c4a3480b
@ -3,8 +3,14 @@ import { Routes, RouterModule } from '@angular/router';
|
|||||||
import { BlockchainComponent } from './blockchain/blockchain.component';
|
import { BlockchainComponent } from './blockchain/blockchain.component';
|
||||||
import { AboutComponent } from './about/about.component';
|
import { AboutComponent } from './about/about.component';
|
||||||
import { StatisticsComponent } from './statistics/statistics.component';
|
import { StatisticsComponent } from './statistics/statistics.component';
|
||||||
|
import { TelevisionComponent } from './television/television.component';
|
||||||
|
import { MasterPageComponent } from './master-page/master-page.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: MasterPageComponent,
|
||||||
|
children: [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
children: [],
|
children: [],
|
||||||
@ -28,6 +34,12 @@ const routes: Routes = [
|
|||||||
path: 'graphs',
|
path: 'graphs',
|
||||||
component: StatisticsComponent,
|
component: StatisticsComponent,
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'tv',
|
||||||
|
component: TelevisionComponent,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '**',
|
path: '**',
|
||||||
redirectTo: ''
|
redirectTo: ''
|
||||||
|
@ -1,32 +1 @@
|
|||||||
<header>
|
|
||||||
<nav class="navbar navbar-expand-md navbar-dark bg-dark">
|
|
||||||
<a class="navbar-brand" routerLink="/"><img src="/assets/mempool-space-logo.png" width="180" class="logo"> <span class="badge badge-warning" style="margin-left: 10px;" *ngIf="isOffline">Offline</span></a>
|
|
||||||
|
|
||||||
<button class="navbar-toggler" type="button" (click)="collapse()" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div class="navbar-collapse collapse" id="navbarCollapse" [ngClass]="{'show': navCollapsed}">
|
|
||||||
<ul class="navbar-nav mr-auto">
|
|
||||||
<li class="nav-item" routerLinkActive="active" [ngClass]="{'active': txActive.isActive}" [routerLinkActiveOptions]="{exact: true}">
|
|
||||||
<a class="nav-link" routerLink="/" (click)="collapse()">Blocks</a>
|
|
||||||
<a class="nav-link" routerLink="/tx" routerLinkActive #txActive="routerLinkActive" style="display: none;"></a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item" routerLinkActive="active">
|
|
||||||
<a class="nav-link" routerLink="/graphs" (click)="collapse()">Graphs</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item" routerLinkActive="active">
|
|
||||||
<a class="nav-link" routerLink="/about" (click)="collapse()">About</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<form [formGroup]="searchForm" class="form-inline mt-2 mt-md-0 mr-4" (submit)="searchForm.valid && search()" novalidate>
|
|
||||||
<input formControlName="txId" required style="width: 300px;" class="form-control mr-sm-2" type="text" placeholder="Track transaction (TXID)" aria-label="Search">
|
|
||||||
<button class="btn btn-primary my-2 my-sm-0" type="submit">Track</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
@ -1,28 +0,0 @@
|
|||||||
li.nav-item.active {
|
|
||||||
background-color: #653b9c;
|
|
||||||
}
|
|
||||||
|
|
||||||
li.nav-item {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar {
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
.navbar {
|
|
||||||
padding: 0rem 1rem;
|
|
||||||
}
|
|
||||||
li.nav-item {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
margin-left: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
li.nav-item a {
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
@ -1,52 +1,10 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { MemPoolService } from './services/mem-pool.service';
|
|
||||||
import { Router } from '@angular/router';
|
|
||||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrls: ['./app.component.scss']
|
styleUrls: ['./app.component.scss']
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnInit {
|
export class AppComponent {
|
||||||
navCollapsed = false;
|
constructor() { }
|
||||||
isOffline = false;
|
|
||||||
searchForm: FormGroup;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private memPoolService: MemPoolService,
|
|
||||||
private router: Router,
|
|
||||||
private formBuilder: FormBuilder,
|
|
||||||
) { }
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.searchForm = this.formBuilder.group({
|
|
||||||
txId: ['', Validators.pattern('^[a-fA-F0-9]{64}$')],
|
|
||||||
});
|
|
||||||
|
|
||||||
this.memPoolService.isOffline$
|
|
||||||
.subscribe((state) => {
|
|
||||||
this.isOffline = state;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
collapse(): void {
|
|
||||||
this.navCollapsed = !this.navCollapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
search() {
|
|
||||||
const txId = this.searchForm.value.txId;
|
|
||||||
if (txId) {
|
|
||||||
if (window.location.pathname === '/' || window.location.pathname.substr(0, 4) === '/tx/') {
|
|
||||||
window.history.pushState({}, '', `/tx/${txId}`);
|
|
||||||
} else {
|
|
||||||
this.router.navigate(['/tx/', txId]);
|
|
||||||
}
|
|
||||||
this.memPoolService.txIdSearch$.next(txId);
|
|
||||||
this.searchForm.setValue({
|
|
||||||
txId: '',
|
|
||||||
});
|
|
||||||
this.collapse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,11 @@ import { ReactiveFormsModule } from '@angular/forms';
|
|||||||
import { BlockModalComponent } from './blockchain-blocks/block-modal/block-modal.component';
|
import { BlockModalComponent } from './blockchain-blocks/block-modal/block-modal.component';
|
||||||
import { StatisticsComponent } from './statistics/statistics.component';
|
import { StatisticsComponent } from './statistics/statistics.component';
|
||||||
import { ProjectedBlockModalComponent } from './blockchain-projected-blocks/projected-block-modal/projected-block-modal.component';
|
import { ProjectedBlockModalComponent } from './blockchain-projected-blocks/projected-block-modal/projected-block-modal.component';
|
||||||
|
import { TelevisionComponent } from './television/television.component';
|
||||||
import { BlockchainBlocksComponent } from './blockchain-blocks/blockchain-blocks.component';
|
import { BlockchainBlocksComponent } from './blockchain-blocks/blockchain-blocks.component';
|
||||||
import { BlockchainProjectedBlocksComponent } from './blockchain-projected-blocks/blockchain-projected-blocks.component';
|
import { BlockchainProjectedBlocksComponent } from './blockchain-projected-blocks/blockchain-projected-blocks.component';
|
||||||
|
import { ApiService } from './services/api.service';
|
||||||
|
import { MasterPageComponent } from './master-page/master-page.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -27,8 +30,10 @@ import { BlockchainProjectedBlocksComponent } from './blockchain-projected-block
|
|||||||
TxBubbleComponent,
|
TxBubbleComponent,
|
||||||
BlockModalComponent,
|
BlockModalComponent,
|
||||||
ProjectedBlockModalComponent,
|
ProjectedBlockModalComponent,
|
||||||
|
TelevisionComponent,
|
||||||
BlockchainBlocksComponent,
|
BlockchainBlocksComponent,
|
||||||
BlockchainProjectedBlocksComponent,
|
BlockchainProjectedBlocksComponent,
|
||||||
|
MasterPageComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
@ -38,6 +43,7 @@ import { BlockchainProjectedBlocksComponent } from './blockchain-projected-block
|
|||||||
SharedModule,
|
SharedModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
|
ApiService,
|
||||||
MemPoolService,
|
MemPoolService,
|
||||||
],
|
],
|
||||||
entryComponents: [
|
entryComponents: [
|
||||||
|
@ -21,7 +21,10 @@ export class BlockchainBlocksComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.blocksSubscription = this.memPoolService.blocks$
|
this.blocksSubscription = this.memPoolService.blocks$
|
||||||
.subscribe((block) => this.blocks.unshift(block));
|
.subscribe((block) => {
|
||||||
|
this.blocks.unshift(block);
|
||||||
|
this.blocks = this.blocks.slice(0, 8);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
32
frontend/src/app/master-page/master-page.component.html
Normal file
32
frontend/src/app/master-page/master-page.component.html
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<header>
|
||||||
|
<nav class="navbar navbar-expand-md navbar-dark bg-dark">
|
||||||
|
<a class="navbar-brand" routerLink="/"><img src="/assets/mempool-space-logo.png" width="180" class="logo"> <span class="badge badge-warning" style="margin-left: 10px;" *ngIf="isOffline">Offline</span></a>
|
||||||
|
|
||||||
|
<button class="navbar-toggler" type="button" (click)="collapse()" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="navbar-collapse collapse" id="navbarCollapse" [ngClass]="{'show': navCollapsed}">
|
||||||
|
<ul class="navbar-nav mr-auto">
|
||||||
|
<li class="nav-item" routerLinkActive="active" [ngClass]="{'active': txActive.isActive}" [routerLinkActiveOptions]="{exact: true}">
|
||||||
|
<a class="nav-link" routerLink="/" (click)="collapse()">Blocks</a>
|
||||||
|
<a class="nav-link" routerLink="/tx" routerLinkActive #txActive="routerLinkActive" style="display: none;"></a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" routerLinkActive="active">
|
||||||
|
<a class="nav-link" routerLink="/graphs" (click)="collapse()">Graphs</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" routerLinkActive="active">
|
||||||
|
<a class="nav-link" routerLink="/about" (click)="collapse()">About</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<form [formGroup]="searchForm" class="form-inline mt-2 mt-md-0 mr-4" (submit)="searchForm.valid && search()" novalidate>
|
||||||
|
<input formControlName="txId" required style="width: 300px;" class="form-control mr-sm-2" type="text" placeholder="Track transaction (TXID)" aria-label="Search">
|
||||||
|
<button class="btn btn-primary my-2 my-sm-0" type="submit">Track</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<router-outlet></router-outlet>
|
28
frontend/src/app/master-page/master-page.component.scss
Normal file
28
frontend/src/app/master-page/master-page.component.scss
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
li.nav-item.active {
|
||||||
|
background-color: #653b9c;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.nav-item {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.navbar {
|
||||||
|
padding: 0rem 1rem;
|
||||||
|
}
|
||||||
|
li.nav-item {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.nav-item a {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
54
frontend/src/app/master-page/master-page.component.ts
Normal file
54
frontend/src/app/master-page/master-page.component.ts
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { MemPoolService } from '../services/mem-pool.service';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-master-page',
|
||||||
|
templateUrl: './master-page.component.html',
|
||||||
|
styleUrls: ['./master-page.component.scss']
|
||||||
|
})
|
||||||
|
export class MasterPageComponent implements OnInit {
|
||||||
|
|
||||||
|
navCollapsed = false;
|
||||||
|
isOffline = false;
|
||||||
|
searchForm: FormGroup;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private memPoolService: MemPoolService,
|
||||||
|
private router: Router,
|
||||||
|
private formBuilder: FormBuilder,
|
||||||
|
) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.searchForm = this.formBuilder.group({
|
||||||
|
txId: ['', Validators.pattern('^[a-fA-F0-9]{64}$')],
|
||||||
|
});
|
||||||
|
|
||||||
|
this.memPoolService.isOffline$
|
||||||
|
.subscribe((state) => {
|
||||||
|
this.isOffline = state;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse(): void {
|
||||||
|
this.navCollapsed = !this.navCollapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
search() {
|
||||||
|
const txId = this.searchForm.value.txId;
|
||||||
|
if (txId) {
|
||||||
|
if (window.location.pathname === '/' || window.location.pathname.substr(0, 4) === '/tx/') {
|
||||||
|
window.history.pushState({}, '', `/tx/${txId}`);
|
||||||
|
} else {
|
||||||
|
this.router.navigate(['/tx/', txId]);
|
||||||
|
}
|
||||||
|
this.memPoolService.txIdSearch$.next(txId);
|
||||||
|
this.searchForm.setValue({
|
||||||
|
txId: '',
|
||||||
|
});
|
||||||
|
this.collapse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -215,13 +215,6 @@ export class StatisticsComponent implements OnInit {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getTimeToNextTenMinutes(): number {
|
|
||||||
const now = new Date();
|
|
||||||
const nextInterval = new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(),
|
|
||||||
Math.floor(now.getMinutes() / 10) * 10 + 10, 0, 0);
|
|
||||||
return nextInterval.getTime() - now.getTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
generateArray(mempoolStats: IMempoolStats[]) {
|
generateArray(mempoolStats: IMempoolStats[]) {
|
||||||
const logFees = [1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100, 125, 150, 175, 200,
|
const logFees = [1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100, 125, 150, 175, 200,
|
||||||
250, 300, 350, 400, 500, 600, 700, 800, 900, 1000, 1200, 1400, 1600, 1800, 2000];
|
250, 300, 350, 400, 500, 600, 700, 800, 900, 1000, 1200, 1400, 1600, 1800, 2000];
|
||||||
|
25
frontend/src/app/television/television.component.html
Normal file
25
frontend/src/app/television/television.component.html
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<div id="tv-wrapper">
|
||||||
|
|
||||||
|
<div *ngIf="loading" class="text-center">
|
||||||
|
<div class="spinner-border text-light"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="chart-holder" *ngIf="mempoolVsizeFeesData">
|
||||||
|
<app-chartist
|
||||||
|
[data]="mempoolVsizeFeesData"
|
||||||
|
[type]="'Line'"
|
||||||
|
[options]="mempoolVsizeFeesOptions">
|
||||||
|
</app-chartist>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center" class="blockchain-wrapper">
|
||||||
|
<div class="position-container">
|
||||||
|
<app-blockchain-projected-blocks></app-blockchain-projected-blocks>
|
||||||
|
<app-blockchain-blocks></app-blockchain-blocks>
|
||||||
|
|
||||||
|
<div id="divider"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
35
frontend/src/app/television/television.component.scss
Normal file
35
frontend/src/app/television/television.component.scss
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#tv-wrapper {
|
||||||
|
height: 100%;
|
||||||
|
margin: 10px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blockchain-wrapper {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.position-container {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
bottom: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#divider {
|
||||||
|
width: 3px;
|
||||||
|
height: 175px;
|
||||||
|
left: 0;
|
||||||
|
top: -40px;
|
||||||
|
background-image: url('/assets/divider-new.png');
|
||||||
|
background-repeat: repeat-y;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
#divider > img {
|
||||||
|
position: absolute;
|
||||||
|
left: -100px;
|
||||||
|
top: -28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-holder {
|
||||||
|
height: calc(100% - 220px);
|
||||||
|
}
|
118
frontend/src/app/television/television.component.ts
Normal file
118
frontend/src/app/television/television.component.ts
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
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 * as Chartist from 'chartist';
|
||||||
|
import { IMempoolStats } from '../blockchain/interfaces';
|
||||||
|
import { MemPoolService } from '../services/mem-pool.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-television',
|
||||||
|
templateUrl: './television.component.html',
|
||||||
|
styleUrls: ['./television.component.scss']
|
||||||
|
})
|
||||||
|
export class TelevisionComponent implements OnInit {
|
||||||
|
loading = true;
|
||||||
|
|
||||||
|
mempoolStats: IMempoolStats[] = [];
|
||||||
|
mempoolVsizeFeesData: any;
|
||||||
|
mempoolVsizeFeesOptions: any;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private apiService: ApiService,
|
||||||
|
@Inject(LOCALE_ID) private locale: string,
|
||||||
|
private bytesPipe: BytesPipe,
|
||||||
|
private memPoolService: MemPoolService,
|
||||||
|
) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.apiService.sendWebSocket({'action': 'want', data: ['projected-blocks', 'live-2h-chart']});
|
||||||
|
|
||||||
|
const labelInterpolationFnc = (value: any, index: any) => {
|
||||||
|
return index % 6 === 0 ? formatDate(value, 'HH:mm', this.locale) : null;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.mempoolVsizeFeesOptions = {
|
||||||
|
showArea: true,
|
||||||
|
showLine: false,
|
||||||
|
fullWidth: true,
|
||||||
|
showPoint: false,
|
||||||
|
low: 0,
|
||||||
|
axisX: {
|
||||||
|
labelInterpolationFnc: labelInterpolationFnc,
|
||||||
|
offset: 40
|
||||||
|
},
|
||||||
|
axisY: {
|
||||||
|
labelInterpolationFnc: (value: number): any => {
|
||||||
|
return this.bytesPipe.transform(value);
|
||||||
|
},
|
||||||
|
offset: 50
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
Chartist.plugins.ctTargetLine({
|
||||||
|
value: 1000000
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
this.apiService.list2HStatistics$()
|
||||||
|
.subscribe((mempoolStats) => {
|
||||||
|
this.mempoolStats = mempoolStats;
|
||||||
|
this.handleNewMempoolData(this.mempoolStats.concat([]));
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.memPoolService.live2Chart$
|
||||||
|
.subscribe((mempoolStats) => {
|
||||||
|
this.mempoolStats.unshift(mempoolStats);
|
||||||
|
this.mempoolStats = this.mempoolStats.slice(0, this.mempoolStats.length - 1);
|
||||||
|
this.handleNewMempoolData(this.mempoolStats.concat([]));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleNewMempoolData(mempoolStats: IMempoolStats[]) {
|
||||||
|
mempoolStats.reverse();
|
||||||
|
const labels = mempoolStats.map(stats => stats.added);
|
||||||
|
|
||||||
|
const finalArrayVbyte = this.generateArray(mempoolStats);
|
||||||
|
|
||||||
|
// Remove the 0-1 fee vbyte since it's practially empty
|
||||||
|
finalArrayVbyte.shift();
|
||||||
|
|
||||||
|
this.mempoolVsizeFeesData = {
|
||||||
|
labels: labels,
|
||||||
|
series: finalArrayVbyte
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
generateArray(mempoolStats: IMempoolStats[]) {
|
||||||
|
const logFees = [1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100, 125, 150, 175, 200,
|
||||||
|
250, 300, 350, 400, 500, 600, 700, 800, 900, 1000, 1200, 1400, 1600, 1800, 2000];
|
||||||
|
|
||||||
|
logFees.reverse();
|
||||||
|
|
||||||
|
const finalArray: number[][] = [];
|
||||||
|
let feesArray: number[] = [];
|
||||||
|
|
||||||
|
logFees.forEach((fee) => {
|
||||||
|
feesArray = [];
|
||||||
|
mempoolStats.forEach((stats) => {
|
||||||
|
// @ts-ignore
|
||||||
|
const theFee = stats['vsize_' + fee];
|
||||||
|
if (theFee) {
|
||||||
|
feesArray.push(parseInt(theFee, 10));
|
||||||
|
} else {
|
||||||
|
feesArray.push(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (finalArray.length) {
|
||||||
|
feesArray = feesArray.map((value, i) => value + finalArray[finalArray.length - 1][i]);
|
||||||
|
}
|
||||||
|
finalArray.push(feesArray);
|
||||||
|
});
|
||||||
|
finalArray.reverse();
|
||||||
|
return finalArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -66,6 +66,10 @@ body {
|
|||||||
margin-bottom: 60px;
|
margin-bottom: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
body.disable-scroll {
|
body.disable-scroll {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
Loading…
Reference in New Issue
Block a user