Skip to content

Commit

Permalink
Merge pull request #99 from marcus-ny/branch-enhance-analytics-gui
Browse files Browse the repository at this point in the history
Implement analytics GUI (Part 2 - Piechart Display)
  • Loading branch information
Joseph31416 authored Apr 4, 2024
2 parents 214941c + 8c6bee6 commit 2cdf8d3
Show file tree
Hide file tree
Showing 10 changed files with 250 additions and 38 deletions.
4 changes: 2 additions & 2 deletions src/main/java/seedu/address/logic/Logic.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.ReadOnlyAddressBook;
import seedu.address.model.person.Analytics;
import seedu.address.model.analytics.DashboardData;
import seedu.address.model.person.Loan;
import seedu.address.model.person.Person;

Expand Down Expand Up @@ -67,5 +67,5 @@ public interface Logic {

void setToPersonTab();

ObjectProperty<Analytics> getAnalytics();
ObjectProperty<DashboardData> getAnalytics();
}
6 changes: 3 additions & 3 deletions src/main/java/seedu/address/logic/LogicManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.Model;
import seedu.address.model.ReadOnlyAddressBook;
import seedu.address.model.person.Analytics;
import seedu.address.model.analytics.DashboardData;
import seedu.address.model.person.Loan;
import seedu.address.model.person.Person;
import seedu.address.storage.Storage;
Expand Down Expand Up @@ -106,8 +106,8 @@ public BooleanProperty getIsLoansTab() {
}

