Changeset 2042


Ignore:
Timestamp:
Sep 29, 2011, 4:43:26 PM (5 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

File:
1 edited

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 )
Note: See TracChangeset for help on using the changeset viewer.