← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 10781: Added web domain properties for columns/rows/filters for Chart. One can now set and get dimension...

 

Merge authors:
  Lars Helge Øverland (larshelge)
------------------------------------------------------------
revno: 10781 [merge]
committer: Lars Helge Øverland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Thu 2013-05-09 00:56:40 +0200
message:
  Added web domain properties for columns/rows/filters for Chart. One can now set and get dimensions from charts without being aware of the underlying dimensional objects.
added:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseDimensionalObject.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/ConfigurablePeriod.java
renamed:
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DimensionType.java => dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionType.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/chart/Chart.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionalObject.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObjectUtils.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategory.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementGroupSet.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitGroupSet.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/Period.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/RelativePeriods.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/Dimension.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java
  dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/DataQueryParamsTest.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultDimensionService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultIdentifiableObjectManager.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/period/DefaultPeriodService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java
  dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/chart/impl/DefaultChartService.java
  dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/jdbc/AnalyticsDataSetReportStore.java
  dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/reporttable/jdbc/JDBCReportTableManager.java
  dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/chart/hibernate/Chart.hbm.xml
  dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisConvenienceTest.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/ChartController.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionType.java


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/chart/Chart.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/chart/Chart.java	2013-05-07 07:43:44 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/chart/Chart.java	2013-05-08 22:56:40 +0000
@@ -27,28 +27,43 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import static org.hisp.dhis.common.DimensionalObject.DATAELEMENT_DIM_ID;
+import static org.hisp.dhis.common.DimensionalObject.DATASET_DIM_ID;
+import static org.hisp.dhis.common.DimensionalObject.DATA_X_DIM_ID;
+import static org.hisp.dhis.common.DimensionalObject.INDICATOR_DIM_ID;
+import static org.hisp.dhis.common.DimensionalObject.ORGUNIT_DIM_ID;
+import static org.hisp.dhis.common.DimensionalObject.PERIOD_DIM_ID;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 
+import org.hisp.dhis.common.BaseDimensionalObject;
 import org.hisp.dhis.common.BaseIdentifiableObject;
 import org.hisp.dhis.common.BaseNameableObject;
+import org.hisp.dhis.common.DimensionalObject;
 import org.hisp.dhis.common.DxfNamespaces;
 import org.hisp.dhis.common.IdentifiableObject;
+import org.hisp.dhis.common.ListMap;
 import org.hisp.dhis.common.NameableObject;
 import org.hisp.dhis.common.adapter.JacksonPeriodDeserializer;
 import org.hisp.dhis.common.adapter.JacksonPeriodSerializer;
 import org.hisp.dhis.common.annotation.Scanned;
 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.dataelement.DataElement;
+import org.hisp.dhis.dataelement.DataElementCategoryOption;
+import org.hisp.dhis.dataelement.DataElementGroup;
 import org.hisp.dhis.dataset.DataSet;
 import org.hisp.dhis.i18n.I18nFormat;
 import org.hisp.dhis.indicator.Indicator;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
-import org.hisp.dhis.organisationunit.OrganisationUnitGroupSet;
+import org.hisp.dhis.organisationunit.OrganisationUnitGroup;
+import org.hisp.dhis.period.ConfigurablePeriod;
 import org.hisp.dhis.period.Period;
+import org.hisp.dhis.period.RelativePeriodEnum;
 import org.hisp.dhis.period.RelativePeriods;
 import org.hisp.dhis.period.comparator.AscendingPeriodEndDateComparator;
 
@@ -84,10 +99,6 @@
     public static final String TYPE_AREA = "area";
     public static final String TYPE_PIE = "pie";
 
-    public static final String DIMENSION_DATA = "data";
-    public static final String DIMENSION_PERIOD = "period";
-    public static final String DIMENSION_ORGANISATIONUNIT = "organisationunit";
-
     private String domainAxisLabel;
 
     private String rangeAxisLabel;
@@ -131,6 +142,12 @@
     
     private RelativePeriods relatives;
 
+    @Scanned
+    private List<DataElementGroup> dataElementGroups = new ArrayList<DataElementGroup>();
+
+    @Scanned
+    private List<OrganisationUnitGroup> organisationUnitGroups = new ArrayList<OrganisationUnitGroup>();
+
     private boolean userOrganisationUnit;
 
     private boolean userOrganisationUnitChildren;
@@ -139,8 +156,6 @@
 
     private boolean rewindRelativePeriods;
 
-    private OrganisationUnitGroupSet organisationUnitGroupSet;
-
     // -------------------------------------------------------------------------
     // Transient properties
     // -------------------------------------------------------------------------
@@ -152,6 +167,16 @@
     private transient List<OrganisationUnit> relativeOrganisationUnits = new ArrayList<OrganisationUnit>();
 
     // -------------------------------------------------------------------------
+    // Web domain properties
+    // -------------------------------------------------------------------------
+
+    private transient List<DimensionalObject> columns = new ArrayList<DimensionalObject>();
+    
+    private transient List<DimensionalObject> rows = new ArrayList<DimensionalObject>();
+    
+    private transient List<DimensionalObject> filters = new ArrayList<DimensionalObject>();
+    
+    // -------------------------------------------------------------------------
     // Constructors
     // -------------------------------------------------------------------------
 
@@ -184,10 +209,87 @@
 
         return list != null && !list.isEmpty() ? list.iterator().next() : null;
     }
+        
+    public void populateWebDomainProperties()
+    {
+        columns.addAll( getDimensionalObjectList( series ) );
+        rows.addAll( getDimensionalObjectList( category ) );
+        
+        for ( String filter : filterDimensions )
+        {
+            filters.addAll( getDimensionalObjectList( filter ) );
+        }
+    }
+    
+    private List<DimensionalObject> getDimensionalObjectList( String dimension )
+    {
+        List<DimensionalObject> objects = new ArrayList<DimensionalObject>();
+        
+        if ( DATA_X_DIM_ID.equals( dimension ) )
+        {
+            if ( !indicators.isEmpty() )
+            {
+                objects.add( new BaseDimensionalObject( INDICATOR_DIM_ID, indicators ) );
+            }
+            
+            if ( !dataElements.isEmpty() )
+            {
+                objects.add( new BaseDimensionalObject( DATAELEMENT_DIM_ID, dataElements ) );
+            }
+            
+            if ( !dataSets.isEmpty() )
+            {
+                objects.add( new BaseDimensionalObject( DATASET_DIM_ID, dataSets ) );
+            }
+        }        
+        else if ( PERIOD_DIM_ID.equals( dimension ) && ( !periods.isEmpty() || hasRelativePeriods() ) )
+        {
+            List<IdentifiableObject> periodList = new ArrayList<IdentifiableObject>( periods );
+            
+            if ( hasRelativePeriods() )
+            {
+                List<RelativePeriodEnum> list = relatives.getRelativePeriodEnums();
 
+                for ( RelativePeriodEnum period : list )
+                {
+                    periodList.add( new ConfigurablePeriod( period.toString(), null, null ) );
+                }
+            }
+            
+            objects.add( new BaseDimensionalObject( dimension, periodList ) );
+        }        
+        else if ( ORGUNIT_DIM_ID.equals( dimension ) && !organisationUnits.isEmpty() )
+        {
+            objects.add( new BaseDimensionalObject( dimension, organisationUnits ) );
+        }
+        else // Dynamic dimension
+        {
+            ListMap<String, IdentifiableObject> listMap = new ListMap<String, IdentifiableObject>();
+            
+            for ( DataElementGroup group : dataElementGroups )
+            {
+                listMap.putValue( group.getGroupSet().getDimension(), group );
+            }
+            
+            for ( OrganisationUnitGroup group : organisationUnitGroups )
+            {
+                listMap.putValue( group.getGroupSet().getUid(), group );
+            }
+            
+            //TODO categories
+            
+            if ( listMap.containsKey( dimension ) )
+            {
+                objects.add( new BaseDimensionalObject( dimension, listMap.get( dimension ) ) );
+            }
+        }
+                
+        return objects;
+    }
+    
     public String generateTitle()
     {
-        if ( DIMENSION_PERIOD.equals( filterDimensions.get( 0 ) ) )
+        if ( PERIOD_DIM_ID.equals( filterDimensions.get( 0 ) ) )
         {
             return format.formatPeriod( getAllPeriods().get( 0 ) );
         }
@@ -234,29 +336,22 @@
     {
         List<NameableObject> list = new ArrayList<NameableObject>();
 
-        if ( DIMENSION_DATA.equals( dimension ) )
+        if ( DATA_X_DIM_ID.equals( dimension ) )
         {
             list.addAll( dataElements );
             list.addAll( indicators );
             list.addAll( dataSets );
         }
-        else if ( DIMENSION_PERIOD.equals( dimension ) )
+        else if ( PERIOD_DIM_ID.equals( dimension ) )
         {
             List<Period> periods = getAllPeriods();
             namePeriods( periods, format );
             Collections.sort( periods, PERIOD_COMPARATOR );
             list.addAll( periods );
         }
-        else if ( DIMENSION_ORGANISATIONUNIT.equals( dimension ) )
+        else if ( ORGUNIT_DIM_ID.equals( dimension ) )
         {
-            if ( isOrganisationUnitGroupBased() )
-            {
-                list.addAll( organisationUnitGroupSet.getOrganisationUnitGroups() );
-            }
-            else
-            {
-                list.addAll( getAllOrganisationUnits() );
-            }
+            list.addAll( getAllOrganisationUnits() );
         }
 
         return list;
@@ -271,15 +366,6 @@
         }
     }
 
-    /**
-     * Indicates whether this report table is based on organisation unit groups
-     * or the organisation unit hierarchy.
-     */
-    public boolean isOrganisationUnitGroupBased()
-    {
-        return organisationUnitGroupSet != null && organisationUnitGroupSet.getOrganisationUnitGroups() != null;
-    }
-    
     public void removeAllDataElements()
     {
         dataElements.clear();
@@ -371,11 +457,11 @@
     }
     
     // -------------------------------------------------------------------------
-    // Getters and setters
+    // Getters and setters properties
     // -------------------------------------------------------------------------
 
     @JsonProperty
-    @JsonView( {DetailedView.class, ExportView.class} )
+    @JsonView( {DetailedView.class, ExportView.class, DimensionalView.class} )
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
     public String getDomainAxisLabel()
     {
@@ -388,7 +474,7 @@
     }
 
     @JsonProperty
-    @JsonView( {DetailedView.class, ExportView.class} )
+    @JsonView( {DetailedView.class, ExportView.class, DimensionalView.class} )
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
     public String getRangeAxisLabel()
     {
@@ -401,7 +487,7 @@
     }
 
     @JsonProperty
-    @JsonView( {DetailedView.class, ExportView.class} )
+    @JsonView( {DetailedView.class, ExportView.class, DimensionalView.class} )
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
     public String getType()
     {
@@ -439,6 +525,10 @@
         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<String> getFilterDimensions()
     {
         return filterDimensions;
@@ -450,21 +540,7 @@
     }
 
     @JsonProperty
-    @JsonView( {DetailedView.class, ExportView.class} )
-    @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
-    public String getFilter()
-    {
-        return filterDimensions.get( 0 ); //TODO
-    }
-
-    public void setFilter( String filter )
-    {
-        this.filterDimensions.clear();
-        this.filterDimensions.add( filter ); //TODO
-    }
-
-    @JsonProperty
-    @JsonView( {DetailedView.class, ExportView.class} )
+    @JsonView( {DetailedView.class, ExportView.class, DimensionalView.class} )
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
     public boolean isHideLegend()
     {
@@ -477,7 +553,7 @@
     }
 
     @JsonProperty
-    @JsonView( {DetailedView.class, ExportView.class} )
+    @JsonView( {DetailedView.class, ExportView.class, DimensionalView.class} )
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
     public boolean isRegression()
     {
@@ -490,7 +566,7 @@
     }
 
     @JsonProperty
-    @JsonView( {DetailedView.class, ExportView.class} )
+    @JsonView( {DetailedView.class, ExportView.class, DimensionalView.class} )
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
     public Double getTargetLineValue()
     {
@@ -503,7 +579,7 @@
     }
 
     @JsonProperty
-    @JsonView( {DetailedView.class, ExportView.class} )
+    @JsonView( {DetailedView.class, ExportView.class, DimensionalView.class} )
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
     public String getTargetLineLabel()
     {
@@ -516,7 +592,7 @@
     }
 
     @JsonProperty
-    @JsonView( {DetailedView.class, ExportView.class} )
+    @JsonView( {DetailedView.class, ExportView.class, DimensionalView.class} )
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
     public Double getBaseLineValue()
     {
@@ -529,7 +605,7 @@
     }
 
     @JsonProperty
-    @JsonView( {DetailedView.class, ExportView.class} )
+    @JsonView( {DetailedView.class, ExportView.class, DimensionalView.class} )
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
     public String getBaseLineLabel()
     {
@@ -542,7 +618,7 @@
     }
 
     @JsonProperty
-    @JsonView( {DetailedView.class, ExportView.class} )
+    @JsonView( {DetailedView.class, ExportView.class, DimensionalView.class} )
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
     public boolean isHideSubtitle()
     {
@@ -645,6 +721,34 @@
 
     @JsonProperty
     @JsonView( {DetailedView.class, ExportView.class} )
+    @JacksonXmlElementWrapper( localName = "dataElementGroups", namespace = DxfNamespaces.DXF_2_0)
+    @JacksonXmlProperty( localName = "dataElementGroup", namespace = DxfNamespaces.DXF_2_0)
+    public List<DataElementGroup> getDataElementGroups()
+    {
+        return dataElementGroups;
+    }
+
+    public void setDataElementGroups( List<DataElementGroup> dataElementGroups )
+    {
+        this.dataElementGroups = dataElementGroups;
+    }
+
+    @JsonProperty
+    @JsonView( {DetailedView.class, ExportView.class} )
+    @JacksonXmlElementWrapper( localName = "organisationUnitGroups", namespace = DxfNamespaces.DXF_2_0)
+    @JacksonXmlProperty( localName = "organisationUnitGroup", namespace = DxfNamespaces.DXF_2_0)
+    public List<OrganisationUnitGroup> getOrganisationUnitGroups()
+    {
+        return organisationUnitGroups;
+    }
+
+    public void setOrganisationUnitGroups( List<OrganisationUnitGroup> organisationUnitGroups )
+    {
+        this.organisationUnitGroups = organisationUnitGroups;
+    }
+
+    @JsonProperty
+    @JsonView( {DetailedView.class, ExportView.class} )
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
     public boolean isUserOrganisationUnit()
     {
@@ -670,7 +774,7 @@
     }
 
     @JsonProperty
-    @JsonView( {DetailedView.class, ExportView.class} )
+    @JsonView( {DetailedView.class, ExportView.class, DimensionalView.class} )
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
     public boolean isShowData()
     {
@@ -683,7 +787,7 @@
     }
 
     @JsonProperty
-    @JsonView( {DetailedView.class, ExportView.class} )
+    @JsonView( {DetailedView.class, ExportView.class, DimensionalView.class} )
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
     public boolean isRewindRelativePeriods()
     {
@@ -695,28 +799,17 @@
         this.rewindRelativePeriods = rewindRelativePeriods;
     }
 
-    @JsonProperty
-    @JsonView( {DetailedView.class, ExportView.class} )
-    @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
-    public OrganisationUnitGroupSet getOrganisationUnitGroupSet()
-    {
-        return organisationUnitGroupSet;
-    }
-
-    public void setOrganisationUnitGroupSet( OrganisationUnitGroupSet organisationUnitGroupSet )
-    {
-        this.organisationUnitGroupSet = organisationUnitGroupSet;
-    }
-
-    // -------------------------------------------------------------------------
-    // Getters and setters for transient fields
-    // -------------------------------------------------------------------------
-
+    // -------------------------------------------------------------------------
+    // Getters and setters for transient properties
+    // -------------------------------------------------------------------------
+
+    @JsonIgnore
     public I18nFormat getFormat()
     {
         return format;
     }
 
+    @JsonIgnore
     public void setFormat( I18nFormat format )
     {
         this.format = format;
@@ -746,6 +839,62 @@
         this.relativeOrganisationUnits = relativeOrganisationUnits;
     }
 
+    // -------------------------------------------------------------------------
+    // Web domain properties
+    // -------------------------------------------------------------------------
+
+    @JsonProperty
+    @JsonDeserialize( contentAs = BaseDimensionalObject.class )
+    @JsonSerialize( contentAs = BaseDimensionalObject.class )
+    @JsonView( {DimensionalView.class} )
+    @JacksonXmlElementWrapper( localName = "columns", namespace = DxfNamespaces.DXF_2_0)
+    @JacksonXmlProperty( localName = "column", namespace = DxfNamespaces.DXF_2_0)
+    public List<DimensionalObject> getColumns()
+    {
+        return columns;
+    }
+
+    public void setColumns( List<DimensionalObject> columns )
+    {
+        this.columns = columns;
+    }
+
+    @JsonProperty
+    @JsonDeserialize( contentAs = BaseDimensionalObject.class )
+    @JsonSerialize( contentAs = BaseDimensionalObject.class )
+    @JsonView( {DimensionalView.class} )
+    @JacksonXmlElementWrapper( localName = "rows", namespace = DxfNamespaces.DXF_2_0)
+    @JacksonXmlProperty( localName = "row", namespace = DxfNamespaces.DXF_2_0)
+    public List<DimensionalObject> getRows()
+    {
+        return rows;
+    }
+
+    public void setRows( List<DimensionalObject> rows )
+    {
+        this.rows = rows;
+    }
+
+    @JsonProperty
+    @JsonDeserialize( contentAs = BaseDimensionalObject.class )
+    @JsonSerialize( contentAs = BaseDimensionalObject.class )
+    @JsonView( {DimensionalView.class} )
+    @JacksonXmlElementWrapper( localName = "filters", namespace = DxfNamespaces.DXF_2_0)
+    @JacksonXmlProperty( localName = "filter", namespace = DxfNamespaces.DXF_2_0)
+    public List<DimensionalObject> getFilters()
+    {
+        return filters;
+    }
+
+    public void setFilters( List<DimensionalObject> filters )
+    {
+        this.filters = filters;
+    }    
+
+    // -------------------------------------------------------------------------
+    // Merge with
+    // -------------------------------------------------------------------------
+
     @Override
     public void mergeWith( IdentifiableObject other )
     {
@@ -759,8 +908,7 @@
             rangeAxisLabel = chart.getRangeAxisLabel() == null ? rangeAxisLabel : chart.getRangeAxisLabel();
             type = chart.getType() == null ? type : chart.getType();
             series = chart.getSeries() == null ? series : chart.getSeries();
-            category = chart.getCategory() == null ? category : chart.getCategory();            
-            setFilter( chart.getFilter() == null ? getFilter() : chart.getFilter() ); //TODO
+            category = chart.getCategory() == null ? category : chart.getCategory();
             hideLegend = chart.isHideLegend();
             regression = chart.isRegression();
             hideSubtitle = chart.isHideSubtitle();
@@ -773,9 +921,11 @@
             showData = chart.isShowData();
             rewindRelativePeriods = chart.isRewindRelativePeriods();
             
+            filters.clear();
+            filters.addAll( chart.getFilters() );
+            
             relatives = chart.getRelatives() == null ? relatives : chart.getRelatives();
             user = chart.getUser() == null ? user : chart.getUser();
-            organisationUnitGroupSet = chart.getOrganisationUnitGroupSet() == null ? organisationUnitGroupSet : chart.getOrganisationUnitGroupSet();
 
             removeAllIndicators();
             indicators.addAll( chart.getIndicators() );

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseDimensionalObject.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseDimensionalObject.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseDimensionalObject.java	2013-05-08 22:56:40 +0000
@@ -0,0 +1,88 @@
+package org.hisp.dhis.common;
+
+/*
+ * Copyright (c) 2004-2012, 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.List;
+
+import org.hisp.dhis.common.view.DimensionalView;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonView;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+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;
+
+@JacksonXmlRootElement( localName = "dimensionalObject", namespace = DxfNamespaces.DXF_2_0)
+public class BaseDimensionalObject
+    extends BaseIdentifiableObject implements DimensionalObject
+{
+    private List<IdentifiableObject> items = new ArrayList<IdentifiableObject>();
+
+    public BaseDimensionalObject()
+    {        
+    }
+    
+    public BaseDimensionalObject( String dimension, List<? extends IdentifiableObject> items )
+    {
+        this.uid = dimension;
+        this.items = new ArrayList<IdentifiableObject>( items );        
+    }
+
+    @JsonProperty
+    @JsonView( {DimensionalView.class} )
+    @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 )
+    public String getDimension()
+    {
+        return uid;
+    }
+
+    public void setDimension( String dimension )
+    {
+        this.uid = dimension;
+    }
+
+    @Override
+    @JsonProperty
+    @JsonSerialize( contentAs = BaseIdentifiableObject.class )
+    @JsonDeserialize( contentAs = BaseIdentifiableObject.class )
+    @JsonView( { DimensionalView.class } )
+    @JacksonXmlElementWrapper( localName = "items", namespace = DxfNamespaces.DXF_2_0 )
+    @JacksonXmlProperty( localName = "item", namespace = DxfNamespaces.DXF_2_0 )
+    public List<IdentifiableObject> getItems()
+    {
+        return items;
+    }
+
+    public void setItems( List<IdentifiableObject> items )
+    {
+        this.items = items;
+    }
+}

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionService.java	2013-04-23 12:02:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionService.java	2013-05-08 10:15:29 +0000
@@ -36,5 +36,7 @@
 {
     DimensionalObject getDimension( String uid );
     
+    DimensionType getDimensionType( String uid );
+    
     List<DimensionalObject> getAllDimensions();
 }

=== renamed file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DimensionType.java' => 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionType.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DimensionType.java	2013-05-07 08:37:33 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionType.java	2013-05-08 10:15:29 +0000
@@ -1,4 +1,4 @@
-package org.hisp.dhis.analytics;
+package org.hisp.dhis.common;
 
 /*
  * Copyright (c) 2004-2012, University of Oslo
@@ -35,6 +35,7 @@
     INDICATOR,
     DATAELEMENT,
     DATASET,
+    DATAELEMENT_OPERAND,
     DATA_X,
     CATEGORY_OPTION_COMBO,
     PERIOD,

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionalObject.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionalObject.java	2013-05-07 08:37:33 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionalObject.java	2013-05-08 22:56:40 +0000
@@ -27,53 +27,26 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import java.util.Arrays;
 import java.util.List;
 
-import org.hisp.dhis.common.view.DimensionalView;
-
-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 Lars Helge Overland
 */
-@JacksonXmlRootElement( localName = "dimension", namespace = DxfNamespaces.DXF_2_0)
-@JsonSerialize( contentAs = DimensionalObject.class )
-public abstract class DimensionalObject
-    extends BaseIdentifiableObject
+public interface DimensionalObject
 {
-    public static final String DATA_X_DIM_ID = "dx"; // in, de, ds
-    public static final String INDICATOR_DIM_ID = "in";
-    public static final String DATAELEMENT_DIM_ID = "de";
-    public static final String DATASET_DIM_ID = "ds";
-    public static final String CATEGORYOPTIONCOMBO_DIM_ID = "co";
-    public static final String PERIOD_DIM_ID = "pe";
-    public static final String ORGUNIT_DIM_ID = "ou";
-    
-    @JsonProperty
-    @JsonView({ DimensionalView.class })
-    @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
-    public String getDimension()
-    {
-        return getUid();
-    }
-    
-    @JsonProperty
-    @JsonSerialize( contentAs = BaseIdentifiableObject.class )
-    @JsonView({ DimensionalView.class })
-    @JacksonXmlElementWrapper( localName = "items", namespace = DxfNamespaces.DXF_2_0 )
-    @JacksonXmlProperty( localName = "item", namespace = DxfNamespaces.DXF_2_0 )
-    public List<IdentifiableObject> getItems()
-    {
-        return getDimensionItems();
-    }
-    
-    /**
-     * Returns an immutable collection of the dimension items for this dimension.
-     */
-    public abstract List<IdentifiableObject> getDimensionItems();
+    final String DATA_X_DIM_ID = "dx"; // in, de, ds, do
+    final String INDICATOR_DIM_ID = "in";
+    final String DATAELEMENT_DIM_ID = "de";
+    final String DATASET_DIM_ID = "ds";
+    final String DATAELEMENT_OPERAND_ID = "do";
+    final String CATEGORYOPTIONCOMBO_DIM_ID = "co";
+    final String PERIOD_DIM_ID = "pe";
+    final String ORGUNIT_DIM_ID = "ou";
+
+    final List<String> DATA_X_DIMS = Arrays.asList( INDICATOR_DIM_ID, DATAELEMENT_DIM_ID, DATASET_DIM_ID, DATAELEMENT_OPERAND_ID );
+    
+    String getDimension();
+    
+    List<IdentifiableObject> getItems();
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObjectUtils.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObjectUtils.java	2013-01-13 13:49:33 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObjectUtils.java	2013-05-08 10:15:29 +0000
@@ -83,7 +83,7 @@
         
         return uids;
     }
-
+    
     /**
      * Filters the given list of IdentifiableObjects based on the given key.
      *

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategory.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategory.java	2013-04-23 12:02:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategory.java	2013-05-08 22:56:40 +0000
@@ -30,12 +30,13 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.hisp.dhis.common.BaseDimensionalObject;
 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.annotation.Scanned;
 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.concept.Concept;
 
@@ -57,7 +58,7 @@
  */
 @JacksonXmlRootElement( localName = "category", namespace = DxfNamespaces.DXF_2_0)
 public class DataElementCategory
-    extends DimensionalObject
+    extends BaseDimensionalObject
 {
     /**
      * Determines if a de-serialized file is compatible with this class.
@@ -142,6 +143,21 @@
     {
         return new ArrayList<IdentifiableObject>( categoryOptions );
     }
+
+    // -------------------------------------------------------------------------
+    // Dimensional object
+    // -------------------------------------------------------------------------
+
+    @Override
+    @JsonProperty
+    @JsonSerialize( contentAs = BaseIdentifiableObject.class )
+    @JsonView( { DetailedView.class, DimensionalView.class } )
+    @JacksonXmlElementWrapper( localName = "items", namespace = DxfNamespaces.DXF_2_0 )
+    @JacksonXmlProperty( localName = "item", namespace = DxfNamespaces.DXF_2_0 )
+    public List<IdentifiableObject> getItems()
+    {
+        return new ArrayList<IdentifiableObject>( categoryOptions );
+    }
     
     // -------------------------------------------------------------------------
     // hashCode, equals and toString

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementGroupSet.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementGroupSet.java	2013-04-23 12:02:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementGroupSet.java	2013-05-08 22:56:40 +0000
@@ -32,13 +32,14 @@
 import java.util.Collections;
 import java.util.List;
 
+import org.hisp.dhis.common.BaseDimensionalObject;
 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.annotation.Scanned;
 import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator;
 import org.hisp.dhis.common.view.DetailedView;
+import org.hisp.dhis.common.view.DimensionalView;
 import org.hisp.dhis.common.view.ExportView;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
@@ -57,7 +58,7 @@
  */
 @JacksonXmlRootElement( localName = "dataElementGroupSet", namespace = DxfNamespaces.DXF_2_0)
 public class DataElementGroupSet
-    extends DimensionalObject
+    extends BaseDimensionalObject
 {
     /**
      * Determines if a de-serialized file is compatible with this class.
@@ -177,6 +178,21 @@
     {
         return new ArrayList<IdentifiableObject>( members );
     }
+
+    // -------------------------------------------------------------------------
+    // Dimensional object
+    // -------------------------------------------------------------------------
+
+    @Override
+    @JsonProperty
+    @JsonSerialize( contentAs = BaseIdentifiableObject.class )
+    @JsonView( { DimensionalView.class } )
+    @JacksonXmlElementWrapper( localName = "items", namespace = DxfNamespaces.DXF_2_0 )
+    @JacksonXmlProperty( localName = "item", namespace = DxfNamespaces.DXF_2_0 )
+    public List<IdentifiableObject> getItems()
+    {
+        return new ArrayList<IdentifiableObject>( members );
+    }
     
     // -------------------------------------------------------------------------
     // equals and hashCode

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitGroupSet.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitGroupSet.java	2013-04-23 12:02:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitGroupSet.java	2013-05-08 22:56:40 +0000
@@ -35,13 +35,14 @@
 import java.util.List;
 import java.util.Set;
 
+import org.hisp.dhis.common.BaseDimensionalObject;
 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.annotation.Scanned;
 import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator;
 import org.hisp.dhis.common.view.DetailedView;
+import org.hisp.dhis.common.view.DimensionalView;
 import org.hisp.dhis.common.view.ExportView;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
@@ -56,7 +57,7 @@
  */
 @JacksonXmlRootElement(localName = "organisationUnitGroupSet", namespace = DxfNamespaces.DXF_2_0)
 public class OrganisationUnitGroupSet
-    extends DimensionalObject
+    extends BaseDimensionalObject
 {
     /**
      * Determines if a de-serialized file is compatible with this class.
@@ -169,6 +170,21 @@
     {
         return new ArrayList<IdentifiableObject>( organisationUnitGroups );
     }
+
+    // -------------------------------------------------------------------------
+    // Dimensional object
+    // -------------------------------------------------------------------------
+
+    @Override
+    @JsonProperty
+    @JsonSerialize( contentAs = BaseIdentifiableObject.class )
+    @JsonView( { DetailedView.class, DimensionalView.class } )
+    @JacksonXmlElementWrapper( localName = "items", namespace = DxfNamespaces.DXF_2_0 )
+    @JacksonXmlProperty( localName = "item", namespace = DxfNamespaces.DXF_2_0 )
+    public List<IdentifiableObject> getItems()
+    {
+        return new ArrayList<IdentifiableObject>( organisationUnitGroups );
+    }
     
     // -------------------------------------------------------------------------
     // hashCode and equals

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/ConfigurablePeriod.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/ConfigurablePeriod.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/ConfigurablePeriod.java	2013-05-07 13:47:18 +0000
@@ -0,0 +1,20 @@
+package org.hisp.dhis.period;
+
+public class ConfigurablePeriod
+    extends Period
+{
+    private String isoDate;
+
+    public ConfigurablePeriod( String isoDate, String name, String code )
+    {
+        this.isoDate = isoDate;
+        this.name = name;
+        this.code = code;
+    }
+    
+    @Override
+    public String getIsoDate()
+    {
+        return isoDate;
+    }
+}

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/Period.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/Period.java	2013-02-13 03:57:52 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/Period.java	2013-05-07 13:47:18 +0000
@@ -101,6 +101,7 @@
         this.endDate = endDate;
     }
 
+    @Deprecated
     public Period( String externalId )
     {
         final String[] id = externalId.split( SEPARATOR );

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/RelativePeriods.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/RelativePeriods.java	2013-03-14 11:51:43 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/RelativePeriods.java	2013-05-08 22:56:40 +0000
@@ -772,12 +772,89 @@
         map.put( RelativePeriodEnum.THIS_FINANCIAL_YEAR, new RelativePeriods().setThisFinancialYear( true ).getRelativePeriods( format, dynamicNames ) );
         map.put( RelativePeriodEnum.LAST_FINANCIAL_YEAR, new RelativePeriods().setLastFinancialYear( true ).getRelativePeriods( format, dynamicNames ) );
         map.put( RelativePeriodEnum.LAST_5_FINANCIAL_YEARS, new RelativePeriods().setLast5FinancialYears( true ).getRelativePeriods( format, dynamicNames ) );
+        map.put( RelativePeriodEnum.LAST_WEEK, new RelativePeriods().setLast4Weeks( true ).getRelativePeriods( format, dynamicNames ) );
         map.put( RelativePeriodEnum.LAST_4_WEEKS, new RelativePeriods().setLast4Weeks( true ).getRelativePeriods( format, dynamicNames ) );
         map.put( RelativePeriodEnum.LAST_12_WEEKS, new RelativePeriods().setLast12Weeks( true ).getRelativePeriods( format, dynamicNames ) );
         map.put( RelativePeriodEnum.LAST_52_WEEKS, new RelativePeriods().setLast52Weeks( true ).getRelativePeriods( format, dynamicNames ) );
         
         return map.get( relativePeriod );
     }
+    
+    /**
+     * Returns a list of RelativePeriodEnums based on the state of this RelativePeriods.
+     * 
+     * @return a list of RelativePeriodEnums.
+     */
+    public List<RelativePeriodEnum> getRelativePeriodEnums()
+    {
+        List<RelativePeriodEnum> list = new ArrayList<RelativePeriodEnum>();
+        
+        add( list, RelativePeriodEnum.LAST_MONTH, reportingMonth );
+        add( list, RelativePeriodEnum.LAST_BIMONTH, reportingBimonth );
+        add( list, RelativePeriodEnum.LAST_QUARTER, reportingQuarter );
+        add( list, RelativePeriodEnum.LAST_SIX_MONTH, lastSixMonth );
+        add( list, RelativePeriodEnum.MONTHS_THIS_YEAR, monthsThisYear );
+        add( list, RelativePeriodEnum.QUARTERS_THIS_YEAR, quartersThisYear );
+        add( list, RelativePeriodEnum.THIS_YEAR, thisYear );
+        add( list, RelativePeriodEnum.MONTHS_LAST_YEAR, monthsLastYear );
+        add( list, RelativePeriodEnum.QUARTERS_LAST_YEAR, quartersLastYear );
+        add( list, RelativePeriodEnum.LAST_YEAR, lastYear );
+        add( list, RelativePeriodEnum.LAST_5_YEARS, last5Years );
+        add( list, RelativePeriodEnum.LAST_12_MONTHS, last12Months );
+        add( list, RelativePeriodEnum.LAST_3_MONTHS, last3Months );
+        add( list, RelativePeriodEnum.LAST_6_BIMONTHS, last6BiMonths );
+        add( list, RelativePeriodEnum.LAST_4_QUARTERS, last4Quarters );
+        add( list, RelativePeriodEnum.LAST_2_SIXMONTHS, last2SixMonths );
+        add( list, RelativePeriodEnum.THIS_FINANCIAL_YEAR, thisFinancialYear );
+        add( list, RelativePeriodEnum.LAST_FINANCIAL_YEAR, lastFinancialYear );
+        add( list, RelativePeriodEnum.LAST_5_FINANCIAL_YEARS, last5FinancialYears );
+        add( list, RelativePeriodEnum.LAST_WEEK, lastWeek );
+        add( list, RelativePeriodEnum.LAST_4_WEEKS, last4Weeks );
+        add( list, RelativePeriodEnum.LAST_12_WEEKS, last12Weeks );
+        add( list, RelativePeriodEnum.LAST_52_WEEKS, last52Weeks );
+        
+        return list;
+    }
+    
+    public RelativePeriods setRelativePeriodsFromEnums( List<RelativePeriodEnum> relativePeriods )
+    {
+        if ( relativePeriods != null )
+        {
+            reportingMonth = relativePeriods.contains( RelativePeriodEnum.LAST_MONTH );
+            reportingBimonth = relativePeriods.contains( RelativePeriodEnum.LAST_BIMONTH );
+            reportingQuarter = relativePeriods.contains( RelativePeriodEnum.LAST_QUARTER );
+            lastSixMonth = relativePeriods.contains( RelativePeriodEnum.LAST_SIX_MONTH );
+            monthsThisYear = relativePeriods.contains( RelativePeriodEnum.MONTHS_THIS_YEAR );
+            quartersThisYear = relativePeriods.contains( RelativePeriodEnum.QUARTERS_THIS_YEAR );
+            thisYear = relativePeriods.contains( RelativePeriodEnum.THIS_YEAR );
+            monthsLastYear = relativePeriods.contains( RelativePeriodEnum.MONTHS_LAST_YEAR );
+            quartersLastYear = relativePeriods.contains( RelativePeriodEnum.QUARTERS_LAST_YEAR );
+            lastYear = relativePeriods.contains( RelativePeriodEnum.LAST_YEAR );
+            last5Years = relativePeriods.contains( RelativePeriodEnum.LAST_5_YEARS );
+            last12Months = relativePeriods.contains( RelativePeriodEnum.LAST_12_MONTHS );
+            last3Months = relativePeriods.contains( RelativePeriodEnum.LAST_3_MONTHS );
+            last6BiMonths = relativePeriods.contains( RelativePeriodEnum.LAST_6_BIMONTHS );
+            last4Quarters = relativePeriods.contains( RelativePeriodEnum.LAST_4_QUARTERS );
+            last2SixMonths = relativePeriods.contains( RelativePeriodEnum.LAST_2_SIXMONTHS );
+            thisFinancialYear = relativePeriods.contains( RelativePeriodEnum.THIS_FINANCIAL_YEAR );
+            lastFinancialYear = relativePeriods.contains( RelativePeriodEnum.LAST_FINANCIAL_YEAR );
+            last5FinancialYears = relativePeriods.contains( RelativePeriodEnum.LAST_5_FINANCIAL_YEARS );
+            lastWeek = relativePeriods.contains( RelativePeriodEnum.LAST_WEEK );
+            last4Weeks = relativePeriods.contains( RelativePeriodEnum.LAST_4_WEEKS );
+            last12Weeks = relativePeriods.contains( RelativePeriodEnum.LAST_12_WEEKS );
+            last52Weeks = relativePeriods.contains( RelativePeriodEnum.LAST_52_WEEKS );
+        }
+        
+        return this;
+    }
+    
+    private static <T> void add( List<T> list, T element, boolean add )
+    {
+        if ( add )
+        {
+            list.add( element );
+        }
+    }
 
     // -------------------------------------------------------------------------
     // Getters & setters

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java	2013-05-07 08:37:33 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java	2013-05-08 10:15:29 +0000
@@ -28,9 +28,9 @@
  */
 
 import static org.hisp.dhis.analytics.AggregationType.AVERAGE_INT_DISAGGREGATION;
-import static org.hisp.dhis.analytics.DimensionType.DATASET;
-import static org.hisp.dhis.analytics.DimensionType.ORGANISATIONUNIT;
-import static org.hisp.dhis.analytics.DimensionType.ORGANISATIONUNIT_GROUPSET;
+import static org.hisp.dhis.common.DimensionType.DATASET;
+import static org.hisp.dhis.common.DimensionType.ORGANISATIONUNIT;
+import static org.hisp.dhis.common.DimensionType.ORGANISATIONUNIT_GROUPSET;
 import static org.hisp.dhis.common.DimensionalObject.CATEGORYOPTIONCOMBO_DIM_ID;
 import static org.hisp.dhis.common.DimensionalObject.DATAELEMENT_DIM_ID;
 import static org.hisp.dhis.common.DimensionalObject.DATASET_DIM_ID;
@@ -54,6 +54,7 @@
 
 import org.apache.commons.lang.StringUtils;
 import org.hisp.dhis.common.CombinationGenerator;
+import org.hisp.dhis.common.DimensionType;
 import org.hisp.dhis.common.IdentifiableObject;
 import org.hisp.dhis.common.ListMap;
 import org.hisp.dhis.dataelement.DataElementCategory;

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/Dimension.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/Dimension.java	2013-05-07 08:37:33 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/Dimension.java	2013-05-08 10:15:29 +0000
@@ -30,6 +30,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.hisp.dhis.common.DimensionType;
 import org.hisp.dhis.common.IdentifiableObject;
 
 /**

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java	2013-05-07 08:37:33 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java	2013-05-08 10:15:29 +0000
@@ -65,7 +65,7 @@
 import org.hisp.dhis.analytics.DataQueryParams;
 import org.hisp.dhis.analytics.Dimension;
 import org.hisp.dhis.analytics.DimensionItem;
-import org.hisp.dhis.analytics.DimensionType;
+import org.hisp.dhis.common.DimensionType;
 import org.hisp.dhis.analytics.IllegalQueryException;
 import org.hisp.dhis.analytics.QueryPlanner;
 import org.hisp.dhis.common.Grid;

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java	2013-05-07 08:37:33 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java	2013-05-08 10:15:29 +0000
@@ -47,7 +47,7 @@
 import org.hisp.dhis.analytics.AggregationType;
 import org.hisp.dhis.analytics.DataQueryParams;
 import org.hisp.dhis.analytics.Dimension;
-import org.hisp.dhis.analytics.DimensionType;
+import org.hisp.dhis.common.DimensionType;
 import org.hisp.dhis.analytics.IllegalQueryException;
 import org.hisp.dhis.analytics.QueryPlanner;
 import org.hisp.dhis.analytics.table.PartitionUtils;

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/DataQueryParamsTest.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/DataQueryParamsTest.java	2013-05-07 08:37:33 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/DataQueryParamsTest.java	2013-05-08 10:15:29 +0000
@@ -39,6 +39,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.hisp.dhis.common.DimensionType;
 import org.hisp.dhis.common.IdentifiableObject;
 import org.hisp.dhis.period.Period;
 import org.junit.Test;

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultDimensionService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultDimensionService.java	2013-04-23 12:02:26 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultDimensionService.java	2013-05-08 22:56:40 +0000
@@ -28,13 +28,13 @@
  */
 
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.hisp.dhis.dataelement.DataElementCategory;
-import org.hisp.dhis.dataelement.DataElementCategoryService;
 import org.hisp.dhis.dataelement.DataElementGroupSet;
-import org.hisp.dhis.dataelement.DataElementService;
-import org.hisp.dhis.organisationunit.OrganisationUnitGroupService;
 import org.hisp.dhis.organisationunit.OrganisationUnitGroupSet;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -45,32 +45,26 @@
     implements DimensionService
 {
     @Autowired
-    private DataElementService dataElementService;
-    
-    @Autowired
-    private OrganisationUnitGroupService organisationUnitGroupService;
-    
-    @Autowired
-    private DataElementCategoryService categoryService;
+    private IdentifiableObjectManager identifiableObjectManager;
     
     @Override
     public DimensionalObject getDimension( String uid )
-    {
-        DataElementGroupSet degs = dataElementService.getDataElementGroupSet( uid );
+    {        
+        DataElementGroupSet degs = identifiableObjectManager.get( DataElementGroupSet.class, uid );
         
         if ( degs != null )
         {
             return degs;
         }
         
-        OrganisationUnitGroupSet ougs = organisationUnitGroupService.getOrganisationUnitGroupSet( uid );
+        OrganisationUnitGroupSet ougs = identifiableObjectManager.get( OrganisationUnitGroupSet.class, uid );
         
         if ( ougs != null )
         {
             return ougs;
         }
         
-        DataElementCategory cat = categoryService.getDataElementCategory( uid );
+        DataElementCategory cat = identifiableObjectManager.get( DataElementCategory.class, uid );
         
         if ( cat != null )
         {
@@ -79,15 +73,55 @@
         
         return null;
     }
+    
+    public DimensionType getDimensionType( String uid )
+    {
+        DataElementGroupSet degs = identifiableObjectManager.get( DataElementGroupSet.class, uid );
+        
+        if ( degs != null )
+        {
+            return DimensionType.DATAELEMENT_GROUPSET;
+        }
+        
+        OrganisationUnitGroupSet ougs = identifiableObjectManager.get( OrganisationUnitGroupSet.class, uid );
+        
+        if ( ougs != null )
+        {
+            return DimensionType.ORGANISATIONUNIT_GROUPSET;
+        }
+        
+        DataElementCategory cat = identifiableObjectManager.get( DataElementCategory.class, uid );
+        
+        if ( cat != null )
+        {
+            return DimensionType.CATEGORY;
+        }
 
+        final Map<String, DimensionType> dimObjectTypeMap = new HashMap<String, DimensionType>();
+        
+        dimObjectTypeMap.put( DimensionalObject.DATA_X_DIM_ID, DimensionType.DATA_X );
+        dimObjectTypeMap.put( DimensionalObject.INDICATOR_DIM_ID, DimensionType.INDICATOR );
+        dimObjectTypeMap.put( DimensionalObject.DATAELEMENT_DIM_ID, DimensionType.DATAELEMENT );
+        dimObjectTypeMap.put( DimensionalObject.DATASET_DIM_ID, DimensionType.DATASET );
+        dimObjectTypeMap.put( DimensionalObject.DATAELEMENT_OPERAND_ID, DimensionType.DATAELEMENT_OPERAND );
+        dimObjectTypeMap.put( DimensionalObject.PERIOD_DIM_ID, DimensionType.PERIOD );
+        dimObjectTypeMap.put( DimensionalObject.ORGUNIT_DIM_ID, DimensionType.ORGANISATIONUNIT );
+        
+        return dimObjectTypeMap.get( uid );
+    }
+    
     @Override
     public List<DimensionalObject> getAllDimensions()
     {
-        List<DimensionalObject> dimensions = new ArrayList<DimensionalObject>();
+        Collection<DataElementGroupSet> degs = identifiableObjectManager.getAll( DataElementGroupSet.class );
+        Collection<OrganisationUnitGroupSet> ougs = identifiableObjectManager.getAll( OrganisationUnitGroupSet.class );
+        Collection<DataElementCategory> dcs = identifiableObjectManager.getAll( DataElementCategory.class );
+
+        final List<DimensionalObject> dimensions = new ArrayList<DimensionalObject>();
         
-        dimensions.addAll( dataElementService.getAllDataElementGroupSets() );
-        dimensions.addAll( organisationUnitGroupService.getAllOrganisationUnitGroupSets() );
-        dimensions.addAll( categoryService.getDataDimensionDataElementCategories() );
+        dimensions.addAll( degs );
+        dimensions.addAll( ougs );
+        dimensions.addAll( dcs );
         
         return dimensions;
     }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultIdentifiableObjectManager.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultIdentifiableObjectManager.java	2013-03-22 09:48:50 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultIdentifiableObjectManager.java	2013-05-08 10:15:29 +0000
@@ -180,7 +180,7 @@
 
         return object;
     }
-
+    
     @Override
     @SuppressWarnings("unchecked")
     public <T extends IdentifiableObject> Collection<T> getAll( Class<T> clazz )

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/period/DefaultPeriodService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/period/DefaultPeriodService.java	2013-01-25 16:38:21 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/period/DefaultPeriodService.java	2013-05-08 10:15:29 +0000
@@ -135,7 +135,7 @@
 
         return periods;
     }
-
+    
     public Collection<Period> getPeriodsByPeriodType( PeriodType periodType )
     {
         return periodStore.getPeriodsByPeriodType( periodType );

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java	2013-05-05 18:08:08 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java	2013-05-08 10:15:29 +0000
@@ -333,6 +333,7 @@
         executeSql( "ALTER TABLE chart DROP COLUMN last12individualmonths" );
         executeSql( "ALTER TABLE chart DROP COLUMN individualmonthsthisyear" );
         executeSql( "ALTER TABLE chart DROP COLUMN individualquartersthisyear" );
+        executeSql( "ALTER TABLE chart DROP COLUMN organisationunitgroupsetid" );
 
         // remove source
 
@@ -458,9 +459,19 @@
         executeSql( "update chart set userorganisationunitchildren = false where userorganisationunitchildren is null" );
         executeSql( "update chart set userorganisationunit = false where userorganisationunit is null" );
         
+        executeSql( "update chart set series = 'dx' where series = 'data'" );
+        executeSql( "update chart set series = 'pe' where series = 'period'" );
+        executeSql( "update chart set series = 'ou' where series = 'organisationunit'" );
+        executeSql( "update chart set category = 'dx' where category = 'data'" );
+        executeSql( "update chart set category = 'pe' where category = 'period'" );
+        executeSql( "update chart set category = 'ou' where category = 'organisationunit'" );
+        executeSql( "update chart_filters set filter = 'dx' where filter = 'data'" );
+        executeSql( "update chart_filters set filter = 'pe' where filter = 'period'" );
+        executeSql( "update chart_filters set filter = 'ou' where filter = 'organisationunit'" );
+        
         executeSql( "insert into chart_filters (chartid, sort_order, filter) select chartid, 0, filter from chart" );
         executeSql( "alter table chart drop column filter" );
-        
+                
         executeSql( "update users set selfregistered = false where selfregistered is null" );
         executeSql( "update users set disabled = false where disabled is null" );
         executeSql( "update dataentryform set format = 1 where format is null" );

=== modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/chart/impl/DefaultChartService.java'
--- dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/chart/impl/DefaultChartService.java	2013-05-02 12:31:26 +0000
+++ dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/chart/impl/DefaultChartService.java	2013-05-08 22:56:40 +0000
@@ -35,6 +35,7 @@
 import org.hisp.dhis.chart.Chart;
 import org.hisp.dhis.chart.ChartService;
 import org.hisp.dhis.chart.ChartStore;
+import org.hisp.dhis.common.DimensionalObject;
 import org.hisp.dhis.common.NameableObject;
 import org.hisp.dhis.dataelement.DataElement;
 import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
@@ -229,7 +230,7 @@
         }
 
         chart.setType( TYPE_LINE );
-        chart.setDimensions( Chart.DIMENSION_DATA, Chart.DIMENSION_PERIOD, Chart.DIMENSION_ORGANISATIONUNIT );
+        chart.setDimensions( DimensionalObject.DATA_X_DIM_ID, DimensionalObject.PERIOD_DIM_ID, DimensionalObject.ORGUNIT_DIM_ID );
         chart.setHideLegend( true );
         chart.getIndicators().add( indicator );
         chart.setRelativePeriods( periods );
@@ -253,7 +254,7 @@
         }
 
         chart.setType( TYPE_COLUMN );
-        chart.setDimensions( Chart.DIMENSION_DATA, Chart.DIMENSION_ORGANISATIONUNIT, Chart.DIMENSION_PERIOD );
+        chart.setDimensions( DimensionalObject.DATA_X_DIM_ID, DimensionalObject.ORGUNIT_DIM_ID, DimensionalObject.PERIOD_DIM_ID );
         chart.setHideLegend( true );
         chart.getIndicators().add( indicator );
         chart.setRelativePeriods( periods );

=== modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/jdbc/AnalyticsDataSetReportStore.java'
--- dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/jdbc/AnalyticsDataSetReportStore.java	2013-05-03 15:06:31 +0000
+++ dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/jdbc/AnalyticsDataSetReportStore.java	2013-05-08 10:15:29 +0000
@@ -38,7 +38,7 @@
 
 import org.hisp.dhis.analytics.AnalyticsService;
 import org.hisp.dhis.analytics.DataQueryParams;
-import org.hisp.dhis.analytics.DimensionType;
+import org.hisp.dhis.common.DimensionType;
 import org.hisp.dhis.dataelement.DataElement;
 import org.hisp.dhis.dataelement.DataElementCategory;
 import org.hisp.dhis.dataset.DataSet;

=== modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/reporttable/jdbc/JDBCReportTableManager.java'
--- dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/reporttable/jdbc/JDBCReportTableManager.java	2012-08-31 14:38:21 +0000
+++ dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/reporttable/jdbc/JDBCReportTableManager.java	2013-05-08 10:15:29 +0000
@@ -90,16 +90,8 @@
     
     public Map<String, Double> getAggregatedValueMap( Chart chart )
     {
-        if ( chart.isOrganisationUnitGroupBased() )
-        {
-            return getAggregatedValueMapOrgUnitGroups( chart.getDataElements(), chart.getIndicators(),
-                chart.getAllPeriods(), chart.getOrganisationUnitGroupSet().getOrganisationUnitGroups(), chart.getFirstOrganisationUnit(), null, false, false );
-        }
-        else
-        {
-            return getAggregatedValueMapOrgUnitHierarchy( chart.getDataElements(), chart.getIndicators(), chart.getDataSets(),
-                chart.getAllPeriods(), chart.getAllOrganisationUnits(), null, false, false );
-        }
+        return getAggregatedValueMapOrgUnitHierarchy( chart.getDataElements(), chart.getIndicators(), chart.getDataSets(),
+            chart.getAllPeriods(), chart.getAllOrganisationUnits(), null, false, false );
     }
 
     // -------------------------------------------------------------------------

=== modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/chart/hibernate/Chart.hbm.xml'
--- dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/chart/hibernate/Chart.hbm.xml	2013-05-07 07:43:44 +0000
+++ dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/chart/hibernate/Chart.hbm.xml	2013-05-08 22:56:40 +0000
@@ -85,9 +85,6 @@
         foreign-key="fk_chart_organisationunits_organisationunitid" />
     </list>
 
-    <many-to-one name="organisationUnitGroupSet" class="org.hisp.dhis.organisationunit.OrganisationUnitGroupSet"
-      column="organisationunitgroupsetid" foreign-key="fk_chart_organisationunitgroupsetid" />
-
     <list name="periods" table="chart_periods">
       <cache usage="read-write" />
       <key column="chartid" foreign-key="fk_chart_periods_chartid" />
@@ -99,6 +96,22 @@
     <many-to-one name="relatives" unique="true" class="org.hisp.dhis.period.RelativePeriods" column="relativeperiodsid"
       cascade="all-delete-orphan" foreign-key="fk_report_relativeperiodsid" />
 
+    <list name="dataElementGroups" table="chart_dataelementgroups">
+      <cache usage="read-write" />
+      <key column="chartid" foreign-key="fk_chart_dataelementgroups_chartid" />
+      <list-index column="sort_order" base="0" />
+      <many-to-many column="dataelementgroupid" class="org.hisp.dhis.dataelement.DataElementGroup"
+        foreign-key="fk_chart_dataelementgroups_dataelementgroupid" />
+    </list>
+
+    <list name="organisationUnitGroups" table="chart_orgunitgroups">
+      <cache usage="read-write" />
+      <key column="chartid" foreign-key="fk_chart_orgunitunitgroups_chartid" />
+      <list-index column="sort_order" base="0" />
+      <many-to-many column="orgunitgroupid" class="org.hisp.dhis.organisationunit.OrganisationUnitGroup"
+        foreign-key="fk_chart_orgunitgroups_orgunitgroupid" />
+    </list>
+    
     <property name="userOrganisationUnit" />
 
     <property name="userOrganisationUnitChildren" />

=== modified file 'dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisConvenienceTest.java'
--- dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisConvenienceTest.java	2013-04-04 18:06:19 +0000
+++ dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisConvenienceTest.java	2013-05-08 22:56:40 +0000
@@ -39,6 +39,7 @@
 import org.hisp.dhis.aggregation.AggregatedDataValueService;
 import org.hisp.dhis.aggregation.AggregatedOrgUnitDataValueService;
 import org.hisp.dhis.chart.Chart;
+import org.hisp.dhis.common.DimensionalObject;
 import org.hisp.dhis.concept.Concept;
 import org.hisp.dhis.constant.Constant;
 import org.hisp.dhis.constant.ConstantService;
@@ -851,7 +852,7 @@
         chart.setIndicators( indicators );
         chart.setPeriods( periods );
         chart.setOrganisationUnits( units );
-        chart.setDimensions( Chart.DIMENSION_DATA, Chart.DIMENSION_PERIOD, Chart.DIMENSION_ORGANISATIONUNIT );
+        chart.setDimensions( DimensionalObject.DATA_X_DIM_ID, DimensionalObject.PERIOD_DIM_ID, DimensionalObject.ORGUNIT_DIM_ID );
 
         return chart;
     }

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/ChartController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/ChartController.java	2013-04-24 14:11:57 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/ChartController.java	2013-05-08 22:56:40 +0000
@@ -27,11 +27,26 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import static org.hisp.dhis.common.DimensionType.DATAELEMENT;
+import static org.hisp.dhis.common.DimensionType.DATAELEMENT_GROUPSET;
+import static org.hisp.dhis.common.DimensionType.DATASET;
+import static org.hisp.dhis.common.DimensionType.INDICATOR;
+import static org.hisp.dhis.common.DimensionType.ORGANISATIONUNIT;
+import static org.hisp.dhis.common.DimensionType.ORGANISATIONUNIT_GROUPSET;
+import static org.hisp.dhis.common.DimensionType.PERIOD;
 import static org.hisp.dhis.common.IdentifiableObjectUtils.getUids;
+import static org.hisp.dhis.organisationunit.OrganisationUnit.KEY_USER_ORGUNIT;
+import static org.hisp.dhis.organisationunit.OrganisationUnit.KEY_USER_ORGUNIT_CHILDREN;
+import static org.hisp.dhis.common.DimensionalObject.DATA_X_DIMS;
+import static org.hisp.dhis.common.DimensionalObject.DATA_X_DIM_ID;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -40,6 +55,9 @@
 import org.hisp.dhis.api.utils.ContextUtils.CacheStrategy;
 import org.hisp.dhis.chart.Chart;
 import org.hisp.dhis.chart.ChartService;
+import org.hisp.dhis.common.DimensionService;
+import org.hisp.dhis.common.DimensionType;
+import org.hisp.dhis.common.DimensionalObject;
 import org.hisp.dhis.dataelement.DataElementService;
 import org.hisp.dhis.dataset.DataSetService;
 import org.hisp.dhis.dxf2.utils.JacksonUtils;
@@ -53,6 +71,9 @@
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.period.Period;
 import org.hisp.dhis.period.PeriodService;
+import org.hisp.dhis.period.PeriodType;
+import org.hisp.dhis.period.RelativePeriodEnum;
+import org.hisp.dhis.period.RelativePeriods;
 import org.hisp.dhis.system.util.CodecUtils;
 import org.hisp.dhis.user.UserService;
 import org.jfree.chart.ChartUtilities;
@@ -103,6 +124,9 @@
     private OrganisationUnitGroupService organisationUnitGroupService;
     
     @Autowired
+    private DimensionService dimensionService;
+    
+    @Autowired
     private I18nManager i18nManager;
 
     @Autowired
@@ -219,6 +243,8 @@
     @Override
     public void postProcessEntity( Chart chart ) throws Exception
     {
+        chart.populateWebDomainProperties();
+        
         I18nFormat format = i18nManager.getI18nFormat();
         
         if ( chart.getPeriods() != null && !chart.getPeriods().isEmpty() )
@@ -236,20 +262,126 @@
 
     private void mergeChart( Chart chart )
     {
-        chart.setDataElements( dataElementService.getDataElementsByUid( getUids( chart.getDataElements() ) ) );
-        chart.setIndicators( indicatorService.getIndicatorsByUid( getUids( chart.getIndicators() ) ) );
-        chart.setDataSets( dataSetService.getDataSetsByUid( getUids( chart.getDataSets() ) ) );
-        chart.setOrganisationUnits( organisationUnitService.getOrganisationUnitsByUid( getUids( chart.getOrganisationUnits() ) ) );
-        chart.setPeriods( periodService.reloadPeriods( chart.getPeriods() ) );
-
-        if ( chart.getOrganisationUnitGroupSet() != null )
-        {
-            chart.setOrganisationUnitGroupSet( organisationUnitGroupService.getOrganisationUnitGroupSet( chart.getOrganisationUnitGroupSet().getUid() ) );
-        }
+        chart.getIndicators().clear();
+        chart.getDataElements().clear();
+        chart.getDataSets().clear();
+        chart.getPeriods().clear();
+        chart.setRelatives( null );
+        chart.getOrganisationUnits().clear();
+        chart.getDataElementGroups().clear();
+        chart.getOrganisationUnitGroups().clear();
+        chart.getFilterDimensions().clear();
         
         if ( chart.getUser() != null )
         {
             chart.setUser( userService.getUser( chart.getUser().getUid() ) );
         }
+        
+        mergeDimensionalObjects( chart, chart.getColumns() );
+        mergeDimensionalObjects( chart, chart.getRows() );
+        mergeDimensionalObjects( chart, chart.getFilters() );
+        
+        chart.setSeries( toDimension( chart.getColumns().get( 0 ).getDimension() ) );
+        chart.setCategory( toDimension( chart.getRows().get( 0 ).getDimension() ) );
+        
+        for ( DimensionalObject dimension : chart.getFilters() )
+        {
+            chart.getFilterDimensions().add( toDimension( dimension.getDimension() ) );
+        }
+    }
+    
+    private void mergeDimensionalObjects( Chart chart, List<DimensionalObject> dimensions )
+    {
+        for ( DimensionalObject dimension : dimensions )
+        {
+            DimensionType type = dimensionService.getDimensionType( dimension.getDimension() );
+            
+            List<String> uids = getUids( dimension.getItems() );
+            
+            if ( INDICATOR.equals( type ) )
+            {
+                chart.getIndicators().addAll( indicatorService.getIndicatorsByUid( uids ) );
+            }
+            else if ( DATAELEMENT.equals( type ) )
+            {
+                chart.getDataElements().addAll( dataElementService.getDataElementsByUid( uids ) );
+            }
+            else if ( DATASET.equals( type ) )
+            {
+                chart.getDataSets().addAll( dataSetService.getDataSetsByUid( uids ) );
+            }
+            else if ( PERIOD.equals( type ) )
+            {
+                List<RelativePeriodEnum> enums = new ArrayList<RelativePeriodEnum>();                
+                Set<Period> periods = new HashSet<Period>();
+                
+                for ( String isoPeriod : uids )
+                {
+                    if ( RelativePeriodEnum.contains( isoPeriod ) )
+                    {
+                        enums.add( RelativePeriodEnum.valueOf( isoPeriod ) );
+                    }
+                    else
+                    {
+                        Period period = PeriodType.getPeriodFromIsoString( isoPeriod );
+                    
+                        if ( period != null )
+                        {
+                            periods.add( period );
+                        }
+                    }
+                }
+
+                chart.setRelatives( new RelativePeriods().setRelativePeriodsFromEnums( enums ) );
+                chart.setPeriods( periodService.reloadPeriods( new ArrayList<Period>( periods ) ) );
+            }
+            else if ( ORGANISATIONUNIT.equals( type ) )
+            {
+                List<OrganisationUnit> ous = new ArrayList<OrganisationUnit>();
+                
+                for ( String ou : uids )
+                {
+                    if ( KEY_USER_ORGUNIT.equals( ou ) )
+                    {
+                        chart.setUserOrganisationUnit( true );
+                    }
+                    else if ( KEY_USER_ORGUNIT_CHILDREN.equals( ou ) )
+                    {
+                        chart.setUserOrganisationUnitChildren( true );
+                    }
+                    else
+                    {
+                        OrganisationUnit unit = organisationUnitService.getOrganisationUnit( ou );
+                        
+                        if ( unit != null )
+                        {
+                            ous.add( unit );
+                        }
+                    }
+                }
+                
+                chart.setOrganisationUnits( ous );
+            }
+            else if ( DATAELEMENT_GROUPSET.equals( type ) )
+            {
+                chart.getDataElementGroups().addAll( dataElementService.getDataElementGroupsByUid( uids ) );
+            }
+            else if ( ORGANISATIONUNIT_GROUPSET.equals( type ) )
+            {
+                chart.getOrganisationUnitGroups().addAll( organisationUnitGroupService.getOrganisationUnitGroupsByUid( uids ) );
+            }
+                        
+            //TODO categories and operands
+        }
+    }
+    
+    private static String toDimension( String object )
+    {
+        if ( DATA_X_DIMS.contains( object ) )
+        {
+            return DATA_X_DIM_ID;
+        }
+        
+        return object;
     }
 }