mirror of
https://github.com/mempool/mempool.git
synced 2025-02-24 22:58:30 +01:00
Merge pull request #2705 from mononaut/flow-diagram-zero-value
better representation of zero-value outputs in flow diagram
This commit is contained in:
commit
56e00d7ea9
3 changed files with 71 additions and 13 deletions
|
@ -21,6 +21,15 @@
|
|||
markerWidth="1.5" markerHeight="1"
|
||||
orient="auto">
|
||||
</marker>
|
||||
<radialGradient id="gradient0" x1="0%" y1="0%" x2="100%" y2="100%" gradientUnits="userSpaceOnUse">
|
||||
<stop [attr.stop-color]="gradient[0]" />
|
||||
</radialGradient>
|
||||
<radialGradient id="gradient1" x1="0%" y1="0%" x2="100%" y2="100%" gradientUnits="userSpaceOnUse">
|
||||
<stop [attr.stop-color]="gradient[1]" />
|
||||
</radialGradient>
|
||||
<radialGradient id="gradient2" x1="0%" y1="0%" x2="100%" y2="100%" gradientUnits="userSpaceOnUse">
|
||||
<stop [attr.stop-color]="gradient[2]" />
|
||||
</radialGradient>
|
||||
<linearGradient id="input-gradient" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" [attr.stop-color]="gradient[0]" />
|
||||
<stop offset="100%" [attr.stop-color]="gradient[1]" />
|
||||
|
@ -117,7 +126,7 @@
|
|||
(pointerout)="onBlur($event, 'output-connector', i);"
|
||||
(click)="onClick($event, 'output-connector', outputData[i].index);"
|
||||
/>
|
||||
<path
|
||||
<path *ngIf="!output.zeroValue"
|
||||
[attr.d]="output.markerPath"
|
||||
class="output marker-target {{output.class}}"
|
||||
[class.highlight]="outputData[i].index === outputIndex"
|
||||
|
@ -125,7 +134,7 @@
|
|||
(pointerout)="onBlur($event, 'output', i);"
|
||||
(click)="onClick($event, 'output', outputData[i].index);"
|
||||
/>
|
||||
<path
|
||||
<path *ngIf="!output.zeroValue"
|
||||
[attr.d]="output.path"
|
||||
class="line {{output.class}}"
|
||||
[class.highlight]="outputIndex != null && outputData[i].index === outputIndex"
|
||||
|
@ -135,6 +144,16 @@
|
|||
(pointerout)="onBlur($event, 'output', i);"
|
||||
(click)="onClick($event, 'output', outputData[i].index);"
|
||||
/>
|
||||
<path *ngIf="output.zeroValue"
|
||||
[attr.d]="output.path"
|
||||
class="line {{output.class}} zerovalue"
|
||||
[class.highlight]="outputIndex != null && outputData[i].index === outputIndex"
|
||||
[class.zerovalue]="output.zeroValue"
|
||||
[style]="output.style"
|
||||
(pointerover)="onHover($event, 'output', i);"
|
||||
(pointerout)="onBlur($event, 'output', i);"
|
||||
(click)="onClick($event, 'output', outputData[i].index);"
|
||||
/>
|
||||
</ng-container>
|
||||
</svg>
|
||||
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
&.fee {
|
||||
stroke: url(#fee-gradient);
|
||||
}
|
||||
&.zerovalue {
|
||||
stroke: url(#gradient0);
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
&.highlight {
|
||||
z-index: 8;
|
||||
|
@ -21,6 +25,9 @@
|
|||
&.output {
|
||||
stroke: url(#output-highlight-gradient);
|
||||
}
|
||||
&.zerovalue {
|
||||
stroke: #1bd8f4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,6 +43,9 @@
|
|||
&.fee {
|
||||
stroke: url(#fee-hover-gradient);
|
||||
}
|
||||
&.zerovalue {
|
||||
stroke: white;
|
||||
}
|
||||
}
|
||||
|
||||
.connector {
|
||||
|
|
|
@ -13,6 +13,7 @@ interface SvgLine {
|
|||
class?: string;
|
||||
connectorPath?: string;
|
||||
markerPath?: string;
|
||||
zeroValue?: boolean;
|
||||
}
|
||||
|
||||
interface Xput {
|
||||
|
@ -63,6 +64,8 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
|
|||
hoverConnector: boolean = false;
|
||||
tooltipPosition = { x: 0, y: 0 };
|
||||
outspends: Outspend[] = [];
|
||||
zeroValueWidth = 60;
|
||||
zeroValueThickness = 20;
|
||||
|
||||
outspendsSubscription: Subscription;
|
||||
refreshOutspends$: ReplaySubject<string> = new ReplaySubject();
|
||||
|
@ -130,6 +133,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
|
|||
this.txWidth = this.connectors ? Math.max(this.width - 200, this.width * 0.8) : this.width - 20;
|
||||
this.combinedWeight = Math.min(this.maxCombinedWeight, Math.floor((this.txWidth - (2 * this.midWidth)) / 6));
|
||||
this.connectorWidth = (this.width - this.txWidth) / 2;
|
||||
this.zeroValueWidth = Math.max(20, Math.min((this.txWidth / 2) - this.midWidth - 110, 60));
|
||||
|
||||
const totalValue = this.calcTotalValue(this.tx);
|
||||
let voutWithFee = this.tx.vout.map((v, i) => {
|
||||
|
@ -236,10 +240,10 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
|
|||
}
|
||||
|
||||
linesFromWeights(side: 'in' | 'out', xputs: Xput[], weights: number[], maxVisibleStrands: number): SvgLine[] {
|
||||
const lineParams = weights.map((w) => {
|
||||
const lineParams = weights.map((w, i) => {
|
||||
return {
|
||||
weight: w,
|
||||
thickness: Math.max(this.minWeight - 1, w) + 1,
|
||||
thickness: xputs[i].value === 0 ? this.zeroValueThickness : Math.max(this.minWeight - 1, w) + 1,
|
||||
offset: 0,
|
||||
innerY: 0,
|
||||
outerY: 0,
|
||||
|
@ -256,7 +260,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
|
|||
let lastOuter = 0;
|
||||
let lastInner = innerTop;
|
||||
// gap between strands
|
||||
const spacing = (this.height - visibleWeight) / gaps;
|
||||
const spacing = Math.max(4, (this.height - visibleWeight) / gaps);
|
||||
|
||||
// curve adjustments to prevent overlaps
|
||||
let offset = 0;
|
||||
|
@ -265,6 +269,12 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
|
|||
let lastWeight = 0;
|
||||
let pad = 0;
|
||||
lineParams.forEach((line, i) => {
|
||||
if (xputs[i].value === 0) {
|
||||
line.outerY = lastOuter + (this.zeroValueThickness / 2);
|
||||
lastOuter += this.zeroValueThickness + spacing;
|
||||
return;
|
||||
}
|
||||
|
||||
// set the vertical position of the (center of the) outer side of the line
|
||||
line.outerY = lastOuter + (line.thickness / 2);
|
||||
line.innerY = Math.min(innerBottom + (line.thickness / 2), Math.max(innerTop + (line.thickness / 2), lastInner + (line.weight / 2)));
|
||||
|
@ -318,19 +328,28 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
|
|||
maxOffset -= minOffset;
|
||||
|
||||
return lineParams.map((line, i) => {
|
||||
return {
|
||||
path: this.makePath(side, line.outerY, line.innerY, line.thickness, line.offset, pad + maxOffset),
|
||||
style: this.makeStyle(line.thickness, xputs[i].type),
|
||||
class: xputs[i].type,
|
||||
connectorPath: this.connectors ? this.makeConnectorPath(side, line.outerY, line.innerY, line.thickness): null,
|
||||
markerPath: this.makeMarkerPath(side, line.outerY, line.innerY, line.thickness),
|
||||
};
|
||||
if (xputs[i].value === 0) {
|
||||
return {
|
||||
path: this.makeZeroValuePath(side, line.outerY),
|
||||
style: this.makeStyle(this.zeroValueThickness, xputs[i].type),
|
||||
class: xputs[i].type,
|
||||
zeroValue: true,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
path: this.makePath(side, line.outerY, line.innerY, line.thickness, line.offset, pad + maxOffset),
|
||||
style: this.makeStyle(line.thickness, xputs[i].type),
|
||||
class: xputs[i].type,
|
||||
connectorPath: this.connectors ? this.makeConnectorPath(side, line.outerY, line.innerY, line.thickness): null,
|
||||
markerPath: this.makeMarkerPath(side, line.outerY, line.innerY, line.thickness),
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
makePath(side: 'in' | 'out', outer: number, inner: number, weight: number, offset: number, pad: number): string {
|
||||
const start = (weight * 0.5) + this.connectorWidth;
|
||||
const curveStart = Math.max(start + 1, pad - offset);
|
||||
const curveStart = Math.max(start + 5, pad - offset);
|
||||
const end = this.width / 2 - (this.midWidth * 0.9) + 1;
|
||||
const curveEnd = end - offset - 10;
|
||||
const midpoint = (curveStart + curveEnd) / 2;
|
||||
|
@ -347,6 +366,16 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
|
|||
}
|
||||
}
|
||||
|
||||
makeZeroValuePath(side: 'in' | 'out', y: number): string {
|
||||
const offset = this.zeroValueThickness / 2;
|
||||
const start = (this.connectorWidth / 2) + 10;
|
||||
if (side === 'in') {
|
||||
return `M ${start + offset} ${y} L ${start + this.zeroValueWidth + offset} ${y}`;
|
||||
} else { // mirrored in y-axis for the right hand side
|
||||
return `M ${this.width - start - offset} ${y} L ${this.width - start - this.zeroValueWidth - offset} ${y}`;
|
||||
}
|
||||
}
|
||||
|
||||
makeConnectorPath(side: 'in' | 'out', y: number, inner, weight: number): string {
|
||||
const halfWidth = weight * 0.5;
|
||||
const offset = 10; //Math.max(2, halfWidth * 0.2);
|
||||
|
|
Loading…
Add table
Reference in a new issue