Search in sources :

Example 1 with StatisticsCaseAttribute

use of de.symeda.sormas.api.statistics.StatisticsCaseAttribute in project SORMAS-Project by hzi-braunschweig.

the class StatisticsFilterComponent method createFilterAttributeElement.

private HorizontalLayout createFilterAttributeElement(int rowIndex) {
    HorizontalLayout filterAttributeLayout = new HorizontalLayout();
    filterAttributeLayout.setSpacing(true);
    filterAttributeLayout.setWidth(100, Unit.PERCENTAGE);
    MenuBar filterAttributeDropdown = new MenuBar();
    filterAttributeDropdown.setId(Captions.statisticsAttribute + "-" + rowIndex);
    filterAttributeDropdown.setCaption(I18nProperties.getCaption(Captions.statisticsAttribute));
    MenuItem filterAttributeItem = filterAttributeDropdown.addItem(I18nProperties.getCaption(Captions.statisticsAttributeSelect), null);
    MenuBar filterSubAttributeDropdown = new MenuBar();
    filterSubAttributeDropdown.setId(Captions.statisticsAttributeSpecification + "-" + rowIndex);
    filterSubAttributeDropdown.setCaption(I18nProperties.getCaption(Captions.statisticsAttributeSpecification));
    MenuItem filterSubAttributeItem = filterSubAttributeDropdown.addItem(SPECIFY_YOUR_SELECTION, null);
    // Add attribute groups
    for (StatisticsCaseAttributeGroup attributeGroup : StatisticsCaseAttributeGroup.values()) {
        MenuItem attributeGroupItem = filterAttributeItem.addItem(attributeGroup.toString(), null);
        attributeGroupItem.setEnabled(false);
        // Add attributes belonging to the current group
        for (StatisticsCaseAttribute attribute : attributeGroup.getAttributes()) {
            Command attributeCommand = selectedItem -> {
                selectedAttribute = attribute;
                selectedSubAttribute = null;
                filterAttributeItem.setText(attribute.toString());
                // Add style to keep chosen item selected and remove it from all other items
                for (MenuItem menuItem : filterAttributeItem.getChildren()) {
                    menuItem.setStyleName(null);
                }
                selectedItem.setStyleName("selected-filter");
                // Reset the sub attribute dropdown
                filterSubAttributeItem.removeChildren();
                filterSubAttributeItem.setText(SPECIFY_YOUR_SELECTION);
                if (attribute.getSubAttributes().length > 0) {
                    for (StatisticsCaseSubAttribute subAttribute : attribute.getSubAttributes()) {
                        if (subAttribute.isUsedForFilters()) {
                            Command subAttributeCommand = selectedSubItem -> {
                                selectedSubAttribute = subAttribute;
                                filterSubAttributeItem.setText(subAttribute.toString());
                                // Add style to keep chosen item selected and remove it from all other items
                                for (MenuItem menuItem : filterSubAttributeItem.getChildren()) {
                                    menuItem.setStyleName(null);
                                }
                                selectedSubItem.setStyleName("selected-filter");
                                updateFilterElement(rowIndex);
                            };
                            filterSubAttributeItem.addItem(subAttribute.toString(), subAttributeCommand);
                        }
                    }
                    // Only add the sub attribute dropdown if there are any sub attributes that are relevant for the filters section
                    if (filterSubAttributeItem.getChildren() != null && filterSubAttributeItem.getChildren().size() > 0) {
                        filterAttributeLayout.addComponent(filterSubAttributeDropdown);
                        filterAttributeLayout.setExpandRatio(filterSubAttributeDropdown, 1);
                    } else {
                        filterAttributeLayout.removeComponent(filterSubAttributeDropdown);
                    }
                } else {
                    filterAttributeLayout.removeComponent(filterSubAttributeDropdown);
                }
                updateFilterElement(rowIndex);
            };
            filterAttributeItem.addItem(attribute.toString(), attributeCommand);
        }
    }
    filterAttributeLayout.addComponent(filterAttributeDropdown);
    filterAttributeLayout.setExpandRatio(filterAttributeDropdown, 0);
    return filterAttributeLayout;
}
Also used : MenuItem(com.vaadin.ui.MenuBar.MenuItem) StatisticsCaseAttribute(de.symeda.sormas.api.statistics.StatisticsCaseAttribute) StatisticsCaseSubAttribute(de.symeda.sormas.api.statistics.StatisticsCaseSubAttribute) StatisticsCaseAttributeGroup(de.symeda.sormas.api.statistics.StatisticsCaseAttributeGroup) CssStyles(de.symeda.sormas.ui.utils.CssStyles) HorizontalLayout(com.vaadin.ui.HorizontalLayout) MenuBar(com.vaadin.ui.MenuBar) I18nProperties(de.symeda.sormas.api.i18n.I18nProperties) Command(com.vaadin.ui.MenuBar.Command) VerticalLayout(com.vaadin.ui.VerticalLayout) Captions(de.symeda.sormas.api.i18n.Captions) Command(com.vaadin.ui.MenuBar.Command) MenuBar(com.vaadin.ui.MenuBar) MenuItem(com.vaadin.ui.MenuBar.MenuItem) StatisticsCaseAttributeGroup(de.symeda.sormas.api.statistics.StatisticsCaseAttributeGroup) StatisticsCaseAttribute(de.symeda.sormas.api.statistics.StatisticsCaseAttribute) StatisticsCaseSubAttribute(de.symeda.sormas.api.statistics.StatisticsCaseSubAttribute) HorizontalLayout(com.vaadin.ui.HorizontalLayout)

Example 2 with StatisticsCaseAttribute

use of de.symeda.sormas.api.statistics.StatisticsCaseAttribute in project SORMAS-Project by hzi-braunschweig.

the class CaseStatisticsFacadeEjb method queryCaseCount.

