Visualize.Hooks.Keyboard (Visualize v0.8.0)

Copy Markdown View Source

Phoenix LiveView hook that reaches a chart's points from the keyboard (spec/10 §17, spec/14 §21.5, D-142).

KeyboardHook makes the chart one tab stop. Inside it the arrow keys move between the points of a series and between series, Home and End jump to a series' ends, and a polite live region reads the point: y, 3 of 51: x 2, y 54.3. Like CrosshairHook it never reads the chart's DOM: attrs/1 writes every point once on the server — its readout and its position in the chart's pixels — so the same attributes serve a chart drawn as SVG and one on a canvas. The live region and the focus marker are appended to document.body, so a LiveView patch of the chart neither removes nor sees them.

A board adds the order across its cells one level up: each cell one stop, or, when the board moves between cells with arrows, Escape inside a chart hands focus back to the nearest element carrying data-vis-cell.

Usage

<div id="chart-keys" phx-hook="KeyboardHook" {Visualize.Hooks.Keyboard.attrs(applied)}>
  {Phoenix.HTML.raw(@svg)}
</div>

Configuration

Data attributes on the container, from attrs/1 (spec/10 §17.2):

  • data-keyboard-name - the chart's name
  • data-keyboard-points - per series, {"name", "points": [[x, y, readout], …]}
  • or, from listed/2, data-keyboard-series - per series, {"name", "count"} - with each point the data-p of one child of the element inside carrying data-keyboard-list (D-204)
  • data-size - width,height of the chart
  • data-vis-focused - the palette's :focused, resolved for the chart's frame: a JSON object of SVG attributes laid over the focus marker's own (spec/10 §4.4); absent, the marker is a 2-pixel currentColor ring

Set by the host:

  • data-keyboard-event - the event pushed with {series, index} when the focused point changes; unset, nothing is pushed
  • data-keyboard-pick-event - the event pushed with {series, index} when a point is picked: Enter at the reached point, or a click, which picks the point nearest to it (spec/10 §17.3, spec/15 §13); unset, nothing is picked
  • data-keyboard-target - the phx-target both events go to with pushEventTo; unset, they go to the LiveView

Summary

Functions

The data attributes of spec/10 §17.2 for an applied chart, computed once: its name, its points by series with their readouts and positions, its size, and the focus marker's style, the palette's :focused as the chart's design and theme resolve it (§4.4).

Returns the JavaScript source of KeyboardHook.

The attributes of attrs/2 with the points one element each, keyed, for a page that sends them as a LiveView comprehension, so a change sends the points it changed and no other (spec/10 §17.2, D-204): {attrs, points, cache}. The attributes carry data-keyboard-series, each series' name, grid and how many points it has, in place of data-keyboard-points; points is every point in series order as {key, json}, json the point as data-keyboard-points writes it and key its series' position and its own, "0.17". The page writes each point as the data-p of one child of an element carrying data-keyboard-list inside the hook's element, in order

Functions

attrs(applied, opts \\ [])

@spec attrs(Visualize.Chart.Applied.t(), keyword()) :: %{
  required(String.t()) => String.t()
}

The data attributes of spec/10 §17.2 for an applied chart, computed once: its name, its points by series with their readouts and positions, its size, and the focus marker's style, the palette's :focused as the chart's design and theme resolve it (§4.4).

Options

  • :placements - Visualize.Chart.placements/1 of the same chart, which a caller that also draws it passes to both, so each point is placed once (#811)

js_hook()

Returns the JavaScript source of KeyboardHook.

listed(applied, opts \\ [])

@spec listed(Visualize.Chart.Applied.t(), keyword()) ::
  {%{required(String.t()) => String.t()}, [{String.t(), String.t()}], map()}

The attributes of attrs/2 with the points one element each, keyed, for a page that sends them as a LiveView comprehension, so a change sends the points it changed and no other (spec/10 §17.2, D-204): {attrs, points, cache}. The attributes carry data-keyboard-series, each series' name, grid and how many points it has, in place of data-keyboard-points; points is every point in series order as {key, json}, json the point as data-keyboard-points writes it and key its series' position and its own, "0.17". The page writes each point as the data-p of one child of an element carrying data-keyboard-list inside the hook's element, in order:

<div hidden data-keyboard-list>
  <i :for={{key, point} <- @points} :key={key} data-p={point}></i>
</div>

Options

  • :placements - as attrs/2
  • :cache - the cache the last call returned: a point the same as last time is not written again (default %{})