diff --git a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.html b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.html
index 23346f405..c58e77335 100644
--- a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.html
+++ b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.html
@@ -21,6 +21,15 @@
markerWidth="1.5" markerHeight="1"
orient="auto">
+
+
+
+
+
+
+
+
+
@@ -117,7 +126,7 @@
(pointerout)="onBlur($event, 'output-connector', i);"
(click)="onClick($event, 'output-connector', outputData[i].index);"
/>
-
-
+
diff --git a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.scss b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.scss
index 7c9ecf0ce..6ba76d5de 100644
--- a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.scss
+++ b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.scss
@@ -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 {
diff --git a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.ts b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.ts
index 39164314a..1f9602512 100644
--- a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.ts
+++ b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.ts
@@ -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 = 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);