Changeset 2037


Ignore:
Timestamp:
Sep 27, 2011, 2:35:38 PM (6 years ago)
Author:
taco@…
Message:

visualization/VisualizeController.groovy, added support for visualizationType 'table'

File:
1 edited

Legend:

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

    r2036 r2037  
    303303        def groupedData
    304304        if(inputData.visualizationType=='horizontal_barchart'){
    305             groupedData = groupFieldData( data, "y", "x" ); // Indicate non-standard axis ordering
     305            groupedData = groupFieldData( inputData.visualizationType, data, "y", "x" ); // Indicate non-standard axis ordering
    306306        } else {
    307             groupedData = groupFieldData( data ); // Don't indicate axis ordering, standard <"x", "y"> will be used
     307            groupedData = groupFieldData( inputData.visualizationType, data ); // Don't indicate axis ordering, standard <"x", "y"> will be used
    308308        }
    309309   
     
    472472         * Group the field data on the values of the specified axis. For example, for a bar chart, the values
    473473         * on the x-axis should be grouped. Currently, the values for each group are averaged, and the standard
    474          * error of the mean is returned in the 'error' property
     474         * error of the mean is returned in the 'error' property
     475     * @param visualizationType Some types require a different formatting/grouping of the data, such as 'table'
    475476         * @param data          Data for both group- and value axis. The output of getAllFieldData fits this input
    476477         * @param groupAxis     Name of the axis to group on. Defaults to "x"
     
    487488         *                                      group axis are combined into a 'unknown' category.
    488489         */
    489         def groupFieldData( data, groupAxis = "x", valueAxis = "y", errorName = "error", unknownName = "unknown" ) {
     490        def groupFieldData( visualizationType, data, groupAxis = "x", valueAxis = "y", errorName = "error", unknownName = "unknown" ) {
    490491                // Create a unique list of values in the groupAxis. First flatten the list, since it might be that a
    491492                // sample belongs to multiple groups. In that case, the group names should not be the lists, but the list
     
    507508                outputData[ errorName ] = [];
    508509                outputData[ groupAxis ] = groupNames;
    509                
    510510                // Loop through all groups, and gather the values for this group
    511                 groups.each { group ->
    512                         // Find the indices of the samples that belong to this group. if a sample belongs to multiple groups (i.e. if
    513                         // the samples groupAxis contains multiple values, is a collection), the value should be used in all groups.
    514                         def indices= data[ groupAxis ].findIndexValues { it instanceof Collection ? it.contains( group ) : it == group };
    515                         def values = data[ valueAxis ][ indices ]
    516                        
    517                         def dataForGroup = computeMeanAndError( values );
    518                        
    519                         outputData[ valueAxis ] << dataForGroup.value
    520                         outputData[ errorName ] << dataForGroup.error
    521                 }
     511        // A visualization of type 'table' is a special case. There, the counts of two combinations of 'groupAxis' and 'valueAxis' items are computed
     512        if(visualizationType=='table'){
     513            // For each 'valueAxis' item and 'groupAxis' item combination, count how often they appear together.
     514            def counts = [:]
     515            // The 'counts' list uses keys like this: ['item1':group, 'item2':value]
     516            // The value will be an integer (the count)
     517            data[ groupAxis ].eachWithIndex { group, index ->
     518                def value =  data[ valueAxis ][index]
     519                if(!counts.get(['item1':group, 'item2':value])){
     520                    counts[['item1':group, 'item2':value]] = 1
     521                } else {
     522                    counts[['item1':group, 'item2':value]] = counts[['item1':group, 'item2':value]] + 1
     523                }
     524            }
     525            outputData[valueAxis] =  data[ valueAxis ]
     526                                        .flatten()
     527                                        .unique { it == null ? "null" : it.class.name + it.toString() }
     528            // Because we are collecting counts, we do not set the 'errorName' item of the 'outputData' map.
     529            // 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'.
     530            def rows = []
     531            outputData[groupAxis].each{ group ->
     532                def row = []
     533                outputData[valueAxis].each{ value ->
     534                    row << counts[['item1':group, 'item2':value]]
     535                }
     536                while(row.contains(null)){
     537                    row[row.indexOf(null)] = 0
     538                } // 'null' should count as '0'. Items of count zero have never been added to the 'counts' list and as such will appear as a 'null' value.
     539                if(row!=[]) rows << row
     540            }
     541            outputData['data']= rows
     542        } else {
     543            groups.each { group ->
     544                // Find the indices of the samples that belong to this group. if a sample belongs to multiple groups (i.e. if
     545                // the samples groupAxis contains multiple values, is a collection), the value should be used in all groups.
     546                def indices= data[ groupAxis ].findIndexValues { it instanceof Collection ? it.contains( group ) : it == group };
     547                def values = data[ valueAxis ][ indices ]
     548
     549                def dataForGroup = computeMeanAndError( values );
     550
     551                outputData[ valueAxis ] << dataForGroup.value
     552                outputData[ errorName ] << dataForGroup.error
     553            }
     554        }
    522555                return outputData
    523556        }
     
    552585        // TODO: Handle name and unit of fields correctly
    553586        if(type=="table"){
    554             // TODO: implement this
    555             def xAxis = groupedData[ groupAxis ].collect { it.toString() };
    556587            def yName = parseFieldId( fields[ valueAxis ] ).name;
    557588
    558589            def return_data = [:]
    559590            return_data[ "type" ] = type
    560             return_data.put("yaxis", ["title" : yName, "unit" : "" ])
    561             return_data.put("xaxis", ["title" : parseFieldId( fields[ groupAxis ] ).name, "unit": "" ])
    562             return_data.put("x", [])
    563             return_data.put("y", [])
    564             return_data.put("data", [])
    565             return_data.put("error", [])
    566 
     591            return_data.put("yaxis", ["title" : "", "unit" : "" ])
     592            return_data.put("xaxis", ["title" : "", "unit": "" ])
     593            return_data.put("series", [[
     594                    "x": groupedData[ groupAxis ].collect { it.toString() },
     595                    "y": groupedData[ valueAxis ].collect { it.toString() },
     596                    "data": groupedData["data"]
     597            ]])
    567598            return return_data;
    568599        } else {
     
    866897            } else {
    867898                data = getModuleData( study, study.getSamples(), parsedField.source, parsedField.name );
    868                 println "Data: " + data
    869899                def cat = determineCategoryFromData(data)
    870900                return cat
     
    9861016                } else {
    9871017                    if(index==(infoMessageOfflineModules.size()-1)){
    988                         message += 'the '+it
     1018                        message += ' the '+it
    9891019                    } else {
    9901020                        message += ', the '+it
Note: See TracChangeset for help on using the changeset viewer.