mirror of
https://github.com/mempool/mempool.git
synced 2025-03-03 09:39:17 +01:00
parent
9bef7da210
commit
8569523b89
9 changed files with 67 additions and 41 deletions
|
@ -1 +1,4 @@
|
||||||
<div class="echarts" echarts [initOpts]="mempoolStatsChartInitOption" [options]="mempoolStatsChartOption"></div>
|
<div class="echarts" echarts [initOpts]="mempoolStatsChartInitOption" [options]="mempoolStatsChartOption" (chartRendered)="rendered()"></div>
|
||||||
|
<div class="text-center loadingGraphs" *ngIf="isLoading">
|
||||||
|
<div class="spinner-border text-light"></div>
|
||||||
|
</div>
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component, OnInit, Input, Inject, LOCALE_ID, ChangeDetectionStrategy } from '@angular/core';
|
import { Component, Input, Inject, LOCALE_ID, ChangeDetectionStrategy, OnInit } from '@angular/core';
|
||||||
import { formatDate } from '@angular/common';
|
import { formatDate } from '@angular/common';
|
||||||
import { EChartsOption } from 'echarts';
|
import { EChartsOption } from 'echarts';
|
||||||
import { OnChanges } from '@angular/core';
|
import { OnChanges } from '@angular/core';
|
||||||
|
@ -7,6 +7,14 @@ import { StorageService } from 'src/app/services/storage.service';
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-incoming-transactions-graph',
|
selector: 'app-incoming-transactions-graph',
|
||||||
templateUrl: './incoming-transactions-graph.component.html',
|
templateUrl: './incoming-transactions-graph.component.html',
|
||||||
|
styles: [`
|
||||||
|
.loadingGraphs {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: calc(50% - 16px);
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
`],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class IncomingTransactionsGraphComponent implements OnInit, OnChanges {
|
export class IncomingTransactionsGraphComponent implements OnInit, OnChanges {
|
||||||
|
@ -18,6 +26,7 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges {
|
||||||
@Input() left: number | string = '0';
|
@Input() left: number | string = '0';
|
||||||
@Input() template: ('widget' | 'advanced') = 'widget';
|
@Input() template: ('widget' | 'advanced') = 'widget';
|
||||||
|
|
||||||
|
isLoading = true;
|
||||||
mempoolStatsChartOption: EChartsOption = {};
|
mempoolStatsChartOption: EChartsOption = {};
|
||||||
mempoolStatsChartInitOption = {
|
mempoolStatsChartInitOption = {
|
||||||
renderer: 'svg'
|
renderer: 'svg'
|
||||||
|
@ -29,13 +38,23 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges {
|
||||||
private storageService: StorageService,
|
private storageService: StorageService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.isLoading = true;
|
||||||
|
}
|
||||||
|
|
||||||
ngOnChanges(): void {
|
ngOnChanges(): void {
|
||||||
|
if (!this.data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.windowPreference = this.storageService.getValue('graphWindowPreference');
|
this.windowPreference = this.storageService.getValue('graphWindowPreference');
|
||||||
this.mountChart();
|
this.mountChart();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
rendered() {
|
||||||
this.mountChart();
|
if (!this.data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.isLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mountChart(): void {
|
mountChart(): void {
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
<div echarts class="echarts" (chartInit)="onChartReady($event)" [initOpts]="mempoolVsizeFeesInitOptions" [options]="mempoolVsizeFeesOptions"></div>
|
<div echarts class="echarts" (chartInit)="onChartReady($event)" (chartRendered)="rendered()" [initOpts]="mempoolVsizeFeesInitOptions" [options]="mempoolVsizeFeesOptions"></div>
|
||||||
|
<div class="text-center loadingGraphs" *ngIf="isLoading">
|
||||||
|
<div class="spinner-border text-light"></div>
|
||||||
|
</div>
|
|
@ -12,6 +12,14 @@ import { feeLevels, chartColors } from 'src/app/app.constants';
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-mempool-graph',
|
selector: 'app-mempool-graph',
|
||||||
templateUrl: './mempool-graph.component.html',
|
templateUrl: './mempool-graph.component.html',
|
||||||
|
styles: [`
|
||||||
|
.loadingGraphs {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: calc(50% - 16px);
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
`],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class MempoolGraphComponent implements OnInit, OnChanges {
|
export class MempoolGraphComponent implements OnInit, OnChanges {
|
||||||
|
@ -25,6 +33,7 @@ export class MempoolGraphComponent implements OnInit, OnChanges {
|
||||||
@Input() template: ('widget' | 'advanced') = 'widget';
|
@Input() template: ('widget' | 'advanced') = 'widget';
|
||||||
@Input() showZoom = true;
|
@Input() showZoom = true;
|
||||||
|
|
||||||
|
isLoading = true;
|
||||||
mempoolVsizeFeesData: any;
|
mempoolVsizeFeesData: any;
|
||||||
mempoolVsizeFeesOptions: EChartsOption;
|
mempoolVsizeFeesOptions: EChartsOption;
|
||||||
mempoolVsizeFeesInitOptions = {
|
mempoolVsizeFeesInitOptions = {
|
||||||
|
@ -45,16 +54,26 @@ export class MempoolGraphComponent implements OnInit, OnChanges {
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
this.isLoading = true;
|
||||||
this.inverted = this.storageService.getValue('inverted-graph') === 'true';
|
this.inverted = this.storageService.getValue('inverted-graph') === 'true';
|
||||||
this.mountFeeChart();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges() {
|
||||||
|
if (!this.data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.windowPreference = this.storageService.getValue('graphWindowPreference');
|
this.windowPreference = this.storageService.getValue('graphWindowPreference');
|
||||||
this.mempoolVsizeFeesData = this.handleNewMempoolData(this.data.concat([]));
|
this.mempoolVsizeFeesData = this.handleNewMempoolData(this.data.concat([]));
|
||||||
this.mountFeeChart();
|
this.mountFeeChart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rendered() {
|
||||||
|
if (!this.data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
|
||||||
onChartReady(myChart: any) {
|
onChartReady(myChart: any) {
|
||||||
myChart.getZr().on('mousemove', (e: any) => {
|
myChart.getZr().on('mousemove', (e: any) => {
|
||||||
if (e.target !== undefined &&
|
if (e.target !== undefined &&
|
||||||
|
|
|
@ -1,14 +1,7 @@
|
||||||
<div class="container-graph">
|
<div class="container-graph">
|
||||||
<div>
|
<div>
|
||||||
<div *ngIf="loading" class="loading">
|
|
||||||
<div class="text-center">
|
|
||||||
<h3 i18n="statistics.loading-graphs">Loading graphs...</h3>
|
|
||||||
<br>
|
|
||||||
<div class="spinner-border text-light"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<div class="card mb-3" *ngIf="mempoolStats.length">
|
<div class="card mb-3">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<i class="fa fa-area-chart"></i> <span i18n="statistics.memory-by-vBytes">Mempool by vBytes (sat/vByte)</span>
|
<i class="fa fa-area-chart"></i> <span i18n="statistics.memory-by-vBytes">Mempool by vBytes (sat/vByte)</span>
|
||||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" (click)="saveGraphPreference()">
|
<form [formGroup]="radioGroupForm" class="formRadioGroup" (click)="saveGraphPreference()">
|
||||||
|
@ -80,7 +73,7 @@
|
||||||
<button (click)="invertGraph()" class="btn btn-primary btn-sm"><fa-icon [icon]="['fas', 'exchange-alt']" [rotate]="90" [fixedWidth]="true" i18n-title="statistics.component-invert.title" title="Invert"></fa-icon></button>
|
<button (click)="invertGraph()" class="btn btn-primary btn-sm"><fa-icon [icon]="['fas', 'exchange-alt']" [rotate]="90" [fixedWidth]="true" i18n-title="statistics.component-invert.title" title="Invert"></fa-icon></button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<div class="spinner-border text-light bootstrap-spinner" *ngIf="spinnerLoading"></div>
|
<div class="spinner-border text-light bootstrap-spinner" *ngIf="spinnerLoading && mempoolStats.length"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="incoming-transactions-graph">
|
<div class="incoming-transactions-graph">
|
||||||
|
@ -92,7 +85,7 @@
|
||||||
[height]="500"
|
[height]="500"
|
||||||
[left]="65"
|
[left]="65"
|
||||||
[right]="10"
|
[right]="10"
|
||||||
[data]="mempoolStats"
|
[data]="mempoolStats && mempoolStats.length ? mempoolStats : null"
|
||||||
></app-mempool-graph>
|
></app-mempool-graph>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -100,7 +93,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="card mb-3" *ngIf="mempoolTransactionsWeightPerSecondData">
|
<div class="card mb-3">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<i class="fa fa-area-chart"></i> <span i18n="statistics.transaction-vbytes-per-second">Transaction vBytes per second (vB/s)</span>
|
<i class="fa fa-area-chart"></i> <span i18n="statistics.transaction-vbytes-per-second">Transaction vBytes per second (vB/s)</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
<div id="tv-wrapper">
|
<div id="tv-wrapper">
|
||||||
|
<div class="tv-container">
|
||||||
<div *ngIf="mempoolStats.length === 0" class="loading">
|
|
||||||
<div class="spinner-border text-light"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="tv-container" *ngIf="mempoolStats.length">
|
|
||||||
<div class="chart-holder">
|
<div class="chart-holder">
|
||||||
<app-mempool-graph
|
<app-mempool-graph
|
||||||
[template]="'advanced'"
|
[template]="'advanced'"
|
||||||
|
@ -12,7 +7,7 @@
|
||||||
[height]="600"
|
[height]="600"
|
||||||
[left]="60"
|
[left]="60"
|
||||||
[right]="10"
|
[right]="10"
|
||||||
[data]="mempoolStats"
|
[data]="mempoolStats && mempoolStats.length ? mempoolStats : null"
|
||||||
[showZoom]="false"
|
[showZoom]="false"
|
||||||
></app-mempool-graph>
|
></app-mempool-graph>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.chart-holder {
|
.chart-holder {
|
||||||
|
position: relative;
|
||||||
height: 650px;
|
height: 650px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 30px auto 0;
|
margin: 30px auto 0;
|
||||||
|
|
|
@ -47,14 +47,16 @@
|
||||||
<ng-container *ngTemplateOutlet="mempoolTable; context: { $implicit: mempoolInfoData }"></ng-container>
|
<ng-container *ngTemplateOutlet="mempoolTable; context: { $implicit: mempoolInfoData }"></ng-container>
|
||||||
<hr>
|
<hr>
|
||||||
</div>
|
</div>
|
||||||
<div class="mempool-graph" *ngIf="(mempoolStats$ | async) as mempoolStats; else loadingSpinner">
|
<ng-container *ngIf="{ value: (mempoolStats$ | async) } as mempoolStats">
|
||||||
<app-mempool-graph
|
<div class="mempool-graph">
|
||||||
|
<app-mempool-graph
|
||||||
[template]="'widget'"
|
[template]="'widget'"
|
||||||
[limitFee]="150"
|
[limitFee]="150"
|
||||||
[limitFilterFee]="1"
|
[limitFilterFee]="1"
|
||||||
[data]="mempoolStats.mempool"
|
[data]="mempoolStats.value?.mempool"
|
||||||
></app-mempool-graph>
|
></app-mempool-graph>
|
||||||
</div>
|
</div>
|
||||||
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -67,10 +69,10 @@
|
||||||
<app-lbtc-pegs-graph [data]="liquidPegsMonth$ | async"></app-lbtc-pegs-graph>
|
<app-lbtc-pegs-graph [data]="liquidPegsMonth$ | async"></app-lbtc-pegs-graph>
|
||||||
</div>
|
</div>
|
||||||
<ng-template #mempoolGraph>
|
<ng-template #mempoolGraph>
|
||||||
<div class="mempool-graph" *ngIf="(mempoolStats$ | async) as mempoolStats; else loadingSpinner">
|
<div class="mempool-graph" *ngIf="{ value: (mempoolStats$ | async) } as mempoolStats">
|
||||||
<app-incoming-transactions-graph
|
<app-incoming-transactions-graph
|
||||||
[left]="50"
|
[left]="50"
|
||||||
[data]="mempoolStats.weightPerSecond"
|
[data]="mempoolStats.value?.weightPerSecond"
|
||||||
></app-incoming-transactions-graph>
|
></app-incoming-transactions-graph>
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
@ -280,13 +282,6 @@
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
|
||||||
<ng-template #loadingSpinner>
|
|
||||||
<div class="text-center loadingGraphs">
|
|
||||||
<div class="spinner-border text-light"></div>
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
|
|
||||||
<ng-template #loadingDifficulty>
|
<ng-template #loadingDifficulty>
|
||||||
<div class="difficulty-skeleton loading-container">
|
<div class="difficulty-skeleton loading-container">
|
||||||
<div class="item">
|
<div class="item">
|
||||||
|
|
|
@ -2,15 +2,13 @@ import { ChangeDetectionStrategy, Component, Inject, LOCALE_ID, OnInit } from '@
|
||||||
import { combineLatest, merge, Observable, of, timer } from 'rxjs';
|
import { combineLatest, merge, Observable, of, timer } from 'rxjs';
|
||||||
import { filter, map, scan, share, switchMap, tap } from 'rxjs/operators';
|
import { filter, map, scan, share, switchMap, tap } from 'rxjs/operators';
|
||||||
import { Block } from '../interfaces/electrs.interface';
|
import { Block } from '../interfaces/electrs.interface';
|
||||||
import { LiquidPegs, OptimizedMempoolStats } from '../interfaces/node-api.interface';
|
import { OptimizedMempoolStats } from '../interfaces/node-api.interface';
|
||||||
import { MempoolInfo, TransactionStripped } from '../interfaces/websocket.interface';
|
import { MempoolInfo, TransactionStripped } from '../interfaces/websocket.interface';
|
||||||
import { ApiService } from '../services/api.service';
|
import { ApiService } from '../services/api.service';
|
||||||
import { StateService } from '../services/state.service';
|
import { StateService } from '../services/state.service';
|
||||||
import { formatDate } from '@angular/common';
|
|
||||||
import { WebsocketService } from '../services/websocket.service';
|
import { WebsocketService } from '../services/websocket.service';
|
||||||
import { SeoService } from '../services/seo.service';
|
import { SeoService } from '../services/seo.service';
|
||||||
import { StorageService } from '../services/storage.service';
|
import { StorageService } from '../services/storage.service';
|
||||||
import { EChartsOption } from 'echarts';
|
|
||||||
|
|
||||||
interface MempoolBlocksData {
|
interface MempoolBlocksData {
|
||||||
blocks: number;
|
blocks: number;
|
||||||
|
|
Loading…
Add table
Reference in a new issue