← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 13618: Analytics, impl support for showHierarchy param

 

Merge authors:
  Lars Helge Øverland (larshelge)
------------------------------------------------------------
revno: 13618 [merge]
committer: Lars Helge Øverland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Tue 2014-01-07 16:52:34 +0100
message:
  Analytics, impl support for showHierarchy param
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/Grid.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/reporttable/ReportTable.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsService.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/data/DefaultAnalyticsService.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/MockAnalyticsService.java
  dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/AnalyticsServiceTest.java
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/grid/ListGrid.java
  dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/grid/GridTest.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AnalyticsController.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/common/Grid.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/Grid.java	2013-12-31 09:05:21 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/Grid.java	2014-01-07 15:52:34 +0000
@@ -219,6 +219,13 @@
     Grid removeCurrentWriteRow();
     
     /**
+     * Indicates whether meta data exists and contains the given key.
+     * 
+     * @param key the meta data key.
+     */
+    boolean hasMetaDataKey( String key );
+    
+    /**
      * Limits the grid from top by the given argument number.
      * 
      * @param limit the top limit, must be greater than zero to have an effect.
@@ -283,6 +290,15 @@
     Grid substituteMetaData( Map<Object, Object> metaDataMap );
     
     /**
+     * Substitutes the values in the meta columns with the mapped value in the
+     * meta-data map for the column with the given index.
+     * 
+     * @param columnIndex the index of the column to substitute.
+     * @param metaDataMap meta-data map of keys and substitutions.
+     */
+    Grid substituteMetaData( int columnIndex, Map<Object, Object> metaDataMap );
+    
+    /**
      * Adds a set of headers based on the column names of the given SQL result set.
      * 
      * @param rs the result set.

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java	2013-11-28 13:52:05 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnit.java	2014-01-07 15:52:34 +0000
@@ -631,6 +631,25 @@
         return builder.toString();
     }
 
+    public String getParentNameGraph( boolean includeThis )
+    {
+        StringBuilder builder = new StringBuilder();
+
+        List<OrganisationUnit> ancestors = getAncestors();
+
+        for ( OrganisationUnit unit : ancestors )
+        {
+            builder.append( "/" ).append( unit.getName() );
+        }
+
+        if ( includeThis )
+        {
+            builder.append( "/" ).append( name );
+        }
+        
+        return builder.toString();
+    }
+
     public Set<DataSet> getAllDataSets()
     {
         Set<DataSet> allDataSets = new HashSet<DataSet>( dataSets );
@@ -662,6 +681,25 @@
         return map;
     }
 
+    /**
+     * Returns a mapping between the uid and the uid parent graph of the given
+     * organisation units.
+     */
+    public static Map<String, String> getParentNameGraphMap( List<OrganisationUnit> organisationUnits, boolean includeThis )
+    {
+        Map<String, String> map = new HashMap<String, String>();
+        
+        if ( organisationUnits != null )
+        {
+            for ( OrganisationUnit unit : organisationUnits )
+            {
+                map.put( unit.getName(), unit.getParentNameGraph( includeThis ) );
+            }
+        }
+        
+        return map;
+    }
+
     // -------------------------------------------------------------------------
     // Getters and setters
     // -------------------------------------------------------------------------

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/reporttable/ReportTable.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/reporttable/ReportTable.java	2013-12-31 09:05:21 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/reporttable/ReportTable.java	2014-01-07 15:52:34 +0000
@@ -573,6 +573,7 @@
      * @param paramColumns whether to include report parameter columns.
      * @return a grid.
      */
+    @SuppressWarnings("unchecked")
     public Grid getGrid( Grid grid, Map<String, Double> valueMap, boolean paramColumns )
     {
         valueMap = new HashMap<String, Double>( valueMap );
@@ -704,6 +705,17 @@
             grid.limitGrid( topLimit );
         }
 
