mempool/frontend/src/app/components/statistics/statistics.component.ts

226 lines
6.5 KiB
TypeScript
Raw Normal View History

2019-07-21 16:59:47 +02:00
import { Component, OnInit, LOCALE_ID, Inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
2019-07-21 16:59:47 +02:00
import { formatDate } from '@angular/common';
import { FormGroup, FormBuilder } from '@angular/forms';
import { of, merge} from 'rxjs';
2019-07-21 16:59:47 +02:00
import { switchMap, tap } from 'rxjs/operators';
import { VbytesPipe } from '../../pipes/bytes-pipe/vbytes.pipe';
2020-02-16 18:26:57 +01:00
import { OptimizedMempoolStats } from '../../interfaces/node-api.interface';
import { WebsocketService } from '../../services/websocket.service';
import { ApiService } from '../../services/api.service';
import * as Chartist from 'chartist';
import { StateService } from 'src/app/services/state.service';
2019-07-21 16:59:47 +02:00
@Component({
selector: 'app-statistics',
templateUrl: './statistics.component.html',
styleUrls: ['./statistics.component.scss']
})
export class StatisticsComponent implements OnInit {
loading = true;
spinnerLoading = false;
2020-02-16 18:26:57 +01:00
mempoolStats: OptimizedMempoolStats[] = [];
2019-07-21 16:59:47 +02:00
mempoolVsizeFeesData: any;
mempoolUnconfirmedTransactionsData: any;
mempoolTransactionsWeightPerSecondData: any;
mempoolVsizeFeesOptions: any;
transactionsWeightPerSecondOptions: any;
radioGroupForm: FormGroup;
constructor(
@Inject(LOCALE_ID) private locale: string,
private vbytesPipe: VbytesPipe,
2019-07-21 16:59:47 +02:00
private formBuilder: FormBuilder,
private route: ActivatedRoute,
private websocketService: WebsocketService,
private apiService: ApiService,
private stateService: StateService,
2019-07-21 16:59:47 +02:00
) {
this.radioGroupForm = this.formBuilder.group({
dateSpan: '2h'
2019-07-21 16:59:47 +02:00
});
}
ngOnInit() {
const labelInterpolationFnc = (value: any, index: any) => {
const nr = 6;
switch (this.radioGroupForm.controls.dateSpan.value) {
2019-07-21 16:59:47 +02:00
case '2h':
case '24h':
value = formatDate(value, 'HH:mm', this.locale);
break;
case '1w':
value = formatDate(value, 'dd/MM HH:mm', this.locale);
break;
case '1m':
case '3m':
case '6m':
2020-02-16 18:26:57 +01:00
case '1y':
2019-07-21 16:59:47 +02:00
value = formatDate(value, 'dd/MM', this.locale);
}
return index % nr === 0 ? value : 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.vbytesPipe.transform(value, 2);
2019-07-21 16:59:47 +02:00
},
offset: 160
},
plugins: [
Chartist.plugins.ctTargetLine({
value: 1000000
}),
Chartist.plugins.legend({
legendNames: [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].map((sats, i, arr) => {
if (sats === 600) {
return '500+';
}
if (i === 0) {
return '1 sat/vbyte';
}
return arr[i - 1] + ' - ' + sats;
})
})
]
};
this.transactionsWeightPerSecondOptions = {
showArea: false,
showLine: true,
showPoint: false,
low: 0,
axisY: {
offset: 40
},
axisX: {
labelInterpolationFnc: labelInterpolationFnc
},
plugins: [
Chartist.plugins.ctTargetLine({
value: 1667
}),
]
};
this.route
.fragment
.subscribe((fragment) => {
2020-02-16 18:26:57 +01:00
if (['2h', '24h', '1w', '1m', '3m', '6m', '1y'].indexOf(fragment) > -1) {
this.radioGroupForm.controls.dateSpan.setValue(fragment, { emitEvent: false });
2019-07-21 16:59:47 +02:00
}
});
merge(
of(''),
this.radioGroupForm.controls.dateSpan.valueChanges
2019-07-21 16:59:47 +02:00
.pipe(
tap(() => {
this.mempoolStats = [];
})
)
)
.pipe(
switchMap(() => {
this.spinnerLoading = true;
if (this.radioGroupForm.controls.dateSpan.value === '2h') {
2020-02-17 14:39:20 +01:00
this.websocketService.want(['blocks', 'live-2h-chart']);
return this.apiService.list2HStatistics$();
2019-07-21 16:59:47 +02:00
}
2020-02-17 14:39:20 +01:00
this.websocketService.want(['blocks']);
if (this.radioGroupForm.controls.dateSpan.value === '24h') {
return this.apiService.list24HStatistics$();
2019-07-21 16:59:47 +02:00
}
if (this.radioGroupForm.controls.dateSpan.value === '1w') {
2019-07-21 16:59:47 +02:00
return this.apiService.list1WStatistics$();
}
if (this.radioGroupForm.controls.dateSpan.value === '1m') {
return this.apiService.list1MStatistics$();
2019-07-21 16:59:47 +02:00
}
if (this.radioGroupForm.controls.dateSpan.value === '3m') {
return this.apiService.list3MStatistics$();
2019-07-21 16:59:47 +02:00
}
2020-02-16 18:26:57 +01:00
if (this.radioGroupForm.controls.dateSpan.value === '6m') {
return this.apiService.list6MStatistics$();
}
return this.apiService.list1YStatistics$();
2019-07-21 16:59:47 +02:00
})
)
.subscribe((mempoolStats: any) => {
this.mempoolStats = mempoolStats;
this.handleNewMempoolData(this.mempoolStats.concat([]));
2019-07-21 16:59:47 +02:00
this.loading = false;
this.spinnerLoading = false;
});
this.stateService.live2Chart$
.subscribe((mempoolStats) => {
this.mempoolStats.unshift(mempoolStats);
this.mempoolStats = this.mempoolStats.slice(0, this.mempoolStats.length - 1);
this.handleNewMempoolData(this.mempoolStats.concat([]));
});
2019-07-21 16:59:47 +02:00
}
2020-02-16 18:26:57 +01:00
handleNewMempoolData(mempoolStats: OptimizedMempoolStats[]) {
2019-07-21 16:59:47 +02:00
mempoolStats.reverse();
const labels = mempoolStats.map(stats => stats.added);
this.mempoolTransactionsWeightPerSecondData = {
labels: labels,
series: [mempoolStats.map((stats) => stats.vbytes_per_second)],
};
const finalArrayVbyte = this.generateArray(mempoolStats);
// Remove the 0-1 fee vbyte since it's practially empty
finalArrayVbyte.shift();
this.mempoolVsizeFeesData = {
labels: labels,
series: finalArrayVbyte
};
}
2020-02-16 18:26:57 +01:00
generateArray(mempoolStats: OptimizedMempoolStats[]) {
2019-07-21 16:59:47 +02:00
const finalArray: number[][] = [];
let feesArray: number[] = [];
2020-02-16 18:26:57 +01:00
for (let index = 37; index > -1; index--) {
2019-07-21 16:59:47 +02:00
feesArray = [];
mempoolStats.forEach((stats) => {
2020-02-16 18:26:57 +01:00
const theFee = stats.vsizes[index].toString();
2019-07-21 16:59:47 +02:00
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);
2020-02-16 18:26:57 +01:00
}
2019-07-21 16:59:47 +02:00
finalArray.reverse();
return finalArray;
}
}