Merge branch 'master' into recvd-htlcs
This commit is contained in:
@@ -134,7 +134,7 @@
|
||||
<ng-template #displayServerError><i class="small">({{ error.error }})</i></ng-template>
|
||||
<ng-template [ngIf]="error.status === 413 || error.status === 405" [ngIfElse]="displayServerError">
|
||||
<ng-container i18n="Electrum server limit exceeded error">
|
||||
<i>The number of transactions on this address exceeds the Electrum server limit</i>
|
||||
<i>There many transactions on this address, more than your backend can handle. See more on <a href="/docs/faq#address-lookup-issues">setting up a stronger backend</a>.</i>
|
||||
<br><br>
|
||||
Consider viewing this address on the official Mempool website instead:
|
||||
</ng-container>
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<app-indexing-progress></app-indexing-progress>
|
||||
|
||||
<div class="full-container">
|
||||
<div class="card-header mb-0 mb-md-4">
|
||||
<span i18n="mining.block-fee-rates">Block fee rates</span>
|
||||
<button class="btn" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
|
||||
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
|
||||
</button>
|
||||
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(statsObservable$ | async) as stats">
|
||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.availableTimespanDay >= 1">
|
||||
|
||||
@@ -59,11 +59,11 @@
|
||||
margin-top: 6px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@media (min-width: 1130px) {
|
||||
@media (min-width: 991px) {
|
||||
position: relative;
|
||||
top: -65px;
|
||||
}
|
||||
@media (min-width: 830px) and (max-width: 1130px) {
|
||||
@media (min-width: 830px) and (max-width: 991px) {
|
||||
position: relative;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { ApiService } from 'src/app/services/api.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { formatNumber } from '@angular/common';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { formatterXAxis, formatterXAxisLabel, formatterXAxisTimeCategory } from 'src/app/shared/graphs.utils';
|
||||
import { download, formatterXAxis, formatterXAxisLabel, formatterXAxisTimeCategory } from 'src/app/shared/graphs.utils';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
import { MiningService } from 'src/app/services/mining.service';
|
||||
import { selectPowerOfTen } from 'src/app/bitcoin.utils';
|
||||
@@ -297,4 +297,22 @@ export class BlockFeeRatesGraphComponent implements OnInit {
|
||||
isMobile() {
|
||||
return (window.innerWidth <= 767.98);
|
||||
}
|
||||
|
||||
onSaveChart() {
|
||||
// @ts-ignore
|
||||
const prevBottom = this.chartOptions.grid.bottom;
|
||||
const now = new Date();
|
||||
// @ts-ignore
|
||||
this.chartOptions.grid.bottom = 40;
|
||||
this.chartOptions.backgroundColor = '#11131f';
|
||||
this.chartInstance.setOption(this.chartOptions);
|
||||
download(this.chartInstance.getDataURL({
|
||||
pixelRatio: 2,
|
||||
excludeComponents: ['dataZoom'],
|
||||
}), `block-fee-rates-${this.timespan}-${Math.round(now.getTime() / 1000)}.svg`);
|
||||
// @ts-ignore
|
||||
this.chartOptions.grid.bottom = prevBottom;
|
||||
this.chartOptions.backgroundColor = 'none';
|
||||
this.chartInstance.setOption(this.chartOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<app-indexing-progress></app-indexing-progress>
|
||||
|
||||
<div class="full-container">
|
||||
<div class="card-header mb-0 mb-md-4">
|
||||
<span i18n="mining.block-fees">Block fees</span>
|
||||
<button class="btn" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
|
||||
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
|
||||
</button>
|
||||
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(statsObservable$ | async) as stats">
|
||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 144">
|
||||
@@ -37,7 +43,8 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="chart" echarts [initOpts]="chartInitOptions" [options]="chartOptions">
|
||||
<div class="chart" echarts [initOpts]="chartInitOptions" [options]="chartOptions"
|
||||
(chartInit)="onChartInit($event)">
|
||||
</div>
|
||||
<div class="text-center loadingGraphs" *ngIf="isLoading">
|
||||
<div class="spinner-border text-light"></div>
|
||||
|
||||
@@ -59,11 +59,11 @@
|
||||
margin-top: 6px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@media (min-width: 1130px) {
|
||||
@media (min-width: 991px) {
|
||||
position: relative;
|
||||
top: -65px;
|
||||
}
|
||||
@media (min-width: 830px) and (max-width: 1130px) {
|
||||
@media (min-width: 830px) and (max-width: 991px) {
|
||||
position: relative;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { ApiService } from 'src/app/services/api.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { formatNumber } from '@angular/common';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { formatterXAxisLabel } from 'src/app/shared/graphs.utils';
|
||||
import { download, formatterXAxisLabel } from 'src/app/shared/graphs.utils';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
import { MiningService } from 'src/app/services/mining.service';
|
||||
|
||||
@@ -40,6 +40,7 @@ export class BlockFeesGraphComponent implements OnInit {
|
||||
isLoading = true;
|
||||
formatNumber = formatNumber;
|
||||
timespan = '';
|
||||
chartInstance: any = undefined;
|
||||
|
||||
constructor(
|
||||
@Inject(LOCALE_ID) public locale: string,
|
||||
@@ -194,7 +195,29 @@ export class BlockFeesGraphComponent implements OnInit {
|
||||
};
|
||||
}
|
||||
|
||||
onChartInit(ec) {
|
||||
this.chartInstance = ec;
|
||||
}
|
||||
|
||||
isMobile() {
|
||||
return (window.innerWidth <= 767.98);
|
||||
}
|
||||
|
||||
onSaveChart() {
|
||||
// @ts-ignore
|
||||
const prevBottom = this.chartOptions.grid.bottom;
|
||||
const now = new Date();
|
||||
// @ts-ignore
|
||||
this.chartOptions.grid.bottom = 40;
|
||||
this.chartOptions.backgroundColor = '#11131f';
|
||||
this.chartInstance.setOption(this.chartOptions);
|
||||
download(this.chartInstance.getDataURL({
|
||||
pixelRatio: 2,
|
||||
excludeComponents: ['dataZoom'],
|
||||
}), `block-fees-${this.timespan}-${Math.round(now.getTime() / 1000)}.svg`);
|
||||
// @ts-ignore
|
||||
this.chartOptions.grid.bottom = prevBottom;
|
||||
this.chartOptions.backgroundColor = 'none';
|
||||
this.chartInstance.setOption(this.chartOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
<app-indexing-progress></app-indexing-progress>
|
||||
|
||||
<div class="full-container">
|
||||
|
||||
<div class="card-header mb-0 mb-md-4">
|
||||
<span i18n="mining.block-rewards">Block rewards</span>
|
||||
<button class="btn" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
|
||||
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
|
||||
</button>
|
||||
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(statsObservable$ | async) as stats">
|
||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 144">
|
||||
@@ -38,7 +44,8 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="chart" echarts [initOpts]="chartInitOptions" [options]="chartOptions">
|
||||
<div class="chart" echarts [initOpts]="chartInitOptions" [options]="chartOptions"
|
||||
(chartInit)="onChartInit($event)">
|
||||
</div>
|
||||
<div class="text-center loadingGraphs" *ngIf="isLoading">
|
||||
<div class="spinner-border text-light"></div>
|
||||
|
||||
@@ -59,11 +59,11 @@
|
||||
margin-top: 6px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@media (min-width: 1130px) {
|
||||
@media (min-width: 991px) {
|
||||
position: relative;
|
||||
top: -65px;
|
||||
}
|
||||
@media (min-width: 830px) and (max-width: 1130px) {
|
||||
@media (min-width: 830px) and (max-width: 991px) {
|
||||
position: relative;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { ApiService } from 'src/app/services/api.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { formatNumber } from '@angular/common';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { formatterXAxisLabel } from 'src/app/shared/graphs.utils';
|
||||
import { download, formatterXAxisLabel } from 'src/app/shared/graphs.utils';
|
||||
import { MiningService } from 'src/app/services/mining.service';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
|
||||
@@ -40,6 +40,7 @@ export class BlockRewardsGraphComponent implements OnInit {
|
||||
isLoading = true;
|
||||
formatNumber = formatNumber;
|
||||
timespan = '';
|
||||
chartInstance: any = undefined;
|
||||
|
||||
constructor(
|
||||
@Inject(LOCALE_ID) public locale: string,
|
||||
@@ -194,7 +195,29 @@ export class BlockRewardsGraphComponent implements OnInit {
|
||||
};
|
||||
}
|
||||
|
||||
onChartInit(ec) {
|
||||
this.chartInstance = ec;
|
||||
}
|
||||
|
||||
isMobile() {
|
||||
return (window.innerWidth <= 767.98);
|
||||
}
|
||||
|
||||
onSaveChart() {
|
||||
// @ts-ignore
|
||||
const prevBottom = this.chartOptions.grid.bottom;
|
||||
const now = new Date();
|
||||
// @ts-ignore
|
||||
this.chartOptions.grid.bottom = 40;
|
||||
this.chartOptions.backgroundColor = '#11131f';
|
||||
this.chartInstance.setOption(this.chartOptions);
|
||||
download(this.chartInstance.getDataURL({
|
||||
pixelRatio: 2,
|
||||
excludeComponents: ['dataZoom'],
|
||||
}), `block-rewards-${this.timespan}-${Math.round(now.getTime() / 1000)}.svg`);
|
||||
// @ts-ignore
|
||||
this.chartOptions.grid.bottom = prevBottom;
|
||||
this.chartOptions.backgroundColor = 'none';
|
||||
this.chartInstance.setOption(this.chartOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<app-indexing-progress *ngIf="!widget"></app-indexing-progress>
|
||||
|
||||
<div class="container-xl" [class]="widget ? 'widget' : 'full-height'">
|
||||
<h1 *ngIf="!widget" class="float-left" i18n="latest-blocks.blocks">Blocks</h1>
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<app-indexing-progress *ngIf="!widget"></app-indexing-progress>
|
||||
|
||||
<div [class]="widget === false ? 'full-container' : ''">
|
||||
|
||||
<div *ngIf="widget">
|
||||
@@ -19,6 +21,10 @@
|
||||
|
||||
<div class="card-header mb-0 mb-md-4" [style]="widget ? 'display:none' : ''">
|
||||
<span i18n="mining.hashrate-difficulty">Hashrate & Difficulty</span>
|
||||
<button class="btn" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
|
||||
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
|
||||
</button>
|
||||
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(hashrateObservable$ | async) as stats">
|
||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 4320">
|
||||
@@ -46,7 +52,8 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div [class]="!widget ? 'chart' : 'chart-widget'" echarts [initOpts]="chartInitOptions" [options]="chartOptions">
|
||||
<div [class]="!widget ? 'chart' : 'chart-widget'" echarts [initOpts]="chartInitOptions" [options]="chartOptions"
|
||||
(chartInit)="onChartInit($event)">
|
||||
</div>
|
||||
<div class="text-center loadingGraphs" *ngIf="isLoading">
|
||||
<div class="spinner-border text-light"></div>
|
||||
|
||||
@@ -59,11 +59,11 @@
|
||||
margin-top: 6px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@media (min-width: 1130px) {
|
||||
@media (min-width: 991px) {
|
||||
position: relative;
|
||||
top: -65px;
|
||||
}
|
||||
@media (min-width: 830px) and (max-width: 1130px) {
|
||||
@media (min-width: 830px) and (max-width: 991px) {
|
||||
position: relative;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { selectPowerOfTen } from 'src/app/bitcoin.utils';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
import { MiningService } from 'src/app/services/mining.service';
|
||||
import { download } from 'src/app/shared/graphs.utils';
|
||||
|
||||
@Component({
|
||||
selector: 'app-hashrate-chart',
|
||||
@@ -43,6 +44,8 @@ export class HashrateChartComponent implements OnInit {
|
||||
hashrateObservable$: Observable<any>;
|
||||
isLoading = true;
|
||||
formatNumber = formatNumber;
|
||||
timespan = '';
|
||||
chartInstance: any = undefined;
|
||||
|
||||
constructor(
|
||||
@Inject(LOCALE_ID) public locale: string,
|
||||
@@ -74,6 +77,7 @@ export class HashrateChartComponent implements OnInit {
|
||||
if (!this.widget && !firstRun) {
|
||||
this.storageService.setValue('miningWindowPreference', timespan);
|
||||
}
|
||||
this.timespan = timespan;
|
||||
firstRun = false;
|
||||
this.miningWindowPreference = timespan;
|
||||
this.isLoading = true;
|
||||
@@ -132,16 +136,12 @@ export class HashrateChartComponent implements OnInit {
|
||||
prepareChartOptions(data) {
|
||||
let title: object;
|
||||
if (data.hashrates.length === 0) {
|
||||
const lastBlock = new Date(data.timestamp * 1000);
|
||||
const dd = String(lastBlock.getDate()).padStart(2, '0');
|
||||
const mm = String(lastBlock.getMonth() + 1).padStart(2, '0'); // January is 0!
|
||||
const yyyy = lastBlock.getFullYear();
|
||||
title = {
|
||||
textStyle: {
|
||||
color: 'grey',
|
||||
fontSize: 15
|
||||
},
|
||||
text: `Indexing in progess - ${yyyy}-${mm}-${dd}`,
|
||||
text: `Indexing in progess`,
|
||||
left: 'center',
|
||||
top: 'center'
|
||||
};
|
||||
@@ -340,7 +340,29 @@ export class HashrateChartComponent implements OnInit {
|
||||
};
|
||||
}
|
||||
|
||||
onChartInit(ec) {
|
||||
this.chartInstance = ec;
|
||||
}
|
||||
|
||||
isMobile() {
|
||||
return (window.innerWidth <= 767.98);
|
||||
}
|
||||
|
||||
onSaveChart() {
|
||||
// @ts-ignore
|
||||
const prevBottom = this.chartOptions.grid.bottom;
|
||||
const now = new Date();
|
||||
// @ts-ignore
|
||||
this.chartOptions.grid.bottom = 30;
|
||||
this.chartOptions.backgroundColor = '#11131f';
|
||||
this.chartInstance.setOption(this.chartOptions);
|
||||
download(this.chartInstance.getDataURL({
|
||||
pixelRatio: 2,
|
||||
excludeComponents: ['dataZoom'],
|
||||
}), `hashrate-difficulty-${this.timespan}-${Math.round(now.getTime() / 1000)}.svg`);
|
||||
// @ts-ignore
|
||||
this.chartOptions.grid.bottom = prevBottom;
|
||||
this.chartOptions.backgroundColor = 'none';
|
||||
this.chartInstance.setOption(this.chartOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
<app-indexing-progress></app-indexing-progress>
|
||||
|
||||
<div class="full-container">
|
||||
|
||||
<div class="card-header mb-0 mb-md-4">
|
||||
<span i18n="mining.pools-dominance">Mining pools dominance</span>
|
||||
<button class="btn" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
|
||||
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
|
||||
</button>
|
||||
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(hashrateObservable$ | async) as stats">
|
||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 4320">
|
||||
@@ -29,8 +35,9 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="chart"
|
||||
echarts [initOpts]="chartInitOptions" [options]="chartOptions"></div>
|
||||
<div class="chart" echarts [initOpts]="chartInitOptions" [options]="chartOptions"
|
||||
(chartInit)="onChartInit($event)">
|
||||
</div>
|
||||
<div class="text-center loadingGraphs" *ngIf="isLoading">
|
||||
<div class="spinner-border text-light"></div>
|
||||
</div>
|
||||
|
||||
@@ -53,11 +53,11 @@
|
||||
margin-top: 6px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@media (min-width: 1130px) {
|
||||
@media (min-width: 991px) {
|
||||
position: relative;
|
||||
top: -65px;
|
||||
}
|
||||
@media (min-width: 830px) and (max-width: 1130px) {
|
||||
@media (min-width: 830px) and (max-width: 991px) {
|
||||
position: relative;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { poolsColor } from 'src/app/app.constants';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
import { MiningService } from 'src/app/services/mining.service';
|
||||
import { download } from 'src/app/shared/graphs.utils';
|
||||
import { time } from 'console';
|
||||
|
||||
@Component({
|
||||
selector: 'app-hashrate-chart-pools',
|
||||
@@ -39,6 +41,8 @@ export class HashrateChartPoolsComponent implements OnInit {
|
||||
|
||||
hashrateObservable$: Observable<any>;
|
||||
isLoading = true;
|
||||
timespan = '';
|
||||
chartInstance: any = undefined;
|
||||
|
||||
constructor(
|
||||
@Inject(LOCALE_ID) public locale: string,
|
||||
@@ -68,6 +72,7 @@ export class HashrateChartPoolsComponent implements OnInit {
|
||||
if (!firstRun) {
|
||||
this.storageService.setValue('miningWindowPreference', timespan);
|
||||
}
|
||||
this.timespan = timespan;
|
||||
firstRun = false;
|
||||
this.isLoading = true;
|
||||
return this.apiService.getHistoricalPoolsHashrate$(timespan)
|
||||
@@ -145,16 +150,12 @@ export class HashrateChartPoolsComponent implements OnInit {
|
||||
prepareChartOptions(data) {
|
||||
let title: object;
|
||||
if (data.series.length === 0) {
|
||||
const lastBlock = new Date(data.timestamp * 1000);
|
||||
const dd = String(lastBlock.getDate()).padStart(2, '0');
|
||||
const mm = String(lastBlock.getMonth() + 1).padStart(2, '0'); // January is 0!
|
||||
const yyyy = lastBlock.getFullYear();
|
||||
title = {
|
||||
textStyle: {
|
||||
color: 'grey',
|
||||
fontSize: 15
|
||||
},
|
||||
text: `Indexing in progess - ${yyyy}-${mm}-${dd}`,
|
||||
text: `Indexing in progess`,
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
};
|
||||
@@ -247,7 +248,29 @@ export class HashrateChartPoolsComponent implements OnInit {
|
||||
};
|
||||
}
|
||||
|
||||
onChartInit(ec) {
|
||||
this.chartInstance = ec;
|
||||
}
|
||||
|
||||
isMobile() {
|
||||
return (window.innerWidth <= 767.98);
|
||||
}
|
||||
|
||||
onSaveChart() {
|
||||
// @ts-ignore
|
||||
const prevBottom = this.chartOptions.grid.bottom;
|
||||
const now = new Date();
|
||||
// @ts-ignore
|
||||
this.chartOptions.grid.bottom = 30;
|
||||
this.chartOptions.backgroundColor = '#11131f';
|
||||
this.chartInstance.setOption(this.chartOptions);
|
||||
download(this.chartInstance.getDataURL({
|
||||
pixelRatio: 2,
|
||||
excludeComponents: ['dataZoom'],
|
||||
}), `pools-dominance-${this.timespan}-${Math.round(now.getTime() / 1000)}.svg`);
|
||||
// @ts-ignore
|
||||
this.chartOptions.grid.bottom = prevBottom;
|
||||
this.chartOptions.backgroundColor = 'none';
|
||||
this.chartInstance.setOption(this.chartOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<div class="echarts" echarts [initOpts]="mempoolStatsChartInitOption" [options]="mempoolStatsChartOption" (chartRendered)="rendered()"></div>
|
||||
<div class="echarts" echarts [initOpts]="mempoolStatsChartInitOption" [options]="mempoolStatsChartOption" (chartRendered)="rendered()"
|
||||
(chartInit)="onChartInit($event)">
|
||||
</div>
|
||||
<div class="text-center loadingGraphs" *ngIf="isLoading">
|
||||
<div class="spinner-border text-light"></div>
|
||||
</div>
|
||||
@@ -2,7 +2,7 @@ import { Component, Input, Inject, LOCALE_ID, ChangeDetectionStrategy, OnInit }
|
||||
import { EChartsOption } from 'echarts';
|
||||
import { OnChanges } from '@angular/core';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
import { formatterXAxis, formatterXAxisLabel } from 'src/app/shared/graphs.utils';
|
||||
import { download, formatterXAxis, formatterXAxisLabel } from 'src/app/shared/graphs.utils';
|
||||
import { formatNumber } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
@@ -34,6 +34,7 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges {
|
||||
renderer: 'svg'
|
||||
};
|
||||
windowPreference: string;
|
||||
chartInstance: any = undefined;
|
||||
|
||||
constructor(
|
||||
@Inject(LOCALE_ID) private locale: string,
|
||||
@@ -224,7 +225,29 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges {
|
||||
};
|
||||
}
|
||||
|
||||
onChartInit(ec) {
|
||||
this.chartInstance = ec;
|
||||
}
|
||||
|
||||
isMobile() {
|
||||
return window.innerWidth <= 767.98;
|
||||
}
|
||||
|
||||
onSaveChart(timespan) {
|
||||
// @ts-ignore
|
||||
const prevHeight = this.mempoolStatsChartOption.grid.height;
|
||||
const now = new Date();
|
||||
// @ts-ignore
|
||||
this.mempoolStatsChartOption.grid.height = prevHeight + 20;
|
||||
this.mempoolStatsChartOption.backgroundColor = '#11131f';
|
||||
this.chartInstance.setOption(this.mempoolStatsChartOption);
|
||||
download(this.chartInstance.getDataURL({
|
||||
pixelRatio: 2,
|
||||
excludeComponents: ['dataZoom'],
|
||||
}), `incoming-vbytes-${timespan}-${Math.round(now.getTime() / 1000)}.svg`);
|
||||
// @ts-ignore
|
||||
this.mempoolStatsChartOption.grid.height = prevHeight;
|
||||
this.mempoolStatsChartOption.backgroundColor = 'none';
|
||||
this.chartInstance.setOption(this.mempoolStatsChartOption);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<app-loading-indicator [name]="'block-indexing'" i18n-label label="Indexing blocks"></app-loading-indicator>
|
||||
<app-loading-indicator [name]="'daily-hashrate-indexing'" i18n-label label="Indexing network hashrate"></app-loading-indicator>
|
||||
<app-loading-indicator [name]="'weekly-hashrate-indexing'" i18n-label label="Indexing pools hashrate"></app-loading-indicator>
|
||||
@@ -0,0 +1,14 @@
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-indexing-progress',
|
||||
templateUrl: './indexing-progress.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class IndexingProgressComponent implements OnInit {
|
||||
constructor(
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<div *ngIf="this.indexingProgress$ | async as progress" class="sticky-loading">
|
||||
<span *ngIf="progress >= 0" class="mr-auto badge badge-pill badge-warning">{{ this.label }} ({{ progress }}%)</span>
|
||||
</div>
|
||||
@@ -0,0 +1,18 @@
|
||||
.sticky-loading {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
z-index: 100;
|
||||
font-size: 14px;
|
||||
@media (width >= 992px) {
|
||||
left: 32px;
|
||||
top: 55px;
|
||||
}
|
||||
@media (576px <= width < 992px ) {
|
||||
left: 18px;
|
||||
top: 55px;
|
||||
}
|
||||
@media (width <= 575px) {
|
||||
left: 18px;
|
||||
top: 100px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-loading-indicator',
|
||||
templateUrl: './loading-indicator.component.html',
|
||||
styleUrls: ['./loading-indicator.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class LoadingIndicatorComponent implements OnInit {
|
||||
@Input() name: string;
|
||||
@Input() label: string;
|
||||
|
||||
public indexingProgress$: Observable<number>;
|
||||
|
||||
constructor(
|
||||
private stateService: StateService,
|
||||
private websocketService: WebsocketService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.indexingProgress$ = this.stateService.loadingIndicators$
|
||||
.pipe(
|
||||
map((indicators) => indicators[this.name] ?? -1)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Component, OnInit, Input, Inject, LOCALE_ID, ChangeDetectionStrategy, OnChanges } from '@angular/core';
|
||||
import { VbytesPipe } from 'src/app/shared/pipes/bytes-pipe/vbytes.pipe';
|
||||
import { formatNumber } from "@angular/common";
|
||||
import { formatNumber } from '@angular/common';
|
||||
import { OptimizedMempoolStats } from 'src/app/interfaces/node-api.interface';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
import { EChartsOption } from 'echarts';
|
||||
import { feeLevels, chartColors } from 'src/app/app.constants';
|
||||
import { formatterXAxis, formatterXAxisLabel } from 'src/app/shared/graphs.utils';
|
||||
import { download, formatterXAxis, formatterXAxisLabel } from 'src/app/shared/graphs.utils';
|
||||
|
||||
@Component({
|
||||
selector: 'app-mempool-graph',
|
||||
@@ -45,6 +45,7 @@ export class MempoolGraphComponent implements OnInit, OnChanges {
|
||||
feeLevelsOrdered = [];
|
||||
chartColorsOrdered = chartColors;
|
||||
inverted: boolean;
|
||||
chartInstance: any = undefined;
|
||||
|
||||
constructor(
|
||||
private vbytesPipe: VbytesPipe,
|
||||
@@ -83,6 +84,7 @@ export class MempoolGraphComponent implements OnInit, OnChanges {
|
||||
this.hoverIndexSerie = e.target.parent.parent.__ecComponentInfo.index;
|
||||
}
|
||||
});
|
||||
this.chartInstance = myChart;
|
||||
}
|
||||
|
||||
handleNewMempoolData(mempoolStats: OptimizedMempoolStats[]) {
|
||||
@@ -99,7 +101,7 @@ export class MempoolGraphComponent implements OnInit, OnChanges {
|
||||
generateArray(mempoolStats: OptimizedMempoolStats[]) {
|
||||
const finalArray: number[][][] = [];
|
||||
let feesArray: number[][] = [];
|
||||
let limitFeesTemplate = this.template === 'advanced' ? 26 : 20;
|
||||
const limitFeesTemplate = this.template === 'advanced' ? 26 : 20;
|
||||
for (let index = limitFeesTemplate; index > -1; index--) {
|
||||
feesArray = [];
|
||||
mempoolStats.forEach((stats) => {
|
||||
@@ -387,5 +389,23 @@ export class MempoolGraphComponent implements OnInit, OnChanges {
|
||||
isMobile() {
|
||||
return window.innerWidth <= 767.98;
|
||||
}
|
||||
|
||||
onSaveChart(timespan) {
|
||||
// @ts-ignore
|
||||
const prevHeight = this.mempoolVsizeFeesOptions.grid.height;
|
||||
const now = new Date();
|
||||
// @ts-ignore
|
||||
this.mempoolVsizeFeesOptions.grid.height = prevHeight + 20;
|
||||
this.mempoolVsizeFeesOptions.backgroundColor = '#11131f';
|
||||
this.chartInstance.setOption(this.mempoolVsizeFeesOptions);
|
||||
download(this.chartInstance.getDataURL({
|
||||
pixelRatio: 2,
|
||||
excludeComponents: ['dataZoom'],
|
||||
}), `mempool-graph-${timespan}-${Math.round(now.getTime() / 1000)}.svg`);
|
||||
// @ts-ignore
|
||||
this.mempoolVsizeFeesOptions.grid.height = prevHeight;
|
||||
this.mempoolVsizeFeesOptions.backgroundColor = 'none';
|
||||
this.chartInstance.setOption(this.mempoolVsizeFeesOptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<app-indexing-progress></app-indexing-progress>
|
||||
|
||||
<div class="container-xl dashboard-container">
|
||||
|
||||
<div class="row row-cols-1 row-cols-md-2">
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
|
||||
@Component({
|
||||
@@ -12,8 +9,6 @@ import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class MiningDashboardComponent implements OnInit {
|
||||
private blocks = [];
|
||||
|
||||
constructor(
|
||||
private seoService: SeoService,
|
||||
private websocketService: WebsocketService,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<app-indexing-progress *ngIf="!widget"></app-indexing-progress>
|
||||
|
||||
<div [class]="widget === false ? 'full-container' : ''">
|
||||
|
||||
<div *ngIf="widget">
|
||||
@@ -25,6 +27,10 @@
|
||||
|
||||
<div class="card-header" *ngIf="!widget">
|
||||
<span i18n="mining.mining-pool-share">Mining pools share</span>
|
||||
<button class="btn" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
|
||||
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
|
||||
</button>
|
||||
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup"
|
||||
*ngIf="!widget && (miningStatsObservable$ | async) as stats">
|
||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||
|
||||
@@ -37,11 +37,11 @@
|
||||
margin-top: 6px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@media (min-width: 1130px) {
|
||||
@media (min-width: 991px) {
|
||||
position: relative;
|
||||
top: -65px;
|
||||
}
|
||||
@media (min-width: 830px) and (max-width: 1130px) {
|
||||
@media (min-width: 830px) and (max-width: 991px) {
|
||||
position: relative;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { MiningService, MiningStats } from '../../services/mining.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { chartColors, poolsColor } from 'src/app/app.constants';
|
||||
import { RelativeUrlPipe } from 'src/app/shared/pipes/relative-url/relative-url.pipe';
|
||||
import { download } from 'src/app/shared/graphs.utils';
|
||||
|
||||
@Component({
|
||||
selector: 'app-pool-ranking',
|
||||
@@ -29,6 +30,7 @@ export class PoolRankingComponent implements OnInit {
|
||||
chartInitOptions = {
|
||||
renderer: 'svg',
|
||||
};
|
||||
timespan = '';
|
||||
chartInstance: any = undefined;
|
||||
|
||||
@HostBinding('attr.dir') dir = 'ltr';
|
||||
@@ -69,6 +71,7 @@ export class PoolRankingComponent implements OnInit {
|
||||
.pipe(
|
||||
startWith(this.miningWindowPreference), // (trigger when the page loads)
|
||||
tap((value) => {
|
||||
this.timespan = value;
|
||||
if (!this.widget) {
|
||||
this.storageService.setValue('miningWindowPreference', value);
|
||||
}
|
||||
@@ -283,5 +286,17 @@ export class PoolRankingComponent implements OnInit {
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
onSaveChart() {
|
||||
const now = new Date();
|
||||
this.chartOptions.backgroundColor = '#11131f';
|
||||
this.chartInstance.setOption(this.chartOptions);
|
||||
download(this.chartInstance.getDataURL({
|
||||
pixelRatio: 2,
|
||||
excludeComponents: ['dataZoom'],
|
||||
}), `pools-ranking-${this.timespan}-${Math.round(now.getTime() / 1000)}.svg`);
|
||||
this.chartOptions.backgroundColor = 'none';
|
||||
this.chartInstance.setOption(this.chartOptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<app-indexing-progress></app-indexing-progress>
|
||||
|
||||
<div class="container-xl">
|
||||
|
||||
<!-- Pool overview -->
|
||||
|
||||
@@ -111,7 +111,7 @@ export class PoolComponent implements OnInit {
|
||||
color: 'grey',
|
||||
fontSize: 15
|
||||
},
|
||||
text: `No data`,
|
||||
text: `Indexing in progress`,
|
||||
left: 'center',
|
||||
top: 'center'
|
||||
};
|
||||
@@ -164,14 +164,14 @@ export class PoolComponent implements OnInit {
|
||||
`;
|
||||
}.bind(this)
|
||||
},
|
||||
xAxis: {
|
||||
xAxis: data.length === 0 ? undefined : {
|
||||
type: 'time',
|
||||
splitNumber: (this.isMobile()) ? 5 : 10,
|
||||
axisLabel: {
|
||||
hideOverlap: true,
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
yAxis: data.length === 0 ? undefined : [
|
||||
{
|
||||
min: (value) => {
|
||||
return value.min * 0.9;
|
||||
@@ -190,7 +190,7 @@ export class PoolComponent implements OnInit {
|
||||
}
|
||||
},
|
||||
],
|
||||
series: [
|
||||
series: data.length === 0 ? undefined : [
|
||||
{
|
||||
zlevel: 0,
|
||||
name: 'Hashrate',
|
||||
|
||||
@@ -3,14 +3,22 @@
|
||||
<div>
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-area-chart"></i> <span i18n="statistics.memory-by-vBytes">Mempool by vBytes (sat/vByte)</span>
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" [class]="stateService.env.MINING_DASHBOARD ? 'mining' : ''" (click)="saveGraphPreference()">
|
||||
<i class="fa fa-area-chart"></i>
|
||||
<span i18n="statistics.memory-by-vBytes">Mempool by vBytes (sat/vByte)</span>
|
||||
<button class="btn" style="margin: 0 0 4px 0px" (click)="onSaveChart('mempool')">
|
||||
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
|
||||
</button>
|
||||
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup"
|
||||
[class]="stateService.env.MINING_DASHBOARD ? 'mining' : ''" (click)="saveGraphPreference()">
|
||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||
<label ngbButtonLabel class="btn-primary btn-sm">
|
||||
<input ngbButton type="radio" [value]="'2h'" [routerLink]="['/graphs' | relativeUrl]" fragment="2h"> 2H (LIVE)
|
||||
<input ngbButton type="radio" [value]="'2h'" [routerLink]="['/graphs' | relativeUrl]" fragment="2h"> 2H
|
||||
(LIVE)
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm">
|
||||
<input ngbButton type="radio" [value]="'24h'" [routerLink]="['/graphs' | relativeUrl]" fragment="24h"> 24H
|
||||
<input ngbButton type="radio" [value]="'24h'" [routerLink]="['/graphs' | relativeUrl]" fragment="24h">
|
||||
24H
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm">
|
||||
<input ngbButton type="radio" [value]="'1w'" [routerLink]="['/graphs' | relativeUrl]" fragment="1w"> 1W
|
||||
@@ -37,39 +45,37 @@
|
||||
<div class="small-buttons">
|
||||
<div ngbDropdown #myDrop="ngbDropdown">
|
||||
<button class="btn btn-primary btn-sm" id="dropdownFees" ngbDropdownAnchor (click)="myDrop.toggle()">
|
||||
<fa-icon [icon]="['fas', 'filter']" [fixedWidth]="true" i18n-title="statistics.component-filter.title" title="Filter"></fa-icon>
|
||||
<fa-icon [icon]="['fas', 'filter']" [fixedWidth]="true" i18n-title="statistics.component-filter.title"
|
||||
title="Filter"></fa-icon>
|
||||
</button>
|
||||
<div class="dropdown-fees" ngbDropdownMenu aria-labelledby="dropdownFees">
|
||||
<ul>
|
||||
<ng-template ngFor let-feeData let-i="index" [ngForOf]="feeLevelDropdownData">
|
||||
<ng-template [ngIf]="feeData.fee <= 400">
|
||||
<li (click)="filterFeeIndex = feeData.fee" [class]="filterFeeIndex > feeData.fee ? 'inactive' : ''">
|
||||
<li (click)="filterFeeIndex = feeData.fee"
|
||||
[class]="filterFeeIndex > feeData.fee ? 'inactive' : ''">
|
||||
<span class="square" [ngStyle]="{'backgroundColor': feeData.color}"></span>
|
||||
<span class="fee-text">{{ feeData.range }}</span>
|
||||
</li>
|
||||
</li>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
</form>
|
||||
<div class="spinner-border text-light bootstrap-spinner" *ngIf="spinnerLoading && mempoolStats.length"></div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="incoming-transactions-graph">
|
||||
<app-mempool-graph
|
||||
dir="ltr"
|
||||
[template]="'advanced'"
|
||||
[limitFee]="500"
|
||||
[limitFilterFee]="filterFeeIndex"
|
||||
[height]="500"
|
||||
[left]="65"
|
||||
[right]="10"
|
||||
[data]="mempoolStats && mempoolStats.length ? mempoolStats : null"
|
||||
></app-mempool-graph>
|
||||
<app-mempool-graph #mempoolgraph dir="ltr" [template]="'advanced'" [limitFee]="500"
|
||||
[limitFilterFee]="filterFeeIndex" [height]="500" [left]="65" [right]="10"
|
||||
[data]="mempoolStats && mempoolStats.length ? mempoolStats : null"></app-mempool-graph>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -78,19 +84,20 @@
|
||||
<div>
|
||||
<div class="card mb-3">
|
||||
<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>
|
||||
<button class="btn" style="margin: 0 0 4px 0px" (click)="onSaveChart('incoming')">
|
||||
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="incoming-transactions-graph">
|
||||
<app-incoming-transactions-graph
|
||||
[height]="500"
|
||||
[left]="65"
|
||||
[template]="'advanced'"
|
||||
[data]="mempoolTransactionsWeightPerSecondData"
|
||||
></app-incoming-transactions-graph>
|
||||
<app-incoming-transactions-graph #incominggraph [height]="500" [left]="65" [template]="'advanced'"
|
||||
[data]="mempoolTransactionsWeightPerSecondData"></app-incoming-transactions-graph>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -53,11 +53,11 @@
|
||||
}
|
||||
}
|
||||
.formRadioGroup.mining {
|
||||
@media (min-width: 1130px) {
|
||||
@media (min-width: 991px) {
|
||||
position: relative;
|
||||
top: -65px;
|
||||
}
|
||||
@media (min-width: 830px) and (max-width: 1130px) {
|
||||
@media (min-width: 830px) and (max-width: 991px) {
|
||||
position: relative;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, OnInit, LOCALE_ID, Inject } from '@angular/core';
|
||||
import { Component, OnInit, LOCALE_ID, Inject, ViewChild, ElementRef } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { FormGroup, FormBuilder } from '@angular/forms';
|
||||
import { of, merge} from 'rxjs';
|
||||
@@ -12,6 +12,8 @@ import { StateService } from 'src/app/services/state.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
import { feeLevels, chartColors } from 'src/app/app.constants';
|
||||
import { MempoolGraphComponent } from '../mempool-graph/mempool-graph.component';
|
||||
import { IncomingTransactionsGraphComponent } from '../incoming-transactions-graph/incoming-transactions-graph.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-statistics',
|
||||
@@ -19,6 +21,9 @@ import { feeLevels, chartColors } from 'src/app/app.constants';
|
||||
styleUrls: ['./statistics.component.scss']
|
||||
})
|
||||
export class StatisticsComponent implements OnInit {
|
||||
@ViewChild('mempoolgraph') mempoolGraph: MempoolGraphComponent;
|
||||
@ViewChild('incominggraph') incomingGraph: IncomingTransactionsGraphComponent;
|
||||
|
||||
network = '';
|
||||
|
||||
loading = true;
|
||||
@@ -38,6 +43,7 @@ export class StatisticsComponent implements OnInit {
|
||||
graphWindowPreference: string;
|
||||
inverted: boolean;
|
||||
feeLevelDropdownData = [];
|
||||
timespan = '';
|
||||
|
||||
constructor(
|
||||
@Inject(LOCALE_ID) private locale: string,
|
||||
@@ -75,6 +81,7 @@ export class StatisticsComponent implements OnInit {
|
||||
)
|
||||
.pipe(
|
||||
switchMap(() => {
|
||||
this.timespan = this.radioGroupForm.controls.dateSpan.value;
|
||||
this.spinnerLoading = true;
|
||||
if (this.radioGroupForm.controls.dateSpan.value === '2h') {
|
||||
this.websocketService.want(['blocks', 'live-2h-chart']);
|
||||
@@ -195,4 +202,12 @@ export class StatisticsComponent implements OnInit {
|
||||
stat.vbytes_per_second = Math.min(median * capRatio, stat.vbytes_per_second);
|
||||
}
|
||||
}
|
||||
|
||||
onSaveChart(name) {
|
||||
if (name === 'mempool') {
|
||||
this.mempoolGraph.onSaveChart(this.timespan);
|
||||
} else if (name === 'incoming') {
|
||||
this.incomingGraph.onSaveChart(this.timespan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user