Add sankey diagram to main tx page
This commit is contained in:
		
							parent
							
								
									5e1ca44a7f
								
							
						
					
					
						commit
						1e5cef4a62
					
				@ -190,6 +190,24 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <br>
 | 
					    <br>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div class="title">
 | 
				
			||||||
 | 
					      <h2 i18n="transaction.diagram|Transaction diagram">Diagram</h2>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div class="box">
 | 
				
			||||||
 | 
					      <div class="graph-container" #graphContainer>
 | 
				
			||||||
 | 
					        <tx-bowtie-graph [tx]="tx" [width]="graphWidth" [height]="graphExpanded ? (maxInOut * 15) : 360" [maxStrands]="graphExpanded ? maxInOut : 24" [network]="network"></tx-bowtie-graph>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="toggle-wrapper" *ngIf="maxInOut > 24">
 | 
				
			||||||
 | 
					        <button class="btn btn-sm btn-primary graph-toggle" (click)="expandGraph();" *ngIf="!graphExpanded; else collapseBtn"><span i18n="show-more">Show more</span></button>
 | 
				
			||||||
 | 
					        <ng-template #collapseBtn>
 | 
				
			||||||
 | 
					          <button class="btn btn-sm btn-primary graph-toggle" (click)="collapseGraph();"><span i18n="show-less">Show less</span></button>
 | 
				
			||||||
 | 
					        </ng-template>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <br>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <div class="title float-left">
 | 
					    <div class="title float-left">
 | 
				
			||||||
      <h2 i18n="transaction.inputs-and-outputs|Transaction inputs and outputs">Inputs & Outputs</h2>
 | 
					      <h2 i18n="transaction.inputs-and-outputs|Transaction inputs and outputs">Inputs & Outputs</h2>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
