Merge branch 'master' into docker_vars_test
This commit is contained in:
		
						commit
						50a865e54e
					
				| @ -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); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -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) | ||||||
|     ); |     ); | ||||||
|  | |||||||
| @ -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; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -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> | ||||||
| @ -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'; | ||||||
| @ -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> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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, | ||||||
|  | |||||||
| @ -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, | ||||||
|           }, |           }, | ||||||
|         ] |         ] | ||||||
|       }, |       }, | ||||||
|  | |||||||
| @ -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); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -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); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -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'; | ||||||
|  | |||||||
| @ -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' } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user