Changeset 2042

Show
Ignore:
Timestamp:
29-09-11 16:43:26 (3 years ago)
Author:
robert@…
Message:

Solved issue VIS-13, categories without values are not shown anymore. Also, fixed a bug in VIS-27 in determining the category of a field

Files:
1 modified

Legend:

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

    r2041 r2042  
    319319            groupedData = groupFieldData( inputData.visualizationType, data ); // Don't indicate axis ordering, standard <"x", "y"> will be used 
    320320        } 
     321                 
     322                println "Data: " + data; 
     323                println "Grouped: " + groupedData 
    321324 
    322325        // Format data so it can be rendered as JSON 
     
    505508         */ 
    506509        def groupFieldData( visualizationType, data, groupAxis = "x", valueAxis = "y", errorName = "error", unknownName = "unknown" ) { 
     510                // TODO: Give the user the possibility to change this value in the user interface 
     511                def showEmptyCategories = false; 
     512                 
    507513                // Create a unique list of values in the groupAxis. First flatten the list, since it might be that a 
    508514                // sample belongs to multiple groups. In that case, the group names should not be the lists, but the list 
     
    514520                                                .flatten() 
    515521                                                .unique { it == null ? "null" : it.class.name + it.toString() } 
     522                                                 
    516523                // Make sure the null category is last 
    517524                groups = groups.findAll { it != null } + groups.findAll { it == null } 
    518                 // Gather names for the groups. Most of the times, the group names are just the names, only with 
    519                 // a null value, the unknownName must be used 
    520                 def groupNames = groups.collect { it != null ? it : unknownName } 
     525                 
     526                println "TEST"; 
     527                groups.each { println "" + it + " - " + it?.class?.toString() } 
     528                 
    521529                // Generate the output object 
    522530                def outputData = [:] 
    523531                outputData[ valueAxis ] = []; 
    524532                outputData[ errorName ] = []; 
    525                 outputData[ groupAxis ] = groupNames; 
     533                outputData[ groupAxis ] = []; 
     534                 
    526535                // Loop through all groups, and gather the values for this group 
    527         // A visualization of type 'table' is a special case. There, the counts of two combinations of 'groupAxis' and 'valueAxis' items are computed 
    528         if(visualizationType=='table'){ 
     536        // A visualization of type 'table' is a special case. There, the counts of two combinations of 'groupAxis' 
     537                // and 'valueAxis' items are computed 
     538        if( visualizationType=='table' ){ 
    529539            // For each 'valueAxis' item and 'groupAxis' item combination, count how often they appear together. 
    530540            def counts = [:] 
     541                         
    531542            // The 'counts' list uses keys like this: ['item1':group, 'item2':value] 
    532543            // The value will be an integer (the count) 
     
    539550                } 
    540551            } 
    541             outputData[valueAxis] =  data[ valueAxis ] 
     552             
     553                        def valueData =  data[ valueAxis ] 
    542554                                        .flatten() 
    543555                                        .unique { it == null ? "null" : it.class.name + it.toString() } 
     556                                                                                                         
     557                        // Now we will first check whether any of the categories is empty. If some of the rows 
     558                        // or columns are empty, don't include them in the output 
     559                        if( !showEmptyCategories ) { 
     560                                groups.eachWithIndex { group, index -> 
     561                                        if( counts.findAll { it.key.item1 == group } ) 
     562                                                outputData[groupAxis] << group 
     563                                } 
     564                                 
     565                                valueData.each { value -> 
     566                                        if( counts.findAll { it.key.item2 == value } ) 
     567                                                outputData[valueAxis] << value 
     568                                } 
     569                        } else { 
     570                                outputData[groupAxis] = groups.collect { it != null ? it : unknownName } 
     571                                ouputData[valueAxis] = valueData 
     572                        } 
     573                                                                                                                                 
    544574            // Because we are collecting counts, we do not set the 'errorName' item of the 'outputData' map. 
    545             // We do however set the 'data' map to contain the counts. We set it in such a manner that it has a 'table' layout with respect to 'groupAxis' and 'valueAxis'. 
     575            // We do however set the 'data' map to contain the counts. We set it in such a manner that it has  
     576                        // a 'table' layout with respect to 'groupAxis' and 'valueAxis'. 
    546577            def rows = [] 
    547578            outputData[groupAxis].each{ group -> 
     
    556587            } 
    557588            outputData['data']= rows 
     589                         
     590                        // Convert groups to group names 
     591                        outputData[ groupAxis ] = outputData[ groupAxis ].collect { it != null ? it : unknownName } 
    558592        } else { 
    559593            groups.each { group -> 
    560594                // Find the indices of the samples that belong to this group. if a sample belongs to multiple groups (i.e. if 
    561595                // the samples groupAxis contains multiple values, is a collection), the value should be used in all groups. 
    562                 def indices= data[ groupAxis ].findIndexValues { it instanceof Collection ? it.contains( group ) : it == group }; 
    563                 def values = data[ valueAxis ][ indices ] 
    564  
    565                 def dataForGroup = computeMeanAndError( values ); 
    566  
    567                 outputData[ valueAxis ] << dataForGroup.value 
    568                 outputData[ errorName ] << dataForGroup.error 
    569             } 
    570         } 
     596                def indices = data[ groupAxis ].findIndexValues { it instanceof Collection ? it.contains( group ) : it == group }; 
     597                def values  = data[ valueAxis ][ indices ] 
     598 
     599                                // The computation for mean and error will return null if no (numerical) values are found 
     600                                // In that case, the user won't see this category 
     601                                def dataForGroup = computeMeanAndError( values ); 
     602 
     603                                if( showEmptyCategories || dataForGroup.value != null ) { 
     604                                        // Gather names for the groups. Most of the times, the group names are just the names, only with 
     605                                        // a null value, the unknownName must be used 
     606                                        outputData[ groupAxis ] << ( group != null ? group : unknownName ) 
     607                        outputData[ valueAxis ] << dataForGroup.value ?: 0 
     608                        outputData[ errorName ] << dataForGroup.error ?: 0 
     609                                } 
     610            } 
     611        } 
     612                 
    571613                return outputData 
    572614        } 
     
    840882                        return sumOfValues / sizeOfValues; 
    841883                else 
    842                         return 0;  
     884                        return null;  
    843885        } 
    844886 
     
    870912           return std / Math.sqrt( sizeOfValues ); 
    871913       } else { 
    872            return 0; 
     914           return null; 
    873915       } 
    874916    } 
     
    9661008            if( parsedField.source == "GSCF" ) { 
    9671009                if(parsedField.id.isNumber()){ 
    968                         return determineCategoryFromTemplateField(parsedField.id) 
     1010                        return determineCategoryFromTemplateFieldId(parsedField.id) 
    9691011                } else { // Domainfield or memberclass 
    9701012                    def callback = domainObjectCallback( parsedField.type )