source: trunk/gui/scripts/table.tcl @ 2790

Last change on this file since 2790 was 1929, checked in by gah, 14 years ago
File size: 7.6 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: table - extracts data from an XML description of a table
3#
4#  This object represents one table in an XML description of a table.
5#  It simplifies the process of extracting data representing columns
6#  in the table.
7# ======================================================================
8#  AUTHOR:  Michael McLennan, Purdue University
9#  Copyright (c) 2004-2005  Purdue Research Foundation
10#
11#  See the file "license.terms" for information on usage and
12#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13# ======================================================================
14package require Itcl
15
16namespace eval Rappture { # forward declaration }
17
18itcl::class Rappture::Table {
19    constructor {xmlobj path} { # defined below }
20    destructor { # defined below }
21
22    public method rows {}
23    public method columns {args}
24    public method values {args}
25    public method limits {col}
26    public method hints {{key ""}}
27
28    private variable _xmlobj ""  ;# ref to lib obj with curve data
29    private variable _table ""   ;# lib obj representing this table
30    private variable _tuples ""  ;# list of tuples with table data
31}
32
33# ----------------------------------------------------------------------
34# CONSTRUCTOR
35# ----------------------------------------------------------------------
36itcl::body Rappture::Table::constructor {xmlobj path} {
37    if {![Rappture::library isvalid $xmlobj]} {
38        error "bad value \"$xmlobj\": should be Rappture::library"
39    }
40    set _table [$xmlobj element -as object $path]
41
42    #
43    # Load data from the table and store in the tuples.
44    #
45    set _tuples [Rappture::Tuples ::#auto]
46    foreach cname [$_table children -type column] {
47        set label [$_table get $cname.label]
48        $_tuples column insert end -name $cname -label $label
49    }
50
51    set cols [llength [$_tuples column names]]
52    set nline 1
53    foreach line [split [$_table get data] \n] {
54        if {[llength $line] == 0} {
55            continue
56        }
57        if {[llength $line] != $cols} {
58            error "bad data at line $nline: expected $cols columns but got \"[string trim $line]\""
59        }
60        $_tuples insert end $line
61        incr nline
62    }
63}
64
65# ----------------------------------------------------------------------
66# DESTRUCTOR
67# ----------------------------------------------------------------------
68itcl::body Rappture::Table::destructor {} {
69    itcl::delete object $_tuples
70    itcl::delete object $_table
71    # don't destroy the _xmlobj! we don't own it!
72}
73
74# ----------------------------------------------------------------------
75# USAGE: rows
76#
77# Returns the number of rows of information in this table.
78# ----------------------------------------------------------------------
79itcl::body Rappture::Table::rows {} {
80    return [$_tuples size]
81}
82
83# ----------------------------------------------------------------------
84# USAGE: columns ?-component|-label|-units? ?<pos>?
85#
86# Returns information about the columns associated with this table.
87# ----------------------------------------------------------------------
88itcl::body Rappture::Table::columns {args} {
89    Rappture::getopts args params {
90        flag switch -component
91        flag switch -label default
92        flag switch -units
93    }
94    if {[llength $args] == 0} {
95        set cols [llength [$_tuples column names]]
96        set plist ""
97        for {set i 0} {$i < $cols} {incr i} {
98            lappend plist $i
99        }
100    } elseif {[llength $args] == 1} {
101        set p [lindex $args 0]
102        if {[string is integer $p]} {
103            lappend plist $p
104        } else {
105            set pos [lsearch -exact [$_tuples column names] $p]
106            if {$pos < 0} {
107                error "bad column \"$p\": should be column name or integer index"
108            }
109            lappend plist $pos
110        }
111    } else {
112        error "wrong # args: should be \"columns ?-component|-label|-units? ?pos?\""
113    }
114
115    set rlist ""
116    switch -- $params(switch) {
117        -component {
118            set names [$_tuples column names]
119            foreach p $plist {
120                lappend rlist [lindex $names $p]
121            }
122        }
123        -label {
124            set names [$_tuples column names]
125            foreach p $plist {
126                set name [lindex $names $p]
127                catch {unset opts}
128                array set opts [$_tuples column info $name]
129                lappend rlist $opts(-label)
130            }
131        }
132        -units {
133            set names [$_tuples column names]
134            foreach p $plist {
135                set comp [lindex $names $p]
136                lappend rlist [$_table get $comp.units]
137            }
138        }
139    }
140    return $rlist
141}
142
143# ----------------------------------------------------------------------
144# USAGE: values ?-row <index>? ?-column <index>?
145#
146# Returns a single value or a list of values for data in this table.
147# If a particular -row and -column is specified, then it returns
148# a single value for that row/column.  If either the -row or the
149# -column is specified, then it returns a list of values in that
150# row or column.  With no args, it returns all values in the table.
151# ----------------------------------------------------------------------
152itcl::body Rappture::Table::values {args} {
153    Rappture::getopts args params {
154        value -row ""
155        value -column ""
156    }
157    if {[llength $args] > 0} {
158        error "wrong # args: should be \"values ?-row r? ?-column c?\""
159    }
160    if {"" == $params(-row) && "" == $params(-column)} {
161        return [$_tuples get]
162    } elseif {"" == $params(-column)} {
163        return [lindex [$_tuples get $params(-row)] 0]
164    }
165
166    if {[string is integer $params(-column)]} {
167        set col [lindex [$_tuples column names] $params(-column)]
168    } else {
169        set col $params(-column)
170        if {"" == [$_tuples column names $col]} {
171            error "bad column name \"$col\": should be [join [$_tuples column names] {, }]"
172        }
173    }
174
175    if {"" == $params(-row)} {
176        # return entire column
177        return [$_tuples get -format $col]
178    }
179    # return a particular cell
180    return [$_tuples get -format $col $params(-row)]
181}
182
183# ----------------------------------------------------------------------
184# USAGE: limits <column>
185#
186# Returns the {min max} limits of the numerical values in the
187# specified <column>, which can be either an integer index to
188# a column or a column name.
189# ----------------------------------------------------------------------
190itcl::body Rappture::Table::limits {column} {
191    set min ""
192    set max ""
193    foreach v [values -column $column] {
194        if {"" == $min} {
195            set min $v
196            set max $v
197        } else {
198            if {$v < $min} { set min $v }
199            if {$v > $max} { set max $v }
200        }
201    }
202    return [list $min $max]
203}
204
205# ----------------------------------------------------------------------
206# USAGE: hints ?<keyword>?
207#
208# Returns a list of key/value pairs for various hints about plotting
209# this table.  If a particular <keyword> is specified, then it returns
210# the hint for that <keyword>, if it exists.
211# ----------------------------------------------------------------------
212itcl::body Rappture::Table::hints {{keyword ""}} {
213    foreach {key path} {
214        label   about.label
215        color   about.color
216        style   about.style
217    } {
218        set str [$_table get $path]
219        if {"" != $str} {
220            set hints($key) $str
221        }
222    }
223
224    if {$keyword != ""} {
225        if {[info exists hints($keyword)]} {
226            return $hints($keyword)
227        }
228        return ""
229    }
230    return [array get hints]
231}
Note: See TracBrowser for help on using the repository browser.