diff --git a/backend/src/api/mempool-blocks.ts b/backend/src/api/mempool-blocks.ts
index 224e31744..57d1a393f 100644
--- a/backend/src/api/mempool-blocks.ts
+++ b/backend/src/api/mempool-blocks.ts
@@ -143,7 +143,7 @@ class MempoolBlocks {
const stackWeight = transactionsSorted.slice(index).reduce((total, tx) => total + (tx.weight || 0), 0);
if (stackWeight > config.MEMPOOL.BLOCK_WEIGHT_UNITS) {
onlineStats = true;
- feeStatsCalculator = new OnlineFeeStatsCalculator(stackWeight, 0.5);
+ feeStatsCalculator = new OnlineFeeStatsCalculator(stackWeight, 0.5, [10, 20, 30, 40, 50, 60, 70, 80, 90]);
feeStatsCalculator.processNext(tx);
}
}
@@ -334,7 +334,7 @@ class MempoolBlocks {
if (hasBlockStack) {
stackWeight = blocks[blocks.length - 1].reduce((total, tx) => total + (mempool[tx]?.weight || 0), 0);
hasBlockStack = stackWeight > config.MEMPOOL.BLOCK_WEIGHT_UNITS;
- feeStatsCalculator = new OnlineFeeStatsCalculator(stackWeight, 0.5);
+ feeStatsCalculator = new OnlineFeeStatsCalculator(stackWeight, 0.5, [10, 20, 30, 40, 50, 60, 70, 80, 90]);
}
const readyBlocks: { transactionIds, transactions, totalSize, totalWeight, totalFees, feeStats }[] = [];
diff --git a/frontend/src/app/components/fee-distribution-graph/fee-distribution-graph.component.ts b/frontend/src/app/components/fee-distribution-graph/fee-distribution-graph.component.ts
index 8c90036fd..823d271a1 100644
--- a/frontend/src/app/components/fee-distribution-graph/fee-distribution-graph.component.ts
+++ b/frontend/src/app/components/fee-distribution-graph/fee-distribution-graph.component.ts
@@ -1,5 +1,9 @@
import { OnChanges } from '@angular/core';
import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';
+import { TransactionStripped } from '../../interfaces/websocket.interface';
+import { StateService } from '../../services/state.service';
+import { VbytesPipe } from '../../shared/pipes/bytes-pipe/vbytes.pipe';
+import { selectPowerOfTen } from '../../bitcoin.utils';
@Component({
selector: 'app-fee-distribution-graph',
@@ -7,47 +11,121 @@ import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class FeeDistributionGraphComponent implements OnInit, OnChanges {
- @Input() data: any;
+ @Input() feeRange: number[];
+ @Input() vsize: number;
+ @Input() transactions: TransactionStripped[];
@Input() height: number | string = 210;
@Input() top: number | string = 20;
@Input() right: number | string = 22;
@Input() left: number | string = 30;
+ @Input() numSamples: number = 200;
+ @Input() numLabels: number = 10;
+
+ simple: boolean = false;
+ data: number[][];
+ labelInterval: number = 50;
mempoolVsizeFeesOptions: any;
mempoolVsizeFeesInitOptions = {
renderer: 'svg'
};
- constructor() { }
+ constructor(
+ private stateService: StateService,
+ private vbytesPipe: VbytesPipe,
+ ) { }
- ngOnInit() {
+ ngOnInit(): void {
this.mountChart();
}
- ngOnChanges() {
+ ngOnChanges(): void {
+ this.simple = !!this.feeRange?.length;
+ this.prepareChart();
this.mountChart();
}
- mountChart() {
+ prepareChart(): void {
+ if (this.simple) {
+ this.data = this.feeRange.map((rate, index) => [index * 10, rate]);
+ this.labelInterval = 1;
+ return;
+ }
+ this.data = [];
+ if (!this.transactions?.length) {
+ return;
+ }
+ const samples = [];
+ const txs = this.transactions.map(tx => { return { vsize: tx.vsize, rate: tx.rate || (tx.fee / tx.vsize) }; }).sort((a, b) => { return b.rate - a.rate; });
+ const maxBlockVSize = this.stateService.env.BLOCK_WEIGHT_UNITS / 4;
+ const sampleInterval = maxBlockVSize / this.numSamples;
+ let cumVSize = 0;
+ let sampleIndex = 0;
+ let nextSample = 0;
+ let txIndex = 0;
+ this.labelInterval = this.numSamples / this.numLabels;
+ while (nextSample <= maxBlockVSize) {
+ if (txIndex >= txs.length) {
+ samples.push([(1 - (sampleIndex / this.numSamples)) * 100, 0]);
+ nextSample += sampleInterval;
+ sampleIndex++;
+ continue;
+ }
+
+ while (txs[txIndex] && nextSample < cumVSize + txs[txIndex].vsize) {
+ samples.push([(1 - (sampleIndex / this.numSamples)) * 100, txs[txIndex].rate]);
+ nextSample += sampleInterval;
+ sampleIndex++;
+ }
+ cumVSize += txs[txIndex].vsize;
+ txIndex++;
+ }
+ this.data = samples.reverse();
+ }
+
+ mountChart(): void {
this.mempoolVsizeFeesOptions = {
grid: {
height: '210',
right: '20',
top: '22',
- left: '30',
+ left: '40',
},
xAxis: {
type: 'category',
boundaryGap: false,
+ name: '% Weight',
+ nameLocation: 'middle',
+ nameGap: 0,
+ nameTextStyle: {
+ verticalAlign: 'top',
+ padding: [30, 0, 0, 0],
+ },
+ axisLabel: {
+ interval: (index: number): boolean => { return index && (index % this.labelInterval === 0); },
+ formatter: (value: number): string => { return Number(value).toFixed(0); },
+ },
+ axisTick: {
+ interval: (index:number): boolean => { return (index % this.labelInterval === 0); },
+ },
},
yAxis: {
type: 'value',
+ // name: 'Effective Fee Rate s/vb',
+ // nameLocation: 'middle',
splitLine: {
lineStyle: {
type: 'dotted',
color: '#ffffff66',
opacity: 0.25,
}
+ },
+ axisLabel: {
+ formatter: (value: number): string => {
+ const selectedPowerOfTen = selectPowerOfTen(value);
+ const newVal = Math.round(value / selectedPowerOfTen.divider);
+ return `${newVal}${selectedPowerOfTen.unit}`;
+ },
}
},
series: [{
@@ -58,14 +136,18 @@ export class FeeDistributionGraphComponent implements OnInit, OnChanges {
position: 'top',
color: '#ffffff',
textShadowBlur: 0,
- formatter: (label: any) => {
- return Math.floor(label.data);
+ formatter: (label: { data: number[] }): string => {
+ const value = label.data[1];
+ const selectedPowerOfTen = selectPowerOfTen(value);
+ const newVal = Math.round(value / selectedPowerOfTen.divider);
+ return `${newVal}${selectedPowerOfTen.unit}`;
},
},
+ showAllSymbol: false,
smooth: true,
lineStyle: {
color: '#D81B60',
- width: 4,
+ width: 1,
},
itemStyle: {
color: '#b71c1c',
diff --git a/frontend/src/app/components/mempool-block/mempool-block.component.html b/frontend/src/app/components/mempool-block/mempool-block.component.html
index 3626e6ff5..7d5b18ccb 100644
--- a/frontend/src/app/components/mempool-block/mempool-block.component.html
+++ b/frontend/src/app/components/mempool-block/mempool-block.component.html
@@ -39,11 +39,11 @@
-