mirror of
https://github.com/mempool/mempool.git
synced 2025-02-24 22:58:30 +01:00
Cleanup hashrate/difficulty widget
This commit is contained in:
parent
c4e5e45855
commit
b19d9c1af2
5 changed files with 119 additions and 63 deletions
|
@ -1,5 +1,23 @@
|
||||||
<div [class]="widget === false ? 'full-container' : ''">
|
<div [class]="widget === false ? 'full-container' : ''">
|
||||||
|
|
||||||
|
<div *ngIf="widget">
|
||||||
|
<div class="pool-distribution" *ngIf="(hashrateObservable$ | async) as hashrates; else loadingStats">
|
||||||
|
<div class="item">
|
||||||
|
<h5 class="card-title" i18n="mining.hashrate">Hashrate</h5>
|
||||||
|
<p class="card-text">
|
||||||
|
{{ hashrates.currentHashrate | amountShortener }}
|
||||||
|
<span class="symbol">hashes/tx</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<h5 class="card-title" i18n="master-page.blocks">Difficulty</h5>
|
||||||
|
<p class="card-text">
|
||||||
|
{{ hashrates.currentDifficulty | amountShortener }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="card-header mb-0 mb-md-4" [style]="widget ? 'display:none' : ''">
|
<div class="card-header mb-0 mb-md-4" [style]="widget ? 'display:none' : ''">
|
||||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(hashrateObservable$ | async) as hashrates">
|
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(hashrateObservable$ | async) as hashrates">
|
||||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||||
|
@ -32,3 +50,20 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<ng-template #loadingStats>
|
||||||
|
<div class="pool-distribution">
|
||||||
|
<div class="item">
|
||||||
|
<h5 class="card-title" i18n="mining.miners-luck">Hashrate</h5>
|
||||||
|
<p class="card-text">
|
||||||
|
<span class="skeleton-loader skeleton-loader-big"></span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<h5 class="card-title" i18n="master-page.blocks">Difficulty</h5>
|
||||||
|
<p class="card-text">
|
||||||
|
<span class="skeleton-loader skeleton-loader-big"></span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
|
@ -29,7 +29,7 @@
|
||||||
.chart-widget {
|
.chart-widget {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
max-height: 293px;
|
max-height: 270px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.formRadioGroup {
|
.formRadioGroup {
|
||||||
|
@ -48,3 +48,66 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pool-distribution {
|
||||||
|
min-height: 56px;
|
||||||
|
display: block;
|
||||||
|
@media (min-width: 485px) {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
h5 {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.item {
|
||||||
|
width: 50%;
|
||||||
|
margin: 0px auto 10px;
|
||||||
|
display: inline-block;
|
||||||
|
@media (min-width: 485px) {
|
||||||
|
margin: 0px auto 10px;
|
||||||
|
}
|
||||||
|
@media (min-width: 785px) {
|
||||||
|
margin: 0px auto 0px;
|
||||||
|
}
|
||||||
|
&:last-child {
|
||||||
|
margin: 0px auto 0px;
|
||||||
|
}
|
||||||
|
&:nth-child(2) {
|
||||||
|
order: 2;
|
||||||
|
@media (min-width: 485px) {
|
||||||
|
order: 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:nth-child(3) {
|
||||||
|
order: 3;
|
||||||
|
@media (min-width: 485px) {
|
||||||
|
order: 2;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.card-title {
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #4a68b9;
|
||||||
|
}
|
||||||
|
.card-text {
|
||||||
|
font-size: 18px;
|
||||||
|
span {
|
||||||
|
color: #ffffff66;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-loader {
|
||||||
|
width: 100%;
|
||||||
|
display: block;
|
||||||
|
max-width: 80px;
|
||||||
|
margin: 15px auto 3px;
|
||||||
|
}
|
||||||
|
|
|
@ -109,21 +109,10 @@ export class HashrateChartComponent implements OnInit {
|
||||||
(new Date().getTime() / 1000) - (data.oldestIndexedBlockTimestamp)
|
(new Date().getTime() / 1000) - (data.oldestIndexedBlockTimestamp)
|
||||||
) / 3600 / 24;
|
) / 3600 / 24;
|
||||||
|
|
||||||
const tableData = [];
|
|
||||||
for (let i = data.difficulty.length - 1; i > 0; --i) {
|
|
||||||
const selectedPowerOfTen: any = selectPowerOfTen(data.difficulty[i].difficulty);
|
|
||||||
const change = (data.difficulty[i].difficulty / data.difficulty[i - 1].difficulty - 1) * 100;
|
|
||||||
|
|
||||||
tableData.push(Object.assign(data.difficulty[i], {
|
|
||||||
change: change,
|
|
||||||
difficultyShorten: formatNumber(
|
|
||||||
data.difficulty[i].difficulty / selectedPowerOfTen.divider,
|
|
||||||
this.locale, '1.2-2') + selectedPowerOfTen.unit
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
availableTimespanDay: availableTimespanDay,
|
availableTimespanDay: availableTimespanDay,
|
||||||
difficulty: this.tableOnly ? tableData.slice(0, 5) : tableData,
|
currentDifficulty: Math.round(data.difficulty[data.difficulty.length - 1].difficulty * 100) / 100,
|
||||||
|
currentHashrate: data.hashrates[data.hashrates.length - 1].avgHashrate,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
retryWhen((errors) => errors.pipe(
|
retryWhen((errors) => errors.pipe(
|
||||||
|
@ -166,6 +155,7 @@ export class HashrateChartComponent implements OnInit {
|
||||||
'#D81B60',
|
'#D81B60',
|
||||||
],
|
],
|
||||||
grid: {
|
grid: {
|
||||||
|
top: 30,
|
||||||
right: this.right,
|
right: this.right,
|
||||||
left: this.left,
|
left: this.left,
|
||||||
bottom: this.widget ? 30 : 60,
|
bottom: this.widget ? 30 : 60,
|
||||||
|
@ -209,7 +199,7 @@ export class HashrateChartComponent implements OnInit {
|
||||||
type: 'time',
|
type: 'time',
|
||||||
splitNumber: (this.isMobile() || this.widget) ? 5 : 10,
|
splitNumber: (this.isMobile() || this.widget) ? 5 : 10,
|
||||||
},
|
},
|
||||||
legend: data.hashrates.length === 0 ? undefined : {
|
legend: (this.widget || data.hashrates.length === 0) ? undefined : {
|
||||||
data: [
|
data: [
|
||||||
{
|
{
|
||||||
name: 'Hashrate',
|
name: 'Hashrate',
|
||||||
|
@ -241,7 +231,6 @@ export class HashrateChartComponent implements OnInit {
|
||||||
return value.min * 0.9;
|
return value.min * 0.9;
|
||||||
},
|
},
|
||||||
type: 'value',
|
type: 'value',
|
||||||
name: 'Hashrate',
|
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
color: 'rgb(110, 112, 121)',
|
color: 'rgb(110, 112, 121)',
|
||||||
formatter: (val) => {
|
formatter: (val) => {
|
||||||
|
@ -259,7 +248,6 @@ export class HashrateChartComponent implements OnInit {
|
||||||
return value.min * 0.9;
|
return value.min * 0.9;
|
||||||
},
|
},
|
||||||
type: 'value',
|
type: 'value',
|
||||||
name: 'Difficulty',
|
|
||||||
position: 'right',
|
position: 'right',
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
color: 'rgb(110, 112, 121)',
|
color: 'rgb(110, 112, 121)',
|
||||||
|
|
|
@ -86,9 +86,6 @@
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card" style="height: 385px">
|
<div class="card" style="height: 385px">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">
|
|
||||||
Hashrate (1y)
|
|
||||||
</h5>
|
|
||||||
<app-hashrate-chart [widget]=true></app-hashrate-chart>
|
<app-hashrate-chart [widget]=true></app-hashrate-chart>
|
||||||
<div class="mt-1"><a [routerLink]="['/mining/hashrate' | relativeUrl]" i18n="dashboard.view-more">View more
|
<div class="mt-1"><a [routerLink]="['/mining/hashrate' | relativeUrl]" i18n="dashboard.view-more">View more
|
||||||
»</a></div>
|
»</a></div>
|
||||||
|
@ -96,20 +93,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- pool dominance -->
|
|
||||||
<!-- <div class="col">
|
|
||||||
<div class="card" style="height: 385px">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">
|
|
||||||
Mining Pools Dominance (1y)
|
|
||||||
</h5>
|
|
||||||
<app-hashrate-chart-pools [widget]=true></app-hashrate-chart-pools>
|
|
||||||
<div class="mt-1"><a [routerLink]="['/mining/hashrate/pools' | relativeUrl]" i18n="dashboard.view-more">View
|
|
||||||
more »</a></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
|
|
||||||
<!-- Latest blocks -->
|
<!-- Latest blocks -->
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card" style="height: 385px">
|
<div class="card" style="height: 385px">
|
||||||
|
|
|
@ -1,39 +1,26 @@
|
||||||
import { Pipe, PipeTransform } from '@angular/core';
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
|
||||||
// https://medium.com/@thunderroid/angular-short-number-suffix-pipe-1k-2m-3b-dded4af82fb4
|
|
||||||
|
|
||||||
@Pipe({
|
@Pipe({
|
||||||
name: 'amountShortener'
|
name: 'amountShortener'
|
||||||
})
|
})
|
||||||
export class AmountShortenerPipe implements PipeTransform {
|
export class AmountShortenerPipe implements PipeTransform {
|
||||||
transform(number: number, args?: any): any {
|
transform(num: number, ...args: number[]): unknown {
|
||||||
if (isNaN(number)) return null; // will only work value is a number
|
if (num < 1000) {
|
||||||
if (number === null) return null;
|
return num;
|
||||||
if (number === 0) return null;
|
|
||||||
let abs = Math.abs(number);
|
|
||||||
const rounder = Math.pow(10, 1);
|
|
||||||
const isNegative = number < 0; // will also work for Negetive numbers
|
|
||||||
let key = '';
|
|
||||||
|
|
||||||
const powers = [
|
|
||||||
{ key: 'E', value: 10e18 },
|
|
||||||
{ key: 'P', value: 10e15 },
|
|
||||||
{ key: 'T', value: 10e12 },
|
|
||||||
{ key: 'B', value: 10e9 },
|
|
||||||
{ key: 'M', value: 10e6 },
|
|
||||||
{ key: 'K', value: 1000 }
|
|
||||||
];
|
|
||||||
|
|
||||||
for (let i = 0; i < powers.length; i++) {
|
|
||||||
let reduced = abs / powers[i].value;
|
|
||||||
reduced = Math.round(reduced * rounder) / rounder;
|
|
||||||
if (reduced >= 1) {
|
|
||||||
abs = reduced;
|
|
||||||
key = powers[i].key;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (isNegative ? '-' : '') + abs + key;
|
const digits = args[0] || 1;
|
||||||
|
const lookup = [
|
||||||
|
{ value: 1, symbol: '' },
|
||||||
|
{ value: 1e3, symbol: 'k' },
|
||||||
|
{ value: 1e6, symbol: 'M' },
|
||||||
|
{ value: 1e9, symbol: 'G' },
|
||||||
|
{ value: 1e12, symbol: 'T' },
|
||||||
|
{ value: 1e15, symbol: 'P' },
|
||||||
|
{ value: 1e18, symbol: 'E' }
|
||||||
|
];
|
||||||
|
const rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
|
||||||
|
var item = lookup.slice().reverse().find((item) => num >= item.value);
|
||||||
|
return item ? (num / item.value).toFixed(digits).replace(rx, '$1') + item.symbol : '0';
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue