Phoenix LiveView JavaScript hooks for interactive visualizations.
This module bundles ten hooks:
ZoomHook— zoom and pan interactions (Visualize.Hooks.Zoom)BrushHook— brush selection (Visualize.Hooks.Brush)CanvasChart— replays Canvas commands or a script (Visualize.Hooks.Canvas)CanvasBinaryChart— replays the canvas binary format (Visualize.Hooks.CanvasBinary)CanvasIncrementalChart— scroll-and-copy incremental canvas updates (Visualize.Hooks.CanvasIncremental)ResizeHook— the container's size pushed once per settle (Visualize.Hooks.Resize)TooltipHook— a tooltip from the datum attributes an element carries (Visualize.Hooks.Tooltip)CrosshairHook— a rule and markers snapped to the nearest x of the data (Visualize.Hooks.Crosshair)LegendHook— a legend entry hides and shows the series it names (Visualize.Hooks.Legend)BuilderHook— a layer of the chart builder dragged into place, an inspector row clicked (Visualize.Hooks.Builder)
TooltipHook and CrosshairHook share hover, and BrushHook the brushed window, across
the charts of a sync group over one bus, VisualizeSync (Visualize.Hooks.Sync), which
the bundle defines before all three and does not export.
Installation
Write the JavaScript file:
File.write!("assets/js/visualize_hooks.js", Visualize.Hooks.js_code())
or Visualize.Hooks.install!/0, which writes it to default_path/0.
Import in your app.js:
import Hooks from "./visualize_hooks"
let liveSocket = new LiveSocket("/live", Socket, { hooks: Hooks })
Usage Examples
Zoom/Pan
<svg phx-hook="ZoomHook" id="zoomable-chart" data-min-zoom="0.5" data-max-zoom="5">
<g class="zoom-container">
<!-- Chart content -->
</g>
</svg>
# Handle zoom events
def handle_event("zoom", %{"k" => scale, "x" => x, "y" => y}, socket) do
{:noreply, assign(socket, transform: %{k: scale, x: x, y: y})}
endBrush Selection
<svg phx-hook="BrushHook" id="brush-chart" data-brush-type="x">
<g class="chart-content">
<!-- Chart content -->
</g>
</svg>
# Handle brush events
def handle_event("brush_select", %{"x0" => x0, "x1" => x1} = params, socket) do
# Filter data or zoom to selection
{:noreply, socket}
endCanvas
<div id="chart" phx-hook="CanvasBinaryChart" phx-update="ignore"
data-binary={@binary} data-width="800" data-height="600">
<canvas width="800" height="600"></canvas>
</div>See Visualize.Hooks.Canvas, Visualize.Hooks.CanvasBinary and
Visualize.Hooks.CanvasIncremental for the attributes and events of each.
Resize
<div id="panel" phx-hook="ResizeHook">
<!-- the chart, rendered at the pushed width and height -->
</div>
def handle_event("resize", %{"width" => width, "height" => height}, socket) do
{:noreply, assign(socket, width: width, height: height)}
endTooltip
<svg id="chart" phx-hook="TooltipHook">
<g class="mark" data-tooltip-template="{t}: {v}">
<circle cx="10" cy="20" r="3" data-datum="t v" data-datum-t="1" data-datum-v="4"/>
</g>
</svg>The attributes are what Visualize.IR.Element.datum/2 writes, and what a mark with a
tooltip node writes on every element. See Visualize.Hooks.Tooltip.
Crosshair
<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)The arrays are computed once on the server and the hook snaps to them, so it works over
a canvas as over an SVG. See Visualize.Hooks.Crosshair.
Legend
<svg id="chart" phx-hook="LegendHook" data-legend-event="legend_toggle">
<!-- a frame with a legend: every legend-item and every element a series draws carry data-series -->
</svg>A click on an entry hides the series it names with display="none" and shows it again
on the next; the event is optional. See Visualize.Hooks.Legend.
Builder
<ol id="layers" phx-hook="BuilderHook" data-builder-target={@myself}>
<li data-builder-layer="0" draggable="true">…</li>
</ol>The chart builder's two browser gestures: a layer dragged onto another pushes reorder,
and a click on an inspector row pushes inspect. See Visualize.Hooks.Builder.
Summary
Functions
Returns the path where hooks should be installed.
Writes the hooks JavaScript to the default location.
Returns the complete JavaScript code for all hooks.
Functions
Returns the path where hooks should be installed.
Writes the hooks JavaScript to the default location.
Returns the complete JavaScript code for all hooks.
Write this to a file in your assets directory.