@SuppressWarnings("unchecked")
@Override
public List<StatisticsCaseCountDto> queryCaseCount(StatisticsCaseCriteria caseCriteria, StatisticsCaseAttribute rowGrouping, StatisticsCaseSubAttribute rowSubGrouping, StatisticsCaseAttribute columnGrouping, StatisticsCaseSubAttribute columnSubGrouping, boolean includePopulation, boolean includeZeroValues, Integer populationReferenceYear) {
    // case counts
    Pair<String, List<Object>> caseCountQueryAndParams = buildCaseCountQuery(caseCriteria, rowGrouping, rowSubGrouping, columnGrouping, columnSubGrouping);
    Query caseCountQuery = em.createNativeQuery(caseCountQueryAndParams.getKey().toString());
    for (int i = 0; i < caseCountQueryAndParams.getValue().size(); i++) {
        caseCountQuery.setParameter(i + 1, caseCountQueryAndParams.getValue().get(i));
    }
    Function<Integer, RegionReferenceDto> regionProvider = id -> regionFacade.getRegionReferenceById(id);
    Function<Integer, DistrictReferenceDto> districtProvider = id -> districtFacade.getDistrictReferenceById(id);
    Function<Integer, CommunityReferenceDto> communityProvider = id -> communityFacade.getCommunityReferenceById(id);
    Function<Integer, FacilityReferenceDto> healthFacilityProvider = id -> facilityFacade.getFacilityReferenceById(id);
    List<StatisticsCaseCountDto> caseCountResults = ((Stream<Object[]>) caseCountQuery.getResultStream()).map(result -> {
        Object rowKey = "".equals(result[1]) ? null : result[1];
        Object columnKey = "".equals(result[2]) ? null : result[2];
        return new StatisticsCaseCountDto(result[0] != null ? ((Number) result[0]).intValue() : null, null, StatisticsHelper.buildGroupingKey(rowKey, rowGrouping, rowSubGrouping, regionProvider, districtProvider, communityProvider, healthFacilityProvider), StatisticsHelper.buildGroupingKey(columnKey, columnGrouping, columnSubGrouping, regionProvider, districtProvider, communityProvider, healthFacilityProvider));
    }).collect(Collectors.toList());
    if (includeZeroValues) {
        List<StatisticsGroupingKey> allRowKeys;
        if (rowGrouping != null) {
            allRowKeys = (List<StatisticsGroupingKey>) caseCriteria.getFilterValuesForGrouping(rowGrouping, rowSubGrouping);
            if (allRowKeys == null) {
                allRowKeys = StatisticsHelper.getAttributeGroupingKeys(rowGrouping, rowSubGrouping, diseaseConfigurationFacade, caseFacade, regionFacade, districtFacade);
            }
        } else {
            allRowKeys = Arrays.asList((StatisticsGroupingKey) null);
        }
        List<StatisticsGroupingKey> allColumnKeys;
        if (columnGrouping != null) {
            allColumnKeys = (List<StatisticsGroupingKey>) caseCriteria.getFilterValuesForGrouping(columnGrouping, columnSubGrouping);
            if (allColumnKeys == null) {
                allColumnKeys = StatisticsHelper.getAttributeGroupingKeys(columnGrouping, columnSubGrouping, diseaseConfigurationFacade, caseFacade, regionFacade, districtFacade);
            }
        } else {
            allColumnKeys = Arrays.asList((StatisticsGroupingKey) null);
        }
        for (StatisticsGroupingKey rowKey : allRowKeys) {
            for (StatisticsGroupingKey columnKey : allColumnKeys) {
                StatisticsCaseCountDto zeroDto = new StatisticsCaseCountDto(0, null, rowKey, columnKey);
                if (!caseCountResults.contains(zeroDto)) {
                    caseCountResults.add(zeroDto);
                }
            }
        }
    }
    // population
    if (includePopulation) {
        Pair<String, List<Object>> populationQueryAndParams = buildPopulationQuery(caseCriteria, rowGrouping, rowSubGrouping, columnGrouping, columnSubGrouping, populationReferenceYear);
        Query populationQuery = em.createNativeQuery(populationQueryAndParams.getKey().toString());
        for (int i = 0; i < populationQueryAndParams.getValue().size(); i++) {
            populationQuery.setParameter(i + 1, populationQueryAndParams.getValue().get(i));
        }
        List<StatisticsCaseCountDto> populationResults = ((Stream<Object[]>) populationQuery.getResultStream()).map(result -> {
            Object rowKey = "".equals(result[1]) ? null : result[1];
            Object columnKey = "".equals(result[2]) ? null : result[2];
            return new StatisticsCaseCountDto(null, result[0] != null ? ((Number) result[0]).intValue() : null, StatisticsHelper.buildGroupingKey(rowKey, rowGrouping, rowSubGrouping, regionProvider, districtProvider, communityProvider, healthFacilityProvider), StatisticsHelper.buildGroupingKey(columnKey, columnGrouping, columnSubGrouping, regionProvider, districtProvider, communityProvider, healthFacilityProvider));
        }).collect(Collectors.toList());
        boolean rowIsPopulation = rowGrouping != null && rowGrouping.isPopulationData();
        boolean columnIsPopulation = columnGrouping != null && columnGrouping.isPopulationData();
        if (!populationResults.isEmpty()) {
            assert ((populationResults.get(0).getRowKey() != null) == rowIsPopulation);
            assert ((populationResults.get(0).getColumnKey() != null) == columnIsPopulation);
        }
        // add the population data to the case counts
        // when a key is not a population data key, we use null instead
        StatisticsCaseCountDto searchDto = new StatisticsCaseCountDto(null, null, null, null);
        for (StatisticsCaseCountDto caseCountResult : caseCountResults) {
            if (rowIsPopulation) {
                searchDto.setRowKey(caseCountResult.getRowKey());
            }
            if (columnIsPopulation) {
                searchDto.setColumnKey(caseCountResult.getColumnKey());
            }
            int index = populationResults.indexOf(searchDto);
            if (index >= 0) {
                caseCountResult.setPopulation(populationResults.get(index).getPopulation());
            }
        }
    }
    return caseCountResults;
}
Also used : Arrays(java.util.Arrays) Date(java.util.Date) IntegerRange(de.symeda.sormas.api.IntegerRange) PopulationData(de.symeda.sormas.backend.infrastructure.PopulationData) DistrictService(de.symeda.sormas.backend.infrastructure.district.DistrictService) StringUtils(org.apache.commons.lang3.StringUtils) AgeGroup(de.symeda.sormas.api.AgeGroup) CommunityFacadeEjbLocal(de.symeda.sormas.backend.infrastructure.community.CommunityFacadeEjb.CommunityFacadeEjbLocal) StatisticsCaseAttribute(de.symeda.sormas.api.statistics.StatisticsCaseAttribute) Facility(de.symeda.sormas.backend.infrastructure.facility.Facility) Pair(org.apache.commons.lang3.tuple.Pair) Stateless(javax.ejb.Stateless) StatisticsGroupingKey(de.symeda.sormas.api.statistics.StatisticsGroupingKey) FacilityService(de.symeda.sormas.backend.infrastructure.facility.FacilityService) Person(de.symeda.sormas.backend.person.Person) CommunityService(de.symeda.sormas.backend.infrastructure.community.CommunityService) Region(de.symeda.sormas.backend.infrastructure.region.Region) District(de.symeda.sormas.backend.infrastructure.district.District) DistrictFacadeEjbLocal(de.symeda.sormas.backend.infrastructure.district.DistrictFacadeEjb.DistrictFacadeEjbLocal) Collectors(java.util.stream.Collectors) CommunityReferenceDto(de.symeda.sormas.api.infrastructure.community.CommunityReferenceDto) List(java.util.List) Query(javax.persistence.Query) Stream(java.util.stream.Stream) User(de.symeda.sormas.backend.user.User) LocalDate(java.time.LocalDate) Location(de.symeda.sormas.backend.location.Location) RegionReferenceDto(de.symeda.sormas.api.infrastructure.region.RegionReferenceDto) IntStream(java.util.stream.IntStream) Community(de.symeda.sormas.backend.infrastructure.community.Community) QueryHelper(de.symeda.sormas.backend.util.QueryHelper) Function(java.util.function.Function) ArrayList(java.util.ArrayList) CollectionUtils(org.apache.commons.collections.CollectionUtils) FacilityFacadeEjbLocal(de.symeda.sormas.backend.infrastructure.facility.FacilityFacadeEjb.FacilityFacadeEjbLocal) LocalBean(javax.ejb.LocalBean) Symptoms(de.symeda.sormas.backend.symptoms.Symptoms) DiseaseConfigurationFacadeEjb(de.symeda.sormas.backend.disease.DiseaseConfigurationFacadeEjb) StatisticsCaseCriteria(de.symeda.sormas.api.statistics.StatisticsCaseCriteria) EJB(javax.ejb.EJB) ModelConstants(de.symeda.sormas.backend.util.ModelConstants) CaseStatisticsFacade(de.symeda.sormas.api.caze.CaseStatisticsFacade) DistrictReferenceDto(de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto) UserDto(de.symeda.sormas.api.user.UserDto) EntityManager(javax.persistence.EntityManager) PersistenceContext(javax.persistence.PersistenceContext) DiseaseConfigurationFacade(de.symeda.sormas.api.disease.DiseaseConfigurationFacade) RegionService(de.symeda.sormas.backend.infrastructure.region.RegionService) FacilityReferenceDto(de.symeda.sormas.api.infrastructure.facility.FacilityReferenceDto) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) StatisticsCaseCountDto(de.symeda.sormas.api.statistics.StatisticsCaseCountDto) StatisticsCaseSubAttribute(de.symeda.sormas.api.statistics.StatisticsCaseSubAttribute) RegionFacadeEjbLocal(de.symeda.sormas.backend.infrastructure.region.RegionFacadeEjb.RegionFacadeEjbLocal) StatisticsHelper(de.symeda.sormas.api.statistics.StatisticsHelper) Query(javax.persistence.Query) FacilityReferenceDto(de.symeda.sormas.api.infrastructure.facility.FacilityReferenceDto) DistrictReferenceDto(de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto) CommunityReferenceDto(de.symeda.sormas.api.infrastructure.community.CommunityReferenceDto) RegionReferenceDto(de.symeda.sormas.api.infrastructure.region.RegionReferenceDto) List(java.util.List) ArrayList(java.util.ArrayList) StatisticsGroupingKey(de.symeda.sormas.api.statistics.StatisticsGroupingKey) StatisticsCaseCountDto(de.symeda.sormas.api.statistics.StatisticsCaseCountDto)