+        // ---------------------------------------------------------------------
+        // Show hierarchy option
+        // ---------------------------------------------------------------------
+
+        if ( showHierarchy && rowDimensions.indexOf( ORGUNIT_DIM_ID ) != -1 && grid.hasMetaDataKey( "ouNameHierarchy" ) )
+        {
+            int ouNameIndex = ( rowDimensions.indexOf( ORGUNIT_DIM_ID ) * 4 ) + 1; // Ou name position            
+            Map<Object, Object> hierarchyNameMap = (Map<Object, Object>) grid.getMetaData().get( "ouNameHierarchy" );
+            grid.substituteMetaData( ouNameIndex, hierarchyNameMap );
+        }
+
         return grid;
     }
     

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsService.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsService.java	2013-12-31 09:05:21 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsService.java	2014-01-07 15:52:34 +0000
@@ -96,6 +96,7 @@
     final String NAMES_META_KEY = "names";
     final String PAGER_META_KEY = "pager";
     final String OU_HIERARCHY_KEY = "ouHierarchy";
+    final String OU_NAME_HIERARCHY_KEY = "ouNameHierarchy";
     
     /**
      * Generates aggregated values for the given query.
@@ -153,11 +154,12 @@
      *        in the hierarchy.
      * @param ignoreLimit whether to ignore the max number of cells limit.
      * @param hideEmptyRows whether to hide rows without data values, applis to table layout.
+     * @param showHierarchy whether to show the org unit hierarchy together with the name.
      * @param format the i18n format.
      * @return a data query parameter object created based on the given URL info.
      */
-    DataQueryParams getFromUrl( Set<String> dimensionParams, Set<String> filterParams, AggregationType aggregationType, 
-        String measureCriteria, boolean skipMeta, boolean skipRounding, boolean hierarchyMeta, boolean ignoreLimit, boolean hideEmptyRows, I18nFormat format );
+    DataQueryParams getFromUrl( Set<String> dimensionParams, Set<String> filterParams, AggregationType aggregationType, String measureCriteria, 
+        boolean skipMeta, boolean skipRounding, boolean hierarchyMeta, boolean ignoreLimit, boolean hideEmptyRows, boolean showHierarchy, I18nFormat format );
     
     /**
      * Creates a data query parameter object from the given BaseAnalyticalObject.

=== 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-12-31 09:18:11 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java	2014-01-07 15:52:34 +0000
@@ -142,6 +142,12 @@
      */
     private boolean hideEmptyRows;
     
+    /**
+     * Indicates whether the org unit hierarchy path should be displayed with the
+     * org unit names on rows.
+     */
+    private boolean showHierarchy;
+    
     // -------------------------------------------------------------------------
     // Transient properties
     // -------------------------------------------------------------------------
@@ -1117,6 +1123,16 @@
         this.hideEmptyRows = hideEmptyRows;
     }
 
+    public boolean isShowHierarchy()
+    {
+        return showHierarchy;
+    }
+
+    public void setShowHierarchy( boolean showHierarchy )
+    {
+        this.showHierarchy = showHierarchy;
+    }
+
     // -------------------------------------------------------------------------
     // Get and set methods for transient properties
     // -------------------------------------------------------------------------

=== 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-12-31 09:05:21 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java	2014-01-07 15:52:34 +0000
@@ -56,6 +56,7 @@
 import static org.hisp.dhis.organisationunit.OrganisationUnit.KEY_USER_ORGUNIT_CHILDREN;
 import static org.hisp.dhis.organisationunit.OrganisationUnit.KEY_USER_ORGUNIT_GRANDCHILDREN;
 import static org.hisp.dhis.organisationunit.OrganisationUnit.getParentGraphMap;
+import static org.hisp.dhis.organisationunit.OrganisationUnit.getParentNameGraphMap;
 import static org.hisp.dhis.period.PeriodType.getPeriodTypeFromIsoString;
 import static org.hisp.dhis.reporttable.ReportTable.IRT2D;
 import static org.hisp.dhis.reporttable.ReportTable.addIfEmpty;
@@ -401,6 +402,11 @@
                 metaData.put( OU_HIERARCHY_KEY, getParentGraphMap( asTypedList( params.getDimensionOrFilter( ORGUNIT_DIM_ID ), OrganisationUnit.class ) ) );
             }
             
