@363045841yyt/klinechart-core 0.7.3 → 0.7.5-alpha.2

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.
Files changed (231) hide show
  1. package/README.md +201 -201
  2. package/README.zh-CN.md +201 -201
  3. package/dist/engine/renderers/webgl/candleSurface.js +47 -47
  4. package/dist/version.d.ts +1 -1
  5. package/dist/version.d.ts.map +1 -1
  6. package/dist/version.js +1 -2
  7. package/dist/version.js.map +1 -1
  8. package/package.json +129 -122
  9. package/src/__tests__/signal.test.ts +124 -124
  10. package/src/config/chartSettings.ts +66 -66
  11. package/src/controllers/__tests__/drawing.test.ts +214 -214
  12. package/src/controllers/__tests__/indicatorSelector.test.ts +481 -481
  13. package/src/controllers/__tests__/toolbar.test.ts +225 -225
  14. package/src/controllers/createChartController.ts +665 -665
  15. package/src/controllers/createDrawingController.ts +96 -96
  16. package/src/controllers/createIndicatorSelectorController.ts +307 -307
  17. package/src/controllers/createToolbarController.ts +146 -146
  18. package/src/controllers/index.ts +19 -19
  19. package/src/controllers/types.ts +284 -284
  20. package/src/engine/__tests__/chart.dpr.test.ts +401 -401
  21. package/src/engine/__tests__/paneRenderer.resize.test.ts +92 -92
  22. package/src/engine/chart-store.ts +121 -121
  23. package/src/engine/chart.d.ts +617 -617
  24. package/src/engine/chart.ts +2815 -2815
  25. package/src/engine/controller/__tests__/interaction.dpr.test.ts +259 -259
  26. package/src/engine/controller/interaction.ts +722 -722
  27. package/src/engine/controller/markerInteraction.ts +130 -130
  28. package/src/engine/controller/pinchTracker.ts +82 -82
  29. package/src/engine/controller/tooltipPosition.ts +48 -48
  30. package/src/engine/draw/__tests__/pixelAlign.spec.ts +176 -176
  31. package/src/engine/draw/pixelAlign.ts +259 -259
  32. package/src/engine/drawing/index.ts +655 -655
  33. package/src/engine/drawing/interaction.ts +842 -842
  34. package/src/engine/drawing/plugin.ts +343 -343
  35. package/src/engine/indicators/__tests__/__fixtures__/golden/atr.json +38 -38
  36. package/src/engine/indicators/__tests__/__fixtures__/golden/dema.json +14 -14
  37. package/src/engine/indicators/__tests__/__fixtures__/golden/hma.json +14 -14
  38. package/src/engine/indicators/__tests__/__fixtures__/golden/index.ts +55 -55
  39. package/src/engine/indicators/__tests__/__fixtures__/golden/kama.json +14 -14
  40. package/src/engine/indicators/__tests__/__fixtures__/golden/tema.json +14 -14
  41. package/src/engine/indicators/__tests__/__fixtures__/golden/wma.json +40 -40
  42. package/src/engine/indicators/__tests__/__fixtures__/synthetic.ts +65 -65
  43. package/src/engine/indicators/__tests__/_propertyAssertions.ts +76 -76
  44. package/src/engine/indicators/__tests__/atr.test.ts +153 -153
  45. package/src/engine/indicators/__tests__/calculators.test.ts +614 -614
  46. package/src/engine/indicators/__tests__/cmf-mfi.test.ts +100 -100
  47. package/src/engine/indicators/__tests__/dema.test.ts +73 -73
  48. package/src/engine/indicators/__tests__/donchian.test.ts +70 -70
  49. package/src/engine/indicators/__tests__/hma.test.ts +73 -73
  50. package/src/engine/indicators/__tests__/ichimoku.test.ts +105 -105
  51. package/src/engine/indicators/__tests__/kama.test.ts +80 -80
  52. package/src/engine/indicators/__tests__/keltner.test.ts +65 -65
  53. package/src/engine/indicators/__tests__/pivot-fib.test.ts +110 -110
  54. package/src/engine/indicators/__tests__/roc.test.ts +68 -68
  55. package/src/engine/indicators/__tests__/sar.test.ts +86 -86
  56. package/src/engine/indicators/__tests__/scheduler.test.ts +831 -831
  57. package/src/engine/indicators/__tests__/soa.test.ts +533 -533
  58. package/src/engine/indicators/__tests__/structure.test.ts +110 -110
  59. package/src/engine/indicators/__tests__/supertrend.test.ts +65 -65
  60. package/src/engine/indicators/__tests__/tema.test.ts +68 -68
  61. package/src/engine/indicators/__tests__/trix.test.ts +70 -70
  62. package/src/engine/indicators/__tests__/volatility.test.ts +117 -117
  63. package/src/engine/indicators/__tests__/volume.test.ts +115 -115
  64. package/src/engine/indicators/__tests__/volumeProfile.test.ts +74 -74
  65. package/src/engine/indicators/__tests__/vwap.test.ts +69 -69
  66. package/src/engine/indicators/__tests__/wma.test.ts +112 -112
  67. package/src/engine/indicators/__tests__/zones.test.ts +95 -95
  68. package/src/engine/indicators/atrState.ts +27 -27
  69. package/src/engine/indicators/bollState.ts +51 -51
  70. package/src/engine/indicators/calculators.ts +2593 -2593
  71. package/src/engine/indicators/cciState.ts +25 -25
  72. package/src/engine/indicators/chaikinVolState.ts +32 -32
  73. package/src/engine/indicators/cmfState.ts +27 -27
  74. package/src/engine/indicators/demaState.ts +27 -27
  75. package/src/engine/indicators/donchianState.ts +43 -43
  76. package/src/engine/indicators/eneState.ts +43 -43
  77. package/src/engine/indicators/expmaState.ts +43 -43
  78. package/src/engine/indicators/fastkState.ts +25 -25
  79. package/src/engine/indicators/fibState.ts +41 -41
  80. package/src/engine/indicators/hmaState.ts +27 -27
  81. package/src/engine/indicators/hvState.ts +28 -28
  82. package/src/engine/indicators/ichimokuState.ts +70 -70
  83. package/src/engine/indicators/indicator.worker.ts +169 -169
  84. package/src/engine/indicators/indicatorDefinitionRegistry.ts +62 -62
  85. package/src/engine/indicators/indicatorMetadata.ts +110 -110
  86. package/src/engine/indicators/indicatorRegistry.ts +106 -106
  87. package/src/engine/indicators/indicatorRuntime.ts +1548 -1548
  88. package/src/engine/indicators/kamaState.ts +34 -34
  89. package/src/engine/indicators/keltnerState.ts +49 -49
  90. package/src/engine/indicators/kstState.ts +42 -42
  91. package/src/engine/indicators/maState.ts +36 -36
  92. package/src/engine/indicators/macdState.ts +76 -76
  93. package/src/engine/indicators/mfiState.ts +27 -27
  94. package/src/engine/indicators/momState.ts +25 -25
  95. package/src/engine/indicators/obvState.ts +25 -25
  96. package/src/engine/indicators/parkinsonState.ts +28 -28
  97. package/src/engine/indicators/pivotState.ts +51 -51
  98. package/src/engine/indicators/pvtState.ts +25 -25
  99. package/src/engine/indicators/rocState.ts +27 -27
  100. package/src/engine/indicators/rsiState.ts +65 -65
  101. package/src/engine/indicators/sarState.ts +41 -41
  102. package/src/engine/indicators/scheduler.ts +1205 -1205
  103. package/src/engine/indicators/soa.ts +352 -352
  104. package/src/engine/indicators/stateComposer.ts +1262 -1262
  105. package/src/engine/indicators/stochState.ts +26 -26
  106. package/src/engine/indicators/structureState.ts +69 -69
  107. package/src/engine/indicators/supertrendState.ts +37 -37
  108. package/src/engine/indicators/temaState.ts +27 -27
  109. package/src/engine/indicators/trixState.ts +35 -35
  110. package/src/engine/indicators/vmaState.ts +27 -27
  111. package/src/engine/indicators/volumeProfileState.ts +63 -63
  112. package/src/engine/indicators/vwapState.ts +29 -29
  113. package/src/engine/indicators/wmaState.ts +27 -27
  114. package/src/engine/indicators/wmsrState.ts +25 -25
  115. package/src/engine/indicators/workerProtocol.ts +613 -613
  116. package/src/engine/indicators/zonesState.ts +47 -47
  117. package/src/engine/layout/pane.ts +161 -161
  118. package/src/engine/marker/registry.ts +265 -265
  119. package/src/engine/paneRenderer.ts +169 -169
  120. package/src/engine/renderers/Indicator/atr.ts +237 -237
  121. package/src/engine/renderers/Indicator/boll.ts +317 -317
  122. package/src/engine/renderers/Indicator/cci.ts +275 -275
  123. package/src/engine/renderers/Indicator/chaikinVol.ts +138 -138
  124. package/src/engine/renderers/Indicator/cmf.ts +137 -137
  125. package/src/engine/renderers/Indicator/dema.ts +136 -136
  126. package/src/engine/renderers/Indicator/donchian.ts +137 -137
  127. package/src/engine/renderers/Indicator/ene.ts +271 -271
  128. package/src/engine/renderers/Indicator/expma.ts +197 -197
  129. package/src/engine/renderers/Indicator/fastk.ts +316 -316
  130. package/src/engine/renderers/Indicator/fib.ts +141 -141
  131. package/src/engine/renderers/Indicator/hma.ts +136 -136
  132. package/src/engine/renderers/Indicator/hv.ts +124 -124
  133. package/src/engine/renderers/Indicator/ichimoku.ts +181 -181
  134. package/src/engine/renderers/Indicator/index.ts +241 -241
  135. package/src/engine/renderers/Indicator/indicatorData.ts +650 -650
  136. package/src/engine/renderers/Indicator/kama.ts +136 -136
  137. package/src/engine/renderers/Indicator/keltner.ts +137 -137
  138. package/src/engine/renderers/Indicator/kst.ts +302 -302
  139. package/src/engine/renderers/Indicator/ma.ts +200 -200
  140. package/src/engine/renderers/Indicator/macd.ts +477 -477
  141. package/src/engine/renderers/Indicator/macdLegend.ts +141 -141
  142. package/src/engine/renderers/Indicator/mainIndicatorLegend.ts +272 -272
  143. package/src/engine/renderers/Indicator/mfi.ts +142 -142
  144. package/src/engine/renderers/Indicator/mom.ts +311 -311
  145. package/src/engine/renderers/Indicator/obv.ts +123 -123
  146. package/src/engine/renderers/Indicator/parkinson.ts +124 -124
  147. package/src/engine/renderers/Indicator/pivot.ts +131 -131
  148. package/src/engine/renderers/Indicator/pvt.ts +123 -123
  149. package/src/engine/renderers/Indicator/roc.ts +143 -143
  150. package/src/engine/renderers/Indicator/rsi.ts +390 -390
  151. package/src/engine/renderers/Indicator/sar.ts +113 -113
  152. package/src/engine/renderers/Indicator/scale/atr_scale.ts +19 -19
  153. package/src/engine/renderers/Indicator/scale/cci_scale.ts +19 -19
  154. package/src/engine/renderers/Indicator/scale/fastk_scale.ts +19 -19
  155. package/src/engine/renderers/Indicator/scale/indicator_scale.ts +204 -204
  156. package/src/engine/renderers/Indicator/scale/kst_scale.ts +19 -19
  157. package/src/engine/renderers/Indicator/scale/macd_scale.ts +22 -22
  158. package/src/engine/renderers/Indicator/scale/mom_scale.ts +19 -19
  159. package/src/engine/renderers/Indicator/scale/rsi_scale.ts +19 -19
  160. package/src/engine/renderers/Indicator/scale/stoch_scale.ts +19 -19
  161. package/src/engine/renderers/Indicator/scale/volume_scale.ts +26 -26
  162. package/src/engine/renderers/Indicator/scale/wmsr_scale.ts +19 -19
  163. package/src/engine/renderers/Indicator/stoch.ts +359 -359
  164. package/src/engine/renderers/Indicator/structure.ts +126 -126
  165. package/src/engine/renderers/Indicator/subPaneConfig.ts +265 -265
  166. package/src/engine/renderers/Indicator/supertrend.ts +115 -115
  167. package/src/engine/renderers/Indicator/tema.ts +136 -136
  168. package/src/engine/renderers/Indicator/trix.ts +158 -158
  169. package/src/engine/renderers/Indicator/vma.ts +124 -124
  170. package/src/engine/renderers/Indicator/volumeProfile.ts +125 -125
  171. package/src/engine/renderers/Indicator/vwap.ts +123 -123
  172. package/src/engine/renderers/Indicator/wma.ts +136 -136
  173. package/src/engine/renderers/Indicator/wmsr.ts +328 -328
  174. package/src/engine/renderers/Indicator/zones.ts +104 -104
  175. package/src/engine/renderers/__tests__/boll.renderer.test.ts +314 -314
  176. package/src/engine/renderers/__tests__/ene.renderer.test.ts +305 -305
  177. package/src/engine/renderers/__tests__/expma.renderer.test.ts +279 -279
  178. package/src/engine/renderers/__tests__/ma.renderer.test.ts +426 -426
  179. package/src/engine/renderers/__tests__/mainIndicatorLegend.renderer.test.ts +502 -502
  180. package/src/engine/renderers/__tests__/yAxis.renderer.test.ts +173 -173
  181. package/src/engine/renderers/candle.ts +459 -459
  182. package/src/engine/renderers/crosshair.ts +69 -69
  183. package/src/engine/renderers/customMarkers.ts +162 -162
  184. package/src/engine/renderers/extremaMarkers.ts +246 -246
  185. package/src/engine/renderers/gridLines.ts +90 -90
  186. package/src/engine/renderers/lastPrice.ts +97 -97
  187. package/src/engine/renderers/paneTitle.ts +136 -136
  188. package/src/engine/renderers/subVolume.ts +236 -236
  189. package/src/engine/renderers/timeAxis.ts +121 -121
  190. package/src/engine/renderers/webgl/candleSurface.ts +955 -955
  191. package/src/engine/renderers/webgl/sharedWebGLSurface.ts +146 -146
  192. package/src/engine/renderers/yAxis.ts +105 -105
  193. package/src/engine/scale/__tests__/logFormula.spec.ts +148 -148
  194. package/src/engine/scale/logFormula.ts +130 -130
  195. package/src/engine/scale/price.ts +39 -39
  196. package/src/engine/scale/priceScale.ts +264 -264
  197. package/src/engine/subPaneManager.ts +427 -427
  198. package/src/engine/theme/colors.ts +642 -642
  199. package/src/engine/theme/fonts.ts +20 -20
  200. package/src/engine/utils/klineConfig.ts +49 -49
  201. package/src/engine/utils/tickCount.ts +11 -11
  202. package/src/engine/utils/tickPosition.ts +214 -214
  203. package/src/engine/utils/zoom.ts +83 -83
  204. package/src/engine/viewport/viewport.ts +67 -67
  205. package/src/index.ts +3 -3
  206. package/src/plugin/ConfigManager.ts +93 -93
  207. package/src/plugin/EventBus.ts +77 -77
  208. package/src/plugin/HookSystem.ts +106 -106
  209. package/src/plugin/PluginHost.ts +243 -243
  210. package/src/plugin/PluginRegistry.ts +92 -92
  211. package/src/plugin/StateStore.ts +73 -73
  212. package/src/plugin/index.ts +19 -19
  213. package/src/plugin/rendererPluginManager.ts +368 -368
  214. package/src/plugin/stateKeys.ts +8 -8
  215. package/src/plugin/types.ts +526 -526
  216. package/src/reactivity/index.ts +2 -2
  217. package/src/reactivity/signal.ts +119 -119
  218. package/src/semantic/controller.ts +251 -251
  219. package/src/semantic/drawShape.ts +260 -260
  220. package/src/semantic/index.ts +28 -28
  221. package/src/semantic/schema.json +256 -256
  222. package/src/semantic/types.ts +251 -251
  223. package/src/semantic/validator.ts +349 -349
  224. package/src/types/kLine.ts +13 -13
  225. package/src/types/price.ts +56 -56
  226. package/src/types/volumePrice.ts +33 -33
  227. package/src/utils/dateFormat.ts +208 -208
  228. package/src/utils/kLineDraw/axis.ts +562 -562
  229. package/src/utils/priceToY.ts +34 -34
  230. package/src/utils/volumePrice.ts +202 -202
  231. package/src/version.ts +1 -1
