← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 17340: Implemented support for text values in analytics

 

------------------------------------------------------------
revno: 17340
committer: Lars Helge Overland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Sun 2014-11-02 19:24:32 -0500
message:
  Implemented support for text values in analytics
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseAnalyticalObject.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/datasetreport/DataSetReportStore.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/i18n/I18nFormat.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/reporttable/ReportTable.java
  dhis-2/dhis-api/src/test/java/org/hisp/dhis/common/BaseAnalyticalObjectTest.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/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-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/impl/DefaultDataSetReportService.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/impl/DefaultReportTableService.java
  dhis-2/dhis-services/dhis-service-reporting/src/test/java/org/hisp/dhis/reporttable/ReportTableGridTest.java
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/grid/GridUtils.java
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/MathUtils.java
  dhis-2/dhis-web/dhis-web-reporting/src/main/java/org/hisp/dhis/reporting/dataset/action/GenerateDataSetReportAction.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/BaseAnalyticalObject.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseAnalyticalObject.java	2014-10-25 08:28:23 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseAnalyticalObject.java	2014-11-03 00:24:32 +0000
@@ -643,9 +643,9 @@
      * 
      * @param valueMap the mapping of keys and values.
      */
-    public static void sortKeys( Map<String, Double> valueMap )
+    public static void sortKeys( Map<String, Object> valueMap )
     {
-        Map<String, Double> map = new HashMap<>();
+        Map<String, Object> map = new HashMap<>();
 
         for ( String key : valueMap.keySet() )
         {

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/datasetreport/DataSetReportStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/datasetreport/DataSetReportStore.java	2014-10-28 10:29:40 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/datasetreport/DataSetReportStore.java	2014-11-03 00:24:32 +0000
@@ -42,11 +42,11 @@
 {
     final String SEPARATOR = "-";
     
-    Map<String, Double> getAggregatedValues( DataSet dataSet, Period period, OrganisationUnit unit, Set<String> dimensions, boolean rawData );
+    Map<String, Object> getAggregatedValues( DataSet dataSet, Period period, OrganisationUnit unit, Set<String> dimensions, boolean rawData );
 
-    Map<String, Double> getAggregatedSubTotals( DataSet dataSet, Period period, OrganisationUnit unit, Set<String> dimensions );
-    
-    Map<String, Double> getAggregatedTotals( DataSet dataSet, Period period, OrganisationUnit unit, Set<String> dimensions );
-    
-    Map<String, Double> getAggregatedIndicatorValues( DataSet dataSet, Period period, OrganisationUnit unit, Set<String> dimensions );
+    Map<String, Object> getAggregatedSubTotals( DataSet dataSet, Period period, OrganisationUnit unit, Set<String> dimensions );
+    
+    Map<String, Object> getAggregatedTotals( DataSet dataSet, Period period, OrganisationUnit unit, Set<String> dimensions );
+    
+    Map<String, Object> getAggregatedIndicatorValues( DataSet dataSet, Period period, OrganisationUnit unit, Set<String> dimensions );
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/i18n/I18nFormat.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/i18n/I18nFormat.java	2014-11-02 22:24:35 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/i18n/I18nFormat.java	2014-11-03 00:24:32 +0000
@@ -30,6 +30,7 @@
 
 import java.text.DateFormat;
 import java.text.DateFormatSymbols;
+import java.text.DecimalFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
@@ -47,6 +48,9 @@
  */
 public class I18nFormat
 {
+    private static final DecimalFormat FORMAT_VALUE = new DecimalFormat( "#.#" ); // Fixed for now
+    private static final String EMPTY = "";
+    
     private static final String INVALID_DATE = "Invalid date format";
 
     public static final String FORMAT_DATE = "yyyy-MM-dd";
@@ -241,7 +245,7 @@
 
         if ( !dayPattern )
         {
-            // set day to first of month, so that we don't overflow when we convert to jdk date
+            // Set day to first of month to not overflow when converting to JDK date
             start.setDay( 1 );
             end.setDay( 1 );
 
@@ -263,7 +267,28 @@
             return INVALID_DATE;
         }
     }
-
+    /**
+     * Formats value. Returns empty string if value is null. Returns NaN if value
+     * is not a number.
+     *
+     * @param value the value to format.
+     */
+    public String formatValue( Object value )
+    {
+        if ( value == null )
+        {
+            return EMPTY;
+        }
+        
+        try
+        {
+            return FORMAT_VALUE.format( value );
+        }
+        catch ( IllegalArgumentException ex )
+        {
+            return String.valueOf( value );
+        }
+    }
     // -------------------------------------------------------------------------
     // Support methods
     // -------------------------------------------------------------------------

=== 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	2014-10-16 06:17:19 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/reporttable/ReportTable.java	2014-11-03 00:24:32 +0000
@@ -575,7 +575,7 @@
      * @return a grid.
      */
     @SuppressWarnings("unchecked")
-    public Grid getGrid( Grid grid, Map<String, Double> valueMap, boolean paramColumns )
+    public Grid getGrid( Grid grid, Map<String, Object> valueMap, boolean paramColumns )
     {
         valueMap = new HashMap<>( valueMap );
         
@@ -669,7 +669,7 @@
             {
                 String key = getIdentifier( column, row );
                 
-                Double value = valueMap.get( key );
+                Object value = valueMap.get( key );
                 
                 grid.addValue( value );
                 

=== modified file 'dhis-2/dhis-api/src/test/java/org/hisp/dhis/common/BaseAnalyticalObjectTest.java'
--- dhis-2/dhis-api/src/test/java/org/hisp/dhis/common/BaseAnalyticalObjectTest.java	2014-08-15 07:40:20 +0000
+++ dhis-2/dhis-api/src/test/java/org/hisp/dhis/common/BaseAnalyticalObjectTest.java	2014-11-03 00:24:32 +0000
@@ -51,7 +51,7 @@
     @Test
     public void testSortKeys()
     {
-        Map<String, Double> valueMap = new HashMap<>();
+        Map<String, Object> valueMap = new HashMap<>();
         
         valueMap.put( "b1-a1-c1", 1d );
         valueMap.put( "a2-c2-b2", 2d );
@@ -66,10 +66,15 @@
         assertTrue( valueMap.containsKey( "a3-b3-c3" ) );
         assertTrue( valueMap.containsKey( "a4-b4-c4" ) );
         
-        assertEquals( 1d, valueMap.get( "a1-b1-c1" ), 0.01 );
-        assertEquals( 2d, valueMap.get( "a2-b2-c2" ), 0.01 );
-        assertEquals( 3d, valueMap.get( "a3-b3-c3" ), 0.01 );
-        assertEquals( 4d, valueMap.get( "a4-b4-c4" ), 0.01 );
+        Object d1 = 1d;
+        Object d2 = 2d;
+        Object d3 = 3d;
+        Object d4 = 4d;
+        
+        assertEquals( d1, valueMap.get( "a1-b1-c1" ) );
+        assertEquals( d2, valueMap.get( "a2-b2-c2" ) );
+        assertEquals( d3, valueMap.get( "a3-b3-c3" ) );
+        assertEquals( d4, valueMap.get( "a4-b4-c4" ) );
         
         valueMap = new HashMap<>();
         
@@ -82,8 +87,8 @@
         assertTrue( valueMap.containsKey( "b1" ) );
         assertTrue( valueMap.containsKey( "b2" ) );
         
-        assertEquals( 1d, valueMap.get( "b1" ), 0.01 );
-        assertEquals( 2d, valueMap.get( "b2" ), 0.01 );
+        assertEquals( d1, valueMap.get( "b1" ) );
+        assertEquals( d2, valueMap.get( "b2" ) );
 
         valueMap = new HashMap<>();
         

=== 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	2014-10-27 18:50:54 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/AnalyticsService.java	2014-11-03 00:24:32 +0000
@@ -130,7 +130,7 @@
      * @param params the DataQueryParams.
      * @return a mapping of dimensional items and aggregated data values.
      */
-    Map<String, Double> getAggregatedDataValueMapping( DataQueryParams params );
+    Map<String, Object> getAggregatedDataValueMapping( DataQueryParams params );
 
     /**
      * Generates a mapping where the key represents the dimensional item identifiers
@@ -141,7 +141,7 @@
      * @param format the I18nFormat, can be null.
      * @return a mapping of dimensional items and aggregated data values.
      */
-    Map<String, Double> getAggregatedDataValueMapping( AnalyticalObject object, I18nFormat format );
+    Map<String, Object> getAggregatedDataValueMapping( AnalyticalObject object, I18nFormat format );
 
     /**
      * Creates a data query parameter object from the given URL.

=== 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	2014-11-02 21:38:37 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java	2014-11-03 00:24:32 +0000
@@ -576,13 +576,13 @@
         reportTable.setHideEmptyRows( params.isHideEmptyRows() );
         reportTable.setShowHierarchy( params.isShowHierarchy() );
 
-        Map<String, Double> valueMap = getAggregatedDataValueMapping( grid );
+        Map<String, Object> valueMap = getAggregatedDataValueMapping( grid );
         
         return reportTable.getGrid( new ListGrid( grid.getMetaData() ), valueMap, false );
     }
 
     @Override
-    public Map<String, Double> getAggregatedDataValueMapping( DataQueryParams params )
+    public Map<String, Object> getAggregatedDataValueMapping( DataQueryParams params )
     {
         Grid grid = getAggregatedDataValues( params );
 
@@ -590,7 +590,7 @@
     }
 
     @Override
-    public Map<String, Double> getAggregatedDataValueMapping( AnalyticalObject object, I18nFormat format )
+    public Map<String, Object> getAggregatedDataValueMapping( AnalyticalObject object, I18nFormat format )
     {
         DataQueryParams params = getFromAnalyticalObject( object, format );
 
@@ -636,9 +636,9 @@
      * @param grid the grid.
      * @return a mapping between item identifiers and aggregated values.
      */
-    private Map<String, Double> getAggregatedDataValueMapping( Grid grid )
+    private Map<String, Object> getAggregatedDataValueMapping( Grid grid )
     {
-        Map<String, Double> map = new HashMap<>();
+        Map<String, Object> map = new HashMap<>();
 
         int metaCols = grid.getWidth() - 1;
         int valueIndex = grid.getWidth() - 1;
@@ -654,7 +654,7 @@
 
             key.deleteCharAt( key.length() - 1 );
 
-            Double value = (Double) row.get( valueIndex );
+            Object value = row.get( valueIndex );
 
             map.put( key.toString(), value );
         }

=== 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	2014-10-27 18:50:54 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/MockAnalyticsService.java	2014-11-03 00:24:32 +0000
@@ -49,9 +49,9 @@
 public class MockAnalyticsService
     implements AnalyticsService
 {
-    private Map<String, Double> valueMap;
+    private Map<String, Object> valueMap;
 
-    public MockAnalyticsService( Map<String, Double> valueMap )
+    public MockAnalyticsService( Map<String, Object> valueMap )
     {
         this.valueMap = valueMap;
     }
@@ -69,13 +69,13 @@
     }
 
     @Override
-    public Map<String, Double> getAggregatedDataValueMapping( DataQueryParams params )
+    public Map<String, Object> getAggregatedDataValueMapping( DataQueryParams params )
     {
         return valueMap;
     }
 
     @Override
-    public Map<String, Double> getAggregatedDataValueMapping( AnalyticalObject object, I18nFormat format )
+    public Map<String, Object> getAggregatedDataValueMapping( AnalyticalObject object, I18nFormat format )
     {
         return valueMap;
     }

=== 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	2014-10-16 06:17:19 +0000
+++ dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/chart/impl/DefaultChartService.java	2014-11-03 00:24:32 +0000
@@ -794,7 +794,7 @@
 
     private CategoryDataset[] getCategoryDataSet( BaseChart chart )
     {
-        Map<String, Double> valueMap = new HashMap<>();
+        Map<String, Object> valueMap = new HashMap<>();
         
         if ( chart.isAnalyticsType( AnalyticsType.AGGREGATE ) )
         {
@@ -839,13 +839,15 @@
                 
                 key = BaseAnalyticalObject.sortKey( key );
 
-                Double value = valueMap.get( key );
+                Object object = valueMap.get( key );
+                
+                Number value = object != null && object instanceof Number ? (Number) object : null;
 
                 regularDataSet.addValue( value, series.getShortName(), category.getShortName() );
 
-                if ( chart.isRegression() && value != null && !MathUtils.isEqual( value, MathUtils.ZERO ) )
+                if ( chart.isRegression() && value != null && value instanceof Double && !MathUtils.isEqual( (Double) value, MathUtils.ZERO ) )
                 {
-                    regression.addData( categoryIndex, value );
+                    regression.addData( categoryIndex, (Double) value );
                 }
             }
 

=== modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/impl/DefaultDataSetReportService.java'
--- dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/impl/DefaultDataSetReportService.java	2014-11-02 22:24:35 +0000
+++ dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/impl/DefaultDataSetReportService.java	2014-11-03 00:24:32 +0000
@@ -109,11 +109,11 @@
     public String getCustomDataSetReport( DataSet dataSet, Period period, OrganisationUnit unit, Set<String> dimensions,
         boolean selectedUnitOnly, I18nFormat format )
     {
-        Map<String, Double> valueMap = dataSetReportStore.getAggregatedValues( dataSet, period, unit, dimensions, selectedUnitOnly );
+        Map<String, Object> valueMap = dataSetReportStore.getAggregatedValues( dataSet, period, unit, dimensions, selectedUnitOnly );
         
         valueMap.putAll( dataSetReportStore.getAggregatedTotals( dataSet, period, unit, dimensions ) );
         
-        Map<String, Double> indicatorValueMap = dataSetReportStore.getAggregatedIndicatorValues( dataSet, period, unit, dimensions );
+        Map<String, Object> indicatorValueMap = dataSetReportStore.getAggregatedIndicatorValues( dataSet, period, unit, dimensions );
         
         return prepareReportContent( dataSet.getDataEntryForm(), valueMap, indicatorValueMap, format );
     }
@@ -141,9 +141,9 @@
         List<Section> sections = new ArrayList<>( dataSet.getSections() );
         Collections.sort( sections, new SectionOrderComparator() );
 
-        Map<String, Double> valueMap = dataSetReportStore.getAggregatedValues( dataSet, period, unit, dimensions, selectedUnitOnly );
-        Map<String, Double> subTotalMap = dataSetReportStore.getAggregatedSubTotals( dataSet, period, unit, dimensions );
-        Map<String, Double> totalMap = dataSetReportStore.getAggregatedTotals( dataSet, period, unit, dimensions );
+        Map<String, Object> valueMap = dataSetReportStore.getAggregatedValues( dataSet, period, unit, dimensions, selectedUnitOnly );
+        Map<String, Object> subTotalMap = dataSetReportStore.getAggregatedSubTotals( dataSet, period, unit, dimensions );
+        Map<String, Object> totalMap = dataSetReportStore.getAggregatedTotals( dataSet, period, unit, dimensions );
 
         List<Grid> grids = new ArrayList<>();
         
@@ -208,7 +208,7 @@
                     attributes.put( ATTR_DE, dataElement.getUid() );
                     attributes.put( ATTR_CO, optionCombo.getUid() );
                     
-                    Double value = null;
+                    Object value = null;
 
                     if ( selectedUnitOnly )
                     {
@@ -228,7 +228,7 @@
                 {
                     for ( DataElementCategoryOption categoryOption : categoryCombo.getCategoryOptions() )
                     {
-                        Double value = subTotalMap.get( dataElement.getUid() + SEPARATOR + categoryOption.getUid() );
+                        Object value = subTotalMap.get( dataElement.getUid() + SEPARATOR + categoryOption.getUid() );
 
                         grid.addValue( new GridValue( value ) );
                     }
@@ -236,7 +236,7 @@
 
                 if ( categoryCombo.doTotal() && !selectedUnitOnly ) // Total
                 {
-                    Double value = totalMap.get( String.valueOf( dataElement.getUid() ) );
+                    Object value = totalMap.get( String.valueOf( dataElement.getUid() ) );
 
                     grid.addValue( new GridValue( value ) );
                 }
@@ -289,8 +289,8 @@
      * @return data entry form HTML code populated with aggregated data in the
      *         input fields.
      */
-    private String prepareReportContent( DataEntryForm dataEntryForm, Map<String, Double> dataValues,
-        Map<String, Double> indicatorValues, I18nFormat format )
+    private String prepareReportContent( DataEntryForm dataEntryForm, Map<String, Object> dataValues,
+        Map<String, Object> indicatorValues, I18nFormat format )
     {
         StringBuffer buffer = new StringBuffer();
 
@@ -321,7 +321,7 @@
                 String dataElementId = identifierMatcher.group( 1 );
                 String optionComboId = identifierMatcher.group( 2 );
 
-                Double dataValue = dataValues.get( dataElementId + SEPARATOR + optionComboId );
+                Object dataValue = dataValues.get( dataElementId + SEPARATOR + optionComboId );
 
                 String value = "<span class=\"val\" data-de=\"" + dataElementId + "\" data-co=\"" + optionComboId + "\">" + trimToEmpty( String.valueOf( getRoundedObject( dataValue ) ) ) + "</span>";
                 
@@ -331,7 +331,7 @@
             {
                 String dataElementId = dataElementTotalMatcher.group( 1 );
                 
-                Double dataValue = dataValues.get( dataElementId );
+                Object dataValue = dataValues.get( dataElementId );
 
                 inputMatcher.appendReplacement( buffer, trimToEmpty( String.valueOf( getRoundedObject( dataValue ) ) ) );
             }
@@ -339,7 +339,7 @@
             {
                 String indicatorId = indicatorMatcher.group( 1 );
 
-                Double indicatorValue = indicatorValues.get( indicatorId );
+                Object indicatorValue = indicatorValues.get( indicatorId );
 
                 inputMatcher.appendReplacement( buffer, trimToEmpty( String.valueOf( getRoundedObject( indicatorValue ) ) ) );
             }

=== 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	2014-10-28 10:29:40 +0000
+++ dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/jdbc/AnalyticsDataSetReportStore.java	2014-11-03 00:24:32 +0000
@@ -66,7 +66,7 @@
     // -------------------------------------------------------------------------
 
     @Override
-    public Map<String, Double> getAggregatedValues( DataSet dataSet, Period period, OrganisationUnit unit, 
+    public Map<String, Object> getAggregatedValues( DataSet dataSet, Period period, OrganisationUnit unit, 
         Set<String> dimensions, boolean rawData )
     {
         List<DataElement> dataElements = new ArrayList<>( dataSet.getDataElements() );
@@ -90,11 +90,11 @@
             params.setFilters( analyticsService.getDimensionalObjects( dimensions, null ) );
         }
         
-        Map<String, Double> map = analyticsService.getAggregatedDataValueMapping( params );
-        
-        Map<String, Double> dataMap = new HashMap<>();
-        
-        for ( Entry<String, Double> entry : map.entrySet() )
+        Map<String, Object> map = analyticsService.getAggregatedDataValueMapping( params );
+        
+        Map<String, Object> dataMap = new HashMap<>();
+        
+        for ( Entry<String, Object> entry : map.entrySet() )
         {
             String[] split = entry.getKey().split( SEPARATOR );            
             dataMap.put( split[0] + SEPARATOR + split[3], entry.getValue() );
@@ -104,9 +104,9 @@
     }
 
     @Override
-    public Map<String, Double> getAggregatedSubTotals( DataSet dataSet, Period period, OrganisationUnit unit, Set<String> dimensions )
+    public Map<String, Object> getAggregatedSubTotals( DataSet dataSet, Period period, OrganisationUnit unit, Set<String> dimensions )
     {
-        Map<String, Double> dataMap = new HashMap<>();
+        Map<String, Object> dataMap = new HashMap<>();
         
         for ( Section section : dataSet.getSections() )
         {
@@ -139,9 +139,9 @@
                     params.setFilters( analyticsService.getDimensionalObjects( dimensions, null ) );
                 }
                 
-                Map<String, Double> map = analyticsService.getAggregatedDataValueMapping( params );
+                Map<String, Object> map = analyticsService.getAggregatedDataValueMapping( params );
                 
-                for ( Entry<String, Double> entry : map.entrySet() )
+                for ( Entry<String, Object> entry : map.entrySet() )
                 {
                     String[] split = entry.getKey().split( SEPARATOR );            
                     dataMap.put( split[0] + SEPARATOR + split[3], entry.getValue() );
@@ -153,7 +153,7 @@
     }
 
     @Override
-    public Map<String, Double> getAggregatedTotals( DataSet dataSet, Period period, OrganisationUnit unit, Set<String> dimensions )
+    public Map<String, Object> getAggregatedTotals( DataSet dataSet, Period period, OrganisationUnit unit, Set<String> dimensions )
     {
         List<DataElement> dataElements = new ArrayList<>( dataSet.getDataElements() );
 
@@ -175,11 +175,11 @@
             params.setFilters( analyticsService.getDimensionalObjects( dimensions, null ) );
         }
         
-        Map<String, Double> map = analyticsService.getAggregatedDataValueMapping( params );
+        Map<String, Object> map = analyticsService.getAggregatedDataValueMapping( params );
 
-        Map<String, Double> dataMap = new HashMap<>();
+        Map<String, Object> dataMap = new HashMap<>();
         
-        for ( Entry<String, Double> entry : map.entrySet() )
+        for ( Entry<String, Object> entry : map.entrySet() )
         {
             String[] split = entry.getKey().split( SEPARATOR );            
             dataMap.put( split[0], entry.getValue() );
@@ -189,7 +189,7 @@
     }
 
     @Override
-    public Map<String, Double> getAggregatedIndicatorValues( DataSet dataSet, Period period, OrganisationUnit unit, Set<String> dimensions )
+    public Map<String, Object> getAggregatedIndicatorValues( DataSet dataSet, Period period, OrganisationUnit unit, Set<String> dimensions )
     {
         List<Indicator> indicators = new ArrayList<>( dataSet.getIndicators() );
         
@@ -209,11 +209,11 @@
             params.setFilters( analyticsService.getDimensionalObjects( dimensions, null ) );
         }
         
-        Map<String, Double> map = analyticsService.getAggregatedDataValueMapping( params );
+        Map<String, Object> map = analyticsService.getAggregatedDataValueMapping( params );
 
-        Map<String, Double> dataMap = new HashMap<>();
+        Map<String, Object> dataMap = new HashMap<>();
         
-        for ( Entry<String, Double> entry : map.entrySet() )
+        for ( Entry<String, Object> entry : map.entrySet() )
         {
             String[] split = entry.getKey().split( SEPARATOR );            
             dataMap.put( split[0], entry.getValue() );

=== modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/reporttable/impl/DefaultReportTableService.java'
--- dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/reporttable/impl/DefaultReportTableService.java	2014-10-16 06:17:19 +0000
+++ dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/reporttable/impl/DefaultReportTableService.java	2014-11-03 00:24:32 +0000
@@ -130,7 +130,7 @@
         
         reportTable.init( currentUserService.getCurrentUser(), reportingPeriod, organisationUnit, atLevels, inGroups, format );
 
-        Map<String, Double> valueMap = analyticsService.getAggregatedDataValueMapping( reportTable, format );
+        Map<String, Object> valueMap = analyticsService.getAggregatedDataValueMapping( reportTable, format );
 
         return reportTable.getGrid( new ListGrid(), valueMap, true );
     }

=== modified file 'dhis-2/dhis-services/dhis-service-reporting/src/test/java/org/hisp/dhis/reporttable/ReportTableGridTest.java'
--- dhis-2/dhis-services/dhis-service-reporting/src/test/java/org/hisp/dhis/reporttable/ReportTableGridTest.java	2014-10-07 13:46:29 +0000
+++ dhis-2/dhis-services/dhis-service-reporting/src/test/java/org/hisp/dhis/reporttable/ReportTableGridTest.java	2014-11-03 00:24:32 +0000
@@ -117,7 +117,7 @@
     private BatchHandlerFactory batchHandlerFactory;
     
     
-    private Map<String, Double> valueMap;
+    private Map<String, Object> valueMap;
     
     private List<DataElement> dataElements;
     private List<DataElementCategoryOptionCombo> categoryOptionCombos;

=== modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/grid/GridUtils.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/grid/GridUtils.java	2014-10-02 17:01:16 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/grid/GridUtils.java	2014-11-03 00:24:32 +0000
@@ -28,7 +28,6 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import static org.apache.commons.lang.StringUtils.trimToEmpty;
 import static org.hisp.dhis.common.DimensionalObject.DIMENSION_SEP;
 import static org.hisp.dhis.system.util.CsvUtils.NEWLINE;
 import static org.hisp.dhis.system.util.CsvUtils.SEPARATOR_B;
@@ -618,9 +617,9 @@
      * @param valueIndex the index of the column holding the value, must be numeric.
      * @return a meta string to value object mapping.
      */
-    public static Map<String, Double> getMetaValueMapping( Grid grid, int valueIndex )
+    public static Map<String, Object> getMetaValueMapping( Grid grid, int valueIndex )
     {
-        Map<String, Double> map = new HashMap<>();
+        Map<String, Object> map = new HashMap<>();
         
         List<Integer> metaIndexes = grid.getMetaColumnIndexes();
 
@@ -630,7 +629,7 @@
             
             String key = TextUtils.join( metaDataRowItems, DIMENSION_SEP, NameableObjectUtils.NULL_REPLACEMENT );
             
-            map.put( key, Double.parseDouble( trimToEmpty( String.valueOf( row.get( valueIndex ) ) ) ) );
+            map.put( key, row.get( valueIndex ) );
         }
         
         return map;

=== modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/MathUtils.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/MathUtils.java	2014-11-02 22:04:54 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/MathUtils.java	2014-11-03 00:24:32 +0000
@@ -460,8 +460,8 @@
         }
         
         return Math.abs( d1 - d2 ) < TOLERANCE;
-    }
-    
+    }    
+
     /**
      * Tests whether the two decimal numbers are equal with a tolerance of 0.01.
      * 

=== modified file 'dhis-2/dhis-web/dhis-web-reporting/src/main/java/org/hisp/dhis/reporting/dataset/action/GenerateDataSetReportAction.java'
--- dhis-2/dhis-web/dhis-web-reporting/src/main/java/org/hisp/dhis/reporting/dataset/action/GenerateDataSetReportAction.java	2014-10-28 10:29:40 +0000
+++ dhis-2/dhis-web/dhis-web-reporting/src/main/java/org/hisp/dhis/reporting/dataset/action/GenerateDataSetReportAction.java	2014-11-03 00:24:32 +0000
@@ -281,7 +281,7 @@
         {
             grids = dataSetReportService.getDefaultDataSetReport( selectedDataSet, selectedPeriod, selectedOrgunit, dimension, selectedUnitOnly, format, i18n );
         }
-        
+                
         return type != null ? type : dataSetType;
     }
 }