szubtsovskiy / elm-visualization / Brush

Brushing is the interactive specification of a one- or two-dimensional selected region using a pointing gesture, such as by clicking and dragging the mouse. Brushing is often used to select discrete elements, such as dots in a scatterplot or files on a desktop. It can also be used to zoom-in to a region of interest, or to select continuous regions for cross-filtering data.

This module implements brushing for mouse events using SVG. Click and drag on the brush selection to translate the selection. Click and drag on one of the selection handles to move the corresponding edge (or edges) of the selection. Click and drag on the invisible overlay to define a new brush selection, or click anywhere within the brushable region while holding down the META (⌘) key. Holding down the ALT (⌥) key while moving the brush causes it to reposition around its center. Holding SHIFT (⇧) locks the dragging to a single dimension.


type Brush dimension

Encapsulates all the data we need to maintain the state of the brush. The dimension type variable can either be OneDimensional or TwoDimensional. This allows us to share a lot of the implementation details as well as implement generic UI customizations over brushes regardless of their dimensionality.

You will typically want to store this in your model.


type OneDimensional


type TwoDimensional

Configuring the Brush behavior

Initializing the brush always requires you to specify in local coordinates the rectangular region where the brush will be active.

initX : Extent -> Brush OneDimensional

Initializes a brush that allows brushing in the X axis.

initY : Extent -> Brush OneDimensional

Initializes a brush that allows brushing in the Y axis.

initXY : Extent -> Brush TwoDimensional

Initializes a two dimensional brush.


type alias Extent =
{ top : Basics.Float
, bottom : Basics.Float
, left : Basics.Float
, right : Basics.Float 
}

Defines a rectangular region.

keyboardModifiersEnabled : Basics.Bool -> Brush dimension -> Brush dimension

By default the brush will use the meta/alt and shift keys to change behavior. You can disable this with this function.

Querying the brush state

selection1d : Brush OneDimensional -> Maybe ( Basics.Float, Basics.Float )

Exposes the selection for a single dimensional brush, where the first number should always be less than the second.

selection2d : Brush TwoDimensional -> Maybe Extent

Exposes the selection for a two dimensional brush.

Updating the Brush


type OnBrush

This is the Msg type that this module uses for communicating between the update and the view.

Note that when handling these messages, it is also extremely likely that the brush selection has somehow changed, so you can also use that place in your update function to react to that.

update : OnBrush -> Brush dim -> Brush dim

Call this in your update function to make the brush work!

subscriptions : Brush dim -> (OnBrush -> msg) -> Platform.Sub.Sub msg

Don't forget the subscriptions, otherwise drag gestures won't work!

Manipulating the Selection

setSelection1d : TransitionOption -> ( Basics.Float, Basics.Float ) -> Brush OneDimensional -> Brush OneDimensional

Programatically set the selection of the Brush.

setSelection2d : TransitionOption -> Extent -> Brush TwoDimensional -> Brush TwoDimensional

Programatically set the selection of the Brush (in two dimensions).

clearSelection : Brush dim -> Brush dim

Clears the selection programmatically.

 brush
   |> Brush.clearSelection
   |> Brush.selection1d --> Nothing


type TransitionOption

instantly : TransitionOption

Perfom the update to the brush instantly, rather than with an animation (animations are not supported yet.)

View

view : List (Attribute msg) -> (OnBrush -> msg) -> Brush dim -> Svg msg

Actually renders the the brush selection widget. You can customise the appearance by passing in functions to render the individual pieces.

The actual widget consists of:

  1. An overlay invisible rectange which covers the interactive area.
  2. The selection rectangle.
  3. Handles in each direction the brush supports being dragged to.


type Attribute msg

This is a type used to customize the view function of this module. However most of the functions that produce the type may appear to also consume it. However, this is not the case, the functions take VirtualDom attributes, but produce this Attribute type.

selectedArea : (Extent -> List (Svg.Attribute msg) -> Svg msg) -> Attribute msg

Customize rendering for the rectangular region that is the selection.

The first argument is the actual coordinates of the selection, the second are the event handlers.

The default version renderes a <rect fill="#777" fill-opacity="0.3" stroke="white" shape-rendering="crispEdges">.

bottomHandle : (Extent -> List (Svg.Attribute msg) -> Svg msg) -> Attribute msg

Customise how to render the bottom handle.

leftHandle : (Extent -> List (Svg.Attribute msg) -> Svg msg) -> Attribute msg

Customise how to render the left handle.

rightHandle : (Extent -> List (Svg.Attribute msg) -> Svg msg) -> Attribute msg

Customise how to render the right handle.

topHandle : (Extent -> List (Svg.Attribute msg) -> Svg msg) -> Attribute msg

Customise how to render the top handle.

topLeftHandle : (Extent -> List (Svg.Attribute msg) -> Svg msg) -> Attribute msg

Customise how to render the top left handle. Only applies to a 2D brush.

topRightHandle : (Extent -> List (Svg.Attribute msg) -> Svg msg) -> Attribute msg

Customise how to render the top right handle. Only applies to a 2D brush.

bottomLeftHandle : (Extent -> List (Svg.Attribute msg) -> Svg msg) -> Attribute msg

Customise how to render the bottom left handle. Only applies to a 2D brush.

bottomRightHandle : (Extent -> List (Svg.Attribute msg) -> Svg msg) -> Attribute msg

Customise how to render the bottom right handle. Only applies to a 2D brush.