Merge branch 'master' into mobile-refinements
This commit is contained in:
		
						commit
						d769226061
					
				
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -31,6 +31,7 @@ import { MiningDashboardComponent } from './components/mining-dashboard/mining-d
 | 
				
			|||||||
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 { MiningStartComponent } from './components/mining-start/mining-start.component';
 | 
					import { MiningStartComponent } from './components/mining-start/mining-start.component';
 | 
				
			||||||
 | 
					import { GraphsComponent } from './components/graphs/graphs.component';
 | 
				
			||||||
import { BlocksList } from './components/blocks-list/blocks-list.component';
 | 
					import { BlocksList } from './components/blocks-list/blocks-list.component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let routes: Routes = [
 | 
					let routes: Routes = [
 | 
				
			||||||
@ -80,18 +81,6 @@ let routes: Routes = [
 | 
				
			|||||||
            path: 'blocks',
 | 
					            path: 'blocks',
 | 
				
			||||||
            component: BlocksList,
 | 
					            component: BlocksList,
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            path: 'hashrate',
 | 
					 | 
				
			||||||
            component: HashrateChartComponent,
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            path: 'hashrate/pools',
 | 
					 | 
				
			||||||
            component: HashrateChartPoolsComponent,
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            path: 'pools',
 | 
					 | 
				
			||||||
            component: PoolRankingComponent,
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
            path: 'pool',
 | 
					            path: 'pool',
 | 
				
			||||||
            children: [
 | 
					            children: [
 | 
				
			||||||
@ -105,7 +94,30 @@ let routes: Routes = [
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        path: 'graphs',
 | 
					        path: 'graphs',
 | 
				
			||||||
        component: StatisticsComponent,
 | 
					        component: GraphsComponent,
 | 
				
			||||||
 | 
					        children: [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            path: '',
 | 
				
			||||||
 | 
					            pathMatch: 'full',
 | 
				
			||||||
 | 
					            redirectTo: 'mempool',
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            path: 'mempool',
 | 
				
			||||||
 | 
					            component: StatisticsComponent,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            path: 'mining/hashrate-difficulty',
 | 
				
			||||||
 | 
					            component: HashrateChartComponent,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            path: 'mining/pools-dominance',
 | 
				
			||||||
 | 
					            component: HashrateChartPoolsComponent,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            path: 'mining/pools',
 | 
				
			||||||
 | 
					            component: PoolRankingComponent,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        path: 'about',
 | 
					        path: 'about',
 | 
				
			||||||
@ -224,7 +236,30 @@ let routes: Routes = [
 | 
				
			|||||||
          },
 | 
					          },
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
            path: 'graphs',
 | 
					            path: 'graphs',
 | 
				
			||||||
            component: StatisticsComponent,
 | 
					            component: GraphsComponent,
 | 
				
			||||||
 | 
					            children: [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                path: '',
 | 
				
			||||||
 | 
					                pathMatch: 'full',
 | 
				
			||||||
 | 
					                redirectTo: 'mempool',
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                path: 'mempool',
 | 
				
			||||||
 | 
					                component: StatisticsComponent,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                path: 'mining/hashrate-difficulty',
 | 
				
			||||||
 | 
					                component: HashrateChartComponent,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                path: 'mining/pools-dominance',
 | 
				
			||||||
 | 
					                component: HashrateChartPoolsComponent,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                path: 'mining/pools',
 | 
				
			||||||
 | 
					                component: PoolRankingComponent,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
            path: 'address/:id',
 | 
					            path: 'address/:id',
 | 
				
			||||||
@ -337,7 +372,30 @@ let routes: Routes = [
 | 
				
			|||||||
          },
 | 
					          },
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
            path: 'graphs',
 | 
					            path: 'graphs',
 | 
				
			||||||
            component: StatisticsComponent,
 | 
					            component: GraphsComponent,
 | 
				
			||||||
 | 
					            children: [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                path: '',
 | 
				
			||||||
 | 
					                pathMatch: 'full',
 | 
				
			||||||
 | 
					                redirectTo: 'mempool',
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                path: 'mempool',
 | 
				
			||||||
 | 
					                component: StatisticsComponent,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                path: 'mining/hashrate-difficulty',
 | 
				
			||||||
 | 
					                component: HashrateChartComponent,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                path: 'mining/pools-dominance',
 | 
				
			||||||
 | 
					                component: HashrateChartPoolsComponent,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                path: 'mining/pools',
 | 
				
			||||||
 | 
					                component: PoolRankingComponent,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
            path: 'address/:id',
 | 
					            path: 'address/:id',
 | 
				
			||||||
@ -439,7 +497,30 @@ if (browserWindowEnv && browserWindowEnv.BASE_MODULE === 'liquid') {
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        path: 'graphs',
 | 
					        path: 'graphs',
 | 
				
			||||||
        component: StatisticsComponent,
 | 
					        component: GraphsComponent,
 | 
				
			||||||
 | 
					        children: [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            path: '',
 | 
				
			||||||
 | 
					            pathMatch: 'full',
 | 
				
			||||||
 | 
					            redirectTo: 'mempool',
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            path: 'mempool',
 | 
				
			||||||
 | 
					            component: StatisticsComponent,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            path: 'mining/hashrate-difficulty',
 | 
				
			||||||
 | 
					            component: HashrateChartComponent,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            path: 'mining/pools-dominance',
 | 
				
			||||||
 | 
					            component: HashrateChartPoolsComponent,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            path: 'mining/pools',
 | 
				
			||||||
 | 
					            component: PoolRankingComponent,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        path: 'address/:id',
 | 
					        path: 'address/:id',
 | 
				
			||||||
@ -548,7 +629,30 @@ if (browserWindowEnv && browserWindowEnv.BASE_MODULE === 'liquid') {
 | 
				
			|||||||
          },
 | 
					          },
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
            path: 'graphs',
 | 
					            path: 'graphs',
 | 
				
			||||||
            component: StatisticsComponent,
 | 
					            component: GraphsComponent,
 | 
				
			||||||
 | 
					            children: [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                path: '',
 | 
				
			||||||
 | 
					                pathMatch: 'full',
 | 
				
			||||||
 | 
					                redirectTo: 'mempool',
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                path: 'mempool',
 | 
				
			||||||
 | 
					                component: StatisticsComponent,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                path: 'mining/hashrate-difficulty',
 | 
				
			||||||
 | 
					                component: HashrateChartComponent,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                path: 'mining/pools-dominance',
 | 
				
			||||||
 | 
					                component: HashrateChartPoolsComponent,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                path: 'mining/pools',
 | 
				
			||||||
 | 
					                component: PoolRankingComponent,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
            path: 'address/:id',
 | 
					            path: 'address/:id',
 | 
				
			||||||
 | 
				
			|||||||
@ -75,6 +75,7 @@ import { HashrateChartPoolsComponent } from './components/hashrates-chart-pools/
 | 
				
			|||||||
import { MiningStartComponent } from './components/mining-start/mining-start.component';
 | 
					import { MiningStartComponent } from './components/mining-start/mining-start.component';
 | 
				
			||||||
import { AmountShortenerPipe } from './shared/pipes/amount-shortener.pipe';
 | 
					import { AmountShortenerPipe } from './shared/pipes/amount-shortener.pipe';
 | 
				
			||||||
import { ShortenStringPipe } from './shared/pipes/shorten-string-pipe/shorten-string.pipe';
 | 
					import { ShortenStringPipe } from './shared/pipes/shorten-string-pipe/shorten-string.pipe';
 | 
				
			||||||
 | 
					import { GraphsComponent } from './components/graphs/graphs.component';
 | 
				
			||||||
import { DifficultyAdjustmentsTable } from './components/difficulty-adjustments-table/difficulty-adjustments-table.components';
 | 
					import { DifficultyAdjustmentsTable } from './components/difficulty-adjustments-table/difficulty-adjustments-table.components';
 | 
				
			||||||
import { BlocksList } from './components/blocks-list/blocks-list.component';
 | 
					import { BlocksList } from './components/blocks-list/blocks-list.component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -133,6 +134,7 @@ import { BlocksList } from './components/blocks-list/blocks-list.component';
 | 
				
			|||||||
    HashrateChartPoolsComponent,
 | 
					    HashrateChartPoolsComponent,
 | 
				
			||||||
    MiningStartComponent,
 | 
					    MiningStartComponent,
 | 
				
			||||||
    AmountShortenerPipe,
 | 
					    AmountShortenerPipe,
 | 
				
			||||||
 | 
					    GraphsComponent,
 | 
				
			||||||
    DifficultyAdjustmentsTable,
 | 
					    DifficultyAdjustmentsTable,
 | 
				
			||||||
    BlocksList,
 | 
					    BlocksList,
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
 | 
				
			|||||||
@ -12,7 +12,7 @@
 | 
				
			|||||||
      <ng-template ngbNavContent>
 | 
					      <ng-template ngbNavContent>
 | 
				
			||||||
        <div class="subtitle"><ng-container i18n="API Docs code example">Code Example</ng-container> <app-clipboard [text]="wrapCommonJS(code)"></app-clipboard></div>
 | 
					        <div class="subtitle"><ng-container i18n="API Docs code example">Code Example</ng-container> <app-clipboard [text]="wrapCommonJS(code)"></app-clipboard></div>
 | 
				
			||||||
        <div class="links">
 | 
					        <div class="links">
 | 
				
			||||||
          <a [href]="npmGithubLink()" target="_blank">github repository</a>
 | 
					          <a [href]="npmGithubLink()" target="_blank">GitHub Repo</a>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <pre><code [innerText]="wrapCommonJS(code)"></code></pre>
 | 
					        <pre><code [innerText]="wrapCommonJS(code)"></code></pre>
 | 
				
			||||||
      </ng-template>
 | 
					      </ng-template>
 | 
				
			||||||
@ -22,8 +22,8 @@
 | 
				
			|||||||
      <ng-template ngbNavContent>
 | 
					      <ng-template ngbNavContent>
 | 
				
			||||||
        <div class="subtitle"><ng-container i18n="API Docs install lib">Install Package</ng-container> <app-clipboard [text]="wrapImportTemplate()"></app-clipboard></div>
 | 
					        <div class="subtitle"><ng-container i18n="API Docs install lib">Install Package</ng-container> <app-clipboard [text]="wrapImportTemplate()"></app-clipboard></div>
 | 
				
			||||||
        <div class="links">
 | 
					        <div class="links">
 | 
				
			||||||
          <a [href]="npmGithubLink()" target="_blank">github repository</a>
 | 
					          <a [href]="npmGithubLink()" target="_blank">GitHub Repo</a>
 | 
				
			||||||
          <a [href]="npmModuleLink()" target="_blank">npm package</a>
 | 
					          <a [href]="npmModuleLink()" target="_blank">NPM Package</a>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <pre><code [innerText]="wrapImportTemplate()"></code></pre>
 | 
					        <pre><code [innerText]="wrapImportTemplate()"></code></pre>
 | 
				
			||||||
        <div class="subtitle"><ng-container i18n="API Docs code example">Code Example</ng-container> <app-clipboard [text]="wrapEsModule(code)"></app-clipboard></div>
 | 
					        <div class="subtitle"><ng-container i18n="API Docs code example">Code Example</ng-container> <app-clipboard [text]="wrapEsModule(code)"></app-clipboard></div>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										25
									
								
								frontend/src/app/components/graphs/graphs.component.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								frontend/src/app/components/graphs/graphs.component.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					<ul ngbNav #nav="ngbNav" class="nav-pills mb-3" style="padding: 0px 35px">
 | 
				
			||||||
 | 
					  <div class="d-inline-flex flex-wrap menu">
 | 
				
			||||||
 | 
					    <li ngbNavItem class="menu-li">
 | 
				
			||||||
 | 
					      <a routerLinkActive="active" [routerLink]="['/graphs/mempool' | relativeUrl]" ngbNavLink>Mempool</a>
 | 
				
			||||||
 | 
					    </li>
 | 
				
			||||||
 | 
					    <li ngbNavItem class="menu-li">
 | 
				
			||||||
 | 
					      <a routerLinkActive="active" [routerLink]="['/graphs/mining/pools' | relativeUrl]" ngbNavLink i18n="mining.pools">
 | 
				
			||||||
 | 
					        Pools ranking
 | 
				
			||||||
 | 
					      </a>
 | 
				
			||||||
 | 
					    </li>
 | 
				
			||||||
 | 
					    <li ngbNavItem class="menu-li">
 | 
				
			||||||
 | 
					      <a routerLinkActive="active" [routerLink]="['/graphs/mining/pools-dominance' | relativeUrl]" ngbNavLink i18n="mining.pools-dominance">
 | 
				
			||||||
 | 
					        Pools dominance
 | 
				
			||||||
 | 
					      </a>
 | 
				
			||||||
 | 
					    </li>
 | 
				
			||||||
 | 
					    <li ngbNavItem class="menu-li">
 | 
				
			||||||
 | 
					      <a routerLinkActive="active" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" ngbNavLink
 | 
				
			||||||
 | 
					        i18n="mining.hashrate-difficulty">
 | 
				
			||||||
 | 
					        Hashrate & Difficulty
 | 
				
			||||||
 | 
					      </a>
 | 
				
			||||||
 | 
					    </li>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</ul>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<router-outlet></router-outlet>
 | 
				
			||||||
							
								
								
									
										9
									
								
								frontend/src/app/components/graphs/graphs.component.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								frontend/src/app/components/graphs/graphs.component.scss
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					.menu {
 | 
				
			||||||
 | 
					  flex-grow: 1;
 | 
				
			||||||
 | 
					  max-width: 600px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.menu-li {
 | 
				
			||||||
 | 
					  flex-grow: 1;
 | 
				
			||||||
 | 
					  text-align: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								frontend/src/app/components/graphs/graphs.component.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								frontend/src/app/components/graphs/graphs.component.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					import { Component, OnInit } from "@angular/core";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					  selector: 'app-graphs',
 | 
				
			||||||
 | 
					  templateUrl: './graphs.component.html',
 | 
				
			||||||
 | 
					  styleUrls: ['./graphs.component.scss'],
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class GraphsComponent implements OnInit {
 | 
				
			||||||
 | 
					  constructor() { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ngOnInit(): void {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,6 +1,25 @@
 | 
				
			|||||||
<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/sec</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' : ''">
 | 
				
			||||||
 | 
					    <span i18n="mining.mining-pool-share">Hashrate & Difficulty</span>
 | 
				
			||||||
    <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">
 | 
				
			||||||
        <label ngbButtonLabel class="btn-primary btn-sm" *ngIf="hashrates.availableTimespanDay >= 90">
 | 
					        <label ngbButtonLabel class="btn-primary btn-sm" *ngIf="hashrates.availableTimespanDay >= 90">
 | 
				
			||||||
@ -32,3 +51,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>
 | 
				
			||||||
@ -1,3 +1,11 @@
 | 
				
			|||||||
 | 
					.card-header {
 | 
				
			||||||
 | 
					  border-bottom: 0;
 | 
				
			||||||
 | 
					  font-size: 18px;
 | 
				
			||||||
 | 
					  @media (min-width: 465px) {
 | 
				
			||||||
 | 
					    font-size: 20px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.main-title {
 | 
					.main-title {
 | 
				
			||||||
  position: relative;
 | 
					  position: relative;
 | 
				
			||||||
  color: #ffffff91;
 | 
					  color: #ffffff91;
 | 
				
			||||||
@ -10,13 +18,14 @@
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.full-container {
 | 
					.full-container {
 | 
				
			||||||
 | 
					  padding: 0px 15px;
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
  height: calc(100% - 100px);
 | 
					  height: calc(100% - 170px);
 | 
				
			||||||
  @media (max-width: 992px) {
 | 
					  @media (max-width: 992px) {
 | 
				
			||||||
    height: calc(100% - 140px);
 | 
					    height: calc(100% - 220px);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  @media (max-width: 576px) {
 | 
					  @media (max-width: 575px) {
 | 
				
			||||||
    height: calc(100% - 180px);
 | 
					    height: calc(100% - 260px);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -24,18 +33,41 @@
 | 
				
			|||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
  height: 100%;
 | 
					  height: 100%;
 | 
				
			||||||
  padding-bottom: 20px;
 | 
					  padding-bottom: 20px;
 | 
				
			||||||
  padding-right: 20px;
 | 
					  padding-right: 10px;
 | 
				
			||||||
 | 
					  @media (max-width: 992px) {
 | 
				
			||||||
 | 
					    padding-bottom: 25px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  @media (max-width: 829px) {
 | 
				
			||||||
 | 
					    padding-bottom: 50px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  @media (max-width: 767px) {
 | 
				
			||||||
 | 
					    padding-bottom: 25px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  @media (max-width: 629px) {
 | 
				
			||||||
 | 
					    padding-bottom: 55px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  @media (max-width: 567px) {
 | 
				
			||||||
 | 
					    padding-bottom: 55px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.chart-widget {
 | 
					.chart-widget {
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
  height: 100%;
 | 
					  height: 100%;
 | 
				
			||||||
  max-height: 293px;
 | 
					  max-height: 270px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.formRadioGroup {
 | 
					.formRadioGroup {
 | 
				
			||||||
  margin-top: 6px;
 | 
					  margin-top: 6px;
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  flex-direction: column;
 | 
					  flex-direction: column;
 | 
				
			||||||
 | 
					  @media (min-width: 1130px) {
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    top: -65px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  @media (min-width: 830px) and (max-width: 1130px) {
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    top: 0px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  @media (min-width: 830px) {
 | 
					  @media (min-width: 830px) {
 | 
				
			||||||
    flex-direction: row;
 | 
					    flex-direction: row;
 | 
				
			||||||
    float: right;
 | 
					    float: right;
 | 
				
			||||||
@ -48,3 +80,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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -61,6 +61,7 @@ export class HashrateChartComponent implements OnInit {
 | 
				
			|||||||
      .pipe(
 | 
					      .pipe(
 | 
				
			||||||
        startWith('1y'),
 | 
					        startWith('1y'),
 | 
				
			||||||
        switchMap((timespan) => {
 | 
					        switchMap((timespan) => {
 | 
				
			||||||
 | 
					          this.isLoading = true;
 | 
				
			||||||
          return this.apiService.getHistoricalHashrate$(timespan)
 | 
					          return this.apiService.getHistoricalHashrate$(timespan)
 | 
				
			||||||
            .pipe(
 | 
					            .pipe(
 | 
				
			||||||
              tap((data: any) => {
 | 
					              tap((data: any) => {
 | 
				
			||||||
@ -109,21 +110,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(
 | 
				
			||||||
@ -155,6 +145,7 @@ export class HashrateChartComponent implements OnInit {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    this.chartOptions = {
 | 
					    this.chartOptions = {
 | 
				
			||||||
      title: title,
 | 
					      title: title,
 | 
				
			||||||
 | 
					      animation: false,
 | 
				
			||||||
      color: [
 | 
					      color: [
 | 
				
			||||||
        new graphic.LinearGradient(0, 0, 0, 0.65, [
 | 
					        new graphic.LinearGradient(0, 0, 0, 0.65, [
 | 
				
			||||||
          { offset: 0, color: '#F4511E' },
 | 
					          { offset: 0, color: '#F4511E' },
 | 
				
			||||||
@ -166,9 +157,10 @@ 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 : this.isMobile() ? 90 : 60,
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      tooltip: {
 | 
					      tooltip: {
 | 
				
			||||||
        show: !this.isMobile() || !this.widget,
 | 
					        show: !this.isMobile() || !this.widget,
 | 
				
			||||||
@ -209,7 +201,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 +233,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 +250,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)',
 | 
				
			||||||
@ -301,17 +291,18 @@ export class HashrateChartComponent implements OnInit {
 | 
				
			|||||||
        type: 'inside',
 | 
					        type: 'inside',
 | 
				
			||||||
        realtime: true,
 | 
					        realtime: true,
 | 
				
			||||||
        zoomLock: true,
 | 
					        zoomLock: true,
 | 
				
			||||||
        zoomOnMouseWheel: true,
 | 
					 | 
				
			||||||
        moveOnMouseMove: true,
 | 
					 | 
				
			||||||
        maxSpan: 100,
 | 
					        maxSpan: 100,
 | 
				
			||||||
        minSpan: 10,
 | 
					        minSpan: 10,
 | 
				
			||||||
 | 
					        moveOnMouseMove: false,
 | 
				
			||||||
      }, {
 | 
					      }, {
 | 
				
			||||||
        showDetail: false,
 | 
					        showDetail: false,
 | 
				
			||||||
        show: true,
 | 
					        show: true,
 | 
				
			||||||
        type: 'slider',
 | 
					        type: 'slider',
 | 
				
			||||||
        brushSelect: false,
 | 
					        brushSelect: false,
 | 
				
			||||||
        realtime: true,
 | 
					        realtime: true,
 | 
				
			||||||
        bottom: 0,
 | 
					        bottom: this.isMobile() ? 30 : 0,
 | 
				
			||||||
 | 
					        left: 20,
 | 
				
			||||||
 | 
					        right: 15,
 | 
				
			||||||
        selectedDataBackground: {
 | 
					        selectedDataBackground: {
 | 
				
			||||||
          lineStyle: {
 | 
					          lineStyle: {
 | 
				
			||||||
            color: '#fff',
 | 
					            color: '#fff',
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
<div [class]="widget === false ? 'full-container' : ''">
 | 
					<div [class]="widget === false ? 'full-container' : ''">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <div class="card-header mb-0 mb-md-4" [style]="widget ? 'display:none' : ''">
 | 
					  <div class="card-header" [style]="widget ? 'display:none' : ''">
 | 
				
			||||||
 | 
					    <span *ngIf="!widget" i18n="mining.pools-dominance">Mining pools dominance</span>
 | 
				
			||||||
    <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">
 | 
				
			||||||
        <label ngbButtonLabel class="btn-primary btn-sm" *ngIf="hashrates.availableTimespanDay >= 90">
 | 
					        <label ngbButtonLabel class="btn-primary btn-sm" *ngIf="hashrates.availableTimespanDay >= 90">
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,11 @@
 | 
				
			|||||||
 | 
					.card-header {
 | 
				
			||||||
 | 
					  border-bottom: 0;
 | 
				
			||||||
 | 
					  font-size: 18px;
 | 
				
			||||||
 | 
					  @media (min-width: 465px) {
 | 
				
			||||||
 | 
					    font-size: 20px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.main-title {
 | 
					.main-title {
 | 
				
			||||||
  position: relative;
 | 
					  position: relative;
 | 
				
			||||||
  color: #ffffff91;
 | 
					  color: #ffffff91;
 | 
				
			||||||
@ -10,21 +18,37 @@
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.full-container {
 | 
					.full-container {
 | 
				
			||||||
 | 
					  padding: 0px 15px;
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
  height: calc(100% - 100px);
 | 
					  height: calc(100% - 140px);
 | 
				
			||||||
  @media (max-width: 992px) {
 | 
					  @media (max-width: 991px) {
 | 
				
			||||||
    height: calc(100% - 140px);
 | 
					    height: calc(100% - 190px);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  @media (max-width: 576px) {
 | 
					  @media (max-width: 575px) {
 | 
				
			||||||
    height: calc(100% - 180px);
 | 
					    height: calc(100% - 235px);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.chart {
 | 
					.chart {
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
  height: 100%;
 | 
					  height: 100%;
 | 
				
			||||||
  padding-bottom: 20px;
 | 
					  padding-bottom: 25px;
 | 
				
			||||||
  padding-right: 20px;
 | 
					  padding-right: 10px;
 | 
				
			||||||
 | 
					  @media (max-width: 992px) {
 | 
				
			||||||
 | 
					    padding-bottom: 25px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  @media (max-width: 829px) {
 | 
				
			||||||
 | 
					    padding-bottom: 50px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  @media (max-width: 767px) {
 | 
				
			||||||
 | 
					    padding-bottom: 50px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  @media (max-width: 629px) {
 | 
				
			||||||
 | 
					    padding-bottom: 85px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  @media (max-width: 567px) {
 | 
				
			||||||
 | 
					    padding-bottom: 85px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.chart-widget {
 | 
					.chart-widget {
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
@ -36,6 +60,14 @@
 | 
				
			|||||||
  margin-top: 6px;
 | 
					  margin-top: 6px;
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  flex-direction: column;
 | 
					  flex-direction: column;
 | 
				
			||||||
 | 
					  @media (min-width: 1130px) {
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    top: -65px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  @media (min-width: 830px) and (max-width: 1130px) {
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    top: 0px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  @media (min-width: 830px) {
 | 
					  @media (min-width: 830px) {
 | 
				
			||||||
    flex-direction: row;
 | 
					    flex-direction: row;
 | 
				
			||||||
    float: right;
 | 
					    float: right;
 | 
				
			||||||
 | 
				
			|||||||
@ -23,7 +23,7 @@ import { poolsColor } from 'src/app/app.constants';
 | 
				
			|||||||
})
 | 
					})
 | 
				
			||||||
export class HashrateChartPoolsComponent implements OnInit {
 | 
					export class HashrateChartPoolsComponent implements OnInit {
 | 
				
			||||||
  @Input() widget = false;
 | 
					  @Input() widget = false;
 | 
				
			||||||
  @Input() right: number | string = 40;
 | 
					  @Input() right: number | string = 45;
 | 
				
			||||||
  @Input() left: number | string = 25;
 | 
					  @Input() left: number | string = 25;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  radioGroupForm: FormGroup;
 | 
					  radioGroupForm: FormGroup;
 | 
				
			||||||
@ -153,11 +153,12 @@ export class HashrateChartPoolsComponent implements OnInit {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    this.chartOptions = {
 | 
					    this.chartOptions = {
 | 
				
			||||||
      title: title,
 | 
					      title: title,
 | 
				
			||||||
 | 
					      animation: false,
 | 
				
			||||||
      grid: {
 | 
					      grid: {
 | 
				
			||||||
        right: this.right,
 | 
					        right: this.right,
 | 
				
			||||||
        left: this.left,
 | 
					        left: this.left,
 | 
				
			||||||
        bottom: this.widget ? 30 : 20,
 | 
					        bottom: this.widget ? 30 : 60,
 | 
				
			||||||
        top: this.widget ? 10 : 40,
 | 
					        top: this.widget || this.isMobile() ? 10 : 50,
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      tooltip: {
 | 
					      tooltip: {
 | 
				
			||||||
        show: !this.isMobile() || !this.widget,
 | 
					        show: !this.isMobile() || !this.widget,
 | 
				
			||||||
@ -206,6 +207,32 @@ export class HashrateChartPoolsComponent implements OnInit {
 | 
				
			|||||||
        min: 0,
 | 
					        min: 0,
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      series: data.series,
 | 
					      series: data.series,
 | 
				
			||||||
 | 
					      dataZoom: this.widget ? null : [{
 | 
				
			||||||
 | 
					        type: 'inside',
 | 
				
			||||||
 | 
					        realtime: true,
 | 
				
			||||||
 | 
					        zoomLock: true,
 | 
				
			||||||
 | 
					        maxSpan: 100,
 | 
				
			||||||
 | 
					        minSpan: 10,
 | 
				
			||||||
 | 
					        moveOnMouseMove: false,
 | 
				
			||||||
 | 
					      }, {
 | 
				
			||||||
 | 
					        showDetail: false,
 | 
				
			||||||
 | 
					        show: true,
 | 
				
			||||||
 | 
					        type: 'slider',
 | 
				
			||||||
 | 
					        brushSelect: false,
 | 
				
			||||||
 | 
					        realtime: true,
 | 
				
			||||||
 | 
					        bottom: 0,
 | 
				
			||||||
 | 
					        left: 20,
 | 
				
			||||||
 | 
					        right: 15,
 | 
				
			||||||
 | 
					        selectedDataBackground: {
 | 
				
			||||||
 | 
					          lineStyle: {
 | 
				
			||||||
 | 
					            color: '#fff',
 | 
				
			||||||
 | 
					            opacity: 0.45,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          areaStyle: {
 | 
				
			||||||
 | 
					            opacity: 0,
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      }],
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -38,7 +38,7 @@
 | 
				
			|||||||
        <a class="nav-link" [routerLink]="['/blocks' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'cubes']" [fixedWidth]="true" i18n-title="master-page.blocks" title="Blocks"></fa-icon></a>
 | 
					        <a class="nav-link" [routerLink]="['/blocks' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'cubes']" [fixedWidth]="true" i18n-title="master-page.blocks" title="Blocks"></fa-icon></a>
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
      <li class="nav-item" routerLinkActive="active" id="btn-graphs">
 | 
					      <li class="nav-item" routerLinkActive="active" id="btn-graphs">
 | 
				
			||||||
        <a class="nav-link" [routerLink]="['/graphs' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'chart-area']" [fixedWidth]="true" i18n-title="master-page.graphs" title="Graphs"></fa-icon></a>
 | 
					        <a class="nav-link" [routerLink]="['/graphs/mempool' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'chart-area']" [fixedWidth]="true" i18n-title="master-page.graphs" title="Graphs"></fa-icon></a>
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
      <li class="nav-item d-none d-lg-block" routerLinkActive="active" id="btn-tv">
 | 
					      <li class="nav-item d-none d-lg-block" routerLinkActive="active" id="btn-tv">
 | 
				
			||||||
        <a class="nav-link" [routerLink]="['/tv' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'tv']" [fixedWidth]="true" i18n-title="master-page.tvview" title="TV view"></fa-icon></a>
 | 
					        <a class="nav-link" [routerLink]="['/tv' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'tv']" [fixedWidth]="true" i18n-title="master-page.tvview" title="TV view"></fa-icon></a>
 | 
				
			||||||
 | 
				
			|||||||
@ -76,7 +76,7 @@
 | 
				
			|||||||
      <div class="card" style="height: 385px">
 | 
					      <div class="card" style="height: 385px">
 | 
				
			||||||
        <div class="card-body">
 | 
					        <div class="card-body">
 | 
				
			||||||
          <app-pool-ranking [widget]=true></app-pool-ranking>
 | 
					          <app-pool-ranking [widget]=true></app-pool-ranking>
 | 
				
			||||||
          <div class="mt-1"><a [routerLink]="['/mining/pools' | relativeUrl]" i18n="dashboard.view-more">View more
 | 
					          <div class="mt-1"><a [routerLink]="['/graphs/mining/pools' | relativeUrl]" i18n="dashboard.view-more">View more
 | 
				
			||||||
              »</a></div>
 | 
					              »</a></div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
@ -86,30 +86,13 @@
 | 
				
			|||||||
    <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]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" i18n="dashboard.view-more">View more
 | 
				
			||||||
              »</a></div>
 | 
					              »</a></div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </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">
 | 
				
			||||||
@ -124,6 +107,7 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <!-- Difficult adjustments -->
 | 
				
			||||||
    <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">
 | 
				
			||||||
@ -131,7 +115,7 @@
 | 
				
			|||||||
            Adjustments
 | 
					            Adjustments
 | 
				
			||||||
          </h5>
 | 
					          </h5>
 | 
				
			||||||
          <app-difficulty-adjustments-table></app-difficulty-adjustments-table>
 | 
					          <app-difficulty-adjustments-table></app-difficulty-adjustments-table>
 | 
				
			||||||
          <div><a [routerLink]="['/mining/hashrate' | relativeUrl]" i18n="dashboard.view-more">View more
 | 
					          <div class="mt-1"><a [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" i18n="dashboard.view-more">View more
 | 
				
			||||||
              »</a></div>
 | 
					              »</a></div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -125,3 +125,7 @@
 | 
				
			|||||||
    max-width: 55px;
 | 
					    max-width: 55px;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.card-text {
 | 
				
			||||||
 | 
					  font-size: 22px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,8 @@
 | 
				
			|||||||
import { ChangeDetectionStrategy, Component, Inject, LOCALE_ID, OnDestroy, OnInit } from '@angular/core';
 | 
					import { ChangeDetectionStrategy, Component, Inject, LOCALE_ID, OnInit } from '@angular/core';
 | 
				
			||||||
import { map } from 'rxjs/operators';
 | 
					import { map } from 'rxjs/operators';
 | 
				
			||||||
import { SeoService } from 'src/app/services/seo.service';
 | 
					import { SeoService } from 'src/app/services/seo.service';
 | 
				
			||||||
import { StateService } from 'src/app/services/state.service';
 | 
					import { StateService } from 'src/app/services/state.service';
 | 
				
			||||||
 | 
					import { formatNumber } from '@angular/common';
 | 
				
			||||||
import { Observable } from 'rxjs';
 | 
					import { Observable } from 'rxjs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
<div [class]="widget === false ? 'container-xl' : ''">
 | 
					<div [class]="widget === false ? 'full-container' : ''">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <div *ngIf="widget">
 | 
					  <div *ngIf="widget">
 | 
				
			||||||
    <div class="pool-distribution" *ngIf="(miningStatsObservable$ | async) as miningStats; else loadingReward">
 | 
					    <div class="pool-distribution" *ngIf="(miningStatsObservable$ | async) as miningStats; else loadingReward">
 | 
				
			||||||
@ -23,14 +23,10 @@
 | 
				
			|||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <div [class]="widget ? 'chart-widget' : 'chart'"
 | 
					  <div class="card-header" *ngIf="!widget">
 | 
				
			||||||
    echarts [initOpts]="chartInitOptions" [options]="chartOptions" (chartInit)="onChartInit($event)"></div>
 | 
					    <span i18n="mining.mining-pool-share">Mining pools share</span>
 | 
				
			||||||
  <div class="text-center loadingGraphs" *ngIf="isLoading">
 | 
					    <form [formGroup]="radioGroupForm" class="formRadioGroup"
 | 
				
			||||||
    <div class="spinner-border text-light"></div>
 | 
					      *ngIf="!widget && (miningStatsObservable$ | async) as miningStats">
 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  <div class="card-header mb-0 mb-lg-4 mt-md-3" [style]="widget ? 'display:none' : ''">
 | 
					 | 
				
			||||||
    <form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(miningStatsObservable$ | async) as miningStats">
 | 
					 | 
				
			||||||
      <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="miningStats.availableTimespanDay >= 1">
 | 
					        <label ngbButtonLabel class="btn-primary btn-sm" *ngIf="miningStats.availableTimespanDay >= 1">
 | 
				
			||||||
          <input ngbButton type="radio" [value]="'24h'" fragment="24h"> 24h
 | 
					          <input ngbButton type="radio" [value]="'24h'" fragment="24h"> 24h
 | 
				
			||||||
@ -66,36 +62,48 @@
 | 
				
			|||||||
    </form>
 | 
					    </form>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <table *ngIf="widget === false" class="table table-borderless text-center pools-table">
 | 
					  <div [class]="!widget ? 'bottom-padding' : 'pb-0'" class="container pb-lg-0">
 | 
				
			||||||
    <thead>
 | 
					    <div [class]="widget ? 'chart-widget' : 'chart'" echarts [initOpts]="chartInitOptions" [options]="chartOptions"
 | 
				
			||||||
      <tr>
 | 
					      (chartInit)="onChartInit($event)"></div>
 | 
				
			||||||
        <th class="d-none d-md-block" i18n="mining.rank">Rank</th>
 | 
					    <div class="text-center loadingGraphs" *ngIf="isLoading">
 | 
				
			||||||
        <th class=""></th>
 | 
					      <div class="spinner-border text-light"></div>
 | 
				
			||||||
        <th class="" i18n="mining.pool-name">Pool</th>
 | 
					    </div>
 | 
				
			||||||
        <th class="" *ngIf="this.poolsWindowPreference === '24h'" i18n="mining.hashrate">Hashrate</th>
 | 
					
 | 
				
			||||||
        <th class="" i18n="master-page.blocks">Blocks</th>
 | 
					    <table *ngIf="widget === false" class="table table-borderless text-center pools-table">
 | 
				
			||||||
        <th class="d-none d-md-block" i18n="mining.empty-blocks">Empty Blocks</th>
 | 
					      <thead>
 | 
				
			||||||
      </tr>
 | 
					        <tr>
 | 
				
			||||||
    </thead>
 | 
					          <th class="d-none d-md-block" i18n="mining.rank">Rank</th>
 | 
				
			||||||
    <tbody *ngIf="(miningStatsObservable$ | async) as miningStats">
 | 
					          <th class=""></th>
 | 
				
			||||||
      <tr *ngFor="let pool of miningStats.pools">
 | 
					          <th class="" i18n="mining.pool-name">Pool</th>
 | 
				
			||||||
        <td class="d-none d-md-block">{{ pool.rank }}</td>
 | 
					          <th class="" *ngIf="this.poolsWindowPreference === '24h'" i18n="mining.hashrate">Hashrate</th>
 | 
				
			||||||
        <td class="text-right"><img width="25" height="25" src="{{ pool.logo }}" onError="this.src = './resources/mining-pools/default.svg'"></td>
 | 
					          <th class="" i18n="master-page.blocks">Blocks</th>
 | 
				
			||||||
        <td class=""><a [routerLink]="[('/mining/pool/' + pool.poolId) | relativeUrl]">{{ pool.name }}</a></td>
 | 
					          <th class="d-none d-md-block" i18n="mining.empty-blocks">Empty Blocks</th>
 | 
				
			||||||
        <td class="" *ngIf="this.poolsWindowPreference === '24h' && !isLoading">{{ pool.lastEstimatedHashrate }} {{ miningStats.miningUnits.hashrateUnit }}</td>
 | 
					        </tr>
 | 
				
			||||||
        <td class="">{{ pool['blockText'] }}</td>
 | 
					      </thead>
 | 
				
			||||||
        <td class="d-none d-md-block">{{ pool.emptyBlocks }} ({{ pool.emptyBlockRatio }}%)</td>
 | 
					      <tbody *ngIf="(miningStatsObservable$ | async) as miningStats">
 | 
				
			||||||
      </tr>
 | 
					        <tr *ngFor="let pool of miningStats.pools">
 | 
				
			||||||
      <tr style="border-top: 1px solid #555">
 | 
					          <td class="d-none d-md-block">{{ pool.rank }}</td>
 | 
				
			||||||
        <td class="d-none d-md-block"></td>
 | 
					          <td class="text-right"><img width="25" height="25" src="{{ pool.logo }}"
 | 
				
			||||||
        <td class="text-right"></td>
 | 
					              onError="this.src = './resources/mining-pools/default.svg'"></td>
 | 
				
			||||||
        <td class="" i18n="mining.all-miners"><b>All miners</b></td>
 | 
					          <td class=""><a [routerLink]="[('/mining/pool/' + pool.poolId) | relativeUrl]">{{ pool.name }}</a></td>
 | 
				
			||||||
        <td class="" *ngIf="this.poolsWindowPreference === '24h'"><b>{{ miningStats.lastEstimatedHashrate}} {{ miningStats.miningUnits.hashrateUnit }}</b></td>
 | 
					          <td class="" *ngIf="this.poolsWindowPreference === '24h' && !isLoading">{{ pool.lastEstimatedHashrate }} {{
 | 
				
			||||||
        <td class=""><b>{{ miningStats.blockCount }}</b></td>
 | 
					            miningStats.miningUnits.hashrateUnit }}</td>
 | 
				
			||||||
        <td class="d-none d-md-block"><b>{{ miningStats.totalEmptyBlock }} ({{ miningStats.totalEmptyBlockRatio }}%)</b></td>
 | 
					          <td class="">{{ pool['blockText'] }}</td>
 | 
				
			||||||
      </tr>
 | 
					          <td class="d-none d-md-block">{{ pool.emptyBlocks }} ({{ pool.emptyBlockRatio }}%)</td>
 | 
				
			||||||
    </tbody>
 | 
					        </tr>
 | 
				
			||||||
  </table>
 | 
					        <tr style="border-top: 1px solid #555">
 | 
				
			||||||
 | 
					          <td class="d-none d-md-block"></td>
 | 
				
			||||||
 | 
					          <td class="text-right"></td>
 | 
				
			||||||
 | 
					          <td class="" i18n="mining.all-miners"><b>All miners</b></td>
 | 
				
			||||||
 | 
					          <td class="" *ngIf="this.poolsWindowPreference === '24h'"><b>{{ miningStats.lastEstimatedHashrate}} {{
 | 
				
			||||||
 | 
					              miningStats.miningUnits.hashrateUnit }}</b></td>
 | 
				
			||||||
 | 
					          <td class=""><b>{{ miningStats.blockCount }}</b></td>
 | 
				
			||||||
 | 
					          <td class="d-none d-md-block"><b>{{ miningStats.totalEmptyBlock }} ({{ miningStats.totalEmptyBlockRatio
 | 
				
			||||||
 | 
					              }}%)</b></td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					      </tbody>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,27 @@
 | 
				
			|||||||
 | 
					.card-header {
 | 
				
			||||||
 | 
					  border-bottom: 0;
 | 
				
			||||||
 | 
					  font-size: 18px;
 | 
				
			||||||
 | 
					  @media (min-width: 465px) {
 | 
				
			||||||
 | 
					    font-size: 20px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.full-container {
 | 
				
			||||||
 | 
					  padding: 0px 15px;
 | 
				
			||||||
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					  height: calc(100% - 140px);
 | 
				
			||||||
 | 
					  @media (max-width: 992px) {
 | 
				
			||||||
 | 
					    height: calc(100% - 190px);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  @media (max-width: 575px) {
 | 
				
			||||||
 | 
					    height: calc(100% - 230px);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.chart {
 | 
					.chart {
 | 
				
			||||||
  max-height: 400px;
 | 
					  max-height: 400px;
 | 
				
			||||||
  @media (max-width: 767.98px) {
 | 
					  @media (max-width: 767.98px) {
 | 
				
			||||||
    max-height: 270px;
 | 
					    max-height: 230px;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.chart-widget {
 | 
					.chart-widget {
 | 
				
			||||||
@ -17,10 +37,17 @@
 | 
				
			|||||||
  margin-top: 6px;
 | 
					  margin-top: 6px;
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  flex-direction: column;
 | 
					  flex-direction: column;
 | 
				
			||||||
 | 
					  @media (min-width: 1130px) {
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    top: -65px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  @media (min-width: 830px) and (max-width: 1130px) {
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    top: 0px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  @media (min-width: 830px) {
 | 
					  @media (min-width: 830px) {
 | 
				
			||||||
    margin-left: 2%;
 | 
					 | 
				
			||||||
    flex-direction: row;
 | 
					    flex-direction: row;
 | 
				
			||||||
    float: left;
 | 
					    float: right;
 | 
				
			||||||
    margin-top: 0px;
 | 
					    margin-top: 0px;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  .btn-sm {
 | 
					  .btn-sm {
 | 
				
			||||||
@ -31,12 +58,21 @@
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.bottom-padding {
 | 
				
			||||||
 | 
					  @media (max-width: 992px) {
 | 
				
			||||||
 | 
					    padding-bottom: 65px
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  @media (max-width: 576px) {
 | 
				
			||||||
 | 
					    padding-bottom: 65px
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@media (max-width: 767.98px) {
 | 
					@media (max-width: 767.98px) {
 | 
				
			||||||
  .pools-table th,
 | 
					  .pools-table th,
 | 
				
			||||||
  .pools-table td {
 | 
					  .pools-table td {
 | 
				
			||||||
      padding: .3em !important;
 | 
					    padding: .3em !important;
 | 
				
			||||||
   }
 | 
					  }
 | 
				
			||||||
 }
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.loadingGraphs {
 | 
					.loadingGraphs {
 | 
				
			||||||
  position: absolute;
 | 
					  position: absolute;
 | 
				
			||||||
@ -44,9 +80,6 @@
 | 
				
			|||||||
  left: calc(50% - 15px);
 | 
					  left: calc(50% - 15px);
 | 
				
			||||||
  z-index: 100;
 | 
					  z-index: 100;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.loadingGraphs.widget {
 | 
					 | 
				
			||||||
  top: 25%;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pool-distribution {
 | 
					.pool-distribution {
 | 
				
			||||||
  min-height: 56px;
 | 
					  min-height: 56px;
 | 
				
			||||||
 | 
				
			|||||||
@ -117,7 +117,7 @@ export class PoolRankingComponent implements OnInit {
 | 
				
			|||||||
    if (this.isMobile() && this.widget) {
 | 
					    if (this.isMobile() && this.widget) {
 | 
				
			||||||
      edgeDistance = 0;
 | 
					      edgeDistance = 0;
 | 
				
			||||||
    } else if (this.isMobile() && !this.widget || this.widget) {
 | 
					    } else if (this.isMobile() && !this.widget || this.widget) {
 | 
				
			||||||
      edgeDistance = 35;
 | 
					      edgeDistance = 10;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    miningStats.pools.forEach((pool) => {
 | 
					    miningStats.pools.forEach((pool) => {
 | 
				
			||||||
@ -209,13 +209,13 @@ export class PoolRankingComponent implements OnInit {
 | 
				
			|||||||
    network = network.charAt(0).toUpperCase() + network.slice(1);
 | 
					    network = network.charAt(0).toUpperCase() + network.slice(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let radius: any[] = ['20%', '80%'];
 | 
					    let radius: any[] = ['20%', '80%'];
 | 
				
			||||||
    let top: any = undefined; let bottom = undefined; let height = undefined;
 | 
					    let top: number = 0; let height = undefined;
 | 
				
			||||||
    if (this.isMobile() && this.widget) {
 | 
					    if (this.isMobile() && this.widget) {
 | 
				
			||||||
      top = -30;
 | 
					      top = -30;
 | 
				
			||||||
      height = 270;
 | 
					      height = 270;
 | 
				
			||||||
      radius = ['10%', '50%'];
 | 
					      radius = ['10%', '50%'];
 | 
				
			||||||
    } else if (this.isMobile() && !this.widget) {
 | 
					    } else if (this.isMobile() && !this.widget) {
 | 
				
			||||||
      top = 0;
 | 
					      top = -40;
 | 
				
			||||||
      height = 300;
 | 
					      height = 300;
 | 
				
			||||||
      radius = ['10%', '50%'];
 | 
					      radius = ['10%', '50%'];
 | 
				
			||||||
    } else if (this.widget) {
 | 
					    } else if (this.widget) {
 | 
				
			||||||
@ -223,22 +223,12 @@ export class PoolRankingComponent implements OnInit {
 | 
				
			|||||||
      top = -20;
 | 
					      top = -20;
 | 
				
			||||||
      height = 330;
 | 
					      height = 330;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      top = 35;
 | 
					      top = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.chartOptions = {
 | 
					    this.chartOptions = {
 | 
				
			||||||
 | 
					      animation: false,
 | 
				
			||||||
      color: chartColors,
 | 
					      color: chartColors,
 | 
				
			||||||
      title: {
 | 
					 | 
				
			||||||
        text: this.widget ? '' : $localize`:@@mining.pool-chart-title:${network}:NETWORK: mining pools share`,
 | 
					 | 
				
			||||||
        left: 'center',
 | 
					 | 
				
			||||||
        textStyle: {
 | 
					 | 
				
			||||||
          color: '#FFF',
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        subtextStyle: {
 | 
					 | 
				
			||||||
          color: '#CCC',
 | 
					 | 
				
			||||||
          fontStyle: 'italic',
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      tooltip: {
 | 
					      tooltip: {
 | 
				
			||||||
        trigger: 'item',
 | 
					        trigger: 'item',
 | 
				
			||||||
        textStyle: {
 | 
					        textStyle: {
 | 
				
			||||||
@ -249,7 +239,6 @@ export class PoolRankingComponent implements OnInit {
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
          minShowLabelAngle: 3.6,
 | 
					          minShowLabelAngle: 3.6,
 | 
				
			||||||
          top: top,
 | 
					          top: top,
 | 
				
			||||||
          bottom: bottom,
 | 
					 | 
				
			||||||
          height: height,
 | 
					          height: height,
 | 
				
			||||||
          name: 'Mining pool',
 | 
					          name: 'Mining pool',
 | 
				
			||||||
          type: 'pie',
 | 
					          type: 'pie',
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,4 @@
 | 
				
			|||||||
import { Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core';
 | 
					import { Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core';
 | 
				
			||||||
import { WebsocketService } from 'src/app/services/websocket.service';
 | 
					 | 
				
			||||||
import { StateService } from 'src/app/services/state.service';
 | 
					import { StateService } from 'src/app/services/state.service';
 | 
				
			||||||
import { specialBlocks } from 'src/app/app.constants';
 | 
					import { specialBlocks } from 'src/app/app.constants';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -20,12 +19,10 @@ export class StartComponent implements OnInit {
 | 
				
			|||||||
  @ViewChild('blockchainContainer') blockchainContainer: ElementRef;
 | 
					  @ViewChild('blockchainContainer') blockchainContainer: ElementRef;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    private websocketService: WebsocketService,
 | 
					 | 
				
			||||||
    private stateService: StateService,
 | 
					    private stateService: StateService,
 | 
				
			||||||
  ) { }
 | 
					  ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnInit() {
 | 
					  ngOnInit() {
 | 
				
			||||||
    this.websocketService.want(['blocks', 'stats', 'mempool-blocks']);
 | 
					 | 
				
			||||||
    this.stateService.blocks$
 | 
					    this.stateService.blocks$
 | 
				
			||||||
      .subscribe((blocks: any) => {
 | 
					      .subscribe((blocks: any) => {
 | 
				
			||||||
        if (this.stateService.network !== '') {
 | 
					        if (this.stateService.network !== '') {
 | 
				
			||||||
 | 
				
			|||||||
@ -40,6 +40,14 @@
 | 
				
			|||||||
  margin-top: 6px;
 | 
					  margin-top: 6px;
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  flex-direction: column;
 | 
					  flex-direction: column;
 | 
				
			||||||
 | 
					  @media (min-width: 1130px) {
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    top: -65px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  @media (min-width: 830px) and (max-width: 1130px) {
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    top: 0px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  @media (min-width: 830px) {
 | 
					  @media (min-width: 830px) {
 | 
				
			||||||
    flex-direction: row;
 | 
					    flex-direction: row;
 | 
				
			||||||
    float: right;
 | 
					    float: right;
 | 
				
			||||||
 | 
				
			|||||||
@ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user