Example 3 with StatisticsCaseAttribute

use of de.symeda.sormas.api.statistics.StatisticsCaseAttribute in project SORMAS-Project by hzi-braunschweig.

the class StatisticsView method generateChart.

public void generateChart() {
    List<StatisticsCaseCountDto> resultData = generateStatistics();
    if (resultData.isEmpty()) {
        resultsLayout.addComponent(emptyResultLabel);
        return;
    }
    if (showCaseIncidence && caseIncidencePossible && populationReferenceYear != null && populationReferenceYear != Calendar.getInstance().get(Calendar.YEAR)) {
        referenceYearLabel = new Label(VaadinIcons.INFO_CIRCLE.getHtml() + " " + String.format(I18nProperties.getString(Strings.infoPopulationReferenceYear), populationReferenceYear), ContentMode.HTML);
        resultsLayout.addComponent(referenceYearLabel);
        CssStyles.style(referenceYearLabel, CssStyles.VSPACE_TOP_4);
    }
    if (showCaseIncidence && (!caseIncidencePossible || hasMissingPopulationData)) {
        if (!caseIncidencePossible) {
            if (hasMissingPopulationData) {
                caseIncidenceNotPossibleLabel = new Label(VaadinIcons.INFO_CIRCLE.getHtml() + " " + String.format(I18nProperties.getString(Strings.infoCaseIncidenceNotPossible), missingPopulationDataNames), ContentMode.HTML);
            } else {
                caseIncidenceNotPossibleLabel = new Label(VaadinIcons.INFO_CIRCLE.getHtml() + " " + I18nProperties.getString(Strings.infoCaseIncidenceIncompatible), ContentMode.HTML);
            }
        } else {
            caseIncidenceNotPossibleLabel = new Label(VaadinIcons.INFO_CIRCLE.getHtml() + " " + String.format(I18nProperties.getString(Strings.infoCaseIncidenceMissingPopulationData), missingPopulationDataNames), ContentMode.HTML);
        }
        resultsLayout.addComponent(caseIncidenceNotPossibleLabel);
        caseIncidenceNotPossibleLabel.setWidth(100, Unit.PERCENTAGE);
        CssStyles.style(caseIncidenceNotPossibleLabel, CssStyles.VSPACE_TOP_4);
    }
    StatisticsVisualizationChartType chartType = visualizationComponent.getVisualizationChartType();
    StatisticsCaseAttribute xAxisAttribute = visualizationComponent.getColumnsAttribute();
    StatisticsCaseSubAttribute xAxisSubAttribute = visualizationComponent.getColumnsSubAttribute();
    StatisticsCaseAttribute seriesAttribute = visualizationComponent.getRowsAttribute();
    StatisticsCaseSubAttribute seriesSubAttribute = visualizationComponent.getRowsSubAttribute();
    HighChart chart = new HighChart();
    chart.setWidth(100, Unit.PERCENTAGE);
    chart.setHeight(580, Unit.PIXELS);
    StringBuilder hcjs = new StringBuilder();
    hcjs.append("var options = {").append("chart:{ " + " ignoreHiddenSeries: false, " + " type: '");
    switch(chartType) {
        case COLUMN:
        case STACKED_COLUMN:
            hcjs.append("column");
            break;
        case LINE:
            hcjs.append("line");
            break;
        case PIE:
            hcjs.append("pie");
            break;
        default:
            throw new IllegalArgumentException(chartType.toString());
    }
    hcjs.append("', " + " backgroundColor: 'transparent' " + "}," + "credits:{ enabled: false }," + "exporting:{ " + " enabled: true," + " buttons:{ contextButton:{ theme:{ fill: 'transparent' } } }" + "}," + "title:{ text: '' },");
    CaseCountOrIncidence dataStyle = showCaseIncidence && caseIncidencePossible ? CaseCountOrIncidence.CASE_INCIDENCE : CaseCountOrIncidence.CASE_COUNT;
    TreeMap<StatisticsGroupingKey, String> xAxisCaptions = new TreeMap<>(new StatisticsKeyComparator());
    TreeMap<StatisticsGroupingKey, String> seriesCaptions = new TreeMap<>(new StatisticsKeyComparator());
    boolean appendUnknownXAxisCaption = false;
    if (seriesAttribute != null || xAxisAttribute != null) {
        // Build captions for x-axis and/or series
        for (StatisticsCaseCountDto row : resultData) {
            if (xAxisAttribute != null) {
                if (!StatisticsHelper.isNullOrUnknown(row.getColumnKey())) {
                    xAxisCaptions.putIfAbsent((StatisticsGroupingKey) row.getColumnKey(), row.getColumnKey().toString());
                } else {
                    appendUnknownXAxisCaption = true;
                }
            }
            if (seriesAttribute != null) {
                if (!StatisticsHelper.isNullOrUnknown(row.getRowKey())) {
                    seriesCaptions.putIfAbsent((StatisticsGroupingKey) row.getRowKey(), row.getRowKey().toString());
                }
            }
        }
    }
    if (chartType != StatisticsVisualizationChartType.PIE) {
        hcjs.append("xAxis: { categories: [");
        if (xAxisAttribute != null) {
            xAxisCaptions.forEach((key, value) -> {
                hcjs.append("'").append(StringEscapeUtils.escapeEcmaScript(xAxisCaptions.get(key))).append("',");
            });
            if (appendUnknownXAxisCaption) {
                hcjs.append("'").append(getEscapedFragment(StatisticsHelper.NOT_SPECIFIED)).append("'");
            }
        } else if (seriesAttribute != null) {
            hcjs.append("'").append(seriesSubAttribute != null ? seriesSubAttribute.toString() : seriesAttribute.toString()).append("'");
        } else {
            hcjs.append("'").append(getEscapedFragment(StatisticsHelper.TOTAL)).append("'");
        }
        int numberOfCategories = xAxisAttribute != null ? appendUnknownXAxisCaption ? xAxisCaptions.size() + 1 : xAxisCaptions.size() : 1;
        hcjs.append("], min: 0, max: " + (numberOfCategories - 1) + "},");
        hcjs.append("yAxis: { min: 0, title: { text: '").append(dataStyle).append("' },").append("allowDecimals: false, softMax: ").append(showCaseIncidence && caseIncidencePossible ? 1 : 10).append(", stackLabels: { enabled: true, ").append("style: {fontWeight: 'normal', textOutline: '0', gridLineColor: '#000000', color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray' } } },");
        hcjs.append("tooltip: { headerFormat: '<b>{point.x}</b><br/>', pointFormat: '{series.name}: {point.y}");
        if (chartType == StatisticsVisualizationChartType.STACKED_COLUMN) {
            hcjs.append("<br/>").append(I18nProperties.getCaption(Captions.total) + ": {point.stackTotal}");
        }
        hcjs.append("'},");
    }
    hcjs.append("legend: { verticalAlign: 'top', backgroundColor: 'transparent', align: 'left', " + "borderWidth: 0, shadow: false, margin: 30, padding: 0 },");
    hcjs.append("colors: ['#FF0000','#6691C4','#ffba08','#519e8a','#ed254e','#39a0ed','#FF8C00','#344055','#D36135','#82d173'],");
    if (chartType == StatisticsVisualizationChartType.STACKED_COLUMN || chartType == StatisticsVisualizationChartType.COLUMN) {
        hcjs.append("plotOptions: { column: { borderWidth: 0, ");
        if (chartType == StatisticsVisualizationChartType.STACKED_COLUMN) {
            hcjs.append("stacking: 'normal', ");
        }
        // @formatter:off
        hcjs.append("groupPadding: 0.05, pointPadding: 0, " + "dataLabels: {" + "enabled: true," + "formatter: function() { if (this.y > 0) return this.y; }," + "color: '#444'," + "backgroundColor: 'rgba(255, 255, 255, 0.75)'," + "borderRadius: 3," + "padding: 3," + "style:{textOutline:'none'}" + "} } },");
    // @formatter:on
    }
    hcjs.append("series: [");
    if (seriesAttribute == null && xAxisAttribute == null) {
        hcjs.append("{ name: '").append(dataStyle).append("', dataLabels: { allowOverlap: false }").append(", data: [['").append(dataStyle).append("',");
        if (!showCaseIncidence || !caseIncidencePossible) {
            hcjs.append(resultData.get(0).getCaseCount().toString());
        } else {
            hcjs.append(resultData.get(0).getIncidence(incidenceDivisor));
        }
        hcjs.append("]]}");
    } else if (visualizationComponent.getVisualizationChartType() == StatisticsVisualizationChartType.PIE) {
        hcjs.append("{ name: '").append(dataStyle).append("', dataLabels: { allowOverlap: false }").append(", data: [");
        TreeMap<StatisticsGroupingKey, StatisticsCaseCountDto> seriesElements = new TreeMap<>(new StatisticsKeyComparator());
        StatisticsCaseCountDto unknownSeriesElement = null;
        for (StatisticsCaseCountDto row : resultData) {
            Object seriesId = row.getRowKey();
            if (StatisticsHelper.isNullOrUnknown(seriesId)) {
                unknownSeriesElement = row;
            } else {
                seriesElements.put((StatisticsGroupingKey) seriesId, row);
            }
        }
        seriesElements.forEach((key, value) -> {
            Object seriesValue;
            if (!showCaseIncidence || !caseIncidencePossible) {
                seriesValue = value.getCaseCount();
            } else {
                seriesValue = value.getIncidence(incidenceDivisor);
            }
            Object seriesId = value.getRowKey();
            hcjs.append("['").append(StringEscapeUtils.escapeEcmaScript(seriesCaptions.get(seriesId))).append("',").append(seriesValue).append("],");
        });
        if (unknownSeriesElement != null) {
            Object seriesValue;
            if (!showCaseIncidence || !caseIncidencePossible) {
                seriesValue = unknownSeriesElement.getCaseCount();
            } else {
                seriesValue = unknownSeriesElement.getIncidence(incidenceDivisor);
            }
            hcjs.append("['").append(dataStyle).append("',").append(seriesValue).append("],");
        }
        hcjs.append("]}");
    } else {
        Object seriesKey = null;
        TreeMap<StatisticsGroupingKey, String> seriesStrings = new TreeMap<>(new StatisticsKeyComparator());
        final StringBuilder currentSeriesString = new StringBuilder();
        final StringBuilder unknownSeriesString = new StringBuilder();
        final StringBuilder totalSeriesString = new StringBuilder();
        TreeMap<Integer, Number> currentSeriesValues = new TreeMap<>();
        for (StatisticsCaseCountDto row : resultData) {
            // Retrieve series caption of the current row
            Object rowSeriesKey;
            if (seriesAttribute != null) {
                if (!StatisticsHelper.isNullOrUnknown(row.getRowKey())) {
                    rowSeriesKey = row.getRowKey();
                } else {
                    rowSeriesKey = StatisticsHelper.VALUE_UNKNOWN;
                }
            } else {
                rowSeriesKey = StatisticsHelper.TOTAL;
            }
            // begin a new series
            if (!DataHelper.equal(seriesKey, rowSeriesKey)) {
                finalizeChartSegment(seriesKey, currentSeriesValues, unknownSeriesString, currentSeriesString, totalSeriesString, seriesStrings);
                // Append the start sequence of the next series String
                if (StatisticsHelper.isNullOrUnknown(rowSeriesKey)) {
                    seriesKey = StatisticsHelper.VALUE_UNKNOWN;
                    unknownSeriesString.append("{ name: '").append(getEscapedFragment(StatisticsHelper.NOT_SPECIFIED)).append("', dataLabels: { allowOverlap: false }, data: [");
                } else if (rowSeriesKey.equals(StatisticsHelper.TOTAL)) {
                    seriesKey = StatisticsHelper.TOTAL;
                    totalSeriesString.append("{name : '").append(getEscapedFragment(StatisticsHelper.TOTAL)).append("', dataLabels: { allowOverlap: false }, data: [");
                } else {
                    seriesKey = (StatisticsGroupingKey) row.getRowKey();
                    currentSeriesString.append("{ name: '").append(StringEscapeUtils.escapeEcmaScript(seriesCaptions.get(seriesKey))).append("', dataLabels: { allowOverlap: false }, data: [");
                }
            }
            Object value;
            if (!showCaseIncidence || !caseIncidencePossible) {
                value = row.getCaseCount();
            } else {
                value = row.getIncidence(incidenceDivisor);
            }
            if (xAxisAttribute != null) {
                Object xAxisId = row.getColumnKey();
                int captionPosition = StatisticsHelper.isNullOrUnknown(xAxisId) ? xAxisCaptions.size() : xAxisCaptions.headMap((StatisticsGroupingKey) xAxisId).size();
                currentSeriesValues.put(captionPosition, (Number) value);
            } else {
                currentSeriesValues.put(0, (Number) value);
            }
        }
        // Add the last series
        finalizeChartSegment(seriesKey, currentSeriesValues, unknownSeriesString, currentSeriesString, totalSeriesString, seriesStrings);
        seriesStrings.forEach((key, value) -> {
            hcjs.append(value);
        });
        // Add the "Unknown" series
        if (unknownSeriesString.length() > 0) {
            hcjs.append(unknownSeriesString.toString());
        }
        // Add the "Total" series
        if (totalSeriesString.length() > 0) {
            hcjs.append(totalSeriesString.toString());
        }
        // Remove last three characters to avoid invalid chart
        hcjs.delete(hcjs.length() - 3, hcjs.length());
        hcjs.append("]}");
    }
    hcjs.append("],");
    // @formatter:off
    hcjs.append("exporting: {\n" + "        buttons: {\n" + "            contextButton: {\n" + "                menuItems: [\n" + "                    'printChart',\n" + "                    'separator',\n" + "                    'downloadPNG',\n" + "                    'downloadJPEG',\n" + "                    'downloadPDF',\n" + "                    'downloadSVG',\n" + "                    'downloadCSV',\n" + "                    'downloadXLS'\n" + "                ]\n" + "            }\n" + "        }\n" + "    }");
    hcjs.append("};");
    // @formatter:on
    chart.setHcjs(hcjs.toString());
    resultsLayout.addComponent(chart);
    resultsLayout.setExpandRatio(chart, 1);
    if (showCaseIncidence && hasMissingPopulationData && caseIncidencePossible) {
        resultsLayout.addComponent(caseIncidenceNotPossibleLabel);
    }
}
Also used : Arrays(java.util.Arrays) TextField(com.vaadin.ui.TextField) Date(java.util.Date) I18nProperties(de.symeda.sormas.api.i18n.I18nProperties) EpiWeek(de.symeda.sormas.api.utils.EpiWeek) IntegerRange(de.symeda.sormas.api.IntegerRange) Alignment(com.vaadin.ui.Alignment) ReferenceDto(de.symeda.sormas.api.ReferenceDto) AgeGroup(de.symeda.sormas.api.AgeGroup) QuarterOfYear(de.symeda.sormas.api.QuarterOfYear) BigDecimal(java.math.BigDecimal) CaseOutcome(de.symeda.sormas.api.caze.CaseOutcome) ExportEntityName(de.symeda.sormas.ui.utils.ExportEntityName) StatisticsCaseAttribute(de.symeda.sormas.api.statistics.StatisticsCaseAttribute) CheckBox(com.vaadin.ui.CheckBox) CssStyles(de.symeda.sormas.ui.utils.CssStyles) Page(com.vaadin.server.Page) Quarter(de.symeda.sormas.api.Quarter) Year(de.symeda.sormas.api.Year) GeoLatLon(de.symeda.sormas.api.geo.GeoLatLon) VaadinIcons(com.vaadin.icons.VaadinIcons) LeafletMap(de.symeda.sormas.ui.map.LeafletMap) UserRole(de.symeda.sormas.api.user.UserRole) LeafletMapUtil(de.symeda.sormas.ui.map.LeafletMapUtil) RoundingMode(java.math.RoundingMode) ValoTheme(com.vaadin.ui.themes.ValoTheme) DownloadUtil(de.symeda.sormas.ui.utils.DownloadUtil) StatisticsGroupingKey(de.symeda.sormas.api.statistics.StatisticsGroupingKey) StatisticsKeyComparator(de.symeda.sormas.api.statistics.StatisticsHelper.StatisticsKeyComparator) Sex(de.symeda.sormas.api.person.Sex) HtmlHelper(de.symeda.sormas.api.utils.HtmlHelper) HighChart(de.symeda.sormas.ui.highcharts.HighChart) CommunityReferenceDto(de.symeda.sormas.api.infrastructure.community.CommunityReferenceDto) List(java.util.List) Type(com.vaadin.ui.Notification.Type) TokenizableValue(de.symeda.sormas.ui.statistics.StatisticsFilterElement.TokenizableValue) RadioButtonGroup(com.vaadin.ui.RadioButtonGroup) Descriptions(de.symeda.sormas.api.i18n.Descriptions) RegionReferenceDto(de.symeda.sormas.api.infrastructure.region.RegionReferenceDto) StreamResource(com.vaadin.server.StreamResource) FacadeProvider(de.symeda.sormas.api.FacadeProvider) VerticalLayout(com.vaadin.ui.VerticalLayout) CaseMeasure(de.symeda.sormas.api.CaseMeasure) CaseClassification(de.symeda.sormas.api.caze.CaseClassification) LeafletPolygon(de.symeda.sormas.ui.map.LeafletPolygon) Function(java.util.function.Function) ArrayList(java.util.ArrayList) Calendar(java.util.Calendar) CollectionUtils(org.apache.commons.collections.CollectionUtils) Notification(com.vaadin.ui.Notification) Label(com.vaadin.ui.Label) StatisticsCaseCriteria(de.symeda.sormas.api.statistics.StatisticsCaseCriteria) AbstractOrderedLayout(com.vaadin.ui.AbstractOrderedLayout) StatisticsVisualizationChartType(de.symeda.sormas.ui.statistics.StatisticsVisualizationType.StatisticsVisualizationChartType) Month(de.symeda.sormas.api.Month) ButtonHelper(de.symeda.sormas.ui.utils.ButtonHelper) ContentMode(com.vaadin.shared.ui.ContentMode) Validations(de.symeda.sormas.api.i18n.Validations) DataHelper(de.symeda.sormas.api.utils.DataHelper) DashboardMapComponent(de.symeda.sormas.ui.dashboard.map.DashboardMapComponent) DistrictReferenceDto(de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto) StringEscapeUtils(org.apache.commons.text.StringEscapeUtils) FacilityReferenceDto(de.symeda.sormas.api.infrastructure.facility.FacilityReferenceDto) Captions(de.symeda.sormas.api.i18n.Captions) StatisticsCaseCountDto(de.symeda.sormas.api.statistics.StatisticsCaseCountDto) Button(com.vaadin.ui.Button) StatisticsCaseSubAttribute(de.symeda.sormas.api.statistics.StatisticsCaseSubAttribute) Disease(de.symeda.sormas.api.Disease) TreeMap(java.util.TreeMap) HorizontalLayout(com.vaadin.ui.HorizontalLayout) FileDownloader(com.vaadin.server.FileDownloader) StatisticsHelper(de.symeda.sormas.api.statistics.StatisticsHelper) MonthOfYear(de.symeda.sormas.api.MonthOfYear) Comparator(java.util.Comparator) Strings(de.symeda.sormas.api.i18n.Strings) Collections(java.util.Collections) StatisticsVisualizationChartType(de.symeda.sormas.ui.statistics.StatisticsVisualizationType.StatisticsVisualizationChartType) StatisticsKeyComparator(de.symeda.sormas.api.statistics.StatisticsHelper.StatisticsKeyComparator) Label(com.vaadin.ui.Label) HighChart(de.symeda.sormas.ui.highcharts.HighChart) TreeMap(java.util.TreeMap) StatisticsCaseSubAttribute(de.symeda.sormas.api.statistics.StatisticsCaseSubAttribute) StatisticsGroupingKey(de.symeda.sormas.api.statistics.StatisticsGroupingKey) StatisticsCaseCountDto(de.symeda.sormas.api.statistics.StatisticsCaseCountDto) StatisticsCaseAttribute(de.symeda.sormas.api.statistics.StatisticsCaseAttribute)

Example 4 with StatisticsCaseAttribute

use of de.symeda.sormas.api.statistics.StatisticsCaseAttribute in project SORMAS-Project by hzi-braunschweig.

the class StatisticsVisualizationElement method createAndAddComponents.

private void createAndAddComponents() {
    displayedAttributeDropdown = new MenuBar();
    displayedAttributeDropdown.setId("visualizationType");
    displayedAttributeDropdown.setCaption(type.toString(visualizationType));
    displayedAttributeItem = displayedAttributeDropdown.addItem(type.getEmptySelectionString(visualizationType), null);
    displayedSubAttributeDropdown = new MenuBar();
    displayedSubAttributeDropdown.setId("displayedSubAttribute");
    CssStyles.style(displayedSubAttributeDropdown, CssStyles.FORCE_CAPTION);
    displayedSubAttributeItem = displayedSubAttributeDropdown.addItem(I18nProperties.getCaption(Captions.statisticsSpecifySelection), null);
    // Empty selections
    Command emptyItemCommand = selectedItem -> {
        attribute = null;
        subAttribute = null;
        resetSubAttributeDropdown();
        displayedAttributeItem.setText(type.getEmptySelectionString(visualizationType));
        removeSelections(displayedAttributeItem);
    };
    emptySelectionItem = displayedAttributeItem.addItem(type.getEmptySelectionString(visualizationType), emptyItemCommand);
    // Add attribute groups
    for (StatisticsCaseAttributeGroup attributeGroup : StatisticsCaseAttributeGroup.values()) {
        MenuItem attributeGroupItem = displayedAttributeItem.addItem(attributeGroup.toString(), null);
        attributeGroupItem.setEnabled(false);
        // Add attributes belonging to the current group
        for (StatisticsCaseAttribute attribute : attributeGroup.getAttributes()) {
            if (attribute.isUsedForVisualisation()) {
                Command attributeCommand = selectedItem -> {
                    resetSubAttributeDropdown();
                    this.attribute = attribute;
                    this.subAttribute = null;
                    displayedAttributeItem.setText(attribute.toString());
                    removeSelections(displayedAttributeItem);
                    selectedItem.setStyleName("selected-filter");
                    // Build sub attribute dropdown
                    if (attribute.getSubAttributes().length > 0) {
                        for (StatisticsCaseSubAttribute subAttribute : attribute.getSubAttributes()) {
                            if (subAttribute.isUsedForGrouping()) {
                                Command subAttributeCommand = selectedSubItem -> {
                                    this.subAttribute = subAttribute;
                                    displayedSubAttributeItem.setText(subAttribute.toString());
                                    removeSelections(displayedSubAttributeItem);
                                    selectedSubItem.setStyleName("selected-filter");
                                };
                                displayedSubAttributeItem.addItem(subAttribute.toString(), subAttributeCommand);
                            }
                        }
                        addComponent(displayedSubAttributeDropdown);
                    }
                };
                displayedAttributeItem.addItem(attribute.toString(), attributeCommand);
            }
        }
    }
    addComponent(displayedAttributeDropdown);
}
Also used : MenuItem(com.vaadin.ui.MenuBar.MenuItem) StatisticsCaseAttribute(de.symeda.sormas.api.statistics.StatisticsCaseAttribute) StatisticsCaseSubAttribute(de.symeda.sormas.api.statistics.StatisticsCaseSubAttribute) StatisticsCaseAttributeGroup(de.symeda.sormas.api.statistics.StatisticsCaseAttributeGroup) CssStyles(de.symeda.sormas.ui.utils.CssStyles) HorizontalLayout(com.vaadin.ui.HorizontalLayout) MenuBar(com.vaadin.ui.MenuBar) I18nProperties(de.symeda.sormas.api.i18n.I18nProperties) Command(com.vaadin.ui.MenuBar.Command) Captions(de.symeda.sormas.api.i18n.Captions) Command(com.vaadin.ui.MenuBar.Command) MenuBar(com.vaadin.ui.MenuBar) MenuItem(com.vaadin.ui.MenuBar.MenuItem) StatisticsCaseAttributeGroup(de.symeda.sormas.api.statistics.StatisticsCaseAttributeGroup) StatisticsCaseAttribute(de.symeda.sormas.api.statistics.StatisticsCaseAttribute) StatisticsCaseSubAttribute(de.symeda.sormas.api.statistics.StatisticsCaseSubAttribute)

