=== added directory 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/eventchart' === added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/eventchart/EventChart.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/eventchart/EventChart.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/eventchart/EventChart.java 2014-06-16 16:20:38 +0000 @@ -0,0 +1,749 @@ +package org.hisp.dhis.eventchart; + +/* + * Copyright (c) 2004-2014, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.hisp.dhis.common.BaseAnalyticalObject; +import org.hisp.dhis.common.BaseIdentifiableObject; +import org.hisp.dhis.common.DimensionalObject; +import org.hisp.dhis.common.DxfNamespaces; +import org.hisp.dhis.common.IdentifiableObject; +import org.hisp.dhis.common.IdentifiableObjectUtils; +import org.hisp.dhis.common.NameableObject; +import org.hisp.dhis.common.view.DetailedView; +import org.hisp.dhis.common.view.DimensionalView; +import org.hisp.dhis.common.view.ExportView; +import org.hisp.dhis.i18n.I18nFormat; +import org.hisp.dhis.organisationunit.OrganisationUnit; +import org.hisp.dhis.period.Period; +import org.hisp.dhis.program.Program; +import org.hisp.dhis.program.ProgramStage; +import org.hisp.dhis.user.User; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonView; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; + +/** + * @author Jan Henrik Overland + */ +@JacksonXmlRootElement( localName = "eventchart", namespace = DxfNamespaces.DXF_2_0 ) +public class EventChart + extends BaseAnalyticalObject +{ + private static final long serialVersionUID = 2570074075484545534L; + + public static final String SIZE_NORMAL = "normal"; + + public static final String SIZE_WIDE = "wide"; + + public static final String SIZE_TALL = "tall"; + + public static final String TYPE_COLUMN = "column"; + + public static final String TYPE_STACKED_COLUMN = "stackedcolumn"; + + public static final String TYPE_BAR = "bar"; + + public static final String TYPE_STACKED_BAR = "stackedbar"; + + public static final String TYPE_LINE = "line"; + + public static final String TYPE_AREA = "area"; + + public static final String TYPE_PIE = "pie"; + + public static final String TYPE_RADAR = "radar"; // Spider web + + private Program program; + + private ProgramStage programStage; + + private Date startDate; + + private Date endDate; + + private String domainAxisLabel; + + private String rangeAxisLabel; + + private String type; + + private String series; + + private String category; + + private List filterDimensions = new ArrayList(); + + private String countType; + + private boolean hideLegend; + + private boolean regression; + + private boolean hideTitle; + + private boolean hideSubtitle; + + private String title; + + private Double targetLineValue; + + private String targetLineLabel; + + private Double baseLineValue; + + private String baseLineLabel; + + private boolean showData; + + private boolean hideEmptyRows; + + private Double rangeAxisMaxValue; + + private Double rangeAxisMinValue; + + private Integer rangeAxisSteps; // min 1 + + private Integer rangeAxisDecimals; + + // ------------------------------------------------------------------------- + // Transient properties + // ------------------------------------------------------------------------- + + private transient I18nFormat format; + + private transient List relativePeriods = new ArrayList(); + + private transient User user; + + private transient List organisationUnitsAtLevel = new ArrayList(); + + private transient List organisationUnitsInGroups = new ArrayList(); + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + public EventChart() + { + setAutoFields(); + } + + public EventChart( String name ) + { + this(); + this.name = name; + } + + // ------------------------------------------------------------------------- + // Init + // ------------------------------------------------------------------------- + + @Override + public void init( User user, Date date, OrganisationUnit organisationUnit, + List organisationUnitsAtLevel, List organisationUnitsInGroups, + I18nFormat format ) + { + this.user = user; + this.relativePeriodDate = date; + this.relativeOrganisationUnit = organisationUnit; + this.organisationUnitsAtLevel = organisationUnitsAtLevel; + this.organisationUnitsInGroups = organisationUnitsInGroups; + this.format = format; + } + + // ------------------------------------------------------------------------- + // Logic + // ------------------------------------------------------------------------- + + public List series() + { + DimensionalObject object = getDimensionalObject( series, relativePeriodDate, user, true, + organisationUnitsAtLevel, organisationUnitsInGroups, format ); + + return object != null ? object.getItems() : null; + } + + public List category() + { + DimensionalObject object = getDimensionalObject( category, relativePeriodDate, user, true, + organisationUnitsAtLevel, organisationUnitsInGroups, format ); + + return object != null ? object.getItems() : null; + } + + public List filters() + { + List filterItems = new ArrayList(); + + for ( String filter : filterDimensions ) + { + DimensionalObject object = getDimensionalObject( filter, relativePeriodDate, user, true, + organisationUnitsAtLevel, organisationUnitsInGroups, format ); + + if ( object != null ) + { + filterItems.addAll( object.getItems() ); + } + } + + return filterItems; + } + + public String generateTitle() + { + return IdentifiableObjectUtils.join( filters() ); + } + + @Override + public void populateAnalyticalProperties() + { + columns.addAll( getDimensionalObjectList( series ) ); + rows.addAll( getDimensionalObjectList( category ) ); + + for ( String filter : filterDimensions ) + { + filters.addAll( getDimensionalObjectList( filter ) ); + } + } + + public List getAllOrganisationUnits() + { + if ( transientOrganisationUnits != null && !transientOrganisationUnits.isEmpty() ) + { + return transientOrganisationUnits; + } + else + { + return organisationUnits; + } + } + + public OrganisationUnit getFirstOrganisationUnit() + { + List units = getAllOrganisationUnits(); + return units != null && !units.isEmpty() ? units.iterator().next() : null; + } + + public List getAllPeriods() + { + List list = new ArrayList(); + + list.addAll( relativePeriods ); + + for ( Period period : periods ) + { + if ( !list.contains( period ) ) + { + list.add( period ); + } + } + + return list; + } + + /** + * Sets all dimensions for this chart. + * + * @param series the series dimension. + * @param category the category dimension. + * @param filter the filter dimension. + */ + public void setDimensions( String series, String category, String filter ) + { + this.series = series; + this.category = category; + this.filterDimensions.clear(); + this.filterDimensions.add( filter ); + } + + public boolean isType( String type ) + { + return this.type != null && this.type.equalsIgnoreCase( type ); + } + + public boolean isTargetLine() + { + return targetLineValue != null; + } + + public boolean isBaseLine() + { + return baseLineValue != null; + } + + public int getWidth() + { + return 700; + } + + public int getHeight() + { + return 500; + } + + // ------------------------------------------------------------------------- + // Getters and setters properties + // ------------------------------------------------------------------------- + + @JsonProperty + @JsonSerialize( as = BaseIdentifiableObject.class ) + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public Program getProgram() + { + return program; + } + + public void setProgram( Program program ) + { + this.program = program; + } + + @JsonProperty + @JsonSerialize( as = BaseIdentifiableObject.class ) + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public ProgramStage getProgramStage() + { + return programStage; + } + + public void setProgramStage( ProgramStage programStage ) + { + this.programStage = programStage; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public Date getStartDate() + { + return startDate; + } + + public void setStartDate( Date startDate ) + { + this.startDate = startDate; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public Date getEndDate() + { + return endDate; + } + + public void setEndDate( Date endDate ) + { + this.endDate = endDate; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public String getDomainAxisLabel() + { + return domainAxisLabel; + } + + public void setDomainAxisLabel( String domainAxisLabel ) + { + this.domainAxisLabel = domainAxisLabel; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public String getRangeAxisLabel() + { + return rangeAxisLabel; + } + + public void setRangeAxisLabel( String rangeAxisLabel ) + { + this.rangeAxisLabel = rangeAxisLabel; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public String getType() + { + return type; + } + + public void setType( String type ) + { + this.type = type; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public String getSeries() + { + return series; + } + + public void setSeries( String series ) + { + this.series = series; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public String getCategory() + { + return category; + } + + public void setCategory( String category ) + { + this.category = category; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class } ) + @JacksonXmlElementWrapper( localName = "filterDimensions", namespace = DxfNamespaces.DXF_2_0 ) + @JacksonXmlProperty( localName = "filterDimension", namespace = DxfNamespaces.DXF_2_0 ) + public List getFilterDimensions() + { + return filterDimensions; + } + + public void setFilterDimensions( List filterDimensions ) + { + this.filterDimensions = filterDimensions; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public String getCountType() + { + return countType; + } + + public void setCountType( String countType ) + { + this.countType = countType; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public boolean isHideLegend() + { + return hideLegend; + } + + public void setHideLegend( boolean hideLegend ) + { + this.hideLegend = hideLegend; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public boolean isRegression() + { + return regression; + } + + public void setRegression( boolean regression ) + { + this.regression = regression; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public Double getTargetLineValue() + { + return targetLineValue; + } + + public void setTargetLineValue( Double targetLineValue ) + { + this.targetLineValue = targetLineValue; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public String getTargetLineLabel() + { + return targetLineLabel; + } + + public void setTargetLineLabel( String targetLineLabel ) + { + this.targetLineLabel = targetLineLabel; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public Double getBaseLineValue() + { + return baseLineValue; + } + + public void setBaseLineValue( Double baseLineValue ) + { + this.baseLineValue = baseLineValue; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public String getBaseLineLabel() + { + return baseLineLabel; + } + + public void setBaseLineLabel( String baseLineLabel ) + { + this.baseLineLabel = baseLineLabel; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public boolean isHideTitle() + { + return hideTitle; + } + + public void setHideTitle( boolean hideTitle ) + { + this.hideTitle = hideTitle; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public boolean isHideSubtitle() + { + return hideSubtitle; + } + + public void setHideSubtitle( Boolean hideSubtitle ) + { + this.hideSubtitle = hideSubtitle; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public String getTitle() + { + return this.title; + } + + public void setTitle( String title ) + { + this.title = title; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public boolean isShowData() + { + return showData; + } + + public void setShowData( boolean showData ) + { + this.showData = showData; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public boolean isHideEmptyRows() + { + return hideEmptyRows; + } + + public void setHideEmptyRows( boolean hideEmptyRows ) + { + this.hideEmptyRows = hideEmptyRows; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public boolean isRewindRelativePeriods() + { + return rewindRelativePeriods; + } + + public void setRewindRelativePeriods( boolean rewindRelativePeriods ) + { + this.rewindRelativePeriods = rewindRelativePeriods; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public Double getRangeAxisMaxValue() + { + return rangeAxisMaxValue; + } + + public void setRangeAxisMaxValue( Double rangeAxisMaxValue ) + { + this.rangeAxisMaxValue = rangeAxisMaxValue; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public Double getRangeAxisMinValue() + { + return rangeAxisMinValue; + } + + public void setRangeAxisMinValue( Double rangeAxisMinValue ) + { + this.rangeAxisMinValue = rangeAxisMinValue; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public Integer getRangeAxisSteps() + { + return rangeAxisSteps; + } + + public void setRangeAxisSteps( Integer rangeAxisSteps ) + { + this.rangeAxisSteps = rangeAxisSteps; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public Integer getRangeAxisDecimals() + { + return rangeAxisDecimals; + } + + public void setRangeAxisDecimals( Integer rangeAxisDecimals ) + { + this.rangeAxisDecimals = rangeAxisDecimals; + } + + // ------------------------------------------------------------------------- + // Getters and setters for transient properties + // ------------------------------------------------------------------------- + + @JsonIgnore + public I18nFormat getFormat() + { + return format; + } + + @JsonIgnore + public void setFormat( I18nFormat format ) + { + this.format = format; + } + + @JsonIgnore + public List getRelativePeriods() + { + return relativePeriods; + } + + @JsonIgnore + public void setRelativePeriods( List relativePeriods ) + { + this.relativePeriods = relativePeriods; + } + + // ------------------------------------------------------------------------- + // Merge with + // ------------------------------------------------------------------------- + + @Override + public void mergeWith( IdentifiableObject other ) + { + super.mergeWith( other ); + + if ( other.getClass().isInstance( this ) ) + { + EventChart eventChart = (EventChart) other; + + program = eventChart.getProgram(); + programStage = eventChart.getProgramStage(); + startDate = eventChart.getStartDate(); + endDate = eventChart.getEndDate(); + domainAxisLabel = eventChart.getDomainAxisLabel(); + rangeAxisLabel = eventChart.getRangeAxisLabel(); + countType = eventChart.getCountType(); + type = eventChart.getType(); + series = eventChart.getSeries(); + category = eventChart.getCategory(); + hideLegend = eventChart.isHideLegend(); + regression = eventChart.isRegression(); + hideTitle = eventChart.isHideTitle(); + hideSubtitle = eventChart.isHideSubtitle(); + title = eventChart.getTitle(); + targetLineValue = eventChart.getTargetLineValue(); + targetLineLabel = eventChart.getTargetLineLabel(); + baseLineValue = eventChart.getBaseLineValue(); + baseLineLabel = eventChart.getBaseLineLabel(); + showData = eventChart.isShowData(); + hideEmptyRows = eventChart.isHideEmptyRows(); + rewindRelativePeriods = eventChart.isRewindRelativePeriods(); + rangeAxisMaxValue = eventChart.getRangeAxisMaxValue(); + rangeAxisMinValue = eventChart.getRangeAxisMinValue(); + rangeAxisSteps = eventChart.getRangeAxisSteps(); + rangeAxisDecimals = eventChart.getRangeAxisDecimals(); + + filterDimensions.clear(); + filterDimensions.addAll( eventChart.getFilterDimensions() ); + } + } +} === added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/eventchart/EventChartService.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/eventchart/EventChartService.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/eventchart/EventChartService.java 2014-06-16 16:20:38 +0000 @@ -0,0 +1,49 @@ +package org.hisp.dhis.eventchart; + +/* + * Copyright (c) 2004-2014, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.List; + +/** +* @author Lars Helge Overland +*/ +public interface EventChartService +{ + int saveEventChart( EventChart eventChart ); + + void updateEventChart( EventChart eventChart ); + + EventChart getEventChart( int id ); + + EventChart getEventChart( String uid ); + + void deleteEventChart( EventChart eventChart ); + + List getAllEventCharts(); +} === added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/descriptors/EventChartSchemaDescriptor.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/descriptors/EventChartSchemaDescriptor.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/descriptors/EventChartSchemaDescriptor.java 2014-06-16 16:20:38 +0000 @@ -0,0 +1,65 @@ +package org.hisp.dhis.schema.descriptors; + +/* + * Copyright (c) 2004-2014, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import org.hisp.dhis.eventchart.EventChart; +import org.hisp.dhis.schema.Authority; +import org.hisp.dhis.schema.AuthorityType; +import org.hisp.dhis.schema.Schema; +import org.hisp.dhis.schema.SchemaDescriptor; +import org.springframework.stereotype.Component; + +import com.google.common.collect.Lists; + +@Component +public class EventChartSchemaDescriptor + implements SchemaDescriptor +{ + public static final String SINGULAR = "eventChart"; + + public static final String PLURAL = "eventCharts"; + + public static final String API_ENDPOINT = "/" + PLURAL; + + @Override + public Schema getSchema() + { + Schema schema = new Schema( EventChart.class, SINGULAR, PLURAL ); + schema.setApiEndpoint( API_ENDPOINT ); + schema.setShareable( true ); + schema.setOrder( 1540 ); + + schema.getAuthorities().add( + new Authority( AuthorityType.CREATE_PUBLIC, Lists.newArrayList( "F_EVENTCHART_PUBLIC_ADD" ) ) ); + schema.getAuthorities().add( + new Authority( AuthorityType.EXTERNALIZE, Lists.newArrayList( "F_EVENTCHART_EXTERNAL" ) ) ); + + return schema; + } +} === added directory 'dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/eventchart' === added file 'dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/eventchart/DefaultEventChartService.java' --- dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/eventchart/DefaultEventChartService.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/eventchart/DefaultEventChartService.java 2014-06-16 16:20:38 +0000 @@ -0,0 +1,83 @@ +package org.hisp.dhis.eventchart; + +/* + * Copyright (c) 2004-2014, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.List; + +import org.hisp.dhis.common.hibernate.HibernateIdentifiableObjectStore; +import org.springframework.transaction.annotation.Transactional; + +/** +* @author Lars Helge Overland +*/ +@Transactional +public class DefaultEventChartService + implements EventChartService +{ + private HibernateIdentifiableObjectStore eventChartStore; + + public void setEventChartStore( HibernateIdentifiableObjectStore eventChartStore ) + { + this.eventChartStore = eventChartStore; + } + + // ------------------------------------------------------------------------- + // EventReportService implementation + // ------------------------------------------------------------------------- + + public int saveEventChart( EventChart eventChart ) + { + return eventChartStore.save( eventChart ); + } + + public void updateEventChart( EventChart eventChart ) + { + eventChartStore.update( eventChart ); + } + + public EventChart getEventChart( int id ) + { + return eventChartStore.get( id ); + } + + public EventChart getEventChart( String uid ) + { + return eventChartStore.getByUid( uid ); + } + + public void deleteEventChart( EventChart eventChart ) + { + eventChartStore.delete( eventChart ); + } + + public List getAllEventCharts() + { + return eventChartStore.getAll(); + } +} === added directory 'dhis-2/dhis-services/dhis-service-tracker/src/main/resources/org/hisp/dhis/eventchart' === added file 'dhis-2/dhis-services/dhis-service-tracker/src/main/resources/org/hisp/dhis/eventchart/EventChart.hbm.xml' --- dhis-2/dhis-services/dhis-service-tracker/src/main/resources/org/hisp/dhis/eventchart/EventChart.hbm.xml 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-services/dhis-service-tracker/src/main/resources/org/hisp/dhis/eventchart/EventChart.hbm.xml 2014-06-16 16:20:38 +0000 @@ -0,0 +1,143 @@ + +] + > + + + + + + + + + + &identifiableProperties; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + === added file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EventChartController.java' --- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EventChartController.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EventChartController.java 2014-06-16 16:20:38 +0000 @@ -0,0 +1,196 @@ +package org.hisp.dhis.webapi.controller.event; + +/* + * Copyright (c) 2004-2014, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import org.hisp.dhis.common.DimensionService; +import org.hisp.dhis.dxf2.utils.JacksonUtils; +import org.hisp.dhis.eventchart.EventChart; +import org.hisp.dhis.eventchart.EventChartService; +import org.hisp.dhis.i18n.I18nFormat; +import org.hisp.dhis.i18n.I18nManager; +import org.hisp.dhis.organisationunit.OrganisationUnit; +import org.hisp.dhis.period.Period; +import org.hisp.dhis.program.ProgramService; +import org.hisp.dhis.program.ProgramStageService; +import org.hisp.dhis.schema.descriptors.EventChartSchemaDescriptor; +import org.hisp.dhis.webapi.controller.AbstractCrudController; +import org.hisp.dhis.webapi.utils.ContextUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseStatus; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import java.io.InputStream; + +import static org.hisp.dhis.common.DimensionalObjectUtils.getDimensions; +import static org.hisp.dhis.common.DimensionalObjectUtils.toDimension; + +/** + * @author Jan Henrik Overland + */ +@Controller +@RequestMapping( value = EventChartSchemaDescriptor.API_ENDPOINT ) +public class EventChartController + extends AbstractCrudController +{ + @Autowired + private EventChartService eventChartService; + + @Autowired + private DimensionService dimensionService; + + @Autowired + private ProgramService programService; + + @Autowired + private ProgramStageService programStageService; + + @Autowired + private I18nManager i18nManager; + + //-------------------------------------------------------------------------- + // CRUD + //-------------------------------------------------------------------------- + + @Override + @RequestMapping( method = RequestMethod.POST, consumes = "application/json" ) + public void postJsonObject( HttpServletResponse response, HttpServletRequest request, InputStream input ) throws Exception + { + EventChart eventChart = JacksonUtils.fromJson( input, EventChart.class ); + + mergeEventChart( eventChart ); + + eventChartService.saveEventChart( eventChart ); + + ContextUtils.createdResponse( response, "Event chart created", EventChartSchemaDescriptor.API_ENDPOINT + "/" + eventChart.getUid() ); + } + + @Override + @RequestMapping( value = "/{uid}", method = RequestMethod.PUT, consumes = "application/json" ) + @ResponseStatus( value = HttpStatus.NO_CONTENT ) + public void putJsonObject( HttpServletResponse response, HttpServletRequest request, @PathVariable( "uid" ) String uid, InputStream input ) throws Exception + { + EventChart eventChart = eventChartService.getEventChart( uid ); + + if ( eventChart == null ) + { + ContextUtils.notFoundResponse( response, "Event chart does not exist: " + uid ); + return; + } + + EventChart newEventChart = JacksonUtils.fromJson( input, EventChart.class ); + + mergeEventChart( newEventChart ); + + eventChart.mergeWith( newEventChart ); + + eventChartService.updateEventChart( eventChart ); + } + + @Override + @RequestMapping( value = "/{uid}", method = RequestMethod.DELETE ) + @ResponseStatus( value = HttpStatus.NO_CONTENT ) + public void deleteObject( HttpServletResponse response, HttpServletRequest request, @PathVariable( "uid" ) String uid ) throws Exception + { + EventChart eventChart = eventChartService.getEventChart( uid ); + + if ( eventChart == null ) + { + ContextUtils.notFoundResponse( response, "Event report does not exist: " + uid ); + return; + } + + eventChartService.deleteEventChart( eventChart ); + } + + //-------------------------------------------------------------------------- + // Hooks + //-------------------------------------------------------------------------- + + @Override + protected void postProcessEntity( EventChart eventChart ) + throws Exception + { + eventChart.populateAnalyticalProperties(); + + for ( OrganisationUnit organisationUnit : eventChart.getOrganisationUnits() ) + { + eventChart.getParentGraphMap().put( organisationUnit.getUid(), organisationUnit.getParentGraph() ); + } + + I18nFormat format = i18nManager.getI18nFormat(); + + if ( eventChart.getPeriods() != null && !eventChart.getPeriods().isEmpty() ) + { + for ( Period period : eventChart.getPeriods() ) + { + period.setName( format.formatPeriod( period ) ); + } + } + } + + //-------------------------------------------------------------------------- + // Supportive methods + //-------------------------------------------------------------------------- + + private void mergeEventChart( EventChart eventChart ) + { + dimensionService.mergeAnalyticalObject( eventChart ); + + eventChart.getFilterDimensions().clear(); + + if ( eventChart.getColumns() != null ) + { + eventChart.setSeries( toDimension( eventChart.getColumns().get( 0 ).getDimension() ) ); + } + + if ( eventChart.getRows() != null ) + { + eventChart.setCategory( toDimension( eventChart.getRows().get( 0 ).getDimension() ) ); + } + + eventChart.getFilterDimensions().addAll( getDimensions( eventChart.getFilters() ) ); + + if ( eventChart.getProgram() != null ) + { + eventChart.setProgram( programService.getProgram( eventChart.getProgram().getUid() ) ); + } + + if ( eventChart.getProgramStage() != null ) + { + eventChart.setProgramStage( programStageService.getProgramStage( eventChart.getProgramStage().getUid() ) ); + } + } +} === modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/plugin.js' --- dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/plugin.js 2014-06-16 13:20:22 +0000 +++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/plugin.js 2014-06-16 15:43:42 +0000 @@ -698,10 +698,12 @@ console.log('Response: no valid headers'); return; } - + if (!(Ext.isArray(config.rows) && config.rows.length > 0)) { - alert('No values found'); - return; + if (DV.app) { + alert('No values found'); + return; + } } if (config.headers.length !== config.rows[0].length) { @@ -2036,7 +2038,7 @@ getDefaultSeriesTitle = function(store) { var a = []; - if (Ext.isObject(xLayout.legend) && Ext.isArray(xLayout.legend.seriesNames)) { + if (xLayout.legend && xLayout.legend.seriesNames) { return xLayout.legend.seriesNames; } else {