Compare commits

..

No commits in common. "b6fef8d42fc16a30fee10ec844bb386197afdc0a" and "a3558b33e6f4cfa97e6cb46d9efa5e62383d7489" have entirely different histories.

5 changed files with 6 additions and 80 deletions

View File

@ -2,7 +2,6 @@ package com.andrewlalis.perfin.control;
import com.andrewlalis.javafx_scene_router.RouteSelectionListener; import com.andrewlalis.javafx_scene_router.RouteSelectionListener;
import com.andrewlalis.perfin.model.Profile; import com.andrewlalis.perfin.model.Profile;
import com.andrewlalis.perfin.view.component.module.TotalAssetsGraphModule;
import com.andrewlalis.perfin.view.component.module.*; import com.andrewlalis.perfin.view.component.module.*;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.geometry.Bounds; import javafx.geometry.Bounds;
@ -31,10 +30,7 @@ public class DashboardController implements RouteSelectionListener {
var m4 = new VendorSpendChartModule(modulesFlowPane); var m4 = new VendorSpendChartModule(modulesFlowPane);
m4.columnsProperty.set(2); m4.columnsProperty.set(2);
var m5 = new TotalAssetsGraphModule(modulesFlowPane); modulesFlowPane.getChildren().addAll(accountsModule, transactionsModule, m3, m4);
m5.columnsProperty.set(1);
modulesFlowPane.getChildren().addAll(accountsModule, transactionsModule, m3, m4, m5);
} }
@Override @Override

View File

@ -9,7 +9,6 @@ import javafx.application.Platform;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.nio.file.Path; import java.nio.file.Path;
import java.time.Instant;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -112,16 +111,15 @@ public interface DataSource {
/** /**
* Gets a list of combined total assets for each currency that's tracked, * Gets a list of combined total assets for each currency that's tracked,
* ordered with highest assets first. * ordered with highest assets first.
* @param timestamp The timestamp at which to get the balance.
* @return A future that resolves to the list of amounts for each currency. * @return A future that resolves to the list of amounts for each currency.
*/ */
default CompletableFuture<List<MoneyValue>> getCombinedAccountBalances(Instant timestamp) { default CompletableFuture<List<MoneyValue>> getCombinedAccountBalances() {
return mapRepoAsync(AccountRepository.class, repo -> { return mapRepoAsync(AccountRepository.class, repo -> {
List<Account> accounts = repo.findAll(PageRequest.unpaged()).items(); List<Account> accounts = repo.findAll(PageRequest.unpaged()).items();
Map<Currency, BigDecimal> totals = new HashMap<>(); Map<Currency, BigDecimal> totals = new HashMap<>();
for (var account : accounts) { for (var account : accounts) {
BigDecimal currencyTotal = totals.computeIfAbsent(account.getCurrency(), c -> BigDecimal.ZERO); BigDecimal currencyTotal = totals.computeIfAbsent(account.getCurrency(), c -> BigDecimal.ZERO);
BigDecimal accountBalance = repo.deriveBalance(account.id, timestamp); BigDecimal accountBalance = repo.deriveCurrentBalance(account.id);
if (account.getType() == AccountType.CREDIT_CARD) accountBalance = accountBalance.negate(); if (account.getType() == AccountType.CREDIT_CARD) accountBalance = accountBalance.negate();
totals.put(account.getCurrency(), currencyTotal.add(accountBalance)); totals.put(account.getCurrency(), currencyTotal.add(accountBalance));
} }
@ -133,8 +131,4 @@ public interface DataSource {
return values; return values;
}); });
} }
default CompletableFuture<List<MoneyValue>> getCombinedAccountBalances() {
return getCombinedAccountBalances(Instant.now());
}
} }

View File