Example 5 with StatisticsCaseAttribute

use of de.symeda.sormas.api.statistics.StatisticsCaseAttribute in project SORMAS-Project by hzi-braunschweig.

the class CaseStatisticsFacadeEjbTest method testQueryCaseCount.

@Test
public void testQueryCaseCount() {
    RDCF rdcf = creator.createRDCF("Region", "District", "Community", "Facility");
    UserDto user = creator.createUser(rdcf.region.getUuid(), rdcf.district.getUuid(), rdcf.facility.getUuid(), "Surv", "Sup", UserRole.SURVEILLANCE_SUPERVISOR);
    PersonDto cazePerson = creator.createPerson("Case", "Person");
    cazePerson.setApproximateAge(30);
    cazePerson.setApproximateAgeReferenceDate(new Date());
    cazePerson.setApproximateAgeType(ApproximateAgeType.YEARS);
    cazePerson = getPersonFacade().savePerson(cazePerson);
    CaseDataDto caze = creator.createCase(user.toReference(), cazePerson.toReference(), Disease.EVD, CaseClassification.PROBABLE, InvestigationStatus.PENDING, new Date(), rdcf);
    caze.setOutcomeDate(DateHelper.addWeeks(caze.getReportDate(), 2));
    caze = getCaseFacade().save(caze);
    StatisticsCaseCriteria criteria = new StatisticsCaseCriteria();
    int year = DateHelper8.toLocalDate(caze.getSymptoms().getOnsetDate()).getYear();
    criteria.years(Arrays.asList(new Year(year), new Year(year + 1)), StatisticsCaseAttribute.ONSET_TIME);
    criteria.regions(Arrays.asList(new RegionReferenceDto(rdcf.region.getUuid(), null, null)));
    criteria.addAgeIntervals(Arrays.asList(new IntegerRange(10, 40)));
    List<StatisticsCaseCountDto> results = getCaseStatisticsFacade().queryCaseCount(criteria, null, null, null, null, false, false, null);
    // List should have one entry
    assertEquals(1, results.size());
    // try all groupings
    for (StatisticsCaseAttribute groupingAttribute : StatisticsCaseAttribute.values()) {
        StatisticsCaseSubAttribute[] subAttributes = groupingAttribute.getSubAttributes();
        if (subAttributes.length == 0) {
            getCaseStatisticsFacade().queryCaseCount(criteria, groupingAttribute, null, null, null, false, false, null);
        } else {
            for (StatisticsCaseSubAttribute subGroupingAttribute : groupingAttribute.getSubAttributes()) {
                if (subGroupingAttribute.isUsedForGrouping()) {
                    getCaseStatisticsFacade().queryCaseCount(criteria, groupingAttribute, subGroupingAttribute, null, null, false, false, null);
                }
            }
        }
    }
}
Also used : IntegerRange(de.symeda.sormas.api.IntegerRange) CaseDataDto(de.symeda.sormas.api.caze.CaseDataDto) PersonDto(de.symeda.sormas.api.person.PersonDto) UserDto(de.symeda.sormas.api.user.UserDto) StatisticsCaseSubAttribute(de.symeda.sormas.api.statistics.StatisticsCaseSubAttribute) Date(java.util.Date) LocalDate(java.time.LocalDate) RDCF(de.symeda.sormas.backend.TestDataCreator.RDCF) RegionReferenceDto(de.symeda.sormas.api.infrastructure.region.RegionReferenceDto) Year(de.symeda.sormas.api.Year) StatisticsCaseCriteria(de.symeda.sormas.api.statistics.StatisticsCaseCriteria) StatisticsCaseCountDto(de.symeda.sormas.api.statistics.StatisticsCaseCountDto) StatisticsCaseAttribute(de.symeda.sormas.api.statistics.StatisticsCaseAttribute) AbstractBeanTest(de.symeda.sormas.backend.AbstractBeanTest) Test(org.junit.Test)