+            if ( params.isShowHierarchy() )
+            {
+                metaData.put( OU_NAME_HIERARCHY_KEY, getParentNameGraphMap( asTypedList( params.getDimensionOrFilter( ORGUNIT_DIM_ID ), OrganisationUnit.class ), true ) );
+            }
+            
             grid.setMetaData( metaData );
         }
         
@@ -420,8 +426,6 @@
         
         queryPlanner.validateTableLayout( params, columns, rows );
         
-        Map<String, Double> valueMap = getAggregatedDataValueMapping( params );
-
         ReportTable reportTable = new ReportTable();
         
         List<NameableObject[]> tableColumns = new ArrayList<NameableObject[]>();
@@ -455,8 +459,13 @@
         
         reportTable.setTitle( IdentifiableObjectUtils.join( params.getFilterItems() ) );
         reportTable.setHideEmptyRows( params.isHideEmptyRows() );
-
-        return reportTable.getGrid( new ListGrid(), valueMap, false );
+        reportTable.setShowHierarchy( params.isShowHierarchy() );
+
+        Grid grid = getAggregatedDataValues( params );
+        
+        Map<String, Double> valueMap = getAggregatedDataValueMapping( grid );
+
+        return reportTable.getGrid( new ListGrid( grid.getMetaData() ), valueMap, false );
     }
     
     @Override
@@ -464,6 +473,19 @@
     {
         Grid grid = getAggregatedDataValues( params );
         
+        return getAggregatedDataValueMapping( grid );
+    }
+    
+    /**
+     * Generates a mapping where the key represents the dimensional item identifiers
+     * concatenated by "-" and the value is the corresponding aggregated data value
+     * based on the given grid.
+     * 
+     * @param grid the grid.
+     * @return a mapping between item identifiers and aggregated values.
+     */
+    private Map<String, Double> getAggregatedDataValueMapping( Grid grid )
+    {
         Map<String, Double> map = new HashMap<String, Double>();
         
         int metaCols = grid.getWidth() - 1;
@@ -588,7 +610,7 @@
     
     @Override
     public DataQueryParams getFromUrl( Set<String> dimensionParams, Set<String> filterParams, AggregationType aggregationType, 
-        String measureCriteria, boolean skipMeta, boolean skipRounding, boolean hierarchyMeta, boolean ignoreLimit, boolean hideEmptyRows, I18nFormat format )
+        String measureCriteria, boolean skipMeta, boolean skipRounding, boolean hierarchyMeta, boolean ignoreLimit, boolean hideEmptyRows, boolean showHierarchy, I18nFormat format )
     {
         DataQueryParams params = new DataQueryParams();
 
@@ -632,6 +654,7 @@
         params.setSkipRounding( skipRounding );
         params.setHierarchyMeta( hierarchyMeta );
         params.setHideEmptyRows( hideEmptyRows );
+        params.setShowHierarchy( showHierarchy );
 
         return params;
     }

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/MockAnalyticsService.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/MockAnalyticsService.java	2013-12-31 09:05:21 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/MockAnalyticsService.java	2014-01-07 15:52:34 +0000
@@ -81,7 +81,7 @@
 
     @Override
     public DataQueryParams getFromUrl( Set<String> dimensionParams, Set<String> filterParams, AggregationType aggregationType, 
-        String measureCriteria, boolean skipMeta, boolean skipRounding, boolean hierarchyMeta, boolean hideEmptyRows, boolean ignoreLimit, I18nFormat format )
+        String measureCriteria, boolean skipMeta, boolean skipRounding, boolean hierarchyMeta, boolean ignoreLimit, boolean hideEmptyRows, boolean showHierarchy, I18nFormat format )
     {
         throw new NotImplementedException();
     }

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/AnalyticsServiceTest.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/AnalyticsServiceTest.java	2013-12-31 09:05:21 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/AnalyticsServiceTest.java	2014-01-07 15:52:34 +0000
@@ -164,7 +164,7 @@
         Set<String> filterParams = new HashSet<String>();
         filterParams.add( "ou:" + ouA.getUid() + ";" + ouB.getUid() + ";" + ouC.getUid() + ";" + ouD.getUid() + ";" + ouE.getUid() );
         
