source: trunk/gui/scripts/xyplot.tcl @ 9

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

Massive changes across the entire toolkit. Rearranged the
XML description to agree better with new documentation and
conventions.

Added a small start of Rappture.interface and Rappture.number
in the python directory. This is the new way of doing Rappture--
by declaring variables directly in the program, not using XML
directly at all.

File size: 8.3 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: xyplot - X/Y plot for analyzing results
3#
4#  This widget is an X/Y plot, meant to view line graphs produced
5#  as output from the run of a Rappture tool.  It takes a -layout
6#  object describing what should be plotted, and an -output object
7#  containing the data.  This widget puts it all together, and lets
8#  the user explore the results.
9# ======================================================================
10#  AUTHOR:  Michael McLennan, Purdue University
11#  Copyright (c) 2004  Purdue Research Foundation, West Lafayette, IN
12# ======================================================================
13package require Itk
14package require BLT
15
16option add *Xyplot.width 4i widgetDefault
17option add *Xyplot.height 4i widgetDefault
18option add *Xyplot.font \
19    -*-helvetica-medium-r-normal-*-*-120-* widgetDefault
20
21itcl::class Rappture::Xyplot {
22    inherit itk::Widget
23
24    itk_option define -layout layout Layout ""
25    itk_option define -output output Output ""
26
27    constructor {args} { # defined below }
28    destructor { # defined below }
29
30    protected method _rebuild {}
31
32    private variable _device ""  ;# device contained in -output
33    private variable _path2obj   ;# maps field/curve name => object
34}
35                                                                               
36itk::usual Xyplot {
37    keep -background -foreground -cursor -font
38}
39
40# ----------------------------------------------------------------------
41# CONSTRUCTOR
42# ----------------------------------------------------------------------
43itcl::body Rappture::Xyplot::constructor {args} {
44    option add hull.width hull.height
45    pack propagate $itk_component(hull) no
46
47    itk_component add plot {
48        blt::graph $itk_interior.plot \
49            -highlightthickness 0 -plotpadx 0 -plotpady 0 \
50            -rightmargin 10
51    } {
52        keep -background -foreground -cursor -font
53    }
54    pack $itk_component(plot) -expand yes -fill both
55
56    Blt_ZoomStack $itk_component(plot)
57    $itk_component(plot) legend configure -hide yes
58
59    eval itk_initialize $args
60}
61
62# ----------------------------------------------------------------------
63# DESTRUCTOR
64# ----------------------------------------------------------------------
65itcl::body Rappture::Xyplot::destructor {} {
66    foreach name [array names _path2obj] {
67        itcl::delete object $_path2obj($name)
68    }
69    if {$_device != ""} {
70        itcl::delete object $_device
71    }
72}
73
74# ----------------------------------------------------------------------
75# USAGE: _rebuild
76#
77# Called automatically whenever something changes that affects the
78# data in the widget.  Clears any existing data and rebuilds the
79# widget to display new data.
80# ----------------------------------------------------------------------
81itcl::body Rappture::Xyplot::_rebuild {} {
82    set g $itk_component(plot)
83    set layout $itk_option(-layout)
84    set run $itk_option(-output)
85
86    # first clear out the widget
87    eval $g element delete [$g element names]
88    $g axis configure y -min "" -max ""
89
90    foreach name [array names _path2obj] {
91        itcl::delete object $_path2obj($name)
92    }
93    catch {unset _path2obj}
94
95    # now extract any new data and plot it
96    if {$layout != "" && $run != ""} {
97        set count 0
98        foreach item [$layout children] {
99          switch -glob -- $item {
100            title {
101                $g configure -title [$layout get title]
102            }
103            legend {
104                set where [$layout get legend]
105                if {$where == "off"} {
106                    $itk_component(plot) legend configure -hide yes
107                } else {
108                    $itk_component(plot) legend configure -hide no \
109                        -position plotarea -anchor $where -borderwidth 0
110                }
111            }
112            xaxis {
113                $g xaxis configure -title [$layout get xaxis]
114            }
115            yaxis {
116                $g yaxis configure -title [$layout get yaxis]
117            }
118            field* {
119              set name [$layout get $item]
120              if {"" != [$run element output.($name)]} {
121                  set fobj [Rappture::Field ::#auto $_device $run output.($name)]
122                  set _path2obj($name) $fobj
123                  foreach {xv yv} [$fobj vectors component0] { break }
124
125                  set elem "elem[incr count]"
126                  set label [$fobj hints label]
127                  $g element create $elem -x $xv -y $yv \
128                      -symbol "" -linewidth 2 -label $label
129
130                  set color [$fobj hints color]
131                  if {$color != ""} {
132                      $g element configure $elem -color $color
133                  }
134
135                  set style [$layout get $item.style]
136                  if {$style == ""} {
137                      set style [$fobj hints style]
138                  }
139                  if {$style != ""} {
140                      eval $g element configure $elem $style
141                  }
142               }
143            }
144            curve* {
145              set name [$layout get $item]
146              if {"" != [$run element output.($name)]} {
147                  set cobj [Rappture::Curve ::#auto $run output.($name)]
148                  set _path2obj($name) $cobj
149                  foreach {xv yv} [$cobj vectors component] { break }
150
151                  set elem "elem[incr count]"
152                  set label [$cobj hints label]
153                  $g element create $elem -x $xv -y $yv \
154                      -symbol "" -linewidth 2 -label $label
155
156                  set color [$cobj hints color]
157                  if {$color != ""} {
158                      $g element configure $elem -color $color
159                  }
160
161                  set style [$layout get $item.style]
162                  if {$style == ""} {
163                      set style [$fobj hints style]
164                  }
165                  if {$style != ""} {
166                      eval $g element configure $elem $style
167                  }
168               }
169            }
170          }
171        }
172
173        #
174        # HACK ALERT!
175        # Use this code to fix up the y-axis limits for the BLT graph.
176        # The auto-limits don't always work well.  We want them to be
177        # set to a "nice" number slightly above or below the min/max
178        # limits.
179        #
180        set log [$g axis cget y -logscale]
181        foreach {min max} [$g axis limits y] { break }
182        if {$log} {
183            if {$min == $max} {
184                set min [expr {0.9*$min}]
185                set max [expr {1.1*$max}]
186            }
187            set min [expr {pow(10.0,floor(log10($min)))}]
188            set max [expr {pow(10.0,ceil(log10($max)))}]
189        } else {
190            if {$min > 0} {
191                set min [expr {0.95*$min}]
192            } else {
193                set min [expr {1.05*$min}]
194            }
195            if {$max > 0} {
196                set max [expr {1.05*$max}]
197            } else {
198                set max [expr {0.95*$max}]
199            }
200        }
201        $g axis configure y -min $min -max $max
202    }
203}
204
205# ----------------------------------------------------------------------
206# CONFIGURATION OPTION: -layout
207#
208# Set to the Rappture::Library object representing the layout being
209# displayed in the plot.
210# ----------------------------------------------------------------------
211itcl::configbody Rappture::Xyplot::layout {
212    if {$itk_option(-layout) != ""} {
213        if {![Rappture::library isvalid $itk_option(-layout)]} {
214            error "bad value \"$itk_option(-layout)\": should be Rappture::Library"
215        }
216    }
217    after cancel [itcl::code $this _rebuild]
218    after idle [itcl::code $this _rebuild]
219}
220
221# ----------------------------------------------------------------------
222# CONFIGURATION OPTION: -output
223#
224# Set to the Rappture::Library object representing the data being
225# displayed in the plot.
226# ----------------------------------------------------------------------
227itcl::configbody Rappture::Xyplot::output {
228    if {$_device != ""} {
229        itcl::delete object $_device
230        set _device ""
231    }
232    if {$itk_option(-output) != ""} {
233        if {![Rappture::library isvalid $itk_option(-output)]} {
234            error "bad value \"$itk_option(-output)\": should be Rappture::Library"
235        }
236        set _device [$itk_option(-output) element -flavor object structure]
237    }
238    after cancel [itcl::code $this _rebuild]
239    after idle [itcl::code $this _rebuild]
240}
Note: See TracBrowser for help on using the repository browser.