Ignore:
Timestamp:
Dec 8, 2011, 4:41:06 PM (11 years ago)
Author:
robert@…
Message:
  • Solved issues and added sorting in visualization with no aggregation
  • Updated jquery to 1.7
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/controllers/dbnp/visualization/VisualizeController.groovy

    r2126 r2128  
    340340                // TODO: handle erroneous input data
    341341                def inputData = parseGetDataParams();
    342 
     342               
    343343        if(inputData.columnIds == null || inputData.rowIds == null){
    344344            infoMessage = "Please select data sources for the y- and x-axes."
     
    364364                fields.each {
    365365                        fieldInfo[ it.key ] = parseFieldId( it.value )
    366                        
    367366                        if( fieldInfo[ it.key ] )
    368367                                fieldInfo[ it.key ].fieldType = determineFieldType( study.id, it.value );
     368                               
    369369                }
    370370               
     
    374374                        fieldInfo.group = null;
    375375                }
    376                
     376
     377                println "Fields: "
     378                fieldInfo.each { println it }
     379
    377380                // Fetch all data from the system. data will be in the format:
    378381                //              [ "x": [ 3, 6, null, 10 ], "y": [ "male", "male", "female", "female" ], "group": [ "US", "NL", "NL", "NL" ]
     
    380383                def data = getAllFieldData( study, samples, fields );
    381384
    382                 // Aggregate the data based on the requested aggregation 
     385                println "All Data: "
     386                data.each { println it }
     387
     388                                // Aggregate the data based on the requested aggregation 
    383389                def aggregatedData = aggregateData( data, fieldInfo, inputData.aggregation );
    384390               
     
    572578                // If no aggregation is requested, we just return the original object (but filtering out null values)
    573579                if( aggregation == "none" ) {
    574                         def filteredData = [:];
    575                        
    576                         // Create a copy of the data object
    577                         data.each {
    578                                 filteredData[ it.key ] = it.value;
    579                         }
    580                        
    581                         // Loop through all values and return all null-values (and the same indices on other elements
    582                         fieldInfo.keySet().each { fieldName ->
    583                                 // If values are found, do filtering. If not, skip this one
    584                                 if( fieldInfo[ fieldName ] != null ) {
    585                                         // Find all non-null values in this list
    586                                         def indices = filteredData[ fieldName ].findIndexValues { it != null };
    587                                        
    588                                         // Remove the non-null values from each data object
    589                                         filteredData.each { key, value ->
    590                                                 if( value && value instanceof Collection )
    591                                                         filteredData[ key ] = value[ indices ];
    592                                         }
    593                                 }
    594                         }
    595                          
    596                         return filteredData
     580                        return sortNonAggregatedData( filterNullValues( data ), [ 'x', 'group' ] );
    597581                }
    598582               
     
    629613                        return returnData;
    630614                }
     615        }
     616       
     617        /**
     618         * Sort the data that has not been aggregated by the given columns
     619         * @param data
     620         * @param sortBy
     621         * @return
     622         */
     623        protected def sortNonAggregatedData( data, sortBy ) {
     624                if( !sortBy )
     625                        return data;
     626                       
     627                // First combine the lists within the data
     628                def combined = [];
     629                for( int i = 0; i < data.numValues; i++ ) {
     630                        def element = [:]
     631                        data.each {
     632                                if( it.value instanceof Collection && i < it.value.size() ) {
     633                                        element[ it.key ] = it.value[ i ];
     634                                }
     635                        }
     636                       
     637                        combined << element;
     638                }
     639               
     640                // Now sort the combined element with a comparator
     641                def comparator = { a, b ->
     642                        for( column in sortBy ) {
     643                                if( a[ column ] != null ) {
     644                                        if( a[ column ] != b[ column ] ) {
     645                                                if( a[ column ] instanceof Number )
     646                                                        return a[ column ] <=> b[ column ];
     647                                                else
     648                                                        return a[ column ].toString() <=> b[ column ].toString();
     649                                        }
     650                                }
     651                        }
     652               
     653                        return 0;
     654                }
     655               
     656                combined.sort( comparator as Comparator );
     657               
     658                // Put the elements back again. First empty the original lists
     659                data.each {
     660                        if( it.value instanceof Collection ) {
     661                                it.value = [];
     662                        }
     663                }
     664               
     665                combined.each { element ->
     666                        element.each { key, value ->
     667                                data[ key ] << value;
     668                        }
     669                }
     670
     671                return data;
     672        }
     673       
     674        /**
     675         * Filter null values from the different lists of data. The associated values in other lists will also be removed
     676         * @param data 
     677         * @return      Filtered data.
     678         *
     679         * [ 'x': [0, 2, 4], 'y': [1,null,2] ] will result in [ 'x': [0, 4], 'y': [1, 2] ]
     680         * [ 'x': [0, 2, 4], 'y': [1,null,2], 'z': [4, null, null] ] will result in [ 'x': [0], 'y': [1], 'z': [4] ]
     681         */
     682        protected def filterNullValues( data ) {
     683                def filteredData = [:];
     684               
     685                // Create a copy of the data object
     686                data.each {
     687                        filteredData[ it.key ] = it.value;
     688                }
     689               
     690                // Loop through all values and return all null-values (and the same indices on other elements
     691                int num = filteredData.numValues;
     692                filteredData.keySet().each { fieldName ->
     693                        // If values are found, do filtering. If not, skip this one
     694                        if( filteredData[ fieldName ] != null && filteredData[ fieldName ] instanceof Collection ) {
     695                                // Find all non-null values in this list
     696                                def indices = filteredData[ fieldName ].findIndexValues { it != null };
     697                               
     698                                // Remove the non-null values from each data object
     699                                filteredData.each { key, value ->
     700                                        if( value && value instanceof Collection )
     701                                                filteredData[ key ] = value[ indices ];
     702                                }
     703                               
     704                                // Store the number of values
     705                                num = indices.size();
     706                        }
     707                }
     708               
     709                filteredData.numValues = num;
     710                 
     711                return filteredData
    631712        }
    632713       
     
    14081489     */
    14091490    protected int determineCategoryFromClass(classObject){
    1410         log.trace "Determine category from class: "+classObject+", of class: "+classObject?.class
    1411         if(classObject==java.lang.String){
    1412             return CATEGORICALDATA
    1413         } else {
    1414             return NUMERICALDATA
    1415         }
     1491        log.trace "Determine category from class: " + classObject
     1492        switch( classObject ) {
     1493                        case java.lang.String:
     1494                        case org.dbnp.gdt.Term:
     1495                        case org.dbnp.gdt.TemplateFieldListItem:
     1496                                return CATEGORICALDATA;
     1497                        default:
     1498                                return NUMERICALDATA;
     1499                }
    14161500    }
    14171501
Note: See TracChangeset for help on using the changeset viewer.