-        DataQueryParams params = analyticsService.getFromUrl( dimensionParams, filterParams, null, null, false, false, false, false, false, null );
+        DataQueryParams params = analyticsService.getFromUrl( dimensionParams, filterParams, null, null, false, false, false, false, false, false, null );
         
         assertEquals( 4, params.getDataElements().size() );
         assertEquals( 3, params.getPeriods().size() );
@@ -181,7 +181,7 @@
         Set<String> filterParams = new HashSet<String>();
         filterParams.add( "ou:" + ouA.getUid() );
         
-        DataQueryParams params = analyticsService.getFromUrl( dimensionParams, filterParams, null, null, false, false, false, false, false, null );
+        DataQueryParams params = analyticsService.getFromUrl( dimensionParams, filterParams, null, null, false, false, false, false, false, false, null );
         
         assertEquals( 4, params.getDataElements().size() );
         assertEquals( 1, params.getFilterOrganisationUnits().size() );
@@ -197,7 +197,7 @@
         Set<String> filterParams = new HashSet<String>();
         filterParams.add( "ou:" + ouA.getUid() + ";" + ouB.getUid() );
 
-        DataQueryParams params = analyticsService.getFromUrl( dimensionParams, filterParams, null, null, false, false, false, false, false, null );
+        DataQueryParams params = analyticsService.getFromUrl( dimensionParams, filterParams, null, null, false, false, false, false, false, false, null );
         
         assertEquals( 4, params.getDataElements().size() );
         assertEquals( 12, params.getPeriods().size() );
@@ -212,7 +212,7 @@
         dimensionParams.add( "dx:" + deA.getUid() + ";" + deB.getUid() );
         dimensionParams.add( "pe:2011;2012" );
         
-        DataQueryParams params = analyticsService.getFromUrl( dimensionParams, null, null, null, false, false, false, false, false, null );
+        DataQueryParams params = analyticsService.getFromUrl( dimensionParams, null, null, null, false, false, false, false, false, false, null );
         
         assertEquals( 1, params.getOrganisationUnits().size() );  
         assertEquals( 2, params.getDataElements().size() );
@@ -227,7 +227,7 @@
         dimensionParams.add( "dx:" + deA.getUid() + ";" + deB.getUid() );
         dimensionParams.add( "pe:2011;2012" );
         
-        DataQueryParams params = analyticsService.getFromUrl( dimensionParams, null, null, null, false, false, false, false, false, null );
+        DataQueryParams params = analyticsService.getFromUrl( dimensionParams, null, null, null, false, false, false, false, false, false, null );
         
         assertEquals( 2, params.getOrganisationUnits().size() );  
         assertEquals( 2, params.getDataElements().size() );
@@ -241,7 +241,7 @@
         dimensionParams.add( "dx" );
         dimensionParams.add( "pe:2012,2012S1,2012S2" );
         
-        analyticsService.getFromUrl( dimensionParams, null, null, null, false, false, false, false, false, null );        
+        analyticsService.getFromUrl( dimensionParams, null, null, null, false, false, false, false, false, false, null );        
     }
     
     @Test( expected = IllegalQueryException.class )
@@ -251,7 +251,7 @@
         dimensionParams.add( "dx:" + BASE_UID + "A;" + BASE_UID + "B;" + BASE_UID + "C;" + BASE_UID + "D" );
         dimensionParams.add( "pe" );
 
-        analyticsService.getFromUrl( dimensionParams, null, null, null, false, false, false, false, false, null );        
+        analyticsService.getFromUrl( dimensionParams, null, null, null, false, false, false, false, false, false, null );        
     }
 
     @Test( expected = IllegalQueryException.class )
@@ -261,7 +261,7 @@
         dimensionParams.add( "dx:" + BASE_UID + "A;" + BASE_UID + "B;" + BASE_UID + "C;" + BASE_UID + "D" );
         dimensionParams.add( "ou" );
         
