Fees vs subsidy graph: add percentage mode

This commit is contained in:
natsoni 2024-05-25 12:32:38 +02:00
parent 46b5b26347
commit 6c6c18830c
No known key found for this signature in database
GPG Key ID: C65917583181743B

View File

@ -48,7 +48,7 @@ export class BlockFeesSubsidyGraphComponent implements OnInit {
formatNumber = formatNumber; formatNumber = formatNumber;
timespan = ''; timespan = '';
chartInstance: any = undefined; chartInstance: any = undefined;
showFiat = false; displayMode: 'normal' | 'fiat' | 'percentage' = 'normal';
updateZoom = false; updateZoom = false;
zoomSpan = 100; zoomSpan = 100;
zoomTimeSpan = ''; zoomTimeSpan = '';
@ -106,8 +106,10 @@ export class BlockFeesSubsidyGraphComponent implements OnInit {
blockHeight: response.body.map(val => val.avgHeight), blockHeight: response.body.map(val => val.avgHeight),
blockFees: response.body.map(val => val.avgFees / 100_000_000), blockFees: response.body.map(val => val.avgFees / 100_000_000),
blockFeesFiat: response.body.filter(val => val['USD'] > 0).map(val => val.avgFees / 100_000_000 * val['USD']), blockFeesFiat: response.body.filter(val => val['USD'] > 0).map(val => val.avgFees / 100_000_000 * val['USD']),
blockFeesPercent: response.body.filter(val => val.avgFees + this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))] > 0).map(val => val.avgFees / (val.avgFees + this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))]) * 100),
blockSubsidy: response.body.map(val => this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))] / 100_000_000), blockSubsidy: response.body.map(val => this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))] / 100_000_000),
blockSubsidyFiat: response.body.filter(val => val['USD'] > 0).map(val => this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))] / 100_000_000 * val['USD']), blockSubsidyFiat: response.body.filter(val => val['USD'] > 0).map(val => this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))] / 100_000_000 * val['USD']),
blockSubsidyPercent: response.body.filter(val => val.avgFees + this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))] > 0).map(val => this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))] / (val.avgFees + this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))]) * 100),
}; };
this.prepareChartOptions(); this.prepareChartOptions();
@ -157,9 +159,9 @@ export class BlockFeesSubsidyGraphComponent implements OnInit {
axisPointer: { axisPointer: {
type: 'line' type: 'line'
}, },
backgroundColor: 'color-mix(in srgb, var(--active-bg) 95%, transparent)', backgroundColor: 'rgba(17, 19, 31, 1)',
borderRadius: 4, borderRadius: 4,
shadowColor: 'color-mix(in srgb, var(--active-bg) 95%, transparent)', shadowColor: 'rgba(0, 0, 0, 0.5)',
textStyle: { textStyle: {
color: 'var(--tooltip-grey)', color: 'var(--tooltip-grey)',
align: 'left', align: 'left',
@ -172,11 +174,13 @@ export class BlockFeesSubsidyGraphComponent implements OnInit {
let tooltip = `<b style="color: white; margin-left: 2px">${formatterXAxis(this.locale, this.zoomTimeSpan, parseInt(this.data.timestamp[data[0].dataIndex], 10))}</b><br>`; let tooltip = `<b style="color: white; margin-left: 2px">${formatterXAxis(this.locale, this.zoomTimeSpan, parseInt(this.data.timestamp[data[0].dataIndex], 10))}</b><br>`;
for (let i = data.length - 1; i >= 0; i--) { for (let i = data.length - 1; i >= 0; i--) {
const tick = data[i]; const tick = data[i];
if (!this.showFiat) tooltip += `${tick.marker} ${tick.seriesName}: ${formatNumber(tick.data, this.locale, '1.0-3')} BTC<br>`; tooltip += `${tick.marker} ${tick.seriesName.split(' ')[0]}: `;
else tooltip += `${tick.marker} ${tick.seriesName}: ${this.fiatCurrencyPipe.transform(tick.data, null, 'USD') }<br>`; if (this.displayMode === 'normal') tooltip += `${formatNumber(tick.data, this.locale, '1.0-3')} BTC<br>`;
else if (this.displayMode === 'fiat') tooltip += `${this.fiatCurrencyPipe.transform(tick.data, null, 'USD') }<br>`;
else tooltip += `${formatNumber(tick.data, this.locale, '1.0-2')}%<br>`;
} }
if (!this.showFiat) tooltip += `<div style="margin-left: 2px">${formatNumber(data.reduce((acc, val) => acc + val.data, 0), this.locale, '1.0-3')} BTC</div>`; if (this.displayMode === 'normal') tooltip += `<div style="margin-left: 2px">${formatNumber(data.reduce((acc, val) => acc + val.data, 0), this.locale, '1.0-3')} BTC</div>`;
else tooltip += `<div style="margin-left: 2px">${this.fiatCurrencyPipe.transform(data.reduce((acc, val) => acc + val.data, 0), null, 'USD')}</div>`; else if (this.displayMode === 'fiat') tooltip += `<div style="margin-left: 2px">${this.fiatCurrencyPipe.transform(data.reduce((acc, val) => acc + val.data, 0), null, 'USD')}</div>`;
if (['24h', '3d'].includes(this.zoomTimeSpan)) { if (['24h', '3d'].includes(this.zoomTimeSpan)) {
tooltip += `<small>` + $localize`At block <b style="color: white; margin-left: 2px">${data[0].axisValue}` + `</small>`; tooltip += `<small>` + $localize`At block <b style="color: white; margin-left: 2px">${data[0].axisValue}` + `</small>`;
} else { } else {
@ -250,12 +254,30 @@ export class BlockFeesSubsidyGraphComponent implements OnInit {
}, },
icon: 'roundRect', icon: 'roundRect',
}, },
{
name: 'Subsidy (%)',
inactiveColor: 'var(--grey)',
textStyle: {
color: 'white',
},
icon: 'roundRect',
},
{
name: 'Fees (%)',
inactiveColor: 'var(--grey)',
textStyle: {
color: 'white',
},
icon: 'roundRect',
},
], ],
selected: { selected: {
'Subsidy (USD)': this.showFiat, 'Subsidy (USD)': this.displayMode === 'fiat',
'Fees (USD)': this.showFiat, 'Fees (USD)': this.displayMode === 'fiat',
'Subsidy': !this.showFiat, 'Subsidy': this.displayMode === 'normal',
'Fees': !this.showFiat, 'Fees': this.displayMode === 'normal',
'Subsidy (%)': this.displayMode === 'percentage',
'Fees (%)': this.displayMode === 'percentage',
}, },
}, },
yAxis: this.data.blockFees.length === 0 ? undefined : [ yAxis: this.data.blockFees.length === 0 ? undefined : [
@ -264,10 +286,15 @@ export class BlockFeesSubsidyGraphComponent implements OnInit {
axisLabel: { axisLabel: {
color: 'var(--grey)', color: 'var(--grey)',
formatter: (val) => { formatter: (val) => {
return `${val} BTC`; return `${val}${this.displayMode === 'percentage' ? '%' : ' BTC'}`;
} }
}, },
min: 0, min: 0,
max: (value) => {
if (this.displayMode === 'percentage') {
return 100;
}
},
splitLine: { splitLine: {
lineStyle: { lineStyle: {
type: 'dotted', type: 'dotted',
@ -295,6 +322,7 @@ export class BlockFeesSubsidyGraphComponent implements OnInit {
name: 'Subsidy', name: 'Subsidy',
yAxisIndex: 0, yAxisIndex: 0,
type: 'bar', type: 'bar',
barWidth: '90%',
stack: 'total', stack: 'total',
data: this.data.blockSubsidy, data: this.data.blockSubsidy,
}, },
@ -302,6 +330,7 @@ export class BlockFeesSubsidyGraphComponent implements OnInit {
name: 'Fees', name: 'Fees',
yAxisIndex: 0, yAxisIndex: 0,
type: 'bar', type: 'bar',
barWidth: '90%',
stack: 'total', stack: 'total',
data: this.data.blockFees, data: this.data.blockFees,
}, },
@ -309,6 +338,7 @@ export class BlockFeesSubsidyGraphComponent implements OnInit {
name: 'Subsidy (USD)', name: 'Subsidy (USD)',
yAxisIndex: 1, yAxisIndex: 1,
type: 'bar', type: 'bar',
barWidth: '90%',
stack: 'total', stack: 'total',
data: this.data.blockSubsidyFiat, data: this.data.blockSubsidyFiat,
}, },
@ -316,9 +346,26 @@ export class BlockFeesSubsidyGraphComponent implements OnInit {
name: 'Fees (USD)', name: 'Fees (USD)',
yAxisIndex: 1, yAxisIndex: 1,
type: 'bar', type: 'bar',
barWidth: '90%',
stack: 'total', stack: 'total',
data: this.data.blockFeesFiat, data: this.data.blockFeesFiat,
}, },
{
name: 'Subsidy (%)',
yAxisIndex: 0,
type: 'bar',
barWidth: '90%',
stack: 'total',
data: this.data.blockSubsidyPercent,
},
{
name: 'Fees (%)',
yAxisIndex: 0,
type: 'bar',
barWidth: '90%',
stack: 'total',
data: this.data.blockFeesPercent,
},
], ],
dataZoom: this.data.blockFees.length === 0 ? undefined : [{ dataZoom: this.data.blockFees.length === 0 ? undefined : [{
type: 'inside', type: 'inside',
@ -349,22 +396,27 @@ export class BlockFeesSubsidyGraphComponent implements OnInit {
this.chartInstance = ec; this.chartInstance = ec;
this.chartInstance.on('legendselectchanged', (params) => { this.chartInstance.on('legendselectchanged', (params) => {
const isFiat = params.name.includes('USD'); let mode: 'normal' | 'fiat' | 'percentage';
if (isFiat === this.showFiat) return; if (params.name.includes('USD')) {
mode = 'fiat';
} else if (params.name.includes('%')) {
mode = 'percentage';
} else {
mode = 'normal';
}
if (this.displayMode === mode) return;
const isActivation = params.selected[params.name]; const isActivation = params.selected[params.name];
if (isFiat === isActivation) {
this.showFiat = true; if (isActivation) {
this.chartInstance.dispatchAction({ type: 'legendUnSelect', name: 'Subsidy' }); this.displayMode = mode;
this.chartInstance.dispatchAction({ type: 'legendUnSelect', name: 'Fees' }); this.chartInstance.dispatchAction({ type: this.displayMode === 'normal' ? 'legendSelect' : 'legendUnSelect', name: 'Subsidy' });
this.chartInstance.dispatchAction({ type: 'legendSelect', name: 'Subsidy (USD)' }); this.chartInstance.dispatchAction({ type: this.displayMode === 'normal' ? 'legendSelect' : 'legendUnSelect', name: 'Fees' });
this.chartInstance.dispatchAction({ type: 'legendSelect', name: 'Fees (USD)' }); this.chartInstance.dispatchAction({ type: this.displayMode === 'fiat' ? 'legendSelect' : 'legendUnSelect', name: 'Subsidy (USD)' });
} else { this.chartInstance.dispatchAction({ type: this.displayMode === 'fiat' ? 'legendSelect' : 'legendUnSelect', name: 'Fees (USD)' });
this.showFiat = false; this.chartInstance.dispatchAction({ type: this.displayMode === 'percentage' ? 'legendSelect' : 'legendUnSelect', name: 'Subsidy (%)' });
this.chartInstance.dispatchAction({ type: 'legendSelect', name: 'Subsidy' }); this.chartInstance.dispatchAction({ type: this.displayMode === 'percentage' ? 'legendSelect' : 'legendUnSelect', name: 'Fees (%)' });
this.chartInstance.dispatchAction({ type: 'legendSelect', name: 'Fees' });
this.chartInstance.dispatchAction({ type: 'legendUnSelect', name: 'Subsidy (USD)' });
this.chartInstance.dispatchAction({ type: 'legendUnSelect', name: 'Fees (USD)' });
} }
}); });
@ -432,12 +484,16 @@ export class BlockFeesSubsidyGraphComponent implements OnInit {
this.data.blockHeight.splice(startIndex, endIndex - startIndex, ...response.body.map(val => val.avgHeight)); this.data.blockHeight.splice(startIndex, endIndex - startIndex, ...response.body.map(val => val.avgHeight));
this.data.blockFees.splice(startIndex, endIndex - startIndex, ...response.body.map(val => val.avgFees / 100_000_000)); this.data.blockFees.splice(startIndex, endIndex - startIndex, ...response.body.map(val => val.avgFees / 100_000_000));
this.data.blockFeesFiat.splice(startIndex, endIndex - startIndex, ...response.body.filter(val => val['USD'] > 0).map(val => val.avgFees / 100_000_000 * val['USD'])); this.data.blockFeesFiat.splice(startIndex, endIndex - startIndex, ...response.body.filter(val => val['USD'] > 0).map(val => val.avgFees / 100_000_000 * val['USD']));
this.data.blockFeesPercent.splice(startIndex, endIndex - startIndex, ...response.body.filter(val => val.avgFees + this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))] > 0).map(val => val.avgFees / (val.avgFees + this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))]) * 100));
this.data.blockSubsidy.splice(startIndex, endIndex - startIndex, ...response.body.map(val => this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))] / 100_000_000)); this.data.blockSubsidy.splice(startIndex, endIndex - startIndex, ...response.body.map(val => this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))] / 100_000_000));
this.data.blockSubsidyFiat.splice(startIndex, endIndex - startIndex, ...response.body.filter(val => val['USD'] > 0).map(val => this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))] / 100_000_000 * val['USD'])); this.data.blockSubsidyFiat.splice(startIndex, endIndex - startIndex, ...response.body.filter(val => val['USD'] > 0).map(val => this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))] / 100_000_000 * val['USD']));
this.data.blockSubsidyPercent.splice(startIndex, endIndex - startIndex, ...response.body.filter(val => val.avgFees + this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))] > 0).map(val => this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))] / (val.avgFees + this.subsidies[Math.floor(Math.min(val.avgHeight / 210000, 33))]) * 100));
option.series[0].data = this.data.blockSubsidy; option.series[0].data = this.data.blockSubsidy;
option.series[1].data = this.data.blockFees; option.series[1].data = this.data.blockFees;
option.series[2].data = this.data.blockSubsidyFiat; option.series[2].data = this.data.blockSubsidyFiat;
option.series[3].data = this.data.blockFeesFiat; option.series[3].data = this.data.blockFeesFiat;
option.series[4].data = this.data.blockSubsidyPercent;
option.series[5].data = this.data.blockFeesPercent;
option.xAxis[0].data = this.data.blockHeight; option.xAxis[0].data = this.data.blockHeight;
option.xAxis[1].data = this.data.timestamp; option.xAxis[1].data = this.data.timestamp;
this.chartInstance.setOption(option, true); this.chartInstance.setOption(option, true);