mirror of
https://github.com/mempool/mempool.git
synced 2025-02-22 14:22:44 +01:00
Reversible mempool block visualization
This commit is contained in:
parent
03c6a7c54f
commit
135fbfc4f3
4 changed files with 51 additions and 10 deletions
|
@ -1,4 +1,4 @@
|
|||
import { Component, ElementRef, ViewChild, HostListener, Input, Output, EventEmitter, NgZone, AfterViewInit, OnDestroy } from '@angular/core';
|
||||
import { Component, ElementRef, ViewChild, HostListener, Input, Output, EventEmitter, NgZone, AfterViewInit, OnDestroy, OnChanges } from '@angular/core';
|
||||
import { TransactionStripped } from '../../interfaces/websocket.interface';
|
||||
import { FastVertexArray } from './fast-vertex-array';
|
||||
import BlockScene from './block-scene';
|
||||
|
@ -11,7 +11,7 @@ import { Position } from './sprite-types';
|
|||
templateUrl: './block-overview-graph.component.html',
|
||||
styleUrls: ['./block-overview-graph.component.scss'],
|
||||
})
|
||||
export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy {
|
||||
export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, OnChanges {
|
||||
@Input() isLoading: boolean;
|
||||
@Input() resolution: number;
|
||||
@Input() blockLimit: number;
|
||||
|
@ -57,6 +57,14 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy {
|
|||
this.resizeCanvas();
|
||||
}
|
||||
|
||||
ngOnChanges(changes): void {
|
||||
if (changes.orientation || changes.flip) {
|
||||
if (this.scene) {
|
||||
this.scene.setOrientation(this.orientation, this.flip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.animationFrameRequest) {
|
||||
cancelAnimationFrame(this.animationFrameRequest);
|
||||
|
|
|
@ -42,6 +42,24 @@ export default class BlockScene {
|
|||
}
|
||||
}
|
||||
|
||||
setOrientation(orientation: string, flip: boolean): void {
|
||||
this.orientation = orientation;
|
||||
this.flip = flip;
|
||||
this.dirty = true;
|
||||
const startTime = performance.now();
|
||||
Object.values(this.txs).forEach(txView => {
|
||||
this.saveGridToScreenPosition(txView);
|
||||
this.applyTxUpdate(txView, {
|
||||
display: {
|
||||
position: txView.screenPosition,
|
||||
color: txView.getColor()
|
||||
},
|
||||
duration: 0
|
||||
});
|
||||
this.setTxOnScreen(txView, startTime, 0);
|
||||
});
|
||||
}
|
||||
|
||||
// Destroy the current layout and clean up graphics sprites without any exit animation
|
||||
destroy(): void {
|
||||
Object.values(this.txs).forEach(tx => tx.destroy());
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
[isLoading]="isLoading$ | async"
|
||||
[resolution]="75"
|
||||
[blockLimit]="stateService.blockVSize"
|
||||
[orientation]="'left'"
|
||||
[orientation]="timeLtr ? 'right' : 'left'"
|
||||
[flip]="true"
|
||||
(txClickEvent)="onTxClick($event)"
|
||||
></app-block-overview-graph>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Component, ComponentRef, ViewChild, HostListener, Input, Output, EventEmitter,
|
||||
OnDestroy, OnChanges, ChangeDetectionStrategy, AfterViewInit } from '@angular/core';
|
||||
OnInit, OnDestroy, OnChanges, ChangeDetectionStrategy, ChangeDetectorRef, AfterViewInit } from '@angular/core';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { MempoolBlockDelta, TransactionStripped } from '../../interfaces/websocket.interface';
|
||||
import { BlockOverviewGraphComponent } from '../../components/block-overview-graph/block-overview-graph.component';
|
||||
|
@ -14,7 +14,7 @@ import { Router } from '@angular/router';
|
|||
templateUrl: './mempool-block-overview.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class MempoolBlockOverviewComponent implements OnDestroy, OnChanges, AfterViewInit {
|
||||
export class MempoolBlockOverviewComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit {
|
||||
@Input() index: number;
|
||||
@Output() txPreviewEvent = new EventEmitter<TransactionStripped | void>();
|
||||
|
||||
|
@ -23,6 +23,10 @@ export class MempoolBlockOverviewComponent implements OnDestroy, OnChanges, Afte
|
|||
lastBlockHeight: number;
|
||||
blockIndex: number;
|
||||
isLoading$ = new BehaviorSubject<boolean>(true);
|
||||
timeLtrSubscription: Subscription;
|
||||
timeLtr: boolean;
|
||||
chainDirection: string = 'right';
|
||||
poolDirection: string = 'left';
|
||||
|
||||
blockSub: Subscription;
|
||||
deltaSub: Subscription;
|
||||
|
@ -31,8 +35,18 @@ export class MempoolBlockOverviewComponent implements OnDestroy, OnChanges, Afte
|
|||
public stateService: StateService,
|
||||
private websocketService: WebsocketService,
|
||||
private router: Router,
|
||||
private cd: ChangeDetectorRef,
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.timeLtrSubscription = this.stateService.timeLtr.subscribe((ltr) => {
|
||||
this.timeLtr = !!ltr;
|
||||
this.chainDirection = ltr ? 'left' : 'right';
|
||||
this.poolDirection = ltr ? 'right' : 'left';
|
||||
this.cd.markForCheck();
|
||||
});
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.blockSub = merge(
|
||||
of(true),
|
||||
|
@ -50,7 +64,7 @@ export class MempoolBlockOverviewComponent implements OnDestroy, OnChanges, Afte
|
|||
ngOnChanges(changes): void {
|
||||
if (changes.index) {
|
||||
if (this.blockGraph) {
|
||||
this.blockGraph.clear(changes.index.currentValue > changes.index.previousValue ? 'right' : 'left');
|
||||
this.blockGraph.clear(changes.index.currentValue > changes.index.previousValue ? this.chainDirection : this.poolDirection);
|
||||
}
|
||||
this.isLoading$.next(true);
|
||||
this.websocketService.startTrackMempoolBlock(changes.index.currentValue);
|
||||
|
@ -60,16 +74,17 @@ export class MempoolBlockOverviewComponent implements OnDestroy, OnChanges, Afte
|
|||
ngOnDestroy(): void {
|
||||
this.blockSub.unsubscribe();
|
||||
this.deltaSub.unsubscribe();
|
||||
this.timeLtrSubscription.unsubscribe();
|
||||
this.websocketService.stopTrackMempoolBlock();
|
||||
}
|
||||
|
||||
replaceBlock(transactionsStripped: TransactionStripped[]): void {
|
||||
const blockMined = (this.stateService.latestBlockHeight > this.lastBlockHeight);
|
||||
if (this.blockIndex !== this.index) {
|
||||
const direction = (this.blockIndex == null || this.index < this.blockIndex) ? 'left' : 'right';
|
||||
const direction = (this.blockIndex == null || this.index < this.blockIndex) ? this.poolDirection : this.chainDirection;
|
||||
this.blockGraph.enter(transactionsStripped, direction);
|
||||
} else {
|
||||
this.blockGraph.replace(transactionsStripped, blockMined ? 'right' : 'left');
|
||||
this.blockGraph.replace(transactionsStripped, blockMined ? this.chainDirection : this.poolDirection);
|
||||
}
|
||||
|
||||
this.lastBlockHeight = this.stateService.latestBlockHeight;
|
||||
|
@ -81,10 +96,10 @@ export class MempoolBlockOverviewComponent implements OnDestroy, OnChanges, Afte
|
|||
const blockMined = (this.stateService.latestBlockHeight > this.lastBlockHeight);
|
||||
|
||||
if (this.blockIndex !== this.index) {
|
||||
const direction = (this.blockIndex == null || this.index < this.blockIndex) ? 'left' : 'right';
|
||||
const direction = (this.blockIndex == null || this.index < this.blockIndex) ? this.poolDirection : this.chainDirection;
|
||||
this.blockGraph.replace(delta.added, direction);
|
||||
} else {
|
||||
this.blockGraph.update(delta.added, delta.removed, blockMined ? 'right' : 'left', blockMined);
|
||||
this.blockGraph.update(delta.added, delta.removed, blockMined ? this.chainDirection : this.poolDirection, blockMined);
|
||||
}
|
||||
|
||||
this.lastBlockHeight = this.stateService.latestBlockHeight;
|
||||
|
|
Loading…
Add table
Reference in a new issue