-        analyticsService.getFromUrl( dimensionParams, null, null, null, false, false, false, false, false, null );        
+        analyticsService.getFromUrl( dimensionParams, null, null, null, false, false, false, false, false, false, null );        
     }
 
     @Test( expected = IllegalQueryException.class )
@@ -271,7 +271,7 @@
         dimensionParams.add( "dx:" + BASE_UID + "A;" + BASE_UID + "B;" + BASE_UID + "C;" + BASE_UID + "D" );
         dimensionParams.add( "yebo:2012,2012S1,2012S2" );
         
-        analyticsService.getFromUrl( dimensionParams, null, null, null, false, false, false, false, false, null );        
+        analyticsService.getFromUrl( dimensionParams, null, null, null, false, false, false, false, false, false, null );        
     }
     
     @Test

=== modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/grid/ListGrid.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/grid/ListGrid.java	2013-12-31 09:05:21 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/grid/ListGrid.java	2014-01-07 15:52:34 +0000
@@ -116,9 +116,19 @@
      */
     public ListGrid()
     {
-        headers = new ArrayList<GridHeader>();
-        metaData = new HashMap<Object, Object>();
-        grid = new ArrayList<List<Object>>();
+        this.headers = new ArrayList<GridHeader>();
+        this.metaData = new HashMap<Object, Object>();
+        this.grid = new ArrayList<List<Object>>();
+    }
+    
+    /**
+     * @param metaData meta data.
+     */
+    public ListGrid( Map<Object, Object> metaData )
+    {
+        this.headers = new ArrayList<GridHeader>();
+        this.metaData = metaData;
+        this.grid = new ArrayList<List<Object>>();
     }
 
     // ---------------------------------------------------------------------
@@ -424,6 +434,11 @@
         return this;
     }
     
+    public boolean hasMetaDataKey( String key )
+    {
+        return metaData != null && metaData.containsKey( key );
+    }
+    
     public Grid limitGrid( int limit )
     {
         if ( limit < 0 )
@@ -611,24 +626,36 @@
             {
                 // Column cells
                 
-                List<Object> col = getColumn( colIndex );
-                
-                for ( int rowIndex = 0; rowIndex < col.size(); rowIndex++ )
-                {
-                    Object object = col.get( rowIndex );
-                    
-                    Object meta = metaDataMap.get( object );
-                    
-                    if ( meta != null )
-                    {
-                        grid.get( rowIndex ).set( colIndex, meta );
-                    }
-                }
+                substituteMetaData( colIndex, metaDataMap );
             }
         }        
         
         return this;
     }
+    
+    public Grid substituteMetaData( int columnIndex, Map<Object, Object> metaDataMap )
+    {
+        if ( metaDataMap == null )
+        {
+            return this;
+        }
+        
+        List<Object> col = getColumn( columnIndex );
+        
+        for ( int rowIndex = 0; rowIndex < col.size(); rowIndex++ )
+        {
+            Object object = col.get( rowIndex );
+            
+            Object meta = metaDataMap.get( object );
+            
+            if ( meta != null )
+            {
+                grid.get( rowIndex ).set( columnIndex, meta );
+            }
+        }
+        
+        return this;
+    }
 
     // -------------------------------------------------------------------------
     // JRDataSource implementation

=== modified file 'dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/grid/GridTest.java'
--- dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/grid/GridTest.java	2013-12-31 09:05:21 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/grid/GridTest.java	2014-01-07 13:11:09 +0000
@@ -126,6 +126,28 @@
         assertEquals( "TwentyOne", gridA.getValue( 1, 0 ) );
         assertEquals( "TwentyTwo", gridA.getValue( 1, 1 ) );
     }
