From f8f9108ae1b41d98ec12a5ce0d27e0bcb03f0eb9 Mon Sep 17 00:00:00 2001 From: nymkappa Date: Fri, 21 Jan 2022 21:50:57 +0900 Subject: [PATCH] Polish mining page UI Make sure to wait for all mining pools queries before continuing --- backend/src/index.ts | 2 +- backend/src/routes.ts | 5 +- .../pool-ranking/pool-ranking.component.html | 39 +++++----- .../pool-ranking/pool-ranking.component.scss | 32 +++++++++ .../pool-ranking/pool-ranking.component.ts | 71 +++++++++++-------- 5 files changed, 99 insertions(+), 50 deletions(-) create mode 100644 frontend/src/app/components/pool-ranking/pool-ranking.component.scss diff --git a/backend/src/index.ts b/backend/src/index.ts index 4839322d4..84be16fbc 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -265,7 +265,7 @@ class Server { .get(config.MEMPOOL.API_URL_PREFIX + 'statistics/1y', routes.$getStatisticsByTime.bind(routes, '1y')) .get(config.MEMPOOL.API_URL_PREFIX + 'statistics/2y', routes.$getStatisticsByTime.bind(routes, '2y')) .get(config.MEMPOOL.API_URL_PREFIX + 'statistics/3y', routes.$getStatisticsByTime.bind(routes, '3y')) - .get(config.MEMPOOL.API_URL_PREFIX + 'pools', routes.getPools) + .get(config.MEMPOOL.API_URL_PREFIX + 'pools', routes.$getPools) ; } diff --git a/backend/src/routes.ts b/backend/src/routes.ts index b7956cd64..00e2ceee0 100644 --- a/backend/src/routes.ts +++ b/backend/src/routes.ts @@ -532,9 +532,12 @@ class Routes { } } - public async getPools(req: Request, res: Response) { + public async $getPools(req: Request, res: Response) { try { let stats = await miningStats.$getPoolsStats(req.query.interval as string); + // res.header('Pragma', 'public'); + // res.header('Cache-control', 'public'); + // res.setHeader('Expires', new Date(Date.now() + 1000 * 300).toUTCString()); res.json(stats); } catch (e) { res.status(500).send(e instanceof Error ? e.message : e); diff --git a/frontend/src/app/components/pool-ranking/pool-ranking.component.html b/frontend/src/app/components/pool-ranking/pool-ranking.component.html index 78b6a45ba..757e11385 100644 --- a/frontend/src/app/components/pool-ranking/pool-ranking.component.html +++ b/frontend/src/app/components/pool-ranking/pool-ranking.component.html @@ -1,13 +1,12 @@
+ - - -
+
-
+
- +
- - - - - - + + + + + + + + - - - - + + + + - - - - + + + + diff --git a/frontend/src/app/components/pool-ranking/pool-ranking.component.scss b/frontend/src/app/components/pool-ranking/pool-ranking.component.scss new file mode 100644 index 000000000..3cf52b6ce --- /dev/null +++ b/frontend/src/app/components/pool-ranking/pool-ranking.component.scss @@ -0,0 +1,32 @@ +.hashrate-pie { + height: 100%; + min-height: 400px; + @media (max-width: 767.98px) { + min-height: 300px; + } +} + +.formRadioGroup { + margin-top: 6px; + display: flex; + flex-direction: column; + @media (min-width: 830px) { + margin-left: 2%; + flex-direction: row; + float: left; + margin-top: 0px; + } + .btn-sm { + font-size: 9px; + @media (min-width: 830px) { + font-size: 14px; + } + } +} + +@media (max-width: 767.98px) { + .pools-table th, + .pools-table td { + padding: .3em !important; + } + } diff --git a/frontend/src/app/components/pool-ranking/pool-ranking.component.ts b/frontend/src/app/components/pool-ranking/pool-ranking.component.ts index 8ce0ef7ab..b5fbfb75f 100644 --- a/frontend/src/app/components/pool-ranking/pool-ranking.component.ts +++ b/frontend/src/app/components/pool-ranking/pool-ranking.component.ts @@ -2,7 +2,8 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; import { EChartsOption } from 'echarts'; import { combineLatest, Observable, of } from 'rxjs'; -import { catchError, skip, startWith, switchMap, tap } from 'rxjs/operators'; +import { catchError, map, skip, startWith, switchMap, tap } from 'rxjs/operators'; +import { SinglePoolStats } from 'src/app/interfaces/node-api.interface'; import { StorageService } from '../..//services/storage.service'; import { MiningService, MiningStats } from '../../services/mining.service'; import { StateService } from '../../services/state.service'; @@ -10,11 +11,12 @@ import { StateService } from '../../services/state.service'; @Component({ selector: 'app-pool-ranking', templateUrl: './pool-ranking.component.html', + styleUrls: ['./pool-ranking.component.scss'], styles: [` .loadingGraphs { position: absolute; - top: 50%; - left: calc(50% - 16px); + top: 38%; + left: calc(50% - 15px); z-index: 100; } `], @@ -70,6 +72,10 @@ export class PoolRankingComponent implements OnInit, OnDestroy { catchError((e) => of(this.getEmptyMiningStat())) ); }), + map(data => { + data.pools = data.pools.map((pool: SinglePoolStats) => this.formatPoolUI(pool)); + return data; + }), tap(data => { this.isLoading = false; this.prepareChartOptions(data); @@ -80,8 +86,17 @@ export class PoolRankingComponent implements OnInit, OnDestroy { ngOnDestroy(): void { } + formatPoolUI(pool: SinglePoolStats) { + pool['blockText'] = pool.blockCount.toString() + ` (${pool.share}%)`; + return pool; + } + + isMobile() { + return (window.innerWidth <= 767.98); + } + generatePoolsChartSerieData(miningStats) { - const poolShareThreshold = 0.5; // Do not draw pools which hashrate share is lower than that + const poolShareThreshold = this.isMobile() ? 1 : 0.5; // Do not draw pools which hashrate share is lower than that const data: object[] = []; miningStats.pools.forEach((pool) => { @@ -90,16 +105,23 @@ export class PoolRankingComponent implements OnInit, OnDestroy { } data.push({ value: pool.share, - name: pool.name + ` (${pool.share}%)`, - label: { color: '#FFFFFF' }, + name: pool.name + (this.isMobile() ? `` : ` (${pool.share}%)`), + label: { + color: '#FFFFFF', + overflow: 'break', + }, tooltip: { + backgroundColor: "#282d47", + textStyle: { + color: "#FFFFFF", + }, formatter: () => { if (this.poolsWindowPreference === '1d') { - return `${pool.name}
` + - pool.lastEstimatedHashrate.toString() + ' PH/s (' + pool.share + `%) -
(` + pool.blockCount.toString() + ` blocks)`; + return `${pool.name} (${pool.share}%)
` + + pool.lastEstimatedHashrate.toString() + ' PH/s' + + `
` + pool.blockCount.toString() + ` blocks`; } else { - return `${pool.name}
` + + return `${pool.name} (${pool.share}%)
` + pool.blockCount.toString() + ` blocks`; } } @@ -116,29 +138,22 @@ export class PoolRankingComponent implements OnInit, OnDestroy { subtext: (this.poolsWindowPreference === '1d') ? 'Estimated from the # of blocks mined' : null, left: 'center', textStyle: { - color: '#FFFFFF', + color: '#FFF', }, subtextStyle: { - color: '#CCCCCC', + color: '#CCC', fontStyle: 'italic', } }, tooltip: { trigger: 'item' }, - legend: (window.innerWidth <= 767.98) ? { - bottom: '0%', - left: 'center', - textStyle: { - color: '#FFF' - } - } : null, series: [ { - top: '5%', + top: this.isMobile() ? '5%' : '20%', name: 'Mining pool', type: 'pie', - radius: ['30%', '70%'], + radius: this.isMobile() ? ['10%', '50%'] : ['20%', '80%'], data: this.generatePoolsChartSerieData(miningStats), labelLine: { lineStyle: { @@ -146,22 +161,20 @@ export class PoolRankingComponent implements OnInit, OnDestroy { }, }, label: { - show: (window.innerWidth > 767.98), fontSize: 14, }, itemStyle: { - borderRadius: 5, + borderRadius: 2, borderWidth: 2, borderColor: '#000', }, emphasis: { itemStyle: { - borderWidth: 5, - borderColor: '#000', - borderRadius: 20, - shadowBlur: 40, - shadowOffsetX: 0, - shadowColor: 'rgba(0, 0, 0, 0.75)' + borderWidth: 2, + borderColor: '#FFF', + borderRadius: 2, + shadowBlur: 80, + shadowColor: 'rgba(255, 255, 255, 0.75)', }, labelLine: { lineStyle: {
RankNameHashrateBlock Count (%)Empty Blocks (%)
RankNameHashrateBlocksEmpty Blocks
-All miners{{ miningStats.lastEstimatedHashrate}} {{ miningStats.miningUnits.hashrateUnit }}{{ miningStats.blockCount }}All miners{{ miningStats.lastEstimatedHashrate}} {{ miningStats.miningUnits.hashrateUnit }}{{ miningStats.blockCount }} {{ miningStats.totalEmptyBlock }} ({{ miningStats.totalEmptyBlockRatio }}%)
{{ pool.rank }}{{ pool.name }}{{ pool.lastEstimatedHashrate }} {{ miningStats.miningUnits.hashrateUnit }}{{ pool.blockCount }} ({{ pool.share }}%){{ pool.name }}{{ pool.lastEstimatedHashrate }} {{ miningStats.miningUnits.hashrateUnit }}{{ pool['blockText'] }} {{ pool.emptyBlocks }} ({{ pool.emptyBlockRatio }}%)