@@ -1,284 +1,284 @@
1
- /**
2
- * Framework-agnostic controller interfaces.
3
- *
4
- * Every adapter (React, Vue, Angular) consumes these. Controllers expose state as
5
- * `Signal<T>` so adapters bridge with their own reactivity (useSyncExternalStore,
6
- * shallowRef, toSignal).
7
- *
8
- * Mutation methods are imperative — adapters call them in event handlers.
9
- */
10
-
11
- import type { Signal } from '../reactivity'
12
- import type { CustomMarkerEntity } from '../engine/marker/registry'
13
-
14
- // Controller-owned public surface. Legacy engine types may mirror these
15
- // shapes internally, but adapters depend only on core-defined contracts.
16
- export interface ChartViewport {
17
- zoomLevel: number
18
- plotWidth: number
19
- plotHeight: number
20
- dpr: number
21
- visibleFrom: number
22
- visibleTo: number
23
- desiredScrollLeft: number | undefined
24
- kWidth: number
25
- kGap: number
26
- }
27
-
28
- export type IndicatorRole = 'main' | 'sub'
29
-
30
- export interface IndicatorInstance {
31
- id: string
32
- definitionId: string
33
- label: string
34
- name: string
35
- role: IndicatorRole
36
- paneId?: string
37
- params: Record<string, unknown>
38
- }
39
-
40
- export interface SubPaneInfo {
41
- paneId: string
42
- indicatorId: string
43
- params: Record<string, unknown>
44
- ratio: number
45
- }
46
-
47
- export type DrawingToolType = 'trendline' | 'horizontal' | 'fib' | 'rectangle' | 'arrow'
48
-
49
- export interface DrawingObject {
50
- id: string
51
- type: DrawingToolType
52
- }
53
-
54
- export type IndicatorPaneRole = IndicatorRole
55
-
56
- // ---------------------------------------------------------------------------
57
- // Data shapes (mirror src/types/price.ts — single source of truth lives here
58
- // long-term; the legacy types re-export from here once migration completes)
59
- // ---------------------------------------------------------------------------
60
-
61
- export interface KLineData {
62
- timestamp: number
63
- open: number
64
- high: number
65
- low: number
66
- close: number
67
- volume?: number
68
- turnover?: number
69
- stockCode?: string
70
- amplitude?: number
71
- changePercent?: number
72
- changeAmount?: number
73
- turnoverRate?: number
74
- }
75
-
76
- // ---------------------------------------------------------------------------
77
- // Indicator metadata
78
- // ---------------------------------------------------------------------------
79
-
80
- export interface IndicatorParamDef {
81
- key: string
82
- label: string
83
- type: 'number' | 'string' | 'boolean' | 'color' | 'select'
84
- default: number | string | boolean
85
- min?: number
86
- max?: number
87
- step?: number
88
- options?: ReadonlyArray<{ value: string; label: string }>
89
- }
90
-
91
- export interface IndicatorDefinition {
92
- id: string
93
- label: string
94
- name?: string
95
- description?: string
96
- role: IndicatorPaneRole
97
- params: ReadonlyArray<IndicatorParamDef>
98
- }
99
-
100
- // ---------------------------------------------------------------------------
101
- // Interaction state
102
- // ---------------------------------------------------------------------------
103
-
104
- export interface InteractionSnapshot {
105
- crosshairPos: { x: number; y: number } | null
106
- crosshairIndex: number | null
107
- crosshairPrice: number | null
108
- hoveredIndex: number | null
109
- activePaneId: string | null
110
- tooltipPos: { x: number; y: number }
111
- tooltipAnchorPlacement: 'right-bottom' | 'left-bottom'
112
- hoveredMarkerData: Record<string, unknown> | null
113
- hoveredCustomMarker: Record<string, unknown> | null
114
- isDragging: boolean
115
- isResizingPaneBoundary: boolean
116
- isHoveringPaneBoundary: boolean
117
- hoveredPaneBoundaryId: string | null
118
- isHoveringRightAxis: boolean
119
- }
120
-
121
- // ---------------------------------------------------------------------------
122
- // Drawing controller callback type (passed to handlePointerEvent)
123
- // ---------------------------------------------------------------------------
124
-
125
- export interface DrawingControllerCallbacks {
126
- onPointerDown?: (e: PointerEvent, container: HTMLElement) => boolean
127
- onPointerMove?: (e: PointerEvent, container: HTMLElement) => boolean
128
- onPointerUp?: (e: PointerEvent, container: HTMLElement) => boolean
129
- }
130
-
131
- // ---------------------------------------------------------------------------
132
- // ChartController — top-level facade; what `useChart` / `<KLineChart>` expose
133
- // ---------------------------------------------------------------------------
134
-
135
- export interface ChartMountOptions {
136
- container: HTMLElement
137
- data: ReadonlyArray<KLineData>
138
- initialZoomLevel?: number
139
- zoomLevels?: number
140
- theme?: 'light' | 'dark'
141
- }
142
-
143
- export interface ChartController {
144
- // ---- Signals ----
145
- readonly viewport: Signal<ChartViewport>
146
- readonly data: Signal<ReadonlyArray<KLineData>>
147
- readonly theme: Signal<'light' | 'dark'>
148
- readonly indicators: Signal<ReadonlyArray<IndicatorInstance>>
149
- readonly subPanes: Signal<ReadonlyArray<SubPaneInfo>>
150
- readonly drawingTool: Signal<DrawingToolType | null>
151
- readonly drawings: Signal<ReadonlyArray<DrawingObject>>
152
- readonly paneRatios: Signal<Readonly<Record<string, number>>>
153
- readonly interactionState: Signal<InteractionSnapshot>
154
-
155
- // indicator catalog (static — adapters use for picker UI)
156
- readonly catalog: ReadonlyArray<IndicatorDefinition>
157
-
158
- // ---- Data ----
159
- setData(next: ReadonlyArray<KLineData>): void
160
- appendData(next: ReadonlyArray<KLineData>): void
161
- updateData(next: ReadonlyArray<KLineData>): void
162
-
163
- // ---- Theme ----
164
- setTheme(theme: 'light' | 'dark'): void
165
-
166
- // ---- Zoom ----
167
- zoomToLevel(level: number, anchorX?: number): void
168
- zoomIn(anchorX?: number): void
169
- zoomOut(anchorX?: number): void
170
-
171
- // ---- Interaction ----
172
- handlePointerEvent(e: PointerEvent, drawingController?: DrawingControllerCallbacks): boolean
173
- handleWheelEvent(e: WheelEvent): void
174
- handleScrollEvent(): void
175
- handlePinchZoom(delta: number, centerClientX: number): void
176
-
177
- // ---- Indicators ----
178
- addIndicator(
179
- definitionId: string,
180
- role: 'main' | 'sub',
181
- params?: Record<string, unknown>,
182
- ): string | null
183
- removeIndicator(instanceId: string): boolean
184
- updateIndicatorParams(instanceId: string, params: Record<string, unknown>): boolean
185
- updateRendererConfig(name: string, config: Record<string, unknown>): void
186
-
187
- // ---- Drawing ----
188
- setDrawingTool(tool: DrawingToolType | null): void
189
- clearDrawings(): void
190
- removeDrawing(drawingId: string): void
191
-
192
- // ---- Layout ----
193
- resizeSubPane(paneId: string, deltaY: number): boolean
194
- createSubPane(paneId: string, indicatorId: string, params?: Record<string, unknown>): boolean
195
- clearSubPanes(): void
196
-
197
- // ---- Drawing / Markers ----
198
- updateCustomMarkers(markers: ReadonlyArray<CustomMarkerEntity>): void
199
- clearCustomMarkers(): void
200
-
201
- // ---- Settings ----
202
- updateSettingsFacade(settings: Record<string, unknown>): void
203
- updateOptionsFacade(options: Record<string, unknown>): void
204
-
205
- /** tear down DOM + listeners; idempotent */
206
- dispose(): void
207
- }
208
-
209
- /**
210
- * Factory contract — adapters call this on mount.
211
- *
212
- * Implementation lives in packages/core/src/controllers/createChartController.ts
213
- * (Phase 1 deliverable). It wires the existing Chart engine in src/core/chart.ts.
214
- */
215
- export type ChartControllerFactory = (opts: ChartMountOptions) => ChartController
216
-
217
- // ---------------------------------------------------------------------------
218
- // Legacy type aliases (deprecated — kept for internal sub-controller tests)
219
- // ---------------------------------------------------------------------------
220
-
221
- /** @deprecated Use `IndicatorInstance` instead. Kept for createIndicatorSelectorController tests. */
222
- export interface ActiveIndicator {
223
- id: string
224
- definitionId: string
225
- label: string
226
- name: string
227
- role: IndicatorPaneRole
228
- params: Readonly<Record<string, number | string | boolean>>
229
- }
230
-
231
- /** @deprecated Flattened into ChartController. Kept for createIndicatorSelectorController tests. */
232
- export interface IndicatorSelectorController {
233
- readonly catalog: Signal<ReadonlyArray<IndicatorDefinition>>
234
- readonly active: Signal<ReadonlyArray<ActiveIndicator>>
235
- readonly menuOpen: Signal<boolean>
236
- readonly searchQuery: Signal<string>
237
- readonly filteredMain: Signal<ReadonlyArray<IndicatorDefinition>>
238
- readonly filteredSub: Signal<ReadonlyArray<IndicatorDefinition>>
239
- add(definitionId: string): string | null
240
- remove(instanceId: string): boolean
241
- updateParams(instanceId: string, params: Record<string, number | string | boolean>): boolean
242
- reorder(fromInstanceId: string, toInstanceId: string): boolean
243
- openMenu(): void
244
- closeMenu(): void
245
- toggleMenu(): void
246
- setSearchQuery(q: string): void
247
- isActive(definitionId: string): boolean
248
- dispose(): void
249
- }
250
-
251
- export type ToolId = string
252
-
253
- export interface ToolDefinition {
254
- id: ToolId
255
- label: string
256
- icon?: string
257
- group?: string
258
- disabled?: boolean
259
- }
260
-
261
- /** @deprecated Flattened into ChartController. Kept for createToolbarController tests. */
262
- export interface ToolbarController {
263
- readonly tools: Signal<ReadonlyArray<ToolDefinition>>
264
- readonly activeTool: Signal<ToolId | null>
265
- readonly disabledTools: Signal<ReadonlySet<ToolId>>
266
- selectTool(id: ToolId): void
267
- clearSelection(): void
268
- setDisabled(id: ToolId, disabled: boolean): void
269
- dispose(): void
270
- }
271
-
272
- export interface DrawingState {
273
- readonly activeTool: DrawingToolType | null
274
- readonly drawingCount: number
275
- }
276
-
277
- /** @deprecated Flattened into ChartController. Kept for createDrawingController tests. */
278
- export interface DrawingController {
279
- readonly state: Signal<DrawingState>
280
- setActiveTool(tool: DrawingToolType | null): void
281
- clearAll(): void
282
- deleteLast(): void
283
- dispose(): void
284
- }
1
+ /**
2
+ * Framework-agnostic controller interfaces.
3
+ *
4
+ * Every adapter (React, Vue, Angular) consumes these. Controllers expose state as
5
+ * `Signal<T>` so adapters bridge with their own reactivity (useSyncExternalStore,
6
+ * shallowRef, toSignal).
7
+ *
8
+ * Mutation methods are imperative — adapters call them in event handlers.
9
+ */
10
+
11
+ import type { Signal } from '../reactivity'
12
+ import type { CustomMarkerEntity } from '../engine/marker/registry'
13
+
14
+ // Controller-owned public surface. Legacy engine types may mirror these
15
+ // shapes internally, but adapters depend only on core-defined contracts.
16
+ export interface ChartViewport {
17
+ zoomLevel: number
18
+ plotWidth: number
19
+ plotHeight: number
20
+ dpr: number
21
+ visibleFrom: number
22
+ visibleTo: number
23
+ desiredScrollLeft: number | undefined
24
+ kWidth: number
25
+ kGap: number
26
+ }
27
+
28
+ export type IndicatorRole = 'main' | 'sub'
29
+
30
+ export interface IndicatorInstance {
31
+ id: string
32
+ definitionId: string
33
+ label: string
34
+ name: string
35
+ role: IndicatorRole
36
+ paneId?: string
37
+ params: Record<string, unknown>
38
+ }
39
+
40
+ export interface SubPaneInfo {
41
+ paneId: string
42
+ indicatorId: string
43
+ params: Record<string, unknown>
44
+ ratio: number
45
+ }
46
+
47
+ export type DrawingToolType = 'trendline' | 'horizontal' | 'fib' | 'rectangle' | 'arrow'
48
+
49
+ export interface DrawingObject {
50
+ id: string
51
+ type: DrawingToolType
52
+ }
53
+
54
+ export type IndicatorPaneRole = IndicatorRole
55
+
56
+ // ---------------------------------------------------------------------------
57
+ // Data shapes (mirror src/types/price.ts — single source of truth lives here
58
+ // long-term; the legacy types re-export from here once migration completes)
59
+ // ---------------------------------------------------------------------------
60
+
61
+ export interface KLineData {
62
+ timestamp: number
63
+ open: number
64
+ high: number
65
+ low: number
66
+ close: number
67
+ volume?: number
68
+ turnover?: number
69
+ stockCode?: string
70
+ amplitude?: number
71
+ changePercent?: number
72
+ changeAmount?: number
73
+ turnoverRate?: number
74
+ }
75
+
76
+ // ---------------------------------------------------------------------------
77
+ // Indicator metadata
78
+ // ---------------------------------------------------------------------------
79
+
80
+ export interface IndicatorParamDef {
81
+ key: string
82
+ label: string
83
+ type: 'number' | 'string' | 'boolean' | 'color' | 'select'
84
+ default: number | string | boolean
85
+ min?: number
86
+ max?: number
87
+ step?: number
88
+ options?: ReadonlyArray<{ value: string; label: string }>
89
+ }
90
+
91
+ export interface IndicatorDefinition {
92
+ id: string
93
+ label: string
94
+ name?: string
95
+ description?: string
96
+ role: IndicatorPaneRole
97
+ params: ReadonlyArray<IndicatorParamDef>
98
+ }
99
+
100
+ // ---------------------------------------------------------------------------
101
+ // Interaction state
102
+ // ---------------------------------------------------------------------------
103
+
104
+ export interface InteractionSnapshot {
105
+ crosshairPos: { x: number; y: number } | null
106
+ crosshairIndex: number | null
107
+ crosshairPrice: number | null
108
+ hoveredIndex: number | null
109
+ activePaneId: string | null
110
+ tooltipPos: { x: number; y: number }
111
+ tooltipAnchorPlacement: 'right-bottom' | 'left-bottom'
112
+ hoveredMarkerData: Record<string, unknown> | null
113
+ hoveredCustomMarker: Record<string, unknown> | null
114
+ isDragging: boolean
115
+ isResizingPaneBoundary: boolean
116
+ isHoveringPaneBoundary: boolean
117
+ hoveredPaneBoundaryId: string | null
118
+ isHoveringRightAxis: boolean
119
+ }
120
+
121
+ // ---------------------------------------------------------------------------
122
+ // Drawing controller callback type (passed to handlePointerEvent)
123
+ // ---------------------------------------------------------------------------
124
+
125
+ export interface DrawingControllerCallbacks {
126
+ onPointerDown?: (e: PointerEvent, container: HTMLElement) => boolean
127
+ onPointerMove?: (e: PointerEvent, container: HTMLElement) => boolean
128
+ onPointerUp?: (e: PointerEvent, container: HTMLElement) => boolean
129
+ }
130
+
131
+ // ---------------------------------------------------------------------------
132
+ // ChartController — top-level facade; what `useChart` / `<KLineChart>` expose
133
+ // ---------------------------------------------------------------------------
134
+
135
+ export interface ChartMountOptions {
136
+ container: HTMLElement
137
+ data: ReadonlyArray<KLineData>
138
+ initialZoomLevel?: number
139
+ zoomLevels?: number
140
+ theme?: 'light' | 'dark'
141
+ }
142
+
143
+ export interface ChartController {
144
+ // ---- Signals ----
145
+ readonly viewport: Signal<ChartViewport>
146
+ readonly data: Signal<ReadonlyArray<KLineData>>
147
+ readonly theme: Signal<'light' | 'dark'>
148
+ readonly indicators: Signal<ReadonlyArray<IndicatorInstance>>
149
+ readonly subPanes: Signal<ReadonlyArray<SubPaneInfo>>
150
+ readonly drawingTool: Signal<DrawingToolType | null>
151
+ readonly drawings: Signal<ReadonlyArray<DrawingObject>>
152
+ readonly paneRatios: Signal<Readonly<Record<string, number>>>
153
+ readonly interactionState: Signal<InteractionSnapshot>
154
+
155
+ // indicator catalog (static — adapters use for picker UI)
156
+ readonly catalog: ReadonlyArray<IndicatorDefinition>
157
+
158
+ // ---- Data ----
159
+ setData(next: ReadonlyArray<KLineData>): void
160
+ appendData(next: ReadonlyArray<KLineData>): void
161
+ updateData(next: ReadonlyArray<KLineData>): void
162
+
163
+ // ---- Theme ----
164
+ setTheme(theme: 'light' | 'dark'): void
165
+
166
+ // ---- Zoom ----
167
+ zoomToLevel(level: number, anchorX?: number): void
168
+ zoomIn(anchorX?: number): void
169
+ zoomOut(anchorX?: number): void
170
+
171
+ // ---- Interaction ----
172
+ handlePointerEvent(e: PointerEvent, drawingController?: DrawingControllerCallbacks): boolean
173
+ handleWheelEvent(e: WheelEvent): void
174
+ handleScrollEvent(): void
175
+ handlePinchZoom(delta: number, centerClientX: number): void
176
+
177
+ // ---- Indicators ----
178
+ addIndicator(
179
+ definitionId: string,
180
+ role: 'main' | 'sub',
181
+ params?: Record<string, unknown>,
182
+ ): string | null
183
+ removeIndicator(instanceId: string): boolean
184
+ updateIndicatorParams(instanceId: string, params: Record<string, unknown>): boolean
185
+ updateRendererConfig(name: string, config: Record<string, unknown>): void
186
+
187
+ // ---- Drawing ----
188
+ setDrawingTool(tool: DrawingToolType | null): void
189
+ clearDrawings(): void
190
+ removeDrawing(drawingId: string): void
191
+
192
+ // ---- Layout ----
193
+ resizeSubPane(paneId: string, deltaY: number): boolean
194
+ createSubPane(paneId: string, indicatorId: string, params?: Record<string, unknown>): boolean
195
+ clearSubPanes(): void
196
+
197
+ // ---- Drawing / Markers ----
198
+ updateCustomMarkers(markers: ReadonlyArray<CustomMarkerEntity>): void
199
+ clearCustomMarkers(): void
200
+
201
+ // ---- Settings ----
202
+ updateSettingsFacade(settings: Record<string, unknown>): void
203
+ updateOptionsFacade(options: Record<string, unknown>): void
204
+
205
+ /** tear down DOM + listeners; idempotent */
206
+ dispose(): void
207
+ }
208
+
209
+ /**
210
+ * Factory contract — adapters call this on mount.
211
+ *
212
+ * Implementation lives in packages/core/src/controllers/createChartController.ts
213
+ * (Phase 1 deliverable). It wires the existing Chart engine in src/core/chart.ts.
214
+ */
215
+ export type ChartControllerFactory = (opts: ChartMountOptions) => ChartController
216
+
217
+ // ---------------------------------------------------------------------------
218
+ // Legacy type aliases (deprecated — kept for internal sub-controller tests)
219
+ // ---------------------------------------------------------------------------
220
+
221
+ /** @deprecated Use `IndicatorInstance` instead. Kept for createIndicatorSelectorController tests. */
222
+ export interface ActiveIndicator {
223
+ id: string
224
+ definitionId: string
225
+ label: string
226
+ name: string
227
+ role: IndicatorPaneRole
228
+ params: Readonly<Record<string, number | string | boolean>>
229
+ }
230
+
231
+ /** @deprecated Flattened into ChartController. Kept for createIndicatorSelectorController tests. */
232
+ export interface IndicatorSelectorController {
233
+ readonly catalog: Signal<ReadonlyArray<IndicatorDefinition>>
234
+ readonly active: Signal<ReadonlyArray<ActiveIndicator>>
235
+ readonly menuOpen: Signal<boolean>
236
+ readonly searchQuery: Signal<string>
237
+ readonly filteredMain: Signal<ReadonlyArray<IndicatorDefinition>>
238
+ readonly filteredSub: Signal<ReadonlyArray<IndicatorDefinition>>
239
+ add(definitionId: string): string | null
240
+ remove(instanceId: string): boolean
241
+ updateParams(instanceId: string, params: Record<string, number | string | boolean>): boolean
242
+ reorder(fromInstanceId: string, toInstanceId: string): boolean
243
+ openMenu(): void
244
+ closeMenu(): void
245
+ toggleMenu(): void
246
+ setSearchQuery(q: string): void
247
+ isActive(definitionId: string): boolean
248
+ dispose(): void
249
+ }
250
+
251
+ export type ToolId = string
252
+
253
+ export interface ToolDefinition {
254
+ id: ToolId
255
+ label: string
256
+ icon?: string
257
+ group?: string
258
+ disabled?: boolean
259
+ }
260
+
261
+ /** @deprecated Flattened into ChartController. Kept for createToolbarController tests. */
262
+ export interface ToolbarController {
263
+ readonly tools: Signal<ReadonlyArray<ToolDefinition>>
264
+ readonly activeTool: Signal<ToolId | null>
265
+ readonly disabledTools: Signal<ReadonlySet<ToolId>>
266
+ selectTool(id: ToolId): void
267
+ clearSelection(): void
268
+ setDisabled(id: ToolId, disabled: boolean): void
269
+ dispose(): void
270
+ }
271
+
272
+ export interface DrawingState {
273
+ readonly activeTool: DrawingToolType | null
274
+ readonly drawingCount: number
275
+ }
276
+
277
+ /** @deprecated Flattened into ChartController. Kept for createDrawingController tests. */
278
+ export interface DrawingController {
279
+ readonly state: Signal<DrawingState>
280
+ setActiveTool(tool: DrawingToolType | null): void
281
+ clearAll(): void
282
+ deleteLast(): void
283
+ dispose(): void
284
+ }