Views
A view draws. Given a source's field catalog and a Model to read from, it
binds the fields named in its panel config and renders, dispatching on each
field's kind — which is why any view renders data from any adapter.
Built-in views
| View | Renders kinds | What it does |
|---|---|---|
videoStack | video, image, file | Many fields merged into one synchronized tile grid. |
lineChart | series | Plots styled series (per-dim) over the timeline, windowed by read. |
timeline | cues | A scrub bar with labelled cue tracks, sharing the cursor. |
fieldsCatalog | any | A discovery table of the source's fields. |
Layout: a panel with children is a gridLayout (a CSS grid of nested
panels; columns default 2). Omit panels (or use view: autoLayout) for
auto-layout.
videoStack
Binds media fields and merges them into one component whose tiles share a cursor.
Each overlays entry names an annotation-file field in the same source and
its format — handJoints (21-joint skeletons), subtasks
(subtitle-style captions), or raw (the file already contains
MediaOverlay JSON); the exact JSON shape per format is specced in
Media overlays → data formats.
on targets one video field, or every tile when omitted. See the
schema example
live.
lineChart
series is a list of styled traces. Each field is a feature (all dims) or
[feature, dim] to select one dim; dim globs ([feature, "left_*"]) select
several. Per-series label, dash, color, width, opacity, ghost apply.
For a quick, unstyled chart use fields: [action, observation.state] instead of
series — every dim, auto-colored.
timeline
tracks binds cue fields, each with an optional label override. A track
may instead name an annotation FILE field with a format — the view
fetches and converts it into blocks (same contract as videoStack
overlays):
fieldsCatalog
A discovery table — point it at an unfamiliar dataset to see field names, kinds, and dim names.
Writing your own panel
A panel is a component that takes ViewProps. Inside you bind fields from the
config, read them, and draw — using cursor to stay in sync with the preview.
Register it per-preview with extensions.views, or once at app boot with
registerView (see Storage → register once, or per preview):
Conventions: a view holds only the Model (it calls read, never a storage);
sync via cursor (cursor.time, cursor.setHover, cursor.seek); window with
read(ref, { timeRange, maxPoints }).
Auto-layout
Omit panels (or place a { view: autoLayout, source }) and viz lays the source
out by kind: media → one videoStack, cues → one timeline, series → one
lineChart per feature (a grid past one) — in that order. It is the overview
layout; write panels explicitly once you know what to compare.
Next: Concept — why it is built in four layers.