D
DreamLake

Views

Pre-built Views

vuer-m3u ships with a small set of views covering the common robotics + ML data types. Every view resolves its clock from the nearest <ClockProvider>, so you only need to wire src in the typical case.

Overview

ViewCompatible dtype(s)HooksSource rate (suggested)
ImuChartViewimu_6dof, vectoruseMergedTrack + 60fps Canvas50–200 Hz
ImuGizmoViewimu_6dofuseMergedTrack + useTrackSample (lerp)50–200 Hz
JointAngleViewjoint_anglesuseMergedTrack + useTrackSample (lerp)30–250 Hz
PoseViewpose_6dofuseMergedTrack + two useTrackSample (lerp + slerpQuat)30–120 Hz
ActionLabelViewaction_labeluseSegment + usePlaylistevent-driven
VideoPlayervideo— (hls.js)
DetectionBoxViewdetection_2duseSegmentevent-driven
SubtitleViewsubtitleuseSegmentevent-driven
BarTrackViewany continuous dtype — scalar, vector, joint_angles, imu_6dof, pose_6dofuseMergedTrack + useTrackSample (lerp)any
URDF Robot (integration)joint_anglesuseJointAnglesForUrdf30–250 Hz

Per-dtype JSONL schemas live on the Dtypes pages.

Two ways to use a view

1. Direct import — pick the view yourself

Simplest path. Import the view component by name and pass it a src:

import { JointAngleView } from '@vuer-ai/vuer-m3u'
 
<JointAngleView src="/robot/qpos.m3u8" />

Great when you know exactly which view fits the track. Views resolve their clock from <ClockProvider> automatically.

2. Dispatch by dtype — <TrackerContainer>

When you have a list of tracks and want one view per track, let the container dispatch:

import {
  TrackerContainer,
  defaultTrackerViews,
  type TimelineConfig,
} from '@vuer-ai/vuer-m3u'
 
const config: TimelineConfig = {
  container: { id: 'ep1', duration: 30 },
  tracks: [
    { id: 'q',   path: 'robot/arm',   dtype: 'joint_angles', src: '/q.m3u8' },
    { id: 'imu', path: 'sensors/imu', dtype: 'imu_6dof',     src: '/imu.m3u8' },
    { id: 'cam', path: 'cams/wrist',  dtype: 'video',        src: '/cam.m3u8' },
  ],
}
 
<TrackerContainer config={config} views={defaultTrackerViews} controller />

defaultTrackerViews wires dtype → view:

DtypeView
videoVideoPlayer
subtitleSubtitleView
scalar / vectorBarTrackView
imu_6dofImuChartView
joint_anglesJointAngleView
pose_6dofPoseView
action_labelActionLabelView
detection_2dDetectionBoxView

Dtypes without an entry (audio, image, marker_event, ribbon_state) render a placeholder instead — ship your own by spreading a view in, or use <TimelineContainer> where every built-in dtype has a default lane.

Override a subset by spreading:

views={{ ...defaultTrackerViews, imu_6dof: ImuGizmoView }}

Same config, two containers

<TrackerContainer> and <TimelineContainer> take the same TimelineConfig. One data object, two presentations — swap components to swap the view mode:

const [mode, setMode] = useState<'tracker' | 'timeline'>('tracker')
 
return mode === 'tracker'
  ? <TrackerContainer  config={config} views={defaultTrackerViews}  />
  : <TimelineContainer config={config} views={defaultTimelineViews} />

Both containers resolve clock identically (prop → context → internal). Wrap them in a single <ClockProvider> and play/seek syncs across both.

Choosing a view

  • Discrete vs continuous — if each segment is a self-contained list (events, cues), use a useSegment view. If the data is a dense time-series you want to scrub and interpolate, use a useMergedTrack view.
  • Interpolator — quaternion data must go through slerpQuat to avoid non-unit intermediates; that's why PoseView splits data into position and orientation tracks internally.
  • Render rate — the views default to 15–30 fps React updates. Tune via the fps prop if you need a faster scrubber or a quieter display.

Not finding what you need?

See Custom Views for step-by-step mini implementations built from the same four core hooks, and a checklist for adding a new view (including the companion doc page).