[Charting]

AXIS chart: ChartHost, PaneManager, series factory, drawings, crosshair sync, and trade markers.

Charting

Charting is the spatial surface for OHLCV, overlays, and annotations. Implementation is imperative under a Solid shell so lightweight-charts owns its DOM subtree.

Abstract

ModuleRole
ChartHost.tsxSolid mount; empty-state overlay; lifecycle
pane-manager.tsMulti-pane LWC charts, time sync
series-factory.tsCandle/volume/line series helpers + palette
drawing-layer.tsUser + script drawings
crosshair-sync.tsCross-pane crosshair
pine-drawings.tsEngine drawing objects → layer
manager-access.tsProcess-wide manager/layer getters

Conceptual model

Interface surface

Panes

store.panes: { id, type, height, order, visible, label }.

typeTypical series
priceCandles + overlay lines + markers + drawings
volumeHistogram
indicatorNon-overlay plots
equityStrategy equity curve

Defaults: price + volume. Indicator/equity created on demand.

Empty / status overlay

When bars.length === 0, ChartHost shows contextual title/sub from store.status (loading, error, running, or “Load data to begin”).

Drawings toolbar

See operator guide Drawings. Tools: cursor, hline, trend, ray, rect, fib, measure, text.

Crosshair & time

syncTimeScales / syncCrosshair keep multi-pane navigation coherent. scrollToTime used from Results trade clicks.

Internals

Solid vs imperative boundary

// ChartHost — Solid owns outer shell
// PaneManager only mutates panesEl — never put Solid children inside panesEl

On cleanup: destroy drawing layer, dispose manager, clear accessors.

Data path

setDataToChart(bars) applies OHLCV; createEffect on store.bars re-applies if bars change outside load helper.

Run apply (chart side)

From runAndApply (indicators):

  • syncOverlayLines — update existing overlay series in place (avoids destroy→blank→add flash on live re-runs)
  • Markers from normalized events (set in place)
  • Script drawings atomic replace via DrawingLayer (setScriptDrawings without empty frame)
  • Equity series when strategy report warrants (silent live runs skip hide thrash)

History vs live bars

  • Full loads: loadBarschartDataGen++setDataToChart + fitContent
  • Live: multiplexappendBar + manager.appendBar only (no fitContent, no full setData)

series-factory

Centralizes series construction options and color palette so Results plot summary and chart stay chromatically related.

Invariants

  1. Solid reconciliation must not rewrite pane roots.
  2. Script drawings ephemeral per run; user drawings store-backed.
  3. Overlay default true unless meta.overlay === false.
  4. Manager may be null before mount—runner no-ops chart apply safely.

Failure modes

SymptomCause
Blank panes after hot reloadManager disposed; full remount
Overlays stack foreverOld path skipped removeOverlays
Fib/tools ignore clicksNo bars / time scale; wrong tool
Markers at t=0Event times not bar-aligned

Worked example (dev)

import { getManager } from './chart/manager-access';
getManager()?.scrollToTime(barTime);

See also