forked from shivi13102/FinWise
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPredictionPanel.java
336 lines (268 loc) · 16 KB
/
PredictionPanel.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Map;
public class PredictionPanel extends JPanel {
private JTable table;
private DefaultTableModel tableModel;
private JTable predictionTable;
private DefaultTableModel predictionTableModel;
private JLabel monthYearLabel;
private ChartPanel chartPanel;
private ChartPanel predictionChartPanel;
private ChartPanel lineChartPanel;
public PredictionPanel() {
setLayout(new BorderLayout());
// Create a label to display the current month and year
monthYearLabel = new JLabel();
monthYearLabel.setHorizontalAlignment(SwingConstants.CENTER);
monthYearLabel.setFont(new Font("Arial", Font.BOLD, 16));
// Fetch and display the current month and year in the label
updateMonthYearLabel();
// Initialize the main expenses table and table model
tableModel = new DefaultTableModel(new Object[]{"Category", "Average Expense"}, 0);
table = new JTable(tableModel);
// Set font size for the table content and adjust row height
table.setFont(new Font("Arial", Font.PLAIN, 16)); // Set font size for table content
table.setRowHeight(30); // Adjust row height to accommodate larger font
// Create scroll pane for the table and remove borders
JScrollPane tableScrollPane = new JScrollPane(table);
tableScrollPane.setPreferredSize(new Dimension(300, 150)); // Set height for the table
tableScrollPane.setBorder(BorderFactory.createEmptyBorder()); // Remove border
// Initialize the chartPanel with an empty chart
chartPanel = new ChartPanel(createBarChart(new DefaultCategoryDataset())); // Pass an empty dataset initially
chartPanel.setPreferredSize(new Dimension(300, 300)); // Set height for the chart
chartPanel.setBorder(BorderFactory.createEmptyBorder()); // Remove border
// Initialize the prediction table and table model
predictionTableModel = new DefaultTableModel(new Object[]{"Category", "Predicted Avg Expense"}, 0);
predictionTable = new JTable(predictionTableModel);
predictionTable.setFont(new Font("Arial", Font.PLAIN, 16));
predictionTable.setRowHeight(30);
// Create scroll pane for the prediction table and remove borders
JScrollPane predictionTableScrollPane = new JScrollPane(predictionTable);
predictionTableScrollPane.setPreferredSize(new Dimension(300, 150)); // Set height for the prediction table
predictionTableScrollPane.setBorder(BorderFactory.createEmptyBorder()); // Remove border
// Initialize the prediction chart panel with an empty chart
predictionChartPanel = new ChartPanel(createPredictionBarChart(new DefaultCategoryDataset())); // Pass an empty dataset initially
predictionChartPanel.setPreferredSize(new Dimension(300, 300)); // Set height for the prediction chart
predictionChartPanel.setBorder(BorderFactory.createEmptyBorder()); // Remove border
// Create a panel for the prediction table and chart
JPanel predictionPanel = new JPanel();
predictionPanel.setLayout(new BoxLayout(predictionPanel, BoxLayout.Y_AXIS));
JLabel predictionLabel = new JLabel(getNextMonthLabel());
predictionLabel.setFont(new Font("Arial", Font.BOLD, 16));
predictionLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
predictionPanel.add(Box.createRigidArea(new Dimension(0, 20))); // Add space before the prediction label
predictionPanel.add(predictionLabel);
predictionPanel.add(Box.createRigidArea(new Dimension(0, 10))); // Add space between label and table
predictionPanel.add(predictionTableScrollPane);
predictionPanel.add(predictionChartPanel); // Add the prediction chart panel
// Create a panel for the table and chart
JPanel tableChartPanel = new JPanel();
tableChartPanel.setLayout(new BoxLayout(tableChartPanel, BoxLayout.Y_AXIS)); // Stack components vertically
// Add the table scroll pane and chart panel to the new panel
tableChartPanel.add(tableScrollPane);
tableChartPanel.add(chartPanel);
// Create a scroll pane for the entire content
JScrollPane mainScrollPane = new JScrollPane();
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
mainPanel.add(monthYearLabel);
mainPanel.add(tableChartPanel);
mainPanel.add(predictionPanel);
mainScrollPane.setViewportView(mainPanel);
// Add the scroll pane to the PredictionPanel
add(mainScrollPane, BorderLayout.CENTER);
// Initialize the line chart panel with an empty chart
lineChartPanel = new ChartPanel(createLineChart(new DefaultCategoryDataset())); // Pass an empty dataset initially
lineChartPanel.setPreferredSize(new Dimension(300, 300)); // Set height for the line chart
lineChartPanel.setBorder(BorderFactory.createEmptyBorder()); // Remove border
predictionPanel.add(predictionChartPanel); // Add the prediction chart panel
predictionPanel.add(lineChartPanel); // Add the line chart panel
// Fetch data and populate the main expense table
try {
populateTable();
} catch (SQLException e) {
JOptionPane.showMessageDialog(this, "Error fetching data: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
private void updateMonthYearLabel() {
// Get the current month and year
LocalDate currentDate = LocalDate.now();
String formattedDate = currentDate.format(DateTimeFormatter.ofPattern("MMMM, yyyy"));
// Set the label text to display "Month, Year"
monthYearLabel.setText(formattedDate);
}
private String getNextMonthLabel() {
// Get the next month
LocalDate nextMonthDate = LocalDate.now().plusMonths(1);
// Create a DateTimeFormatter for the desired format
DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("MMMM");
DateTimeFormatter yearFormatter = DateTimeFormatter.ofPattern("yyyy");
// Format the next month and current year
String nextMonth = nextMonthDate.format(monthFormatter);
String currentYear = nextMonthDate.format(yearFormatter);
return nextMonth + ", " + currentYear + " Prediction";
}
private void populateTable() throws SQLException {
// Get the current year and month
LocalDate currentDate = LocalDate.now();
String currentYear = String.valueOf(currentDate.getYear());
String currentMonth = String.format("%02d", currentDate.getMonthValue());
// Fetch total expenses and count for the current month
Map<String, ExpenseDataFetcher.CategoryExpense> monthlyExpenses = ExpenseDataFetcher.getMonthlyExpensesWithCount(currentYear, currentMonth);
// List of categories to display
String[] categories = {"Food & Drinks", "Shopping", "Bills & Utilities", "Others"};
// Clear the existing table data
tableModel.setRowCount(0);
// Populate the table with only the specified categories
for (String category : categories) {
// Fetch data for the category, defaulting to 0 if not found
ExpenseDataFetcher.CategoryExpense expense = monthlyExpenses.getOrDefault(category, new ExpenseDataFetcher.CategoryExpense(0.0, 0));
// Calculate the average expense
double average = expense.getAverage();
// Add data to the table (average for the current month)
tableModel.addRow(new Object[]{category, String.format("%.2f", average)});
}
// After populating the table, update the bar chart and prediction table
updateBarChart(monthlyExpenses);
updatePredictionTable(monthlyExpenses);
}
private JFreeChart createBarChart(DefaultCategoryDataset dataset) {
// Create the chart with the provided dataset
JFreeChart chart = ChartFactory.createBarChart(
"Current Month Average Expenses", // Chart title
"Category", // X-axis label
"Average Expense", // Y-axis label
dataset, // Dataset
PlotOrientation.VERTICAL, // Plot orientation
false, // Include legend
true, // Tooltips
false // URLs
);
// Change the color of the bars to light blue
chart.getCategoryPlot().getRenderer().setSeriesPaint(0, new Color(34, 82, 179)); // Light blue color
return chart;
}
private void updateBarChart(Map<String, ExpenseDataFetcher.CategoryExpense> monthlyExpenses) {
// Create a dataset for the chart
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
// List of categories to display
String[] categories = {"Food & Drinks", "Shopping", "Bills & Utilities", "Others"};
// Populate the dataset with average expenses for each category
for (String category : categories) {
ExpenseDataFetcher.CategoryExpense expense = monthlyExpenses.getOrDefault(category, new ExpenseDataFetcher.CategoryExpense(0.0, 0));
double average = expense.getAverage();
dataset.addValue(average, "Average", category);
}
// Update the chart's dataset by creating a new chart with updated data
JFreeChart barChart = createBarChart(dataset);
// Refresh the chart panel with the new chart
chartPanel.setChart(barChart);
chartPanel.revalidate();
chartPanel.repaint();
}
// Update the updatePredictionTable method to refresh the prediction chart
private void updatePredictionTable(Map<String, ExpenseDataFetcher.CategoryExpense> monthlyExpenses) {
// Clear the existing prediction table data
predictionTableModel.setRowCount(0);
// List of categories to display and their percentage increases
String[] categories = {"Food & Drinks", "Shopping", "Bills & Utilities", "Others"};
double[] increases = {1.1, 1.08, 1.05, 1.03}; // Increase percentages for each category
// Populate the prediction table with the predicted average expenses for the next month
for (int i = 0; i < categories.length; i++) {
String category = categories[i];
ExpenseDataFetcher.CategoryExpense expense = monthlyExpenses.getOrDefault(category, new ExpenseDataFetcher.CategoryExpense(0.0, 0));
double average = expense.getAverage();
double predictedAverage = average * increases[i];
// Add data to the prediction table
predictionTableModel.addRow(new Object[]{category, String.format("%.2f", predictedAverage)});
}
// After populating the prediction table, update the prediction bar chart and line chart
updatePredictionBarChart();
updateLineChart(monthlyExpenses);
}
private JFreeChart createPredictionBarChart(DefaultCategoryDataset dataset) {
// Create the prediction chart with the provided dataset
JFreeChart chart = ChartFactory.createBarChart(
"Next Month Prediction", // Chart title
"Category", // X-axis label
"Predicted Avg Expense", // Y-axis label
dataset, // Dataset
PlotOrientation.VERTICAL, // Plot orientation
false, // Include legend
true, // Tooltips
false // URLs
);
// Change the color of the bars to light green
chart.getCategoryPlot().getRenderer().setSeriesPaint(0, new Color(34, 179, 82)); // Light green color
return chart;
}
private void updatePredictionBarChart() {
// Create a dataset for the prediction chart
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
// List of categories to display
String[] categories = {"Food & Drinks", "Shopping", "Bills & Utilities", "Others"};
// Populate the dataset with predicted averages for each category
for (int i = 0; i < categories.length; i++) {
String category = categories[i];
double predictedAverage = Double.parseDouble(predictionTableModel.getValueAt(i, 1).toString());
dataset.addValue(predictedAverage, "Predicted", category);
}
// Update the prediction chart's dataset by creating a new chart with updated data
JFreeChart predictionChart = createPredictionBarChart(dataset);
// Refresh the prediction chart panel with the new chart
predictionChartPanel.setChart(predictionChart);
predictionChartPanel.revalidate();
predictionChartPanel.repaint();
}
private JFreeChart createLineChart(DefaultCategoryDataset dataset) {
// Create the line chart with the provided dataset
JFreeChart lineChart = ChartFactory.createLineChart(
"Monthly Expense Comparison", // Chart title
"Category", // X-axis label
"Expense", // Y-axis label
dataset, // Dataset
PlotOrientation.VERTICAL, // Plot orientation
true, // Include legend
true, // Tooltips
false // URLs
);
// Customize the line colors
lineChart.getCategoryPlot().getRenderer().setSeriesPaint(0, new Color(34, 82, 179)); // Current month (light blue)
lineChart.getCategoryPlot().getRenderer().setSeriesPaint(1, new Color(34, 179, 82)); // Next month (light green)
return lineChart;
}
private void updateLineChart(Map<String, ExpenseDataFetcher.CategoryExpense> monthlyExpenses) {
// Create a dataset for the line chart
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
// List of categories to display
String[] categories = {"Food & Drinks", "Shopping", "Bills & Utilities", "Others"};
// Populate the dataset with average expenses for the current month
for (String category : categories) {
ExpenseDataFetcher.CategoryExpense expense = monthlyExpenses.getOrDefault(category, new ExpenseDataFetcher.CategoryExpense(0.0, 0));
double average = expense.getAverage();
dataset.addValue(average, "Current Month", category);
}
// Populate the dataset with predicted averages for the next month
for (int i = 0; i < categories.length; i++) {
String category = categories[i];
double predictedAverage = Double.parseDouble(predictionTableModel.getValueAt(i, 1).toString());
dataset.addValue(predictedAverage, "Next Month", category);
}
// Update the line chart's dataset by creating a new chart with updated data
JFreeChart lineChart = createLineChart(dataset);
// Refresh the line chart panel with the new chart
lineChartPanel.setChart(lineChart);
lineChartPanel.revalidate();
lineChartPanel.repaint();
}
}