A virtual base class for data models that store a selection, which might be of items, regions, or whatever. Clients can register handlers for selection changes and can create proxy models to transform selections, link across datasets and map selections to actions on the data.

This design is preliminary and subject to change.

Interpreting The Selection

Internally, the selection may be stored as any object, including as a function that is invoked whenever the selection is stored or retrieved. The function allows dynamic mapping of selections. Due to this generality, the client should not access the selection directly. Instead, it should explicitly coerce the selection object to an interpretable representation. The set of supported coercions depends on the subclass. For example, ItemSelection has a as.logical method that coerces it to a logical vector, where an element is TRUE if the corresponding element in the dataset is selected.

Responding to Selection Changes

Whenever the selection is changed, the changed signal is emitted. The signal has zero arguments. See the objectSignals package for details on using signals.

Eventually, a selection leads to the execution of some action by the application. In interactive graphics, that action usually involves scaling/transforming the selection to a modification on the data. The x$scale(scaler, data) method tries to facilitate these operaitons. All it does is create a handler for the changed signal on x that passes x and data to the function scaler, which implements the change.

The Selection Calculus

Since any type of object can represent a selection, setting the selection has very few constraints. There are several ways to modify the selection. Not all of them will be supported by every subclass. In the code snippets below, x represents a Selection object and selection represents the primary representation of a selection, like a logical vector.


x$replace(selection): this is supported by all implementations.


x$add(selection): the result contains the union of the original selection and selection.


x$subtract(selection): the result contains the original selection except that indicated by selection.


x$intersect(selection): the result contains the intersection of the original selection and selection.


x$toggle(selection): The intersection of the original selection and selection is deselected, that only in selection is selected.

Linking Selections

In interactive graphics, it is often necessary to link selections within and across datasets. The x$link(linker) method creates a new Selection object that proxies x and maps the selection in x through linker. Changes to the selection in x will propagate via linker to changes in the proxy. Analogously, the linker will pass modifications to the proxy down to x.

The linker may be provided as an integer vector, like that returned by match, but it is usually a function, as that allows very general linking strategies. As an example, let us consider a simple linker between two datasets based on key matching. We assume that the keys, source_keys and dest_keys, are in the enclosure of our linker function.

    function(source_selection, new_dest_value) {
      if (missing(new_dest_value))
      else source_keys 

The linker function takes one or two arguments, depending on whether the selection is being retrieved or stored. When the selection is being retrieved, source_selection is passed as the only argument. The duty of the linker is then to retrieve the underlying selection from source_selection (through coercion, see above) and figure out which keys in the destination selection match the selected source keys. The new_dest_value argument is provided whenever the selection is being stored/set. In that case, the analogous operation is performed, in the opposite direction. The symmetry here is fairly obvious, and duplex_data_linker is a utility for facilitating the implementation of such two-way linking functions.


Michael Lawrence

See Also

The ItemSelection and RegionSelection subclasses, which have examples.

comments powered by Disqus