@ -52,7 +52,6 @@ public abstract class PieChartModule extends DashboardModule {
this.timeRangeChoiceBox.getItems().addAll(RANGE_CHOICES); this.timeRangeChoiceBox.getItems().addAll(RANGE_CHOICES);
this.timeRangeChoiceBox.getSelectionModel().select("All Time"); this.timeRangeChoiceBox.getSelectionModel().select("All Time");
this.currencyChoiceBox.managedProperty().bind(this.currencyChoiceBox.visibleProperty());
PieChart chart = new PieChart(chartData); PieChart chart = new PieChart(chartData);
chart.setLegendVisible(false); chart.setLegendVisible(false);
@ -69,7 +68,9 @@ public abstract class PieChartModule extends DashboardModule {
chartData.clear(); chartData.clear();
} }
}); });
timeRangeChoiceBox.valueProperty().addListener((observable, oldValue, newValue) -> renderChart()); timeRangeChoiceBox.valueProperty().addListener((observable, oldValue, newValue) -> {
renderChart();
});
} }
@Override @Override
@ -135,7 +136,6 @@ public abstract class PieChartModule extends DashboardModule {
} else { } else {
currencyChoiceBox.getSelectionModel().selectFirst(); currencyChoiceBox.getSelectionModel().selectFirst();
} }
currencyChoiceBox.setVisible(orderedCurrencies.size() > 1);
}); });
}); });
} }

View File

@ -1,63 +0,0 @@
package com.andrewlalis.perfin.view.component.module;
import com.andrewlalis.perfin.model.Profile;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.chart.*;
import javafx.scene.layout.Pane;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* A module for visualizing the total asset value in the user's profile over
* a configurable period of time.
*/
public class TotalAssetsGraphModule extends DashboardModule {
private final ObservableList<XYChart.Data<String, Number>> totalAssetDataPoints = FXCollections.observableArrayList();
public TotalAssetsGraphModule(Pane parent) {
super(parent);
Axis<String> xAxis = new CategoryAxis();
Axis<Number> yAxis = new NumberAxis();
LineChart<String, Number> chart = new LineChart<>(xAxis, yAxis, FXCollections.observableArrayList(
new XYChart.Series<>("Total Assets", totalAssetDataPoints)
));
chart.setLegendVisible(false);
this.getChildren().add(new ModuleHeader(
"Total Assets over Time"
));
this.getChildren().add(chart);
}
@Override
public void refreshContents() {
totalAssetDataPoints.clear();
String[] dateLabels = new String[12];
double[] values = new double[12];
CompletableFuture<?>[] futures = new CompletableFuture[12];
for (int i = 0; i < 12; i++) {
final int idx = i;
Instant timestamp = Instant.now().minus((12 - i - 1) * 30, ChronoUnit.DAYS);
dateLabels[i] = LocalDate.from(timestamp.atZone(ZoneId.systemDefault())).toString();
futures[i] = Profile.getCurrent().dataSource().getCombinedAccountBalances(timestamp)
.thenAccept(moneyValues -> {
values[idx] = moneyValues.getFirst().amount().doubleValue();
});
}
CompletableFuture.allOf(futures).thenRun(() -> {
List<XYChart.Data<String, Number>> dataPoints = new ArrayList<>(12);
for (int i = 0; i < 12; i++) {
dataPoints.add(new XYChart.Data<>(dateLabels[i], values[i]));
}
Platform.runLater(() -> totalAssetDataPoints.addAll(dataPoints));
});
}
}

View File

@ -20,5 +20,4 @@ module com.andrewlalis.perfin {
opens com.andrewlalis.perfin.view.component to javafx.fxml; opens com.andrewlalis.perfin.view.component to javafx.fxml;
opens com.andrewlalis.perfin.view.component.validation to javafx.fxml; opens com.andrewlalis.perfin.view.component.validation to javafx.fxml;
exports com.andrewlalis.perfin.model.history to javafx.graphics; exports com.andrewlalis.perfin.model.history to javafx.graphics;
opens com.andrewlalis.perfin.view.component.module to javafx.fxml;
} }