+
+    @Test
+    public void testSubstituteMetaDataForIndex()
+    {
+        Map<Object, Object> metaData = new HashMap<Object, Object>();
+        metaData.put( 11, "Eleven" );
+        metaData.put( 12, "Twelve" );
+        metaData.put( 21, "TwentyOne" );
+        metaData.put( 22, "TwentyTwo" );
+                
+        assertEquals( 11, gridA.getValue( 0, 0 ) );
+        assertEquals( 12, gridA.getValue( 0, 1 ) );
+        assertEquals( 21, gridA.getValue( 1, 0 ) );
+        assertEquals( 22, gridA.getValue( 1, 1 ) );
+        
+        gridA.substituteMetaData( 1, metaData );
+
+        assertEquals( 11, gridA.getValue( 0, 0 ) );
+        assertEquals( "Twelve", gridA.getValue( 0, 1 ) );
+        assertEquals( 21, gridA.getValue( 1, 0 ) );
+        assertEquals( "TwentyTwo", gridA.getValue( 1, 1 ) );
+    }
     
     @Test
     public void testGetHeight()

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AnalyticsController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AnalyticsController.java	2013-12-31 09:05:21 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AnalyticsController.java	2014-01-07 15:52:34 +0000
@@ -86,12 +86,14 @@
         @RequestParam(required = false) boolean ignoreLimit,
         @RequestParam(required = false) boolean tableLayout,
         @RequestParam(required = false) boolean hideEmptyRows,
