From aff44d90d5ebc678f86e9caeadd5e82376c33e09 Mon Sep 17 00:00:00 2001 From: Mononaut Date: Fri, 8 Dec 2023 13:03:08 +0000 Subject: [PATCH] Rerefactor acceleration dashboard --- .../acceleration-fees-graph.component.html | 33 +--- .../acceleration-fees-graph.component.scss | 57 +------ .../acceleration-fees-graph.component.ts | 145 ++++++++++-------- .../acceleration-stats.component.ts | 2 +- .../accelerations-list.component.html | 57 ++++--- .../accelerations-list.component.scss | 14 +- .../accelerator-dashboard.component.html | 24 ++- .../accelerator-dashboard.component.ts | 2 +- 8 files changed, 158 insertions(+), 176 deletions(-) diff --git a/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.html b/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.html index 0c15f9f44..9ae0ddade 100644 --- a/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.html +++ b/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.html @@ -28,19 +28,8 @@
-
-
-
Avg Out-of-band Fees (24h)
-

- -

-
-
-
Avg Out-of-band Fees (1w)
-

- -

-
+
+
Out-of-band Fees Per Block
@@ -50,22 +39,4 @@
-
- - -
-
Avg Out-of-band Fees (24h)
-

- -

-
-
- -
-
Avg Out-of-band Fees (1w)
-

- -

