15 changed files with 337 additions and 28 deletions
@ -0,0 +1,84 @@ |
|||
package com.sparrowwallet.sparrow.control; |
|||
|
|||
import com.sparrowwallet.drongo.BitcoinUnit; |
|||
import com.sparrowwallet.drongo.wallet.Wallet; |
|||
import com.sparrowwallet.sparrow.io.Config; |
|||
import com.sparrowwallet.sparrow.wallet.TransactionEntry; |
|||
import com.sparrowwallet.sparrow.wallet.WalletTransactionsEntry; |
|||
import javafx.beans.NamedArg; |
|||
import javafx.scene.Node; |
|||
import javafx.scene.chart.*; |
|||
|
|||
import java.util.List; |
|||
import java.util.Set; |
|||
import java.util.stream.Collectors; |
|||
|
|||
public class BalanceChart extends LineChart<Number, Number> { |
|||
private XYChart.Series<Number, Number> balanceSeries; |
|||
|
|||
private TransactionEntry selectedEntry; |
|||
|
|||
public BalanceChart(@NamedArg("xAxis") Axis<Number> xAxis, @NamedArg("yAxis") Axis<Number> yAxis) { |
|||
super(xAxis, yAxis); |
|||
} |
|||
|
|||
public void initialize(WalletTransactionsEntry walletTransactionsEntry) { |
|||
balanceSeries = new XYChart.Series<>(); |
|||
getData().add(balanceSeries); |
|||
update(walletTransactionsEntry); |
|||
|
|||
BitcoinUnit unit = Config.get().getBitcoinUnit(); |
|||
setBitcoinUnit(walletTransactionsEntry.getWallet(), unit); |
|||
} |
|||
|
|||
public void update(WalletTransactionsEntry walletTransactionsEntry) { |
|||
balanceSeries.getData().clear(); |
|||
|
|||
List<Data<Number, Number>> balanceDataList = walletTransactionsEntry.getChildren().stream() |
|||
.map(entry -> (TransactionEntry)entry) |
|||
.map(txEntry -> new XYChart.Data<>((Number)txEntry.getBlockTransaction().getDate().getTime(), (Number)txEntry.getBalance(), txEntry)) |
|||
.collect(Collectors.toList()); |
|||
|
|||
if(!balanceDataList.isEmpty()) { |
|||
long min = balanceDataList.stream().map(data -> data.getXValue().longValue()).min(Long::compare).get(); |
|||
long max = balanceDataList.stream().map(data -> data.getXValue().longValue()).max(Long::compare).get(); |
|||
|
|||
DateAxisFormatter dateAxisFormatter = new DateAxisFormatter(max - min); |
|||
NumberAxis xAxis = (NumberAxis)getXAxis(); |
|||
xAxis.setTickLabelFormatter(dateAxisFormatter); |
|||
} |
|||
|
|||
balanceSeries.getData().addAll(balanceDataList); |
|||
|
|||
if(selectedEntry != null) { |
|||
select(selectedEntry); |
|||
} |
|||
} |
|||
|
|||
public void select(TransactionEntry transactionEntry) { |
|||
Set<Node> selectedSymbols = lookupAll(".chart-line-symbol.selected"); |
|||
for(Node selectedSymbol : selectedSymbols) { |
|||
selectedSymbol.getStyleClass().remove("selected"); |
|||
} |
|||
|
|||
for(int i = 0; i < balanceSeries.getData().size(); i++) { |
|||
XYChart.Data<Number, Number> data = balanceSeries.getData().get(i); |
|||
Node symbol = lookup(".chart-line-symbol.data" + i); |
|||
if(symbol != null) { |
|||
if(data.getXValue().equals(transactionEntry.getBlockTransaction().getDate().getTime())) { |
|||
symbol.getStyleClass().add("selected"); |
|||
selectedEntry = transactionEntry; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
public void setBitcoinUnit(Wallet wallet, BitcoinUnit unit) { |
|||
if(unit == null || unit.equals(BitcoinUnit.AUTO)) { |
|||
unit = wallet.getAutoUnit(); |
|||
} |
|||
|
|||
NumberAxis yaxis = (NumberAxis)getYAxis(); |
|||
yaxis.setTickLabelFormatter(new CoinAxisFormatter(yaxis, unit)); |
|||
} |
|||
} |
@ -0,0 +1,44 @@ |
|||
package com.sparrowwallet.sparrow.control; |
|||
|
|||
import javafx.util.StringConverter; |
|||
|
|||
import java.text.DateFormat; |
|||
import java.text.DecimalFormat; |
|||
import java.text.ParseException; |
|||
import java.text.SimpleDateFormat; |
|||
import java.util.Date; |
|||
|
|||
public class DateAxisFormatter extends StringConverter<Number> { |
|||
private static final DateFormat HOUR_FORMAT = new SimpleDateFormat("HH:mm"); |
|||
private static final DateFormat DAY_FORMAT = new SimpleDateFormat("d MMM"); |
|||
private static final DateFormat MONTH_FORMAT = new SimpleDateFormat("MMM yy"); |
|||
|
|||
private final DateFormat dateFormat; |
|||
private int oddCounter; |
|||
|
|||
public DateAxisFormatter(long duration) { |
|||
if(duration < (24 * 60 * 60 * 1000L)) { |
|||
dateFormat = HOUR_FORMAT; |
|||
} else if(duration < (365 * 24 * 60 * 60 * 1000L)) { |
|||
dateFormat = DAY_FORMAT; |
|||
} else { |
|||
dateFormat = MONTH_FORMAT; |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public String toString(Number object) { |
|||
oddCounter++; |
|||
return oddCounter % 3 == 0 ? dateFormat.format(new Date(object.longValue())) : ""; |
|||
} |
|||
|
|||
@Override |
|||
public Number fromString(String string) { |
|||
try { |
|||
Date date = dateFormat.parse(string); |
|||
return date.getTime(); |
|||
} catch (ParseException e) { |
|||
throw new RuntimeException(e); |
|||
} |
|||
} |
|||
} |
Loading…
Reference in new issue