@@ -215,14 +215,37 @@ page), ``"driven"`` (it is refreshed on every dispatch) or ``"static"``.
215215 emits; ``columns `` renames the block's columns when they
216216 are not ``x ``/``y `` (and ``u ``/``v ``, ``x1 ``…``y2 ``).
217217``reduce `` ``{block, navigator_panel} `` — a detector widget on this
218- panel re-maps the navigator. For a ragged block, name
219- the ``x ``, ``y `` and ``value `` columns.
220- ``chips `` ``[{label, block}] `` — per-position scalars, written into
221- ``#apl-chips-<panel_id> ``.
218+ panel re-maps the navigator (see below). For a ragged
219+ block, name the ``x ``, ``y `` and ``value `` columns.
220+ ``views `` ``[{label, block}] `` — a committed result's alternative
221+ frames (a strain map's εxx, εyy, εxy, ω). The page
222+ renders a segmented control that swaps which block the
223+ panel's frame is read from, at whatever position the
224+ navigator is on. With ``views ``, ``frame.block `` may be
225+ omitted and the first entry is shown first.
222226``readout `` ``{block, names, units} `` — written into
223227 ``#apl-readout-<panel_id> ``.
224228===================== ========================================================
225229
230+ ``frame `` also takes ``width `` and ``height ``, the pixel grid a ``"disks" ``
231+ raster is splatted into; they default to the panel's own image size. A
232+ navigator binding takes ``initial_index `` to open somewhere other than the
233+ origin.
234+
235+ How a virtual image flows through it
236+ ------------------------------------
237+
238+ The signal panel carries a detector widget — a rectangle, a circle or an
239+ annulus — and its binding's ``reduce `` names the block to read and the
240+ navigator panel to write. When the detector moves, the page turns the widget
241+ into a mask over the signal grid: every pixel whose integer coordinate lies
242+ inside the shape. It then sums, for each navigation position, that position's
243+ frame under the mask (a dense block) or the intensity of every row whose
244+ rounded position falls inside it (a ragged block). The result is one value per
245+ navigation position — exactly the navigator's own shape — and it goes to the
246+ navigator with ``setImage ``. Moving the detector therefore re-maps the whole
247+ scan, which is what a virtual image is.
248+
226249A binding that names a panel or a block the page does not carry raises
227250``ValueError `` at build time rather than rendering an empty figure.
228251
@@ -244,12 +267,14 @@ skip ``navigated_html`` and mount it directly:
244267 ``mountNavigated `` returns the ordinary ``mount() `` handle, so everything in
245268the table above still works on it.
246269
247- The readers are exported too, for chrome the page grows around the figure:
248- ``dense(block) `` and ``ragged(block) `` give ``at `` / ``gather `` / ``reduce ``,
249- ``maskFromWidget(widget, w, h) `` turns a rectangle, circle or annulus widget
250- into a selection mask, ``rasterDisks(rows, w, h, radius, combine) `` splats
251- rows as disks, and ``robustLevels `` / ``toU8 `` are the percentile window and
252- the 8-bit code map the renderer blits.
270+ The readers are exported too, under the ``embed `` namespace, for chrome the
271+ page grows around the figure: ``embed.dense(block) `` and ``embed.ragged(block) ``
272+ give ``at `` / ``gather `` / ``reduce ``, ``embed.maskFromWidget(widget, w, h) ``
273+ turns a rectangle, circle or annulus widget into a selection mask,
274+ ``embed.rasterDisks(rows, w, h, radius, combine) `` splats rows as disks, and
275+ ``embed.robustLevels `` / ``embed.toU8 `` are the percentile window and the 8-bit
276+ code map the renderer blits. ``mountNavigated `` is both a named export and a
277+ member of that namespace.
253278
254279Pushing frames: ``setImage ``
255280-----------------------------
@@ -263,8 +288,9 @@ here, because the bytes go straight to the renderer's draw path instead of
263288through base64 and a JSON trait.
264289
265290``opts.display_min `` / ``opts.display_max `` set the colour window the codes were
266- mapped over; geometry follows the bytes, so a frame of a different size just
267- works. The repaint lands on the next animation frame, so several frames pushed
291+ mapped over; geometry follows the bytes in the same animation frame, so a frame
292+ of a different size never paints once at the new dimensions over the old
293+ pixels. The repaint lands on the next animation frame, so several frames pushed
268294in one task paint once — call ``handle.flushImages() `` if you need the pixels
269295before then (``exportPNG `` and ``exportCanvas `` already do).
270296
0 commit comments