diff --git a/backend/package-lock.json b/backend/package-lock.json index 4d16fa012..db71881cc 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -17,7 +17,7 @@ "crypto-js": "~4.2.0", "express": "~4.18.2", "maxmind": "~4.3.11", - "mysql2": "~3.7.0", + "mysql2": "~3.9.1", "redis": "^4.6.6", "rust-gbt": "file:./rust-gbt", "socks-proxy-agent": "~7.0.0", @@ -3673,9 +3673,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "funding": [ { "type": "individual", @@ -6110,9 +6110,9 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/mysql2": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.7.0.tgz", - "integrity": "sha512-c45jA3Jc1X8yJKzrWu1GpplBKGwv/wIV6ITZTlCSY7npF2YfJR+6nMP5e+NTQhUeJPSyOQAbGDCGEHbAl8HN9w==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.1.tgz", + "integrity": "sha512-3njoWAAhGBYy0tWBabqUQcLtczZUxrmmtc2vszQUekg3kTJyZ5/IeLC3Fo04u6y6Iy5Sba7pIIa2P/gs8D3ZeQ==", "dependencies": { "denque": "^2.1.0", "generate-function": "^2.3.1", @@ -10440,9 +10440,9 @@ "dev": true }, "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==" }, "form-data": { "version": "4.0.0", @@ -12230,9 +12230,9 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "mysql2": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.7.0.tgz", - "integrity": "sha512-c45jA3Jc1X8yJKzrWu1GpplBKGwv/wIV6ITZTlCSY7npF2YfJR+6nMP5e+NTQhUeJPSyOQAbGDCGEHbAl8HN9w==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.1.tgz", + "integrity": "sha512-3njoWAAhGBYy0tWBabqUQcLtczZUxrmmtc2vszQUekg3kTJyZ5/IeLC3Fo04u6y6Iy5Sba7pIIa2P/gs8D3ZeQ==", "requires": { "denque": "^2.1.0", "generate-function": "^2.3.1", diff --git a/backend/package.json b/backend/package.json index cd1255392..c42f455e5 100644 --- a/backend/package.json +++ b/backend/package.json @@ -47,7 +47,7 @@ "crypto-js": "~4.2.0", "express": "~4.18.2", "maxmind": "~4.3.11", - "mysql2": "~3.7.0", + "mysql2": "~3.9.1", "rust-gbt": "file:./rust-gbt", "redis": "^4.6.6", "socks-proxy-agent": "~7.0.0", 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 98095aa07..3698a3060 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 @@ -27,12 +27,6 @@ -
-
-
Total Bid Boost
-
-
-
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 c4b4335ee..e01beb350 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 @@ -53,11 +53,6 @@ padding-bottom: 55px; } } -.chart-widget { - width: 100%; - height: 100%; - max-height: 290px; -} h5 { margin-bottom: 10px; 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 d75cbba2d..c47232501 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,6 +1,6 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, Input, LOCALE_ID, OnDestroy, OnInit } from '@angular/core'; import { EChartsOption, graphic } from 'echarts'; -import { Observable, Subscription, combineLatest } from 'rxjs'; +import { Observable, Subscription, combineLatest, fromEvent } from 'rxjs'; import { map, max, startWith, switchMap, tap } from 'rxjs/operators'; import { ApiService } from '../../../services/api.service'; import { SeoService } from '../../../services/seo.service'; @@ -28,6 +28,7 @@ import { Acceleration } from '../../../interfaces/node-api.interface'; }) export class AccelerationFeesGraphComponent implements OnInit, OnDestroy { @Input() widget: boolean = false; + @Input() height: number | string = '200'; @Input() right: number | string = 45; @Input() left: number | string = 75; @Input() accelerations$: Observable; @@ -74,6 +75,7 @@ export class AccelerationFeesGraphComponent implements OnInit, OnDestroy { this.statsObservable$ = combineLatest([ (this.accelerations$ || this.apiService.getAccelerationHistory$({ timeframe: this.miningWindowPreference })), this.apiService.getHistoricalBlockFees$(this.miningWindowPreference), + fromEvent(window, 'resize').pipe(startWith(null)), ]).pipe( tap(([accelerations, blockFeesResponse]) => { this.prepareChartOptions(accelerations, blockFeesResponse.body); @@ -173,6 +175,7 @@ export class AccelerationFeesGraphComponent implements OnInit, OnDestroy { ], animation: false, grid: { + height: this.height, right: this.right, left: this.left, bottom: this.widget ? 30 : 80, 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 19d01e726..6d9e49265 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 @@ -37,6 +37,11 @@
+ +
Mempool Goggles: Accelerations
+   + +
@@ -48,7 +53,15 @@
- +
Total Bid Boost
+
+ +
diff --git a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.scss b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.scss index 145569342..d6fb57953 100644 --- a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.scss +++ b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.scss @@ -17,6 +17,16 @@ } } +.mempool-graph { + height: 295px; + @media (min-width: 768px) { + height: 325px; + } + @media (min-width: 992px) { + height: 400px; + } +} + .card-title { font-size: 1rem; color: #4a68b9; @@ -135,7 +145,12 @@ } .card { - height: 385px; + @media (min-width: 768px) { + height: 420px; + } + @media (min-width: 992px) { + height: 510px; + } } .list-card { height: 410px; @@ -145,7 +160,16 @@ } .mempool-block-wrapper { - max-height: 380px; - max-width: 380px; + max-height: 430px; + max-width: 430px; margin: auto; + + @media (min-width: 768px) { + max-height: 344px; + max-width: 344px; + } + @media (min-width: 992px) { + max-height: 430px; + max-width: 430px; + } } \ No newline at end of file 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 c39dbd253..07a513e7f 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 @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, HostListener, OnInit } from '@angular/core'; import { SeoService } from '../../../services/seo.service'; import { WebsocketService } from '../../../services/websocket.service'; import { Acceleration, BlockExtended } from '../../../interfaces/node-api.interface'; @@ -30,6 +30,8 @@ export class AcceleratorDashboardComponent implements OnInit { minedAccelerations$: Observable; loadingBlocks: boolean = true; + graphHeight: number = 300; + constructor( private seoService: SeoService, private websocketService: WebsocketService, @@ -40,6 +42,7 @@ export class AcceleratorDashboardComponent implements OnInit { } ngOnInit(): void { + this.onResize(); this.websocketService.want(['blocks', 'mempool-blocks', 'stats']); this.pendingAccelerations$ = interval(30000).pipe( @@ -121,4 +124,15 @@ export class AcceleratorDashboardComponent implements OnInit { return normalColors[feeLevelIndex] || normalColors[mempoolFeeColors.length - 1]; } } + + @HostListener('window:resize', ['$event']) + onResize(): void { + if (window.innerWidth >= 992) { + this.graphHeight = 330; + } else if (window.innerWidth >= 768) { + this.graphHeight = 245; + } else { + this.graphHeight = 210; + } + } } diff --git a/frontend/src/app/components/address-labels/address-labels.component.ts b/frontend/src/app/components/address-labels/address-labels.component.ts index f4b3d0ca5..2365c167f 100644 --- a/frontend/src/app/components/address-labels/address-labels.component.ts +++ b/frontend/src/app/components/address-labels/address-labels.component.ts @@ -43,7 +43,7 @@ export class AddressLabelsComponent implements OnChanges { handleVin() { if (this.vin.inner_witnessscript_asm) { - if (this.vin.inner_witnessscript_asm.indexOf('OP_DEPTH OP_PUSHNUM_12 OP_EQUAL OP_IF OP_PUSHNUM_11') === 0) { + if (this.vin.inner_witnessscript_asm.indexOf('OP_DEPTH OP_PUSHNUM_12 OP_EQUAL OP_IF OP_PUSHNUM_11') === 0 || this.vin.inner_witnessscript_asm.indexOf('OP_PUSHNUM_15 OP_CHECKMULTISIG OP_IFDUP OP_NOTIF OP_PUSHBYTES_2') === 1259) { if (this.vin.witness.length > 11) { this.label = 'Liquid Peg Out'; } else { diff --git a/frontend/src/app/components/address/address.component.ts b/frontend/src/app/components/address/address.component.ts index 0e10b207f..33cf3abf7 100644 --- a/frontend/src/app/components/address/address.component.ts +++ b/frontend/src/app/components/address/address.component.ts @@ -31,8 +31,7 @@ export class AddressComponent implements OnInit, OnDestroy { addressLoadingStatus$: Observable; addressInfo: null | AddressInformation = null; - totalConfirmedTxCount = 0; - loadedConfirmedTxCount = 0; + fullyLoaded = false; txCount = 0; received = 0; sent = 0; @@ -66,7 +65,7 @@ export class AddressComponent implements OnInit, OnDestroy { switchMap((params: ParamMap) => { this.error = undefined; this.isLoadingAddress = true; - this.loadedConfirmedTxCount = 0; + this.fullyLoaded = false; this.address = null; this.isLoadingTransactions = true; this.transactions = null; @@ -128,7 +127,6 @@ export class AddressComponent implements OnInit, OnDestroy { this.tempTransactions = transactions; if (transactions.length) { this.lastTransactionTxId = transactions[transactions.length - 1].txid; - this.loadedConfirmedTxCount += transactions.filter((tx) => tx.status.confirmed).length; } const fetchTxs: string[] = []; @@ -191,8 +189,6 @@ export class AddressComponent implements OnInit, OnDestroy { this.audioService.playSound('magic'); } } - this.totalConfirmedTxCount++; - this.loadedConfirmedTxCount++; }); } @@ -252,16 +248,19 @@ export class AddressComponent implements OnInit, OnDestroy { } loadMore() { - if (this.isLoadingTransactions || !this.totalConfirmedTxCount || this.loadedConfirmedTxCount >= this.totalConfirmedTxCount) { + if (this.isLoadingTransactions || this.fullyLoaded) { return; } this.isLoadingTransactions = true; this.retryLoadMore = false; this.electrsApiService.getAddressTransactions$(this.address.address, this.lastTransactionTxId) .subscribe((transactions: Transaction[]) => { - this.lastTransactionTxId = transactions[transactions.length - 1].txid; - this.loadedConfirmedTxCount += transactions.length; - this.transactions = this.transactions.concat(transactions); + if (transactions && transactions.length) { + this.lastTransactionTxId = transactions[transactions.length - 1].txid; + this.transactions = this.transactions.concat(transactions); + } else { + this.fullyLoaded = true; + } this.isLoadingTransactions = false; }, (error) => { @@ -278,7 +277,6 @@ export class AddressComponent implements OnInit, OnDestroy { this.received = this.address.chain_stats.funded_txo_sum + this.address.mempool_stats.funded_txo_sum; this.sent = this.address.chain_stats.spent_txo_sum + this.address.mempool_stats.spent_txo_sum; this.txCount = this.address.chain_stats.tx_count + this.address.mempool_stats.tx_count; - this.totalConfirmedTxCount = this.address.chain_stats.tx_count; } ngOnDestroy() { diff --git a/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts b/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts index d6000e27b..ac1df2bf5 100644 --- a/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts +++ b/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts @@ -42,6 +42,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On @Input() showFilters: boolean = false; @Input() excludeFilters: string[] = []; @Input() filterFlags: bigint | null = null; + @Input() filterMode: 'and' | 'or' = 'and'; @Input() blockConversion: Price; @Input() overrideColors: ((tx: TxView) => Color) | null = null; @Output() txClickEvent = new EventEmitter<{ tx: TransactionStripped, keyModifier: boolean}>(); @@ -113,7 +114,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On if (changes.overrideColor && this.scene) { this.scene.setColorFunction(this.overrideColors); } - if ((changes.filterFlags || changes.showFilters)) { + if ((changes.filterFlags || changes.showFilters || changes.filterMode)) { this.setFilterFlags(); } } @@ -121,8 +122,8 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On setFilterFlags(flags?: bigint | null): void { this.activeFilterFlags = this.filterFlags || flags || null; if (this.scene) { - if (flags != null) { - this.scene.setColorFunction(this.getFilterColorFunction(flags)); + if (this.activeFilterFlags != null) { + this.scene.setColorFunction(this.getFilterColorFunction(this.activeFilterFlags)); } else { this.scene.setColorFunction(this.overrideColors); } @@ -523,7 +524,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On getFilterColorFunction(flags: bigint): ((tx: TxView) => Color) { return (tx: TxView) => { - if ((tx.bigintFlags & flags) === flags) { + if ((this.filterMode === 'and' && (tx.bigintFlags & flags) === flags) || (this.filterMode === 'or' && (tx.bigintFlags & flags) > 0n)) { return defaultColorFunction(tx); } else { return defaultColorFunction( diff --git a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.html b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.html index 83f8a3a4c..f3d340472 100644 --- a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.html +++ b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.html @@ -54,7 +54,7 @@
-
diff --git a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.scss b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.scss index 886608573..32885d5de 100644 --- a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.scss +++ b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.scss @@ -57,8 +57,6 @@ } .chart-widget { width: 100%; - height: 100%; - height: 240px; } .pool-distribution { diff --git a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts index 9858807a6..2bda9a35a 100644 --- a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts +++ b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit, HostBinding } from '@angular/core'; import { echarts, EChartsOption } from '../../graphs/echarts'; -import { merge, Observable, of } from 'rxjs'; +import { combineLatest, fromEvent, merge, Observable, of } from 'rxjs'; import { map, mergeMap, share, startWith, switchMap, tap } from 'rxjs/operators'; import { ApiService } from '../../services/api.service'; import { SeoService } from '../../services/seo.service'; @@ -31,6 +31,7 @@ import { seoDescriptionNetwork } from '../../shared/common.utils'; export class HashrateChartComponent implements OnInit { @Input() tableOnly = false; @Input() widget = false; + @Input() height: number = 300; @Input() right: number | string = 45; @Input() left: number | string = 75; @@ -86,28 +87,32 @@ export class HashrateChartComponent implements OnInit { } }); - this.hashrateObservable$ = merge( - this.radioGroupForm.get('dateSpan').valueChanges - .pipe( - startWith(this.radioGroupForm.controls.dateSpan.value), - switchMap((timespan) => { - if (!this.widget && !firstRun) { - this.storageService.setValue('miningWindowPreference', timespan); - } - this.timespan = timespan; - firstRun = false; - this.miningWindowPreference = timespan; - this.isLoading = true; - return this.apiService.getHistoricalHashrate$(this.timespan); - }) - ), - this.stateService.chainTip$ + this.hashrateObservable$ = combineLatest( + merge( + this.radioGroupForm.get('dateSpan').valueChanges .pipe( - switchMap(() => { + startWith(this.radioGroupForm.controls.dateSpan.value), + switchMap((timespan) => { + if (!this.widget && !firstRun) { + this.storageService.setValue('miningWindowPreference', timespan); + } + this.timespan = timespan; + firstRun = false; + this.miningWindowPreference = timespan; + this.isLoading = true; return this.apiService.getHistoricalHashrate$(this.timespan); }) - ) + ), + this.stateService.chainTip$ + .pipe( + switchMap(() => { + return this.apiService.getHistoricalHashrate$(this.timespan); + }) + ) + ), + fromEvent(window, 'resize').pipe(startWith(null)), ).pipe( + map(([response, _]) => response), tap((response: any) => { const data = response.body; @@ -221,6 +226,7 @@ export class HashrateChartComponent implements OnInit { ]), ], grid: { + height: (this.widget && this.height) ? this.height - 30 : undefined, top: this.widget ? 20 : 40, bottom: this.widget ? 30 : 70, right: this.right, diff --git a/frontend/src/app/components/mempool-block-overview/mempool-block-overview.component.html b/frontend/src/app/components/mempool-block-overview/mempool-block-overview.component.html index 85e7eebb1..7cc458e60 100644 --- a/frontend/src/app/components/mempool-block-overview/mempool-block-overview.component.html +++ b/frontend/src/app/components/mempool-block-overview/mempool-block-overview.component.html @@ -1,11 +1,13 @@ diff --git a/frontend/src/app/components/mempool-block-overview/mempool-block-overview.component.ts b/frontend/src/app/components/mempool-block-overview/mempool-block-overview.component.ts index 8dad6a9c1..7fb036718 100644 --- a/frontend/src/app/components/mempool-block-overview/mempool-block-overview.component.ts +++ b/frontend/src/app/components/mempool-block-overview/mempool-block-overview.component.ts @@ -18,8 +18,11 @@ import TxView from '../block-overview-graph/tx-view'; }) export class MempoolBlockOverviewComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit { @Input() index: number; + @Input() resolution = 86; @Input() showFilters: boolean = false; @Input() overrideColors: ((tx: TxView) => Color) | null = null; + @Input() filterFlags: bigint | undefined = undefined; + @Input() filterMode: 'and' | 'or' = 'and'; @Output() txPreviewEvent = new EventEmitter(); @ViewChild('blockGraph') blockGraph: BlockOverviewGraphComponent; diff --git a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html index fd6e045dc..c4fca72eb 100644 --- a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html +++ b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html @@ -26,9 +26,11 @@
-
+
- +
+ +
@@ -38,7 +40,9 @@
- +
+ +
diff --git a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.scss b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.scss index 4f01f7cad..310b9e9de 100644 --- a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.scss +++ b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.scss @@ -17,6 +17,19 @@ } } +.fixed-mempool-graph { + height: 330px; +} + +.mempool-graph, .fixed-mempool-graph { + @media (min-width: 768px) { + height: 345px; + } + @media (min-width: 992px) { + height: 472px; + } +} + .card-title { font-size: 1rem; color: #4a68b9; diff --git a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.ts b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.ts index b3b2093ce..1a446d673 100644 --- a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.ts +++ b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { AfterViewInit, ChangeDetectionStrategy, Component, HostListener, OnInit } from '@angular/core'; import { SeoService } from '../../services/seo.service'; import { WebsocketService } from '../../services/websocket.service'; import { StateService } from '../../services/state.service'; @@ -11,6 +11,8 @@ import { EventType, NavigationStart, Router } from '@angular/router'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class MiningDashboardComponent implements OnInit, AfterViewInit { + graphHeight = 300; + constructor( private seoService: SeoService, private websocketService: WebsocketService, @@ -22,6 +24,7 @@ export class MiningDashboardComponent implements OnInit, AfterViewInit { } ngOnInit(): void { + this.onResize(); this.websocketService.want(['blocks', 'mempool-blocks', 'stats']); } @@ -35,4 +38,15 @@ export class MiningDashboardComponent implements OnInit, AfterViewInit { } }); } + + @HostListener('window:resize', ['$event']) + onResize(): void { + if (window.innerWidth >= 992) { + this.graphHeight = 340; + } else if (window.innerWidth >= 768) { + this.graphHeight = 245; + } else { + this.graphHeight = 240; + } + } } 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 19ccaccdd..85dd16152 100644 --- a/frontend/src/app/components/pool-ranking/pool-ranking.component.html +++ b/frontend/src/app/components/pool-ranking/pool-ranking.component.html @@ -76,7 +76,7 @@
-
diff --git a/frontend/src/app/components/pool-ranking/pool-ranking.component.scss b/frontend/src/app/components/pool-ranking/pool-ranking.component.scss index 970b3a8ea..f5a49678b 100644 --- a/frontend/src/app/components/pool-ranking/pool-ranking.component.scss +++ b/frontend/src/app/components/pool-ranking/pool-ranking.component.scss @@ -28,7 +28,9 @@ .chart-widget { width: 100%; height: 100%; - height: 240px; + @media (max-width: 767px) { + max-height: 240px; + } @media (max-width: 485px) { max-height: 200px; } 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 392cdf8c5..f7b91e151 100644 --- a/frontend/src/app/components/pool-ranking/pool-ranking.component.ts +++ b/frontend/src/app/components/pool-ranking/pool-ranking.component.ts @@ -20,6 +20,7 @@ import { isMobile } from '../../shared/common.utils'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class PoolRankingComponent implements OnInit { + @Input() height: number = 300; @Input() widget = false; miningWindowPreference: string; diff --git a/frontend/src/app/dashboard/dashboard.component.html b/frontend/src/app/dashboard/dashboard.component.html index 1cb2fadd1..16c1af36d 100644 --- a/frontend/src/app/dashboard/dashboard.component.html +++ b/frontend/src/app/dashboard/dashboard.component.html @@ -16,23 +16,34 @@
-
-
- -
-
+
- -
- + +
Mempool Goggles: {{ goggleCycle[goggleIndex].name }}
+   + +
+
+
+
- +
+
+ +
+
+ +
+
@@ -41,9 +52,21 @@
- -
-
+ + +
Incoming Transactions
+
+ +
+
+
+
@@ -60,15 +83,6 @@
- -
- -
-
@@ -287,19 +301,3 @@
- - -
Incoming Transactions
- - -  Backend is synchronizing ({{ mempoolLoadingStatus$ | async }}%) - - -
-
 
-
‎{{ mempoolInfoData.value.vBytesPerSecond | ceil | number }} vB/s
-
‎{{ mempoolInfoData.value.vBytesPerSecond * 4 | ceil | number }} WU/s
-
-
-
-
diff --git a/frontend/src/app/dashboard/dashboard.component.scss b/frontend/src/app/dashboard/dashboard.component.scss index 2b319c425..9bd44ea29 100644 --- a/frontend/src/app/dashboard/dashboard.component.scss +++ b/frontend/src/app/dashboard/dashboard.component.scss @@ -44,8 +44,11 @@ .graph-card { height: 100%; + @media (min-width: 768px) { + height: 415px; + } @media (min-width: 992px) { - height: 385px; + height: 510px; } } @@ -258,6 +261,12 @@ .mempool-graph { height: 255px; + @media (min-width: 768px) { + height: 285px; + } + @media (min-width: 992px) { + height: 370px; + } } .loadingGraphs{ height: 250px; @@ -364,3 +373,39 @@ text-decoration: none; color: inherit; } + +.mempool-block-wrapper { + max-height: 410px; + max-width: 410px; + margin: auto; + + @media (min-width: 768px) { + max-height: 344px; + max-width: 344px; + } + @media (min-width: 992px) { + max-height: 410px; + max-width: 410px; + } +} + +.goggle-badge { + margin: 6px 5px 8px; + background: none; + border: solid 2px #105fb0; + cursor: pointer; + + &.active { + background: #105fb0; + } +} + +.btn-xs { + padding: 0.35rem 0.5rem; + font-size: 12px; +} + +.quick-filter { + margin-top: 5px; + margin-bottom: 6px; +} diff --git a/frontend/src/app/dashboard/dashboard.component.ts b/frontend/src/app/dashboard/dashboard.component.ts index 6e65f2332..c762d309f 100644 --- a/frontend/src/app/dashboard/dashboard.component.ts +++ b/frontend/src/app/dashboard/dashboard.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; +import { AfterViewInit, ChangeDetectionStrategy, Component, HostListener, OnDestroy, OnInit } from '@angular/core'; import { combineLatest, EMPTY, merge, Observable, of, Subject, Subscription, timer } from 'rxjs'; import { catchError, delayWhen, filter, map, scan, share, shareReplay, startWith, switchMap, takeUntil, tap, throttleTime } from 'rxjs/operators'; import { AuditStatus, BlockExtended, CurrentPegs, OptimizedMempoolStats } from '../interfaces/node-api.interface'; @@ -54,12 +54,23 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit { currentReserves$: Observable; fullHistory$: Observable; isLoad: boolean = true; + mempoolInfoSubscription: Subscription; currencySubscription: Subscription; currency: string; + incomingGraphHeight: number = 300; private lastPegBlockUpdate: number = 0; private lastPegAmount: string = ''; private lastReservesBlockUpdate: number = 0; + goggleResolution = 82; + goggleCycle = [ + { index: 0, name: 'All' }, + { index: 1, name: 'Consolidations', flag: 0b00000010_00000000_00000000_00000000_00000000n }, + { index: 2, name: 'Coinjoin', flag: 0b00000001_00000000_00000000_00000000_00000000n }, + { index: 3, name: '💩', flag: 0b00000100_00000000_00000000_00000000n | 0b00000010_00000000_00000000_00000000n | 0b00000001_00000000_00000000_00000000n }, + ]; + goggleIndex = 0; // Math.floor(Math.random() * this.goggleCycle.length); + private destroy$ = new Subject(); constructor( @@ -74,6 +85,7 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit { } ngOnDestroy(): void { + this.mempoolInfoSubscription.unsubscribe(); this.currencySubscription.unsubscribe(); this.websocketService.stopTrackRbfSummary(); this.destroy$.next(1); @@ -81,6 +93,7 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit { } ngOnInit(): void { + this.onResize(); this.isLoadingWebSocket$ = this.stateService.isLoadingWebSocket$; this.seoService.resetTitle(); this.seoService.resetDescription(); @@ -95,36 +108,37 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit { this.mempoolInfoData$ = combineLatest([ this.stateService.mempoolInfo$, this.stateService.vbytesPerSecond$ - ]) - .pipe( - map(([mempoolInfo, vbytesPerSecond]) => { - const percent = Math.round((Math.min(vbytesPerSecond, this.vBytesPerSecondLimit) / this.vBytesPerSecondLimit) * 100); + ]).pipe( + map(([mempoolInfo, vbytesPerSecond]) => { + const percent = Math.round((Math.min(vbytesPerSecond, this.vBytesPerSecondLimit) / this.vBytesPerSecondLimit) * 100); - let progressColor = 'bg-success'; - if (vbytesPerSecond > 1667) { - progressColor = 'bg-warning'; - } - if (vbytesPerSecond > 3000) { - progressColor = 'bg-danger'; - } + let progressColor = 'bg-success'; + if (vbytesPerSecond > 1667) { + progressColor = 'bg-warning'; + } + if (vbytesPerSecond > 3000) { + progressColor = 'bg-danger'; + } - const mempoolSizePercentage = (mempoolInfo.usage / mempoolInfo.maxmempool * 100); - let mempoolSizeProgress = 'bg-danger'; - if (mempoolSizePercentage <= 50) { - mempoolSizeProgress = 'bg-success'; - } else if (mempoolSizePercentage <= 75) { - mempoolSizeProgress = 'bg-warning'; - } + const mempoolSizePercentage = (mempoolInfo.usage / mempoolInfo.maxmempool * 100); + let mempoolSizeProgress = 'bg-danger'; + if (mempoolSizePercentage <= 50) { + mempoolSizeProgress = 'bg-success'; + } else if (mempoolSizePercentage <= 75) { + mempoolSizeProgress = 'bg-warning'; + } - return { - memPoolInfo: mempoolInfo, - vBytesPerSecond: vbytesPerSecond, - progressWidth: percent + '%', - progressColor: progressColor, - mempoolSizeProgress: mempoolSizeProgress, - }; - }) - ); + return { + memPoolInfo: mempoolInfo, + vBytesPerSecond: vbytesPerSecond, + progressWidth: percent + '%', + progressColor: progressColor, + mempoolSizeProgress: mempoolSizeProgress, + }; + }) + ); + + this.mempoolInfoSubscription = this.mempoolInfoData$.subscribe(); this.mempoolBlocksData$ = this.stateService.mempoolBlocks$ .pipe( @@ -347,4 +361,18 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit { trackByBlock(index: number, block: BlockExtended) { return block.height; } + + @HostListener('window:resize', ['$event']) + onResize(): void { + if (window.innerWidth >= 992) { + this.incomingGraphHeight = 300; + this.goggleResolution = 82; + } else if (window.innerWidth >= 768) { + this.incomingGraphHeight = 215; + this.goggleResolution = 80; + } else { + this.incomingGraphHeight = 180; + this.goggleResolution = 86; + } + } } diff --git a/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.html b/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.html index 89059185e..ec59b7432 100644 --- a/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.html +++ b/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.html @@ -34,9 +34,11 @@
-
+
- +
+ +
@@ -44,11 +46,13 @@
-
+
-
Lightning Network History
- - +
+
Lightning Network History
+ + +
diff --git a/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.scss b/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.scss index e91f7606a..052ea6227 100644 --- a/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.scss +++ b/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.scss @@ -20,6 +20,19 @@ } } +.fixed-mempool-graph { + height: 330px; +} + +.mempool-graph, .fixed-mempool-graph { + @media (min-width: 768px) { + height: 345px; + } + @media (min-width: 992px) { + height: 442px; + } +} + .card-title { font-size: 1rem; color: #4a68b9; diff --git a/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.ts b/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.ts index dece98ddb..63cdab42d 100644 --- a/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.ts +++ b/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { AfterViewInit, ChangeDetectionStrategy, Component, HostListener, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; import { share } from 'rxjs/operators'; import { INodesRanking, INodesStatistics } from '../../interfaces/node-api.interface'; @@ -16,6 +16,7 @@ export class LightningDashboardComponent implements OnInit, AfterViewInit { statistics$: Observable; nodesRanking$: Observable; officialMempoolSpace = this.stateService.env.OFFICIAL_MEMPOOL_SPACE; + graphHeight: number = 300; constructor( private lightningApiService: LightningApiService, @@ -24,6 +25,8 @@ export class LightningDashboardComponent implements OnInit, AfterViewInit { ) { } ngOnInit(): void { + this.onResize(); + this.seoService.setTitle($localize`:@@142e923d3b04186ac6ba23387265d22a2fa404e0:Lightning Explorer`); this.seoService.setDescription($localize`:@@meta.description.lightning.dashboard:Get stats on the Lightning network (aggregate capacity, connectivity, etc), Lightning nodes (channels, liquidity, etc) and Lightning channels (status, fees, etc).`); @@ -34,4 +37,15 @@ export class LightningDashboardComponent implements OnInit, AfterViewInit { ngAfterViewInit(): void { this.stateService.focusSearchInputDesktop(); } + + @HostListener('window:resize', ['$event']) + onResize(): void { + if (window.innerWidth >= 992) { + this.graphHeight = 340; + } else if (window.innerWidth >= 768) { + this.graphHeight = 245; + } else { + this.graphHeight = 210; + } + } } diff --git a/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.html b/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.html index 908b98fda..915f2f7ec 100644 --- a/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.html +++ b/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.html @@ -35,7 +35,7 @@
-
+
diff --git a/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.scss b/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.scss index 0e6fb056d..aaea41265 100644 --- a/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.scss +++ b/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.scss @@ -56,7 +56,6 @@ } .chart-widget { width: 100%; - height: 145px; } .pool-distribution { diff --git a/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts b/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts index 30f786b16..82c74395b 100644 --- a/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts +++ b/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit, HostBinding } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit, HostBinding, OnChanges, SimpleChanges } from '@angular/core'; import { echarts, EChartsOption, LineSeriesOption } from '../../graphs/echarts'; import { Observable } from 'rxjs'; import { map, share, startWith, switchMap, tap } from 'rxjs/operators'; @@ -26,7 +26,8 @@ import { isMobile } from '../../shared/common.utils'; `], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class NodesNetworksChartComponent implements OnInit { +export class NodesNetworksChartComponent implements OnInit, OnChanges { + @Input() height: number = 150; @Input() right: number | string = 45; @Input() left: number | string = 45; @Input() widget = false; @@ -47,6 +48,9 @@ export class NodesNetworksChartComponent implements OnInit { timespan = ''; chartInstance: any = undefined; + chartData: any; + maxYAxis: number; + constructor( @Inject(LOCALE_ID) public locale: string, private seoService: SeoService, @@ -71,44 +75,49 @@ export class NodesNetworksChartComponent implements OnInit { this.radioGroupForm = this.formBuilder.group({ dateSpan: this.miningWindowPreference }); this.radioGroupForm.controls.dateSpan.setValue(this.miningWindowPreference); - this.nodesNetworkObservable$ = this.radioGroupForm.get('dateSpan').valueChanges - .pipe( - startWith(this.miningWindowPreference), - switchMap((timespan) => { - this.timespan = timespan; - if (!this.widget && !firstRun) { - this.storageService.setValue('lightningWindowPreference', timespan); - } - firstRun = false; - this.miningWindowPreference = timespan; - this.isLoading = true; - return this.lightningApiService.cachedRequest(this.lightningApiService.listStatistics$, 250, timespan) - .pipe( - tap((response:any) => { - const data = response.body; - const chartData = { - tor_nodes: data.map(val => [val.added * 1000, val.tor_nodes]), - clearnet_nodes: data.map(val => [val.added * 1000, val.clearnet_nodes]), - unannounced_nodes: data.map(val => [val.added * 1000, val.unannounced_nodes]), - clearnet_tor_nodes: data.map(val => [val.added * 1000, val.clearnet_tor_nodes]), - }; - let maxYAxis = 0; - for (const day of data) { - maxYAxis = Math.max(maxYAxis, day.tor_nodes + day.clearnet_nodes + day.unannounced_nodes + day.clearnet_tor_nodes); - } - maxYAxis = Math.ceil(maxYAxis / 3000) * 3000; - this.prepareChartOptions(chartData, maxYAxis); - this.isLoading = false; - }), - map((response) => { - return { - days: parseInt(response.headers.get('x-total-count'), 10), - }; - }), - ); - }), - share() - ); + this.nodesNetworkObservable$ = this.radioGroupForm.get('dateSpan').valueChanges.pipe( + startWith(this.miningWindowPreference), + switchMap((timespan) => { + this.timespan = timespan; + if (!this.widget && !firstRun) { + this.storageService.setValue('lightningWindowPreference', timespan); + } + firstRun = false; + this.miningWindowPreference = timespan; + this.isLoading = true; + return this.lightningApiService.cachedRequest(this.lightningApiService.listStatistics$, 250, timespan) + .pipe( + tap((response:any) => { + const data = response.body; + this.chartData = { + tor_nodes: data.map(val => [val.added * 1000, val.tor_nodes]), + clearnet_nodes: data.map(val => [val.added * 1000, val.clearnet_nodes]), + unannounced_nodes: data.map(val => [val.added * 1000, val.unannounced_nodes]), + clearnet_tor_nodes: data.map(val => [val.added * 1000, val.clearnet_tor_nodes]), + }; + this.maxYAxis = 0; + for (const day of data) { + this.maxYAxis = Math.max(this.maxYAxis, day.tor_nodes + day.clearnet_nodes + day.unannounced_nodes + day.clearnet_tor_nodes); + } + this.maxYAxis = Math.ceil(this.maxYAxis / 3000) * 3000; + this.prepareChartOptions(this.chartData, this.maxYAxis); + this.isLoading = false; + }), + map((response) => { + return { + days: parseInt(response.headers.get('x-total-count'), 10), + }; + }), + ); + }), + share() + ); + } + + ngOnChanges(changes: SimpleChanges): void { + if (changes.height && this.chartData && this.maxYAxis != null) { + this.prepareChartOptions(this.chartData, this.maxYAxis); + } } prepareChartOptions(data, maxYAxis): void { @@ -228,7 +237,7 @@ export class NodesNetworksChartComponent implements OnInit { title: title, animation: false, grid: { - height: this.widget ? 90 : undefined, + height: this.widget ? ((this.height || 120) - 60) : undefined, top: this.widget ? 20 : 40, bottom: this.widget ? 0 : 70, right: (isMobile() && this.widget) ? 35 : this.right, diff --git a/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html b/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html index 259c3503a..794ced684 100644 --- a/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html +++ b/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html @@ -39,7 +39,7 @@
-
diff --git a/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts b/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts index 5342f616b..3d8a4b861 100644 --- a/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts +++ b/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts @@ -18,6 +18,7 @@ import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pi changeDetection: ChangeDetectionStrategy.OnPush, }) export class NodesPerISPChartComponent implements OnInit { + @Input() height: number = 300; @Input() widget: boolean = false; isLoading = true; diff --git a/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.html b/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.html index 68fe3ee64..9bb88ac59 100644 --- a/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.html +++ b/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.html @@ -42,7 +42,7 @@
-
diff --git a/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.scss b/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.scss index c885e4839..923a8a3e4 100644 --- a/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.scss +++ b/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.scss @@ -56,7 +56,6 @@ } .chart-widget { width: 100%; - height: 145px; } .pool-distribution { diff --git a/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.ts b/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.ts index 0e4f66ca0..8bcf01015 100644 --- a/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.ts +++ b/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.ts @@ -1,6 +1,6 @@ -import { Component, Inject, Input, LOCALE_ID, OnInit, HostBinding } from '@angular/core'; +import { Component, Inject, Input, LOCALE_ID, OnInit, HostBinding, OnChanges, SimpleChanges } from '@angular/core'; import { echarts, EChartsOption } from '../../graphs/echarts'; -import { Observable } from 'rxjs'; +import { Observable, combineLatest, fromEvent } from 'rxjs'; import { map, share, startWith, switchMap, tap } from 'rxjs/operators'; import { SeoService } from '../../services/seo.service'; import { formatNumber } from '@angular/common'; @@ -25,7 +25,8 @@ import { isMobile } from '../../shared/common.utils'; } `], }) -export class LightningStatisticsChartComponent implements OnInit { +export class LightningStatisticsChartComponent implements OnInit, OnChanges { + @Input() height: number = 150; @Input() right: number | string = 45; @Input() left: number | string = 45; @Input() widget = false; @@ -37,6 +38,7 @@ export class LightningStatisticsChartComponent implements OnInit { chartInitOptions = { renderer: 'svg', }; + chartData: any; @HostBinding('attr.dir') dir = 'ltr'; @@ -70,36 +72,42 @@ export class LightningStatisticsChartComponent implements OnInit { this.radioGroupForm = this.formBuilder.group({ dateSpan: this.miningWindowPreference }); this.radioGroupForm.controls.dateSpan.setValue(this.miningWindowPreference); - this.capacityObservable$ = this.radioGroupForm.get('dateSpan').valueChanges - .pipe( - startWith(this.miningWindowPreference), - switchMap((timespan) => { - this.timespan = timespan; - if (!this.widget && !firstRun) { - this.storageService.setValue('lightningWindowPreference', timespan); - } - firstRun = false; - this.miningWindowPreference = timespan; - this.isLoading = true; - return this.lightningApiService.cachedRequest(this.lightningApiService.listStatistics$, 250, timespan) - .pipe( - tap((response:any) => { - const data = response.body; - this.prepareChartOptions({ - channel_count: data.map(val => [val.added * 1000, val.channel_count]), - capacity: data.map(val => [val.added * 1000, val.total_capacity]), - }); - this.isLoading = false; - }), - map((response) => { - return { - days: parseInt(response.headers.get('x-total-count'), 10), - }; - }), - ); - }), - share(), - ); + this.capacityObservable$ = this.radioGroupForm.get('dateSpan').valueChanges.pipe( + startWith(this.miningWindowPreference), + switchMap((timespan) => { + this.timespan = timespan; + if (!this.widget && !firstRun) { + this.storageService.setValue('lightningWindowPreference', timespan); + } + firstRun = false; + this.miningWindowPreference = timespan; + this.isLoading = true; + return this.lightningApiService.cachedRequest(this.lightningApiService.listStatistics$, 250, timespan) + .pipe( + tap((response:any) => { + const data = response.body; + this.chartData = { + channel_count: data.map(val => [val.added * 1000, val.channel_count]), + capacity: data.map(val => [val.added * 1000, val.total_capacity]), + }; + this.prepareChartOptions(this.chartData); + this.isLoading = false; + }), + map((response) => { + return { + days: parseInt(response.headers.get('x-total-count'), 10), + }; + }), + ); + }), + share(), + ); + } + + ngOnChanges(changes: SimpleChanges): void { + if (changes.height && this.chartData) { + this.prepareChartOptions(this.chartData); + } } prepareChartOptions(data): void { @@ -138,7 +146,7 @@ export class LightningStatisticsChartComponent implements OnInit { ]), ], grid: { - height: this.widget ? 90 : undefined, + height: this.widget ? ((this.height || 120) - 60) : undefined, top: this.widget ? 20 : 40, bottom: this.widget ? 0 : 70, right: (isMobile() && this.widget) ? 35 : this.right,