mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-11-04 21:36:45 +00:00
show relative sizes of amounts in transaction diagram
This commit is contained in:
parent
5d0025b4a7
commit
aff872eea0
3 changed files with 60 additions and 22 deletions
2
drongo
2
drongo
|
@ -1 +1 @@
|
||||||
Subproject commit 6ac593f161f7d17bf1f99658a92d7d65d25997be
|
Subproject commit d59da365065fffe07fbaf6bae45b457752114e79
|
|
@ -27,6 +27,7 @@ import javafx.scene.control.ContentDisplay;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.Tooltip;
|
import javafx.scene.control.Tooltip;
|
||||||
import javafx.scene.layout.*;
|
import javafx.scene.layout.*;
|
||||||
|
import javafx.scene.shape.Circle;
|
||||||
import javafx.scene.shape.CubicCurve;
|
import javafx.scene.shape.CubicCurve;
|
||||||
import javafx.scene.shape.Line;
|
import javafx.scene.shape.Line;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
|
@ -44,6 +45,7 @@ public class TransactionDiagram extends GridPane {
|
||||||
private static final double DIAGRAM_HEIGHT = 210.0;
|
private static final double DIAGRAM_HEIGHT = 210.0;
|
||||||
private static final double REDUCED_DIAGRAM_HEIGHT = DIAGRAM_HEIGHT - 60;
|
private static final double REDUCED_DIAGRAM_HEIGHT = DIAGRAM_HEIGHT - 60;
|
||||||
private static final int TOOLTIP_SHOW_DELAY = 50;
|
private static final int TOOLTIP_SHOW_DELAY = 50;
|
||||||
|
private static final int RELATIVE_SIZE_MAX_RADIUS = 7;
|
||||||
|
|
||||||
private WalletTransaction walletTx;
|
private WalletTransaction walletTx;
|
||||||
private final BooleanProperty finalProperty = new SimpleBooleanProperty(false);
|
private final BooleanProperty finalProperty = new SimpleBooleanProperty(false);
|
||||||
|
@ -387,6 +389,7 @@ public class TransactionDiagram extends GridPane {
|
||||||
|
|
||||||
double width = 140.0;
|
double width = 140.0;
|
||||||
List<BlockTransactionHashIndex> inputs = new ArrayList<>(displayedUtxos.keySet());
|
List<BlockTransactionHashIndex> inputs = new ArrayList<>(displayedUtxos.keySet());
|
||||||
|
long sum = walletTx.getTotal();
|
||||||
int numUtxos = displayedUtxos.size();
|
int numUtxos = displayedUtxos.size();
|
||||||
for(int i = 1; i <= numUtxos; i++) {
|
for(int i = 1; i <= numUtxos; i++) {
|
||||||
CubicCurve curve = new CubicCurve();
|
CubicCurve curve = new CubicCurve();
|
||||||
|
@ -398,7 +401,7 @@ public class TransactionDiagram extends GridPane {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
curve.setStartX(0);
|
curve.setStartX(RELATIVE_SIZE_MAX_RADIUS);
|
||||||
double scaleFactor = (double)i / (numUtxos + 1);
|
double scaleFactor = (double)i / (numUtxos + 1);
|
||||||
int nodeHeight = 17;
|
int nodeHeight = 17;
|
||||||
double additional = (0.5 - scaleFactor) * ((double)nodeHeight);
|
double additional = (0.5 - scaleFactor) * ((double)nodeHeight);
|
||||||
|
@ -406,12 +409,18 @@ public class TransactionDiagram extends GridPane {
|
||||||
curve.setEndX(width);
|
curve.setEndX(width);
|
||||||
curve.setEndY(scale(getDiagramHeight(), 0.5, 0));
|
curve.setEndY(scale(getDiagramHeight(), 0.5, 0));
|
||||||
|
|
||||||
curve.setControlX1(scale(width, 0.2, 0));
|
curve.setControlX1(scale(width - RELATIVE_SIZE_MAX_RADIUS, 0.2, 0));
|
||||||
curve.setControlY1(curve.getStartY());
|
curve.setControlY1(curve.getStartY());
|
||||||
curve.setControlX2(scale(width, 0.8, 0));
|
curve.setControlX2(scale(width - RELATIVE_SIZE_MAX_RADIUS, 0.8, 0));
|
||||||
curve.setControlY2(curve.getEndY());
|
curve.setControlY2(curve.getEndY());
|
||||||
|
|
||||||
group.getChildren().add(curve);
|
group.getChildren().add(curve);
|
||||||
|
|
||||||
|
if(sum > 0 && !curve.getStyleClass().contains("input-dashed-line")) {
|
||||||
|
long radius = Math.round((double)inputs.get(numUtxos-i).getValue() * (RELATIVE_SIZE_MAX_RADIUS - 1) / sum) + 1;
|
||||||
|
Circle circle = new Circle(curve.getStartX(), curve.getStartY(), radius);
|
||||||
|
group.getChildren().add(circle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pane.getChildren().add(group);
|
pane.getChildren().add(group);
|
||||||
|
@ -458,6 +467,9 @@ public class TransactionDiagram extends GridPane {
|
||||||
group.getChildren().add(yaxisLine);
|
group.getChildren().add(yaxisLine);
|
||||||
|
|
||||||
double width = 140.0;
|
double width = 140.0;
|
||||||
|
long sum = walletTx.getTotal();
|
||||||
|
List<Long> values = walletTx.getTransaction().getOutputs().stream().map(TransactionOutput::getValue).collect(Collectors.toList());
|
||||||
|
values.add(walletTx.getFee());
|
||||||
int numOutputs = displayedPayments.size() + walletTx.getChangeMap().size() + 1;
|
int numOutputs = displayedPayments.size() + walletTx.getChangeMap().size() + 1;
|
||||||
for(int i = 1; i <= numOutputs; i++) {
|
for(int i = 1; i <= numOutputs; i++) {
|
||||||
CubicCurve curve = new CubicCurve();
|
CubicCurve curve = new CubicCurve();
|
||||||
|
@ -465,18 +477,24 @@ public class TransactionDiagram extends GridPane {
|
||||||
|
|
||||||
curve.setStartX(0);
|
curve.setStartX(0);
|
||||||
curve.setStartY(scale(getDiagramHeight(), 0.5, 0));
|
curve.setStartY(scale(getDiagramHeight(), 0.5, 0));
|
||||||
curve.setEndX(width);
|
curve.setEndX(width - RELATIVE_SIZE_MAX_RADIUS);
|
||||||
double scaleFactor = (double)i / (numOutputs + 1);
|
double scaleFactor = (double)i / (numOutputs + 1);
|
||||||
int nodeHeight = 20;
|
int nodeHeight = 20;
|
||||||
double additional = (0.5 - scaleFactor) * ((double)nodeHeight);
|
double additional = (0.5 - scaleFactor) * ((double)nodeHeight);
|
||||||
curve.setEndY(scale(getDiagramHeight(), scaleFactor, additional));
|
curve.setEndY(scale(getDiagramHeight(), scaleFactor, additional));
|
||||||
|
|
||||||
curve.setControlX1(scale(width, 0.2, 0));
|
curve.setControlX1(scale(width - RELATIVE_SIZE_MAX_RADIUS, 0.2, 0));
|
||||||
curve.controlY1Property().bind(curve.startYProperty());
|
curve.controlY1Property().bind(curve.startYProperty());
|
||||||
curve.setControlX2(scale(width, 0.8, 0));
|
curve.setControlX2(scale(width - RELATIVE_SIZE_MAX_RADIUS, 0.8, 0));
|
||||||
curve.controlY2Property().bind(curve.endYProperty());
|
curve.controlY2Property().bind(curve.endYProperty());
|
||||||
|
|
||||||
group.getChildren().add(curve);
|
group.getChildren().add(curve);
|
||||||
|
|
||||||
|
if(sum > 0) {
|
||||||
|
long radius = Math.min(RELATIVE_SIZE_MAX_RADIUS, Math.round((double)values.get(numOutputs-i) * (RELATIVE_SIZE_MAX_RADIUS - 1) / sum) + 1);
|
||||||
|
Circle circle = new Circle(curve.getEndX(), curve.getEndY(), radius);
|
||||||
|
group.getChildren().add(circle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pane.getChildren().add(group);
|
pane.getChildren().add(group);
|
||||||
|
@ -880,7 +898,7 @@ public class TransactionDiagram extends GridPane {
|
||||||
private final List<BlockTransactionHashIndex> additionalInputs;
|
private final List<BlockTransactionHashIndex> additionalInputs;
|
||||||
|
|
||||||
public AdditionalBlockTransactionHashIndex(List<BlockTransactionHashIndex> additionalInputs) {
|
public AdditionalBlockTransactionHashIndex(List<BlockTransactionHashIndex> additionalInputs) {
|
||||||
super(Sha256Hash.ZERO_HASH, 0, new Date(), 0L, 0, 0);
|
super(Sha256Hash.ZERO_HASH, 0, new Date(), 0L, 0, additionalInputs.stream().mapToLong(BlockTransactionHashIndex::getValue).sum());
|
||||||
this.additionalInputs = additionalInputs;
|
this.additionalInputs = additionalInputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -403,6 +403,11 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
feeAmt = 0L;
|
feeAmt = 0L;
|
||||||
} else if(headersForm.getInputTransactions() != null) {
|
} else if(headersForm.getInputTransactions() != null) {
|
||||||
feeAmt = calculateFee(headersForm.getInputTransactions());
|
feeAmt = calculateFee(headersForm.getInputTransactions());
|
||||||
|
} else {
|
||||||
|
Wallet wallet = getWalletFromTransactionInputs();
|
||||||
|
if(wallet != null) {
|
||||||
|
feeAmt = calculateFee(wallet.getTransactions());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(feeAmt != null) {
|
if(feeAmt != null) {
|
||||||
|
@ -523,7 +528,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockTransaction inputTx = inputTransactions.get(input.getOutpoint().getHash());
|
BlockTransaction inputTx = inputTransactions.get(input.getOutpoint().getHash());
|
||||||
if(inputTx == null) {
|
if(inputTx == null && headersForm.getInputTransactions() != null) {
|
||||||
inputTx = headersForm.getInputTransactions().get(input.getOutpoint().getHash());
|
inputTx = headersForm.getInputTransactions().get(input.getOutpoint().getHash());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,11 +562,18 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
Wallet wallet = getWalletFromTransactionInputs();
|
Wallet wallet = getWalletFromTransactionInputs();
|
||||||
|
|
||||||
if(wallet != null) {
|
if(wallet != null) {
|
||||||
|
Map<Sha256Hash, BlockTransaction> walletInputTransactions = inputTransactions;
|
||||||
|
if(walletInputTransactions == null) {
|
||||||
|
Set<Sha256Hash> refs = headersForm.getTransaction().getInputs().stream().map(txInput -> txInput.getOutpoint().getHash()).collect(Collectors.toSet());
|
||||||
|
walletInputTransactions = new HashMap<>(wallet.getTransactions());
|
||||||
|
walletInputTransactions.keySet().retainAll(refs);
|
||||||
|
}
|
||||||
|
|
||||||
Map<BlockTransactionHashIndex, WalletNode> selectedTxos = new LinkedHashMap<>();
|
Map<BlockTransactionHashIndex, WalletNode> selectedTxos = new LinkedHashMap<>();
|
||||||
Map<BlockTransactionHashIndex, WalletNode> walletTxos = wallet.getWalletTxos();
|
Map<BlockTransactionHashIndex, WalletNode> walletTxos = wallet.getWalletTxos();
|
||||||
for(TransactionInput txInput : headersForm.getTransaction().getInputs()) {
|
for(TransactionInput txInput : headersForm.getTransaction().getInputs()) {
|
||||||
BlockTransactionHashIndex selectedTxo = walletTxos.keySet().stream().filter(txo -> txInput.getOutpoint().getHash().equals(txo.getHash()) && txInput.getOutpoint().getIndex() == txo.getIndex())
|
BlockTransactionHashIndex selectedTxo = walletTxos.keySet().stream().filter(txo -> txInput.getOutpoint().getHash().equals(txo.getHash()) && txInput.getOutpoint().getIndex() == txo.getIndex())
|
||||||
.findFirst().orElse(new BlockTransactionHashIndex(txInput.getOutpoint().getHash(), 0, null, null, txInput.getOutpoint().getIndex(), 0));
|
.findFirst().orElse(getBlockTransactionInput(walletInputTransactions, txInput));
|
||||||
selectedTxos.put(selectedTxo, walletTxos.get(selectedTxo));
|
selectedTxos.put(selectedTxo, walletTxos.get(selectedTxo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,19 +619,10 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new WalletTransaction(wallet, headersForm.getTransaction(), Collections.emptyList(), List.of(selectedTxos), payments, changeMap, fee.getValue(), inputTransactions);
|
return new WalletTransaction(wallet, headersForm.getTransaction(), Collections.emptyList(), List.of(selectedTxos), payments, changeMap, fee.getValue(), walletInputTransactions);
|
||||||
} else {
|
} else {
|
||||||
Map<BlockTransactionHashIndex, WalletNode> selectedTxos = headersForm.getTransaction().getInputs().stream()
|
Map<BlockTransactionHashIndex, WalletNode> selectedTxos = headersForm.getTransaction().getInputs().stream()
|
||||||
.collect(Collectors.toMap(txInput -> {
|
.collect(Collectors.toMap(txInput -> getBlockTransactionInput(inputTransactions, txInput),
|
||||||
if(inputTransactions != null) {
|
|
||||||
BlockTransaction blockTransaction = inputTransactions.get(txInput.getOutpoint().getHash());
|
|
||||||
if(blockTransaction != null) {
|
|
||||||
TransactionOutput txOutput = blockTransaction.getTransaction().getOutputs().get((int)txInput.getOutpoint().getIndex());
|
|
||||||
return new BlockTransactionHashIndex(blockTransaction.getHash(), blockTransaction.getHeight(), blockTransaction.getDate(), blockTransaction.getFee(), txInput.getOutpoint().getIndex(), txOutput.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new BlockTransactionHashIndex(txInput.getOutpoint().getHash(), 0, null, null, txInput.getOutpoint().getIndex(), 0);
|
|
||||||
},
|
|
||||||
txInput -> new WalletNode("m/0"),
|
txInput -> new WalletNode("m/0"),
|
||||||
(u, v) -> { throw new IllegalStateException("Duplicate TXOs"); },
|
(u, v) -> { throw new IllegalStateException("Duplicate TXOs"); },
|
||||||
LinkedHashMap::new));
|
LinkedHashMap::new));
|
||||||
|
@ -638,6 +641,18 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BlockTransactionHashIndex getBlockTransactionInput(Map<Sha256Hash, BlockTransaction> inputTransactions, TransactionInput txInput) {
|
||||||
|
if(inputTransactions != null) {
|
||||||
|
BlockTransaction blockTransaction = inputTransactions.get(txInput.getOutpoint().getHash());
|
||||||
|
if(blockTransaction != null) {
|
||||||
|
TransactionOutput txOutput = blockTransaction.getTransaction().getOutputs().get((int) txInput.getOutpoint().getIndex());
|
||||||
|
return new BlockTransactionHashIndex(blockTransaction.getHash(), blockTransaction.getHeight(), blockTransaction.getDate(), blockTransaction.getFee(), txInput.getOutpoint().getIndex(), txOutput.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BlockTransactionHashIndex(txInput.getOutpoint().getHash(), 0, null, null, txInput.getOutpoint().getIndex(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
private Wallet getWalletFromTransactionInputs() {
|
private Wallet getWalletFromTransactionInputs() {
|
||||||
for(TransactionInput txInput : headersForm.getTransaction().getInputs()) {
|
for(TransactionInput txInput : headersForm.getTransaction().getInputs()) {
|
||||||
for(Wallet openWallet : AppServices.get().getOpenWallets().keySet()) {
|
for(Wallet openWallet : AppServices.get().getOpenWallets().keySet()) {
|
||||||
|
@ -1147,7 +1162,12 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
if(feeAmt != null) {
|
if(feeAmt != null) {
|
||||||
updateFee(feeAmt);
|
updateFee(feeAmt);
|
||||||
}
|
}
|
||||||
transactionDiagram.update(getWalletTransaction(event.getInputTransactions()));
|
|
||||||
|
Map<Sha256Hash, BlockTransaction> allFetchedInputTransactions = new HashMap<>(event.getInputTransactions());
|
||||||
|
if(headersForm.getInputTransactions() != null) {
|
||||||
|
allFetchedInputTransactions.putAll(headersForm.getInputTransactions());
|
||||||
|
}
|
||||||
|
transactionDiagram.update(getWalletTransaction(allFetchedInputTransactions));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue