Visualize.Backend.Hybrid (Visualize v0.8.0)

Copy Markdown View Source

Hybrid SVG/Canvas backend for optimized rendering.

Renders static elements (axes, labels, grids) as SVG and dynamic data (lines, points, areas) as Canvas commands. This provides the best of both worlds:

  • SVG for crisp, accessible static elements (rendered once)
  • Canvas for efficient high-frequency data updates

Usage

# Build your chart elements
axis_elements = build_axes(scales)
data_path = Shape.Line.generate_path(line, data)

# Render hybrid output
output = Visualize.Backend.Hybrid.render(
  static: axis_elements,
  dynamic: data_path,
  width: 800,
  height: 600,
  margin: %{top: 20, right: 20, bottom: 30, left: 40}
)

# Returns %{svg: "...", canvas_commands: "...", container: "..."}

In LiveView

<div class="hybrid-chart" style="position: relative;">
  <!-- Static SVG background (render once or on resize) -->
  <%= Phoenix.HTML.raw(@chart.svg) %>

  <!-- Dynamic Canvas overlay (updates frequently) -->
  <div
    id="chart-canvas"
    phx-hook="CanvasChart"
    data-commands={@chart.canvas_commands}
    data-width={@width}
    data-height={@height}
    style="position: absolute; top: 0; left: 0;"
  >
    <canvas width={@width} height={@height}></canvas>
  </div>
</div>

Summary

Functions

Renders a hybrid chart with SVG static elements and Canvas dynamic data.

Renders only the dynamic Canvas portion (for data updates).

Renders only the static SVG portion (for initial render or resize): an aria-hidden root, one layer of a picture another element names (spec/14 §21.4).

Functions

render(opts)

@spec render(keyword()) :: %{svg: String.t(), canvas: String.t(), html: String.t()}

Renders a hybrid chart with SVG static elements and Canvas dynamic data.

Options

  • :static - List of IR.Element for static rendering (axes, labels, grid)
  • :dynamic - IR.Path or IR.Element for dynamic data
  • :dynamic_style - Style map for the dynamic element (stroke, fill, etc.)
  • :width - Chart width
  • :height - Chart height
  • :margin - Margin map with :top, :right, :bottom, :left
  • :canvas_format - Canvas output format: :json (default), :js or :commands; the container's CanvasChart hook (Visualize.Hooks.Canvas) replays :json from data-commands and :js from data-script
  • :title, :description - the chart's accessible name and description (spec/14 §21.4, D-142), put on the <canvas> of html as Visualize.Backend.Canvas's root wrapper puts them; Visualize.Chart.Summary's name and text
  • :canvas_id - the prefix of the description's id (default "visualize-hybrid-canvas"), unique per chart on a page

The SVG layer is aria-hidden: it is one layer of a picture the canvas names.

Returns

  • %{svg: String.t(), canvas: String.t(), html: String.t()}

render_dynamic(opts)

@spec render_dynamic(keyword()) :: String.t()

Renders only the dynamic Canvas portion (for data updates).

render_static(opts)

@spec render_static(keyword()) :: String.t()

Renders only the static SVG portion (for initial render or resize): an aria-hidden root, one layer of a picture another element names (spec/14 §21.4).