Visualize.Hooks.Crosshair (Visualize v0.2.35)

Copy Markdown View Source

Phoenix LiveView hook that snaps a rule and per-series markers to the nearest x of the data (spec/10 §13).

CrosshairHook never reads the chart's DOM: the server writes the mark's x pixels once, as data-xs, and the hook finds the nearest one to the pointer by binary search, so the same attributes serve a mark drawn as SVG and one the compiler sent to the canvas layer (D-76). attrs/3 computes them from a realised Visualize.Chart.Frame; the hook draws in an overlay it appends to document.body, so a LiveView patch of the chart never removes it, and re-reads the arrays on updated(). The overlay is placed over the chart itself — the container's first <svg> or <canvas> — not over the container, whose box the page lays out (spec/10 §13.3, #507).

In a sync group (spec/10 §4.3, §13.4) the hook publishes the pointer's x in domain units on the group's bus and draws every other member's hover at the nearest x of its own data; attrs/3 adds the frame's data-vis-sync and data-vis-sync-x when the frame is a group's (Visualize.Chart.Frame.sync_attrs/1).

Usage

<div id="chart" phx-hook="CrosshairHook" {@crosshair} data-crosshair-event="hover">
  {Phoenix.HTML.raw(@svg)}
</div>

crosshair = Visualize.Hooks.Crosshair.attrs(applied.frame, applied.sources)

def handle_event("hover", %{"index" => index}, socket) do
  {:noreply, assign(socket, hovered: index)}
end

Configuration

Data attributes on the container, from attrs/3 (spec/10 §13.2):

  • data-xs - the distinct x pixels, ascending, in plot coordinates
  • data-ys - one array per series of the y pixel at each x, null where absent
  • data-plot - left,top,width,height of the plot area inside the chart
  • data-size - width,height of the chart; absent, the chart element's own size. Over a canvas, the canvas's data-width/data-height are this size, from the same frame

Set by the host:

  • data-crosshair-event - the event pushed with {index} when the nearest index changes; unset, nothing is pushed
  • data-crosshair-color - the rule's stroke and the default marker fill (default: "#666")
  • data-crosshair-colors - a JSON array of one marker fill per series

Summary

Functions

As attrs/3 with no options: the first mark.

The data attributes of spec/10 §13.2 for one mark of the frame, computed once.

Returns the JavaScript source of CrosshairHook.

Functions

attrs(frame, sources)

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

As attrs/3 with no options: the first mark.

attrs(frame, sources, opts)

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

The data attributes of spec/10 §13.2 for one mark of the frame, computed once.

Options

  • :mark - the one-based position of the mark among the frame's marks (default 1)

Raises ArgumentError for a :facet or :polar frame, or a mark without x and y channels.

js_hook()

Returns the JavaScript source of CrosshairHook.