Changeset 2041


Ignore:
Timestamp:
Sep 29, 2011, 4:22:24 PM (9 years ago)
Author:
taco@…
Message:

visualization/VisualizeController.groovy, VIS-27 'Handle dates and times in a more sustainable way (e.g. check for fieldtype)'

File:
1 edited

Legend:

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

    r2039 r2041  
    2828    final int CATEGORICALDATA = 0
    2929    final int NUMERICALDATA = 1
     30    final int RELTIME = 2
     31    final int DATE = 3
    3032
    3133        /**
     
    292294                // TODO: handle erroneous input data
    293295                def inputData = parseGetDataParams();
    294 
    295         println ": "+params
    296296
    297297        if(inputData.columnIds == null || inputData.rowIds == null){
     
    603603        // TODO: Handle name and unit of fields correctly
    604604
    605         def valueAxisTypeString = (valueAxisType==CATEGORICALDATA ? "categorical" : "numerical")
    606         def groupAxisTypeString = (groupAxisType==CATEGORICALDATA ? "categorical" : "numerical")
    607         groupedData[groupAxis] = renderTimesAndDatesHumanReadable(groupedData[groupAxis], fields[groupAxis])
     605        def valueAxisTypeString = (valueAxisType==CATEGORICALDATA || valueAxisType==DATE || valueAxisType==RELTIME ? "categorical" : "numerical")
     606        def groupAxisTypeString = (groupAxisType==CATEGORICALDATA || groupAxisType==DATE || groupAxisType==RELTIME ? "categorical" : "numerical")
     607        groupedData[groupAxis] = renderTimesAndDatesHumanReadable(groupedData[groupAxis], groupAxisType)
     608        groupedData[valueAxis] = renderTimesAndDatesHumanReadable(groupedData[valueAxis], valueAxisType)
    608609
    609610        if(type=="table"){
     
    640641     * If the input variable 'data' contains dates or times according to input variable 'fieldInfo', these dates and times are converted to a human-readable version.
    641642     * @param data  The list of items that needs to be checked/converted
    642      * @param fieldInfo This variable contains a fieldId, e.g.
     643     * @param axisType As determined by determineFieldType
    643644     * @return The input variable 'data', with it's date and time elements converted.
    644      */
    645     def renderTimesAndDatesHumanReadable(data, fieldInfo){
    646         /* Perhaps this should be replaced with a more structured approach.
    647          * TODO: Handle the human-readable rendering of dates and times in a more structured fashion */
    648         if(fieldInfo.startsWith("startTime") || fieldInfo.startsWith("endTime") || fieldInfo.startsWith("duration")){
    649             def tmpTimeContainer = []
    650             data. each {
    651                 if(it instanceof Number) {
    652                     try{
    653                         tmpTimeContainer << new RelTime( it ).toPrettyString()
    654                     } catch(IllegalArgumentException e){
    655                         tmpTimeContainer << it
    656                     }
    657                 } else {
    658                     tmpTimeContainer << it // To handle items such as 'unknown'
     645     * @see determineFieldType
     646     */
     647    def renderTimesAndDatesHumanReadable(data, axisType){
     648        if(axisType==RELTIME){
     649            data = renderTimesHumanReadable(data)
     650        }
     651        if(axisType==DATE){
     652           data = renderDatesHumanReadable(data)
     653        }
     654        return data
     655    }
     656
     657    /**
     658     * Takes a one-dimensional list, returns the list with the appropriate items converted to a human readable string
     659     * @param data
     660     * @return
     661     */
     662    def renderTimesHumanReadable(data){
     663        def tmpTimeContainer = []
     664        data. each {
     665            if(it instanceof Number) {
     666                try{
     667                    tmpTimeContainer << new RelTime( it ).toPrettyString()
     668                } catch(IllegalArgumentException e){
     669                    tmpTimeContainer << it
    659670                }
    660             }
    661             return tmpTimeContainer
    662         } else {
    663             return data
    664         }
    665     }
    666 
     671            } else {
     672                tmpTimeContainer << it // To handle items such as 'unknown'
     673            }
     674        }
     675        return tmpTimeContainer
     676    }
     677
     678    /**
     679     * Takes a one-dimensional list, returns the list with the appropriate items converted to a human readable string
     680     * @param data
     681     * @return
     682     */
     683    def renderDatesHumanReadable(data) {
     684        def tmpDateContainer = []
     685        data. each {
     686            if(it instanceof Number) {
     687                try{
     688                    tmpDateContainer << new java.util.Date( it ).toString()
     689                } catch(IllegalArgumentException e){
     690                    tmpDateContainer << it
     691                }
     692            } else {
     693                tmpDateContainer << it // To handle items such as 'unknown'
     694            }
     695        }
     696        return tmpDateContainer
     697    }
    667698        /**
    668699         * Returns a closure for the given entitytype that determines the value for a criterion
     
    925956     * @param fieldId The field id as returned from the client, will be used to retrieve the data required to determine the type of data a field contains
    926957     * @param inputData Optional parameter that contains the data we are computing the type of. When including in the function call we do not need to request data from a module, should the data belong to a module
    927      * @return Either CATEGORICALDATA of NUMERICALDATA
     958     * @return Either CATEGORICALDATA, NUMERICALDATA, DATE or RELTIME
    928959     */
    929960    protected int determineFieldType(studyId, fieldId, inputData = null){
     
    937968                        return determineCategoryFromTemplateField(parsedField.id)
    938969                } else { // Domainfield or memberclass
    939                     def field = domainObjectCallback( parsedField.type )?.declaredFields.find { it.name == parsedField.name };
     970                    def callback = domainObjectCallback( parsedField.type )
     971
     972                    // Can the field be found in the domainFields as well? If so, treat it as a template field, so that dates and times can be properly rendered in a human-readable fashion
     973                    if(callback?.giveDomainFields().name.contains(parsedField.name.toString())){
     974                        // Use the associated templateField to determine the field type
     975                        return determineCategoryFromTemplateField(
     976                                callback?.giveDomainFields()[
     977                                    callback?.giveDomainFields().name.indexOf(parsedField.name.toString())
     978                                ]
     979                        )
     980                    }
     981                    // Apparently it is not a templatefield as well as a memberclass
     982
     983                    def field = callback?.declaredFields.find { it.name == parsedField.name };
    940984                    if( field ) {
    941985                        return determineCategoryFromClass( field.getType() )
     
    10071051
    10081052    /**
     1053     * Determines a field category, based on the TemplateFieldId of a Templatefield
     1054     * @param id A database ID for a TemplateField
     1055     * @return Either CATEGORICALDATA of NUMERICALDATA
     1056     */
     1057    protected int determineCategoryFromTemplateFieldId(id){
     1058        TemplateField tf = TemplateField.get(id)
     1059        return determineCategoryFromTemplateField(tf)
     1060    }
     1061
     1062    /**
    10091063     * Determines a field category, based on the TemplateFieldType of a Templatefield
    10101064     * @param id A database ID for a TemplateField
    10111065     * @return Either CATEGORICALDATA of NUMERICALDATA
    10121066     */
    1013     protected int determineCategoryFromTemplateField(id){
    1014         TemplateField tf = TemplateField.get(id)
    1015         if(tf.type==TemplateFieldType.DOUBLE || tf.type==TemplateFieldType.LONG || tf.type==TemplateFieldType.DATE || tf.type==TemplateFieldType.RELTIME){
     1067    protected int determineCategoryFromTemplateField(tf){
     1068        if(tf.type==TemplateFieldType.DOUBLE || tf.type==TemplateFieldType.LONG){
    10161069            println "GSCF templatefield: NUMERICALDATA ("+NUMERICALDATA+") (based on "+tf.type+")"
    10171070            return NUMERICALDATA
    1018         } else {
    1019             println "GSCF templatefield: CATEGORICALDATA ("+CATEGORICALDATA+") (based on "+tf.type+")"
    1020             return CATEGORICALDATA
    1021         }
     1071        }
     1072        if(tf.type==TemplateFieldType.DATE){
     1073            println "GSCF templatefield: DATE ("+DATE+") (based on "+tf.type+")"
     1074            return DATE
     1075        }
     1076        if(tf.type==TemplateFieldType.RELTIME){
     1077            println "GSCF templatefield: RELTIME ("+RELTIME+") (based on "+tf.type+")"
     1078            return RELTIME
     1079        }
     1080        println "GSCF templatefield: CATEGORICALDATA ("+CATEGORICALDATA+") (based on "+tf.type+")"
     1081        return CATEGORICALDATA
    10221082    }
    10231083    /**
     
    11171177    protected def determineVisualizationTypes(rowType, columnType){
    11181178         def types = []
    1119         if(rowType==CATEGORICALDATA){
    1120             if(columnType==CATEGORICALDATA){
     1179        if(rowType==CATEGORICALDATA || DATE || RELTIME){
     1180            if(columnType==CATEGORICALDATA || DATE || RELTIME){
    11211181                types = [ [ "id": "table", "name": "Table"] ];
    11221182            }
     
    11261186        }
    11271187        if(rowType==NUMERICALDATA){
    1128             if(columnType==CATEGORICALDATA){
     1188            if(columnType==CATEGORICALDATA || DATE || RELTIME){
    11291189                types = [ [ "id": "barchart", "name": "Barchart"], [ "id": "linechart", "name": "Linechart"] ];
    11301190            }
Note: See TracChangeset for help on using the changeset viewer.