source: trunk/gui/scripts/curve.tcl @ 6

Last change on this file since 6 was 6, checked in by mmc, 16 years ago

Fixed the Tcl library to mirror the API developed for XML
libraries on the Python side. The Tcl Rappture::library
now has methods like "children", "element", "put", etc.
One difference: On the Tcl side, the default -flavor for
element/children is "component", since that works better
in Tcl code. In Python, the default is flavor=object.

Also fixed the Tcl install script to install not just
the tcl/scripts library, but also the ../gui and ../lib
directories.

File size: 5.6 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: curve - extracts data from an XML description of a field
3#
4#  This object represents a curve of data in an XML description of
5#  simulator output.  A curve is similar to a field, but a field is
6#  a quantity versus position in device.  A curve is any quantity
7#  versus any other quantity.  This class simplifies the process of
8#  extracting data vectors that represent the curve.
9# ======================================================================
10#  AUTHOR:  Michael McLennan, Purdue University
11#  Copyright (c) 2004  Purdue Research Foundation, West Lafayette, IN
12# ======================================================================
13package require Itcl
14package require BLT
15
16namespace eval Rappture { # forward declaration }
17
18itcl::class Rappture::Curve {
19    constructor {libobj path} { # defined below }
20    destructor { # defined below }
21
22    public method components {{pattern *}}
23    public method vectors {{what -overall}}
24    public method controls {option args}
25    public method hints {{key ""}}
26
27    protected method _build {}
28
29    private variable _libobj ""  ;# ref to lib obj with curve data
30    private variable _curve ""   ;# lib obj representing this curve
31    private variable _comp2vecs  ;# maps component name => x,y vectors
32
33    private common _counter 0    ;# counter for unique vector names
34}
35
36# ----------------------------------------------------------------------
37# CONSTRUCTOR
38# ----------------------------------------------------------------------
39itcl::body Rappture::Curve::constructor {libobj path} {
40    if {![Rappture::library isvalid $libobj]} {
41        error "bad value \"$libobj\": should be LibraryObj"
42    }
43    set _libobj $libobj
44    set _curve [$libobj element -flavor object $path]
45
46    # build up vectors for various components of the curve
47    _build
48}
49
50# ----------------------------------------------------------------------
51# DESTRUCTOR
52# ----------------------------------------------------------------------
53itcl::body Rappture::Curve::destructor {} {
54    itcl::delete object $_curve
55    # don't destroy the _libobj! we don't own it!
56
57    foreach name [array names _comp2vecs] {
58        eval blt::vector destroy $_comp2vecs($name)
59    }
60}
61
62# ----------------------------------------------------------------------
63# USAGE: components ?<pattern>?
64#
65# Returns a list of names for the various components of this curve.
66# If the optional glob-style <pattern> is specified, then it returns
67# only the component names matching the pattern.
68# ----------------------------------------------------------------------
69itcl::body Rappture::Curve::components {{pattern *}} {
70    set rlist ""
71    foreach name [array names _comp2vecs] {
72        if {[string match $pattern $name]} {
73            lappend rlist $name
74        }
75    }
76    return $rlist
77}
78
79# ----------------------------------------------------------------------
80# USAGE: vectors ?<name>?
81#
82# Returns a list {xvec yvec} for the specified curve component <name>.
83# If the name is not specified, then it returns the vectors for the
84# overall curve (sum of all components).
85# ----------------------------------------------------------------------
86itcl::body Rappture::Curve::vectors {{what -overall}} {
87    if {[info exists _comp2vecs($what)]} {
88        return $_comp2vecs($what)
89    }
90    error "bad option \"$what\": should be [join [lsort [array names _comp2vecs]] {, }]"
91}
92
93# ----------------------------------------------------------------------
94# USAGE: hints ?<keyword>?
95#
96# Returns a list of key/value pairs for various hints about plotting
97# this curve.  If a particular <keyword> is specified, then it returns
98# the hint for that <keyword>, if it exists.
99# ----------------------------------------------------------------------
100itcl::body Rappture::Curve::hints {{keyword ""}} {
101    foreach {key path} {
102        label   label
103        color   color
104        color   style
105        xlabel  xaxis.label
106        xunits  xaxis.units
107        xscale  xaxis.scale
108        ylabel  yaxis.label
109        yunits  yaxis.units
110        yscale  yaxis.scale
111    } {
112        set str [$_curve get $path]
113        if {"" != $str} {
114            set hints($key) $str
115        }
116    }
117
118    if {$keyword != ""} {
119        if {[info exists hints($keyword)]} {
120            return $hints($keyword)
121        }
122        return ""
123    }
124    return [array get hints]
125}
126
127# ----------------------------------------------------------------------
128# USAGE: _build
129#
130# Used internally to build up the vector representation for the
131# curve when the object is first constructed, or whenever the curve
132# data changes.  Discards any existing vectors and builds everything
133# from scratch.
134# ----------------------------------------------------------------------
135itcl::body Rappture::Curve::_build {} {
136    # discard any existing data
137    foreach name [array names _comp2vecs] {
138        eval blt::vector destroy $_comp2vecs($name)
139    }
140    catch {unset _comp2vecs}
141
142    #
143    # Scan through the components of the curve and create
144    # vectors for each part.
145    #
146    foreach cname [$_curve children -type component] {
147        set xv ""
148        set yv ""
149
150        set xydata [$_curve get $cname.xy]
151        if {"" != $xydata} {
152            set xv [blt::vector create x$_counter]
153            set yv [blt::vector create y$_counter]
154
155            foreach line [split $xydata \n] {
156                if {[scan $line {%g %g} xval yval] == 2} {
157                    $xv append $xval
158                    $yv append $yval
159                }
160            }
161        }
162
163        if {$xv != "" && $yv != ""} {
164            set _comp2vecs($cname) [list $xv $yv]
165            incr _counter
166        }
167    }
168}
Note: See TracBrowser for help on using the repository browser.