feat: new graph added in DashboardView
This commit is contained in:
parent
1b0b469c7b
commit
7c01f5d5cc
1 changed files with 127 additions and 14 deletions
|
@ -5,7 +5,9 @@ import com.application.munera.services.ExpenseService;
|
||||||
import com.application.munera.views.MainLayout;
|
import com.application.munera.views.MainLayout;
|
||||||
import com.nimbusds.jose.shaded.gson.Gson;
|
import com.nimbusds.jose.shaded.gson.Gson;
|
||||||
import com.vaadin.flow.component.html.Div;
|
import com.vaadin.flow.component.html.Div;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||||
|
import com.vaadin.flow.router.PageTitle;
|
||||||
import com.vaadin.flow.router.Route;
|
import com.vaadin.flow.router.Route;
|
||||||
|
|
||||||
import java.time.Year;
|
import java.time.Year;
|
||||||
|
@ -15,8 +17,10 @@ import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
//@HtmlImport("frontend://styles/shared-styles.html") // If you have custom styles
|
//@HtmlImport("frontend://styles/shared-styles.html") // If you have custom styles
|
||||||
|
@PageTitle("Dashboard")
|
||||||
@Route(value = "highcharts-view", layout = MainLayout.class)
|
@Route(value = "highcharts-view", layout = MainLayout.class)
|
||||||
public class DashboardView extends Div {
|
public class DashboardView extends Div {
|
||||||
|
|
||||||
|
@ -26,23 +30,76 @@ public class DashboardView extends Div {
|
||||||
this.expenseService = expenseService;
|
this.expenseService = expenseService;
|
||||||
addClassName("highcharts-view"); // Optional CSS class for styling
|
addClassName("highcharts-view"); // Optional CSS class for styling
|
||||||
|
|
||||||
VerticalLayout layout = new VerticalLayout();
|
VerticalLayout mainLayout = new VerticalLayout();
|
||||||
layout.setSizeFull();
|
mainLayout.setSizeFull();
|
||||||
|
mainLayout.getStyle().set("padding", "10px"); // Add padding to main layout
|
||||||
|
|
||||||
// Create a div to host the chart
|
// Create a horizontal layout for the top row
|
||||||
Div chartDiv = new Div();
|
HorizontalLayout topRowLayout = new HorizontalLayout();
|
||||||
chartDiv.setId("chart"); // Assign an ID to this div for later reference
|
topRowLayout.setSizeFull();
|
||||||
chartDiv.getStyle().set("min-height", "400px"); // Set minimum height for the chart
|
topRowLayout.setHeight("50%"); // Make sure the top row occupies half of the page height
|
||||||
layout.add(chartDiv);
|
topRowLayout.getStyle().set("padding", "10px"); // Add padding to top row
|
||||||
add(layout);
|
|
||||||
|
|
||||||
String jsInit = generateChartInitializationScript();
|
// Create and add the existing bar chart to the top left
|
||||||
|
Div barChartDiv = new Div();
|
||||||
|
barChartDiv.setId("barChart");
|
||||||
|
barChartDiv.getStyle().set("min-height", "100%"); // Ensure it occupies the full height of the container
|
||||||
|
barChartDiv.getStyle().set("width", "50%"); // Occupy half of the width
|
||||||
|
barChartDiv.getStyle().set("border", "1px solid #ccc"); // Add border
|
||||||
|
barChartDiv.getStyle().set("padding", "10px"); // Add padding inside the border
|
||||||
|
topRowLayout.add(barChartDiv);
|
||||||
|
|
||||||
// Execute the JavaScript to initialize the chart
|
// Create and add the new pie chart to the top right
|
||||||
getElement().executeJs(jsInit);
|
Div pieChartDiv = new Div();
|
||||||
|
pieChartDiv.setId("pieChart");
|
||||||
|
pieChartDiv.getStyle().set("min-height", "100%"); // Ensure it occupies the full height of the container
|
||||||
|
pieChartDiv.getStyle().set("width", "50%"); // Occupy half of the width
|
||||||
|
pieChartDiv.getStyle().set("border", "1px solid #ccc"); // Add border
|
||||||
|
pieChartDiv.getStyle().set("padding", "10px"); // Add padding inside the border
|
||||||
|
topRowLayout.add(pieChartDiv);
|
||||||
|
|
||||||
|
mainLayout.add(topRowLayout);
|
||||||
|
|
||||||
|
// Create a horizontal layout for the bottom row
|
||||||
|
HorizontalLayout bottomRowLayout = new HorizontalLayout();
|
||||||
|
bottomRowLayout.setSizeFull();
|
||||||
|
bottomRowLayout.setHeight("50%"); // Make sure the bottom row occupies the other half of the page height
|
||||||
|
bottomRowLayout.getStyle().set("padding", "10px"); // Add padding to bottom row
|
||||||
|
|
||||||
|
// Create placeholder divs for the bottom charts
|
||||||
|
Div bottomLeftChartDiv = new Div();
|
||||||
|
bottomLeftChartDiv.setId("bottomLeftChart");
|
||||||
|
bottomLeftChartDiv.getStyle().set("min-height", "100%"); // Ensure it occupies the full height of the container
|
||||||
|
bottomLeftChartDiv.getStyle().set("width", "50%"); // Occupy half of the width
|
||||||
|
bottomLeftChartDiv.getStyle().set("border", "1px solid #ccc"); // Add border
|
||||||
|
bottomLeftChartDiv.getStyle().set("padding", "10px"); // Add padding inside the border
|
||||||
|
bottomRowLayout.add(bottomLeftChartDiv);
|
||||||
|
|
||||||
|
Div bottomRightChartDiv = new Div();
|
||||||
|
bottomRightChartDiv.setId("bottomRightChart");
|
||||||
|
bottomRightChartDiv.getStyle().set("min-height", "100%"); // Ensure it occupies the full height of the container
|
||||||
|
bottomRightChartDiv.getStyle().set("width", "50%"); // Occupy half of the width
|
||||||
|
bottomRightChartDiv.getStyle().set("border", "1px solid #ccc"); // Add border
|
||||||
|
bottomRightChartDiv.getStyle().set("padding", "10px"); // Add padding inside the border
|
||||||
|
bottomRowLayout.add(bottomRightChartDiv);
|
||||||
|
|
||||||
|
mainLayout.add(bottomRowLayout);
|
||||||
|
|
||||||
|
add(mainLayout);
|
||||||
|
|
||||||
|
String barChartJs = generateBarChartScript();
|
||||||
|
String pieChartJs = generatePieChartScript();
|
||||||
|
String bottomLeftChartJs = generatePlaceholderChartScript("bottomLeftChart", "Bottom Left Chart");
|
||||||
|
String bottomRightChartJs = generatePlaceholderChartScript("bottomRightChart", "Bottom Right Chart");
|
||||||
|
|
||||||
|
// Execute the JavaScript to initialize the charts
|
||||||
|
getElement().executeJs(barChartJs);
|
||||||
|
getElement().executeJs(pieChartJs);
|
||||||
|
getElement().executeJs(bottomLeftChartJs);
|
||||||
|
getElement().executeJs(bottomRightChartJs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String generateChartInitializationScript() {
|
private String generateBarChartScript() {
|
||||||
List<Expense> expenses = expenseService.findAllByYear(Year.now().getValue());
|
List<Expense> expenses = expenseService.findAllByYear(Year.now().getValue());
|
||||||
|
|
||||||
// Prepare data for Highcharts
|
// Prepare data for Highcharts
|
||||||
|
@ -58,7 +115,6 @@ public class DashboardView extends Div {
|
||||||
// Populate map with actual data
|
// Populate map with actual data
|
||||||
for (Expense expense : expenses) {
|
for (Expense expense : expenses) {
|
||||||
String monthName = expense.getDate().getMonth().getDisplayName(TextStyle.SHORT, Locale.ENGLISH);
|
String monthName = expense.getDate().getMonth().getDisplayName(TextStyle.SHORT, Locale.ENGLISH);
|
||||||
// Convert BigDecimal to Double
|
|
||||||
Double amount = expense.getCost().doubleValue();
|
Double amount = expense.getCost().doubleValue();
|
||||||
monthlyData.put(monthName, monthlyData.get(monthName) + amount);
|
monthlyData.put(monthName, monthlyData.get(monthName) + amount);
|
||||||
}
|
}
|
||||||
|
@ -71,7 +127,7 @@ public class DashboardView extends Div {
|
||||||
data.setCharAt(data.length() - 1, ']'); // Replace last comma with closing bracket
|
data.setCharAt(data.length() - 1, ']'); // Replace last comma with closing bracket
|
||||||
|
|
||||||
// Generate JavaScript initialization
|
// Generate JavaScript initialization
|
||||||
return "Highcharts.chart('chart', {" +
|
return "Highcharts.chart('barChart', {" +
|
||||||
"chart: {" +
|
"chart: {" +
|
||||||
"type: 'column'" +
|
"type: 'column'" +
|
||||||
"}," +
|
"}," +
|
||||||
|
@ -87,4 +143,61 @@ public class DashboardView extends Div {
|
||||||
"}]" +
|
"}]" +
|
||||||
"});";
|
"});";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String generatePieChartScript() {
|
||||||
|
List<Expense> expenses = expenseService.findAllByYear(Year.now().getValue());
|
||||||
|
|
||||||
|
// Group expenses by category name and sum their costs
|
||||||
|
Map<String, Double> categoryData = expenses.stream()
|
||||||
|
.collect(Collectors.groupingBy(
|
||||||
|
expense -> expense.getCategory().getName(),
|
||||||
|
LinkedHashMap::new,
|
||||||
|
Collectors.summingDouble(expense -> expense.getCost().doubleValue())
|
||||||
|
));
|
||||||
|
|
||||||
|
// Prepare series data for Highcharts
|
||||||
|
StringBuilder data = new StringBuilder("[");
|
||||||
|
for (Map.Entry<String, Double> entry : categoryData.entrySet()) {
|
||||||
|
data.append("{ name: '").append(entry.getKey()).append("', y: ").append(entry.getValue()).append(" },");
|
||||||
|
}
|
||||||
|
data.setCharAt(data.length() - 1, ']'); // Replace last comma with closing bracket
|
||||||
|
|
||||||
|
// Generate JavaScript initialization
|
||||||
|
return "Highcharts.chart('pieChart', {" +
|
||||||
|
"chart: {" +
|
||||||
|
"type: 'pie'" +
|
||||||
|
"}," +
|
||||||
|
"title: {" +
|
||||||
|
"text: 'Expenses by Category for " + Year.now().getValue() + "'" +
|
||||||
|
"}," +
|
||||||
|
"plotOptions: {" +
|
||||||
|
"pie: {" +
|
||||||
|
"size: '80%'" + // Adjust size to make the pie chart larger
|
||||||
|
"}" +
|
||||||
|
"}," +
|
||||||
|
"series: [{" +
|
||||||
|
"name: 'Expenses'," +
|
||||||
|
"colorByPoint: true," +
|
||||||
|
"data: " + data + // Use the data fetched from DB
|
||||||
|
"}]" +
|
||||||
|
"});";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generatePlaceholderChartScript(String chartId, String title) {
|
||||||
|
return "Highcharts.chart('" + chartId + "', {" +
|
||||||
|
"chart: {" +
|
||||||
|
"type: 'line'" + // Placeholder type
|
||||||
|
"}," +
|
||||||
|
"title: {" +
|
||||||
|
"text: '" + title + "'" +
|
||||||
|
"}," +
|
||||||
|
"xAxis: {" +
|
||||||
|
"categories: []" + // Placeholder empty categories
|
||||||
|
"}," +
|
||||||
|
"series: [{" +
|
||||||
|
"name: 'Placeholder'," +
|
||||||
|
"data: []" + // Placeholder empty data
|
||||||
|
"}]" +
|
||||||
|
"});";
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue