@christtrade/depth 0.17.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,7 +10,7 @@ import { ExecutionEngine } from './ExecutionEngine';
10
10
  import type { FillSearchOptions } from '../lib/matchingEngine';
11
11
  import { LiveTransformer } from '../interfaces/ICoordinateTransformer';
12
12
  import { BottomBarItem, ChartPlugin, InstalledPlugin, PluginType, ToolbarItem } from './PluginRegistry';
13
- import { RenderEngine } from './RenderEngine';
13
+ import { RenderEngine, type DrawHook, type DrawPhase } from './RenderEngine';
14
14
  import { ChartEvents, TypedEventBus } from './TypedEventBus';
15
15
  import { ChartState } from './ChartState';
16
16
  import type { SyncInLayout } from '../lib/types/layout-sync';
@@ -18,6 +18,8 @@ import { ChartModel, type ChartPaneState } from './ChartModel';
18
18
  import { DrawingStore } from './DrawingStore';
19
19
  import { ChartPane, Indicator } from '../lib/types/indicator-types';
20
20
  import { AccountManager, LedgerAdjustment, LedgerFill, LedgerOrder, LedgerPosition, type AccountSaveState } from './AccountManager';
21
+ import type { ThemeDef } from '../interfaces/plugins/IChartPlugin';
22
+ import type { StyleField } from '../components/drawings/drawing-settings-dialog';
21
23
  import { PlaybackMode, type PrefetchOptions } from '../hooks/usePlaybackEngine';
22
24
  import { type ChartPreferences } from '../lib/storage';
23
25
  import { type PluginCatalogEntry, type PluginStartupEntry, type PluginStartupRecord } from './plugin-startup';
@@ -101,6 +103,8 @@ export interface ChartOptions {
101
103
  */
102
104
  restore?: ChartSaveState;
103
105
  toolbar?: (chart: DepthChart) => React.ReactNode[];
106
+ /** Theme id to start on. Register custom ones with `chart.registerTheme()` first. */
107
+ theme?: string;
104
108
  }
105
109
  /** Bump when the save document shape changes incompatibly; handled in migrate(). */
106
110
  export declare const SAVE_VERSION = 1;
@@ -175,12 +179,15 @@ export declare class DepthChart {
175
179
  private readonly options;
176
180
  readonly id: string;
177
181
  readonly eventBus: TypedEventBus;
182
+ private readonly _themes;
183
+ private readonly _themeStyle;
178
184
  readonly executionEngine: ExecutionEngine;
179
185
  private readonly dataEngine;
180
186
  readonly transformer: LiveTransformer;
181
187
  private features;
182
188
  private readonly pluginRegistry;
183
- private _renderEngine;
189
+ private readonly _engines;
190
+ private _pluginRenderEngine;
184
191
  private _panelRegistry;
185
192
  private _toolbarRegistry;
186
193
  private _bottomBarRegistry;
@@ -192,9 +199,11 @@ export declare class DepthChart {
192
199
  private registeredPlugins;
193
200
  private _pluginStateListeners;
194
201
  private _pluginCatalog;
202
+ private _panesRestored;
195
203
  private playbackController;
196
204
  private readonly playbackStateRegistry;
197
205
  private readonly pluginSchedules;
206
+ private readonly extensionParams;
198
207
  readonly state: ChartState;
199
208
  private readonly _panes;
200
209
  readonly drawingStore: DrawingStore;
@@ -225,7 +234,7 @@ export declare class DepthChart {
225
234
  openBar(): OhlcvBar | null;
226
235
  /** What the chart holds for the active symbol - the same snapshot a plugin's `ctx.getData()` returns. */
227
236
  getData(): ChartDataSnapshot;
228
- /** The paint loop, once a pane has mounted one. */
237
+ /** The focused cell's paint loop, once a cell has mounted one. Every cell's: `getRenderEngines()`. */
229
238
  get renderEngine(): RenderEngine | null;
230
239
  getMaxLookbackBars(): number;
231
240
  horizon(): number;
@@ -402,6 +411,7 @@ export declare class DepthChart {
402
411
  * document decide again.
403
412
  */
404
413
  setPluginStartup(id: string, entry: Partial<PluginStartupEntry> | null): this;
414
+ private _deactivateRemoved;
405
415
  /**
406
416
  * Install what this session should open with: every plugin a restored pane
407
417
  * references, plus every plugin marked autostart. Idempotent - already-loaded
@@ -438,6 +448,18 @@ export declare class DepthChart {
438
448
  * set of ids actually changes - pane models notify on unrelated churn (axis
439
449
  * drags rewrite settings every frame) that callers shouldn't re-render on.
440
450
  */
451
+ /**
452
+ * The settings a loaded extension declared with `params`, and their current
453
+ * values. Null when it declared none. A script holding several extensions
454
+ * gets one combined set.
455
+ */
456
+ getExtensionParams(id: string): {
457
+ schema: StyleField[];
458
+ defaults: Record<string, unknown>;
459
+ values: Record<string, unknown>;
460
+ } | null;
461
+ /** Save some of an extension's params, and hand the new values to the extension. */
462
+ setExtensionParams(id: string, patch: Record<string, unknown>): void;
441
463
  onPluginStateChange(cb: (state: {
442
464
  installed: Set<string>;
443
465
  active: Set<string>;
@@ -454,11 +476,33 @@ export declare class DepthChart {
454
476
  visible: boolean;
455
477
  }>;
456
478
  getToolbarRegistry(): ReadonlyMap<string, ToolbarItem>;
479
+ /** The theme the chart is on. */
480
+ getTheme(): ThemeDef;
481
+ /** Every theme it can switch to, built-in and registered. */
482
+ getThemes(): ThemeDef[];
483
+ /**
484
+ * Switch theme. Emits `theme:change`. False for an id that isn't registered,
485
+ * and the chart stays where it was.
486
+ */
487
+ setTheme(id: string): boolean;
488
+ /**
489
+ * Add a theme, or replace one with the same id. Returns the unregister - if
490
+ * the chart is on that theme, it falls back to the default.
491
+ */
492
+ registerTheme(theme: ThemeDef): () => void;
457
493
  getBottomBarRegistry(): ReadonlyMap<string, BottomBarItem>;
458
494
  attachRenderEngine(engine: RenderEngine): void;
495
+ /** Every cell's paint loop, by cell id. */
496
+ getRenderEngines(): ReadonlyMap<number, RenderEngine>;
497
+ /**
498
+ * Draw on every cell, including cells that mount later - a layout switch
499
+ * keeps the overlay on all of them. Returns the remove.
500
+ */
501
+ addOverlay(phase: DrawPhase, hook: DrawHook): () => void;
502
+ private get pluginRenderEngine();
459
503
  /**
460
- * Snapshot of the chart with every layer composited (base, drawings, UI).
461
- * Returns null until the render engine has attached.
504
+ * Snapshot of the focused cell with every layer composited (base, drawings, UI).
505
+ * Returns null until a render engine has attached.
462
506
  */
463
507
  screenshot(): HTMLCanvasElement | null;
464
508
  private _focusedCellId;
@@ -2,14 +2,25 @@ export interface PluginSchedule {
2
2
  interval(ms: number, fn: () => void): () => void;
3
3
  timeout(ms: number, fn: () => void): () => void;
4
4
  raf(fn: () => void): () => void;
5
+ frames(fps: number, fn: (time: number, dt: number) => void): () => void;
5
6
  }
6
7
  export declare class PluginScheduleImpl implements PluginSchedule {
8
+ private readonly getElements;
7
9
  private readonly intervals;
8
10
  private readonly timeouts;
9
11
  private readonly rafIds;
12
+ private readonly frameLoops;
10
13
  private destroyed;
14
+ private observer;
15
+ private readonly observed;
16
+ private readonly visible;
17
+ /** `getElements` - every cell the plugin draws on. Frames run while any is on screen */
18
+ constructor(getElements?: () => readonly Element[]);
19
+ private get onScreen();
11
20
  interval(ms: number, fn: () => void): () => void;
12
21
  timeout(ms: number, fn: () => void): () => void;
13
22
  raf(fn: () => void): () => void;
23
+ frames(fps: number, fn: (time: number, dt: number) => void): () => void;
24
+ private watchVisibility;
14
25
  destroy(): void;
15
26
  }
@@ -3,7 +3,7 @@ import type { ChartPane, Rect } from '../lib/types/indicator-types';
3
3
  import type { Indicator } from '../lib/types/indicator-types';
4
4
  import type { TradePoint, PriceHistory, ViewBounds } from '../lib/types';
5
5
  import type { FootprintBar } from '../lib/types/footprint';
6
- import type { ChartSettings } from '../lib/types/chart-settings';
6
+ import { type ChartColors, type ChartSettings } from '../lib/types/chart-settings';
7
7
  import type { Crosshair } from '../lib/renderers/renderer';
8
8
  import type { Drawing, DraftDrawing, DrawingAnchorId, ActiveDrawingTool } from '../lib/types/drawing-types';
9
9
  import type { TradeLine } from '../lib/types';
@@ -12,7 +12,26 @@ import { ChartTypePlugin } from './PluginRegistry';
12
12
  import { SessionMapper } from './SessionMapper';
13
13
  import { AccountSnapshot, DataLevel, SymbolInfo } from '.';
14
14
  import type { CrosshairSync } from '../lib/types/layout-sync';
15
- export type DrawHook = (ctx: CanvasRenderingContext2D, view: ViewBounds, transformer: LiveTransformer) => void;
15
+ /** Layout of the frame a draw hook runs in. Everything in css px */
16
+ export interface DrawInfo {
17
+ width: number;
18
+ height: number;
19
+ dpr: number;
20
+ /** The main plot - the canvas minus the price and time axis */
21
+ plot: Rect;
22
+ /** Every panes box by id, `main` included */
23
+ panes: Readonly<Record<string, Rect>>;
24
+ /** The resolved background color */
25
+ background: string;
26
+ /** `performance.now()` at the start of the frame */
27
+ time: number;
28
+ /** The layout cell being painted - a hook runs once per cell */
29
+ cell: number;
30
+ /** Whether that cell is the focused one */
31
+ focused: boolean;
32
+ }
33
+ export type DrawHook = (ctx: CanvasRenderingContext2D, view: ViewBounds, transformer: LiveTransformer, info: DrawInfo) => void;
34
+ export type DrawPhase = 'before-base' | 'after-background' | 'after-base' | 'after-ui';
16
35
  export interface DrawParams {
17
36
  panes: ChartPane[];
18
37
  layouts: Record<string, Rect>;
@@ -95,11 +114,17 @@ export interface DrawParams {
95
114
  syncCrosshair: CrosshairSync | null;
96
115
  }
97
116
  export declare class RenderEngine {
117
+ private readonly backgroundCanvas;
98
118
  private readonly baseCanvas;
99
119
  private readonly drawingsCanvas;
100
120
  private readonly uiCanvas;
101
121
  private readonly eventBus;
102
122
  private readonly chartId;
123
+ /** The layout cell this engine paints */
124
+ get cellId(): number;
125
+ private focused;
126
+ /** Set by the chart. Repaints if there are hooks, they might draw differently on the focused cell */
127
+ setFocused(focused: boolean): void;
103
128
  private rafId;
104
129
  /** The element the canvases sit in, for overlays that want to draw over the chart without touching it */
105
130
  get container(): HTMLElement | null;
@@ -115,10 +140,14 @@ export declare class RenderEngine {
115
140
  maxMs: number;
116
141
  };
117
142
  private dirty;
143
+ private paintedBackgroundColor;
118
144
  private beforeBaseDraw;
145
+ private afterBackgroundDraw;
119
146
  private afterBaseDraw;
120
147
  private afterUIDraw;
121
148
  private drawParams;
149
+ private rawDrawParams;
150
+ private themeColors;
122
151
  private view;
123
152
  private readonly priceTransition;
124
153
  private resizeObserver;
@@ -129,11 +158,18 @@ export declare class RenderEngine {
129
158
  private readonly onDprChange;
130
159
  private watchDpr;
131
160
  private startLoop;
132
- markDirty(layer: 'base' | 'drawings' | 'ui'): void;
161
+ markDirty(layer: 'background' | 'base' | 'drawings' | 'ui'): void;
133
162
  markAllDirty(): void;
134
163
  setDrawParams(params: DrawParams): void;
164
+ /** Set by the chart. Colors the user didn't pick come from here. */
165
+ setThemeColors(colors: Partial<ChartColors> | undefined): void;
135
166
  setView(v: ViewBounds): void;
136
167
  getView(): ViewBounds | null;
168
+ /** The transformer this cell paints with, once it has drawn */
169
+ get transformer(): LiveTransformer | null;
170
+ private doBackgroundRedraw;
171
+ private readonly failedHooks;
172
+ private runHooks;
137
173
  private doBaseRedraw;
138
174
  /**
139
175
  * Draws the ChristTrade banner into the base layer, in the same pass that
@@ -146,15 +182,16 @@ export declare class RenderEngine {
146
182
  private drawAttribution;
147
183
  private doDrawingsRedraw;
148
184
  private doUIRedraw;
149
- addDrawHook(phase: 'before-base' | 'after-base' | 'after-ui', hook: DrawHook): () => void;
185
+ addDrawHook(phase: DrawPhase, hook: DrawHook): () => void;
150
186
  private handleResize;
151
187
  private flushSync;
152
188
  toDataURL(type?: string): string;
153
189
  /**
154
- * All three layers flattened onto a fresh canvas, in paint order. Use this
190
+ * Every layer flattened onto a fresh canvas, in paint order. Use this
155
191
  * rather than `toDataURL` when the snapshot should include the drawings and
156
192
  * the crosshair/UI layer.
157
193
  */
158
194
  captureComposite(): HTMLCanvasElement;
195
+ private flatten;
159
196
  destroy(): void;
160
197
  }
@@ -0,0 +1,18 @@
1
+ import type { ThemeDef } from '../interfaces/plugins/IChartPlugin';
2
+ import type { TypedEventBus } from './TypedEventBus';
3
+ import { BASE_DARK_VARS, BUILTIN_THEMES } from './builtin-themes';
4
+ export { BASE_DARK_VARS, BUILTIN_THEMES };
5
+ export declare const DEFAULT_THEME_ID = "dark";
6
+ export declare class ThemeRegistry {
7
+ private readonly bus;
8
+ private readonly themes;
9
+ private currentId;
10
+ constructor(bus: TypedEventBus, builtins?: readonly ThemeDef[], initial?: string);
11
+ get current(): ThemeDef;
12
+ get(id: string): ThemeDef | undefined;
13
+ list(): ThemeDef[];
14
+ /** Same id replaces, so a hot-reloaded theme updates in place. Returns the unregister. */
15
+ register(theme: ThemeDef): () => void;
16
+ /** False for an unknown id. Setting the current theme again does nothing. */
17
+ set(id: string): boolean;
18
+ }
@@ -8,6 +8,8 @@ import { IExecutionAdapter } from '../interfaces/IExecutionAdapter';
8
8
  import { ActiveDrawingTool, Anchor, Drawing } from '../lib/types/drawing-types';
9
9
  import { TradeLineHitMap } from '../lib/renderers/drawTradeLines';
10
10
  import type { TradeLine } from '../lib/types';
11
+ import type { StyleField } from '../components/drawings/drawing-settings-dialog';
12
+ import type { ThemeDef } from '../interfaces/plugins/IChartPlugin';
11
13
  import { FootprintBar } from '../lib/types/footprint';
12
14
  import { ChartPane, Indicator } from '../lib/types/indicator-types';
13
15
  import { SerialTrade } from '../lib/types';
@@ -69,7 +71,8 @@ export interface ChartEvents {
69
71
  old: string;
70
72
  new: string;
71
73
  };
72
- 'theme:change': 'light' | 'dark';
74
+ 'theme:change': ThemeDef;
75
+ 'theme:list': ThemeDef[];
73
76
  'chart:focused': {
74
77
  id: number;
75
78
  };
@@ -373,6 +376,9 @@ export interface ChartEvents {
373
376
  'render-engine:ready': {
374
377
  engine: RenderEngine;
375
378
  };
379
+ 'render-engine:destroyed': {
380
+ engine: RenderEngine;
381
+ };
376
382
  /**
377
383
  * A cell handing over its forming-bar getter. The bar mutates in place, so
378
384
  * this is a getter and not a value - read it, dont keep it. `get: null`
@@ -594,6 +600,16 @@ export interface ChartEvents {
594
600
  id: string;
595
601
  params: Record<string, unknown>;
596
602
  };
603
+ 'plugin:extension-params': {
604
+ id: string;
605
+ entry: string;
606
+ schema: StyleField[] | null;
607
+ defaults: Record<string, unknown>;
608
+ };
609
+ 'plugin:extension-params-change': {
610
+ id: string;
611
+ values: Record<string, unknown>;
612
+ };
597
613
  /** @console command */
598
614
  'plugin:strategy-range': {
599
615
  id: string;
@@ -0,0 +1,7 @@
1
+ import type { ThemeDef } from '../interfaces/plugins/IChartPlugin';
2
+ /**
3
+ * What every built-in dark theme starts from. Spread it and override what's
4
+ * different: `vars: { ...BASE_DARK_VARS, primary: '207 82% 66%' }`.
5
+ */
6
+ export declare const BASE_DARK_VARS: Readonly<Record<string, string>>;
7
+ export declare const BUILTIN_THEMES: readonly ThemeDef[];
@@ -18,7 +18,7 @@ export type { DrawParams } from './RenderEngine';
18
18
  export type { IDataAdapter, DataLevel, TickEvent, OhlcvBar, L2Snapshot, MboEvent, } from '../interfaces/IDataAdapter';
19
19
  export type { IExecutionAdapter } from '../interfaces/IExecutionAdapter';
20
20
  export { LiveTransformer } from '../interfaces/ICoordinateTransformer';
21
- export type { ICoordinateTransformer, PriceScaleMode, TransformedDrawHook, } from '../interfaces/ICoordinateTransformer';
21
+ export type { ICoordinateTransformer, PriceScaleMode, } from '../interfaces/ICoordinateTransformer';
22
22
  export { PluginRegistry } from './PluginRegistry';
23
23
  export type { PluginIcon, InstalledPlugin } from './PluginRegistry';
24
24
  export type { PluginCatalogEntry, PluginStartupEntry, PluginStartupRecord, } from './plugin-startup';
@@ -53,8 +53,8 @@ export type { TradePoint, PriceHistory, ViewBounds, OhlcvBarMs } from '../lib/ty
53
53
  export type { Timeframe } from '../lib/timeframes';
54
54
  export type { DrawingTool } from '../lib/types/drawing-types';
55
55
  export type { FootprintBar, FootprintOptions } from '../lib/types/footprint';
56
- export type { ChartSettings } from '../lib/types/chart-settings';
57
- export { DEFAULT_CHART_SETTINGS } from '../lib/types/chart-settings';
56
+ export type { ChartColorKey, ChartColors, ChartSettings } from '../lib/types/chart-settings';
57
+ export { CHART_COLOR_KEYS, DEFAULT_CHART_SETTINGS, themedSettings } from '../lib/types/chart-settings';
58
58
  export type { PlaceOrderRequest, L3EngineOptions, FeeSchedule, BookDepth, BookLevel } from '../lib/matchingEngine';
59
59
  export { createL3MatchingEngine, feeScheduleFor, MICRO_FEE_SCHEDULE, NQ_FEE_SCHEDULE, ZERO_FEE_SCHEDULE, } from '../lib/matchingEngine';
60
60
  export { SimulatedMarketAdapter, createSimulatedAdapter } from '../lib/createSimulatedAdapter';
@@ -93,6 +93,7 @@ export type { FootprintLevel, FootprintMode, PriceRange } from '../lib/types/foo
93
93
  export type { BarPreviewResponse, BarResponse, DataAdapterErrorCode, FetchRequest, PreProcessedPayload, SupplementalBarSet, SymbolIconSpec, TimeRange, } from '../interfaces/IDataAdapter';
94
94
  export { SymbolIcon } from '../components/chart/symbol-icon';
95
95
  export type { BottomBarHandle, BottomBarItem, ContextMenuItem, FloatingPanelOpts, NotifyLevel, NotifyOptions, PaneOptions, PluginExecutionSurface, PluginLifecycle, PluginServices, PluginStorage, ServiceApi, ServiceObserver, SettingSchema, SettingSchemaType, ThemeDef, ToolbarItem, } from '../interfaces/plugins/IChartPlugin';
96
+ export { BASE_DARK_VARS, BUILTIN_THEMES, DEFAULT_THEME_ID } from './ThemeRegistry';
96
97
  export type { ChartTypeActiveContext, ChartTypeKeyEvent, ChartTypePointerEvent, } from '../interfaces/plugins/IChartTypePlugin';
97
98
  export type { AnchorConfig, Point } from '../interfaces/plugins/IDrawingPlugin';
98
99
  export type { IndicatorCrosshair } from '../interfaces/plugins/IIndicatorPlugin';
@@ -111,6 +112,6 @@ export type { ChartPane, Indicator, Rect } from '../lib/types/indicator-types';
111
112
  export type { CrosshairSync, TimeRangeSync } from '../lib/types/layout-sync';
112
113
  export type { TradeLineHitMap } from '../lib/renderers/drawTradeLines';
113
114
  export type { PlaybackMode } from '../hooks/usePlaybackEngine';
114
- export type { DrawHook } from './RenderEngine';
115
+ export type { DrawHook, DrawInfo, DrawPhase } from './RenderEngine';
115
116
  export type { InterceptableEvent, Interceptor } from './TypedEventBus';
116
117
  export { ChartState } from './ChartState';
@@ -23,11 +23,13 @@ export interface PluginCatalogEntry {
23
23
  export interface PluginStartupEntry {
24
24
  /** Install the plugin when the chart opens. */
25
25
  autostart: boolean;
26
- /** Indicators only: also put an instance on a pane. */
26
+ /**
27
+ * Indicators only: also put an instance on a pane. Ignored when the chart was
28
+ * restored with pane state - the save decides what's on its panes.
29
+ */
27
30
  activate?: boolean;
28
31
  }
29
32
  export type PluginStartupRecord = Record<string, PluginStartupEntry>;
30
- export declare function ptrace(...args: unknown[]): void;
31
33
  export declare function readPluginStartup(): PluginStartupRecord;
32
34
  /** Merge a patch into one plugin's entry. `null` forgets the plugin entirely. */
33
35
  export declare function writePluginStartup(id: string, patch: Partial<PluginStartupEntry> | null): PluginStartupRecord;
@@ -0,0 +1,9 @@
1
+ import type { ThemeDef } from '../interfaces/plugins/IChartPlugin';
2
+ export declare function themeCss(theme: ThemeDef): string | null;
3
+ export declare class ThemeStyle {
4
+ private readonly id;
5
+ private el;
6
+ constructor(id: string);
7
+ apply(theme: ThemeDef): void;
8
+ remove(): void;
9
+ }
@@ -52,7 +52,6 @@ export interface UseChartDataParams {
52
52
  updateSettingsBarPosRef: MutableRefObject<(id: string | null) => void>;
53
53
  resetViewRef: MutableRefObject<() => void>;
54
54
  syncPixelLayoutsRef: MutableRefObject<(panes?: ChartPane[]) => void>;
55
- doBaseRedrawRef: MutableRefObject<() => void>;
56
55
  setIndicators: (inds: Indicator[]) => void;
57
56
  setPanes: (updater: ((prev: ChartPane[]) => ChartPane[]) | ChartPane[]) => void;
58
57
  getPanel: () => DomPanelHandle | null;
@@ -158,6 +158,7 @@ export interface UseChartInteractionParams {
158
158
  hideTimeScale: boolean;
159
159
  activeTool: ActiveDrawingTool;
160
160
  touchPlusRef: RefObject<HTMLButtonElement>;
161
+ lastInputTouchRef: MutableRefObject<boolean>;
161
162
  }
162
163
  export declare function useChartInteraction(p: UseChartInteractionParams): void;
163
164
  export {};
@@ -54,6 +54,7 @@ export interface UseChartSubscriptionsParams {
54
54
  autofitIndicatorPanes: () => void;
55
55
  handleAddIndicator: (id: string) => void;
56
56
  handleRemoveIndicator: (id: string) => void;
57
+ userRemoveIndicator: (id: string) => void;
57
58
  onSymbolChange: (symbol: string) => void;
58
59
  /** This layout's live sync switches (a ref: the handlers outlive a render). */
59
60
  syncInLayoutRef: MutableRefObject<SyncInLayout>;
@@ -1,24 +1,7 @@
1
1
  import { type MutableRefObject, type RefObject } from 'react';
2
2
  import { RenderEngine } from '../core/RenderEngine';
3
3
  import { type TypedEventBus } from '../core/TypedEventBus';
4
- import { type ViewBounds, type TradePoint, type PriceHistory, type OhlcvBarMs } from '../lib/types';
5
- import { type ChartPane, type Indicator, type Rect } from '../lib/types/indicator-types';
6
- import { type FootprintBar } from '../lib/types/footprint';
7
- import { type ChartSettings } from '../lib/types/chart-settings';
8
- import { type DataLevel } from '../interfaces/IDataAdapter';
9
- import { type LiveTransformer } from '../interfaces/ICoordinateTransformer';
10
- type HeatmapBitmapOffsets = {
11
- x: number;
12
- y: number;
13
- w: number;
14
- h: number;
15
- };
16
- type CacheBounds = {
17
- tMin: bigint;
18
- tMax: bigint;
19
- pMin: number;
20
- pMax: number;
21
- };
4
+ import { type ViewBounds } from '../lib/types';
22
5
  export interface UseRenderEngineParams {
23
6
  renderEngineRef: MutableRefObject<RenderEngine | null>;
24
7
  baseCanvasRef: RefObject<HTMLCanvasElement>;
@@ -29,36 +12,5 @@ export interface UseRenderEngineParams {
29
12
  * other cells can tell our repaints from theirs. */
30
13
  chartId: number;
31
14
  viewRef: MutableRefObject<ViewBounds | null>;
32
- /** Auto-computed right price-axis width (css px). */
33
- priceScaleWidthRef: MutableRefObject<number>;
34
- tradesRef: MutableRefObject<TradePoint[]>;
35
- getLayouts: () => Record<string, Rect>;
36
- heatmapBitmapRef: MutableRefObject<ImageBitmap | null>;
37
- cacheBoundsRef: MutableRefObject<CacheBounds | null>;
38
- heatmapBitmapOffsetsRef: MutableRefObject<HeatmapBitmapOffsets>;
39
- panesRef: MutableRefObject<ChartPane[]>;
40
- indicatorsRef: MutableRefObject<Indicator[]>;
41
- priceHistoryRef: MutableRefObject<PriceHistory[]>;
42
- footprintBarsRef: MutableRefObject<FootprintBar[]>;
43
- activeTimeframeRef: MutableRefObject<{
44
- barNs: bigint;
45
- }>;
46
- chartSettingsRef: MutableRefObject<ChartSettings>;
47
- horizonRef: MutableRefObject<bigint>;
48
- candleCacheRef: MutableRefObject<Map<bigint, any> | null>;
49
- openBarRef: MutableRefObject<FootprintBar | null>;
50
- dataLevelRef: MutableRefObject<DataLevel | null>;
51
- ohlcvBarsRef: MutableRefObject<{
52
- barNs: bigint;
53
- bars: OhlcvBarMs[];
54
- display: OhlcvBarMs[];
55
- }>;
56
- previewBarsRef: MutableRefObject<OhlcvBarMs[]>;
57
- transformer: LiveTransformer;
58
- hideTimeScale: boolean;
59
15
  }
60
- export interface UseRenderEngineResult {
61
- doBaseRedraw: () => void;
62
- }
63
- export declare function useRenderEngine(p: UseRenderEngineParams): UseRenderEngineResult;
64
- export {};
16
+ export declare function useRenderEngine(p: UseRenderEngineParams): void;
@@ -44,6 +44,7 @@ interface UseTradeLines {
44
44
  * price - final price (snapped to tickSize)
45
45
  */
46
46
  onGhostMove?: (lineId: string, kind: 'tp' | 'sl', index: number, price: number) => void;
47
+ isTouchRef?: React.MutableRefObject<boolean>;
47
48
  }
48
49
  interface UseTradeLinesReturn {
49
50
  hoveredLineId: string | null;
@@ -68,6 +69,7 @@ interface UseTradeLinesReturn {
68
69
  * always up-to-date without needing React state.
69
70
  */
70
71
  getGhostState: () => GhostInteractionState;
72
+ getArmedLineId: () => string | null;
71
73
  onMouseMove: (e: React.MouseEvent<HTMLCanvasElement>) => void;
72
74
  onMouseDown: (e: React.MouseEvent<HTMLCanvasElement>) => void;
73
75
  onMouseUp: (e: React.MouseEvent<HTMLCanvasElement>) => void;
@@ -76,5 +78,5 @@ interface UseTradeLinesReturn {
76
78
  onDoubleClick: (e: React.MouseEvent<HTMLCanvasElement>) => void;
77
79
  onClick: (e: React.MouseEvent<HTMLCanvasElement>) => void;
78
80
  }
79
- export declare function useTradeLines({ tradeLines, onLinesChange, onSyncLines, onLineDelete, hitMapRef, chartWRef, chartHRef, chartOYRef, getLayouts, boundsRef, chartSettingsRef, redraw, symbolInfoRef, onGhostMove, linesRef, resolveLine, draggingLineIdRef, transformer, }: UseTradeLines): UseTradeLinesReturn;
81
+ export declare function useTradeLines({ tradeLines, onLinesChange, onSyncLines, onLineDelete, hitMapRef, chartWRef, chartHRef, chartOYRef, getLayouts, boundsRef, chartSettingsRef, redraw, symbolInfoRef, onGhostMove, linesRef, resolveLine, draggingLineIdRef, transformer, isTouchRef, }: UseTradeLines): UseTradeLinesReturn;
80
82
  export {};
@@ -102,4 +102,3 @@ export declare class LiveTransformer {
102
102
  private _pctPriceToY;
103
103
  private _pctYToPrice;
104
104
  }
105
- export type TransformedDrawHook = (ctx: CanvasRenderingContext2D, transformer: LiveTransformer) => void;
@@ -4,10 +4,11 @@
4
4
  * ChartPlugin and is installed through PluginContext.
5
5
  */
6
6
  import type { TypedEventBus, InterceptableEvent, Interceptor } from '../../core/TypedEventBus';
7
- import type { RenderEngine, DrawHook } from '../../core/RenderEngine';
7
+ import type { RenderEngine, DrawHook, DrawPhase } from '../../core/RenderEngine';
8
8
  import type { ExecutionEngine } from '../../core/ExecutionEngine';
9
9
  import type { GlobalChartBus } from '../../core/GlobalChartBus';
10
10
  import type { LiveTransformer } from '../ICoordinateTransformer';
11
+ import type { ChartColors } from '../../lib/types/chart-settings';
11
12
  import type { DataLevel, OhlcvBar, SymbolInfo, TickEvent } from '../IDataAdapter';
12
13
  import type { SerialTrade, PriceHistory } from '../../lib/types';
13
14
  import type { FootprintBar } from '../../lib/types/footprint';
@@ -54,8 +55,16 @@ export interface ContextMenuItem {
54
55
  export interface ThemeDef {
55
56
  id: string;
56
57
  name: string;
58
+ /** Dark surfaces or light ones - what `onThemeChange` reports. Defaults to dark. */
59
+ dark?: boolean;
57
60
  /** CSS variables to inject - keys are var names without the leading '--'. */
58
61
  vars: Record<string, string>;
62
+ /**
63
+ * Canvas colors: candles, grid, background, crosshair and the rest. Each one
64
+ * only applies where the user hasn't picked their own; leave a key out to keep
65
+ * the default.
66
+ */
67
+ chart?: Partial<ChartColors>;
59
68
  }
60
69
  export type SettingSchemaType = 'number' | 'string' | 'boolean' | 'color' | 'select';
61
70
  export interface SettingSchema {
@@ -94,6 +103,13 @@ export interface PluginSchedule {
94
103
  timeout(ms: number, fn: () => void): () => void;
95
104
  /** Managed animation-frame callback - auto-cancelled on plugin teardown. */
96
105
  raf(fn: () => void): () => void;
106
+ /**
107
+ * Repeating animation loop, at most `fps` a second, 0 = every frame. Skips frames
108
+ * while the chart is off screen; the first frame back gets one interval as `dt`.
109
+ * `time` is the raf timestamp, `dt` the ms since the last call. Auto-cancelled on
110
+ * plugin teardown.
111
+ */
112
+ frames(fps: number, fn: (time: number, dt: number) => void): () => void;
97
113
  }
98
114
  export type NotifyLevel = 'info' | 'success' | 'warn' | 'error';
99
115
  export interface NotifyOptions {
@@ -124,7 +140,7 @@ export interface PluginExecutionSurface {
124
140
  export interface PluginLifecycle {
125
141
  onSymbolChange(cb: (symbol: string) => void): () => void;
126
142
  onTimeframeChange(cb: (tf: string) => void): () => void;
127
- onThemeChange(cb: (theme: 'light' | 'dark') => void): () => void;
143
+ onThemeChange(cb: (mode: 'light' | 'dark', theme: ThemeDef) => void): () => void;
128
144
  onFocus(cb: (id: number) => void): () => void;
129
145
  onBlur(cb: () => void): () => void;
130
146
  }
@@ -193,7 +209,7 @@ export interface PluginContext {
193
209
  registerPanel(id: string, element: React.ReactNode, title?: string, visible?: boolean): () => void;
194
210
  getSettings<T>(defaults: T): T;
195
211
  saveSettings<T>(patch: Partial<T>): void;
196
- addOverlay(phase: 'before-base' | 'after-base' | 'after-ui', hook: DrawHook): () => void;
212
+ addOverlay(phase: DrawPhase, hook: DrawHook): () => void;
197
213
  registerToolbarItem(item: ToolbarItem): () => void;
198
214
  registerBottomBarItem(id: string, render: () => React.ReactNode): BottomBarHandle;
199
215
  registerContextMenuItem(item: ContextMenuItem): () => void;
@@ -22,17 +22,6 @@ export type Crosshair = {
22
22
  export declare const Y_AXIS_WIDTH = 65;
23
23
  export declare const X_AXIS_HEIGHT = 30;
24
24
  export declare const TRADE_SNAP_RADIUS = 12;
25
- export declare const COLORS: {
26
- background: string;
27
- buyLine: string;
28
- sellLine: string;
29
- grid: string;
30
- label: string;
31
- axisBg: string;
32
- crosshair: string;
33
- crosshairBg: string;
34
- crosshairText: string;
35
- };
36
25
  export declare function computeRightScaleWidth(bounds: ViewBounds, symbolInfo: SymbolInfo | undefined, chartSettings: ChartSettings, hidePriceScale?: boolean, ctx?: CanvasRenderingContext2D | null): number;
37
26
  export declare function drawBaseLayer(canvas: HTMLCanvasElement, panes: ChartPane[], layouts: Record<string, Rect>, indicators: Indicator[], trades: TradePoint[], priceHistory: PriceHistory[], snapshots: BookSnapshot[], bounds: ViewBounds, footprintBars: FootprintBar[], heatmapBitmap: ImageBitmap | null, bitmapOffsetX: number, bitmapOffsetY: number, bitmapOffsetW: number, bitmapOffsetH: number, barNs: bigint, chartSettings: ChartSettings, horizon: bigint, candleCache: CandleCache | null,
38
27
  /** Live incrementally-built open bar - overrides the cache for the current bucket. */
@@ -76,6 +65,7 @@ export declare function drawHeatmap(ctx: CanvasRenderingContext2D, snapshots: Bo
76
65
  export declare function nearestIndex(priceHistory: PriceHistory[], target: bigint): number;
77
66
  export declare function nearestTradeIndex(trades: TradePoint[], target: bigint): number;
78
67
  export declare function findNearestTrade(clickX: number, clickY: number, trades: TradePoint[], bounds: ViewBounds, chartW: number, chartH: number, chartSettings: ChartSettings, horizon: bigint, transformer: LiveTransformer): TradePoint | null;
68
+ export declare function drawBackground(ctx: CanvasRenderingContext2D, cssW: number, cssH: number, chartSettings: ChartSettings): void;
79
69
  export declare const snapTs: (ts: bigint, tf: bigint, sessionMapper?: SessionMapper | null) => bigint;
80
70
  export declare const snapPrice: (snappedTs: bigint, rawPrice: number, chartSettings: ChartSettings, footprintBars: FootprintBar[], priceHistory: PriceHistory[], ohlcvBars: {
81
71
  time: number;
@@ -42,6 +42,9 @@ export type ChartSettings = {
42
42
  gridVerticalColor: string;
43
43
  crosshairMode: 'normal' | 'magnet' | 'hidden';
44
44
  crosshairColor: string;
45
+ /** The time and price boxes on the crosshair. */
46
+ crosshairLabelColor: string;
47
+ crosshairLabelTextColor: string;
45
48
  crosshairWidth: number;
46
49
  crosshairDash: number[];
47
50
  showBreaks: boolean;
@@ -56,8 +59,16 @@ export type ChartSettings = {
56
59
  statusLineFontSize: number;
57
60
  backgroundColor: string;
58
61
  axisBackgroundColor: string;
62
+ /** Tick labels on the price and time axis. */
63
+ axisTextColor: string;
64
+ /** The line between the plot and the axes. */
65
+ axisBorderColor: string;
66
+ /** Text on the colored price pills on the price axis. */
67
+ priceLabelTextColor: string;
59
68
  showBidLine: boolean;
60
69
  showAskLine: boolean;
70
+ bidLineColor: string;
71
+ askLineColor: string;
61
72
  showMidLine: boolean;
62
73
  showLastTradeLine: boolean;
63
74
  showFills: boolean;
@@ -74,6 +85,7 @@ export type ChartSettings = {
74
85
  sessionHighlightColor: string;
75
86
  horizonScrollEasing: 'none' | 'linear' | 'easeOut' | 'easeInOut';
76
87
  horizonScrollDuration: number;
88
+ touchMomentum: boolean;
77
89
  timezone: string;
78
90
  use24HourClock: boolean;
79
91
  showTimezoneLabel: boolean;
@@ -88,3 +100,8 @@ export declare const DEFAULT_CHART_SETTINGS: ChartSettings;
88
100
  export declare function diffChartSettings(settings: ChartSettings): Partial<ChartSettings>;
89
101
  /** Re-expand a settings diff back onto the current defaults. */
90
102
  export declare function mergeChartSettings(diff?: Partial<ChartSettings>): ChartSettings;
103
+ /** The settings a theme can color. */
104
+ export declare const CHART_COLOR_KEYS: readonly ["upBodyColor", "downBodyColor", "upWickColor", "downWickColor", "upBorderColor", "downBorderColor", "gridHorizontalColor", "gridVerticalColor", "crosshairColor", "crosshairLabelColor", "crosshairLabelTextColor", "breaksColor", "backgroundColor", "axisBackgroundColor", "axisTextColor", "axisBorderColor", "priceLabelTextColor", "bidLineColor", "askLineColor", "heatmapColorBid", "heatmapColorAsk", "priceLineColor", "sessionHighlightColor"];
105
+ export type ChartColorKey = (typeof CHART_COLOR_KEYS)[number];
106
+ export type ChartColors = Pick<ChartSettings, ChartColorKey>;
107
+ export declare function themedSettings(settings: ChartSettings, colors?: Partial<ChartColors>): ChartSettings;