Aggregations

StatisticsCaseAttribute (de.symeda.sormas.api.statistics.StatisticsCaseAttribute)5 StatisticsCaseSubAttribute (de.symeda.sormas.api.statistics.StatisticsCaseSubAttribute)5 HorizontalLayout (com.vaadin.ui.HorizontalLayout)3 IntegerRange (de.symeda.sormas.api.IntegerRange)3 Captions (de.symeda.sormas.api.i18n.Captions)3 I18nProperties (de.symeda.sormas.api.i18n.I18nProperties)3 RegionReferenceDto (de.symeda.sormas.api.infrastructure.region.RegionReferenceDto)3 StatisticsCaseCountDto (de.symeda.sormas.api.statistics.StatisticsCaseCountDto)3 StatisticsCaseCriteria (de.symeda.sormas.api.statistics.StatisticsCaseCriteria)3 CssStyles (de.symeda.sormas.ui.utils.CssStyles)3 Date (java.util.Date)3 MenuBar (com.vaadin.ui.MenuBar)2 Command (com.vaadin.ui.MenuBar.Command)2 MenuItem (com.vaadin.ui.MenuBar.MenuItem)2 AgeGroup (de.symeda.sormas.api.AgeGroup)2 Year (de.symeda.sormas.api.Year)2 CommunityReferenceDto (de.symeda.sormas.api.infrastructure.community.CommunityReferenceDto)2 DistrictReferenceDto (de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto)2 FacilityReferenceDto (de.symeda.sormas.api.infrastructure.facility.FacilityReferenceDto)2 StatisticsGroupingKey (de.symeda.sormas.api.statistics.StatisticsGroupingKey)2