@Override
public ObjectProperty<Analytics> getAnalytics() {
return model.getAnalytics();
public ObjectProperty<DashboardData> getAnalytics() {
return model.getDashboardData();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@ public CommandResult execute(Model model) throws CommandException {
}

Person targetPerson = lastShownList.get(targetIndex.getZeroBased());
model.updateFilteredLoanList(loan -> loan.isAssignedTo(targetPerson) && loan.isActive());
model.updateFilteredLoanList(loan -> loan.isAssignedTo(targetPerson));
Analytics targetAnalytics = Analytics.getAnalytics(model.getSortedLoanList());
// TODO: Implement analytics GUI display logic
model.setAnalytics(targetAnalytics);

model.generateDashboardData(targetAnalytics);
model.setIsAnalyticsTab(true);
return new CommandResult(MESSAGE_SUCCESS + model.getAnalytics().getValue(),

return new CommandResult(MESSAGE_SUCCESS + " for " + targetPerson.getName() + " ",
false, false, false);
}

Expand Down
9 changes: 4 additions & 5 deletions src/main/java/seedu/address/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import javafx.collections.ObservableList;
import seedu.address.commons.core.GuiSettings;
import seedu.address.logic.commands.LinkLoanCommand;
import seedu.address.model.analytics.DashboardData;
import seedu.address.model.person.Analytics;
import seedu.address.model.person.Loan;
import seedu.address.model.person.Person;
Expand Down Expand Up @@ -150,11 +151,9 @@ public interface Model {

void markLoan(Loan loanToMark);

void unmarkLoan(Loan loanToUnmark);

void setAnalytics(Analytics analytics);

ObjectProperty<Analytics> getAnalytics();
void generateDashboardData(Analytics analytics);

void unmarkLoan(Loan loanToUnmark);

ObjectProperty<DashboardData> getDashboardData();
}
17 changes: 10 additions & 7 deletions src/main/java/seedu/address/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;

import java.nio.file.Path;
import java.util.Date;
import java.util.List;
import java.util.function.Predicate;
import java.util.logging.Logger;
Expand All @@ -18,6 +19,7 @@
import seedu.address.commons.core.GuiSettings;
import seedu.address.commons.core.LogsCenter;
import seedu.address.logic.commands.LinkLoanCommand;
import seedu.address.model.analytics.DashboardData;
import seedu.address.model.person.Analytics;
import seedu.address.model.person.Loan;
import seedu.address.model.person.Person;
Expand All @@ -35,7 +37,7 @@ public class ModelManager implements Model {
private final SortedList<Loan> sortedLoans;
private final BooleanProperty isLoansTab = new SimpleBooleanProperty(false);
private final BooleanProperty isAnalyticsTab = new SimpleBooleanProperty(false);
private final ObjectProperty<Analytics> targetAnalytics = new SimpleObjectProperty<>();
private final ObjectProperty<DashboardData> dashboardData = new SimpleObjectProperty<>();

/**
* Initializes a ModelManager with the given addressBook and userPrefs.
Expand All @@ -50,7 +52,7 @@ public ModelManager(ReadOnlyAddressBook addressBook, ReadOnlyUserPrefs userPrefs
filteredPersons = new FilteredList<>(this.addressBook.getPersonList());
filteredLoans = new FilteredList<>(this.addressBook.getLoanList());
sortedLoans = new SortedList<>(filteredLoans, Loan::compareTo);
targetAnalytics.setValue(null);
dashboardData.setValue(null);
}

public ModelManager() {
Expand Down Expand Up @@ -244,13 +246,14 @@ public void setIsAnalyticsTab(Boolean isAnalyticsTab) {
}

@Override
public ObjectProperty<Analytics> getAnalytics() {
return targetAnalytics;
public ObjectProperty<DashboardData> getDashboardData() {
return dashboardData;
}

@Override
public void setAnalytics(Analytics analytics) {
targetAnalytics.setValue(analytics);
public void generateDashboardData(Analytics analytics) {
float impactBenchmark = this.addressBook.getUniqueLoanList().getMaxLoanValue();
Date urgencyBenchmark = this.addressBook.getUniqueLoanList().getEarliestReturnDate();
dashboardData.setValue(new DashboardData(analytics, impactBenchmark, urgencyBenchmark));
}

}
77 changes: 77 additions & 0 deletions src/main/java/seedu/address/model/analytics/DashboardData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package seedu.address.model.analytics;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;

import seedu.address.model.person.Analytics;


/**
* Represents the analytics data of the dashboard with 3 values
* - Analytics object to be displayed
* - Max loan value
* - Earliest return date
*/
public class DashboardData {
private Analytics analytics;
private float maxLoanValue;
private Date earliestReturnDate;

/**
* Creates a DashboardData object with the given analytics, max loan value and earliest return date
*
* @param analytics analytics object to be displayed
* @param maxLoanValue maximum loan value of all loans
* @param earliestReturnDate earliest return date of all loans (not returned and not overdue)
*/
public DashboardData(Analytics analytics, float maxLoanValue, Date earliestReturnDate) {
this.analytics = analytics;
this.maxLoanValue = maxLoanValue;
this.earliestReturnDate = earliestReturnDate;
}

public Analytics getAnalytics() {
return analytics;
}

public float getMaxLoanValue() {
return maxLoanValue;
}

/**
* Calculates the impact index of the dashboard data
* Impact index is calculated as the ratio of the average loan value to the maximum loan value
*
* @return impact index between 0 and 1
*/
public float getImpactIndex() {
return analytics.getAverageLoanValue() / maxLoanValue;
}

/**
* Calculates the urgency index of the dashboard data
* Urgency index is calculated as the ratio of the number of days between the earliest return date and the current
* to the number of days between the earliest return date and the benchmark date
*
* @return urgency index between 0 and 1
*/
public Float getUrgencyIndex() {
// Should take extra measures to ensure no overdue loans are used for calculations
if (analytics.getEarliestReturnDate() == null || earliestReturnDate == null) {
return null;
}
LocalDate target = analytics.getEarliestReturnDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate benchmark = this.earliestReturnDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate now = LocalDate.now();
long dayDiffBenchmark = benchmark.toEpochDay() - now.toEpochDay();
long dayDiffTarget = target.toEpochDay() - now.toEpochDay();
return (float) dayDiffBenchmark / dayDiffTarget;
}

@Override
public String toString() {
return "Analytics: " + analytics + ", Max Loan Value: " + maxLoanValue + ", Earliest Return Date: "
+ earliestReturnDate;
}
}
43 changes: 43 additions & 0 deletions src/main/java/seedu/address/model/person/UniqueLoanList.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public boolean contains(Loan toCheck) {

/**
* Adds a loan to the list of loans.
*
* @param loan A valid loan.
*/
public void addLoan(Loan loan) {
Expand All @@ -50,6 +51,7 @@ public void addLoan(Loan loan) {

/**
* Adds a loan to the list of loans.
*
* @param value A valid value.
* @param startDate A valid start date.
* @param returnDate A valid return date.
Expand All @@ -62,6 +64,7 @@ public Loan addLoan(float value, Date startDate, Date returnDate, Person assigne

/**
* Adds a loan to the list of loans.
*
* @param loanDescription A valid LinkLoanDescriptor, which contains details about the loan to be added.
*/
public Loan addLoan(LinkLoanDescriptor loanDescription, Person assignee) {
Expand All @@ -73,6 +76,7 @@ public Loan addLoan(LinkLoanDescriptor loanDescription, Person assignee) {

/**
* Adds a loan to the list of loans.
*
* @param value A valid value.
* @param startDate A valid start date.
* @param returnDate A valid return date.
Expand All @@ -91,6 +95,7 @@ public void addLoan(float value, String startDate, String returnDate, Person ass

/**
* Removes a loan from the list of loans.
*
* @param toRemove A valid loan.
*/
public void removeLoan(Loan toRemove) {
Expand Down Expand Up @@ -147,6 +152,7 @@ public Loan getLoanById(int id) {

/**
* Marks a loan as returned.
*
* @param idx A valid index.
*/
public void markLoanAsReturned(int idx) {
Expand All @@ -155,6 +161,7 @@ public void markLoanAsReturned(int idx) {

/**
* Marks a loan as returned.
*
* @param id A valid id.
*/
public void markLoanAsReturnedById(int id) {
Expand All @@ -166,6 +173,7 @@ public void markLoanAsReturnedById(int id) {

/**
* Marks a loan as not returned.
*
* @param loanToMark A valid loan.
*/
public void markLoan(Loan loanToMark) {
Expand Down Expand Up @@ -235,6 +243,7 @@ public void unmarkLoan(int idx) {
public int size() {
return internalList.size();
}

@Override
public String toString() {
String output = "Loans:\n";
Expand Down Expand Up @@ -291,6 +300,7 @@ private boolean loansAreUnique(List<Loan> loans) {

/**
* Removes all loans attached to a person.
*
* @param key A valid person.
*/
public void removeLoansAttachedTo(Person key) {
Expand All @@ -300,6 +310,7 @@ public void removeLoansAttachedTo(Person key) {

/**
* Modifies the assignee of all loans attached to a person.
*
* @param target A valid person.
* @param editedPerson A valid person.
*/
Expand All @@ -315,4 +326,36 @@ public void modifyLoanAssignee(Person target, Person editedPerson) {
internalList.set(0, internalList.get(0));
}
}

/**
* Returns the maximum loan value of all loans.
*
* @return The maximum loan value of all loans.
*/
public int getMaxLoanValue() {
int maxLoanValue = 0;
for (Loan loan : internalList) {
if (loan.getValue() > maxLoanValue) {
maxLoanValue = (int) loan.getValue();
}
}
return maxLoanValue;
}

/**
* Returns the earliest return date of all loans.
* The loan must not be overdue and must not have been returned.
*
* @return The earliest return date of all loans. Returns null if there are no loans that meet the criteria.
*/
public Date getEarliestReturnDate() {
Date earliestReturnDate = null;
for (Loan loan : internalList) {
if ((earliestReturnDate == null || loan.getReturnDate().before(earliestReturnDate))
&& !loan.getReturnDate().before(new Date()) && !loan.isReturned()) {
earliestReturnDate = loan.getReturnDate();
}
}
return earliestReturnDate;
}
}
Loading

0 comments on commit 2cdf8d3

Please sign in to comment.