From 3e3e6ee86f92eb42d4e4a166a0c84afb7d096f9d Mon Sep 17 00:00:00 2001 From: = Date: Wed, 13 May 2026 18:34:14 +0200 Subject: [PATCH] Feat: Updated Top bar and Stats page Stats page and top bar now has graphs that change over weeks and value changes --- .../ntnu/idi/idatt2003/g40/mappe/Main.java | 11 +- .../idatt2003/g40/mappe/view/ViewElement.java | 1 + .../financialsummary/SummaryController.java | 23 ++- .../widgets/financialsummary/SummaryView.java | 41 ++++-- .../view/widgets/stats/StatsActions.java | 3 +- .../view/widgets/stats/StatsController.java | 39 ++++-- .../mappe/view/widgets/stats/StatsView.java | 131 +++++++++++------- src/main/resources/styles.css | 23 ++- 8 files changed, 198 insertions(+), 74 deletions(-) diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java index 841fbb4..b2048c1 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java @@ -1,6 +1,7 @@ package edu.ntnu.idi.idatt2003.g40.mappe; import edu.ntnu.idi.idatt2003.g40.mappe.engine.Exchange; +import edu.ntnu.idi.idatt2003.g40.mappe.model.Player; import edu.ntnu.idi.idatt2003.g40.mappe.model.Stock; import edu.ntnu.idi.idatt2003.g40.mappe.service.FileConverter; import edu.ntnu.idi.idatt2003.g40.mappe.service.FileParser; @@ -16,11 +17,13 @@ import edu.ntnu.idi.idatt2003.g40.mappe.view.settings.SettingsController; import edu.ntnu.idi.idatt2003.g40.mappe.view.settings.SettingsView; import java.io.IOException; +import java.math.BigDecimal; import java.util.List; import java.util.Objects; import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.financialsummary.SummaryController; import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.financialsummary.SummaryView; +import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.stats.StatsController; import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.stats.StatsView; import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.topbar.TopBarController; import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.topbar.TopBarView; @@ -62,6 +65,7 @@ public void start(final Stage stage) throws Exception { stocksInFile = converter1.getStocksFromStrings(parser1.readFile()); Exchange exchange = new Exchange("Exchange", stocksInFile); + Player player = new Player("Player 1", new BigDecimal("10000")); // Main menu MainMenuView mainMenuView = new MainMenuView(); @@ -82,7 +86,7 @@ public void start(final Stage stage) throws Exception { // Summary section of the top bar SummaryView summaryView = new SummaryView(); - new SummaryController(summaryView, eventManager, exchange); + new SummaryController(summaryView, eventManager, exchange, player); // Top bar TopBarView topBarView = new TopBarView(summaryView); @@ -90,6 +94,11 @@ public void start(final Stage stage) throws Exception { // Stats page StatsView statsView = new StatsView(); + new StatsController(statsView, + eventManager, + player, + exchange, + stocksInFile); // In-game InGameView inGameView = new InGameView(topBarView, statsView.getRootPane()); diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ViewElement.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ViewElement.java index 0463471..11e91cd 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ViewElement.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ViewElement.java @@ -1,5 +1,6 @@ package edu.ntnu.idi.idatt2003.g40.mappe.view; +import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventData; import edu.ntnu.idi.idatt2003.g40.mappe.utils.Validator; import java.util.EnumMap; import java.util.Map; diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryController.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryController.java index 5f720e8..cd6c58a 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryController.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryController.java @@ -1,31 +1,50 @@ package edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.financialsummary; import edu.ntnu.idi.idatt2003.g40.mappe.engine.Exchange; +import edu.ntnu.idi.idatt2003.g40.mappe.model.Player; import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventManager; import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewController; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; public class SummaryController extends ViewController { private Exchange exchange; + private Player player; + private List playerNetWorthHistory; + /** * {@inheritDoc}. */ public SummaryController(final SummaryView viewElement, final EventManager eventManager, - final Exchange exchange) + final Exchange exchange, + final Player player) throws IllegalArgumentException { this.exchange = exchange; + this.player = player; + this.playerNetWorthHistory = new ArrayList<>(); super(viewElement, eventManager); + getViewElement().setBalance(player.getStartingMoney().floatValue(), player.getStartingMoney().floatValue()); } @Override protected void initInteractions() { + playerNetWorthHistory.add(player.getNetWorth().floatValue()); getViewElement().setOnAction(SummaryActions.NEXT_WEEK, () -> { - exchange.nextWeek(); + exchange.advance(); }); exchange.weekProperty().addListener((observable, o, n) -> { getViewElement().setWeek((Integer) n); + playerNetWorthHistory.add(player.getNetWorth().floatValue()); + getViewElement().updateChart(playerNetWorthHistory); + getViewElement().setBalance(player.getMoney().floatValue(), player.getNetWorth().floatValue()); + }); + + player.getNetWorthAsFloatProperty().addListener((observable, o, n) -> { + getViewElement().setBalance(player.getMoney().floatValue(), player.getNetWorth().floatValue()); }); } } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryView.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryView.java index 816d87f..6527f0a 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryView.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryView.java @@ -12,6 +12,9 @@ import javafx.scene.layout.Region; import javafx.scene.layout.VBox; +import java.math.BigDecimal; +import java.util.List; + public class SummaryView extends ViewElement { private Label balanceLabel; private Label weekLabel; @@ -19,6 +22,8 @@ public class SummaryView extends ViewElement { private LineChart chart; private XYChart.Series dataSeries; private Button nextBtn; + private NumberAxis xAxis; + private NumberAxis yAxis; public SummaryView() { super(new HBox(), SummaryActions.class); @@ -38,20 +43,20 @@ protected void initLayout() { VBox balanceInfo = new VBox(); - titleLabel = new Label("balance/investments"); - balanceLabel = new Label("10000$/0$"); + titleLabel = new Label("Networth"); + balanceLabel = new Label("0$"); Region spacerL = new Region(); VBox.setVgrow(spacerL, Priority.ALWAYS); balanceInfo.getChildren().addAll(titleLabel, spacerL, balanceLabel); - NumberAxis xAxis = new NumberAxis(1, 22, 1); + xAxis = new NumberAxis(1, 10, 1); xAxis.setMinorTickVisible(false); xAxis.setTickMarkVisible(true); xAxis.setTickLabelsVisible(true); - NumberAxis yAxis = new NumberAxis(); + yAxis = new NumberAxis(); yAxis.setTickLabelsVisible(false); yAxis.setTickMarkVisible(false); yAxis.setMinorTickVisible(false); @@ -103,15 +108,35 @@ protected void initStyling() { nextBtn.getStyleClass().add("next-button"); } - public void setBalance(final String text) { - balanceLabel.setText(text); + public void setBalance(final float money, final float netWorth) { + balanceLabel.setText(Math.round(money*100f)/100f + "$ / " + Math.round(netWorth*100f)/100f + "$"); } public void setWeek(int week) { weekLabel.setText("week: " + week); } - public void updateChart(double x, double y) { - dataSeries.getData().add(new XYChart.Data<>(x, y)); + public void updateChart(final List playerNetWorthHistory) { + dataSeries.getData().clear(); + xAxis.setLowerBound(Math.max(1, playerNetWorthHistory.size() - 10)); + xAxis.setUpperBound(Math.max(10, playerNetWorthHistory.size())); + + double min = playerNetWorthHistory.stream() + .min(Float::compare) + .orElse(0.0f); + + double max = playerNetWorthHistory.stream() + .max(Float::compare) + .orElse(100.0f); + + double padding = (max - min) * 0.05; + + yAxis.setLowerBound(Math.max(0, min - padding)); + yAxis.setUpperBound(max + padding); + + yAxis.setTickUnit(Math.round((max - min) / 5)); + for (int i = 0; i < playerNetWorthHistory.size(); i++) { + dataSeries.getData().add(new XYChart.Data<>(i + 1, playerNetWorthHistory.get(i))); + } } } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/stats/StatsActions.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/stats/StatsActions.java index 693d1cd..a724f56 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/stats/StatsActions.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/stats/StatsActions.java @@ -2,5 +2,6 @@ public enum StatsActions { BUY_SHARES, - SELL_SHARES; + SELL_SHARES, + SELECT_STOCK; } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/stats/StatsController.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/stats/StatsController.java index 873ca7b..c3a4544 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/stats/StatsController.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/stats/StatsController.java @@ -2,21 +2,19 @@ import edu.ntnu.idi.idatt2003.g40.mappe.engine.Exchange; import edu.ntnu.idi.idatt2003.g40.mappe.model.Player; -import edu.ntnu.idi.idatt2003.g40.mappe.model.Share; -import edu.ntnu.idi.idatt2003.g40.mappe.model.Transaction; -import edu.ntnu.idi.idatt2003.g40.mappe.service.PurchaseCalculator; -import edu.ntnu.idi.idatt2003.g40.mappe.service.TransactionCalculator; -import edu.ntnu.idi.idatt2003.g40.mappe.service.TransactionFactory; -import edu.ntnu.idi.idatt2003.g40.mappe.service.TransactionType; +import edu.ntnu.idi.idatt2003.g40.mappe.model.Stock; import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventManager; import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewController; +import javafx.scene.control.Button; import java.math.BigDecimal; +import java.util.List; public class StatsController extends ViewController { private Player player; private Exchange exchange; + private List stockList; /** * {@inheritDoc} @@ -24,23 +22,48 @@ public class StatsController extends ViewController { public StatsController(final StatsView viewElement, final EventManager eventManager, final Player player, - final Exchange exchange) + final Exchange exchange, + final List stockList) throws IllegalArgumentException { this.player = player; + this.stockList = stockList; this.exchange = exchange; super(viewElement, eventManager); } + private void handleStockSelection(Stock stock) { + getViewElement().setCurrentStock(stock); + getViewElement().updateGraph(); + } + + private void populateStockList() { + getViewElement().clearStockList(); + for (Stock s : stockList) { + Button stockBtn = getViewElement().createStockButton(s.getSymbol()); + + getViewElement().setOnStockAction(stockBtn, s, selectedStock -> { + handleStockSelection(selectedStock); + }); + } + } + + @Override protected void initInteractions() { + populateStockList(); + getViewElement().setCurrentStock(stockList.getFirst()); + getViewElement().updateGraph(); getViewElement().setOnAction(StatsActions.BUY_SHARES, () -> { BigDecimal amountToBuy = new BigDecimal("1.0"); - Transaction transaction = exchange.buy( + exchange.buy( getViewElement().getCurrentStock().getSymbol(), amountToBuy, player ); + }); + exchange.weekProperty().addListener((observable,o,n) -> { + getViewElement().updateGraph(); }); } } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/stats/StatsView.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/stats/StatsView.java index 0c4c702..31fd47a 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/stats/StatsView.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/stats/StatsView.java @@ -2,7 +2,13 @@ import edu.ntnu.idi.idatt2003.g40.mappe.model.Stock; import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewElement; + +import java.math.BigDecimal; import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.chart.LineChart; import javafx.scene.chart.NumberAxis; @@ -19,14 +25,16 @@ public class StatsView extends ViewElement { private LineChart chart; private XYChart.Series dataSeries; private VBox sidebar; - private ArrayList stocks; - private ArrayList stockStrings; private ArrayList