Skip to content

Selection Architecture

Karan Dodia edited this page Aug 27, 2014 · 13 revisions

Requirements

  • handle multiple types of selections: POINT, LINE, CIRCLE, RECT, OVAL, POLY, LASSO
  • draw overlays for selections
  • hittest against renderers' data
  • render selected/non-selected glyphs differently according to policies
  • be able to combine disjoint selections (e.g. ctrl-click in listboxes)
  • execute selection callbacks
  • that happen continuously (every mouse event)
  • that only happen when a selection is "final"

Components

Selection: list of indices into data source

Selection Geometry: object that describes a region to hittest. Has a type, and whatever attributes are appropriate for that type. All coordinate and measures are in screen space/units. Examples:

selection:
  type : "point" 
  x    : 110 
  y    : 512
selection:
  type   : "circle" 
  x      : 110 
  y      : 512
  radius : 5
selection:
  type : "line" 
  x1   : 110 
  y1   : 512
  x2   : 120
  y2   : 480
selection:
  type : "rect" 
  x1   : 110 
  y1   : 512
  x2   : 137
  y2   : 564
selection:
  type : "poly" 
  xs   : [...] 
  ys   : [...]

Selection Highlight Policy: functions that accept a glyphspec and return a new glyph spec. For example, a policy to dilate the size of glyphs might be defined:

  dilate = (factor, attr="size") ->
    return (glyphspec) ->
        new_spec = _.clone(glyphspec)
        new_spec[attr] *= factor

Also can just be new glyphspec to replace default spec with wholesale.

Glyph Renderer: holds data for glyphs, as well as current selections. Responsible for:

  • carrying out hittest, given a selection geometry
  • rendering glyphs using selection/non-selection policies as appropriate

Selection Overlays: renderers that draw boxes, ploys, etc on top of plot. Used by selection tools.

Selection Tool: handles mouse/key/touch events

  • construct appropriate selection geometry from user interactions
  • update selection overlays with new geometry
  • update selection manager with new geometry

Selection Manager: registers selection callbacks on glyph renderers. Responsible for:

  • hittest glyph renderers against selection geometries supplied from tools
  • handles appending/replacing existing selection as needed
  • update the glyph renderers' selections
  • execute callbacks when appropriate

Diagram

Additional Notes and Questions

  • propose to use RTree.js as an efficient spatial index for bounding boxes of data items
  • question: data-space or screen-space? Probably either, depending on the situation...
  • Should tools/overlays be made plot-independent? i.e. should one pan tool be able to service multiple plots? (Question motivated by grid plot case.)
    • Yes. --peter
  • Should selections themselves be more than just lists of indices? Oftentimes an index range, or a list of index ranges, can be the most compact, and the client side can do in-out testing against those just as easily, especially if there was a way to communicate when index ranges are non-overlapping and monotonically increasing. (Actually, overlapping isn't even a problem, from an implementation standpoint.)
  • Need to think about the (common) situation when selections are made over renderers that are backed by a subset of columns in a data table. Let's say we box-select two scatter plots, of Index vs. columns A and B. This will may hit different indices in each column. Should we union the indices? For range select, yes; for box select; no. More significantly, should we select the entire row, i.e. for columns C, D, and E which are not present in this plot, but might be rendered in related plots, do we link the selection? To handle this question we need the renderers to optionally provide selection masks back to the selection tool (as a memento).