+        @RequestParam(required = false) boolean showHierarchy,
         @RequestParam(required = false) String columns,
         @RequestParam(required = false) String rows,
         Model model,
         HttpServletResponse response ) throws Exception
     {
-        DataQueryParams params = analyticsService.getFromUrl( dimension, filter, aggregationType, measureCriteria, skipMeta, skipRounding, hierarchyMeta, ignoreLimit, hideEmptyRows, i18nManager.getI18nFormat() );
+        DataQueryParams params = analyticsService.getFromUrl( dimension, filter, aggregationType, measureCriteria, 
+            skipMeta, skipRounding, hierarchyMeta, ignoreLimit, hideEmptyRows, showHierarchy, i18nManager.getI18nFormat() );
 
         contextUtils.configureResponse( response, ContextUtils.CONTENT_TYPE_JSON, CacheStrategy.RESPECT_SYSTEM_SETTING );
         Grid grid = analyticsService.getAggregatedDataValues( params, tableLayout, getDimensionsFromParam( columns ), getDimensionsFromParam( rows ) );
@@ -112,12 +114,14 @@
         @RequestParam(required = false) boolean ignoreLimit,
         @RequestParam(required = false) boolean tableLayout,
         @RequestParam(required = false) boolean hideEmptyRows,
+        @RequestParam(required = false) boolean showHierarchy,
         @RequestParam(required = false) String columns,
         @RequestParam(required = false) String rows,
         Model model,
         HttpServletResponse response ) throws Exception
     {
-        DataQueryParams params = analyticsService.getFromUrl( dimension, filter, aggregationType, measureCriteria, skipMeta, skipRounding, hierarchyMeta, ignoreLimit, hideEmptyRows, i18nManager.getI18nFormat() );
+        DataQueryParams params = analyticsService.getFromUrl( dimension, filter, aggregationType, measureCriteria, 
+            skipMeta, skipRounding, hierarchyMeta, ignoreLimit, hideEmptyRows, showHierarchy, i18nManager.getI18nFormat() );
 
         contextUtils.configureResponse( response, ContextUtils.CONTENT_TYPE_XML, CacheStrategy.RESPECT_SYSTEM_SETTING );
         Grid grid = analyticsService.getAggregatedDataValues( params, tableLayout, getDimensionsFromParam( columns ), getDimensionsFromParam( rows ) );
@@ -136,12 +140,14 @@
         @RequestParam(required = false) boolean ignoreLimit,
         @RequestParam(required = false) boolean tableLayout,
         @RequestParam(required = false) boolean hideEmptyRows,
+        @RequestParam(required = false) boolean showHierarchy,
         @RequestParam(required = false) String columns,
         @RequestParam(required = false) String rows,
         Model model,
         HttpServletResponse response ) throws Exception
     {
-        DataQueryParams params = analyticsService.getFromUrl( dimension, filter, aggregationType, measureCriteria, skipMeta, skipRounding, hierarchyMeta, ignoreLimit, hideEmptyRows, i18nManager.getI18nFormat() );
+        DataQueryParams params = analyticsService.getFromUrl( dimension, filter, aggregationType, measureCriteria, 
+            skipMeta, skipRounding, hierarchyMeta, ignoreLimit, hideEmptyRows, showHierarchy, i18nManager.getI18nFormat() );
 
         contextUtils.configureResponse( response, ContextUtils.CONTENT_TYPE_HTML, CacheStrategy.RESPECT_SYSTEM_SETTING );
         Grid grid = analyticsService.getAggregatedDataValues( params, tableLayout, getDimensionsFromParam( columns ), getDimensionsFromParam( rows ) );
@@ -160,12 +166,14 @@
         @RequestParam(required = false) boolean ignoreLimit,
         @RequestParam(required = false) boolean tableLayout,
         @RequestParam(required = false) boolean hideEmptyRows,
+        @RequestParam(required = false) boolean showHierarchy,
         @RequestParam(required = false) String columns,
         @RequestParam(required = false) String rows,
         Model model,
         HttpServletResponse response ) throws Exception
     {
-        DataQueryParams params = analyticsService.getFromUrl( dimension, filter, aggregationType, measureCriteria, skipMeta, skipRounding, hierarchyMeta, ignoreLimit, hideEmptyRows, i18nManager.getI18nFormat() );
+        DataQueryParams params = analyticsService.getFromUrl( dimension, filter, aggregationType, measureCriteria, 
+            skipMeta, skipRounding, hierarchyMeta, ignoreLimit, hideEmptyRows, showHierarchy, i18nManager.getI18nFormat() );
 
         contextUtils.configureResponse( response, ContextUtils.CONTENT_TYPE_CSV, CacheStrategy.RESPECT_SYSTEM_SETTING, "data.csv", true );
         Grid grid = analyticsService.getAggregatedDataValues( params, tableLayout, getDimensionsFromParam( columns ), getDimensionsFromParam( rows ) );
@@ -184,12 +192,14 @@
         @RequestParam(required = false) boolean ignoreLimit,
         @RequestParam(required = false) boolean tableLayout,
         @RequestParam(required = false) boolean hideEmptyRows,
+        @RequestParam(required = false) boolean showHierarchy,
         @RequestParam(required = false) String columns,
         @RequestParam(required = false) String rows,
         Model model,
         HttpServletResponse response ) throws Exception
     {
-        DataQueryParams params = analyticsService.getFromUrl( dimension, filter, aggregationType, measureCriteria, skipMeta, skipRounding, hierarchyMeta, ignoreLimit, hideEmptyRows, i18nManager.getI18nFormat() );
+        DataQueryParams params = analyticsService.getFromUrl( dimension, filter, aggregationType, measureCriteria, 
+            skipMeta, skipRounding, hierarchyMeta, ignoreLimit, hideEmptyRows, showHierarchy, i18nManager.getI18nFormat() );
 
         contextUtils.configureResponse( response, ContextUtils.CONTENT_TYPE_EXCEL, CacheStrategy.RESPECT_SYSTEM_SETTING, "data.xls", true );
         Grid grid = analyticsService.getAggregatedDataValues( params, tableLayout, getDimensionsFromParam( columns ), getDimensionsFromParam( rows ) );
@@ -208,12 +218,14 @@
         @RequestParam(required = false) boolean ignoreLimit,
         @RequestParam(required = false) boolean tableLayout,
         @RequestParam(required = false) boolean hideEmptyRows,
+        @RequestParam(required = false) boolean showHierarchy,
         @RequestParam(required = false) String columns,
         @RequestParam(required = false) String rows,
         Model model,
         HttpServletResponse response ) throws Exception
     {
-        DataQueryParams params = analyticsService.getFromUrl( dimension, filter, null, null, true, false, false, false, false, i18nManager.getI18nFormat() );
+        DataQueryParams params = analyticsService.getFromUrl( dimension, filter, null, null, 
+            true, false, false, false, false, false, i18nManager.getI18nFormat() );
 
         contextUtils.configureResponse( response, ContextUtils.CONTENT_TYPE_XML, CacheStrategy.RESPECT_SYSTEM_SETTING, "data.jrxml", false );
         Grid grid = analyticsService.getAggregatedDataValues( params );