Merge pull request #1895 from mempool/nymkappa/feature/hashrate-moving-average
Add moving average to the hashrate & difficulty chart
This commit is contained in:
commit
93dab57959
@ -27,9 +27,6 @@
|
|||||||
|
|
||||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(hashrateObservable$ | async) as stats">
|
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(hashrateObservable$ | async) as stats">
|
||||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 4320">
|
|
||||||
<input ngbButton type="radio" [value]="'1m'" fragment="1m" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]"> 1M
|
|
||||||
</label>
|
|
||||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 12960">
|
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 12960">
|
||||||
<input ngbButton type="radio" [value]="'3m'" fragment="3m" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]"> 3M
|
<input ngbButton type="radio" [value]="'3m'" fragment="3m" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]"> 3M
|
||||||
</label>
|
</label>
|
||||||
|
@ -47,6 +47,7 @@ export class HashrateChartComponent implements OnInit {
|
|||||||
formatNumber = formatNumber;
|
formatNumber = formatNumber;
|
||||||
timespan = '';
|
timespan = '';
|
||||||
chartInstance: any = undefined;
|
chartInstance: any = undefined;
|
||||||
|
maResolution: number = 30;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(LOCALE_ID) public locale: string,
|
@Inject(LOCALE_ID) public locale: string,
|
||||||
@ -122,9 +123,24 @@ export class HashrateChartComponent implements OnInit {
|
|||||||
++diffIndex;
|
++diffIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.maResolution = 30;
|
||||||
|
if (["3m", "6m"].includes(this.timespan)) {
|
||||||
|
this.maResolution = 7;
|
||||||
|
}
|
||||||
|
const hashrateMa = [];
|
||||||
|
for (let i = this.maResolution - 1; i < data.hashrates.length; ++i) {
|
||||||
|
let avg = 0;
|
||||||
|
for (let y = this.maResolution - 1; y >= 0; --y) {
|
||||||
|
avg += data.hashrates[i - y].avgHashrate;
|
||||||
|
}
|
||||||
|
avg /= this.maResolution;
|
||||||
|
hashrateMa.push([data.hashrates[i].timestamp * 1000, avg]);
|
||||||
|
}
|
||||||
|
|
||||||
this.prepareChartOptions({
|
this.prepareChartOptions({
|
||||||
hashrates: data.hashrates.map(val => [val.timestamp * 1000, val.avgHashrate]),
|
hashrates: data.hashrates.map(val => [val.timestamp * 1000, val.avgHashrate]),
|
||||||
difficulty: diffFixed.map(val => [val.timestamp * 1000, val.difficulty]),
|
difficulty: diffFixed.map(val => [val.timestamp * 1000, val.difficulty]),
|
||||||
|
hashrateMa: hashrateMa,
|
||||||
});
|
});
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
}),
|
}),
|
||||||
@ -160,6 +176,14 @@ export class HashrateChartComponent implements OnInit {
|
|||||||
title: title,
|
title: title,
|
||||||
animation: false,
|
animation: false,
|
||||||
color: [
|
color: [
|
||||||
|
new graphic.LinearGradient(0, 0, 0, 0.65, [
|
||||||
|
{ offset: 0, color: '#F4511E99' },
|
||||||
|
{ offset: 0.25, color: '#FB8C0099' },
|
||||||
|
{ offset: 0.5, color: '#FFB30099' },
|
||||||
|
{ offset: 0.75, color: '#FDD83599' },
|
||||||
|
{ offset: 1, color: '#7CB34299' }
|
||||||
|
]),
|
||||||
|
'#D81B60',
|
||||||
new graphic.LinearGradient(0, 0, 0, 0.65, [
|
new graphic.LinearGradient(0, 0, 0, 0.65, [
|
||||||
{ offset: 0, color: '#F4511E' },
|
{ offset: 0, color: '#F4511E' },
|
||||||
{ offset: 0.25, color: '#FB8C00' },
|
{ offset: 0.25, color: '#FB8C00' },
|
||||||
@ -167,10 +191,9 @@ export class HashrateChartComponent implements OnInit {
|
|||||||
{ offset: 0.75, color: '#FDD835' },
|
{ offset: 0.75, color: '#FDD835' },
|
||||||
{ offset: 1, color: '#7CB342' }
|
{ offset: 1, color: '#7CB342' }
|
||||||
]),
|
]),
|
||||||
'#D81B60',
|
|
||||||
],
|
],
|
||||||
grid: {
|
grid: {
|
||||||
top: 20,
|
top: this.widget ? 20 : 40,
|
||||||
bottom: this.widget ? 30 : 70,
|
bottom: this.widget ? 30 : 70,
|
||||||
right: this.right,
|
right: this.right,
|
||||||
left: this.left,
|
left: this.left,
|
||||||
@ -192,6 +215,7 @@ export class HashrateChartComponent implements OnInit {
|
|||||||
formatter: (ticks) => {
|
formatter: (ticks) => {
|
||||||
let hashrateString = '';
|
let hashrateString = '';
|
||||||
let difficultyString = '';
|
let difficultyString = '';
|
||||||
|
let hashrateStringMA = '';
|
||||||
let hashratePowerOfTen: any = selectPowerOfTen(1);
|
let hashratePowerOfTen: any = selectPowerOfTen(1);
|
||||||
|
|
||||||
for (const tick of ticks) {
|
for (const tick of ticks) {
|
||||||
@ -201,7 +225,7 @@ export class HashrateChartComponent implements OnInit {
|
|||||||
hashratePowerOfTen = selectPowerOfTen(tick.data[1]);
|
hashratePowerOfTen = selectPowerOfTen(tick.data[1]);
|
||||||
hashrate = Math.round(tick.data[1] / hashratePowerOfTen.divider);
|
hashrate = Math.round(tick.data[1] / hashratePowerOfTen.divider);
|
||||||
}
|
}
|
||||||
hashrateString = `${tick.marker} ${tick.seriesName}: ${formatNumber(hashrate, this.locale, '1.0-0')} ${hashratePowerOfTen.unit}H/s`;
|
hashrateString = `${tick.marker} ${tick.seriesName}: ${formatNumber(hashrate, this.locale, '1.0-0')} ${hashratePowerOfTen.unit}H/s<br>`;
|
||||||
} else if (tick.seriesIndex === 1) { // Difficulty
|
} else if (tick.seriesIndex === 1) { // Difficulty
|
||||||
let difficultyPowerOfTen = hashratePowerOfTen;
|
let difficultyPowerOfTen = hashratePowerOfTen;
|
||||||
let difficulty = tick.data[1];
|
let difficulty = tick.data[1];
|
||||||
@ -209,7 +233,14 @@ export class HashrateChartComponent implements OnInit {
|
|||||||
difficultyPowerOfTen = selectPowerOfTen(tick.data[1]);
|
difficultyPowerOfTen = selectPowerOfTen(tick.data[1]);
|
||||||
difficulty = Math.round(tick.data[1] / difficultyPowerOfTen.divider);
|
difficulty = Math.round(tick.data[1] / difficultyPowerOfTen.divider);
|
||||||
}
|
}
|
||||||
difficultyString = `${tick.marker} ${tick.seriesName}: ${formatNumber(difficulty, this.locale, '1.2-2')} ${difficultyPowerOfTen.unit}`;
|
difficultyString = `${tick.marker} ${tick.seriesName}: ${formatNumber(difficulty, this.locale, '1.2-2')} ${difficultyPowerOfTen.unit}<br>`;
|
||||||
|
} else if (tick.seriesIndex === 2) { // Hashrate MA
|
||||||
|
let hashrate = tick.data[1];
|
||||||
|
if (this.isMobile()) {
|
||||||
|
hashratePowerOfTen = selectPowerOfTen(tick.data[1]);
|
||||||
|
hashrate = Math.round(tick.data[1] / hashratePowerOfTen.divider);
|
||||||
|
}
|
||||||
|
hashrateStringMA = `${tick.marker} ${tick.seriesName}: ${formatNumber(hashrate, this.locale, '1.0-0')} ${hashratePowerOfTen.unit}H/s`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,8 +248,9 @@ export class HashrateChartComponent implements OnInit {
|
|||||||
|
|
||||||
return `
|
return `
|
||||||
<b style="color: white; margin-left: 2px">${date}</b><br>
|
<b style="color: white; margin-left: 2px">${date}</b><br>
|
||||||
<span>${hashrateString}</span><br>
|
|
||||||
<span>${difficultyString}</span>
|
<span>${difficultyString}</span>
|
||||||
|
<span>${hashrateString}</span>
|
||||||
|
<span>${hashrateStringMA}</span>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -243,15 +275,23 @@ export class HashrateChartComponent implements OnInit {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: $localize`:@@25148835d92465353fc5fe8897c27d5369978e5a:Difficulty`,
|
name: $localize`::Difficulty`,
|
||||||
|
inactiveColor: 'rgb(110, 112, 121)',
|
||||||
|
textStyle: {
|
||||||
|
color: 'white',
|
||||||
|
},
|
||||||
|
icon: 'roundRect',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: $localize`Hashrate` + ` (MA${this.maResolution})`,
|
||||||
inactiveColor: 'rgb(110, 112, 121)',
|
inactiveColor: 'rgb(110, 112, 121)',
|
||||||
textStyle: {
|
textStyle: {
|
||||||
color: 'white',
|
color: 'white',
|
||||||
},
|
},
|
||||||
icon: 'roundRect',
|
icon: 'roundRect',
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
color: '#D81B60',
|
color: '#FFB300',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -270,8 +310,12 @@ export class HashrateChartComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
splitLine: {
|
splitLine: {
|
||||||
show: false,
|
lineStyle: {
|
||||||
}
|
type: 'dotted',
|
||||||
|
color: '#ffffff66',
|
||||||
|
opacity: 0.25,
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
min: (value) => {
|
min: (value) => {
|
||||||
@ -288,12 +332,8 @@ export class HashrateChartComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
splitLine: {
|
splitLine: {
|
||||||
lineStyle: {
|
show: false,
|
||||||
type: 'dotted',
|
}
|
||||||
color: '#ffffff66',
|
|
||||||
opacity: 0.25,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
series: data.hashrates.length === 0 ? [] : [
|
series: data.hashrates.length === 0 ? [] : [
|
||||||
@ -305,7 +345,7 @@ export class HashrateChartComponent implements OnInit {
|
|||||||
data: data.hashrates,
|
data: data.hashrates,
|
||||||
type: 'line',
|
type: 'line',
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
width: 2,
|
width: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -319,6 +359,18 @@ export class HashrateChartComponent implements OnInit {
|
|||||||
lineStyle: {
|
lineStyle: {
|
||||||
width: 3,
|
width: 3,
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
zlevel: 2,
|
||||||
|
name: $localize`Hashrate` + ` (MA${this.maResolution})`,
|
||||||
|
showSymbol: false,
|
||||||
|
symbol: 'none',
|
||||||
|
data: data.hashrateMa,
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
lineStyle: {
|
||||||
|
width: 3,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
dataZoom: this.widget ? null : [{
|
dataZoom: this.widget ? null : [{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user