1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package com.hack23.cia.web.impl.ui.application.views.common.chartfactory.impl;
20
21 import java.text.SimpleDateFormat;
22 import java.util.ArrayList;
23 import java.util.Calendar;
24 import java.util.List;
25 import java.util.Locale;
26 import java.util.Map;
27 import java.util.Map.Entry;
28 import java.util.Objects;
29 import java.util.Optional;
30 import java.util.stream.Collectors;
31
32 import org.apache.commons.lang3.time.DateUtils;
33 import org.dussan.vaadin.dcharts.DCharts;
34 import org.dussan.vaadin.dcharts.base.elements.XYseries;
35 import org.dussan.vaadin.dcharts.data.DataSeries;
36 import org.dussan.vaadin.dcharts.options.Series;
37 import org.springframework.beans.factory.annotation.Autowired;
38 import org.springframework.stereotype.Service;
39
40 import com.hack23.cia.model.internal.application.data.committee.impl.RiksdagenVoteDataBallotPartyPeriodSummaryEmbeddedId;
41 import com.hack23.cia.model.internal.application.data.committee.impl.ViewRiksdagenVoteDataBallotPartySummaryDaily;
42 import com.hack23.cia.service.api.ApplicationManager;
43 import com.hack23.cia.service.api.DataContainer;
44 import com.hack23.cia.web.impl.ui.application.views.common.chartfactory.api.ChartOptions;
45 import com.hack23.cia.web.impl.ui.application.views.common.chartfactory.api.PartyChartDataManager;
46 import com.vaadin.ui.AbstractOrderedLayout;
47
48
49
50
51 @Service
52 public final class PartyChartDataManagerImpl extends AbstractChartDataManagerImpl implements PartyChartDataManager {
53
54
55
56 private static final String PARTY_ABSENT = "Party Absent";
57
58
59 private static final String PARTY_WON = "Party Won";
60
61
62 private static final String NUMBER_BALLOTS = "Number ballots";
63
64
65 private static final String DD_MMM_YYYY = "dd-MMM-yyyy";
66
67
68 @Autowired
69 private ApplicationManager applicationManager;
70
71
72 @Autowired
73 private ChartOptions chartOptions;
74
75
76
77 private Map<String, List<ViewRiksdagenVoteDataBallotPartySummaryDaily>> partyMap;
78
79
80
81
82 public PartyChartDataManagerImpl() {
83 super();
84 }
85
86
87
88
89
90
91
92 private List<ViewRiksdagenVoteDataBallotPartySummaryDaily> getMaxSizeViewRiksdagenVoteDataBallotPartySummaryDaily() {
93 initPartyMap();
94
95 final Optional<Entry<String, List<ViewRiksdagenVoteDataBallotPartySummaryDaily>>> first = partyMap.entrySet()
96 .stream().sorted((e1, e2) -> Integer.compare(e2.getValue().size(), e1.getValue().size())
97
98 ).findFirst();
99
100 if (first.isPresent()) {
101 return first.get().getValue();
102 } else {
103 return new ArrayList<>();
104 }
105 }
106
107
108
109
110
111
112
113 private Map<String, List<ViewRiksdagenVoteDataBallotPartySummaryDaily>> getPartyMap() {
114 initPartyMap();
115
116 return partyMap;
117 }
118
119
120
121
122
123
124
125
126 private void initPartyMap() {
127 if (partyMap == null) {
128 final DataContainer<ViewRiksdagenVoteDataBallotPartySummaryDaily, RiksdagenVoteDataBallotPartyPeriodSummaryEmbeddedId> partyBallotSummaryDailyDataContainer = applicationManager
129 .getDataContainer(ViewRiksdagenVoteDataBallotPartySummaryDaily.class);
130
131 partyMap = partyBallotSummaryDailyDataContainer.getAll().parallelStream().filter(Objects::nonNull)
132 .collect(Collectors.groupingBy(t -> t.getEmbeddedId().getParty()));
133 }
134 }
135
136 @Override
137 public void createPartyWinnerChart(final AbstractOrderedLayout content) {
138
139 final Map<String, List<ViewRiksdagenVoteDataBallotPartySummaryDaily>> map = getPartyMap();
140
141 final DataSeries dataSeries = new DataSeries();
142
143 final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DD_MMM_YYYY, Locale.ENGLISH);
144
145 final Series series = new Series();
146
147 for (final Entry<String, List<ViewRiksdagenVoteDataBallotPartySummaryDaily>> entry : map.entrySet()) {
148
149 series.addSeries(new XYseries().setLabel(getPartyName(entry.getKey())));
150
151 dataSeries.newSeries();
152 final List<ViewRiksdagenVoteDataBallotPartySummaryDaily> list = entry.getValue();
153 for (final ViewRiksdagenVoteDataBallotPartySummaryDaily viewRiksdagenVoteDataBallotPartySummaryDaily : list) {
154 if (viewRiksdagenVoteDataBallotPartySummaryDaily != null) {
155 dataSeries.add(
156 simpleDateFormat
157 .format(viewRiksdagenVoteDataBallotPartySummaryDaily.getEmbeddedId().getVoteDate()),
158 viewRiksdagenVoteDataBallotPartySummaryDaily.getPartyWonPercentage());
159 }
160 }
161
162 }
163
164 series.addSeries(new XYseries().setLabel(NUMBER_BALLOTS));
165
166 dataSeries.newSeries();
167 final List<ViewRiksdagenVoteDataBallotPartySummaryDaily> list = getMaxSizeViewRiksdagenVoteDataBallotPartySummaryDaily();
168 for (final ViewRiksdagenVoteDataBallotPartySummaryDaily viewRiksdagenVoteDataBallotPartySummaryDaily : list) {
169 if (viewRiksdagenVoteDataBallotPartySummaryDaily != null) {
170 dataSeries.add(
171 simpleDateFormat
172 .format(viewRiksdagenVoteDataBallotPartySummaryDaily.getEmbeddedId().getVoteDate()),
173 viewRiksdagenVoteDataBallotPartySummaryDaily.getNumberBallots());
174 }
175 }
176
177 addChart(content,"Party winner by daily ballot average", new DCharts().setDataSeries(dataSeries).setOptions(chartOptions.createOptionsXYDateFloatLegendOutside(series)).show());
178 }
179
180
181
182
183
184
185
186
187 private List<ViewRiksdagenVoteDataBallotPartySummaryDaily> getViewRiksdagenVoteDataBallotPartySummaryDaily(
188 final String party) {
189 initPartyMap();
190
191 return partyMap.get(party);
192 }
193
194
195 @Override
196 public void createPartyLineChart(final AbstractOrderedLayout content,final String partyId) {
197
198 final List<ViewRiksdagenVoteDataBallotPartySummaryDaily> list = getViewRiksdagenVoteDataBallotPartySummaryDaily(
199 partyId);
200
201 final Series series = new Series().addSeries(new XYseries().setLabel(PARTY_WON))
202 .addSeries(new XYseries().setLabel(PARTY_ABSENT));
203
204 final DataSeries dataSeries = new DataSeries().newSeries();
205
206 final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DD_MMM_YYYY, Locale.ENGLISH);
207
208 if (list != null) {
209
210 for (final ViewRiksdagenVoteDataBallotPartySummaryDaily viewRiksdagenVoteDataBallotPartySummaryDaily : list) {
211 if (viewRiksdagenVoteDataBallotPartySummaryDaily != null) {
212 dataSeries.add(
213 simpleDateFormat
214 .format(viewRiksdagenVoteDataBallotPartySummaryDaily.getEmbeddedId().getVoteDate()),
215 viewRiksdagenVoteDataBallotPartySummaryDaily.getPartyWonPercentage());
216 }
217 }
218
219 dataSeries.newSeries();
220
221 for (final ViewRiksdagenVoteDataBallotPartySummaryDaily viewRiksdagenVoteDataBallotPartySummaryDaily : list) {
222 if (viewRiksdagenVoteDataBallotPartySummaryDaily != null) {
223 dataSeries.add(
224 simpleDateFormat
225 .format(viewRiksdagenVoteDataBallotPartySummaryDaily.getEmbeddedId().getVoteDate()),
226 viewRiksdagenVoteDataBallotPartySummaryDaily.getPartyPercentageAbsent());
227 }
228 }
229 }
230
231 addChart(content,"Party result by", new DCharts().setDataSeries(dataSeries).setOptions(chartOptions.createOptionsPartyLineChart(series)).show());
232 }
233
234
235 @Override
236 public void createPartyGenderChart(final AbstractOrderedLayout content) {
237
238 createPartyBallotChart(content,viewRiksdagenVoteDataBallotPartySummaryDaily -> 100 - viewRiksdagenVoteDataBallotPartySummaryDaily.getPartyAvgPercentageMale().intValue());
239
240 }
241
242
243 @Override
244 public void createPartyAgeChart(final AbstractOrderedLayout content) {
245 createPartyBallotChart(content,viewRiksdagenVoteDataBallotPartySummaryDaily -> (DateUtils.toCalendar(viewRiksdagenVoteDataBallotPartySummaryDaily.getEmbeddedId().getVoteDate()).get(Calendar.YEAR)) - viewRiksdagenVoteDataBallotPartySummaryDaily.getPartyAvgBornYear().intValue());
246 }
247
248
249
250
251
252
253
254
255
256
257 private void createPartyBallotChart(final AbstractOrderedLayout content,final DataValueCalculator dataValueCalculator) {
258 final Map<String, List<ViewRiksdagenVoteDataBallotPartySummaryDaily>> map = getPartyMap();
259
260 final DataSeries dataSeries = new DataSeries();
261
262 final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DD_MMM_YYYY, Locale.ENGLISH);
263
264 final Series series = new Series();
265
266 for (final Entry<String, List<ViewRiksdagenVoteDataBallotPartySummaryDaily>> entry : map.entrySet()) {
267
268 if (!"-".equals(entry.getKey())) {
269 series.addSeries(new XYseries().setLabel(getPartyName(entry.getKey())));
270
271 dataSeries.newSeries();
272 final List<ViewRiksdagenVoteDataBallotPartySummaryDaily> list = entry.getValue();
273 for (final ViewRiksdagenVoteDataBallotPartySummaryDaily viewRiksdagenVoteDataBallotPartySummaryDaily : list) {
274 if (viewRiksdagenVoteDataBallotPartySummaryDaily != null) {
275 dataSeries.add(
276 simpleDateFormat
277 .format(viewRiksdagenVoteDataBallotPartySummaryDaily.getEmbeddedId().getVoteDate()),
278 dataValueCalculator.getDataValue(viewRiksdagenVoteDataBallotPartySummaryDaily));
279 }
280 }
281 }
282 }
283
284 addChart(content,"Party ballot chart", new DCharts().setDataSeries(dataSeries).setOptions(chartOptions.createOptionsXYDateFloatLegendOutside(series)).show());
285 }
286
287
288
289
290 @FunctionalInterface
291 interface DataValueCalculator {
292
293
294
295
296
297
298
299
300 Object getDataValue(ViewRiksdagenVoteDataBallotPartySummaryDaily item);
301 }
302
303
304 }