Loon: An Interactive Statistical Visualization Toolkit

Event Bindings

Event bindings provide the functionality of binding code to specific event types. The bound code is called a callback. In loon, we distinguish between four classes of events: state change events, item events, canvas events and content events. Examples of each type of event (in the same order as mentioned before) include: a selected state modification of a plot, moving the mouse cursor over a point glyph, re-sizing the plot window and adding a layer.

For example, a state binding is triggered on particular state changes

set p [plot -x {1 2 3} -y {3 2 1}]

$p bind state add {selected active xTemp} {puts "%W had events: %e"}

The above code creates a plot with three points and adds a state binding that evaluates the callback code puts "%W had event %e" if any of the states selected, active or xTemp get changed of p. The %W and %e get substituted with the widget path name and a list of the events that were responsible for the code to be evaluated, respectively.

There are also a number of other bindings:

Besides the bind subcommand we also provide the systembind subcommand. bind and systembind can be used interchangeably. systembind is used for loon's own use and no error catching is performed when evaluating system binding code.

State Change Bindings

State bindings get triggered when widget states change. For more information on widget states see the states documentation.

A configure call that changes multiple states will collect which states have changed and only evaluate the change bindings once. For example

set p [plot -x {1 2 3} -y {3 2 1}]

$p bind state add {selected active xTemp} {puts "%W had events: %e"}

$p configure -selected {T F F} -size {1 4 3}

#% .l0.plot had events: selected size

$p configure -xTemp {1 1 1}

#% .l0.plot had events: xTemp

A couple of notes:

A state binding gets thrown only if at least one state is really changed. Suppose at least one point is not selected, then

$p configure -selected 1
#% .l0.plot had events selected
$p configure -selected TRUE

The above code will only throw one event for the first expression and no event for the second expression, as the selected state does not change (1 and TRUE both represent the same logical value).

Substitutions

The current substitutions for state bindings are

string substituted value
%W widget path name
%e states that got changed
%b binding id
%O object path, useful for debugging

List, Reorder & Delete Bindings

Assume the following plot and bindings

set p [plot -x {1 2 3} -y {1 2 3}]
$p bind state add all {puts A}
$p bind state add {selected active} {puts B}
$p bind state add {showAxes selected} {puts C}
$p bind state add {zoomX panX selected} {puts D}

To list the bindings use

$p bind state ids

#% stateBinding0 stateBinding1 stateBinding2 stateBinding3

To get the binding events and callback say for stateBinding0 use

$p bind state get stateBinding0

#% all {puts A}

The order of binding evaluation is as returned by bind state ids for those bindings that are triggered by a particular state change. For the above example all bindings are triggered by a selected state change, hence, changing the selected state of p would print A, B, C and D. The evaluation can be reversed/changed as follows

$p bind state reorder [lreverse [$p bind state ids]]

Now a change of the selected state of p would cause to print the letters D,. C, B, A.

Finally, to delete a binding use

$p bind state delete stateBinding0

Other State Bindings

Next to a loon's displays the layers, glyphs, navigators and contexts support state bindings too. We now demonstrate this with a layer state binding (note that this it will work with all the other types the same).

set p [plot -x {1 2 3} -y {1 2 3}]
set l [$p layer rectangle -x {1 3} -y {1 3} -color blue]
$p layer use $l bind state add color {puts "layer color has changed"}
$p layer use $l configure -color green

#% layer color has changed

Item Bindings

Item bindings are triggered by a mouse/keyboard gesture over a visual item in a plot. Visual items include point glyphs, layers, axes and labels. Every visual item has a set of tags as outlined in the Visual Item Tags section. In addition, displays and layers have a tag state for user specified tags.

Note that item bindings are Tk canvas bindings with one level of indirection in order to support loon's context specific substitutions instead of the standard Tk substitutions.

Valid event patterns for mouse/keyboard gestures are taken from the Tk bindings. The tag specification for item bindings allow for logical expressions of Visual Item Tags using the operators &&, ||, ^,!, and parenthesized subexpressions (see the Tk canvas manual).

To get the tags for the item that lies below the mouse cursor use the currenttags subcommand. To get the index (in relation to the abstract dimension) of the visual item below the mouse cursor (if there is an index) use the currentindex subcommand.

For example, say we wish to print out the point number in a scatterplot on leaving and entering the point

set p [plot -x {1 2 3} -y {1 2 3}]

$p bind item add "model&&point" <Enter> {puts "Entered point [%W currentindex]"}
$p bind item add "model&&point" <Leave> {puts "Left point [%W currentindex]"}

The item binding API also support List, Reorder & Delete Bindings, but the item binding order has currently no effect.

Substitutions

The current substitutions for item bindings are

string substituted value
%W widget path name
%b binding id
%O canvas path, useful for debugging
%x x coordinate
%y y coordinate

Visual Item Tags

Visual items have tags. It is possible to add user defined tags with the tag state for the relative object (i.e. plot and layer). There are, however, also tags that we use which are listed in the table below.

It is possible to query the item tags interactively with a mouse button press on an item as follows

set p [plot -x {1 2 3} -y {1 2 3} -xlabel xlab\
    -ylabel ylab -title "Query Visual Item Tags"]

$p bind item add all <Enter> {puts "[%W currenttags]"}

The current tagging scheme for the histogram, scatterplot and graph displays is

Canvas Bindings

Canvas bindings are in contrast to the item bindings triggered by a mouse/keyboard gesture over the plot as a whole. Canvas bindings are for example useful if one wants to capture plot resize events or a mouse moving events.

As for item bindings the valid event patterns for mouse/keyboard gestures are taken from the Tk bindings.

For the first example, we print the size of the plot when it gets resized.

set p [plot -x {1 2 3} -y {1 2 3}]

proc printSize {widget width height} {
    puts [format "Size of widget %s is %sx%s pixels" $widget $width $height]
}

$p bind canvas add <Configure> {printSize %W %w %h}

Or, say, we want to track the mouse and print out its location in data coordinates

set p [plot -x {1 2 3} -y {1 2 3}]

proc printLocation {widget x y} {
    puts [format "In widget %s the location of the mouse cursor is at: %s and %s"\
        $widget $x $y]
}

$p bind canvas add <Motion> {printLocation %W %x %y}

Substitutions

The current substitutions for canvas bindings are

string substituted value
%W widget path name
%b binding id
%O canvas path, useful for debugging
%x x coordinate
%y y coordinate
%w plot width in pixel
%h plot height in pixel

Content Bindings

There are also layer, glyph, navigator and context bindings. These bindings get evaluated if the collection of one of those changes. For example

set p [plot -x {1 2 3} -y {1 2 3}]

$p bind layer add {add delete} {puts "Widget %W had event %e for layer: %l"}

$p layer texts -x {2 2} -y {1.5 2.5} -text {A B}

#% Widget .l0.plot had event add for layer layer1

Valid events for the different types are