Draggable Gantt-style schedule visualisation, two-way bound to a SchedulePlayer.

  • Renders every task in the player's schedule as a horizontal bar coloured by its tradeColor, with the task's display name baked into the bar.
  • Renders milestones as diamond chevrons on the time axis.
  • Draws a vertical cursor at the player's current date.
  • Click anywhere in the timeline area scrubs the cursor to that date. Drag the cursor itself for fine-grain scrubbing.
  • Play / pause / step-to-milestone buttons in the chrome bar.
  • A speed slider exposes the player's playbackSpeed directly.

The panel subscribes to player.onDateChanged / onPlay / onPause so any other UI (an InfoPanel slider, programmatic setDateMs, etc.) keeps the panel in sync. destroy() unsubscribes everything.

Hierarchy (View Summary)

Constructors

Properties

_classPrefix: string
_closeBtn: HTMLButtonElement

Close button (clicked → hide(), surfaces the pill).

_container: HTMLElement
_destroyed: boolean = false
_header: HTMLElement

Drag handle inside the panel — usually the title row.

_minHeight: number
_minWidth: number
_modal: boolean
_panel: HTMLElement

Root panel element. Populated by subclass in _buildDom().

_pill: HTMLElement

Floating "reopen" pill shown while the panel is hidden.

_resizable: boolean
_storageKey: string
_tier: "default" | "view"
onLayoutChanged: EventEmitter<FloatingPanelBase, void> = ...

Fires while the user drags the panel (one notification per pointermove during a drag) and once when the drag ends.

Drag changes the panel's CSS left / top but never its size, so a ResizeObserver on any descendant element never sees it. Subclasses or hosts that need to track the panel's viewport position — for example a View embedded in the body whose shared WebGL canvas must follow the panel — should subscribe to this and re-read the panel's bounding rect.

onVisibilityChanged: EventEmitter<FloatingPanelBase, boolean> = ...

Fires when show() / hide() toggles the panel's visibility.

Accessors

Methods

  • Inject eight invisible drag handles (4 edges + 4 corners) into _panel and wire pointer events. Each handle pins the panel to absolute left / top on pointerdown (so subsequent size + position writes take effect over any CSS that uses right / bottom), then writes new width / height — and, for north / west edges, new left / top — on pointermove. onLayoutChanged fires per move and at drag-end; the saved layout is updated on drag-end.

    min-width / min-height enforced from _minWidth / _minHeight; max-width / max-height are released by setting them to "none" inline so user-driven size is not clipped by CSS bounds like max-height: calc(100vh - 32px).

    Returns void

  • Engage the header drag from an external pointerdown / move event so the panel begins following ev immediately. Used by the drag-to-undock gesture on docked View cells — the cell's own pointer listener detects motion-past-threshold, replaces the cell with this freshly-created floating panel, and hands the live pointer over via this method.

    The panel is reflowed so the pointer sits inside its header at (panelOffsetX, panelOffsetY) from the panel's top-left. Then setPointerCapture routes all subsequent pointermove / pointerup events for this pointerId to the panel's own header, where _bindChrome's existing listeners drive the drag — no parallel drag loop required.

    Parameters

    • ev: PointerEvent
    • OptionalpanelOffsetX: number
    • OptionalpanelOffsetY: number

    Returns void

  • Rebuild the gantt against the player's current schedule. Call if the caller has mutated the schedule out from under the player (rare — Schedule is immutable, so the more common path is to construct a new player and a new panel).

    Returns void