-
-
diff --git a/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.scss b/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.scss index 2ffcc6374..c4b4335ee 100644 --- a/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.scss +++ b/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.scss @@ -56,61 +56,16 @@ .chart-widget { width: 100%; height: 100%; - max-height: 238px; + max-height: 290px; } -.acceleration-fees { - min-height: 56px; - display: block; - @media (min-width: 485px) { - display: flex; - flex-direction: row; - } - h5 { - margin-bottom: 10px; - } - .item { - width: 50%; - display: inline-block; - margin: 0px auto 20px; - &: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; - } - } - } +h5 { + margin-bottom: 10px; } -.skeleton-loader { - width: 100%; - display: block; - max-width: 80px; - margin: 15px auto 3px; +.card-title { + font-size: 1rem; + color: #4a68b9; } .disabled { diff --git a/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.ts b/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.ts index b5dc21eb6..d27b10690 100644 --- a/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.ts +++ b/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.ts @@ -1,12 +1,12 @@ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, Input, LOCALE_ID, OnDestroy, OnInit } from '@angular/core'; import { EChartsOption, graphic } from 'echarts'; -import { Observable, combineLatest } from 'rxjs'; -import { map, startWith, switchMap, tap } from 'rxjs/operators'; +import { Observable, Subscription, combineLatest } from 'rxjs'; +import { map, max, startWith, switchMap, tap } from 'rxjs/operators'; import { ApiService } from '../../../services/api.service'; import { SeoService } from '../../../services/seo.service'; import { formatNumber } from '@angular/common'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; -import { download, formatterXAxis } from '../../../shared/graphs.utils'; +import { download, formatterXAxis, formatterXAxisLabel, formatterXAxisTimeCategory } from '../../../shared/graphs.utils'; import { StorageService } from '../../../services/storage.service'; import { MiningService } from '../../../services/mining.service'; import { ActivatedRoute } from '@angular/router'; @@ -26,7 +26,7 @@ import { Acceleration } from '../../../interfaces/node-api.interface'; `], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class AccelerationFeesGraphComponent implements OnInit { +export class AccelerationFeesGraphComponent implements OnInit, OnDestroy { @Input() widget: boolean = false; @Input() right: number | string = 45; @Input() left: number | string = 75; @@ -42,6 +42,7 @@ export class AccelerationFeesGraphComponent implements OnInit { hrStatsObservable$: Observable; statsObservable$: Observable; + statsSubscription: Subscription; isLoading = true; formatNumber = formatNumber; timespan = ''; @@ -66,26 +67,17 @@ export class AccelerationFeesGraphComponent implements OnInit { ngOnInit(): void { this.seoService.setTitle($localize`:@@6c453b11fd7bd159ae30bc381f367bc736d86909:Acceleration Fees`); + this.isLoading = true; if (this.widget) { - this.miningWindowPreference = '1w'; - this.isLoading = true; + this.miningWindowPreference = '1m'; this.timespan = this.miningWindowPreference; - this.hrStatsObservable$ = (this.accelerations$ || this.apiService.getAccelerationHistory$({ timeframe: '24h' })).pipe( - map((accelerations) => { - return { - avgFeesPaid: accelerations.filter(acc => acc.status === 'completed' && acc.lastUpdated < (Date.now() - (24 * 60 * 60 * 1000))).reduce((total, acc) => total + acc.feePaid, 0) / accelerations.length - }; - }) - ); - this.statsObservable$ = combineLatest([ (this.accelerations$ || this.apiService.getAccelerationHistory$({ timeframe: this.miningWindowPreference })), this.apiService.getHistoricalBlockFees$(this.miningWindowPreference), ]).pipe( tap(([accelerations, blockFeesResponse]) => { this.prepareChartOptions(accelerations, blockFeesResponse.body); - this.isLoading = false; }), map(([accelerations, blockFeesResponse]) => { return { @@ -121,11 +113,13 @@ export class AccelerationFeesGraphComponent implements OnInit { ]).pipe( tap(([accelerations, blockFeesResponse]) => { this.prepareChartOptions(accelerations, blockFeesResponse.body); - this.isLoading = false; - this.cd.markForCheck(); }) ); } + this.statsSubscription = this.statsObservable$.subscribe(() => { + this.isLoading = false; + this.cd.markForCheck(); + }); } prepareChartOptions(accelerations, blockFees) { @@ -143,6 +137,8 @@ export class AccelerationFeesGraphComponent implements OnInit { } let last = null; + let minValue = Infinity; + let maxValue = 0; const data = []; for (const val of blockFees) { if (last == null) { @@ -151,31 +147,29 @@ export class AccelerationFeesGraphComponent implements OnInit { let totalFeeDelta = 0; let totalFeePaid = 0; let totalCount = 0; + let blockCount = 0; while (last <= val.avgHeight) { + blockCount++; totalFeeDelta += (blockAccelerations[last] || []).reduce((total, acc) => total + acc.feeDelta, 0); totalFeePaid += (blockAccelerations[last] || []).reduce((total, acc) => total + acc.feePaid, 0); totalCount += (blockAccelerations[last] || []).length; last++; } + minValue = Math.min(minValue, val.avgFees); + maxValue = Math.max(maxValue, val.avgFees); data.push({ ...val, feeDelta: totalFeeDelta, - feePaid: totalFeePaid, - accelerations: totalCount, + avgFeePaid: (totalFeePaid / blockCount), + accelerations: totalCount / blockCount, }); } this.chartOptions = { title: title, color: [ - '#1E88E5', - new graphic.LinearGradient(0, 0, 0, 0.65, [ - { offset: 0, color: '#F4511E' }, - { offset: 0.25, color: '#FB8C00' }, - { offset: 0.5, color: '#FFB300' }, - { offset: 0.75, color: '#FDD835' }, - { offset: 1, color: '#7CB342' } - ]), + '#8F5FF6', + '#6b6b6b', ], animation: false, grid: { @@ -205,11 +199,11 @@ export class AccelerationFeesGraphComponent implements OnInit { let tooltip = ` ${formatterXAxis(this.locale, this.timespan, parseInt(data[0].axisValue, 10))}
`; - for (const tick of data) { - if (tick.seriesIndex === 1) { + for (const tick of data.reverse()) { + if (tick.data[1] >= 1_000_000) { + tooltip += `${tick.marker} ${tick.seriesName}: ${formatNumber(tick.data[1] / 100_000_000, this.locale, '1.0-3')} BTC
`; + } else { tooltip += `${tick.marker} ${tick.seriesName}: ${formatNumber(tick.data[1], this.locale, '1.0-0')} sats
`; - } else if (tick.seriesIndex === 0) { - tooltip += `${tick.marker} ${tick.seriesName}: ${formatNumber(tick.data[1], this.locale, '1.0-0')}
`; } } @@ -224,24 +218,35 @@ export class AccelerationFeesGraphComponent implements OnInit { }, xAxis: data.length === 0 ? undefined : { - type: 'time', - splitNumber: this.isMobile() ? 5 : 10, + name: this.widget ? undefined : formatterXAxisLabel(this.locale, this.timespan), + nameLocation: 'middle', + nameTextStyle: { + padding: [10, 0, 0, 0], + }, + type: 'category', + boundaryGap: false, + axisLine: { onZero: true }, axisLabel: { + formatter: val => formatterXAxisTimeCategory(this.locale, this.timespan, parseInt(val, 10)), + align: 'center', + fontSize: 11, + lineHeight: 12, hideOverlap: true, - } + padding: [0, 5], + }, }, - legend: (this.widget || data.length === 0) ? undefined : { + legend: { data: [ { - name: 'Total accelerations', + name: 'In-band fees per block', inactiveColor: 'rgb(110, 112, 121)', - textStyle: { + textStyle: { color: 'white', }, icon: 'roundRect', }, { - name: 'Out-of-band fees paid', + name: 'Out-of-band fees per block', inactiveColor: 'rgb(110, 112, 121)', textStyle: { color: 'white', @@ -249,6 +254,11 @@ export class AccelerationFeesGraphComponent implements OnInit { icon: 'roundRect', }, ], + selected: { + 'In-band fees per block': false, + 'Out-of-band fees per block': true, + }, + show: !this.widget, }, yAxis: data.length === 0 ? undefined : [ { @@ -288,35 +298,23 @@ export class AccelerationFeesGraphComponent implements OnInit { series: data.length === 0 ? undefined : [ { legendHoverLink: false, - zlevel: 0, - yAxisIndex: 1, - name: 'Total accelerations', - data: data.map(block => [block.timestamp * 1000, block.accelerations, block.avgHeight]), - type: 'line', - symbol: 'none', - areaStyle: { - color: '#1E88E5', - opacity: 0.5 - }, - lineStyle: { - width: 1, - opacity: 1, - }, - step: 'middle', + zlevel: 1, + name: 'Out-of-band fees per block', + data: data.map(block => [block.timestamp * 1000, block.avgFeePaid, block.avgHeight]), + stack: 'Total', + type: 'bar', + barWidth: '100%', + large: true, }, { legendHoverLink: false, - zlevel: 1, - yAxisIndex: 0, - name: 'Out-of-band fees paid', - data: data.map(block => [block.timestamp * 1000, block.feePaid, block.avgHeight]), - type: 'line', - smooth: 0.25, - symbol: 'none', - lineStyle: { - width: 2, - opacity: 1, - } + zlevel: 0, + name: 'In-band fees per block', + data: data.map(block => [block.timestamp * 1000, block.avgFees, block.avgHeight]), + stack: 'Total', + type: 'bar', + barWidth: '100%', + large: true, }, ], dataZoom: (this.widget || data.length === 0 )? undefined : [{ @@ -344,6 +342,17 @@ export class AccelerationFeesGraphComponent implements OnInit { } }, }], + visualMap: { + type: 'continuous', + min: minValue, + max: maxValue, + dimension: 1, + seriesIndex: 1, + show: false, + inRange: { + color: ['#F4511E7f', '#FB8C007f', '#FFB3007f', '#FDD8357f', '#7CB3427f'].reverse() // Gradient color range + } + }, }; } @@ -372,4 +381,10 @@ export class AccelerationFeesGraphComponent implements OnInit { this.chartOptions.backgroundColor = 'none'; this.chartInstance.setOption(this.chartOptions); } + + ngOnDestroy(): void { + if (this.statsSubscription) { + this.statsSubscription.unsubscribe(); + } + } } diff --git a/frontend/src/app/components/acceleration/acceleration-stats/acceleration-stats.component.ts b/frontend/src/app/components/acceleration/acceleration-stats/acceleration-stats.component.ts index 51f7360e1..d83303619 100644 --- a/frontend/src/app/components/acceleration/acceleration-stats/acceleration-stats.component.ts +++ b/frontend/src/app/components/acceleration/acceleration-stats/acceleration-stats.component.ts @@ -12,7 +12,7 @@ import { Acceleration } from '../../../interfaces/node-api.interface'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class AccelerationStatsComponent implements OnInit { - @Input() timespan: '24h' | '1w' = '24h'; + @Input() timespan: '24h' | '1w' | '1m' = '24h'; @Input() accelerations$: Observable; public accelerationStats$: Observable; diff --git a/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.html b/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.html index a64c4724b..4a864b024 100644 --- a/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.html +++ b/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.html @@ -8,9 +8,16 @@ - - - + + + + + + + + + + @@ -19,20 +26,33 @@ - - - - + + + + + + + + + + + @@ -63,7 +83,8 @@
- There are no accelerations show here yet! + There are no active accelerations yet! + There are no accelerations show here yet!
diff --git a/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.scss b/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.scss index 55cecdcbd..69aae18cc 100644 --- a/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.scss +++ b/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.scss @@ -50,7 +50,7 @@ tr, td, th { } .txid { - width: 30%; + width: 25%; @media (max-width: 1100px) { padding-right: 10px; } @@ -64,10 +64,18 @@ tr, td, th { } .fee { - width: 25%; + width: 35%; } -.fee-delta { +.block { + width: 20%; +} + +.bid { + width: 30%; +} + +.time { width: 25%; } diff --git a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html index 0dbba3219..91b721db6 100644 --- a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html +++ b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html @@ -7,7 +7,7 @@
- Pending accelerations + Active accelerations
@@ -18,16 +18,16 @@
- +
Acceleration stats  - (1008 blocks) + (1 month)
- +
@@ -54,11 +54,23 @@
- + + + +
-
Pending Accelerations
+
diff --git a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts index c3a40730b..79a77a600 100644 --- a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts +++ b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts @@ -56,7 +56,7 @@ export class AcceleratorDashboardComponent implements OnInit { this.accelerations$ = this.stateService.chainTip$.pipe( distinctUntilChanged(), switchMap((chainTip) => { - return this.apiService.getAccelerationHistory$({ timeframe: '1w' }); + return this.apiService.getAccelerationHistory$({ timeframe: '1m' }); }), catchError((e) => { return of([]);
TXIDFinal FeeMax BidStatusFee RateAcceleration BidRequestedOut-of-band FeeBlockStatus
- {{ (acceleration.feePaid - acceleration.baseFee - acceleration.vsizeFee) | number }} sat - - ~ - - {{ acceleration.feeDelta | number }} sat - - Pending - Mined - Canceled - + + + {{ (acceleration.feeDelta) | number }} sat + + + + {{ (acceleration.feePaid) | number }} sat + + ~ + + {{ acceleration.blockHeight }} + + Pending + Mined + Canceled +