Fix analytics chart
This commit is contained in:
@@ -17,7 +17,10 @@ import org.example.petshopdesktop.util.ActivityLogger;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.DateTimeParseException;
|
||||||
|
import javafx.util.StringConverter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -42,7 +45,10 @@ public class AnalyticsController {
|
|||||||
private Label lblTotalItems;
|
private Label lblTotalItems;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private LineChart<String, Number> chartSalesOverTime;
|
private LineChart<Number, Number> chartSalesOverTime;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private NumberAxis axisSalesDate;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private BarChart<Number, String> chartTopRevenue;
|
private BarChart<Number, String> chartTopRevenue;
|
||||||
@@ -58,6 +64,8 @@ public class AnalyticsController {
|
|||||||
|
|
||||||
private final NumberFormat currency = NumberFormat.getCurrencyInstance(Locale.CANADA);
|
private final NumberFormat currency = NumberFormat.getCurrencyInstance(Locale.CANADA);
|
||||||
private final NumberFormat wholeNumber = NumberFormat.getIntegerInstance();
|
private final NumberFormat wholeNumber = NumberFormat.getIntegerInstance();
|
||||||
|
private final DateTimeFormatter chartDateFormatter = DateTimeFormatter.ofPattern("MMM d", Locale.CANADA);
|
||||||
|
private final List<String> salesDateLabels = new ArrayList<>();
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
@@ -75,7 +83,30 @@ public class AnalyticsController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void configureCharts() {
|
private void configureCharts() {
|
||||||
chartSalesOverTime.setAnimated(true);
|
chartSalesOverTime.setAnimated(false);
|
||||||
|
axisSalesDate.setAnimated(false);
|
||||||
|
axisSalesDate.setAutoRanging(false);
|
||||||
|
axisSalesDate.setForceZeroInRange(false);
|
||||||
|
axisSalesDate.setMinorTickVisible(false);
|
||||||
|
axisSalesDate.setTickUnit(1);
|
||||||
|
axisSalesDate.setTickLabelRotation(-45);
|
||||||
|
axisSalesDate.setTickLabelFormatter(new StringConverter<>() {
|
||||||
|
@Override
|
||||||
|
public String toString(Number value) {
|
||||||
|
int index = value.intValue();
|
||||||
|
if (index < 0 || index >= salesDateLabels.size()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
int labelStep = Math.max(1, (salesDateLabels.size() + 14) / 15);
|
||||||
|
boolean showLabel = index == 0 || index == salesDateLabels.size() - 1 || index % labelStep == 0;
|
||||||
|
return showLabel ? salesDateLabels.get(index) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Number fromString(String string) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
chartTopRevenue.setAnimated(true);
|
chartTopRevenue.setAnimated(true);
|
||||||
chartTopQuantity.setAnimated(true);
|
chartTopQuantity.setAnimated(true);
|
||||||
chartPaymentMethods.setAnimated(true);
|
chartPaymentMethods.setAnimated(true);
|
||||||
@@ -142,19 +173,36 @@ public class AnalyticsController {
|
|||||||
|
|
||||||
private void loadSalesOverTime(DashboardResponse dashboard) throws Exception {
|
private void loadSalesOverTime(DashboardResponse dashboard) throws Exception {
|
||||||
List<DailySales> dailySales = dashboard.getDailySales() != null ? dashboard.getDailySales() : new ArrayList<>();
|
List<DailySales> dailySales = dashboard.getDailySales() != null ? dashboard.getDailySales() : new ArrayList<>();
|
||||||
XYChart.Series<String, Number> series = new XYChart.Series<>();
|
XYChart.Series<Number, Number> series = new XYChart.Series<>();
|
||||||
series.setName("Daily Revenue");
|
series.setName("Daily Revenue");
|
||||||
|
|
||||||
for (DailySales dailySale : dailySales) {
|
salesDateLabels.clear();
|
||||||
String dateStr = dailySale.getDate();
|
for (int i = 0; i < dailySales.size(); i++) {
|
||||||
|
DailySales dailySale = dailySales.get(i);
|
||||||
|
salesDateLabels.add(formatChartDate(dailySale.getDate()));
|
||||||
BigDecimal revenue = dailySale.getRevenue() != null ? dailySale.getRevenue() : BigDecimal.ZERO;
|
BigDecimal revenue = dailySale.getRevenue() != null ? dailySale.getRevenue() : BigDecimal.ZERO;
|
||||||
series.getData().add(new XYChart.Data<>(dateStr, revenue));
|
series.getData().add(new XYChart.Data<>(i, revenue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int upperBound = Math.max(0, salesDateLabels.size() - 1);
|
||||||
|
axisSalesDate.setLowerBound(0);
|
||||||
|
axisSalesDate.setUpperBound(upperBound);
|
||||||
chartSalesOverTime.getData().clear();
|
chartSalesOverTime.getData().clear();
|
||||||
chartSalesOverTime.getData().add(series);
|
chartSalesOverTime.getData().add(series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String formatChartDate(String date) {
|
||||||
|
if (date == null || date.isBlank()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return LocalDate.parse(date).format(chartDateFormatter);
|
||||||
|
} catch (DateTimeParseException ignored) {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void loadTopProductsByRevenue(DashboardResponse dashboard) throws Exception {
|
private void loadTopProductsByRevenue(DashboardResponse dashboard) throws Exception {
|
||||||
List<TopProduct> topProducts = dashboard.getTopProducts() != null ? dashboard.getTopProducts() : new ArrayList<>();
|
List<TopProduct> topProducts = dashboard.getTopProducts() != null ? dashboard.getTopProducts() : new ArrayList<>();
|
||||||
XYChart.Series<Number, String> series = new XYChart.Series<>();
|
XYChart.Series<Number, String> series = new XYChart.Series<>();
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.chart.BarChart?>
|
<?import javafx.scene.chart.BarChart?>
|
||||||
<?import javafx.scene.chart.CategoryAxis?>
|
|
||||||
<?import javafx.scene.chart.LineChart?>
|
<?import javafx.scene.chart.LineChart?>
|
||||||
<?import javafx.scene.chart.NumberAxis?>
|
<?import javafx.scene.chart.NumberAxis?>
|
||||||
<?import javafx.scene.chart.PieChart?>
|
<?import javafx.scene.chart.PieChart?>
|
||||||
@@ -125,7 +124,7 @@
|
|||||||
</Label>
|
</Label>
|
||||||
<LineChart fx:id="chartSalesOverTime" animated="true" legendSide="BOTTOM" prefHeight="380.0">
|
<LineChart fx:id="chartSalesOverTime" animated="true" legendSide="BOTTOM" prefHeight="380.0">
|
||||||
<xAxis>
|
<xAxis>
|
||||||
<CategoryAxis label="Date" side="BOTTOM" />
|
<NumberAxis fx:id="axisSalesDate" label="Date" side="BOTTOM" />
|
||||||
</xAxis>
|
</xAxis>
|
||||||
<yAxis>
|
<yAxis>
|
||||||
<NumberAxis label="Revenue" side="LEFT" />
|
<NumberAxis label="Revenue" side="LEFT" />
|
||||||
|
|||||||
Reference in New Issue
Block a user