Skip to content
This repository was archived by the owner on May 5, 2021. It is now read-only.

Commit 1545ef7

Browse files
author
Martin Wahnschaffe
authored
Merge pull request SORMAS-Foundation#2893 from hzi-braunschweig/feature-2527-CampaignDashboard
Feature 2527 campaign dashboard
2 parents f99a5a5 + 3d373f1 commit 1545ef7

6 files changed

Lines changed: 124 additions & 84 deletions

File tree

sormas-ui/src/main/java/de/symeda/sormas/ui/dashboard/AbstractDashboardView.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ protected AbstractDashboardView(String viewName) {
7777
dashboardLayout.setStyleName("crud-main-layout");
7878

7979
addComponent(dashboardLayout);
80+
setExpandRatio(dashboardLayout, 1);
8081
}
8182

8283
protected void navigateToDashboardView(Property.ValueChangeEvent e) {

sormas-ui/src/main/java/de/symeda/sormas/ui/dashboard/campaigns/CampaignDashboardDiagramComponent.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@
99
import java.util.function.Function;
1010
import java.util.stream.Collectors;
1111

12-
import com.vaadin.ui.CssLayout;
12+
import com.vaadin.ui.VerticalLayout;
1313

1414
import de.symeda.sormas.api.campaign.diagram.CampaignDiagramDataDto;
1515
import de.symeda.sormas.api.campaign.diagram.CampaignDiagramDefinitionDto;
1616
import de.symeda.sormas.api.campaign.diagram.CampaignDiagramSeries;
1717
import de.symeda.sormas.ui.highcharts.HighChart;
1818

19-
public class CampaignDashboardDiagramComponent extends CssLayout {
19+
@SuppressWarnings("serial")
20+
public class CampaignDashboardDiagramComponent extends VerticalLayout {
2021

2122
private CampaignDiagramDefinitionDto diagramDefinition;
2223

@@ -32,8 +33,10 @@ public CampaignDashboardDiagramComponent(CampaignDiagramDefinitionDto diagramDef
3233

3334
campaignColumnChart = new HighChart();
3435

36+
setSizeFull();
3537
campaignColumnChart.setSizeFull();
3638

39+
setMargin(false);
3740
addComponent(campaignColumnChart);
3841
// setExpandRatio(campaignColumnChart, 1);
3942

@@ -64,8 +67,6 @@ private void buildDiagramChart(String title) {
6467
hcjs.append("var options = {"
6568
+ "chart:{ "
6669
+ " type: 'column', "
67-
+ " width: $(\"#container\").height(), "
68-
+ " height: $(\"#container\").width(), "
6970
+ " backgroundColor: 'transparent', "
7071
+ " borderRadius: '1', "
7172
+ " borderWidth: '1', "
@@ -78,7 +79,7 @@ private void buildDiagramChart(String title) {
7879
+ "},"
7980
+ "legend: { backgroundColor: 'transparent', margin: 30 },"
8081
+ "colors: ['#4472C4', '#ED7D31', '#A5A5A5', '#FFC000', '#5B9BD5', '#70AD47', '#FF0000', '#6691C4','#ffba08','#519e8a','#ed254e','#39a0ed','#FF8C00','#344055','#D36135','#82d173'],"
81-
+ "title:{ text: '" + title + "'},");
82+
+ "title:{ text: '" + title + "', style: { fontSize: '15px' } },");
8283
//@formatter:on
8384

8485
Map<String, Long> stackMap = diagramDefinition.getCampaignDiagramSeriesList()

sormas-ui/src/main/java/de/symeda/sormas/ui/dashboard/campaigns/CampaignDashboardView.java

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ public class CampaignDashboardView extends AbstractDashboardView {
3838
private List<VerticalLayout> campaignDashboardDiagramComponents = new ArrayList<>();
3939
private List<String> campaignDashboardDiagramStyles = new ArrayList<>();
4040

41-
private GridTemplateAreaCreator gridTemplateAreaCreator = new GridTemplateAreaCreator();
42-
4341
public CampaignDashboardView() {
4442
super(VIEW_NAME);
4543

@@ -52,7 +50,8 @@ public CampaignDashboardView() {
5250
dashboardSwitcher.addValueChangeListener(e -> navigateToDashboardView(e));
5351

5452
filterLayout.setInfoLabelText(I18nProperties.getString(Strings.infoCampaignsDashboard));
55-
dashboardLayout.setHeightUndefined();
53+
dashboardLayout.setExpandRatio(filterLayout, 0);
54+
dashboardLayout.setSizeFull();
5655
}
5756

5857
@Override
@@ -74,12 +73,14 @@ public void refreshDashboard() {
7473
tabLayout.setSpacing(false);
7574
campaignDashboardDiagramComponents.add(tabLayout);
7675
dashboardLayout.addComponent(tabLayout);
76+
dashboardLayout.setExpandRatio(tabLayout, 1);
7777

7878
final OptionGroup tabSwitcher = new OptionGroup();
7979
final VerticalLayout tabSwitcherLayout = new VerticalLayout(tabSwitcher);
8080
tabSwitcherLayout.setMargin(new MarginInfo(false, false, false, true));
8181
tabSwitcherLayout.setSpacing(false);
8282
tabLayout.addComponent(tabSwitcherLayout);
83+
tabLayout.setExpandRatio(tabSwitcherLayout, 0);
8384

8485
final Map<String, Map<CampaignDashboardDiagramDto, List<CampaignDiagramDataDto>>> campaignFormDataTabMap =
8586
groupCampaignFormDataByTab(dataProvider.getCampaignFormDataMap());
@@ -108,21 +109,31 @@ public void refreshDashboard() {
108109

109110
campaignFormDataTabMap.forEach((tabId, campaignFormDataMap) -> {
110111

112+
final List<CampaignDashboardElement> dashboardElements = campaignFormDataMap.keySet()
113+
.stream()
114+
.map(campaignDashboardDiagramDto -> campaignDashboardDiagramDto.getCampaignDashboardElement())
115+
.collect(Collectors.toList());
116+
final GridTemplateAreaCreator gridTemplateAreaCreator = new GridTemplateAreaCreator(dashboardElements);
117+
111118
final VerticalLayout diagramsWrapper = new VerticalLayout();
112119
diagramsWrapper.setMargin(new MarginInfo(false, true, false, true));
113120
diagramsWrapper.setId(tabId);
114-
diagramsWrapper.setSizeFull();
121+
122+
diagramsWrapper.setWidth(
123+
dashboardElements.size() == 1 && gridTemplateAreaCreator.getGridColumns() == 1 ? gridTemplateAreaCreator.getWidthsSum() : 100,
124+
Unit.PERCENTAGE);
125+
diagramsWrapper.setHeight(gridTemplateAreaCreator.getGridContainerHeight(), Unit.PERCENTAGE);
115126

116127
final CssLayout diagramsLayout = new CssLayout();
117-
diagramsLayout.setId(tabId);
118128
diagramsLayout.setSizeFull();
119129
final String gridCssClass = tabId.replaceAll("[^a-zA-Z]+", "") + generateRandomString() + GRID_CONTAINER;
120-
final List<CampaignDashboardElement> dashboardElements = campaignFormDataMap.keySet()
121-
.stream()
122-
.map(campaignDashboardDiagramDto -> campaignDashboardDiagramDto.getCampaignDashboardElement())
123-
.collect(Collectors.toList());
124130

125-
styles.add(createDiagramGridStyle(gridCssClass, dashboardElements));
131+
styles.add(
132+
createDiagramGridStyle(
133+
gridCssClass,
134+
gridTemplateAreaCreator.getFormattedGridTemplate(),
135+
gridTemplateAreaCreator.getGridRows(),
136+
gridTemplateAreaCreator.getGridColumns()));
126137
diagramsLayout.setStyleName(gridCssClass);
127138

128139
campaignFormDataMap.forEach((campaignDashboardDiagramDto, diagramData) -> {
@@ -139,6 +150,7 @@ public void refreshDashboard() {
139150

140151
diagramsWrapper.setVisible(false);
141152
tabLayout.addComponent(diagramsWrapper);
153+
tabLayout.setExpandRatio(diagramsWrapper, 1);
142154
});
143155

144156
tabSwitcher.setValue(tabs.isEmpty() ? StringUtils.EMPTY : tabs.get(0));
@@ -156,18 +168,17 @@ private String generateRandomString() {
156168
return UUID.randomUUID().toString().substring(0, 6);
157169
}
158170

159-
private String createDiagramGridStyle(String gridCssClass, List<CampaignDashboardElement> dashboardElements) {
160-
String s = "." + gridCssClass;
171+
private String createDiagramGridStyle(String gridCssClass, String gridAreasTemplate, int rows, int columns) {
172+
final String s = "." + gridCssClass;
161173
campaignDashboardDiagramStyles.add(s);
162-
return s + "{ display: grid; grid-gap:10px; grid-auto-columns: 1fr; grid-auto-rows: 1fr;" + " grid-template-areas:"
163-
+ gridTemplateAreaCreator.createGridTemplate(dashboardElements) + "; }";
174+
return s + "{ display: grid; grid-gap:1%; grid-auto-columns: " + (100 / columns - 1) + "%; grid-auto-rows: " + (100 / rows - 1)
175+
+ "%; grid-template-areas:" + gridAreasTemplate + "; }";
164176
}
165177

166178
private String createDiagramStyle(String diagramCssClass, String diagramId) {
167-
String s = "." + diagramCssClass;
179+
final String s = "." + diagramCssClass;
168180
campaignDashboardDiagramStyles.add(s);
169-
final String style = s + "{ grid-area: " + diagramId + "; }";
170-
return style;
181+
return s + "{ grid-area: " + diagramId + "; }";
171182
}
172183

173184
private String removeStyles(String styleInnerText) {

sormas-ui/src/main/java/de/symeda/sormas/ui/dashboard/campaigns/GridTemplateAreaCreator.java

Lines changed: 65 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,26 @@ public class GridTemplateAreaCreator {
1212

1313
public static final String APOSTROPHE = "'";
1414

15-
public String createGridTemplate(List<CampaignDashboardElement> dashboardElements) {
16-
15+
private String[][] grid;
16+
private Integer widthsSum;
17+
private Integer nrOfGridAreaColumns;
18+
private Integer nrOfGridAreaRows;
19+
private Integer oneWidthAreaPercentage;
20+
private Integer oneHeightAreaPercentage;
21+
22+
public GridTemplateAreaCreator(List<CampaignDashboardElement> dashboardElements) {
1723
dashboardElements =
1824
dashboardElements.stream().sorted(Comparator.comparingInt(CampaignDashboardElement::getOrder)).collect(Collectors.toList());
1925

2026
final List<Integer> widths = dashboardElements.stream().map(cde -> cde.getWidth()).collect(Collectors.toList());
2127
final List<Integer> heights = dashboardElements.stream().map(cde -> cde.getHeight()).collect(Collectors.toList());
22-
final Integer oneWidthAreaPercentage = gcd(widths);
23-
final Integer oneHeightAreaPercentage = gcd(heights);
24-
final Integer nrOfGridAreaColumns = 100 / oneWidthAreaPercentage;
25-
final Integer widthsSum = widths.stream().reduce(0, Integer::sum);
26-
final Integer nrOfGridAreaRows = (widthsSum / 100 + (widthsSum % 100 == 0 ? 0 : 1)) * 100 / gcd(heights);
28+
oneWidthAreaPercentage = gcd(widths);
29+
oneHeightAreaPercentage = gcd(heights);
30+
nrOfGridAreaColumns = 100 / oneWidthAreaPercentage;
31+
widthsSum = widths.stream().reduce(0, Integer::sum);
32+
nrOfGridAreaRows = (widthsSum / 100 + (widthsSum % 100 == 0 ? 0 : 1)) * 100 / gcd(heights);
2733

28-
final String[][] grid = new String[nrOfGridAreaColumns][nrOfGridAreaRows];
34+
grid = new String[nrOfGridAreaColumns][nrOfGridAreaRows];
2935

3036
int startingColumn = 0;
3137
int startingRow = 0;
@@ -40,58 +46,75 @@ public String createGridTemplate(List<CampaignDashboardElement> dashboardElement
4046
grid[y + startingColumn][x + startingRow] = campaignDashboardElement.getDiagramId();
4147
}
4248
}
43-
final GridElementIndex nextDiagramFirstGridElement = findNextDiagramsStartingIndex(
44-
dashboardElements,
45-
elementIndex,
46-
oneWidthAreaPercentage,
47-
widthAreas,
48-
heightAreas,
49-
nrOfGridAreaColumns,
50-
nrOfGridAreaRows,
51-
grid,
52-
startingRow,
53-
startingColumn);
49+
final GridElementIndex nextDiagramFirstGridElement =
50+
findNextDiagramsStartPosition(dashboardElements, elementIndex, oneWidthAreaPercentage, widthAreas, startingRow, startingColumn);
5451
startingColumn = nextDiagramFirstGridElement.getX();
5552
startingRow = nextDiagramFirstGridElement.getY();
5653
}
57-
58-
return formatGridArea(nrOfGridAreaColumns, nrOfGridAreaRows, grid);
5954
}
6055

61-
private String formatGridArea(Integer nrOfGridColumnAreas, Integer nrOfGridRowAreas, String[][] grid) {
56+
public String getFormattedGridTemplate() {
6257
final StringBuilder result = new StringBuilder();
6358

64-
for (int x = 0; x < nrOfGridRowAreas; x++) {
65-
if (rowIsNull(grid, x, nrOfGridColumnAreas)) {
59+
for (int x = 0; x < nrOfGridAreaRows; x++) {
60+
if (rowIsNull(x, nrOfGridAreaColumns)) {
6661
continue;
6762
} else {
6863
result.append(APOSTROPHE);
69-
for (int y = 0; y < nrOfGridColumnAreas; y++) {
70-
result.append(grid[y][x] + (y == nrOfGridColumnAreas - 1 ? StringUtils.EMPTY : StringUtils.SPACE));
64+
for (int y = 0; y < nrOfGridAreaColumns; y++) {
65+
final String diagramId = grid[y][x];
66+
final String area = diagramId != null ? diagramId : ("area" + x);
67+
result.append(area + (y == nrOfGridAreaColumns - 1 ? StringUtils.EMPTY : StringUtils.SPACE));
7168
}
7269
result.append(APOSTROPHE);
7370
}
7471
}
7572
return result.toString();
7673
}
7774

78-
private boolean rowIsNull(String[][] grid, int x, Integer nrOfGridColumnAreas) {
75+
public Integer getGridContainerHeight() {
76+
int nonNullRows = 0;
77+
for (int x = 0; x < nrOfGridAreaRows; x++) {
78+
if (!rowIsNull(x, nrOfGridAreaColumns)) {
79+
nonNullRows++;
80+
}
81+
}
82+
return nonNullRows * oneHeightAreaPercentage;
83+
}
84+
85+
public Integer getWidthsSum() {
86+
return widthsSum;
87+
}
88+
89+
public Integer getGridColumns() {
90+
return nrOfGridAreaColumns;
91+
}
92+
93+
public int getGridRows() {
94+
int rows = 0;
95+
for (int x = 0; x < nrOfGridAreaRows; x++) {
96+
if (rowIsNull(x, nrOfGridAreaColumns)) {
97+
continue;
98+
} else {
99+
rows++;
100+
}
101+
}
102+
return rows;
103+
}
104+
105+
private boolean rowIsNull(int x, Integer nrOfGridColumnAreas) {
79106
for (int y = 0; y < nrOfGridColumnAreas; y++) {
80107
if (grid[y][x] != null)
81108
return false;
82109
}
83110
return true;
84111
}
85112

86-
private GridElementIndex findNextDiagramsStartingIndex(
113+
private GridElementIndex findNextDiagramsStartPosition(
87114
List<CampaignDashboardElement> dashboardElements,
88115
int elementIndex,
89116
int oneWidthAreaPercentage,
90117
int widthAreas,
91-
int heightAreas,
92-
int nrOfGridAreaColumns,
93-
int nrOfGridAreaRows,
94-
String[][] grid,
95118
int startingRow,
96119
int startingColumn) {
97120
if (elementIndex < dashboardElements.size() - 1) {
@@ -100,24 +123,21 @@ private GridElementIndex findNextDiagramsStartingIndex(
100123
if (widthAreas + startingColumn + nextWidthAreas <= nrOfGridAreaColumns) {
101124
startingColumn += widthAreas;
102125
} else {
103-
final GridElementIndex firstEmptyGridElement = findFirstEmptyGridElement(grid, nrOfGridAreaColumns, nrOfGridAreaRows);
104-
if (startingRow + heightAreas >= nrOfGridAreaRows
105-
|| (firstEmptyGridElement.getY() < startingRow + heightAreas && nextWidthAreas <= nrOfGridAreaColumns - widthAreas)) {
106-
startingColumn = firstEmptyGridElement.getX();
107-
startingRow = firstEmptyGridElement.getY();
108-
} else {
109-
startingRow += heightAreas;
110-
startingColumn = startingRow == nrOfGridAreaRows || grid[0][startingRow] != null ? startingColumn : 0;
111-
}
126+
final int nextStartingColumn = startingColumn == 0 ? widthAreas : startingColumn;
127+
final int nrOfColumnsToBeParsed =
128+
nextStartingColumn + nextWidthAreas <= nrOfGridAreaColumns ? nrOfGridAreaColumns : nextStartingColumn;
129+
final GridElementIndex firstEmptyGridElement = findFirstEmptyGridElement(nrOfColumnsToBeParsed, nrOfGridAreaRows);
130+
startingColumn = firstEmptyGridElement.getX();
131+
startingRow = firstEmptyGridElement.getY();
112132
}
113133
}
114134
return new GridElementIndex(startingColumn, startingRow);
115135
}
116136

117-
private GridElementIndex findFirstEmptyGridElement(String[][] matrix, Integer nrOfColumns, Integer nrOfRows) {
118-
for (int x = 0; x < nrOfColumns; x++) {
119-
for (int y = 0; y < nrOfRows; y++) {
120-
if (matrix[x][y] == null) {
137+
private GridElementIndex findFirstEmptyGridElement(Integer nrOfColumnsToBeParsed, Integer nrOfRows) {
138+
for (int y = 0; y < nrOfRows; y++) {
139+
for (int x = 0; x < nrOfColumnsToBeParsed; x++) {
140+
if (grid[x][y] == null) {
121141
return new GridElementIndex(x, y);
122142
}
123143
}

sormas-ui/src/main/java/de/symeda/sormas/ui/highcharts/HighChart.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,6 @@
5555
"highcharts-connector.js",
5656
"highcharts-exporting.js",
5757
"highcharts-export-data.js" })
58-
//@StyleSheet({
59-
// "highcharts.css" })
6058
public class HighChart extends AbstractJavaScriptComponent {
6159

6260
private static final long serialVersionUID = 7738496276049495017L;

0 commit comments

Comments
 (0)