2 # barChart -- A bar chart display visualization for Paradyn
4 # $Log: barChart.tcl,v $
5 # Revision 1.6 1994/10/10 23:08:41 tamches
6 # preliminary changes on the way to swapping the x and y axes
8 # Revision 1.5 1994/10/07 22:06:36 tamches
9 # Fixed some bugs w.r.t. resizing the window (bars and resources were
10 # sometimes redrawn at the old locations, instead of adapting to the
11 # resize). The problem was related to [winfo width ...] returning
12 # the old value while in the middle of a resize event. The solution
13 # was to include %w and %h in the configure-even callback (see the
14 # tk "bind" command man page)
16 # Revision 1.4 1994/10/04 22:10:56 tamches
17 # more color fixing (moved codes from barChart.C to here)
19 # Revision 1.3 1994/10/04 19:00:23 tamches
20 # implemented resourceWidth algorithm: try to make resources the maximum
21 # pixel width, but if they don't all fit in the window, shrink (down
22 # to a fixed minimum). Reapply algorithm when: window resizes, resources
25 # Revision 1.2 1994/10/01 02:22:25 tamches
26 # Fixed some bugs related to scrolling; now, the user can't accidentally
27 # scroll to the left of the leftmost bar or to the right of the rightmost
30 # Revision 1.1 1994/09/29 19:49:50 tamches
31 # rewritten for new version of barchart; the bars are now drawn
32 # with xlib code in C++ (no more blt_barchart) in barChart.C.
33 # See also barChartTcl.C and barChartDriver.C
35 # Revision 1.5 1994/09/08 00:10:43 tamches
36 # Added preliminary blt_drag&drop interface.
37 # changed window title.
39 # Revision 1.4 1994/09/04 23:55:29 tamches
40 # added 'to do' and 'problems' lists. tightened code around speed-critical
41 # areas. improved look of resources axis.
43 # Revision 1.3 1994/09/03 01:24:40 tamches
44 # Cleaned up syntax some more, e.g. longer variable names.
48 # Revision 1.2 1994/09/02 21:00:30 tamches
49 # minor get-acquainted formatting cleanups
51 # Revision 1.1 1994/08/06 22:50:47 rbi
52 # Bar Chart Visi originally written by Sherri Frizell.
53 # Initial revision includes bug fixes and cleanups by rbi.
56 # ######################################################
58 # 1) draw numerical values on the bars (menu option) (default=on?)
59 # 2) resources: make deletion work
60 # 3) staggered x-axis names
61 # 4) multiple metrics: put a "key" on screen
62 # 5) multiple metrics: make them show on y axis
63 # 6) multiple metrics: allow deletion
64 # 7) option to sort resources (will be difficult--would need to map resourceid
65 # as given by visi to our new ordering)
66 # ######################################################
68 # ################### Default options #################
70 option add *Visi*font *-New*Century*Schoolbook-Bold-R-*-18-*
71 option add *Data*font *-Helvetica-*-r-*-12-*
72 option add *MyMenu*font *-New*Century*Schoolbook-Bold-R-*-14-*
74 if {[string match [tk colormodel .] color] == 1} {
75 # You have a color monitor...
76 # change primary background color from 'bisque' to 'grey'
78 option add *Background grey
79 option add *activeBackground LightGrey
80 option add *activeForeground black
81 option add *Scale.activeForeground grey
83 # You don't have a color monitor...
84 option add *Background white
85 option add *Foreground black
88 # #################### Overall frame ###########################
90 set metricsAxisWidth 0.75i
91 set resourcesAxisHeight 0.65i
97 pack $W.top -side top -fill x -expand false -anchor n
98 # this area will encompass the title bar, menu bar, and logo
99 # expand is set to false; if the window is made taller,
100 # we don't want to get any taller.
103 pack $W.top.left -side left -fill both -expand true
104 # this area encompasses the title bar and menu bar
105 # expand is set to true so that if the window is made
106 # wider, we get the extra space (as opposed to the logo
107 # or as opposed to nobody, which would leave ugly blank
110 # #################### Paradyn logo #################
112 label $W.top.logo -relief raised \
113 -bitmap @/p/paradyn/core/paradyn/tcl/logo.xbm \
114 -foreground #b3331e1b53c7
116 pack $W.top.logo -side right -expand false
117 # we set expand to false; if the window is made wider, we
118 # don't want any of the extra space; let the menu bar and
121 # #################### Title bar #################
123 label $W.top.left.titlebar -text "BarChart Visualization" -foreground white -background lightslategray
124 pack $W.top.left.titlebar -side top -fill both -expand true
125 # expand is set to true, not because we want more space if the window
126 # is made taller (which won't happen, since the expand flag of our
127 # parent was set to false), but because we want to take up any padding
128 # space left after we and the menu bar are placed (if the logo is
129 # taller than the two of us, which it currently is)
131 # ##################### Menu bar ###################
133 set Wmbar $W.top.left.mbar
134 frame $Wmbar -class MyMenu -borderwidth 2 -relief raised
135 pack $Wmbar -side top -fill both -expand false
137 # #################### File menu #################
139 menubutton $Wmbar.file -text File -menu $Wmbar.file.m
141 $Wmbar.file.m add command -label "Close Bar chart" -command exit
143 # #################### Metrics menu ###################
145 menubutton $Wmbar.metrics -text Metrics -menu $Wmbar.metrics.m
146 menu $Wmbar.metrics.m
147 $Wmbar.metrics.m add command -label "Add Metric..." -command AddMetricDialog
148 $Wmbar.metrics.m add command -label "Remove Selected Metric" -state disabled
150 # #################### Resources menu #################
152 menubutton $Wmbar.resources -text Resources -menu $Wmbar.resources.m
153 menu $Wmbar.resources.m
154 $Wmbar.resources.m add command -label "Add Resource..." -command AddResourceDialog
155 $Wmbar.resources.m add command -label "Remove Selected Resource" -state disabled
156 $Wmbar.resources.m add separator
157 $Wmbar.resources.m add radio -label "Order by Name (ascending)" -variable SortPrefs -command ProcessNewSortPrefs -value ByName -state disabled
158 $Wmbar.resources.m add radio -label "Order by Name (descending)" -variable SortPrefs -command ProcessNewSortPrefs -value ByNameDescending -state disabled
159 $Wmbar.resources.m add radio -label "Order as Inserted by User" -variable SortPrefs -command ProcessNewSortPrefs -value NoParticular -state disabled
161 # #################### Display menu #################
163 menubutton $Wmbar.opts -text "Display" -menu $Wmbar.opts.m
165 $Wmbar.opts.m add radio -label "Current Value" \
166 -variable DataFormat -command {rethinkDataFormat} \
168 $Wmbar.opts.m add radio -label "Average Value" \
169 -variable DataFormat -command {rethinkDataFormat} \
171 $Wmbar.opts.m add radio -label "Total Value" \
172 -variable DataFormat -command {rethinkDataFormat} \
175 # #################### Help menu #################
177 menubutton $Wmbar.help -text Help \
180 $Wmbar.help.m add command -label "General" -command "NotImpl" -state disabled
181 $Wmbar.help.m add command -label "Context" -command "NotImpl" -state disabled
184 # #################### Build the menu bar and add to display #################
186 pack $Wmbar.file $Wmbar.metrics \
187 $Wmbar.resources $Wmbar.opts \
189 pack $Wmbar.help -side right
191 # #################### Organize all menu buttons into a menubar #################
193 tk_menuBar $Wmbar $Wmbar.file $Wmbar.metrics \
194 $Wmbar.resources $Wmbar.opts $Wmbar.help
196 # #################### Barchart Title ("Metric: xxxxxxxx") #################
198 label $W.titleLabel -text "(no barchart currently loaded)" \
199 -font "-adobe-helvetica-bold-o-*-*-*-*-*-*-*-*-iso8859-1"
200 pack $W.titleLabel -side top -fill x -expand false
201 # expand is set to false; if the window is made taller, we don't want
202 # any of the extra space to go to the title (we want it to go to the
203 # bar graph main area in the middle)
206 # #################### Barchart Resources Axis Title ("Resource(s)") ###############
208 label $W.resourcesAxisTitle -text "Resource(s)" \
209 -font "-adobe-helvetica-bold-o-*-*-*-*-*-*-*-*-iso8859-1"
210 pack $W.resourcesAxisTitle -side bottom -fill x -expand false
211 # expand is set to false; if the window is made taller, we don't want
212 # extra height to go to us.
214 # ############### A sub-window to hold x-axis scrollbar & some padding ##########
216 canvas $W.sbRegion -height 16
217 # on configure events, must update the -scrollregion
218 pack $W.sbRegion -side bottom -expand false -fill x
219 # expand is set to false; if the window is made taller, we don't want
220 # any of the extra height; let the middle section have it.
222 canvas $W.sbRegion.padding -width $metricsAxisWidth -height 16
223 pack $W.sbRegion.padding -side left -expand false
224 # expand is set to false; if the window is made wider, we don't
225 # want any of the extra width.
227 scrollbar $W.sbRegion.resourcesAxisScrollbar -orient horizontal -width 16 -foreground gray \
228 -activeforeground gray -relief sunken \
229 -command processNewScrollPosition
230 pack $W.sbRegion.resourcesAxisScrollbar -side right -fill x -expand true
231 # expand is set to true; if the window is made wider, we want
234 # ############# A sub-window to hold x-axis canvas & some padding #########
236 canvas $W.bottom -height $resourcesAxisHeight
237 pack $W.bottom -side bottom -expand false -fill x
238 # expand is set to false; if the window is made taller, we don't want
239 # any of the extra height; let the middle section have it.
241 canvas $W.bottom.padding -width $metricsAxisWidth -height $resourcesAxisHeight
242 pack $W.bottom.padding -side left -expand false
243 # expand is set to false; if the window is made wider, we don't
244 # want any of the extra width.
245 # We are the blank space at (0,0); we exist to keep the X and Y
246 # axis from getting any of this area, which would be difficult to manage.
248 set WresourcesCanvas $W.bottom.resourcesAxisCanvas
249 canvas $WresourcesCanvas -height $resourcesAxisHeight -relief groove \
250 -xscrollcommand myXScroll \
252 pack $WresourcesCanvas -side right -expand true -fill x
253 # expand is set to true; if the window is made wider, we want
256 # #################### Y Axis Canvas ##################################
258 canvas $W.metricsAxisCanvas -width $metricsAxisWidth
259 pack $W.metricsAxisCanvas -side left -fill y -expand false
260 # expand is set to false; if the window is made wider, we don't want
261 # extra width to go to the y axis
263 # #################### Barchart Area ($W.body) #################
265 canvas $W.body -height 3i -width 2.5i -relief groove
266 #frame $W.body -height 3i -width 2.5i -relief groove
267 pack $W.body -side top -fill both -expand true
268 # expand is set to true; if the window is made taller, we want the
269 # extra height to go to us (and our slave window $W.body.barCanvas)
271 # #################### Bar Canvas ##############################
273 #frame $W.body.barCanvas -relief groove -background red
274 #pack $W.body.barCanvas -side top -fill both -expand true
276 #canvas $W.body.barCanvas -relief groove
277 #pack $W.body.barCanvas -side top -fill both -expand true
279 # ######### pack $W (and all its subwindows) into the main (top-level) window such that
280 # ######### it basically consumes the entire window...
281 pack append . $W {fill expand frame center}
283 # set some window manager hints:
285 wm title . "Barchart"
287 proc getWindowWidth {wName} {
288 # warning! This routine will return an old number if an important
289 # event (i.e. resize) happened but idle routines haven't yet kicked in.
290 # --> *** In such cases, be sure to grab the latest information directly
291 # from the event structure instead of calling this routine!!!!
293 set result [winfo width $wName]
295 # hack for a window that hasn't yet been mapped
296 set result [winfo reqwidth $wName]
302 proc getWindowHeight {wName} {
303 # warning! This routine will return an old number if an important
304 # event (i.e. resize) happened but idle routines haven't yet kicked in.
305 # --> *** In such cases, be sure to grab the latest information directly
306 # from the event structure instead of calling this routine!!!!
308 set result [winfo height $wName]
310 # hack for a window that hasn't yet been mapped
311 set result [winfo reqwidth $wName]
317 # ################ Initialization and LaunchBarChart ######################
319 # a subset of DgConfigCallback that sets important global vrbles
320 # stuff that needs to be in order **BEFORE** the call to launchBarChart
321 # (i.e. launchBarChart depends on these settings)
323 # puts stderr "Welcome to Initialize!"
330 global metricMinValues
331 global metricMaxValues
336 global currResourceWidth
337 global minResourceWidth
338 global maxResourceWidth
342 global clickedOnResource
343 global clickedOnResourceText
344 global numLabelsDrawn
345 global numResourcesDrawn
351 set SortPrefs NoParticular
353 set clickedOnResource ""
354 set clickedOnResourceText ""
356 set numResourcesDrawn 0
358 set DataFormat Instantaneous
359 set numMetrics [Dg nummetrics]
361 for {set metriclcv 0} {$metriclcv < $numMetrics} {incr metriclcv} {
362 set metricNames($metriclcv) [Dg metricname $metriclcv]
363 set metricUnits($metriclcv) [Dg metricunits $metriclcv]
364 set metricMinValues($metriclcv) [lindex [getMetricHints $metricNames($metriclcv)] 1]
365 set metricMaxValues($metriclcv) [lindex [getMetricHints $metricNames($metriclcv)] 2]
368 set numResources [Dg numresources]
369 for {set resourcelcv 0} {$resourcelcv < $numResources} {incr resourcelcv} {
370 set resourceNames($resourcelcv) [Dg resourcename $resourcelcv]
373 set minResourceWidth 45
374 set maxResourceWidth 90
375 set currResourceWidth $maxResourceWidth
376 # as resources are added, we try to shrink the resource width down to a minimum of
377 # (minResourceWidth) rather than having to invoke the scrollbar.
378 # The question then becomes, if the window is made wider, should we
379 # tend "resourceWidth" back toward "maxResourceWidth", if it had been shrunk
380 # toward "minResourceWidth"? Or once a resource is shrunk, should it never
383 # bar colors: (see /usr/lib/X11/rgb.txt)
384 # purple is reserved for the where axis.
385 # red should not be next to green; they look equal to colorblind
386 # use greyscales if b&w monitor
387 # set barColors(0) "tomato"
388 set barColors(0) "cornflower blue"
389 set barColors(1) "medium sea green"
390 set barColors(2) "hotpink"
391 set barColors(3) "chocolate"
392 set barColors(4) "orange"
395 # launch our C++ barchart code
396 # launchBarChart $W.body.barCanvas doublebuffer noflicker $numMetrics $numResources 0
397 launchBarChart $W.body doublebuffer noflicker $numMetrics $numResources 0
399 # trap window resize and window expose events --- for the subwindow
400 # containing the bars only, however. Note that using
401 # $W.body instead of "." avoids LOTS of unneeded
402 # configuration callbacks. In particular, when a window is just
403 # moved, it won't create a callback (yea!) This means we
404 # can treat a configuration event as a true resize.
406 # [sec 19.2: 'event patterns' in tk/tcl manual]
408 bind $W.body <Configure> {myConfigureEventHandler %w %h}
409 bind $W.body <Expose> {myExposeEventHandler}
412 # ############################################################################
413 # ####################### important procedures ###############################
414 # ############################################################################
416 # LOW-LEVEL PROCEDURES:
417 # processEnterResource - given a widget name, let the user know that clicking
418 # on it will enable the "delete" item under the resource
419 # menu. Called when the mouse enters the widget.
420 # processClickResource - Bound to buttonpress in resource widgets; just
421 # calls selectResource
422 # processExitResource - Bound to when the mouse leaves a resource message widget.
423 # depending on whether the user clicked, we do something
424 # appropriate user-interface-speaking.
426 # drawResourcesAxis - Completely rethinks the layout of the resource axis and its
427 # scrollbar, and redraws them. Call at the beginning of the program,
428 # after the window is resized, and when resources (or metrics) are added
431 # drawMetricsAxis - analagous to drawResourcesAxis...
433 # drawTitle - rethinks and redraws the chart title (just below the menubar).
434 # Call at the beginning of the program and when metrics are
435 # added or deleted (since they comprise the title)
437 # myConfigureEventHandler - called whenever the window configuration has changed
439 # HIGH-LEVEL PROCEDURES:
440 # selectResource - given a widget name, select it and enable the "delete resource"
442 # unSelectResource - un-select the widget and disable the "delete resource" menu item.
443 # addResource - given a new resource name, adds it (calling drawResourcesAxis, etc.
446 # delResource - given an index (0 thru numResources-1), deletes it (calling
447 # drawResourcesAxis, etc. automatically)
449 # addMetric - given a new metric name (and its units), adds it (calling drawResourcesAxis,
450 # drawMetricsAxis, drawTitle, etc. automatically)
452 # delMetric - analagous to delResource...
454 # ############################################################################
456 proc selectResource {widgetName} {
457 global clickedOnResource
458 global clickedOnResourceText
461 # if someone else was previous selected, un-select him
462 if {$clickedOnResource != ""} {
463 unSelectResource $clickedOnResource
467 set clickedOnResource $widgetName
468 set clickedOnResourceText [lindex [$widgetName configure -text] 4]
469 $widgetName configure -relief sunken
470 $Wmbar.resources.m entryconfigure 1 -state normal \
471 -label "Remove \"$clickedOnResourceText\"" \
472 -command {delResourceByName $clickedOnResourceText}
475 proc unSelectResource {widgetName} {
476 global clickedOnResource
477 global clickedOnResourceText
480 set clickedOnResource ""
481 set clickedOnResourceText ""
482 $widgetName configure -relief flat
483 $Wmbar.resources.m entryconfigure 1 -state disabled \
484 -label "Remove Selected Resource" \
485 -command {puts "ignoring unexpected deletion..."}
488 proc processEnterResource {widgetName} {
489 global clickedOnResource
490 global clickedOnResourceText
492 # if this widget has already been clicked on, do nothing
493 if {$widgetName == $clickedOnResource} {
497 $widgetName configure -relief groove
500 proc processClickResource {widgetName} {
501 selectResource $widgetName
504 proc processExitResource {widgetName} {
505 global clickedOnResource
506 global clickedOnResourceText
508 # if we clicked on this guy, then do nothing (keep him selected),
509 # otherwise undo the -relief groove
510 if {$clickedOnResource != $widgetName} {
511 $widgetName configure -relief flat
515 proc rethinkResourceWidths {screenWidth} {
516 # When resources are added or deleted, this routine is called.
517 # Its sole purpose is to rethink the value of currResourceWidth,
518 # depending on the resources.
520 # algorithm: get current window width. set resource width equal
521 # to window width / num resources. If that would make the resource
522 # width too small, make the resource width currResourceWidth
523 global minResourceWidth
524 global maxResourceWidth
525 global currResourceWidth
527 global WresourcesCanvas
529 set tentativeResourceWidth [expr $screenWidth / $numResources]
530 if {$tentativeResourceWidth < $minResourceWidth} {
531 set tentativeResourceWidth $minResourceWidth
532 } elseif {$tentativeResourceWidth > $maxResourceWidth} {
533 set tentativeResourceWidth $maxResourceWidth
536 set currResourceWidth $tentativeResourceWidth
538 # puts stderr "Leaving rethinkResourceWidths; we have decided upon $currResourceWidth"
541 proc drawResourcesAxis {resourcesAxisWidth} {
542 # how it works: deletes all canvas items with the tag "resourcesAxisItemTag", including
543 # the window items. message widgets have to be deleted separately, notwithstanding
544 # the fact that the canvas window items were deleted already.
545 # (it knows how many message widgets there are via numResourcesDrawn, which at the
546 # time this routine is called, may not be up-to-date with respect to numResources),
547 # and then redraws by re-recreating the canvas items and message widgets
551 global WresourcesCanvas
553 global resourcesAxisHeight
554 global metricsAxisWidth
557 global numResourcesDrawn
559 global clickedOnResource
560 global clickedOnResourceText
562 global minResourceWidth
563 global maxResourceWidth
564 global currResourceWidth
568 # puts stderr "Welcome to drawResourcesAxis"
573 set resourceNameFont -adobe-courier-medium-r-normal-*-12-120-*-*-*-*-iso8859-1
575 # ###### delete leftover stuff
576 $WresourcesCanvas delete resourcesAxisItemTag
577 for {set rindex 0} {$rindex < $numResourcesDrawn} {incr rindex} {
578 destroy $WresourcesCanvas.message$rindex
581 # next, several tick marks extending down a few pixels from the resources axis (one per resource),
582 # plus (while we're at it) the text of the given resources (centered at their respective
585 # yet to implement: STAGGERED TEXT
586 # needed : a way to detect when two message widgets have collided.
587 # doesn't sound too difficult... (use winfo -geometry for each widget)
590 for {set rindex 0} {$rindex < $numResources} {incr rindex} {
591 set left [expr $rindex * $currResourceWidth]
592 set right [expr $left + $currResourceWidth - 1]
593 set middle [expr ($left + $right) / 2]
596 $WresourcesCanvas create line $middle $top $middle [expr $top+$tickHeight-1] -tag resourcesAxisItemTag
598 # create a message widget, bind some commands to it, and attach it to the
599 # canvas via "create window"
601 set theText $resourceNames($rindex)
603 message $WresourcesCanvas.message$rindex -text $theText \
604 -justify center -width $currResourceWidth \
605 -font $resourceNameFont
606 bind $WresourcesCanvas.message$rindex <Enter> \
607 {processEnterResource %W}
608 bind $WresourcesCanvas.message$rindex <Leave> \
609 {processExitResource %W}
610 bind $WresourcesCanvas.message$rindex <ButtonPress> \
611 {processClickResource %W}
612 $WresourcesCanvas create window $middle [expr $top+$tickHeight] \
613 -anchor n -tag resourcesAxisItemTag \
614 -window $WresourcesCanvas.message$rindex
617 # the axis itself--a horizontal line
618 $WresourcesCanvas create line 0 $top $right $top -tag resourcesAxisItemTag
620 # Update the scrollbar's scrollregion configuration:
621 set regionList {0 0 0 0}
622 set regionList [lreplace $regionList 2 2 $right]
623 set regionList [lreplace $regionList 3 3 $resourcesAxisHeight]
624 $WresourcesCanvas configure -scrollregion $regionList
626 set screenWidth $resourcesAxisWidth
628 set oldconfig [$W.sbRegion.resourcesAxisScrollbar get]
629 set oldTotalWidth [lindex $oldconfig 0]
631 if {$oldTotalWidth != $right} {
632 # puts stderr "drawResourcesAxis: detected major change in resources ($oldTotalWidth != $right), resetting"
636 set firstUnit [lindex $oldconfig 2]
639 set lastUnit [expr $firstUnit + $screenWidth - 1]
640 # puts stderr "setting sb: $right $screenWidth $firstUnit $lastUnit"
641 $W.sbRegion.resourcesAxisScrollbar set $right $screenWidth $firstUnit $lastUnit
643 # set the maximum width of the window to be $right + $metricsAxisWidth
644 # wm maxsize . [expr $right + inches2pixels($metricsAxisWidth)] [unlimited-y-size]
646 set numResourcesDrawn $numResources
649 proc processNewMetricMax {mindex newmaxval} {
650 # called from barChart.C when y-axis overflow is detected and
651 # a new max value is chosen
652 global metricMinValues
653 global metricMaxValues
656 set metricMaxValues($mindex) $newmaxval
658 drawMetricsAxis [getWindowHeight $W.metricsAxisCanvas]
661 proc drawMetricsAxis {metricsAxisHeight} {
662 # the y axis changes to reflect the units of the current metric(s).
663 # It is not necessary to call drawMetricsAxis if the window width is
664 # resized; it IS necessary to call drawMetricsAxis if the window
666 # It is not necessary to call drawMetricsAxis if resources are
667 # added or removed; it IS necessary to call drawMetricsAxis if
668 # metrics are added or removed.
672 global numLabelsDrawn
675 global metricUnitTypes
676 global metricMinValues
677 global metricMaxValues
679 # puts stderr "welcome to drawMetricsAxis"
681 # first, delete all leftover canvas items (those with a metricsAxis tag to them)
682 $W.metricsAxisCanvas delete metricsAxisTag
684 # we still have to delete the label widgets, which can't have tags...
686 for {set labelindex 0} {$labelindex < $numLabelsDrawn} {incr labelindex} {
687 destroy $W.metricsAxisCanvas.label$labelindex
690 # canvas item: the axis itself (a vertical line)
691 set winHeight $metricsAxisHeight
692 set winWidth [getWindowWidth $W.metricsAxisCanvas]
696 set right [expr $winWidth - 5]
697 set tickLeft [expr $right-$tickWidth+1]
699 set bottom [expr $winHeight - 5]
700 set labelRight [expr $tickLeft]
701 set labelWidth [expr $labelRight - $left + 1]
702 set height [expr $bottom - $top + 1]
703 set tickStep [expr ($height-1) / ($numlabels-1)]
705 set numericalStep [expr (1.0 * $metricMaxValues(0)-$metricMinValues(0)) / ($numlabels-1)]
707 # puts stderr "drawMetricsAxis: numericalStep is $numericalStep; metric-min is $metricMinValues(0); metric-max is $metricMaxValues(0)"
710 $W.metricsAxisCanvas create line $right $top $right $bottom -tag metricsAxisTag
712 set labelFont -adobe-courier-medium-r-normal-*-12-120-*-*-*-*-iso8859-1
713 # draw tick marks, and while we're at it, their associated message widgets
714 for {set labelindex 0} {$labelindex < $numlabels} {incr labelindex} {
715 set currY [expr $bottom - round($labelindex*$tickStep)]
717 $W.metricsAxisCanvas create line $tickLeft $currY $right $currY -tag metricsAxisTag
719 set labelText [expr $metricMinValues(0) + $labelindex*$numericalStep]
720 message $W.metricsAxisCanvas.label$labelindex -text $labelText \
721 -justify right -width $labelWidth \
724 $W.metricsAxisCanvas create window $labelRight $currY -anchor e \
725 -tag metricsAxisItemTag \
726 -window $W.metricsAxisCanvas.label$labelindex
729 set numLabelsDrawn $numlabels
733 # the title changes to reflect the current metric(s)
734 # currently, only a single metric is supported
741 if {$numMetrics == 0} {
742 set newTitle "(no metrics currently defined)"
744 set newTitle "Metric: $metricNames(0) (Units: $metricUnits(0))"
747 $W.titleLabel configure -text $newTitle
750 proc myConfigureEventHandler {newWidth newHeight} {
751 #puts stderr "Welcome to myConfigureEventHandler; newWidth=$newWidth; newHeight=$newHeight"
754 # rethink how wide the resources should be
755 rethinkResourceWidths $newWidth
757 # Call drawResourcesAxis to rethink the scrollbar and to rethink the resource widths
758 drawResourcesAxis $newWidth
760 # We only need to redraw the y axis if the window height has changed
761 # (and at the beginning of the program)
762 drawMetricsAxis $newHeight
764 # Redraw the title (only needed if metrics changed)
767 # if the resources axis has changed then call this: (barChart.C)
768 resourcesAxisHasChanged $newWidth
770 # if the y axis has changed then call this: (barChart.C)
771 metricsAxisHasChanged $newHeight
773 # inform our C++ code (barChart.C) that a resize has taken place
774 resizeCallback $newWidth $newHeight
777 proc myExposeEventHandler {} {
778 # puts stderr "barChart.tcl -- welcome to myExposeEventHandler"
781 # all tk widgets redraw automatically (though not 'till the next idle)
783 # all that's left to do is inform our C++ code of the expose
787 proc addResource {rName} {
792 # first, make sure this resource doesn't already exist
793 for {set rindex 0} {$rindex < $numResources} {incr rindex} {
794 if {$resourceNames($rindex) == $rName} {
795 puts stderr "detected a duplicate resource: $rname (ignoring addition request)"
800 set resourceNames($numResources) $rName
803 drawResourcesAxis [getWindowWidth $W.bottom.resourcesAxisCanvas]
806 proc delResource {delindex} {
810 global clickedOnResource
811 global clickedOnResourceText
815 # first, make sure this resource index is valid
816 if {$delindex < 0 || $delindex >= $numResources} {
817 puts stderr "delResource -- ignoring out of bounds index: $delindex"
821 if {$clickedOnResourceText == $resourceNames($delindex)} {
822 set clickedOnResource ""
823 $Wmbar.resources.m entryconfigure 1 -state disabled \
824 -label "Remove Selected Resource" \
825 -command {puts stderr "ignoring unexpected deletion..."}
827 puts stderr "delResource -- no mbar changes since $clickedOnResourceText != $resourceNames($delindex)"
830 # inform that visi lib that we don't want to receive anything
831 # more about this resource
832 # NOTE: unfortunately, [Dg numResources] etc. will not be
833 # lowered, even after this is done! (******A bug********)
834 # The temporary solution is to rigidly test the
835 # Valid bit of each metric-resource pair before
837 for {set mindex 0} {$mindex < $numMetrics} {incr mindex} {
838 Dg stop $mindex $delindex
841 # shift resourceNames
842 for {set rindex $delindex} {$rindex < [expr $numResources - 1]} {incr rindex} {
843 set resourceNames($rindex) $resourceNames([expr $rindex + 1])
846 set numResources [Dg numresources]
847 # as mentioned above, the current visi-lib won't
848 # lower the value by 1...
850 # callback to barChart.C
851 resourcesAxisHasChanged
853 drawResourcesAxis [getWindowWidth $W.bottom.resourcesAxisCanvas]
856 proc delResourceByName {rName} {
860 # find the appropriate index and call delResource...
861 for {set rindex 0} {$rindex < $numResources} {incr rindex} {
862 if {$rName == $resourceNames($rindex)} {
868 puts stderr "delResourceByName: ignoring request to delete resource named: $rName (no such resource)"
871 proc getMetricHints {theMetric} {
873 # return metric unit type, hinted min, hinted max, hinted step
874 # depending on the metric (a hardcoded temporary hack)
876 "exec_time" {return {percentage 0.0 1.0 0.1}}
877 "hybrid_cost" {return {real 0.0 1.0 0.1}}
878 "procedure_calls" {return {integer 0 1000 100}}
879 "predicted_cost" {return {real 0.0 1.0 .1}}
880 "msgs" {return {integer 0 10 10}}
881 "msg_bytes" {return {integer 0 100 100}}
882 "pause_time" {return {percentage 0.0 1.0 .1}}
883 "msg_bytes_sent" {return {integer 0 100 100}}
884 "msg_bytes_recv" {return {integer 0 100 100}}
885 "active_processes" {return {integer 0 1 1}}
886 "sync_ops" {return {real 0.0 5 1}}
887 "observed_cost" {return {real 0.0 1.0 0.1}}
888 "sync_wait" {return {integer 0.0 5 1}}
889 "active_slots" {return {integer 0.0 2 1}}
890 "cpu" {return {real 0.0 1.0 0.1}}
893 puts stderr "NOTICE -- getMetricHints: unexpected metric: $theMetric...continuing"
894 return {real 0.0 1.0 0.1}
898 proc addMetric {theName theUnits} {
902 global metricUnitTypes
903 global metricMinValues
904 global metricMaxValues
907 puts stderr "Welcome to addMetric; name is $theName; units are $theUnits"
909 # first make sure that this metric isn't already present (if so, do nothing)
910 for {set metricIndex 0} {$metricIndex < $numMetrics} {incr metricIndex} {
911 if {$metricNames($metricIndex) == $theName} {
912 puts stderr "addMetric: ignoring request to add $theName (already present)"
918 set metricNames($numMetrics) $theName
919 set metricUnits($numMetrics) $theUnits
921 set theHints [getMetricHints $theName]
923 set metricUnitTypes($numMetrics) [lindex $theHints 0]
924 set metricMinValues($numMetrics) [lindex $theHints 1]
925 set metricMaxValues($numMetrics) [lindex $theHints 2]
929 drawResourcesAxis [getWindowWidth $W.bottom.resourcesAxisCanvas]
930 drawMetricsAxis [getWindowHeight $W.metricsAxisCanvas]
934 proc delMetric {delIndex} {
940 # first, make sure this metric index is valid
941 if {$delIndex < 0 || $delIndex >= $numMetrics} {
942 puts stderr "delMetric: ignoring out of bounds index: $delIndex"
947 for {set mindex $delIndex} {$mindex < [expr $numMetrics-1]} {incr mindex} {
948 set metricNames($mindex) $metricNames([expr $mindex + 1])
949 set metricUnits($mindex) $metricUnits([expr $mindex + 1])
952 set numMetrics [expr $numMetrics - 1]
955 drawResourcesAxis [getWindowWidth $W.bottom.resourcesAxisCanvas]
956 drawMetricsAxis [getWindowHeight $W.metricsAxisCanvas]
958 # don't we need to tell paradyn to stop sending us data on
962 proc processNewScrollPosition {newTop} {
963 # the -command configuration of the scrollbar is fixed to call this procedure.
964 # This happens whenever scrolling takes place. We update the x-axis canvas
965 global WresourcesCanvas
968 # puts stderr "barChart.tcl: welcome to processNewScrollPosition: newTop is now: $newTop"
974 # if max <= visible then set newTop 0
975 set currSettings [$W.sbRegion.resourcesAxisScrollbar get]
976 set totalSize [lindex $currSettings 0]
977 set visibleSize [lindex $currSettings 1]
979 if {$visibleSize > $totalSize} {
981 } elseif {[expr $newTop + $visibleSize] > $totalSize} {
982 set newTop [expr $totalSize - $visibleSize]
985 # update the x-axis canvas
986 # will automatically generate a call to myXScroll, which then updates the
987 # look of the scrollbar to reflect the new position...
988 $WresourcesCanvas xview $newTop
990 # call our C++ code to update the bars
991 newScrollPosition $newTop
994 proc myXScroll {totalSize visibleSize left right} {
995 # the -scrollcommand configuration of the resources axis canvas.
996 # gets called whenever the canvas view changes or is resized.
997 # The idea is to give us the opportunity to rethink the scrollbar that
998 # we are associated with. Four parameters are passed: total size,
999 # window size, left, right---arguments which we simply pass to the "set"
1000 # command of the scrollbar
1004 $W.sbRegion.resourcesAxisScrollbar set $totalSize $visibleSize $left $right
1007 # ############################################################################
1008 # ############# blt_drag&drop: declare that we are willing and able ##########
1009 # ######### to receive drag n' drops of type "text" (the type may change) ####
1010 # ############################################################################
1012 proc dragAndDropTargetHandler {} {
1013 # according to the drag n' drop interface, this routine will be
1014 # called via a "send" command from the source. So don't expect
1015 # to see this routine called from elsewhere in this file...
1017 # the variable DragDrop(text) contains what should be added
1020 # not yet implemented...
1021 puts stderr "Welcome to dragAndDropTargetHandler(); DragDrop(text) is $DragDrop(text)"
1022 addResource $DragDrop(text)
1025 #blt_drag&drop target . handler text dragAndDropTargetHandler
1026 #...that cryptic line reads: "declare the window '.' to be a drag n' drop
1027 # handler for sources of type 'text'; routine dragAndDropTargetHandler
1028 # gets called (via a "send" from the source...) Using window '.' means
1029 # the entire barchart...
1031 # #################### Called by visi library when histos have folded #################
1033 proc DgFoldCallback {} {
1034 puts stderr "FOLD detected..."
1039 # ########### Called by visi library when metric/resource space changes. #######
1041 # note: this routine is too generic; in the future, we plan to
1042 # implement callbacks that actually tell what was added (as opposed
1043 # to what was already there...)
1045 # ###############################################################################
1047 proc DgConfigCallback {} {
1048 # puts stderr "Welcome to DgConfigCallback"
1056 global metricMinValues
1057 global metricMaxValues
1060 global numResourcesDrawn
1061 global resourceNames
1063 set numMetrics [Dg nummetrics]
1064 for {set metriclcv 0} {$metriclcv < $numMetrics} {incr metriclcv} {
1065 set metricNames($metriclcv) [Dg metricname $metriclcv]
1066 set metricUnits($metriclcv) [Dg metricunits $metriclcv]
1068 # note -- the following 2 lines are very dubious for already-existing
1069 # resources (i.e. we should try to stick with the initial values)
1070 set metricMinValues($metriclcv) [lindex [getMetricHints $metricNames($metriclcv)] 1]
1071 set metricMaxValues($metriclcv) [lindex [getMetricHints $metricNames($metriclcv)] 2]
1074 set numResources [Dg numresources]
1075 for {set resourcelcv 0} {$resourcelcv < $numResources} {incr resourcelcv} {
1076 set resourceNames($resourcelcv) [file tail [Dg resourcename $resourcelcv]]
1079 # rethink the layout of the axes
1080 rethinkResourceWidths [getWindowWidth $W.bottom.resourcesAxisCanvas]
1081 drawResourcesAxis [getWindowWidth $W.bottom.resourcesAxisCanvas]
1082 drawMetricsAxis [getWindowHeight $W.metricsAxisCanvas]
1085 # inform our C++ code that stuff has changed
1086 resourcesAxisHasChanged [getWindowWidth $W.bottom.resourcesAxisCanvas]
1087 metricsAxisHasChanged [getWindowHeight $W.metricsAxisCanvas]
1090 # ################# AddMetricDialog -- Ask paradyn for another metric #################
1092 proc AddMetricDialog {} {
1096 # ################# AddResourceDialog -- Ask paradyn for another resource #################
1098 proc AddResourceDialog {} {
1102 proc ProcessNewSortPrefs {} {
1105 # redraw the resources axis
1108 # redraw the bars (callback to our C++ code)
1109 resourcesAxisHasChanged
1112 proc rethinkDataFormat {} {
1113 # invoked when a menu item from among "current, average, total"
1118 global metricMinValues
1119 global metricMaxValues
1122 # reset y-axis min & max values
1123 for {set metriclcv 0} {$metriclcv < $numMetrics} {incr metriclcv} {
1124 set metricMinValues($metriclcv) [lindex [getMetricHints $metricNames($metriclcv)] 1]
1125 set metricMaxValues($metriclcv) [lindex [getMetricHints $metricNames($metriclcv)] 2]
1128 # inform our C++ code that the data format has changed
1129 dataFormatHasChanged
1132 drawMetricsAxis [getWindowHeight $W.metricsAxisCanvas]
1135 # ######################################################################################
1137 # ######################################################################################