mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-24 12:46:45 +00:00
utxo chart rewrite
This commit is contained in:
parent
67d624f049
commit
d8c94504c3
5 changed files with 102 additions and 72 deletions
|
@ -0,0 +1,80 @@
|
||||||
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
|
import com.sparrowwallet.sparrow.wallet.Entry;
|
||||||
|
import com.sparrowwallet.sparrow.wallet.UtxoEntry;
|
||||||
|
import com.sparrowwallet.sparrow.wallet.WalletUtxosEntry;
|
||||||
|
import javafx.beans.NamedArg;
|
||||||
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.chart.Axis;
|
||||||
|
import javafx.scene.chart.BarChart;
|
||||||
|
import javafx.scene.chart.XYChart;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class UtxosChart extends BarChart<String, Number> {
|
||||||
|
private static final int MAX_BARS = 8;
|
||||||
|
private static final String OTHER_CATEGORY = "Other";
|
||||||
|
|
||||||
|
private Entry selectedEntry;
|
||||||
|
|
||||||
|
private XYChart.Series<String, Number> utxoSeries;
|
||||||
|
|
||||||
|
public UtxosChart(@NamedArg("xAxis") Axis<String> xAxis, @NamedArg("yAxis") Axis<Number> yAxis) {
|
||||||
|
super(xAxis, yAxis);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initialize(WalletUtxosEntry walletUtxosEntry) {
|
||||||
|
utxoSeries = new XYChart.Series<>();
|
||||||
|
getData().add(utxoSeries);
|
||||||
|
update(walletUtxosEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(WalletUtxosEntry walletUtxosEntry) {
|
||||||
|
List<Data<String, Number>> utxoDataList = walletUtxosEntry.getChildren().stream()
|
||||||
|
.map(entry -> new XYChart.Data<>(entry.getLabel() != null && !entry.getLabel().isEmpty() ? entry.getLabel() : ((UtxoEntry)entry).getDescription(), (Number)entry.getValue(), entry))
|
||||||
|
.sorted((o1, o2) -> (int) (o2.getYValue().longValue() - o1.getYValue().longValue()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if(utxoDataList.size() > MAX_BARS) {
|
||||||
|
Long otherTotal = utxoDataList.subList(MAX_BARS - 1, utxoDataList.size()).stream().mapToLong(data -> data.getYValue().longValue()).sum();
|
||||||
|
utxoDataList = utxoDataList.subList(0, MAX_BARS - 1);
|
||||||
|
utxoDataList.add(new XYChart.Data<>(OTHER_CATEGORY, otherTotal));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < utxoDataList.size(); i++) {
|
||||||
|
XYChart.Data<String, Number> newData = utxoDataList.get(i);
|
||||||
|
if(i < utxoSeries.getData().size()) {
|
||||||
|
XYChart.Data<String, Number> existingData = utxoSeries.getData().get(i);
|
||||||
|
if(!newData.getXValue().equals(existingData.getXValue()) || !newData.getYValue().equals(existingData.getYValue()) || (newData.getExtraValue() != null && !newData.getExtraValue().equals(existingData.getExtraValue()))) {
|
||||||
|
utxoSeries.getData().set(i, newData);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
utxoSeries.getData().add(newData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(utxoSeries.getData().size() > utxoDataList.size()) {
|
||||||
|
utxoSeries.getData().remove(utxoDataList.size() - 1, utxoSeries.getData().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(selectedEntry != null) {
|
||||||
|
select(selectedEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void select(Entry entry) {
|
||||||
|
for(int i = 0; i < utxoSeries.getData().size(); i++) {
|
||||||
|
XYChart.Data<String, Number> data = utxoSeries.getData().get(i);
|
||||||
|
Node bar = lookup(".data" + i);
|
||||||
|
if(bar != null) {
|
||||||
|
if(data.getExtraValue() != null && data.getExtraValue().equals(entry)) {
|
||||||
|
bar.getStyleClass().add("selected");
|
||||||
|
this.selectedEntry = entry;
|
||||||
|
} else {
|
||||||
|
bar.getStyleClass().remove("selected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -70,8 +70,8 @@ public class UtxosTreeTable extends TreeTableView<Entry> {
|
||||||
setPlaceholder(new Label("No unspent outputs"));
|
setPlaceholder(new Label("No unspent outputs"));
|
||||||
setEditable(true);
|
setEditable(true);
|
||||||
setColumnResizePolicy(TreeTableView.CONSTRAINED_RESIZE_POLICY);
|
setColumnResizePolicy(TreeTableView.CONSTRAINED_RESIZE_POLICY);
|
||||||
dateCol.setSortType(TreeTableColumn.SortType.DESCENDING);
|
amountCol.setSortType(TreeTableColumn.SortType.DESCENDING);
|
||||||
getSortOrder().add(dateCol);
|
getSortOrder().add(amountCol);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateAll(WalletUtxosEntry rootEntry) {
|
public void updateAll(WalletUtxosEntry rootEntry) {
|
||||||
|
@ -80,9 +80,9 @@ public class UtxosTreeTable extends TreeTableView<Entry> {
|
||||||
rootItem.setExpanded(true);
|
rootItem.setExpanded(true);
|
||||||
|
|
||||||
if(getColumns().size() > 0 && getSortOrder().isEmpty()) {
|
if(getColumns().size() > 0 && getSortOrder().isEmpty()) {
|
||||||
TreeTableColumn<Entry, ?> dateCol = getColumns().get(0);
|
TreeTableColumn<Entry, ?> amountCol = getColumns().get(getColumns().size() - 1);
|
||||||
getSortOrder().add(dateCol);
|
getSortOrder().add(amountCol);
|
||||||
dateCol.setSortType(TreeTableColumn.SortType.DESCENDING);
|
amountCol.setSortType(TreeTableColumn.SortType.DESCENDING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,21 +2,16 @@ package com.sparrowwallet.sparrow.wallet;
|
||||||
|
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
|
import com.sparrowwallet.sparrow.control.UtxosChart;
|
||||||
import com.sparrowwallet.sparrow.control.UtxosTreeTable;
|
import com.sparrowwallet.sparrow.control.UtxosTreeTable;
|
||||||
import com.sparrowwallet.sparrow.event.WalletEntryLabelChangedEvent;
|
import com.sparrowwallet.sparrow.event.WalletEntryLabelChangedEvent;
|
||||||
import com.sparrowwallet.sparrow.event.WalletHistoryChangedEvent;
|
import com.sparrowwallet.sparrow.event.WalletHistoryChangedEvent;
|
||||||
import com.sparrowwallet.sparrow.event.WalletNodesChangedEvent;
|
import com.sparrowwallet.sparrow.event.WalletNodesChangedEvent;
|
||||||
import javafx.collections.ListChangeListener;
|
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
import javafx.scene.chart.BarChart;
|
|
||||||
import javafx.scene.chart.XYChart;
|
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class UtxosController extends WalletFormController implements Initializable {
|
public class UtxosController extends WalletFormController implements Initializable {
|
||||||
|
|
||||||
|
@ -24,7 +19,7 @@ public class UtxosController extends WalletFormController implements Initializab
|
||||||
private UtxosTreeTable utxosTable;
|
private UtxosTreeTable utxosTable;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private BarChart<String, Number> utxosChart;
|
private UtxosChart utxosChart;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
|
@ -34,52 +29,11 @@ public class UtxosController extends WalletFormController implements Initializab
|
||||||
@Override
|
@Override
|
||||||
public void initializeView() {
|
public void initializeView() {
|
||||||
utxosTable.initialize(getWalletForm().getWalletUtxosEntry());
|
utxosTable.initialize(getWalletForm().getWalletUtxosEntry());
|
||||||
initializeChart(getWalletForm().getWalletUtxosEntry());
|
utxosChart.initialize(getWalletForm().getWalletUtxosEntry());
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeChart(WalletUtxosEntry walletUtxosEntry) {
|
utxosTable.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
XYChart.Series<String, Number> utxoSeries = new XYChart.Series<>();
|
Entry entry = newValue.getValue();
|
||||||
|
utxosChart.select(entry);
|
||||||
List<XYChart.Data<String, Number>> 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<XYChart.Data<String, Number>> 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<Entry>) change -> {
|
|
||||||
while(change.next()) {
|
|
||||||
if(change.wasAdded()) {
|
|
||||||
List<XYChart.Data<String, Number>> 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<XYChart.Data<String, Number>> 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<XYChart.Data<String, Number>> optRemovedData = utxoSeries.getData().stream().filter(data -> data.getExtraValue().equals(utxoData.entry)).findFirst();
|
|
||||||
optRemovedData.ifPresent(removedData -> utxoSeries.getData().remove(removedData));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +41,7 @@ public class UtxosController extends WalletFormController implements Initializab
|
||||||
public void walletNodesChanged(WalletNodesChangedEvent event) {
|
public void walletNodesChanged(WalletNodesChangedEvent event) {
|
||||||
if(event.getWallet().equals(walletForm.getWallet())) {
|
if(event.getWallet().equals(walletForm.getWallet())) {
|
||||||
utxosTable.updateAll(getWalletForm().getWalletUtxosEntry());
|
utxosTable.updateAll(getWalletForm().getWalletUtxosEntry());
|
||||||
initializeChart(getWalletForm().getWalletUtxosEntry());
|
utxosChart.update(getWalletForm().getWalletUtxosEntry());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +49,7 @@ public class UtxosController extends WalletFormController implements Initializab
|
||||||
public void walletHistoryChanged(WalletHistoryChangedEvent event) {
|
public void walletHistoryChanged(WalletHistoryChangedEvent event) {
|
||||||
if(event.getWallet().equals(walletForm.getWallet())) {
|
if(event.getWallet().equals(walletForm.getWallet())) {
|
||||||
utxosTable.updateHistory(event.getHistoryChangedNodes());
|
utxosTable.updateHistory(event.getHistoryChangedNodes());
|
||||||
|
utxosChart.update(getWalletForm().getWalletUtxosEntry());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,18 +57,7 @@ public class UtxosController extends WalletFormController implements Initializab
|
||||||
public void walletEntryLabelChanged(WalletEntryLabelChangedEvent event) {
|
public void walletEntryLabelChanged(WalletEntryLabelChangedEvent event) {
|
||||||
if(event.getWallet().equals(walletForm.getWallet())) {
|
if(event.getWallet().equals(walletForm.getWallet())) {
|
||||||
utxosTable.updateLabel(event.getEntry());
|
utxosTable.updateLabel(event.getEntry());
|
||||||
}
|
utxosChart.update(getWalletForm().getWalletUtxosEntry());
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,4 +6,8 @@
|
||||||
|
|
||||||
.chart-bar {
|
.chart-bar {
|
||||||
-fx-bar-fill: rgba(105, 108, 119, 0.6);
|
-fx-bar-fill: rgba(105, 108, 119, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-bar.selected {
|
||||||
|
-fx-bar-fill: rgba(30, 136, 207, 0.6);
|
||||||
}
|
}
|
|
@ -11,6 +11,8 @@
|
||||||
<?import com.sparrowwallet.sparrow.control.UtxosTreeTable?>
|
<?import com.sparrowwallet.sparrow.control.UtxosTreeTable?>
|
||||||
<?import javafx.scene.chart.CategoryAxis?>
|
<?import javafx.scene.chart.CategoryAxis?>
|
||||||
<?import javafx.scene.chart.NumberAxis?>
|
<?import javafx.scene.chart.NumberAxis?>
|
||||||
|
<?import com.sparrowwallet.sparrow.control.UtxosChart?>
|
||||||
|
|
||||||
<GridPane hgap="10.0" vgap="10.0" stylesheets="@utxos.css, @wallet.css, @../general.css" styleClass="wallet-pane" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.wallet.UtxosController">
|
<GridPane hgap="10.0" vgap="10.0" stylesheets="@utxos.css, @wallet.css, @../general.css" styleClass="wallet-pane" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.wallet.UtxosController">
|
||||||
<padding>
|
<padding>
|
||||||
<Insets left="25.0" right="25.0" top="15.0" bottom="25.0" />
|
<Insets left="25.0" right="25.0" top="15.0" bottom="25.0" />
|
||||||
|
@ -32,14 +34,14 @@
|
||||||
</BorderPane>
|
</BorderPane>
|
||||||
<BorderPane GridPane.columnIndex="0" GridPane.rowIndex="1">
|
<BorderPane GridPane.columnIndex="0" GridPane.rowIndex="1">
|
||||||
<center>
|
<center>
|
||||||
<BarChart fx:id="utxosChart" legendVisible="false" verticalGridLinesVisible="false" animated="false">
|
<UtxosChart fx:id="utxosChart" legendVisible="false" verticalGridLinesVisible="false" animated="false">
|
||||||
<xAxis>
|
<xAxis>
|
||||||
<CategoryAxis side="BOTTOM" animated="false" />
|
<CategoryAxis side="BOTTOM" animated="false" />
|
||||||
</xAxis>
|
</xAxis>
|
||||||
<yAxis>
|
<yAxis>
|
||||||
<NumberAxis side="LEFT" />
|
<NumberAxis side="LEFT" />
|
||||||
</yAxis>
|
</yAxis>
|
||||||
</BarChart>
|
</UtxosChart>
|
||||||
</center>
|
</center>
|
||||||
</BorderPane>
|
</BorderPane>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
|
|
Loading…
Reference in a new issue