@ -283,6 +301,36 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <br>
 | 
					    <br>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div class="title">
 | 
				
			||||||
 | 
					      <h2 i18n="transaction.diagram|Transaction diagram">Diagram</h2>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div class="box">
 | 
				
			||||||
 | 
					      <div class="graph-container" #graphContainer style="visibility: hidden;"></div>
 | 
				
			||||||
 | 
					      <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-sm">
 | 
				
			||||||
 | 
					          <table class="table table-borderless table-striped">
 | 
				
			||||||
 | 
					            <tbody>
 | 
				
			||||||
 | 
					              <tr>
 | 
				
			||||||
 | 
					                <td><span class="skeleton-loader"></span></td>
 | 
				
			||||||
 | 
					              </tr>
 | 
				
			||||||
 | 
					            </tbody>
 | 
				
			||||||
 | 
					          </table>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col-sm">
 | 
				
			||||||
 | 
					          <table class="table table-borderless table-striped">
 | 
				
			||||||
 | 
					            <tbody>
 | 
				
			||||||
 | 
					              <tr>
 | 
				
			||||||
 | 
					                <td><span class="skeleton-loader"></span></td>
 | 
				
			||||||
 | 
					              </tr>
 | 
				
			||||||
 | 
					            </tbody>
 | 
				
			||||||
 | 
					          </table>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <br>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <div class="title">
 | 
					    <div class="title">
 | 
				
			||||||
      <h2 i18n="transaction.inputs-and-outputs|Transaction inputs and outputs">Inputs & Outputs</h2>
 | 
					      <h2 i18n="transaction.inputs-and-outputs|Transaction inputs and outputs">Inputs & Outputs</h2>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -73,6 +73,24 @@
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.graph-container {
 | 
				
			||||||
 | 
					  position: relative;
 | 
				
			||||||
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					  background: #181b2d;
 | 
				
			||||||
 | 
					  padding: 10px;
 | 
				
			||||||
 | 
					  padding-bottom: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.toggle-wrapper {
 | 
				
			||||||
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					  text-align: center;
 | 
				
			||||||
 | 
					  margin: 1.25em 0 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.graph-toggle {
 | 
				
			||||||
 | 
					  margin: auto;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@media (max-width: 767.98px) {
 | 
					@media (max-width: 767.98px) {
 | 
				
			||||||
	.mobile-bottomcol {
 | 
						.mobile-bottomcol {
 | 
				
			||||||
		margin-top: 15px;
 | 
							margin-top: 15px;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import { Component, OnInit, OnDestroy } from '@angular/core';
 | 
					import { Component, OnInit, AfterViewInit, OnDestroy, HostListener, ViewChild, ElementRef } from '@angular/core';
 | 
				
			||||||
import { ElectrsApiService } from '../../services/electrs-api.service';
 | 
					import { ElectrsApiService } from '../../services/electrs-api.service';
 | 
				
			||||||
import { ActivatedRoute, ParamMap } from '@angular/router';
 | 
					import { ActivatedRoute, ParamMap } from '@angular/router';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
@ -24,7 +24,7 @@ import { LiquidUnblinding } from './liquid-ublinding';
 | 
				
			|||||||
  templateUrl: './transaction.component.html',
 | 
					  templateUrl: './transaction.component.html',
 | 
				
			||||||
  styleUrls: ['./transaction.component.scss'],
 | 
					  styleUrls: ['./transaction.component.scss'],
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class TransactionComponent implements OnInit, OnDestroy {
 | 
					export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
 | 
				
			||||||
  network = '';
 | 
					  network = '';
 | 
				
			||||||
  tx: Transaction;
 | 
					  tx: Transaction;
 | 
				
			||||||
  txId: string;
 | 
					  txId: string;
 | 
				
			||||||
@ -47,6 +47,12 @@ export class TransactionComponent implements OnInit, OnDestroy {
 | 
				
			|||||||
  timeAvg$: Observable<number>;
 | 
					  timeAvg$: Observable<number>;
 | 
				
			||||||
  liquidUnblinding = new LiquidUnblinding();
 | 
					  liquidUnblinding = new LiquidUnblinding();
 | 
				
			||||||
  outputIndex: number;
 | 
					  outputIndex: number;
 | 
				
			||||||
 | 
					  graphExpanded: boolean = false;
 | 
				
			||||||
 | 
					  graphWidth: number = 1000;
 | 
				
			||||||
 | 
					  maxInOut: number = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @ViewChild('graphContainer')
 | 
				
			||||||
 | 
					  graphContainer: ElementRef;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    private route: ActivatedRoute,
 | 
					    private route: ActivatedRoute,
 | 
				
			||||||
@ -167,6 +173,7 @@ export class TransactionComponent implements OnInit, OnDestroy {
 | 
				
			|||||||
          this.waitingForTransaction = false;
 | 
					          this.waitingForTransaction = false;
 | 
				
			||||||
          this.setMempoolBlocksSubscription();
 | 
					          this.setMempoolBlocksSubscription();
 | 
				
			||||||
          this.websocketService.startTrackTransaction(tx.txid);
 | 
					          this.websocketService.startTrackTransaction(tx.txid);
 | 
				
			||||||
 | 
					          this.setupGraph();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          if (!tx.status.confirmed && tx.firstSeen) {
 | 
					          if (!tx.status.confirmed && tx.firstSeen) {
 | 
				
			||||||
            this.transactionTime = tx.firstSeen;
 | 
					            this.transactionTime = tx.firstSeen;
 | 
				
			||||||
@ -222,6 +229,10 @@ export class TransactionComponent implements OnInit, OnDestroy {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ngAfterViewInit(): void {
 | 
				
			||||||
 | 
					    this.setGraphSize();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleLoadElectrsTransactionError(error: any): Observable<any> {
 | 
					  handleLoadElectrsTransactionError(error: any): Observable<any> {
 | 
				
			||||||
    if (error.status === 404 && /^[a-fA-F0-9]{64}$/.test(this.txId)) {
 | 
					    if (error.status === 404 && /^[a-fA-F0-9]{64}$/.test(this.txId)) {
 | 
				
			||||||
      this.websocketService.startMultiTrackTransaction(this.txId);
 | 
					      this.websocketService.startMultiTrackTransaction(this.txId);
 | 
				
			||||||
@ -284,6 +295,26 @@ export class TransactionComponent implements OnInit, OnDestroy {
 | 
				
			|||||||
    return +(cpfpTx.fee / (cpfpTx.weight / 4)).toFixed(1);
 | 
					    return +(cpfpTx.fee / (cpfpTx.weight / 4)).toFixed(1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  setupGraph() {
 | 
				
			||||||
 | 
					    this.maxInOut = Math.min(250, Math.max(this.tx?.vin?.length || 1, this.tx?.vout?.length || 1));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  expandGraph() {
 | 
				
			||||||
 | 
					    this.graphExpanded = true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  collapseGraph() {
 | 
				
			||||||
 | 
					    this.graphExpanded = false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @HostListener('window:resize', ['$event'])
 | 
				
			||||||
 | 
					  setGraphSize(): void {
 | 
				
			||||||
 | 
					    console.log('resize', this.graphContainer);
 | 
				
			||||||
 | 
					    if (this.graphContainer) {
 | 
				
			||||||
 | 
					      this.graphWidth = this.graphContainer.nativeElement.clientWidth - 24;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnDestroy() {
 | 
					  ngOnDestroy() {
 | 
				
			||||||
    this.subscription.unsubscribe();
 | 
					    this.subscription.unsubscribe();
 | 
				
			||||||
    this.fetchCpfpSubscription.unsubscribe();
 | 
					    this.fetchCpfpSubscription.unsubscribe();
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user