diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java index 9e9d27f2..5c5ab181 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java @@ -5,17 +5,26 @@ import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.control.UtxosTreeTable; import com.sparrowwallet.sparrow.event.WalletHistoryChangedEvent; import com.sparrowwallet.sparrow.event.WalletNodesChangedEvent; +import javafx.collections.ListChangeListener; import javafx.fxml.FXML; import javafx.fxml.Initializable; +import javafx.scene.chart.BarChart; +import javafx.scene.chart.XYChart; import java.net.URL; +import java.util.List; +import java.util.Optional; import java.util.ResourceBundle; +import java.util.stream.Collectors; public class UtxosController extends WalletFormController implements Initializable { @FXML private UtxosTreeTable utxosTable; + @FXML + private BarChart utxosChart; + @Override public void initialize(URL location, ResourceBundle resources) { EventManager.get().register(this); @@ -24,12 +33,60 @@ public class UtxosController extends WalletFormController implements Initializab @Override public void initializeView() { utxosTable.initialize(getWalletForm().getWalletUtxosEntry()); + initializeChart(getWalletForm().getWalletUtxosEntry()); + } + + private void initializeChart(WalletUtxosEntry walletUtxosEntry) { + XYChart.Series utxoSeries = new XYChart.Series<>(); + + List> utxoDataList = walletUtxosEntry.getChildren().stream() + .map(UtxoData::new) + .map(data -> new XYChart.Data<>(data.name, data.value, data.entry)) + .collect(Collectors.toList()); + utxoSeries.getData().addAll(utxoDataList); + walletUtxosEntry.getChildren().forEach(entry -> entry.labelProperty().addListener((observable, oldValue, newValue) -> { + Optional> optData = utxoSeries.getData().stream().filter(data -> data.getExtraValue().equals(entry)).findFirst(); + if(optData.isPresent()) { + int index = utxoSeries.getData().indexOf(optData.get()); + utxoSeries.getData().set(index, new XYChart.Data<>(newValue, optData.get().getYValue(), optData.get().getExtraValue())); + } + })); + utxoSeries.getData().sort((o1, o2) -> (int) (o2.getYValue().longValue() - o1.getYValue().longValue())); + + utxosChart.getData().clear(); + utxosChart.getData().add(utxoSeries); + + walletUtxosEntry.getChildren().addListener((ListChangeListener) change -> { + while(change.next()) { + if(change.wasAdded()) { + List> addedList = change.getAddedSubList().stream().map(UtxoData::new).map(data -> new XYChart.Data<>(data.name, data.value, data.entry)).collect(Collectors.toList()); + utxoSeries.getData().addAll(addedList); + utxoSeries.getData().sort((o1, o2) -> (int) (o2.getYValue().longValue() - o1.getYValue().longValue())); + change.getAddedSubList().forEach(entry -> entry.labelProperty().addListener((observable, oldValue, newValue) -> { + Optional> optData = utxoSeries.getData().stream().filter(data -> data.getExtraValue().equals(entry)).findFirst(); + if(optData.isPresent()) { + int index = utxoSeries.getData().indexOf(optData.get()); + utxoSeries.getData().set(index, new XYChart.Data<>(newValue, optData.get().getYValue(), optData.get().getExtraValue())); + } + })); + } + + if(change.wasRemoved()) { + change.getRemoved().forEach(entry -> { + UtxoData utxoData = new UtxoData(entry); + Optional> optRemovedData = utxoSeries.getData().stream().filter(data -> data.getExtraValue().equals(utxoData.entry)).findFirst(); + optRemovedData.ifPresent(removedData -> utxoSeries.getData().remove(removedData)); + }); + } + } + }); } @Subscribe public void walletNodesChanged(WalletNodesChangedEvent event) { if(event.getWallet().equals(walletForm.getWallet())) { utxosTable.updateAll(getWalletForm().getWalletUtxosEntry()); + initializeChart(getWalletForm().getWalletUtxosEntry()); } } @@ -39,4 +96,16 @@ public class UtxosController extends WalletFormController implements Initializab utxosTable.updateHistory(event.getHistoryChangedNodes()); } } + + private static class UtxoData { + public final Entry entry; + public final String name; + public final Number value; + + public UtxoData(Entry entry) { + this.entry = entry; + this.name = entry.getLabel() != null && !entry.getLabel().isEmpty() ? entry.getLabel() : ((UtxoEntry)entry).getDescription(); + this.value = entry.getValue(); + } + } } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletUtxosEntry.java b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletUtxosEntry.java index a6a349f1..9cc32c40 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletUtxosEntry.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletUtxosEntry.java @@ -39,6 +39,7 @@ public class WalletUtxosEntry extends Entry { utxoEntry.setDuplicateAddress(true); } else { addressMap.put(address, utxoEntry); + utxoEntry.setDuplicateAddress(false); } } } diff --git a/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.css b/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.css index 2e809bff..f7afc201 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.css +++ b/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.css @@ -2,4 +2,8 @@ -fx-font-weight: bold; -fx-font-size: 1.2em; -fx-padding: 10 0 10 0; +} + +.chart-bar { + -fx-bar-fill: rgba(105, 108, 119, 0.6); } \ No newline at end of file diff --git a/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.fxml b/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.fxml index 47a3a523..954da1de 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.fxml @@ -9,6 +9,8 @@ + + @@ -30,7 +32,14 @@
- + + + + + + + +