Merge pull request #3406 from mempool/nymkappa/block-health-history-i18n

Rename block prediction to block health
This commit is contained in:
softsimon 2023-05-14 16:39:43 -05:00 committed by GitHub
commit 2156fb2a83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 45 additions and 79 deletions

View File

@ -26,7 +26,7 @@ class MiningRoutes {
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/fee-rates/:interval', this.$getHistoricalBlockFeeRates) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/fee-rates/:interval', this.$getHistoricalBlockFeeRates)
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/sizes-weights/:interval', this.$getHistoricalBlockSizeAndWeight) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/sizes-weights/:interval', this.$getHistoricalBlockSizeAndWeight)
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/difficulty-adjustments/:interval', this.$getDifficultyAdjustments) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/difficulty-adjustments/:interval', this.$getDifficultyAdjustments)
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/predictions/:interval', this.$getHistoricalBlockPrediction) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/predictions/:interval', this.$getHistoricalBlocksHealth)
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/audit/scores', this.$getBlockAuditScores) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/audit/scores', this.$getBlockAuditScores)
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/audit/scores/:height', this.$getBlockAuditScores) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/audit/scores/:height', this.$getBlockAuditScores)
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/audit/score/:hash', this.$getBlockAuditScore) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/audit/score/:hash', this.$getBlockAuditScore)
@ -244,15 +244,15 @@ class MiningRoutes {
} }
} }
private async $getHistoricalBlockPrediction(req: Request, res: Response) { private async $getHistoricalBlocksHealth(req: Request, res: Response) {
try { try {
const blockPredictions = await mining.$getBlockPredictionsHistory(req.params.interval); const blocksHealth = await mining.$getBlocksHealthHistory(req.params.interval);
const blockCount = await BlocksAuditsRepository.$getPredictionsCount(); const blockCount = await BlocksAuditsRepository.$getBlocksHealthCount();
res.header('Pragma', 'public'); res.header('Pragma', 'public');
res.header('Cache-control', 'public'); res.header('Cache-control', 'public');
res.header('X-total-count', blockCount.toString()); res.header('X-total-count', blockCount.toString());
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString()); res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
res.json(blockPredictions.map(prediction => [prediction.time, prediction.height, prediction.match_rate])); res.json(blocksHealth.map(health => [health.time, health.height, health.match_rate]));
} catch (e) { } catch (e) {
res.status(500).send(e instanceof Error ? e.message : e); res.status(500).send(e instanceof Error ? e.message : e);
} }

View File

@ -13,7 +13,6 @@ import BlocksAuditsRepository from '../../repositories/BlocksAuditsRepository';
import PricesRepository from '../../repositories/PricesRepository'; import PricesRepository from '../../repositories/PricesRepository';
import { bitcoinCoreApi } from '../bitcoin/bitcoin-api-factory'; import { bitcoinCoreApi } from '../bitcoin/bitcoin-api-factory';
import { IEsploraApi } from '../bitcoin/esplora-api.interface'; import { IEsploraApi } from '../bitcoin/esplora-api.interface';
import database from '../../database';
class Mining { class Mining {
private blocksPriceIndexingRunning = false; private blocksPriceIndexingRunning = false;
@ -21,10 +20,10 @@ class Mining {
public lastWeeklyHashrateIndexingDate: number | null = null; public lastWeeklyHashrateIndexingDate: number | null = null;
/** /**
* Get historical block predictions match rate * Get historical blocks health
*/ */
public async $getBlockPredictionsHistory(interval: string | null = null): Promise<any> { public async $getBlocksHealthHistory(interval: string | null = null): Promise<any> {
return await BlocksAuditsRepository.$getBlockPredictionsHistory( return await BlocksAuditsRepository.$getBlocksHealthHistory(
this.getTimeRange(interval), this.getTimeRange(interval),
Common.getSqlInterval(interval) Common.getSqlInterval(interval)
); );

View File

@ -19,7 +19,7 @@ class BlocksAuditRepositories {
} }
} }
public async $getBlockPredictionsHistory(div: number, interval: string | null): Promise<any> { public async $getBlocksHealthHistory(div: number, interval: string | null): Promise<any> {
try { try {
let query = `SELECT UNIX_TIMESTAMP(time) as time, height, match_rate FROM blocks_audits`; let query = `SELECT UNIX_TIMESTAMP(time) as time, height, match_rate FROM blocks_audits`;
@ -32,17 +32,17 @@ class BlocksAuditRepositories {
const [rows] = await DB.query(query); const [rows] = await DB.query(query);
return rows; return rows;
} catch (e: any) { } catch (e: any) {
logger.err(`Cannot fetch block prediction history. Reason: ` + (e instanceof Error ? e.message : e)); logger.err(`Cannot fetch blocks health history. Reason: ` + (e instanceof Error ? e.message : e));
throw e; throw e;
} }
} }
public async $getPredictionsCount(): Promise<number> { public async $getBlocksHealthCount(): Promise<number> {
try { try {
const [rows] = await DB.query(`SELECT count(hash) as count FROM blocks_audits`); const [rows] = await DB.query(`SELECT count(hash) as count FROM blocks_audits`);
return rows[0].count; return rows[0].count;
} catch (e: any) { } catch (e: any) {
logger.err(`Cannot fetch block prediction history. Reason: ` + (e instanceof Error ? e.message : e)); logger.err(`Cannot fetch blocks health count. Reason: ` + (e instanceof Error ? e.message : e));
throw e; throw e;
} }
} }

View File

@ -3,7 +3,7 @@
<div class="full-container"> <div class="full-container">
<div class="card-header mb-0 mb-md-4"> <div class="card-header mb-0 mb-md-4">
<div class="d-flex d-md-block align-items-baseline"> <div class="d-flex d-md-block align-items-baseline">
<span i18n="mining.block-prediction-accuracy">Block Prediction Accuracy</span> <span i18n="mining.blocks-health">Block Health</span>
<button class="btn p-0 pl-2" style="margin: 0 0 4px 0px" (click)="onSaveChart()"> <button class="btn p-0 pl-2" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon> <fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
</button> </button>
@ -12,34 +12,34 @@
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(statsObservable$ | async) as stats"> <form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(statsObservable$ | async) as stats">
<div class="btn-group btn-group-toggle" name="radioBasic" [class]="{'disabled': isLoading}"> <div class="btn-group btn-group-toggle" name="radioBasic" [class]="{'disabled': isLoading}">
<label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 144" [class.active]="radioGroupForm.get('dateSpan').value === '24h'"> <label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 144" [class.active]="radioGroupForm.get('dateSpan').value === '24h'">
<input type="radio" [value]="'24h'" fragment="24h" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]" formControlName="dateSpan"> 24h <input type="radio" [value]="'24h'" fragment="24h" [routerLink]="['/graphs/mining/block-health' | relativeUrl]" formControlName="dateSpan"> 24h
</label> </label>
<label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 432" [class.active]="radioGroupForm.get('dateSpan').value === '3d'"> <label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 432" [class.active]="radioGroupForm.get('dateSpan').value === '3d'">
<input type="radio" [value]="'3d'" fragment="3d" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]" formControlName="dateSpan"> 3D <input type="radio" [value]="'3d'" fragment="3d" [routerLink]="['/graphs/mining/block-health' | relativeUrl]" formControlName="dateSpan"> 3D
</label> </label>
<label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 1008" [class.active]="radioGroupForm.get('dateSpan').value === '1w'"> <label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 1008" [class.active]="radioGroupForm.get('dateSpan').value === '1w'">
<input type="radio" [value]="'1w'" fragment="1w" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]" formControlName="dateSpan"> 1W <input type="radio" [value]="'1w'" fragment="1w" [routerLink]="['/graphs/mining/block-health' | relativeUrl]" formControlName="dateSpan"> 1W
</label> </label>
<label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 4320" [class.active]="radioGroupForm.get('dateSpan').value === '1m'"> <label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 4320" [class.active]="radioGroupForm.get('dateSpan').value === '1m'">
<input type="radio" [value]="'1m'" fragment="1m" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]" formControlName="dateSpan"> 1M <input type="radio" [value]="'1m'" fragment="1m" [routerLink]="['/graphs/mining/block-health' | relativeUrl]" formControlName="dateSpan"> 1M
</label> </label>
<label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 12960" [class.active]="radioGroupForm.get('dateSpan').value === '3m'"> <label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 12960" [class.active]="radioGroupForm.get('dateSpan').value === '3m'">
<input type="radio" [value]="'3m'" fragment="3m" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]" formControlName="dateSpan"> 3M <input type="radio" [value]="'3m'" fragment="3m" [routerLink]="['/graphs/mining/block-health' | relativeUrl]" formControlName="dateSpan"> 3M
</label> </label>
<label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 25920" [class.active]="radioGroupForm.get('dateSpan').value === '6m'"> <label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 25920" [class.active]="radioGroupForm.get('dateSpan').value === '6m'">
<input type="radio" [value]="'6m'" fragment="6m" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]" formControlName="dateSpan"> 6M <input type="radio" [value]="'6m'" fragment="6m" [routerLink]="['/graphs/mining/block-health' | relativeUrl]" formControlName="dateSpan"> 6M
</label> </label>
<label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 52560" [class.active]="radioGroupForm.get('dateSpan').value === '1y'"> <label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 52560" [class.active]="radioGroupForm.get('dateSpan').value === '1y'">
<input type="radio" [value]="'1y'" fragment="1y" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]" formControlName="dateSpan"> 1Y <input type="radio" [value]="'1y'" fragment="1y" [routerLink]="['/graphs/mining/block-health' | relativeUrl]" formControlName="dateSpan"> 1Y
</label> </label>
<label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 105120" [class.active]="radioGroupForm.get('dateSpan').value === '2y'"> <label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 105120" [class.active]="radioGroupForm.get('dateSpan').value === '2y'">
<input type="radio" [value]="'2y'" fragment="2y" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]" formControlName="dateSpan"> 2Y <input type="radio" [value]="'2y'" fragment="2y" [routerLink]="['/graphs/mining/block-health' | relativeUrl]" formControlName="dateSpan"> 2Y
</label> </label>
<label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 157680" [class.active]="radioGroupForm.get('dateSpan').value === '3y'"> <label class="btn btn-primary btn-sm" *ngIf="stats.blockCount >= 157680" [class.active]="radioGroupForm.get('dateSpan').value === '3y'">
<input type="radio" [value]="'3y'" fragment="3y" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]" formControlName="dateSpan"> 3Y <input type="radio" [value]="'3y'" fragment="3y" [routerLink]="['/graphs/mining/block-health' | relativeUrl]" formControlName="dateSpan"> 3Y
</label> </label>
<label class="btn btn-primary btn-sm" *ngIf="stats.blockCount > 157680" [class.active]="radioGroupForm.get('dateSpan').value === 'all'"> <label class="btn btn-primary btn-sm" *ngIf="stats.blockCount > 157680" [class.active]="radioGroupForm.get('dateSpan').value === 'all'">
<input type="radio" [value]="'all'" fragment="all" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]" formControlName="dateSpan"> ALL <input type="radio" [value]="'all'" fragment="all" [routerLink]="['/graphs/mining/block-health' | relativeUrl]" formControlName="dateSpan"> ALL
</label> </label>
</div> </div>
</form> </form>

View File

@ -13,9 +13,9 @@ import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pi
import { StateService } from '../../services/state.service'; import { StateService } from '../../services/state.service';
@Component({ @Component({
selector: 'app-block-prediction-graph', selector: 'app-block-health-graph',
templateUrl: './block-prediction-graph.component.html', templateUrl: './block-health-graph.component.html',
styleUrls: ['./block-prediction-graph.component.scss'], styleUrls: ['./block-health-graph.component.scss'],
styles: [` styles: [`
.loadingGraphs { .loadingGraphs {
position: absolute; position: absolute;
@ -26,7 +26,7 @@ import { StateService } from '../../services/state.service';
`], `],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class BlockPredictionGraphComponent implements OnInit { export class BlockHealthGraphComponent implements OnInit {
@Input() right: number | string = 45; @Input() right: number | string = 45;
@Input() left: number | string = 75; @Input() left: number | string = 75;
@ -60,7 +60,7 @@ export class BlockPredictionGraphComponent implements OnInit {
} }
ngOnInit(): void { ngOnInit(): void {
this.seoService.setTitle($localize`:@@d7d5fcf50179ad70c938491c517efb82de2c8146:Block Prediction Accuracy`); this.seoService.setTitle($localize`:@@d7d5fcf50179ad70c938491c517efb82de2c8146:Block Health`);
this.miningWindowPreference = '24h';//this.miningService.getDefaultTimespan('24h'); this.miningWindowPreference = '24h';//this.miningService.getDefaultTimespan('24h');
this.radioGroupForm = this.formBuilder.group({ dateSpan: this.miningWindowPreference }); this.radioGroupForm = this.formBuilder.group({ dateSpan: this.miningWindowPreference });
this.radioGroupForm.controls.dateSpan.setValue(this.miningWindowPreference); this.radioGroupForm.controls.dateSpan.setValue(this.miningWindowPreference);
@ -80,7 +80,7 @@ export class BlockPredictionGraphComponent implements OnInit {
this.storageService.setValue('miningWindowPreference', timespan); this.storageService.setValue('miningWindowPreference', timespan);
this.timespan = timespan; this.timespan = timespan;
this.isLoading = true; this.isLoading = true;
return this.apiService.getHistoricalBlockPrediction$(timespan) return this.apiService.getHistoricalBlocksHealth$(timespan)
.pipe( .pipe(
tap((response) => { tap((response) => {
this.prepareChartOptions(response.body); this.prepareChartOptions(response.body);
@ -163,7 +163,7 @@ export class BlockPredictionGraphComponent implements OnInit {
hideOverlap: true, hideOverlap: true,
padding: [0, 5], padding: [0, 5],
}, },
data: data.map(prediction => prediction[0]) data: data.map(health => health[0])
}, },
yAxis: data.length === 0 ? undefined : [ yAxis: data.length === 0 ? undefined : [
{ {
@ -186,12 +186,12 @@ export class BlockPredictionGraphComponent implements OnInit {
series: data.length === 0 ? undefined : [ series: data.length === 0 ? undefined : [
{ {
zlevel: 0, zlevel: 0,
name: $localize`Match rate`, name: $localize`Health`,
data: data.map(prediction => ({ data: data.map(health => ({
value: prediction[2], value: health[2],
block: prediction[1], block: health[1],
itemStyle: { itemStyle: {
color: this.getPredictionColor(prediction[2]) color: this.getHealthColor(health[2])
} }
})), })),
type: 'bar', type: 'bar',
@ -257,7 +257,7 @@ export class BlockPredictionGraphComponent implements OnInit {
return 'rgb(' + gradient.red + ',' + gradient.green + ',' + gradient.blue + ')'; return 'rgb(' + gradient.red + ',' + gradient.green + ',' + gradient.blue + ')';
} }
getPredictionColor(matchRate) { getHealthColor(matchRate) {
return this.colorGradient( return this.colorGradient(
Math.pow((100 - matchRate) / 100, 0.5), Math.pow((100 - matchRate) / 100, 0.5),
{red: 67, green: 171, blue: 71}, {red: 67, green: 171, blue: 71},
@ -294,7 +294,7 @@ export class BlockPredictionGraphComponent implements OnInit {
download(this.chartInstance.getDataURL({ download(this.chartInstance.getDataURL({
pixelRatio: 2, pixelRatio: 2,
excludeComponents: ['dataZoom'], excludeComponents: ['dataZoom'],
}), `block-fees-${this.timespan}-${Math.round(now.getTime() / 1000)}.svg`); }), `block-health-${this.timespan}-${Math.round(now.getTime() / 1000)}.svg`);
// @ts-ignore // @ts-ignore
this.chartOptions.grid.bottom = prevBottom; this.chartOptions.grid.bottom = prevBottom;
this.chartOptions.backgroundColor = 'none'; this.chartOptions.backgroundColor = 'none';

View File

@ -22,7 +22,7 @@
<a class="dropdown-item" routerLinkActive="active" <a class="dropdown-item" routerLinkActive="active"
[routerLink]="['/graphs/mining/block-sizes-weights' | relativeUrl]" i18n="mining.block-sizes-weights">Block Sizes and Weights</a> [routerLink]="['/graphs/mining/block-sizes-weights' | relativeUrl]" i18n="mining.block-sizes-weights">Block Sizes and Weights</a>
<a *ngIf="stateService.env.AUDIT" class="dropdown-item" routerLinkActive="active" <a *ngIf="stateService.env.AUDIT" class="dropdown-item" routerLinkActive="active"
[routerLink]="['/graphs/mining/block-prediction' | relativeUrl]" i18n="mining.block-prediction-accuracy">Block Prediction Accuracy</a> [routerLink]="['/graphs/mining/block-health' | relativeUrl]" i18n="mining.block-health">Block Health</a>
</div> </div>
</div> </div>

View File

@ -21,7 +21,7 @@ import { DashboardComponent } from '../dashboard/dashboard.component';
import { MiningDashboardComponent } from '../components/mining-dashboard/mining-dashboard.component'; import { MiningDashboardComponent } from '../components/mining-dashboard/mining-dashboard.component';
import { HashrateChartComponent } from '../components/hashrate-chart/hashrate-chart.component'; import { HashrateChartComponent } from '../components/hashrate-chart/hashrate-chart.component';
import { HashrateChartPoolsComponent } from '../components/hashrates-chart-pools/hashrate-chart-pools.component'; import { HashrateChartPoolsComponent } from '../components/hashrates-chart-pools/hashrate-chart-pools.component';
import { BlockPredictionGraphComponent } from '../components/block-prediction-graph/block-prediction-graph.component'; import { BlockHealthGraphComponent } from '../components/block-health-graph/block-health-graph.component';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
@NgModule({ @NgModule({
@ -46,7 +46,7 @@ import { CommonModule } from '@angular/common';
LbtcPegsGraphComponent, LbtcPegsGraphComponent,
HashrateChartComponent, HashrateChartComponent,
HashrateChartPoolsComponent, HashrateChartPoolsComponent,
BlockPredictionGraphComponent, BlockHealthGraphComponent,
], ],
imports: [ imports: [
CommonModule, CommonModule,

View File

@ -1,6 +1,6 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { BlockPredictionGraphComponent } from '../components/block-prediction-graph/block-prediction-graph.component'; import { BlockHealthGraphComponent } from '../components/block-health-graph/block-health-graph.component';
import { BlockFeeRatesGraphComponent } from '../components/block-fee-rates-graph/block-fee-rates-graph.component'; import { BlockFeeRatesGraphComponent } from '../components/block-fee-rates-graph/block-fee-rates-graph.component';
import { BlockFeesGraphComponent } from '../components/block-fees-graph/block-fees-graph.component'; import { BlockFeesGraphComponent } from '../components/block-fees-graph/block-fees-graph.component';
import { BlockRewardsGraphComponent } from '../components/block-rewards-graph/block-rewards-graph.component'; import { BlockRewardsGraphComponent } from '../components/block-rewards-graph/block-rewards-graph.component';
@ -143,9 +143,9 @@ const routes: Routes = [
redirectTo: 'mempool', redirectTo: 'mempool',
}, },
{ {
path: 'mining/block-prediction', path: 'mining/block-health',
data: { networks: ['bitcoin'] }, data: { networks: ['bitcoin'] },
component: BlockPredictionGraphComponent, component: BlockHealthGraphComponent,
}, },
] ]
}, },

View File

@ -253,20 +253,4 @@ export class NodeFeeChartComponent implements OnInit {
isMobile() { isMobile() {
return (window.innerWidth <= 767.98); return (window.innerWidth <= 767.98);
} }
onSaveChart() {
// @ts-ignore
const prevBottom = this.chartOptions.grid.bottom;
// @ts-ignore
this.chartOptions.grid.bottom = 40;
this.chartOptions.backgroundColor = '#11131f';
this.chartInstance.setOption(this.chartOptions);
download(this.chartInstance.getDataURL({
pixelRatio: 2,
}), `node-fee-chart.svg`);
// @ts-ignore
this.chartOptions.grid.bottom = prevBottom;
this.chartOptions.backgroundColor = 'none';
this.chartInstance.setOption(this.chartOptions);
}
} }

View File

@ -252,21 +252,4 @@ export class NodeStatisticsChartComponent implements OnInit {
isMobile() { isMobile() {
return (window.innerWidth <= 767.98); 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,
}), `block-sizes-weights-${this.timespan}-${Math.round(now.getTime() / 1000)}.svg`);
// @ts-ignore
this.chartOptions.grid.bottom = prevBottom;
this.chartOptions.backgroundColor = 'none';
this.chartInstance.setOption(this.chartOptions);
}
} }

View File

@ -442,7 +442,7 @@ export class NodesNetworksChartComponent implements OnInit {
download(this.chartInstance.getDataURL({ download(this.chartInstance.getDataURL({
pixelRatio: 2, pixelRatio: 2,
excludeComponents: ['dataZoom'], excludeComponents: ['dataZoom'],
}), `block-sizes-weights-${this.timespan}-${Math.round(now.getTime() / 1000)}.svg`); }), `lightning-nodes-per-network-${Math.round(now.getTime() / 1000)}.svg`);
// @ts-ignore // @ts-ignore
this.chartOptions.grid.bottom = prevBottom; this.chartOptions.grid.bottom = prevBottom;
this.chartOptions.backgroundColor = 'none'; this.chartOptions.backgroundColor = 'none';

View File

@ -238,7 +238,7 @@ export class ApiService {
); );
} }
getHistoricalBlockPrediction$(interval: string | undefined) : Observable<any> { getHistoricalBlocksHealth$(interval: string | undefined) : Observable<any> {
return this.httpClient.get<any[]>( return this.httpClient.get<any[]>(
this.apiBaseUrl + this.apiBasePath + `/api/v1/mining/blocks/predictions` + this.apiBaseUrl + this.apiBasePath + `/api/v1/mining/blocks/predictions` +
(interval !== undefined ? `/${interval}` : ''), { observe: 'response' } (interval !== undefined ? `/${interval}` : ''), { observe: 'response' }