GovernmentBodyChartDataManagerImpl.java
/*
* Copyright 2010-2024 James Pether Sörling
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Id$
* $HeadURL$
*/
package com.hack23.cia.web.impl.ui.application.views.common.chartfactory.impl;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.dussan.vaadin.dcharts.DCharts;
import org.dussan.vaadin.dcharts.base.elements.XYseries;
import org.dussan.vaadin.dcharts.data.DataSeries;
import org.dussan.vaadin.dcharts.options.Series;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.hack23.cia.service.external.esv.api.EsvApi;
import com.hack23.cia.service.external.esv.api.GovernmentBodyAnnualOutcomeSummary;
import com.hack23.cia.service.external.esv.api.GovernmentBodyAnnualSummary;
import com.hack23.cia.web.impl.ui.application.views.common.chartfactory.api.GovernmentBodyChartDataManager;
import com.vaadin.ui.AbstractOrderedLayout;
import com.vaadin.ui.VerticalLayout;
/**
* The Class GovernmentBodyChartDataManagerImpl.
*/
@Service
public final class GovernmentBodyChartDataManagerImpl extends AbstractChartDataManagerImpl
implements GovernmentBodyChartDataManager {
/** The Constant ALL_GOVERNMENT_BODIES. */
private static final String ALL_GOVERNMENT_BODIES = "All government bodies";
/** The Constant ANNUAL_EXPENDITURE. */
private static final String ANNUAL_EXPENDITURE = "Annual Expenditure";
/** The Constant ANNUAL_HEADCOUNT. */
private static final String ANNUAL_HEADCOUNT = "Annual headcount";
/** The Constant ANNUAL_HEADCOUNT_ALL_MINISTRIES. */
private static final String ANNUAL_HEADCOUNT_ALL_MINISTRIES = "Annual headcount, all ministries";
/** The Constant ANNUAL_HEADCOUNT_SUMMARY_ALL_GOVERNMENT_BODIES. */
private static final String ANNUAL_HEADCOUNT_SUMMARY_ALL_GOVERNMENT_BODIES = " Annual headcount summary, all government bodies";
/** The Constant ANNUAL_HEADCOUNT_TOTAL_ALL_GOVERNMENT_BODIES. */
private static final String ANNUAL_HEADCOUNT_TOTAL_ALL_GOVERNMENT_BODIES = "Annual headcount total all government bodies";
/** The Constant ANNUAL_INCOME. */
private static final String ANNUAL_INCOME = "Annual Income";
/** The Constant ANSLAGSPOSTSNAMN. */
private static final String ANSLAGSPOSTSNAMN = "Anslagspostsnamn";
/** The Constant EXPENDITURE_GROUP_NAME. */
private static final String EXPENDITURE_GROUP_NAME = "Utgiftsområdesnamn";
/** The Constant FIRST_JAN_DATA_SUFFIX. */
private static final String FIRST_JAN_DATA_SUFFIX = "-01-01";
/** The Constant FIRST_OF_JAN. */
private static final String FIRST_OF_JAN = "01-JAN-";
/** The Constant INKOMSTTITELGRUPPSNAMN. */
private static final String INKOMSTTITELGRUPPSNAMN = "Inkomsttitelgruppsnamn";
/** The Constant INKOMSTTITELSNAMN. */
private static final String INKOMSTTITELSNAMN = "Inkomsttitelsnamn";
/** The esv api. */
@Autowired
private EsvApi esvApi;
/**
* Instantiates a new government body chart data manager impl.
*/
public GovernmentBodyChartDataManagerImpl() {
super();
}
/**
* Adds the annual summary data.
*
* @param dataSeries the data series
* @param series the series
* @param entry the entry
* @param allValues the all values
*/
private static void addAnnualSummaryData(final DataSeries dataSeries, final Series series,
final Entry<String, List<GovernmentBodyAnnualOutcomeSummary>> entry,
final List<GovernmentBodyAnnualOutcomeSummary> allValues) {
series.addSeries(new XYseries().setLabel(entry.getKey()).setShowLabel(true));
dataSeries.newSeries();
final Map<Integer, List<GovernmentBodyAnnualOutcomeSummary>> map = allValues.stream()
.collect(Collectors.groupingBy(GovernmentBodyAnnualOutcomeSummary::getYear));
for (final Entry<Integer, List<GovernmentBodyAnnualOutcomeSummary>> data : map.entrySet()) {
final List<GovernmentBodyAnnualOutcomeSummary> values = data.getValue();
final double sum = values.stream().mapToDouble(GovernmentBodyAnnualOutcomeSummary::getYearTotal).sum();
if (sum > 0) {
dataSeries.add(data.getKey() + FIRST_JAN_DATA_SUFFIX, (int) sum);
}
}
}
/**
* Adds the data serie value.
*
* @param dataSeries the data series
* @param entry the entry
* @param value the value
*/
private static void addDataSerieValue(final DataSeries dataSeries, final Entry entry,
final int value) {
if (entry.getKey() != null && value > 0) {
dataSeries.add(FIRST_OF_JAN + entry.getKey(), value);
}
}
/**
* Adds the entry data.
*
* @param dataSeries the data series
* @param simpleDateFormat the simple date format
* @param entry the entry
*/
private static void addEntryData(final DataSeries dataSeries, final SimpleDateFormat simpleDateFormat,
final Entry<String, List<GovernmentBodyAnnualOutcomeSummary>> entry) {
for (final GovernmentBodyAnnualOutcomeSummary data : entry.getValue()) {
final Map<Date, Double> valueMap = data.getValueMap();
for (final Entry<Date, Double> entryData : valueMap.entrySet()) {
if (entryData.getValue() != null && entryData.getValue().intValue() > 0) {
dataSeries.add(simpleDateFormat.format(entryData.getKey()) , entryData.getValue().intValue());
}
}
}
}
/**
* Adds the annual data.
*
* @param content
* the content
* @param name
* the name
* @param label
* the label
* @param collect
* the collect
*/
private void addAnnualData(final VerticalLayout content, final String name, final String label,
final Map<String, List<GovernmentBodyAnnualOutcomeSummary>> collect) {
final DataSeries dataSeries = new DataSeries();
final Series series = new Series();
final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd",Locale.ENGLISH);
for (final Entry<String, List<GovernmentBodyAnnualOutcomeSummary>> entry : collect.entrySet()) {
series.addSeries(new XYseries().setLabel(entry.getKey()));
dataSeries.newSeries();
addEntryData(dataSeries, simpleDateFormat, entry);
}
addChart(content, name + " " + label,
new DCharts().setDataSeries(dataSeries)
.setOptions(getChartOptions().createOptionsXYDateFloatLogYAxisLegendOutside(series)).show(),
true);
}
/**
* Adds the annual summary.
*
* @param report
* the report
* @param content
* the content
* @param label
* the label
*/
private void addAnnualSummary(final Map<String, List<GovernmentBodyAnnualOutcomeSummary>> report, final VerticalLayout content,
final String label) {
final DataSeries dataSeries = new DataSeries();
final Series series = new Series();
for (final Entry<String, List<GovernmentBodyAnnualOutcomeSummary>> entry : report.entrySet()) {
final List<GovernmentBodyAnnualOutcomeSummary> allValues = entry.getValue();
if (!allValues.isEmpty()) {
addAnnualSummaryData(dataSeries, series, entry, allValues);
}
}
addChart(content, label,
new DCharts().setDataSeries(dataSeries)
.setOptions(getChartOptions().createOptionsXYDateFloatLogYAxisLegendOutside(series)).show(),
true);
}
@Override
public void createGovernmentBodyExpenditureSummaryChart(final VerticalLayout content) {
addAnnualSummary(esvApi.getGovernmentBodyReportByField(EXPENDITURE_GROUP_NAME), content, ANNUAL_EXPENDITURE);
}
@Override
public void createGovernmentBodyExpenditureSummaryChart(final VerticalLayout content, final String name) {
final Map<String, List<GovernmentBodyAnnualOutcomeSummary>> collect = esvApi.getGovernmentBodyReport().get(name)
.stream().filter(p -> p.getDescriptionFields().get(ANSLAGSPOSTSNAMN) != null)
.collect(Collectors.groupingBy(t -> t.getDescriptionFields().get(ANSLAGSPOSTSNAMN)));
addAnnualData(content, name, ANNUAL_EXPENDITURE, collect);
}
@Override
public void createGovernmentBodyHeadcountSummaryChart(final VerticalLayout content) {
final Map<Integer, List<GovernmentBodyAnnualSummary>> map = esvApi.getData();
final DataSeries dataSeries = new DataSeries();
final Series series = new Series();
series.addSeries(new XYseries().setLabel(ALL_GOVERNMENT_BODIES));
dataSeries.newSeries();
for (final Entry<Integer, List<GovernmentBodyAnnualSummary>> entry : map.entrySet()) {
addDataSerieValue(dataSeries, entry, entry.getValue().stream().mapToInt(GovernmentBodyAnnualSummary::getHeadCount).sum());
}
addChart(content, ANNUAL_HEADCOUNT_TOTAL_ALL_GOVERNMENT_BODIES,
new DCharts().setDataSeries(dataSeries)
.setOptions(getChartOptions().createOptionsXYDateFloatLogYAxisLegendOutside(series)).show(),
true);
}
@Override
public void createGovernmentBodyHeadcountSummaryChart(final VerticalLayout content, final String name) {
final Map<Integer, GovernmentBodyAnnualSummary> map = esvApi.getDataPerGovernmentBody(name);
final DataSeries dataSeries = new DataSeries();
final Series series = new Series();
series.addSeries(new XYseries().setLabel(name));
dataSeries.newSeries();
for (final Entry<Integer, GovernmentBodyAnnualSummary> entry : map.entrySet()) {
addDataSerieValue(dataSeries, entry, entry.getValue().getHeadCount());
}
addChart(content, name + " "+ ANNUAL_HEADCOUNT,
new DCharts().setDataSeries(dataSeries)
.setOptions(getChartOptions().createOptionsXYDateFloatLogYAxisLegendOutside(series)).show(),
true);
}
@Override
public void createGovernmentBodyIncomeSummaryChart(final VerticalLayout content) {
addAnnualSummary(esvApi.getGovernmentBodyReportByField(INKOMSTTITELGRUPPSNAMN), content, ANNUAL_INCOME);
}
@Override
public void createGovernmentBodyIncomeSummaryChart(final VerticalLayout content, final String name) {
final Map<String, List<GovernmentBodyAnnualOutcomeSummary>> collect = esvApi.getGovernmentBodyReport().get(name)
.stream().filter(p -> p.getDescriptionFields().get(INKOMSTTITELSNAMN) != null)
.collect(Collectors.groupingBy(t -> t.getDescriptionFields().get(INKOMSTTITELSNAMN)));
addAnnualData(content, name, ANNUAL_INCOME, collect);
}
@Override
public void createMinistryGovernmentBodyExpenditureSummaryChart(final AbstractOrderedLayout content) {
createMinistrySummary(content,EXPENDITURE_GROUP_NAME,"MinistryGovernmentBodySpendingSummaryChart");
}
@Override
public void createMinistryGovernmentBodyExpenditureSummaryChart(final VerticalLayout content, final String name) {
addAnnualSummary(esvApi.getGovernmentBodyReportByFieldAndMinistry(EXPENDITURE_GROUP_NAME, name), content, ANNUAL_EXPENDITURE);
}
@Override
public void createMinistryGovernmentBodyHeadcountSummaryChart(final AbstractOrderedLayout content) {
final Map<Integer, List<GovernmentBodyAnnualSummary>> map = esvApi.getData();
final List<String> ministryNames = esvApi.getMinistryNames();
final DataSeries dataSeries = new DataSeries();
final Series series = new Series();
for (final String ministryName : ministryNames) {
series.addSeries(new XYseries().setLabel(ministryName));
dataSeries.newSeries();
for (final Entry<Integer, List<GovernmentBodyAnnualSummary>> entry : map.entrySet()) {
addDataSerieValue(dataSeries, entry, entry.getValue().stream()
.filter((final GovernmentBodyAnnualSummary p) -> p.getMinistry().equalsIgnoreCase(ministryName))
.mapToInt(GovernmentBodyAnnualSummary::getHeadCount).sum());
}
}
addChart(content, ANNUAL_HEADCOUNT_ALL_MINISTRIES,
new DCharts().setDataSeries(dataSeries)
.setOptions(getChartOptions().createOptionsXYDateFloatLogYAxisLegendOutside(series)).show(),
true);
}
@Override
public void createMinistryGovernmentBodyHeadcountSummaryChart(final AbstractOrderedLayout content,
final String name) {
final Map<Integer, List<GovernmentBodyAnnualSummary>> map = esvApi.getDataPerMinistry(name);
final List<String> governmentBodyNames = esvApi.getGovernmentBodyNames(name);
final DataSeries dataSeries = new DataSeries();
final Series series = new Series();
for (final String govBodyName : governmentBodyNames) {
series.addSeries(new XYseries().setLabel(govBodyName));
dataSeries.newSeries();
for (final Entry<Integer, List<GovernmentBodyAnnualSummary>> entry : map.entrySet()) {
addDataSerieValue(dataSeries, entry, entry.getValue().stream()
.filter((final GovernmentBodyAnnualSummary p) -> p.getName().equalsIgnoreCase(govBodyName))
.mapToInt(GovernmentBodyAnnualSummary::getHeadCount).sum());
}
}
addChart(content, name + " "+ ANNUAL_HEADCOUNT_SUMMARY_ALL_GOVERNMENT_BODIES,
new DCharts().setDataSeries(dataSeries)
.setOptions(getChartOptions().createOptionsXYDateFloatLogYAxisLegendOutside(series)).show(),
true);
}
@Override
public void createMinistryGovernmentBodyIncomeSummaryChart(final AbstractOrderedLayout content) {
createMinistrySummary(content,INKOMSTTITELGRUPPSNAMN,"MinistryGovernmentBodyIncomeSummaryChart");
}
@Override
public void createMinistryGovernmentBodyIncomeSummaryChart(final VerticalLayout content, final String name) {
addAnnualSummary(esvApi.getGovernmentBodyReportByFieldAndMinistry(INKOMSTTITELGRUPPSNAMN,name), content, ANNUAL_INCOME);
}
/**
* Creates the ministry summary.
*
* @param content the content
* @param field the field
* @param label the label
*/
private void createMinistrySummary(final AbstractOrderedLayout content, final String field, final String label) {
final DataSeries dataSeries = new DataSeries();
final Series series = new Series();
final Map<String, List<GovernmentBodyAnnualOutcomeSummary>> reportByMinistry = esvApi.getGovernmentBodyReportByMinistry();
for (final Entry<String, List<GovernmentBodyAnnualOutcomeSummary>> entry : reportByMinistry.entrySet()) {
series.addSeries(new XYseries().setLabel(entry.getKey()));
dataSeries.newSeries();
final Map<Integer, Double> annualSummaryMap = entry.getValue().stream().filter(t -> t.getDescriptionFields().get(field) != null).collect(Collectors.groupingBy(GovernmentBodyAnnualOutcomeSummary::getYear,Collectors.summingDouble(GovernmentBodyAnnualOutcomeSummary::getYearTotal)));
for (final Entry<Integer, Double> entryData : annualSummaryMap.entrySet()) {
if (entryData.getValue() != null && entryData.getValue().intValue() > 0) {
dataSeries.add(entryData.getKey() +1 +"-01-01" , entryData.getValue());
}
}
}
addChart(content, label,
new DCharts().setDataSeries(dataSeries)
.setOptions(getChartOptions().createOptionsXYDateFloatLogYAxisLegendOutside(series)).show(),
true);
}
}