@363045841yyt/klinechart-core 0.8.12 → 0.8.13-alpha.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.
Files changed (1134) hide show
  1. package/README.md +18 -12
  2. package/README.zh-CN.md +18 -12
  3. package/dist/alerts/createAlertController.d.ts.map +1 -1
  4. package/dist/alerts/createAlertController.js +2 -6
  5. package/dist/alerts/createAlertController.js.map +1 -1
  6. package/dist/alerts/index.d.ts +1 -1
  7. package/dist/alerts/index.d.ts.map +1 -1
  8. package/dist/alerts/index.js +1 -1
  9. package/dist/alerts/index.js.map +1 -1
  10. package/dist/alerts/predicates.d.ts.map +1 -1
  11. package/dist/alerts/predicates.js +1 -4
  12. package/dist/alerts/predicates.js.map +1 -1
  13. package/dist/alerts/ruleSchema.d.ts.map +1 -1
  14. package/dist/alerts/ruleSchema.js +1 -1
  15. package/dist/alerts/ruleSchema.js.map +1 -1
  16. package/dist/alerts/types.d.ts.map +1 -1
  17. package/dist/chartTypes/heikinAshi.d.ts.map +1 -1
  18. package/dist/chartTypes/heikinAshi.js.map +1 -1
  19. package/dist/chartTypes/pointAndFigure.d.ts.map +1 -1
  20. package/dist/chartTypes/pointAndFigure.js.map +1 -1
  21. package/dist/chartTypes/rangeBars.d.ts.map +1 -1
  22. package/dist/chartTypes/rangeBars.js.map +1 -1
  23. package/dist/chartTypes/renko.d.ts.map +1 -1
  24. package/dist/chartTypes/renko.js.map +1 -1
  25. package/dist/chartTypes/types.d.ts.map +1 -1
  26. package/dist/components/anchoredVwap/computeAnchoredVwap.d.ts.map +1 -1
  27. package/dist/components/anchoredVwap/computeAnchoredVwap.js.map +1 -1
  28. package/dist/components/anchoredVwap/createAnchoredVwapController.d.ts.map +1 -1
  29. package/dist/components/anchoredVwap/createAnchoredVwapController.js +6 -17
  30. package/dist/components/anchoredVwap/createAnchoredVwapController.js.map +1 -1
  31. package/dist/components/anchoredVwap/index.d.ts.map +1 -1
  32. package/dist/components/anchoredVwap/types.d.ts.map +1 -1
  33. package/dist/components/crosshairSync/createCrosshairSync.d.ts.map +1 -1
  34. package/dist/components/crosshairSync/createCrosshairSync.js.map +1 -1
  35. package/dist/components/crosshairSync/index.d.ts.map +1 -1
  36. package/dist/components/crosshairSync/index.js.map +1 -1
  37. package/dist/components/footprint/aggressor.d.ts.map +1 -1
  38. package/dist/components/footprint/aggressor.js.map +1 -1
  39. package/dist/components/footprint/createFootprintController.d.ts.map +1 -1
  40. package/dist/components/footprint/createFootprintController.js +2 -3
  41. package/dist/components/footprint/createFootprintController.js.map +1 -1
  42. package/dist/components/footprint/index.d.ts +2 -2
  43. package/dist/components/footprint/index.d.ts.map +1 -1
  44. package/dist/components/footprint/index.js +2 -2
  45. package/dist/components/footprint/index.js.map +1 -1
  46. package/dist/components/footprint/perBarStats.d.ts.map +1 -1
  47. package/dist/components/footprint/perBarStats.js.map +1 -1
  48. package/dist/components/footprint/types.d.ts.map +1 -1
  49. package/dist/components/mtfOverlay/alignToBaseIndex.d.ts.map +1 -1
  50. package/dist/components/mtfOverlay/alignToBaseIndex.js.map +1 -1
  51. package/dist/components/mtfOverlay/createMtfController.d.ts.map +1 -1
  52. package/dist/components/mtfOverlay/createMtfController.js.map +1 -1
  53. package/dist/components/mtfOverlay/index.d.ts.map +1 -1
  54. package/dist/components/mtfOverlay/resampleBars.d.ts.map +1 -1
  55. package/dist/components/mtfOverlay/resampleBars.js.map +1 -1
  56. package/dist/components/mtfOverlay/types.d.ts.map +1 -1
  57. package/dist/components/orderBookHeatmap/createHeatmapController.d.ts.map +1 -1
  58. package/dist/components/orderBookHeatmap/createHeatmapController.js +20 -3
  59. package/dist/components/orderBookHeatmap/createHeatmapController.js.map +1 -1
  60. package/dist/components/orderBookHeatmap/createOrderBookState.d.ts.map +1 -1
  61. package/dist/components/orderBookHeatmap/createOrderBookState.js +1 -3
  62. package/dist/components/orderBookHeatmap/createOrderBookState.js.map +1 -1
  63. package/dist/components/orderBookHeatmap/deltaArchive.d.ts.map +1 -1
  64. package/dist/components/orderBookHeatmap/deltaArchive.js.map +1 -1
  65. package/dist/components/orderBookHeatmap/index.d.ts.map +1 -1
  66. package/dist/components/orderBookHeatmap/logColorScale.d.ts.map +1 -1
  67. package/dist/components/orderBookHeatmap/logColorScale.js.map +1 -1
  68. package/dist/components/orderBookHeatmap/snapshotRing.d.ts.map +1 -1
  69. package/dist/components/orderBookHeatmap/snapshotRing.js.map +1 -1
  70. package/dist/components/orderBookHeatmap/types.d.ts +10 -0
  71. package/dist/components/orderBookHeatmap/types.d.ts.map +1 -1
  72. package/dist/components/volumeProfile/binning.d.ts.map +1 -1
  73. package/dist/components/volumeProfile/binning.js.map +1 -1
  74. package/dist/components/volumeProfile/createVolumeProfileController.d.ts.map +1 -1
  75. package/dist/components/volumeProfile/createVolumeProfileController.js.map +1 -1
  76. package/dist/components/volumeProfile/index.d.ts.map +1 -1
  77. package/dist/components/volumeProfile/poc.js.map +1 -1
  78. package/dist/components/volumeProfile/types.d.ts.map +1 -1
  79. package/dist/components/volumeProfile/valueArea.d.ts.map +1 -1
  80. package/dist/components/volumeProfile/valueArea.js.map +1 -1
  81. package/dist/config/chartSettings.d.ts.map +1 -1
  82. package/dist/config/chartSettings.js +56 -11
  83. package/dist/config/chartSettings.js.map +1 -1
  84. package/dist/controllers/createChartController.d.ts.map +1 -1
  85. package/dist/controllers/createChartController.js +33 -14
  86. package/dist/controllers/createChartController.js.map +1 -1
  87. package/dist/controllers/createDrawingController.d.ts.map +1 -1
  88. package/dist/controllers/createDrawingController.js.map +1 -1
  89. package/dist/controllers/createIndicatorSelectorController.d.ts.map +1 -1
  90. package/dist/controllers/createIndicatorSelectorController.js +1 -2
  91. package/dist/controllers/createIndicatorSelectorController.js.map +1 -1
  92. package/dist/controllers/createToolbarController.d.ts.map +1 -1
  93. package/dist/controllers/createToolbarController.js +1 -3
  94. package/dist/controllers/createToolbarController.js.map +1 -1
  95. package/dist/controllers/index.d.ts +7 -5
  96. package/dist/controllers/index.d.ts.map +1 -1
  97. package/dist/controllers/index.js +5 -3
  98. package/dist/controllers/index.js.map +1 -1
  99. package/dist/controllers/types.d.ts +24 -0
  100. package/dist/controllers/types.d.ts.map +1 -1
  101. package/dist/data-fetchers/baostock.d.ts.map +1 -1
  102. package/dist/data-fetchers/baostock.js.map +1 -1
  103. package/dist/data-fetchers/binance.d.ts +33 -0
  104. package/dist/data-fetchers/binance.d.ts.map +1 -0
  105. package/dist/data-fetchers/binance.js +115 -0
  106. package/dist/data-fetchers/binance.js.map +1 -0
  107. package/dist/data-fetchers/dataBuffer.d.ts.map +1 -1
  108. package/dist/data-fetchers/dataBuffer.effects.d.ts.map +1 -1
  109. package/dist/data-fetchers/dataBuffer.effects.js.map +1 -1
  110. package/dist/data-fetchers/dataBuffer.js +8 -5
  111. package/dist/data-fetchers/dataBuffer.js.map +1 -1
  112. package/dist/data-fetchers/depthConnector.d.ts +47 -0
  113. package/dist/data-fetchers/depthConnector.d.ts.map +1 -0
  114. package/dist/data-fetchers/depthConnector.js +88 -0
  115. package/dist/data-fetchers/depthConnector.js.map +1 -0
  116. package/dist/data-fetchers/depthTypes.d.ts +52 -0
  117. package/dist/data-fetchers/depthTypes.d.ts.map +1 -0
  118. package/dist/data-fetchers/depthTypes.js +9 -0
  119. package/dist/data-fetchers/depthTypes.js.map +1 -0
  120. package/dist/data-fetchers/fetcherDefinitionRegistry.d.ts.map +1 -1
  121. package/dist/data-fetchers/fetcherDefinitionRegistry.js.map +1 -1
  122. package/dist/data-fetchers/gotdx.js +13 -3
  123. package/dist/data-fetchers/gotdx.js.map +1 -1
  124. package/dist/data-fetchers/index.d.ts +4 -1
  125. package/dist/data-fetchers/index.d.ts.map +1 -1
  126. package/dist/data-fetchers/index.js +3 -1
  127. package/dist/data-fetchers/index.js.map +1 -1
  128. package/dist/data-fetchers/router.d.ts.map +1 -1
  129. package/dist/data-fetchers/router.js +1 -1
  130. package/dist/data-fetchers/router.js.map +1 -1
  131. package/dist/data-fetchers/timeShareBuffer.d.ts.map +1 -1
  132. package/dist/data-fetchers/timeShareBuffer.js.map +1 -1
  133. package/dist/data-fetchers/tradingview.js.map +1 -1
  134. package/dist/engine/chart.d.ts +6 -2
  135. package/dist/engine/chart.d.ts.map +1 -1
  136. package/dist/engine/chart.js +48 -14
  137. package/dist/engine/chart.js.map +1 -1
  138. package/dist/engine/controller/interaction.d.ts.map +1 -1
  139. package/dist/engine/controller/interaction.js +30 -9
  140. package/dist/engine/controller/interaction.js.map +1 -1
  141. package/dist/engine/controller/markerInteraction.d.ts.map +1 -1
  142. package/dist/engine/controller/markerInteraction.js.map +1 -1
  143. package/dist/engine/data/chartDataManager.d.ts +11 -1
  144. package/dist/engine/data/chartDataManager.d.ts.map +1 -1
  145. package/dist/engine/data/chartDataManager.js +71 -22
  146. package/dist/engine/data/chartDataManager.js.map +1 -1
  147. package/dist/engine/draw/pixelAlign.d.ts.map +1 -1
  148. package/dist/engine/draw/pixelAlign.js.map +1 -1
  149. package/dist/engine/drawing/HitTester.d.ts.map +1 -1
  150. package/dist/engine/drawing/HitTester.js +3 -5
  151. package/dist/engine/drawing/HitTester.js.map +1 -1
  152. package/dist/engine/drawing/PreviewRenderer.d.ts.map +1 -1
  153. package/dist/engine/drawing/PreviewRenderer.js +25 -5
  154. package/dist/engine/drawing/PreviewRenderer.js.map +1 -1
  155. package/dist/engine/drawing/index.d.ts.map +1 -1
  156. package/dist/engine/drawing/index.js +88 -20
  157. package/dist/engine/drawing/index.js.map +1 -1
  158. package/dist/engine/drawing/interaction.d.ts.map +1 -1
  159. package/dist/engine/drawing/interaction.js.map +1 -1
  160. package/dist/engine/drawing/linearRegression.d.ts.map +1 -1
  161. package/dist/engine/drawing/linearRegression.js.map +1 -1
  162. package/dist/engine/drawing/plugin.d.ts.map +1 -1
  163. package/dist/engine/drawing/plugin.js +25 -10
  164. package/dist/engine/drawing/plugin.js.map +1 -1
  165. package/dist/engine/indicators/calculators/_shared.d.ts.map +1 -1
  166. package/dist/engine/indicators/calculators/_shared.js.map +1 -1
  167. package/dist/engine/indicators/calculators/bands.d.ts.map +1 -1
  168. package/dist/engine/indicators/calculators/bands.js +2 -2
  169. package/dist/engine/indicators/calculators/bands.js.map +1 -1
  170. package/dist/engine/indicators/calculators/index.d.ts +3 -3
  171. package/dist/engine/indicators/calculators/index.d.ts.map +1 -1
  172. package/dist/engine/indicators/calculators/index.js +2 -2
  173. package/dist/engine/indicators/calculators/index.js.map +1 -1
  174. package/dist/engine/indicators/calculators/movingAverages.d.ts.map +1 -1
  175. package/dist/engine/indicators/calculators/movingAverages.js.map +1 -1
  176. package/dist/engine/indicators/calculators/oscillators.d.ts.map +1 -1
  177. package/dist/engine/indicators/calculators/oscillators.js +3 -3
  178. package/dist/engine/indicators/calculators/oscillators.js.map +1 -1
  179. package/dist/engine/indicators/calculators/patterns.d.ts.map +1 -1
  180. package/dist/engine/indicators/calculators/patterns.js +3 -2
  181. package/dist/engine/indicators/calculators/patterns.js.map +1 -1
  182. package/dist/engine/indicators/calculators/volatility.d.ts.map +1 -1
  183. package/dist/engine/indicators/calculators/volatility.js +2 -2
  184. package/dist/engine/indicators/calculators/volatility.js.map +1 -1
  185. package/dist/engine/indicators/calculators/volume.d.ts.map +1 -1
  186. package/dist/engine/indicators/calculators/volume.js +1 -1
  187. package/dist/engine/indicators/calculators/volume.js.map +1 -1
  188. package/dist/engine/indicators/chartIndicatorManager.d.ts +7 -1
  189. package/dist/engine/indicators/chartIndicatorManager.d.ts.map +1 -1
  190. package/dist/engine/indicators/chartIndicatorManager.js +44 -11
  191. package/dist/engine/indicators/chartIndicatorManager.js.map +1 -1
  192. package/dist/engine/indicators/indicator.worker.js +1 -1
  193. package/dist/engine/indicators/indicator.worker.js.map +1 -1
  194. package/dist/engine/indicators/indicatorDefinitionRegistry.d.ts.map +1 -1
  195. package/dist/engine/indicators/indicatorDefinitionRegistry.js +16 -10
  196. package/dist/engine/indicators/indicatorDefinitionRegistry.js.map +1 -1
  197. package/dist/engine/indicators/indicatorMetadata.d.ts.map +1 -1
  198. package/dist/engine/indicators/indicatorMetadata.js.map +1 -1
  199. package/dist/engine/indicators/indicatorRegistry.d.ts.map +1 -1
  200. package/dist/engine/indicators/indicatorRegistry.js +6 -3
  201. package/dist/engine/indicators/indicatorRegistry.js.map +1 -1
  202. package/dist/engine/indicators/indicatorRuntime.d.ts.map +1 -1
  203. package/dist/engine/indicators/indicatorRuntime.js +8 -8
  204. package/dist/engine/indicators/indicatorRuntime.js.map +1 -1
  205. package/dist/engine/indicators/registerBuiltins.d.ts.map +1 -1
  206. package/dist/engine/indicators/registerBuiltins.js.map +1 -1
  207. package/dist/engine/indicators/scheduler.d.ts.map +1 -1
  208. package/dist/engine/indicators/scheduler.js +19 -15
  209. package/dist/engine/indicators/scheduler.js.map +1 -1
  210. package/dist/engine/indicators/soa.d.ts.map +1 -1
  211. package/dist/engine/indicators/soa.js +1 -3
  212. package/dist/engine/indicators/soa.js.map +1 -1
  213. package/dist/engine/indicators/state/atrState.d.ts.map +1 -1
  214. package/dist/engine/indicators/state/atrState.js.map +1 -1
  215. package/dist/engine/indicators/state/bollState.d.ts.map +1 -1
  216. package/dist/engine/indicators/state/bollState.js.map +1 -1
  217. package/dist/engine/indicators/state/cciState.d.ts.map +1 -1
  218. package/dist/engine/indicators/state/cciState.js.map +1 -1
  219. package/dist/engine/indicators/state/chaikinVolState.d.ts.map +1 -1
  220. package/dist/engine/indicators/state/chaikinVolState.js.map +1 -1
  221. package/dist/engine/indicators/state/cmfState.d.ts.map +1 -1
  222. package/dist/engine/indicators/state/cmfState.js.map +1 -1
  223. package/dist/engine/indicators/state/demaState.d.ts.map +1 -1
  224. package/dist/engine/indicators/state/demaState.js.map +1 -1
  225. package/dist/engine/indicators/state/donchianState.d.ts.map +1 -1
  226. package/dist/engine/indicators/state/donchianState.js.map +1 -1
  227. package/dist/engine/indicators/state/eneState.d.ts.map +1 -1
  228. package/dist/engine/indicators/state/eneState.js.map +1 -1
  229. package/dist/engine/indicators/state/expmaState.d.ts.map +1 -1
  230. package/dist/engine/indicators/state/expmaState.js.map +1 -1
  231. package/dist/engine/indicators/state/fastkState.d.ts.map +1 -1
  232. package/dist/engine/indicators/state/fastkState.js.map +1 -1
  233. package/dist/engine/indicators/state/fibState.d.ts.map +1 -1
  234. package/dist/engine/indicators/state/fibState.js.map +1 -1
  235. package/dist/engine/indicators/state/hmaState.d.ts.map +1 -1
  236. package/dist/engine/indicators/state/hmaState.js.map +1 -1
  237. package/dist/engine/indicators/state/hvState.d.ts.map +1 -1
  238. package/dist/engine/indicators/state/hvState.js +5 -1
  239. package/dist/engine/indicators/state/hvState.js.map +1 -1
  240. package/dist/engine/indicators/state/ichimokuState.d.ts.map +1 -1
  241. package/dist/engine/indicators/state/ichimokuState.js.map +1 -1
  242. package/dist/engine/indicators/state/kamaState.d.ts.map +1 -1
  243. package/dist/engine/indicators/state/kamaState.js.map +1 -1
  244. package/dist/engine/indicators/state/keltnerState.d.ts.map +1 -1
  245. package/dist/engine/indicators/state/keltnerState.js.map +1 -1
  246. package/dist/engine/indicators/state/kstState.d.ts.map +1 -1
  247. package/dist/engine/indicators/state/kstState.js.map +1 -1
  248. package/dist/engine/indicators/state/maState.d.ts.map +1 -1
  249. package/dist/engine/indicators/state/maState.js.map +1 -1
  250. package/dist/engine/indicators/state/mfiState.d.ts.map +1 -1
  251. package/dist/engine/indicators/state/mfiState.js.map +1 -1
  252. package/dist/engine/indicators/state/momState.d.ts.map +1 -1
  253. package/dist/engine/indicators/state/momState.js.map +1 -1
  254. package/dist/engine/indicators/state/obvState.d.ts.map +1 -1
  255. package/dist/engine/indicators/state/obvState.js.map +1 -1
  256. package/dist/engine/indicators/state/parkinsonState.d.ts.map +1 -1
  257. package/dist/engine/indicators/state/parkinsonState.js +5 -1
  258. package/dist/engine/indicators/state/parkinsonState.js.map +1 -1
  259. package/dist/engine/indicators/state/pivotState.d.ts.map +1 -1
  260. package/dist/engine/indicators/state/pivotState.js.map +1 -1
  261. package/dist/engine/indicators/state/pvtState.d.ts.map +1 -1
  262. package/dist/engine/indicators/state/pvtState.js.map +1 -1
  263. package/dist/engine/indicators/state/rocState.d.ts.map +1 -1
  264. package/dist/engine/indicators/state/rocState.js.map +1 -1
  265. package/dist/engine/indicators/state/rsiState.d.ts.map +1 -1
  266. package/dist/engine/indicators/state/rsiState.js.map +1 -1
  267. package/dist/engine/indicators/state/sarState.d.ts.map +1 -1
  268. package/dist/engine/indicators/state/sarState.js.map +1 -1
  269. package/dist/engine/indicators/state/stochState.d.ts.map +1 -1
  270. package/dist/engine/indicators/state/stochState.js.map +1 -1
  271. package/dist/engine/indicators/state/structureState.d.ts.map +1 -1
  272. package/dist/engine/indicators/state/structureState.js.map +1 -1
  273. package/dist/engine/indicators/state/supertrendState.d.ts.map +1 -1
  274. package/dist/engine/indicators/state/supertrendState.js.map +1 -1
  275. package/dist/engine/indicators/state/temaState.d.ts.map +1 -1
  276. package/dist/engine/indicators/state/temaState.js.map +1 -1
  277. package/dist/engine/indicators/state/trixState.d.ts.map +1 -1
  278. package/dist/engine/indicators/state/trixState.js.map +1 -1
  279. package/dist/engine/indicators/state/vmaState.d.ts.map +1 -1
  280. package/dist/engine/indicators/state/vmaState.js.map +1 -1
  281. package/dist/engine/indicators/state/volumeProfileState.d.ts.map +1 -1
  282. package/dist/engine/indicators/state/volumeProfileState.js.map +1 -1
  283. package/dist/engine/indicators/state/vwapState.d.ts.map +1 -1
  284. package/dist/engine/indicators/state/vwapState.js.map +1 -1
  285. package/dist/engine/indicators/state/wmaState.d.ts.map +1 -1
  286. package/dist/engine/indicators/state/wmaState.js.map +1 -1
  287. package/dist/engine/indicators/state/wmsrState.d.ts.map +1 -1
  288. package/dist/engine/indicators/state/wmsrState.js.map +1 -1
  289. package/dist/engine/indicators/state/zonesState.d.ts.map +1 -1
  290. package/dist/engine/indicators/state/zonesState.js.map +1 -1
  291. package/dist/engine/indicators/stateComposer.d.ts.map +1 -1
  292. package/dist/engine/indicators/stateComposer.js +1 -1
  293. package/dist/engine/indicators/stateComposer.js.map +1 -1
  294. package/dist/engine/indicators/visibleStateComposers.d.ts.map +1 -1
  295. package/dist/engine/indicators/visibleStateComposers.js +9 -11
  296. package/dist/engine/indicators/visibleStateComposers.js.map +1 -1
  297. package/dist/engine/indicators/workerProtocol.d.ts.map +1 -1
  298. package/dist/engine/indicators/workerProtocol.js.map +1 -1
  299. package/dist/engine/layout/chartPaneLayout.d.ts.map +1 -1
  300. package/dist/engine/layout/chartPaneLayout.js +2 -5
  301. package/dist/engine/layout/chartPaneLayout.js.map +1 -1
  302. package/dist/engine/layout/pane.d.ts.map +1 -1
  303. package/dist/engine/layout/pane.js +3 -1
  304. package/dist/engine/layout/pane.js.map +1 -1
  305. package/dist/engine/marker/registry.d.ts.map +1 -1
  306. package/dist/engine/marker/registry.js +8 -6
  307. package/dist/engine/marker/registry.js.map +1 -1
  308. package/dist/engine/modes/kLineMode.d.ts.map +1 -1
  309. package/dist/engine/modes/kLineMode.js +2 -4
  310. package/dist/engine/modes/kLineMode.js.map +1 -1
  311. package/dist/engine/modes/timeShareMode.d.ts.map +1 -1
  312. package/dist/engine/modes/timeShareMode.js.map +1 -1
  313. package/dist/engine/modes/types.d.ts.map +1 -1
  314. package/dist/engine/paneRenderer.d.ts.map +1 -1
  315. package/dist/engine/paneRenderer.js.map +1 -1
  316. package/dist/engine/render/chartRenderer.d.ts +11 -2
  317. package/dist/engine/render/chartRenderer.d.ts.map +1 -1
  318. package/dist/engine/render/chartRenderer.js +204 -96
  319. package/dist/engine/render/chartRenderer.js.map +1 -1
  320. package/dist/engine/render/layers/candleLayer.d.ts +4 -0
  321. package/dist/engine/render/layers/candleLayer.d.ts.map +1 -0
  322. package/dist/engine/render/layers/candleLayer.js +7 -0
  323. package/dist/engine/render/layers/candleLayer.js.map +1 -0
  324. package/dist/engine/render/layers/comparisonLineLayer.d.ts +4 -0
  325. package/dist/engine/render/layers/comparisonLineLayer.d.ts.map +1 -0
  326. package/dist/engine/render/layers/comparisonLineLayer.js +7 -0
  327. package/dist/engine/render/layers/comparisonLineLayer.js.map +1 -0
  328. package/dist/engine/render/layers/crosshairLayer.d.ts +14 -0
  329. package/dist/engine/render/layers/crosshairLayer.d.ts.map +1 -0
  330. package/dist/engine/render/layers/crosshairLayer.js +6 -0
  331. package/dist/engine/render/layers/crosshairLayer.js.map +1 -0
  332. package/dist/engine/render/layers/customMarkersLayer.d.ts +4 -0
  333. package/dist/engine/render/layers/customMarkersLayer.d.ts.map +1 -0
  334. package/dist/engine/render/layers/customMarkersLayer.js +6 -0
  335. package/dist/engine/render/layers/customMarkersLayer.js.map +1 -0
  336. package/dist/engine/render/layers/extremaMarkersLayer.d.ts +4 -0
  337. package/dist/engine/render/layers/extremaMarkersLayer.d.ts.map +1 -0
  338. package/dist/engine/render/layers/extremaMarkersLayer.js +6 -0
  339. package/dist/engine/render/layers/extremaMarkersLayer.js.map +1 -0
  340. package/dist/engine/render/layers/gridLinesLayer.d.ts +4 -0
  341. package/dist/engine/render/layers/gridLinesLayer.d.ts.map +1 -0
  342. package/dist/engine/render/layers/gridLinesLayer.js +6 -0
  343. package/dist/engine/render/layers/gridLinesLayer.js.map +1 -0
  344. package/dist/engine/render/layers/lastPriceLabelLayer.d.ts +4 -0
  345. package/dist/engine/render/layers/lastPriceLabelLayer.d.ts.map +1 -0
  346. package/dist/engine/render/layers/lastPriceLabelLayer.js +6 -0
  347. package/dist/engine/render/layers/lastPriceLabelLayer.js.map +1 -0
  348. package/dist/engine/render/layers/lastPriceLineLayer.d.ts +4 -0
  349. package/dist/engine/render/layers/lastPriceLineLayer.d.ts.map +1 -0
  350. package/dist/engine/render/layers/lastPriceLineLayer.js +7 -0
  351. package/dist/engine/render/layers/lastPriceLineLayer.js.map +1 -0
  352. package/dist/engine/render/layers/leftYAxisLayer.d.ts +12 -0
  353. package/dist/engine/render/layers/leftYAxisLayer.d.ts.map +1 -0
  354. package/dist/engine/render/layers/leftYAxisLayer.js +6 -0
  355. package/dist/engine/render/layers/leftYAxisLayer.js.map +1 -0
  356. package/dist/engine/render/layers/mainIndicatorLegendLayer.d.ts +6 -0
  357. package/dist/engine/render/layers/mainIndicatorLegendLayer.d.ts.map +1 -0
  358. package/dist/engine/render/layers/mainIndicatorLegendLayer.js +13 -0
  359. package/dist/engine/render/layers/mainIndicatorLegendLayer.js.map +1 -0
  360. package/dist/engine/render/layers/yAxisLayer.d.ts +12 -0
  361. package/dist/engine/render/layers/yAxisLayer.d.ts.map +1 -0
  362. package/dist/engine/render/layers/yAxisLayer.js +6 -0
  363. package/dist/engine/render/layers/yAxisLayer.js.map +1 -0
  364. package/dist/engine/renderers/Indicator/atr.js +8 -3
  365. package/dist/engine/renderers/Indicator/atr.js.map +1 -1
  366. package/dist/engine/renderers/Indicator/boll.d.ts.map +1 -1
  367. package/dist/engine/renderers/Indicator/boll.js +27 -6
  368. package/dist/engine/renderers/Indicator/boll.js.map +1 -1
  369. package/dist/engine/renderers/Indicator/cci.js +4 -4
  370. package/dist/engine/renderers/Indicator/cci.js.map +1 -1
  371. package/dist/engine/renderers/Indicator/chaikinVol.js +17 -5
  372. package/dist/engine/renderers/Indicator/chaikinVol.js.map +1 -1
  373. package/dist/engine/renderers/Indicator/cmf.js +13 -3
  374. package/dist/engine/renderers/Indicator/cmf.js.map +1 -1
  375. package/dist/engine/renderers/Indicator/dema.js +16 -4
  376. package/dist/engine/renderers/Indicator/dema.js.map +1 -1
  377. package/dist/engine/renderers/Indicator/donchian.js +26 -7
  378. package/dist/engine/renderers/Indicator/donchian.js.map +1 -1
  379. package/dist/engine/renderers/Indicator/ene.d.ts.map +1 -1
  380. package/dist/engine/renderers/Indicator/ene.js +7 -3
  381. package/dist/engine/renderers/Indicator/ene.js.map +1 -1
  382. package/dist/engine/renderers/Indicator/expma.d.ts.map +1 -1
  383. package/dist/engine/renderers/Indicator/expma.js +8 -5
  384. package/dist/engine/renderers/Indicator/expma.js.map +1 -1
  385. package/dist/engine/renderers/Indicator/fastk.js.map +1 -1
  386. package/dist/engine/renderers/Indicator/fib.js +26 -7
  387. package/dist/engine/renderers/Indicator/fib.js.map +1 -1
  388. package/dist/engine/renderers/Indicator/hma.js +16 -4
  389. package/dist/engine/renderers/Indicator/hma.js.map +1 -1
  390. package/dist/engine/renderers/Indicator/hv.js +18 -4
  391. package/dist/engine/renderers/Indicator/hv.js.map +1 -1
  392. package/dist/engine/renderers/Indicator/ichimoku.js +52 -8
  393. package/dist/engine/renderers/Indicator/ichimoku.js.map +1 -1
  394. package/dist/engine/renderers/Indicator/index.d.ts.map +1 -1
  395. package/dist/engine/renderers/Indicator/index.js.map +1 -1
  396. package/dist/engine/renderers/Indicator/indicatorCatalog.d.ts.map +1 -1
  397. package/dist/engine/renderers/Indicator/indicatorCatalog.js +661 -66
  398. package/dist/engine/renderers/Indicator/indicatorCatalog.js.map +1 -1
  399. package/dist/engine/renderers/Indicator/kama.js +16 -4
  400. package/dist/engine/renderers/Indicator/kama.js.map +1 -1
  401. package/dist/engine/renderers/Indicator/keltner.js +37 -7
  402. package/dist/engine/renderers/Indicator/keltner.js.map +1 -1
  403. package/dist/engine/renderers/Indicator/kst.js +22 -5
  404. package/dist/engine/renderers/Indicator/kst.js.map +1 -1
  405. package/dist/engine/renderers/Indicator/ma.d.ts.map +1 -1
  406. package/dist/engine/renderers/Indicator/ma.js +26 -10
  407. package/dist/engine/renderers/Indicator/ma.js.map +1 -1
  408. package/dist/engine/renderers/Indicator/macd.js +29 -10
  409. package/dist/engine/renderers/Indicator/macd.js.map +1 -1
  410. package/dist/engine/renderers/Indicator/mainIndicatorLegend.d.ts.map +1 -1
  411. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js +3 -2
  412. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js.map +1 -1
  413. package/dist/engine/renderers/Indicator/mfi.js +13 -3
  414. package/dist/engine/renderers/Indicator/mfi.js.map +1 -1
  415. package/dist/engine/renderers/Indicator/mom.js +1 -1
  416. package/dist/engine/renderers/Indicator/mom.js.map +1 -1
  417. package/dist/engine/renderers/Indicator/obv.js +12 -3
  418. package/dist/engine/renderers/Indicator/obv.js.map +1 -1
  419. package/dist/engine/renderers/Indicator/parkinson.js +21 -5
  420. package/dist/engine/renderers/Indicator/parkinson.js.map +1 -1
  421. package/dist/engine/renderers/Indicator/pivot.js +42 -6
  422. package/dist/engine/renderers/Indicator/pivot.js.map +1 -1
  423. package/dist/engine/renderers/Indicator/pvt.js +12 -3
  424. package/dist/engine/renderers/Indicator/pvt.js.map +1 -1
  425. package/dist/engine/renderers/Indicator/roc.js +13 -3
  426. package/dist/engine/renderers/Indicator/roc.js.map +1 -1
  427. package/dist/engine/renderers/Indicator/rsi.js +30 -16
  428. package/dist/engine/renderers/Indicator/rsi.js.map +1 -1
  429. package/dist/engine/renderers/Indicator/sar.js +15 -8
  430. package/dist/engine/renderers/Indicator/sar.js.map +1 -1
  431. package/dist/engine/renderers/Indicator/scale/atr_scale.d.ts.map +1 -1
  432. package/dist/engine/renderers/Indicator/scale/atr_scale.js.map +1 -1
  433. package/dist/engine/renderers/Indicator/scale/cci_scale.d.ts.map +1 -1
  434. package/dist/engine/renderers/Indicator/scale/cci_scale.js.map +1 -1
  435. package/dist/engine/renderers/Indicator/scale/fastk_scale.d.ts.map +1 -1
  436. package/dist/engine/renderers/Indicator/scale/fastk_scale.js.map +1 -1
  437. package/dist/engine/renderers/Indicator/scale/indicator_scale.d.ts.map +1 -1
  438. package/dist/engine/renderers/Indicator/scale/indicator_scale.js +1 -1
  439. package/dist/engine/renderers/Indicator/scale/indicator_scale.js.map +1 -1
  440. package/dist/engine/renderers/Indicator/scale/kst_scale.d.ts.map +1 -1
  441. package/dist/engine/renderers/Indicator/scale/kst_scale.js.map +1 -1
  442. package/dist/engine/renderers/Indicator/scale/macd_scale.d.ts.map +1 -1
  443. package/dist/engine/renderers/Indicator/scale/macd_scale.js.map +1 -1
  444. package/dist/engine/renderers/Indicator/scale/mom_scale.d.ts.map +1 -1
  445. package/dist/engine/renderers/Indicator/scale/mom_scale.js.map +1 -1
  446. package/dist/engine/renderers/Indicator/scale/rsi_scale.d.ts.map +1 -1
  447. package/dist/engine/renderers/Indicator/scale/rsi_scale.js.map +1 -1
  448. package/dist/engine/renderers/Indicator/scale/stoch_scale.d.ts.map +1 -1
  449. package/dist/engine/renderers/Indicator/scale/stoch_scale.js.map +1 -1
  450. package/dist/engine/renderers/Indicator/scale/volume_scale.d.ts.map +1 -1
  451. package/dist/engine/renderers/Indicator/scale/volume_scale.js.map +1 -1
  452. package/dist/engine/renderers/Indicator/scale/wmsr_scale.d.ts.map +1 -1
  453. package/dist/engine/renderers/Indicator/scale/wmsr_scale.js.map +1 -1
  454. package/dist/engine/renderers/Indicator/shared/dashedLines.d.ts.map +1 -1
  455. package/dist/engine/renderers/Indicator/shared/dashedLines.js +2 -2
  456. package/dist/engine/renderers/Indicator/shared/dashedLines.js.map +1 -1
  457. package/dist/engine/renderers/Indicator/shared/titleInfo.d.ts.map +1 -1
  458. package/dist/engine/renderers/Indicator/shared/titleInfo.js +3 -1
  459. package/dist/engine/renderers/Indicator/shared/titleInfo.js.map +1 -1
  460. package/dist/engine/renderers/Indicator/stoch.js +11 -2
  461. package/dist/engine/renderers/Indicator/stoch.js.map +1 -1
  462. package/dist/engine/renderers/Indicator/structure.js +46 -8
  463. package/dist/engine/renderers/Indicator/structure.js.map +1 -1
  464. package/dist/engine/renderers/Indicator/supertrend.js +26 -8
  465. package/dist/engine/renderers/Indicator/supertrend.js.map +1 -1
  466. package/dist/engine/renderers/Indicator/tema.js +16 -4
  467. package/dist/engine/renderers/Indicator/tema.js.map +1 -1
  468. package/dist/engine/renderers/Indicator/trix.js +12 -3
  469. package/dist/engine/renderers/Indicator/trix.js.map +1 -1
  470. package/dist/engine/renderers/Indicator/vma.js +13 -3
  471. package/dist/engine/renderers/Indicator/vma.js.map +1 -1
  472. package/dist/engine/renderers/Indicator/volumeProfile.js +24 -7
  473. package/dist/engine/renderers/Indicator/volumeProfile.js.map +1 -1
  474. package/dist/engine/renderers/Indicator/vwap.js +12 -3
  475. package/dist/engine/renderers/Indicator/vwap.js.map +1 -1
  476. package/dist/engine/renderers/Indicator/wma.js +16 -4
  477. package/dist/engine/renderers/Indicator/wma.js.map +1 -1
  478. package/dist/engine/renderers/Indicator/wmsr.js +3 -3
  479. package/dist/engine/renderers/Indicator/wmsr.js.map +1 -1
  480. package/dist/engine/renderers/Indicator/zones.js +31 -11
  481. package/dist/engine/renderers/Indicator/zones.js.map +1 -1
  482. package/dist/engine/renderers/candle.d.ts.map +1 -1
  483. package/dist/engine/renderers/candle.js +27 -21
  484. package/dist/engine/renderers/candle.js.map +1 -1
  485. package/dist/engine/renderers/comparisonLine.d.ts.map +1 -1
  486. package/dist/engine/renderers/comparisonLine.js +3 -1
  487. package/dist/engine/renderers/comparisonLine.js.map +1 -1
  488. package/dist/engine/renderers/crosshair.d.ts.map +1 -1
  489. package/dist/engine/renderers/crosshair.js.map +1 -1
  490. package/dist/engine/renderers/customMarkers.d.ts.map +1 -1
  491. package/dist/engine/renderers/customMarkers.js +2 -2
  492. package/dist/engine/renderers/customMarkers.js.map +1 -1
  493. package/dist/engine/renderers/extremaMarkers.d.ts.map +1 -1
  494. package/dist/engine/renderers/extremaMarkers.js +6 -2
  495. package/dist/engine/renderers/extremaMarkers.js.map +1 -1
  496. package/dist/engine/renderers/gridLines.d.ts.map +1 -1
  497. package/dist/engine/renderers/gridLines.js.map +1 -1
  498. package/dist/engine/renderers/lastPrice.d.ts.map +1 -1
  499. package/dist/engine/renderers/lastPrice.js +6 -2
  500. package/dist/engine/renderers/lastPrice.js.map +1 -1
  501. package/dist/engine/renderers/leftYAxis.d.ts.map +1 -1
  502. package/dist/engine/renderers/leftYAxis.js +7 -3
  503. package/dist/engine/renderers/leftYAxis.js.map +1 -1
  504. package/dist/engine/renderers/paneTitle.d.ts.map +1 -1
  505. package/dist/engine/renderers/paneTitle.js.map +1 -1
  506. package/dist/engine/renderers/subVolume.js +8 -5
  507. package/dist/engine/renderers/subVolume.js.map +1 -1
  508. package/dist/engine/renderers/timeAxis.d.ts.map +1 -1
  509. package/dist/engine/renderers/timeAxis.js.map +1 -1
  510. package/dist/engine/renderers/timeShare.d.ts.map +1 -1
  511. package/dist/engine/renderers/timeShare.js +2 -5
  512. package/dist/engine/renderers/timeShare.js.map +1 -1
  513. package/dist/engine/renderers/webgl/candleSurface.d.ts.map +1 -1
  514. package/dist/engine/renderers/webgl/candleSurface.js +13 -14
  515. package/dist/engine/renderers/webgl/candleSurface.js.map +1 -1
  516. package/dist/engine/renderers/webgl/sharedWebGLSurface.d.ts +20 -0
  517. package/dist/engine/renderers/webgl/sharedWebGLSurface.d.ts.map +1 -1
  518. package/dist/engine/renderers/webgl/sharedWebGLSurface.js.map +1 -1
  519. package/dist/engine/renderers/yAxis.d.ts.map +1 -1
  520. package/dist/engine/renderers/yAxis.js +1 -1
  521. package/dist/engine/renderers/yAxis.js.map +1 -1
  522. package/dist/engine/scale/logFormula.d.ts.map +1 -1
  523. package/dist/engine/scale/logFormula.js.map +1 -1
  524. package/dist/engine/scale/price.js.map +1 -1
  525. package/dist/engine/scale/priceScale.d.ts.map +1 -1
  526. package/dist/engine/scale/priceScale.js +1 -1
  527. package/dist/engine/scale/priceScale.js.map +1 -1
  528. package/dist/engine/subPaneManager.d.ts +11 -1
  529. package/dist/engine/subPaneManager.d.ts.map +1 -1
  530. package/dist/engine/subPaneManager.js +59 -6
  531. package/dist/engine/subPaneManager.js.map +1 -1
  532. package/dist/engine/theme/fonts.js.map +1 -1
  533. package/dist/engine/utils/chartZoomController.d.ts.map +1 -1
  534. package/dist/engine/utils/chartZoomController.js.map +1 -1
  535. package/dist/engine/utils/klineConfig.js.map +1 -1
  536. package/dist/engine/utils/tickCount.js.map +1 -1
  537. package/dist/engine/utils/tickPosition.d.ts.map +1 -1
  538. package/dist/engine/utils/tickPosition.js.map +1 -1
  539. package/dist/engine/viewport/chartViewportManager.d.ts.map +1 -1
  540. package/dist/engine/viewport/chartViewportManager.js +16 -13
  541. package/dist/engine/viewport/chartViewportManager.js.map +1 -1
  542. package/dist/engine/viewport/viewport.d.ts.map +1 -1
  543. package/dist/engine/viewport/viewport.js.map +1 -1
  544. package/dist/errors-help.d.ts.map +1 -1
  545. package/dist/errors-help.js +1 -0
  546. package/dist/errors-help.js.map +1 -1
  547. package/dist/errors.d.ts +1 -1
  548. package/dist/errors.d.ts.map +1 -1
  549. package/dist/errors.js.map +1 -1
  550. package/dist/index.d.ts +1 -1
  551. package/dist/index.d.ts.map +1 -1
  552. package/dist/index.js +1 -1
  553. package/dist/index.js.map +1 -1
  554. package/dist/indicators/alma.d.ts.map +1 -1
  555. package/dist/indicators/alma.js.map +1 -1
  556. package/dist/indicators/awesomeOscillator.d.ts.map +1 -1
  557. package/dist/indicators/awesomeOscillator.js.map +1 -1
  558. package/dist/indicators/dpo.d.ts.map +1 -1
  559. package/dist/indicators/dpo.js.map +1 -1
  560. package/dist/indicators/fisherTransform.d.ts.map +1 -1
  561. package/dist/indicators/fisherTransform.js.map +1 -1
  562. package/dist/indicators/frama.d.ts.map +1 -1
  563. package/dist/indicators/frama.js.map +1 -1
  564. package/dist/indicators/index.d.ts +4 -4
  565. package/dist/indicators/index.d.ts.map +1 -1
  566. package/dist/indicators/index.js +4 -4
  567. package/dist/indicators/index.js.map +1 -1
  568. package/dist/indicators/lsma.d.ts.map +1 -1
  569. package/dist/indicators/lsma.js.map +1 -1
  570. package/dist/indicators/schaffTrendCycle.d.ts.map +1 -1
  571. package/dist/indicators/schaffTrendCycle.js.map +1 -1
  572. package/dist/indicators/stochRSI.d.ts.map +1 -1
  573. package/dist/indicators/stochRSI.js.map +1 -1
  574. package/dist/indicators/t3.d.ts.map +1 -1
  575. package/dist/indicators/t3.js +1 -4
  576. package/dist/indicators/t3.js.map +1 -1
  577. package/dist/indicators/ultimateOscillator.d.ts.map +1 -1
  578. package/dist/indicators/ultimateOscillator.js.map +1 -1
  579. package/dist/indicators/vidya.d.ts.map +1 -1
  580. package/dist/indicators/vidya.js.map +1 -1
  581. package/dist/indicators/zlema.d.ts.map +1 -1
  582. package/dist/indicators/zlema.js.map +1 -1
  583. package/dist/input/gesture.d.ts.map +1 -1
  584. package/dist/input/gesture.js +2 -6
  585. package/dist/input/gesture.js.map +1 -1
  586. package/dist/input/index.d.ts.map +1 -1
  587. package/dist/input/index.js.map +1 -1
  588. package/dist/input/keyboard.d.ts.map +1 -1
  589. package/dist/input/keyboard.js.map +1 -1
  590. package/dist/mcp/chartBridge.d.ts.map +1 -1
  591. package/dist/mcp/chartBridge.js.map +1 -1
  592. package/dist/plugin/HookSystem.d.ts.map +1 -1
  593. package/dist/plugin/HookSystem.js.map +1 -1
  594. package/dist/plugin/PluginHost.d.ts.map +1 -1
  595. package/dist/plugin/PluginHost.js.map +1 -1
  596. package/dist/plugin/StateStore.js +1 -1
  597. package/dist/plugin/StateStore.js.map +1 -1
  598. package/dist/plugin/rendererPluginManager.d.ts.map +1 -1
  599. package/dist/plugin/rendererPluginManager.js.map +1 -1
  600. package/dist/plugin/types.d.ts.map +1 -1
  601. package/dist/plugin/types.js.map +1 -1
  602. package/dist/reactivity/signal.d.ts.map +1 -1
  603. package/dist/reactivity/signal.js.map +1 -1
  604. package/dist/render/Renderer.d.ts.map +1 -1
  605. package/dist/render/SurfaceBackend.d.ts.map +1 -1
  606. package/dist/render/createWebGLRenderer.d.ts +5 -0
  607. package/dist/render/createWebGLRenderer.d.ts.map +1 -0
  608. package/dist/render/createWebGLRenderer.js +233 -0
  609. package/dist/render/createWebGLRenderer.js.map +1 -0
  610. package/dist/render/createWebGLSurfaceBackend.d.ts +4 -0
  611. package/dist/render/createWebGLSurfaceBackend.d.ts.map +1 -0
  612. package/dist/render/createWebGLSurfaceBackend.js +37 -0
  613. package/dist/render/createWebGLSurfaceBackend.js.map +1 -0
  614. package/dist/render/index.d.ts +5 -6
  615. package/dist/render/index.d.ts.map +1 -1
  616. package/dist/render/index.js +4 -6
  617. package/dist/render/index.js.map +1 -1
  618. package/dist/renderer-tier/detectRendererTier.d.ts.map +1 -1
  619. package/dist/renderer-tier/detectRendererTier.js.map +1 -1
  620. package/dist/renderer-tier/index.d.ts.map +1 -1
  621. package/dist/renderer-tier/index.js.map +1 -1
  622. package/dist/renderer-tier/selectBackend.d.ts.map +1 -1
  623. package/dist/renderer-tier/selectBackend.js +1 -5
  624. package/dist/renderer-tier/selectBackend.js.map +1 -1
  625. package/dist/renderer-tier/types.d.ts.map +1 -1
  626. package/dist/renderer-tier/types.js.map +1 -1
  627. package/dist/replay/createReplayController.d.ts.map +1 -1
  628. package/dist/replay/createReplayController.js +3 -5
  629. package/dist/replay/createReplayController.js.map +1 -1
  630. package/dist/replay/index.d.ts +1 -1
  631. package/dist/replay/index.d.ts.map +1 -1
  632. package/dist/replay/index.js +1 -1
  633. package/dist/replay/index.js.map +1 -1
  634. package/dist/replay/timeline.d.ts.map +1 -1
  635. package/dist/replay/timeline.js.map +1 -1
  636. package/dist/replay/types.d.ts.map +1 -1
  637. package/dist/scale/anchoredZoom.d.ts.map +1 -1
  638. package/dist/scale/anchoredZoom.js.map +1 -1
  639. package/dist/scale/createPriceScale.d.ts.map +1 -1
  640. package/dist/scale/createPriceScale.js.map +1 -1
  641. package/dist/scale/createTimeScale.d.ts.map +1 -1
  642. package/dist/scale/createTimeScale.js.map +1 -1
  643. package/dist/scale/index.d.ts.map +1 -1
  644. package/dist/scale/index.js.map +1 -1
  645. package/dist/scale/originShift.d.ts.map +1 -1
  646. package/dist/scale/originShift.js.map +1 -1
  647. package/dist/scale/types.d.ts.map +1 -1
  648. package/dist/scene/createLayerFromPlugin.d.ts +4 -0
  649. package/dist/scene/createLayerFromPlugin.d.ts.map +1 -0
  650. package/dist/scene/createLayerFromPlugin.js +45 -0
  651. package/dist/scene/createLayerFromPlugin.js.map +1 -0
  652. package/dist/scene/createScene.d.ts.map +1 -1
  653. package/dist/scene/createScene.js +6 -3
  654. package/dist/scene/createScene.js.map +1 -1
  655. package/dist/scene/index.d.ts +4 -3
  656. package/dist/scene/index.d.ts.map +1 -1
  657. package/dist/scene/index.js +2 -1
  658. package/dist/scene/index.js.map +1 -1
  659. package/dist/scene/layerRegistry.d.ts.map +1 -1
  660. package/dist/scene/layerRegistry.js.map +1 -1
  661. package/dist/scene/types.d.ts +8 -3
  662. package/dist/scene/types.d.ts.map +1 -1
  663. package/dist/scheduler/createFrameBudget.d.ts.map +1 -1
  664. package/dist/scheduler/createFrameBudget.js.map +1 -1
  665. package/dist/scheduler/index.d.ts.map +1 -1
  666. package/dist/scheduler/index.js.map +1 -1
  667. package/dist/semantic/controller.d.ts.map +1 -1
  668. package/dist/semantic/controller.js +8 -3
  669. package/dist/semantic/controller.js.map +1 -1
  670. package/dist/semantic/index.d.ts +1 -1
  671. package/dist/semantic/index.d.ts.map +1 -1
  672. package/dist/semantic/index.js +1 -1
  673. package/dist/semantic/index.js.map +1 -1
  674. package/dist/semantic/schema.json +16 -4
  675. package/dist/semantic/validator.d.ts.map +1 -1
  676. package/dist/semantic/validator.js +4 -4
  677. package/dist/semantic/validator.js.map +1 -1
  678. package/dist/tokens/colorPresetSettings.d.ts.map +1 -1
  679. package/dist/tokens/colorPresetSettings.js +3 -1
  680. package/dist/tokens/colorPresetSettings.js.map +1 -1
  681. package/dist/tokens/index.d.ts.map +1 -1
  682. package/dist/tokens/index.js.map +1 -1
  683. package/dist/tokens/mergeTheme.js.map +1 -1
  684. package/dist/tokens/theme-base.d.ts.map +1 -1
  685. package/dist/tokens/theme-base.js.map +1 -1
  686. package/dist/tokens/theme-china.d.ts.map +1 -1
  687. package/dist/tokens/theme-china.js.map +1 -1
  688. package/dist/tokens/theme-dark.js.map +1 -1
  689. package/dist/tokens/theme-light.js.map +1 -1
  690. package/dist/tokens/themeToCssVars.d.ts.map +1 -1
  691. package/dist/tokens/themeToCssVars.js.map +1 -1
  692. package/dist/tokens/types.d.ts.map +1 -1
  693. package/dist/types/price.d.ts.map +1 -1
  694. package/dist/types/price.js +5 -1
  695. package/dist/types/price.js.map +1 -1
  696. package/dist/utils/dateFormat.d.ts.map +1 -1
  697. package/dist/utils/dateFormat.js.map +1 -1
  698. package/dist/utils/kLineDraw/axis.d.ts.map +1 -1
  699. package/dist/utils/kLineDraw/axis.js +3 -3
  700. package/dist/utils/kLineDraw/axis.js.map +1 -1
  701. package/dist/utils/priceToY.d.ts.map +1 -1
  702. package/dist/utils/priceToY.js.map +1 -1
  703. package/dist/utils/volumePrice.d.ts.map +1 -1
  704. package/dist/utils/volumePrice.js +1 -1
  705. package/dist/utils/volumePrice.js.map +1 -1
  706. package/dist/version.d.ts +1 -1
  707. package/dist/version.d.ts.map +1 -1
  708. package/dist/version.js +1 -1
  709. package/dist/version.js.map +1 -1
  710. package/package.json +1 -1
  711. package/src/__bench__/indicators.bench.ts +129 -129
  712. package/src/__bench__/orderBookHeatmap.bench.ts +32 -32
  713. package/src/__bench__/scale.bench.ts +56 -56
  714. package/src/__bench__/signal.bench.ts +23 -23
  715. package/src/__bench__/volumeProfile.bench.ts +35 -35
  716. package/src/__tests__/depthPipeline.test.ts +315 -0
  717. package/src/__tests__/errors-help.test.ts +132 -135
  718. package/src/__tests__/errors.test.ts +140 -144
  719. package/src/__tests__/signal.test.ts +100 -100
  720. package/src/alerts/__tests__/controller.test.ts +173 -173
  721. package/src/alerts/__tests__/predicates.test.ts +287 -287
  722. package/src/alerts/__tests__/ruleSchema.test.ts +145 -148
  723. package/src/alerts/createAlertController.ts +236 -255
  724. package/src/alerts/index.ts +10 -14
  725. package/src/alerts/predicates.ts +152 -158
  726. package/src/alerts/ruleSchema.ts +181 -186
  727. package/src/alerts/types.ts +103 -103
  728. package/src/chartTypes/__tests__/heikinAshi.test.ts +105 -105
  729. package/src/chartTypes/__tests__/pointAndFigure.test.ts +147 -147
  730. package/src/chartTypes/__tests__/rangeBars.test.ts +127 -127
  731. package/src/chartTypes/__tests__/renko.test.ts +144 -138
  732. package/src/chartTypes/heikinAshi.ts +59 -55
  733. package/src/chartTypes/pointAndFigure.ts +171 -165
  734. package/src/chartTypes/rangeBars.ts +213 -213
  735. package/src/chartTypes/renko.ts +199 -193
  736. package/src/chartTypes/types.ts +29 -29
  737. package/src/components/anchoredVwap/__tests__/computeAnchoredVwap.test.ts +261 -268
  738. package/src/components/anchoredVwap/__tests__/controller.test.ts +324 -343
  739. package/src/components/anchoredVwap/computeAnchoredVwap.ts +81 -81
  740. package/src/components/anchoredVwap/createAnchoredVwapController.ts +246 -279
  741. package/src/components/anchoredVwap/index.ts +5 -5
  742. package/src/components/anchoredVwap/types.ts +88 -91
  743. package/src/components/crosshairSync/__tests__/crosshairSync.test.ts +174 -174
  744. package/src/components/crosshairSync/createCrosshairSync.ts +113 -113
  745. package/src/components/crosshairSync/index.ts +3 -3
  746. package/src/components/footprint/__tests__/aggressor.test.ts +110 -106
  747. package/src/components/footprint/__tests__/controller.test.ts +97 -97
  748. package/src/components/footprint/__tests__/perBarStats.test.ts +92 -92
  749. package/src/components/footprint/aggressor.ts +55 -60
  750. package/src/components/footprint/createFootprintController.ts +262 -269
  751. package/src/components/footprint/index.ts +8 -16
  752. package/src/components/footprint/perBarStats.ts +50 -52
  753. package/src/components/footprint/types.ts +92 -92
  754. package/src/components/mtfOverlay/__tests__/alignToBaseIndex.test.ts +70 -70
  755. package/src/components/mtfOverlay/__tests__/controller.test.ts +134 -134
  756. package/src/components/mtfOverlay/__tests__/resampleBars.test.ts +80 -80
  757. package/src/components/mtfOverlay/alignToBaseIndex.ts +55 -55
  758. package/src/components/mtfOverlay/createMtfController.ts +149 -148
  759. package/src/components/mtfOverlay/index.ts +5 -5
  760. package/src/components/mtfOverlay/resampleBars.ts +88 -82
  761. package/src/components/mtfOverlay/types.ts +70 -73
  762. package/src/components/orderBookHeatmap/__tests__/controller.test.ts +337 -204
  763. package/src/components/orderBookHeatmap/__tests__/deltaArchive.test.ts +71 -71
  764. package/src/components/orderBookHeatmap/__tests__/logColorScale.test.ts +56 -56
  765. package/src/components/orderBookHeatmap/__tests__/orderBookState.test.ts +97 -97
  766. package/src/components/orderBookHeatmap/__tests__/snapshotRing.test.ts +39 -39
  767. package/src/components/orderBookHeatmap/computeShader.wgsl.md +3 -3
  768. package/src/components/orderBookHeatmap/createHeatmapController.ts +239 -213
  769. package/src/components/orderBookHeatmap/createOrderBookState.ts +77 -83
  770. package/src/components/orderBookHeatmap/deltaArchive.ts +70 -73
  771. package/src/components/orderBookHeatmap/index.ts +11 -11
  772. package/src/components/orderBookHeatmap/logColorScale.ts +52 -46
  773. package/src/components/orderBookHeatmap/snapshotRing.ts +43 -40
  774. package/src/components/orderBookHeatmap/types.ts +86 -76
  775. package/src/components/volumeProfile/__tests__/binning.test.ts +98 -98
  776. package/src/components/volumeProfile/__tests__/poc.test.ts +21 -21
  777. package/src/components/volumeProfile/__tests__/valueArea.test.ts +140 -140
  778. package/src/components/volumeProfile/binning.ts +67 -67
  779. package/src/components/volumeProfile/createVolumeProfileController.ts +143 -156
  780. package/src/components/volumeProfile/index.ts +6 -6
  781. package/src/components/volumeProfile/poc.ts +13 -13
  782. package/src/components/volumeProfile/types.ts +67 -67
  783. package/src/components/volumeProfile/valueArea.ts +119 -119
  784. package/src/config/chartSettings.ts +60 -14
  785. package/src/controllers/__tests__/drawing.test.ts +164 -170
  786. package/src/controllers/__tests__/indicatorSelector.test.ts +418 -405
  787. package/src/controllers/__tests__/toolbar.test.ts +174 -174
  788. package/src/controllers/createChartController.ts +911 -885
  789. package/src/controllers/createDrawingController.ts +54 -60
  790. package/src/controllers/createIndicatorSelectorController.ts +212 -228
  791. package/src/controllers/createToolbarController.ts +99 -103
  792. package/src/controllers/index.ts +65 -39
  793. package/src/controllers/types.ts +318 -285
  794. package/src/data-fetchers/__tests__/binance.test.ts +297 -0
  795. package/src/data-fetchers/__tests__/dataBuffer.test.ts +409 -412
  796. package/src/data-fetchers/__tests__/depthConnector.test.ts +259 -0
  797. package/src/data-fetchers/__tests__/fetcherRegistry.test.ts +64 -29
  798. package/src/data-fetchers/baostock.ts +4 -1
  799. package/src/data-fetchers/binance.ts +130 -0
  800. package/src/data-fetchers/dataBuffer.effects.ts +8 -11
  801. package/src/data-fetchers/dataBuffer.ts +248 -231
  802. package/src/data-fetchers/dataBufferTypes.ts +1 -1
  803. package/src/data-fetchers/depthConnector.ts +103 -0
  804. package/src/data-fetchers/depthTypes.ts +69 -0
  805. package/src/data-fetchers/fetcherDefinitionRegistry.ts +11 -7
  806. package/src/data-fetchers/gotdx.ts +35 -13
  807. package/src/data-fetchers/index.ts +9 -2
  808. package/src/data-fetchers/router.ts +10 -5
  809. package/src/data-fetchers/timeShareBuffer.ts +5 -2
  810. package/src/data-fetchers/tradingview.ts +4 -1
  811. package/src/data-fetchers/types.ts +1 -1
  812. package/src/engine/__tests__/chart.dpr.test.ts +6 -2
  813. package/src/engine/__tests__/subPaneManager.test.ts +23 -10
  814. package/src/engine/chart.ts +1290 -1213
  815. package/src/engine/controller/interaction.ts +921 -896
  816. package/src/engine/controller/markerInteraction.ts +4 -1
  817. package/src/engine/data/chartDataManager.ts +109 -45
  818. package/src/engine/draw/__tests__/pixelAlign.spec.ts +1 -1
  819. package/src/engine/draw/pixelAlign.ts +170 -166
  820. package/src/engine/drawing/AnchorCollector.ts +1 -1
  821. package/src/engine/drawing/DragHandler.ts +1 -1
  822. package/src/engine/drawing/DrawingState.ts +2 -2
  823. package/src/engine/drawing/HitTester.ts +34 -17
  824. package/src/engine/drawing/PreviewRenderer.ts +46 -19
  825. package/src/engine/drawing/coordinateUtils.ts +5 -5
  826. package/src/engine/drawing/index.ts +107 -28
  827. package/src/engine/drawing/interaction.ts +9 -7
  828. package/src/engine/drawing/linearRegression.ts +3 -1
  829. package/src/engine/drawing/plugin.ts +100 -30
  830. package/src/engine/drawing/toolConfig.ts +1 -1
  831. package/src/engine/indicators/__tests__/__fixtures__/golden/atr.json +104 -36
  832. package/src/engine/indicators/__tests__/__fixtures__/golden/dema.json +11 -12
  833. package/src/engine/indicators/__tests__/__fixtures__/golden/hma.json +39 -12
  834. package/src/engine/indicators/__tests__/__fixtures__/golden/index.ts +28 -28
  835. package/src/engine/indicators/__tests__/__fixtures__/golden/kama.json +39 -12
  836. package/src/engine/indicators/__tests__/__fixtures__/golden/tema.json +11 -12
  837. package/src/engine/indicators/__tests__/__fixtures__/golden/wma.json +73 -38
  838. package/src/engine/indicators/__tests__/__fixtures__/synthetic.ts +36 -29
  839. package/src/engine/indicators/__tests__/_propertyAssertions.ts +55 -54
  840. package/src/engine/indicators/__tests__/atr.test.ts +141 -144
  841. package/src/engine/indicators/__tests__/calculators.test.ts +4 -17
  842. package/src/engine/indicators/__tests__/chartIndicatorManager.test.ts +12 -1
  843. package/src/engine/indicators/__tests__/cmf-mfi.test.ts +77 -77
  844. package/src/engine/indicators/__tests__/dema.test.ts +54 -56
  845. package/src/engine/indicators/__tests__/donchian.test.ts +52 -58
  846. package/src/engine/indicators/__tests__/hma.test.ts +53 -55
  847. package/src/engine/indicators/__tests__/ichimoku.test.ts +91 -91
  848. package/src/engine/indicators/__tests__/indicatorRegistry.test.ts +6 -2
  849. package/src/engine/indicators/__tests__/kama.test.ts +60 -62
  850. package/src/engine/indicators/__tests__/keltner.test.ts +49 -55
  851. package/src/engine/indicators/__tests__/pivot-fib.test.ts +89 -89
  852. package/src/engine/indicators/__tests__/registerBuiltins.test.ts +199 -51
  853. package/src/engine/indicators/__tests__/roc.test.ts +56 -53
  854. package/src/engine/indicators/__tests__/sar.test.ts +70 -70
  855. package/src/engine/indicators/__tests__/scheduler.test.ts +58 -15
  856. package/src/engine/indicators/__tests__/soa.test.ts +27 -7
  857. package/src/engine/indicators/__tests__/stateComposer.test.ts +227 -45
  858. package/src/engine/indicators/__tests__/structure.test.ts +109 -93
  859. package/src/engine/indicators/__tests__/supertrend.test.ts +47 -53
  860. package/src/engine/indicators/__tests__/tema.test.ts +49 -51
  861. package/src/engine/indicators/__tests__/trix.test.ts +56 -56
  862. package/src/engine/indicators/__tests__/volatility.test.ts +88 -94
  863. package/src/engine/indicators/__tests__/volume.test.ts +102 -102
  864. package/src/engine/indicators/__tests__/volumeProfile.test.ts +55 -61
  865. package/src/engine/indicators/__tests__/vwap.test.ts +56 -56
  866. package/src/engine/indicators/__tests__/wma.test.ts +86 -89
  867. package/src/engine/indicators/__tests__/zones.test.ts +88 -79
  868. package/src/engine/indicators/calculators/_shared.ts +41 -35
  869. package/src/engine/indicators/calculators/bands.ts +271 -282
  870. package/src/engine/indicators/calculators/index.ts +26 -3
  871. package/src/engine/indicators/calculators/movingAverages.ts +134 -134
  872. package/src/engine/indicators/calculators/oscillators.ts +302 -306
  873. package/src/engine/indicators/calculators/patterns.ts +233 -225
  874. package/src/engine/indicators/calculators/volatility.ts +119 -119
  875. package/src/engine/indicators/calculators/volume.ts +217 -220
  876. package/src/engine/indicators/calculators.ts +0 -2
  877. package/src/engine/indicators/chartIndicatorManager.ts +576 -484
  878. package/src/engine/indicators/indicator.worker.ts +134 -132
  879. package/src/engine/indicators/indicatorDefinitionRegistry.ts +111 -96
  880. package/src/engine/indicators/indicatorMetadata.ts +183 -175
  881. package/src/engine/indicators/indicatorRegistry.ts +146 -137
  882. package/src/engine/indicators/indicatorRuntime.ts +206 -196
  883. package/src/engine/indicators/registerBuiltins.ts +2 -1
  884. package/src/engine/indicators/scheduler.ts +725 -674
  885. package/src/engine/indicators/soa.ts +29 -19
  886. package/src/engine/indicators/state/atrState.ts +15 -16
  887. package/src/engine/indicators/state/bollState.ts +28 -28
  888. package/src/engine/indicators/state/cciState.ts +15 -16
  889. package/src/engine/indicators/state/chaikinVolState.ts +19 -19
  890. package/src/engine/indicators/state/cmfState.ts +15 -16
  891. package/src/engine/indicators/state/demaState.ts +15 -16
  892. package/src/engine/indicators/state/donchianState.ts +28 -28
  893. package/src/engine/indicators/state/eneState.ts +20 -20
  894. package/src/engine/indicators/state/expmaState.ts +20 -20
  895. package/src/engine/indicators/state/fastkState.ts +15 -16
  896. package/src/engine/indicators/state/fibState.ts +26 -27
  897. package/src/engine/indicators/state/hmaState.ts +15 -16
  898. package/src/engine/indicators/state/hvState.ts +19 -16
  899. package/src/engine/indicators/state/ichimokuState.ts +42 -42
  900. package/src/engine/indicators/state/kamaState.ts +20 -21
  901. package/src/engine/indicators/state/keltnerState.ts +32 -33
  902. package/src/engine/indicators/state/kstState.ts +31 -32
  903. package/src/engine/indicators/state/maState.ts +14 -14
  904. package/src/engine/indicators/state/mfiState.ts +15 -16
  905. package/src/engine/indicators/state/momState.ts +15 -16
  906. package/src/engine/indicators/state/obvState.ts +15 -16
  907. package/src/engine/indicators/state/parkinsonState.ts +19 -15
  908. package/src/engine/indicators/state/pivotState.ts +38 -39
  909. package/src/engine/indicators/state/pvtState.ts +15 -16
  910. package/src/engine/indicators/state/rocState.ts +15 -16
  911. package/src/engine/indicators/state/rsiState.ts +38 -39
  912. package/src/engine/indicators/state/sarState.ts +21 -22
  913. package/src/engine/indicators/state/stochState.ts +15 -16
  914. package/src/engine/indicators/state/structureState.ts +45 -45
  915. package/src/engine/indicators/state/supertrendState.ts +21 -21
  916. package/src/engine/indicators/state/temaState.ts +15 -16
  917. package/src/engine/indicators/state/trixState.ts +22 -23
  918. package/src/engine/indicators/state/vmaState.ts +15 -16
  919. package/src/engine/indicators/state/volumeProfileState.ts +41 -41
  920. package/src/engine/indicators/state/vwapState.ts +15 -16
  921. package/src/engine/indicators/state/wmaState.ts +15 -16
  922. package/src/engine/indicators/state/wmsrState.ts +15 -16
  923. package/src/engine/indicators/state/zonesState.ts +30 -31
  924. package/src/engine/indicators/stateComposer.ts +185 -190
  925. package/src/engine/indicators/visibleStateComposers.ts +785 -748
  926. package/src/engine/indicators/workerProtocol.ts +394 -397
  927. package/src/engine/layout/chartPaneLayout.ts +25 -16
  928. package/src/engine/layout/pane.ts +11 -3
  929. package/src/engine/marker/registry.ts +208 -190
  930. package/src/engine/modes/kLineMode.ts +26 -16
  931. package/src/engine/modes/timeShareMode.ts +26 -14
  932. package/src/engine/modes/types.ts +26 -14
  933. package/src/engine/paneRenderer.ts +130 -125
  934. package/src/engine/render/chartRenderer.ts +291 -118
  935. package/src/engine/render/layers/candleLayer.ts +9 -0
  936. package/src/engine/render/layers/comparisonLineLayer.ts +9 -0
  937. package/src/engine/render/layers/crosshairLayer.ts +18 -0
  938. package/src/engine/render/layers/customMarkersLayer.ts +8 -0
  939. package/src/engine/render/layers/extremaMarkersLayer.ts +8 -0
  940. package/src/engine/render/layers/gridLinesLayer.ts +8 -0
  941. package/src/engine/render/layers/lastPriceLabelLayer.ts +8 -0
  942. package/src/engine/render/layers/lastPriceLineLayer.ts +9 -0
  943. package/src/engine/render/layers/leftYAxisLayer.ts +15 -0
  944. package/src/engine/render/layers/mainIndicatorLegendLayer.ts +18 -0
  945. package/src/engine/render/layers/yAxisLayer.ts +15 -0
  946. package/src/engine/renderers/Indicator/__tests__/createSubIndicatorRenderer.test.ts +4 -1
  947. package/src/engine/renderers/Indicator/atr.ts +197 -188
  948. package/src/engine/renderers/Indicator/boll.ts +364 -309
  949. package/src/engine/renderers/Indicator/cci.ts +223 -219
  950. package/src/engine/renderers/Indicator/chaikinVol.ts +129 -112
  951. package/src/engine/renderers/Indicator/cmf.ts +121 -111
  952. package/src/engine/renderers/Indicator/dema.ts +124 -112
  953. package/src/engine/renderers/Indicator/donchian.ts +162 -132
  954. package/src/engine/renderers/Indicator/ene.ts +286 -264
  955. package/src/engine/renderers/Indicator/expma.ts +237 -220
  956. package/src/engine/renderers/Indicator/fastk.ts +201 -197
  957. package/src/engine/renderers/Indicator/fib.ts +162 -138
  958. package/src/engine/renderers/Indicator/hma.ts +124 -112
  959. package/src/engine/renderers/Indicator/hv.ts +108 -94
  960. package/src/engine/renderers/Indicator/ichimoku.ts +183 -112
  961. package/src/engine/renderers/Indicator/index.ts +10 -10
  962. package/src/engine/renderers/Indicator/indicatorCatalog.ts +685 -78
  963. package/src/engine/renderers/Indicator/kama.ts +124 -112
  964. package/src/engine/renderers/Indicator/keltner.ts +170 -131
  965. package/src/engine/renderers/Indicator/kst.ts +290 -255
  966. package/src/engine/renderers/Indicator/ma.ts +292 -254
  967. package/src/engine/renderers/Indicator/macd.ts +174 -38
  968. package/src/engine/renderers/Indicator/mainIndicatorLegend.ts +30 -8
  969. package/src/engine/renderers/Indicator/mfi.ts +126 -116
  970. package/src/engine/renderers/Indicator/mom.ts +268 -250
  971. package/src/engine/renderers/Indicator/obv.ts +107 -98
  972. package/src/engine/renderers/Indicator/parkinson.ts +110 -94
  973. package/src/engine/renderers/Indicator/pivot.ts +187 -145
  974. package/src/engine/renderers/Indicator/pvt.ts +107 -98
  975. package/src/engine/renderers/Indicator/roc.ts +136 -124
  976. package/src/engine/renderers/Indicator/rsi.ts +395 -346
  977. package/src/engine/renderers/Indicator/sar.ts +121 -106
  978. package/src/engine/renderers/Indicator/scale/atr_scale.ts +13 -13
  979. package/src/engine/renderers/Indicator/scale/cci_scale.ts +13 -13
  980. package/src/engine/renderers/Indicator/scale/fastk_scale.ts +13 -13
  981. package/src/engine/renderers/Indicator/scale/indicator_scale.ts +193 -174
  982. package/src/engine/renderers/Indicator/scale/kst_scale.ts +13 -13
  983. package/src/engine/renderers/Indicator/scale/macd_scale.ts +13 -13
  984. package/src/engine/renderers/Indicator/scale/mom_scale.ts +13 -13
  985. package/src/engine/renderers/Indicator/scale/rsi_scale.ts +13 -13
  986. package/src/engine/renderers/Indicator/scale/stoch_scale.ts +13 -13
  987. package/src/engine/renderers/Indicator/scale/volume_scale.ts +15 -15
  988. package/src/engine/renderers/Indicator/scale/wmsr_scale.ts +13 -13
  989. package/src/engine/renderers/Indicator/shared/dashedLines.ts +16 -7
  990. package/src/engine/renderers/Indicator/shared/titleInfo.ts +3 -1
  991. package/src/engine/renderers/Indicator/shared/webglBand.ts +1 -1
  992. package/src/engine/renderers/Indicator/stoch.ts +263 -246
  993. package/src/engine/renderers/Indicator/structure.ts +165 -120
  994. package/src/engine/renderers/Indicator/supertrend.ts +145 -112
  995. package/src/engine/renderers/Indicator/tema.ts +124 -112
  996. package/src/engine/renderers/Indicator/trix.ts +170 -159
  997. package/src/engine/renderers/Indicator/vma.ts +108 -98
  998. package/src/engine/renderers/Indicator/volumeProfile.ts +150 -126
  999. package/src/engine/renderers/Indicator/vwap.ts +107 -98
  1000. package/src/engine/renderers/Indicator/wma.ts +124 -112
  1001. package/src/engine/renderers/Indicator/wmsr.ts +289 -265
  1002. package/src/engine/renderers/Indicator/zones.ts +139 -109
  1003. package/src/engine/renderers/__tests__/boll.renderer.test.ts +20 -9
  1004. package/src/engine/renderers/__tests__/ene.renderer.test.ts +3 -5
  1005. package/src/engine/renderers/__tests__/expma.renderer.test.ts +1 -1
  1006. package/src/engine/renderers/__tests__/ma.renderer.test.ts +14 -5
  1007. package/src/engine/renderers/__tests__/mainIndicatorLegend.renderer.test.ts +36 -49
  1008. package/src/engine/renderers/__tests__/yAxis.renderer.test.ts +7 -1
  1009. package/src/engine/renderers/candle.ts +556 -437
  1010. package/src/engine/renderers/comparisonLine.ts +96 -91
  1011. package/src/engine/renderers/crosshair.ts +5 -1
  1012. package/src/engine/renderers/customMarkers.ts +144 -118
  1013. package/src/engine/renderers/extremaMarkers.ts +191 -180
  1014. package/src/engine/renderers/gridLines.ts +51 -48
  1015. package/src/engine/renderers/lastPrice.ts +81 -70
  1016. package/src/engine/renderers/leftYAxis.ts +47 -26
  1017. package/src/engine/renderers/paneTitle.ts +140 -124
  1018. package/src/engine/renderers/subVolume.ts +264 -194
  1019. package/src/engine/renderers/timeAxis.ts +70 -48
  1020. package/src/engine/renderers/timeShare.ts +42 -13
  1021. package/src/engine/renderers/webgl/candleSurface.ts +943 -850
  1022. package/src/engine/renderers/webgl/sharedWebGLSurface.ts +146 -122
  1023. package/src/engine/renderers/yAxis.ts +45 -29
  1024. package/src/engine/scale/__tests__/logFormula.spec.ts +141 -141
  1025. package/src/engine/scale/logFormula.ts +40 -40
  1026. package/src/engine/scale/price.ts +21 -22
  1027. package/src/engine/scale/priceScale.ts +269 -269
  1028. package/src/engine/subPaneManager.ts +291 -200
  1029. package/src/engine/theme/fonts.ts +5 -5
  1030. package/src/engine/utils/__tests__/tickPosition.test.ts +43 -43
  1031. package/src/engine/utils/chartZoomController.ts +10 -3
  1032. package/src/engine/utils/klineConfig.ts +22 -22
  1033. package/src/engine/utils/tickCount.ts +2 -2
  1034. package/src/engine/utils/tickPosition.ts +205 -207
  1035. package/src/engine/viewport/chartViewportManager.ts +33 -22
  1036. package/src/engine/viewport/viewport.ts +35 -28
  1037. package/src/errors-help.ts +134 -135
  1038. package/src/errors.ts +65 -62
  1039. package/src/index.ts +5 -9
  1040. package/src/indicators/__tests__/maFamily.test.ts +114 -114
  1041. package/src/indicators/__tests__/oscillators.test.ts +108 -104
  1042. package/src/indicators/alma.ts +36 -33
  1043. package/src/indicators/awesomeOscillator.ts +36 -33
  1044. package/src/indicators/dpo.ts +18 -17
  1045. package/src/indicators/fisherTransform.ts +40 -37
  1046. package/src/indicators/frama.ts +60 -53
  1047. package/src/indicators/index.ts +4 -16
  1048. package/src/indicators/lsma.ts +32 -31
  1049. package/src/indicators/schaffTrendCycle.ts +61 -59
  1050. package/src/indicators/stochRSI.ts +74 -74
  1051. package/src/indicators/t3.ts +55 -56
  1052. package/src/indicators/ultimateOscillator.ts +57 -54
  1053. package/src/indicators/vidya.ts +49 -48
  1054. package/src/indicators/zlema.ts +21 -20
  1055. package/src/input/__tests__/gesture.test.ts +182 -182
  1056. package/src/input/__tests__/keyboard.test.ts +228 -235
  1057. package/src/input/gesture.ts +262 -268
  1058. package/src/input/index.ts +15 -15
  1059. package/src/input/keyboard.ts +235 -237
  1060. package/src/mcp/chartBridge.ts +3 -11
  1061. package/src/plugin/HookSystem.ts +2 -6
  1062. package/src/plugin/PluginHost.ts +26 -6
  1063. package/src/plugin/StateStore.ts +1 -1
  1064. package/src/plugin/rendererPluginManager.ts +4 -8
  1065. package/src/plugin/types.ts +10 -7
  1066. package/src/reactivity/signal.ts +69 -69
  1067. package/src/render/Renderer.ts +57 -57
  1068. package/src/render/SurfaceBackend.ts +51 -51
  1069. package/src/render/__tests__/contract.test.ts +134 -134
  1070. package/src/render/__tests__/webglRenderer.fallback.test.ts +226 -0
  1071. package/src/render/__tests__/webglRenderer.test.ts +363 -0
  1072. package/src/render/__tests__/webglSurfaceBackend.test.ts +125 -0
  1073. package/src/render/createWebGLRenderer.ts +288 -0
  1074. package/src/render/createWebGLSurfaceBackend.ts +43 -0
  1075. package/src/render/index.ts +15 -19
  1076. package/src/renderer-tier/__tests__/detectRendererTier.test.ts +116 -119
  1077. package/src/renderer-tier/__tests__/selectBackend.test.ts +168 -172
  1078. package/src/renderer-tier/detectRendererTier.ts +65 -74
  1079. package/src/renderer-tier/index.ts +15 -15
  1080. package/src/renderer-tier/selectBackend.ts +89 -98
  1081. package/src/renderer-tier/types.ts +11 -11
  1082. package/src/replay/__tests__/controller.test.ts +268 -268
  1083. package/src/replay/__tests__/timeline.test.ts +77 -77
  1084. package/src/replay/createReplayController.ts +224 -232
  1085. package/src/replay/index.ts +7 -11
  1086. package/src/replay/timeline.ts +44 -50
  1087. package/src/replay/types.ts +63 -65
  1088. package/src/scale/__tests__/anchoredZoom.test.ts +121 -110
  1089. package/src/scale/__tests__/originShift.test.ts +80 -80
  1090. package/src/scale/__tests__/priceScale.test.ts +205 -205
  1091. package/src/scale/__tests__/timeScale.test.ts +104 -98
  1092. package/src/scale/anchoredZoom.ts +44 -44
  1093. package/src/scale/createPriceScale.ts +178 -175
  1094. package/src/scale/createTimeScale.ts +130 -124
  1095. package/src/scale/index.ts +3 -3
  1096. package/src/scale/originShift.ts +49 -43
  1097. package/src/scale/types.ts +43 -43
  1098. package/src/scene/__tests__/layerFromPlugin.test.ts +243 -0
  1099. package/src/scene/__tests__/layerRegistry.test.ts +154 -170
  1100. package/src/scene/__tests__/scene.test.ts +341 -345
  1101. package/src/scene/createLayerFromPlugin.ts +47 -0
  1102. package/src/scene/createScene.ts +85 -82
  1103. package/src/scene/index.ts +5 -16
  1104. package/src/scene/layerRegistry.ts +52 -54
  1105. package/src/scene/types.ts +37 -32
  1106. package/src/scheduler/__tests__/createFrameBudget.test.ts +227 -223
  1107. package/src/scheduler/createFrameBudget.ts +224 -224
  1108. package/src/scheduler/index.ts +5 -5
  1109. package/src/semantic/__tests__/controller.test.ts +11 -9
  1110. package/src/semantic/controller.ts +42 -18
  1111. package/src/semantic/drawShape.ts +3 -3
  1112. package/src/semantic/index.ts +7 -1
  1113. package/src/semantic/schema.json +16 -4
  1114. package/src/semantic/validator.ts +22 -8
  1115. package/src/tokens/__tests__/baseline.test.ts +99 -102
  1116. package/src/tokens/__tests__/themeToCssVars.test.ts +117 -128
  1117. package/src/tokens/__tests__/tokens.test.ts +119 -130
  1118. package/src/tokens/colorPresetSettings.ts +103 -99
  1119. package/src/tokens/index.ts +44 -44
  1120. package/src/tokens/mergeTheme.ts +20 -20
  1121. package/src/tokens/theme-base.ts +1 -2
  1122. package/src/tokens/theme-china.ts +70 -70
  1123. package/src/tokens/theme-dark.ts +182 -182
  1124. package/src/tokens/theme-light.ts +186 -186
  1125. package/src/tokens/themeToCssVars.ts +53 -54
  1126. package/src/tokens/types.ts +215 -215
  1127. package/src/types/price.ts +7 -2
  1128. package/src/types/volumePrice.ts +1 -2
  1129. package/src/utils/__tests__/dateFormat.test.ts +137 -142
  1130. package/src/utils/dateFormat.ts +115 -110
  1131. package/src/utils/kLineDraw/axis.ts +486 -453
  1132. package/src/utils/priceToY.ts +21 -21
  1133. package/src/utils/volumePrice.ts +8 -4
  1134. package/src/version.ts +1 -1
@@ -1,14 +1,23 @@
1
1
  import type { KLineData } from '../types/price'
2
2
  import type { ChartSettings } from '../config/chartSettings'
3
3
  import { createSignal, type Signal, type Computed } from '../reactivity/signal'
4
- import type { SymbolSpec, CustomDataSource } from '../controllers/types'
4
+ import type { SymbolSpec, SymbolInfo, CustomDataSource } from '../controllers/types'
5
5
  import { ChartDataManager } from './data/chartDataManager'
6
6
  import { ChartPaneLayout } from './layout/chartPaneLayout'
7
7
  import { UpdateLevel, type VisibleRange } from './layout/pane'
8
8
  import type { ScaleType } from './utils/tickPosition'
9
9
  import { InteractionController, type InteractionSnapshot } from './controller/interaction'
10
10
  export type { InteractionSnapshot }
11
- import type { ChartDom, PaneSpec, ChartOptions, Viewport, ViewportState, IndicatorInstance, SubPaneInfo, DrawingToolType } from './chartTypes'
11
+ import type {
12
+ ChartDom,
13
+ PaneSpec,
14
+ ChartOptions,
15
+ Viewport,
16
+ ViewportState,
17
+ IndicatorInstance,
18
+ SubPaneInfo,
19
+ DrawingToolType,
20
+ } from './chartTypes'
12
21
  import { PaneRenderer } from './paneRenderer'
13
22
  import { SharedWebGLSurface } from './renderers/webgl/sharedWebGLSurface'
14
23
  import type { MarkerManager, CustomMarkerEntity } from './marker/registry'
@@ -24,12 +33,12 @@ import { TimeShareMode } from './modes/timeShareMode'
24
33
  import type { ChartModeHandler } from './modes/types'
25
34
 
26
35
  import {
27
- createPluginHost,
28
- type PluginHostImpl,
29
- RendererPluginManager,
30
- type RendererPlugin,
31
- type RendererPluginWithHost,
32
- wrapPaneInfo,
36
+ createPluginHost,
37
+ type PluginHostImpl,
38
+ RendererPluginManager,
39
+ type RendererPlugin,
40
+ type RendererPluginWithHost,
41
+ wrapPaneInfo,
33
42
  } from '../plugin'
34
43
  import type { SubIndicatorType } from './renderers/Indicator'
35
44
  import type { AlertController, MarketSnapshot } from '../alerts/types'
@@ -41,56 +50,69 @@ import {
41
50
  } from '../alerts/rollingVolume'
42
51
  import { resolveStateKey } from './indicators/indicatorMetadata'
43
52
  import type { IndicatorMetadata } from './indicators/indicatorMetadata'
44
-
53
+ import type { Layer } from '../scene/types'
45
54
 
46
55
  // 重新导出以保持向后兼容
47
56
  export { getPhysicalKLineConfig }
48
- export type { ChartDom, PaneSpec, PaneRendererDom, ChartOptions, KLinePositions, Viewport, ViewportState, IndicatorRole, IndicatorInstance, SubPaneInfo, DrawingToolType, DrawingObject } from './chartTypes'
57
+ export type {
58
+ ChartDom,
59
+ PaneSpec,
60
+ PaneRendererDom,
61
+ ChartOptions,
62
+ KLinePositions,
63
+ Viewport,
64
+ ViewportState,
65
+ IndicatorRole,
66
+ IndicatorInstance,
67
+ SubPaneInfo,
68
+ DrawingToolType,
69
+ DrawingObject,
70
+ } from './chartTypes'
49
71
 
50
72
  type ResolvedChartOptions = Omit<ChartOptions, 'kWidth' | 'kGap'> & {
51
- kWidth: number
52
- kGap: number
73
+ kWidth: number
74
+ kGap: number
53
75
  }
54
76
 
55
77
  export class Chart {
56
- private dom: ChartDom
57
- private opt: ResolvedChartOptions
58
- private dataManager: ChartDataManager
59
-
60
- private viewportManager: ChartViewportManager
61
- private layoutManager: ChartPaneLayout
62
- private get paneRenderers(): PaneRenderer[] {
63
- return this.layoutManager.getPaneRenderers()
64
- }
65
- readonly interaction: InteractionController
78
+ private dom: ChartDom
79
+ private opt: ResolvedChartOptions
80
+ private dataManager: ChartDataManager
81
+
82
+ private viewportManager: ChartViewportManager
83
+ private layoutManager: ChartPaneLayout
84
+ private get paneRenderers(): PaneRenderer[] {
85
+ return this.layoutManager.getPaneRenderers()
86
+ }
87
+ readonly interaction: InteractionController
66
88
 
67
- /** 插件宿主 */
68
- private pluginHost: PluginHostImpl
89
+ /** 插件宿主 */
90
+ private pluginHost: PluginHostImpl
69
91
 
70
- /** 渲染器插件管理器 */
71
- private rendererPluginManager: RendererPluginManager
92
+ /** 渲染器插件管理器 */
93
+ private rendererPluginManager: RendererPluginManager
72
94
 
73
- /** Chart 级共享 WebGL canvas/context */
74
- private sharedWebGLSurface: SharedWebGLSurface
95
+ /** Chart 级共享 WebGL canvas/context */
96
+ private sharedWebGLSurface: SharedWebGLSurface
75
97
 
76
- /** 缩放控制器 */
77
- private zoomController: ChartZoomController
98
+ /** 缩放控制器 */
99
+ private zoomController: ChartZoomController
78
100
 
79
- /** 指标管理器 */
80
- private indicatorManager: ChartIndicatorManager
101
+ /** 指标管理器 */
102
+ private indicatorManager: ChartIndicatorManager
81
103
 
82
- /** 渲染器 */
83
- private renderer: ChartRenderer
104
+ /** 渲染器 */
105
+ private renderer: ChartRenderer
84
106
 
85
- /** 当前活跃的模式处理器 */
86
- private _activeMode: ChartModeHandler
87
- private _kLineMode = new KLineMode()
88
- private _timeShareMode = new TimeShareMode()
107
+ /** 当前活跃的模式处理器 */
108
+ private _activeMode: ChartModeHandler
109
+ private _kLineMode = new KLineMode()
110
+ private _timeShareMode = new TimeShareMode()
89
111
 
90
- /** 模式切换时保存的渲染状态(退出分时时恢复) */
91
- private _modeSavedKWidth = 0
92
- private _modeSavedKGap = 0
93
- private _modeSavedZoomLevel = 0
112
+ /** 模式切换时保存的渲染状态(退出分时时恢复) */
113
+ private _modeSavedKWidth = 0
114
+ private _modeSavedKGap = 0
115
+ private _modeSavedZoomLevel = 0
94
116
 
95
117
  /** 分时模式激活前的 pane Y 轴刻度类型(退出分时时恢复) */
96
118
  private _savedScaleTypes: Map<string, ScaleType> | undefined
@@ -104,1196 +126,1251 @@ export class Chart {
104
126
  /** 滚动成交量窗口(惰性初始化) */
105
127
  private _volumeLookbacks: VolumeLookbacks | null = null
106
128
 
107
- /**
108
- * 启用主图指标
109
- * @param indicatorId 指标ID
110
- * @param params 可选的指标参数
111
- * @returns 是否成功启用
112
- */
113
- enableMainIndicator(indicatorId: string, params?: Record<string, number | boolean | string>): boolean {
114
- return this.indicatorManager.enableMainIndicator(indicatorId, params)
115
- }
116
-
117
- disableMainIndicator(indicatorId: string): boolean {
118
- return this.indicatorManager.disableMainIndicator(indicatorId)
119
- }
120
-
121
- toggleMainIndicator(indicatorId: string, enabled: boolean): void {
122
- this.indicatorManager.toggleMainIndicator(indicatorId, enabled)
123
- }
124
-
125
- getActiveMainIndicators(): string[] {
126
- return this.indicatorManager.getActiveMainIndicators()
127
- }
128
-
129
- isMainIndicatorActive(indicatorId: string): boolean {
130
- return this.indicatorManager.isMainIndicatorActive(indicatorId)
131
- }
132
-
133
- updateMainIndicatorParams(indicatorId: string, params: Record<string, number | boolean | string>): void {
134
- this.indicatorManager.updateMainIndicatorParams(indicatorId, params)
135
- }
136
-
137
- getMainIndicatorParams(indicatorId: string): Record<string, number | boolean | string> | null {
138
- return this.indicatorManager.getMainIndicatorParams(indicatorId)
139
- }
140
-
141
- clearMainIndicators(): void {
142
- this.indicatorManager.clearMainIndicators()
143
- }
144
-
145
- /**
146
- * @deprecated 使用 enableMainIndicator/disableMainIndicator 替代
147
- */
148
- setActiveMainIndicators(indicators: string[]): void {
149
- this.indicatorManager.setActiveMainIndicators(indicators)
150
- }
151
-
152
- /**
153
- * 创建图表实例
154
- * @param dom 由 Vue 组件传入的 DOM 句柄
155
- * @param opt 初始配置
156
- */
157
- constructor(dom: ChartDom, opt: ChartOptions) {
158
- this.dom = dom
159
- const { kWidth: _kWidth, kGap: _kGap, ...restOpt } = opt
160
- // Chart 不持有业务 SSOT,kWidth/kGap/zoomLevel 由外部通过 applyRenderState() 传入
161
- this.opt = { ...restOpt, kWidth: _kWidth ?? 0, kGap: _kGap ?? 0 }
162
- this._activeMode = this._kLineMode
163
- this.interaction = new InteractionController(this)
164
- this.interaction.setOnInteractionChange((snapshot) => {
165
- this._interactionSignal.set(snapshot)
166
- })
167
- this.pluginHost = createPluginHost()
168
- this.rendererPluginManager = new RendererPluginManager()
169
- this.sharedWebGLSurface = new SharedWebGLSurface()
170
-
171
- // 注入依赖
172
- this.rendererPluginManager.setPluginHost(this.pluginHost)
173
- this.rendererPluginManager.setInvalidateCallback(() => this.scheduleDraw())
174
-
175
- this.viewportManager = new ChartViewportManager({
176
- getDom: () => this.dom,
177
- getBottomAxisHeight: () => this.opt.bottomAxisHeight,
178
- getLeftLoadBufferWidth: () => this.dataManager.getLeftLoadBufferWidth(),
179
- getZoomLevel: () => this.zoomController.currentZoomLevel,
180
- getLastVisibleRange: () => this.dataManager.lastVisibleRange,
181
- getKWidth: () => this.opt.kWidth,
182
- getKGap: () => this.opt.kGap,
183
- scheduleDraw: (level) => this.scheduleDraw(level),
184
- onResizeCompleted: () => { this.resize() },
185
- resizeSharedWebGLSurface: (plotWidth, plotHeight, dpr) => this.sharedWebGLSurface.resize(plotWidth, plotHeight, dpr),
186
- })
187
-
188
- this.layoutManager = new ChartPaneLayout(this.opt.panes, {
189
- getDom: () => this.dom,
190
- getOption: () => ({
191
- rightAxisWidth: this.opt.rightAxisWidth,
192
- leftAxisWidth: this.opt.leftAxisWidth,
193
- yPaddingPx: this.opt.yPaddingPx,
194
- priceLabelWidth: this.opt.priceLabelWidth,
195
- paneGap: this.opt.paneGap,
196
- defaultPaneMinHeightPx: this.opt.defaultPaneMinHeightPx,
197
- }),
198
- getViewport: () => this.viewportManager.getViewport(),
199
- getSharedWebGLSurface: () => this.sharedWebGLSurface,
200
- setKnownPaneIds: (ids) => this.rendererPluginManager.setKnownPaneIds(ids),
201
- notifyPaneResize: (paneId, pane) => this.rendererPluginManager.notifyResize(paneId, wrapPaneInfo(pane)),
202
- scheduleDraw: (level) => this.scheduleDraw(level),
203
- onLayoutChange: (ratios, specs) => {
204
- this._paneRatiosSignal.set(ratios)
205
- this._paneLayoutSignal.set(specs)
206
- this.opt = { ...this.opt, panes: specs }
207
- },
208
- })
209
-
210
- this.alertController = createAlertController()
211
-
212
- this.dataManager = new ChartDataManager({
213
- getOption: () => this.opt,
214
- getEffectiveDpr: () => this.viewportManager.getEffectiveDpr(),
215
- getLogicalScrollLeft: () => this.viewportManager.getLogicalScrollLeft(),
216
- getCachedScrollLeft: () => this.viewportManager.getCachedScrollLeft(),
217
- setScrollLeft: (v) => { this.viewportManager.setScrollLeft(v) },
218
- getDom: () => this.dom,
219
- getObservedSize: () => this.viewportManager.getObservedSize(),
220
- getViewport: () => this.viewportManager.getViewport(),
221
- scheduleDraw: (level) => this.scheduleDraw(level),
222
- resetInteraction: () => this.interaction.reset(),
223
- getIndicatorScheduler: () => this.indicatorManager.indicatorSchedulerAccessor,
224
- setPendingIndicatorDataUpdate: (v) => { this.dataManager.pendingIndicatorDataUpdate = v },
225
- isPointerDown: () => this.interaction.isPointerDown(),
226
- onTimeShareDataReady: (dataLength) => {
227
- const vp = this.viewportManager.computeViewport()
228
- if (!vp || vp.plotWidth <= 0) return
229
- const result = this._activeMode.computeKWidth(dataLength, vp.plotWidth, vp.dpr)
230
- if (result) {
231
- this.applyRenderState(result.kWidth, result.kGap)
232
- const container = this.dom.container
233
- if (container) {
234
- const leftBuffer = this.dataManager.getLeftLoadBufferWidth()
235
- this.viewportManager.setScrollLeft(leftBuffer)
236
- this.viewportManager.applyPendingScrollLeft(container)
237
- }
238
- }
239
- },
240
- onDataProcessed: (data, range) => this.evaluateAlerts(data, range), // Alert 管线绑定
241
- })
242
-
243
- this.zoomController = new ChartZoomController({
244
- getLogicalScrollLeft: () => this.viewportManager.getLogicalScrollLeft(),
245
- getCurrentDpr: () => this.viewportManager.getEffectiveDpr(),
246
- getLeftLoadBufferWidth: () => this.dataManager.getLeftLoadBufferWidth(),
247
- getContentWidth: () => this.dataManager.getContentWidth(),
248
- getClientWidth: () => this.viewportManager.getViewport()?.viewWidth ?? this.dom.container?.clientWidth ?? 0,
249
- setScrollLeft: (v) => { this.viewportManager.setScrollLeft(v) },
250
- onZoomCommitted: (result) => {
251
- this.opt = { ...this.opt, kWidth: result.kWidth, kGap: result.kGap }
252
- this.updateViewportSignal()
253
- this.scheduleDraw()
254
- },
255
- getKWidth: () => this.opt.kWidth,
256
- getKGap: () => this.opt.kGap,
257
- getMinKWidth: () => this.opt.minKWidth,
258
- getMaxKWidth: () => this.opt.maxKWidth,
259
- zoomLevelCount: Math.max(2, Math.round(this.opt.zoomLevels ?? 20)),
260
- initialZoomLevel: this.opt.initialZoomLevel ?? 1,
261
- })
262
- // 注意:初始 kWidth/kGap 应由外部通过 applyRenderState() 传入
263
-
264
- // 初始化指标管理器
265
- this.indicatorManager = new ChartIndicatorManager({
266
- getOption: () => this.opt,
267
- getPluginHost: () => this.pluginHost,
268
- getRenderer: (name) => this.getRenderer(name),
269
- useRenderer: (plugin, config) => this.useRenderer(plugin, config),
270
- removeRenderer: (name) => this.removeRenderer(name),
271
- updateRendererConfig: (name, config) => this.updateRendererConfig(name, config),
272
- setRendererEnabled: (name, enabled) => this.setRendererEnabled(name, enabled),
273
- hasPane: (paneId) => this.layoutManager.hasPane(paneId),
274
- upsertPane: (def) => this.layoutManager.upsertPane(def),
275
- removePaneDefinition: (paneId) => this.layoutManager.removePaneDefinition(paneId),
276
- getPaneSpecs: () => this.layoutManager.getPaneSpecs(),
277
- getPaneRatiosSignal: () => this._paneRatiosSignal,
278
- getInternalPaneRatios: () => this.layoutManager.getInternalPaneRatios(),
279
- setInternalPaneRatio: (paneId, ratio) => this.layoutManager.setInternalPaneRatio(paneId, ratio),
280
- deleteInternalPaneRatio: (paneId) => this.layoutManager.deleteInternalPaneRatio(paneId),
281
- applyPaneLayoutSpecs: (specs) => this.layoutManager.applyPaneLayoutSpecs(specs),
282
- getLastVisibleRange: () => this.dataManager.lastVisibleRange,
283
- getCrosshairPos: () => this.interaction.crosshairPos,
284
- getCrosshairPrice: () => this.interaction.crosshairPrice,
285
- getActivePaneId: () => this.interaction.activePaneId,
286
- scheduleDraw: (level) => this.scheduleDraw(level),
287
- setPendingIndicatorDataUpdate: (v) => { this.dataManager.pendingIndicatorDataUpdate = v },
288
- })
289
-
290
- // Worker 异步结果就绪后串联 Alert 管线
291
- this.indicatorManager.indicatorSchedulerAccessor.setOnResultsApplied(() => {
292
- const data = this.dataManager.getInternalData()
293
- this.evaluateAlerts(data, this.dataManager.lastVisibleRange)
294
- })
295
-
296
- // 初始化渲染器
297
- this.renderer = new ChartRenderer({
298
- getDom: () => this.dom,
299
- getOption: () => this.opt,
300
- getPaneRenderers: () => this.paneRenderers,
301
- getInteraction: () => this.interaction,
302
- getSharedWebGLSurface: () => this.sharedWebGLSurface,
303
- getPluginHost: () => this.pluginHost,
304
- getRendererPluginManager: () => this.rendererPluginManager,
305
- getTheme: () => this._themeSignal.peek(),
306
- getCurrentZoomLevel: () => this.zoomController.currentZoomLevel,
307
- getZoomLevelCount: () => this.zoomController.zoomLevelCount,
308
- getViewportManager: () => this.viewportManager,
309
- getDataManager: () => this.dataManager,
310
- getIndicatorManager: () => this.indicatorManager,
311
- getActiveMode: () => this._activeMode,
312
- })
313
- this.renderer.registerDrawingPlugins()
314
- this.renderer.initCoreRenderers()
315
- this.viewportManager.init()
316
- }
317
-
318
-
319
- getViewport(): Viewport | null {
320
- return this.viewportManager.getViewport()
321
- }
322
-
323
- /** 获取当前活跃的模式处理器 */
324
- get activeMode(): ChartModeHandler {
325
- return this._activeMode
326
- }
327
-
328
- /** 切换模式处理器 */
329
- setActiveMode(mode: ChartModeHandler): void {
330
- if (this._activeMode === mode) return
331
- const prev = this._activeMode
332
-
333
- if (mode === this._timeShareMode) {
334
- this._modeSavedKWidth = this.opt.kWidth
335
- this._modeSavedKGap = this.opt.kGap
336
- this._modeSavedZoomLevel = this.zoomController.currentZoomLevel
337
- this._savedScaleTypes = new Map<string, ScaleType>()
338
- for (const r of this.paneRenderers) {
339
- this._savedScaleTypes.set(r.getPane().id, r.getPane().yAxis.getScaleType())
340
- }
341
- } else if (prev === this._timeShareMode) {
342
- for (const renderer of this.paneRenderers) {
343
- const p = renderer.getPane()
344
- const saved = this._savedScaleTypes?.get(p.id) ?? 'linear'
345
- p.yAxis.setScaleType(saved)
346
- p.yAxis.setBasePrice(null)
347
- }
348
- this._savedScaleTypes = undefined
349
- }
350
-
351
- if (this._modeSavedKWidth > 0 && mode !== this._timeShareMode) {
352
- this.applyRenderState(this._modeSavedKWidth, this._modeSavedKGap, this._modeSavedZoomLevel)
353
- this._modeSavedKWidth = 0
354
- }
355
-
356
- prev.onDeactivate(
357
- { enableMainIndicator: (id, p) => this.enableMainIndicator(id, p), disableMainIndicator: (id) => this.disableMainIndicator(id), setRendererEnabled: (n, e) => this.setRendererEnabled(n, e), dataManager: this.dataManager },
358
- mode,
359
- )
360
- this._activeMode = mode
361
- this._activeMode.onActivate(
362
- { enableMainIndicator: (id, p) => this.enableMainIndicator(id, p), disableMainIndicator: (id) => this.disableMainIndicator(id), setRendererEnabled: (n, e) => this.setRendererEnabled(n, e), dataManager: this.dataManager, currentPeriod: this.dataManager.currentPeriod },
363
- prev,
364
- )
365
- }
366
-
367
- getCurrentDpr(): number {
368
- return this.viewportManager.getEffectiveDpr()
369
- }
370
-
371
- /** 获取当前周期 */
372
- get currentPeriod(): string {
373
- return this.dataManager.currentPeriod
374
- }
129
+ /**
130
+ * 启用主图指标
131
+ * @param indicatorId 指标ID
132
+ * @param params 可选的指标参数
133
+ * @returns 是否成功启用
134
+ */
135
+ enableMainIndicator(
136
+ indicatorId: string,
137
+ params?: Record<string, number | boolean | string>,
138
+ ): boolean {
139
+ return this.indicatorManager.enableMainIndicator(indicatorId, params)
140
+ }
141
+
142
+ disableMainIndicator(indicatorId: string): boolean {
143
+ return this.indicatorManager.disableMainIndicator(indicatorId)
144
+ }
145
+
146
+ toggleMainIndicator(indicatorId: string, enabled: boolean): void {
147
+ this.indicatorManager.toggleMainIndicator(indicatorId, enabled)
148
+ }
149
+
150
+ getActiveMainIndicators(): string[] {
151
+ return this.indicatorManager.getActiveMainIndicators()
152
+ }
153
+
154
+ isMainIndicatorActive(indicatorId: string): boolean {
155
+ return this.indicatorManager.isMainIndicatorActive(indicatorId)
156
+ }
157
+
158
+ updateMainIndicatorParams(
159
+ indicatorId: string,
160
+ params: Record<string, number | boolean | string>,
161
+ ): void {
162
+ this.indicatorManager.updateMainIndicatorParams(indicatorId, params)
163
+ }
164
+
165
+ getMainIndicatorParams(indicatorId: string): Record<string, number | boolean | string> | null {
166
+ return this.indicatorManager.getMainIndicatorParams(indicatorId)
167
+ }
168
+
169
+ clearMainIndicators(): void {
170
+ this.indicatorManager.clearMainIndicators()
171
+ }
172
+
173
+ /**
174
+ * @deprecated 使用 enableMainIndicator/disableMainIndicator 替代
175
+ */
176
+ setActiveMainIndicators(indicators: string[]): void {
177
+ this.indicatorManager.setActiveMainIndicators(indicators)
178
+ }
179
+
180
+ /**
181
+ * 创建图表实例
182
+ * @param dom Vue 组件传入的 DOM 句柄
183
+ * @param opt 初始配置
184
+ */
185
+ constructor(dom: ChartDom, opt: ChartOptions) {
186
+ this.dom = dom
187
+ const { kWidth: _kWidth, kGap: _kGap, ...restOpt } = opt
188
+ // Chart 不持有业务 SSOT,kWidth/kGap/zoomLevel 由外部通过 applyRenderState() 传入
189
+ this.opt = { ...restOpt, kWidth: _kWidth ?? 0, kGap: _kGap ?? 0 }
190
+ this._activeMode = this._kLineMode
191
+ this.interaction = new InteractionController(this)
192
+ this.interaction.setOnInteractionChange((snapshot) => {
193
+ this._interactionSignal.set(snapshot)
194
+ })
195
+ this.pluginHost = createPluginHost()
196
+ this.rendererPluginManager = new RendererPluginManager()
197
+ this.sharedWebGLSurface = new SharedWebGLSurface()
198
+
199
+ // 注入依赖
200
+ this.rendererPluginManager.setPluginHost(this.pluginHost)
201
+ this.rendererPluginManager.setInvalidateCallback(() => this.scheduleDraw())
202
+
203
+ this.viewportManager = new ChartViewportManager({
204
+ getDom: () => this.dom,
205
+ getBottomAxisHeight: () => this.opt.bottomAxisHeight,
206
+ getLeftLoadBufferWidth: () => this.dataManager.getLeftLoadBufferWidth(),
207
+ getZoomLevel: () => this.zoomController.currentZoomLevel,
208
+ getLastVisibleRange: () => this.dataManager.lastVisibleRange,
209
+ getKWidth: () => this.opt.kWidth,
210
+ getKGap: () => this.opt.kGap,
211
+ scheduleDraw: (level) => this.scheduleDraw(level),
212
+ onResizeCompleted: () => {
213
+ this.resize()
214
+ },
215
+ resizeSharedWebGLSurface: (plotWidth, plotHeight, dpr) =>
216
+ this.sharedWebGLSurface.resize(plotWidth, plotHeight, dpr),
217
+ })
375
218
 
376
- /** 获取缓存的 scrollLeft(避免读取 DOM 触发强制回流) */
377
- getCachedScrollLeft(): number {
378
- return this.viewportManager.getCachedScrollLeft()
379
- }
219
+ this.layoutManager = new ChartPaneLayout(this.opt.panes, {
220
+ getDom: () => this.dom,
221
+ getOption: () => ({
222
+ rightAxisWidth: this.opt.rightAxisWidth,
223
+ leftAxisWidth: this.opt.leftAxisWidth,
224
+ yPaddingPx: this.opt.yPaddingPx,
225
+ priceLabelWidth: this.opt.priceLabelWidth,
226
+ paneGap: this.opt.paneGap,
227
+ defaultPaneMinHeightPx: this.opt.defaultPaneMinHeightPx,
228
+ }),
229
+ getViewport: () => this.viewportManager.getViewport(),
230
+ getSharedWebGLSurface: () => this.sharedWebGLSurface,
231
+ setKnownPaneIds: (ids) => this.rendererPluginManager.setKnownPaneIds(ids),
232
+ notifyPaneResize: (paneId, pane) =>
233
+ this.rendererPluginManager.notifyResize(paneId, wrapPaneInfo(pane)),
234
+ scheduleDraw: (level) => this.scheduleDraw(level),
235
+ onLayoutChange: (ratios, specs) => {
236
+ this._paneRatiosSignal.set(ratios)
237
+ this._paneLayoutSignal.set(specs)
238
+ this.opt = { ...this.opt, panes: specs }
239
+ },
240
+ })
380
241
 
381
- /** 同步程序性 scrollLeft 写入后的缓存,避免等待异步 scroll 事件 */
382
- syncScrollLeft(scrollLeft: number): void {
383
- this.viewportManager.setScrollLeft(scrollLeft)
384
- }
242
+ this.alertController = createAlertController()
385
243
 
386
- setScrollLeft(v: number): void {
244
+ this.dataManager = new ChartDataManager({
245
+ getOption: () => this.opt,
246
+ getEffectiveDpr: () => this.viewportManager.getEffectiveDpr(),
247
+ getLogicalScrollLeft: () => this.viewportManager.getLogicalScrollLeft(),
248
+ getCachedScrollLeft: () => this.viewportManager.getCachedScrollLeft(),
249
+ setScrollLeft: (v) => {
387
250
  this.viewportManager.setScrollLeft(v)
388
- }
389
-
390
- /** 获取逻辑 scrollLeft(减去左侧加载缓冲宽度,可为负值) */
391
- getLogicalScrollLeft(): number {
392
- return this.viewportManager.getLogicalScrollLeft()
393
- }
394
-
395
- /** 获取插件宿主 */
396
- get plugin(): PluginHostImpl {
397
- return this.pluginHost
398
- }
399
-
400
- // ========== 渲染器插件 API ==========
401
-
402
- /** 安装渲染器插件 */
403
- useRenderer(plugin: RendererPlugin | RendererPluginWithHost, config?: Record<string, unknown>): void {
404
- this.rendererPluginManager.register(plugin)
405
- if (config && plugin.setConfig) {
406
- plugin.setConfig(config)
407
- }
408
- }
409
-
410
- /** 移除渲染器插件 */
411
- removeRenderer(name: string): void {
412
- this.rendererPluginManager.unregister(name)
413
- }
414
-
415
- /** 获取渲染器插件 */
416
- getRenderer<T extends RendererPlugin = RendererPlugin>(name: string): T | undefined {
417
- return this.rendererPluginManager.getPlugin<T>(name)
418
- }
419
-
420
- /** 更新渲染器配置(自动重绘) */
421
- updateRendererConfig(name: string, config: Record<string, unknown>): void {
422
- this.rendererPluginManager.updateConfig(name, config)
423
- }
424
-
425
- /** 启用/禁用渲染器 */
426
- setRendererEnabled(name: string, enabled: boolean): void {
427
- this.rendererPluginManager.setEnabled(name, enabled)
428
- }
429
-
430
- /** 获取所有渲染器 */
431
- getAllRenderers(): RendererPlugin[] {
432
- return this.rendererPluginManager.getAllPlugins()
433
- }
434
-
435
- /** 更新用户设置(触发重绘) */
436
- updateSettings(settings: ChartSettings): void {
437
- this.renderer.updateSettings(settings)
438
- this.interaction.updateSettings(settings)
439
-
440
- // 同步右轴刻度类型设置到所有 pane(百分比仅用于主图)
441
- if ('rightAxisType' in settings) {
442
- const axisType = settings.rightAxisType as string
443
- if (axisType !== 'none') {
444
- for (const renderer of this.paneRenderers) {
445
- const pane = renderer.getPane()
446
- const scaleType = axisType === 'percent' && pane.role !== 'price' ? 'linear' : (axisType as ScaleType)
447
- pane.yAxis.setScaleType(scaleType)
448
- }
449
- }
450
- }
451
-
452
- this.scheduleDraw()
453
- }
454
-
455
- /**
456
- * 绘制一帧
457
- * @param level 更新级别,决定渲染哪些层
458
- */
459
- draw(level: UpdateLevel = UpdateLevel.All) {
460
- this.renderer.draw(level)
461
- }
462
-
463
-
464
-
465
- // ========== Render State API (Vue SSOT) ==========
466
-
467
- /**
468
- * 应用渲染状态(由 Vue/Store 层在状态更新后调用)
469
- * Chart 不拥有业务 SSOT,只负责接收参数并渲染
470
- * 这是写入 opt.kWidth/kGap 和 currentZoomLevel 的唯一入口
471
- */
472
- applyRenderState(kWidth: number, kGap: number, zoomLevel?: number): void {
473
- const nextZoomLevel = zoomLevel !== undefined
474
- ? Math.max(1, Math.min(this.zoomController.zoomLevelCount, zoomLevel))
475
- : this.zoomController.currentZoomLevel
476
- const renderStateChanged = this.opt.kWidth !== kWidth
477
- || this.opt.kGap !== kGap
478
- || this.zoomController.currentZoomLevel !== nextZoomLevel
479
-
480
- if (!renderStateChanged) {
481
- return
251
+ },
252
+ getDom: () => this.dom,
253
+ getObservedSize: () => this.viewportManager.getObservedSize(),
254
+ getViewport: () => this.viewportManager.getViewport(),
255
+ scheduleDraw: (level) => this.scheduleDraw(level),
256
+ resetInteraction: () => this.interaction.reset(),
257
+ getIndicatorScheduler: () => this.indicatorManager.indicatorSchedulerAccessor,
258
+ setPendingIndicatorDataUpdate: (v) => {
259
+ this.dataManager.pendingIndicatorDataUpdate = v
260
+ },
261
+ isPointerDown: () => this.interaction.isPointerDown(),
262
+ onTimeShareDataReady: (dataLength) => {
263
+ const vp = this.viewportManager.computeViewport()
264
+ if (!vp || vp.plotWidth <= 0) return
265
+ const result = this._activeMode.computeKWidth(dataLength, vp.plotWidth, vp.dpr)
266
+ if (result) {
267
+ this.applyRenderState(result.kWidth, result.kGap)
268
+ const container = this.dom.container
269
+ if (container) {
270
+ const leftBuffer = this.dataManager.getLeftLoadBufferWidth()
271
+ this.viewportManager.setScrollLeft(leftBuffer)
272
+ this.viewportManager.applyPendingScrollLeft(container)
273
+ }
482
274
  }
275
+ },
276
+ onDataProcessed: (data, range) => this.evaluateAlerts(data, range), // Alert 管线绑定
277
+ })
483
278
 
484
- this.opt = { ...this.opt, kWidth, kGap }
485
- if (zoomLevel !== undefined) {
486
- this.zoomController.setZoomLevel(nextZoomLevel)
487
- }
279
+ this.zoomController = new ChartZoomController({
280
+ getLogicalScrollLeft: () => this.viewportManager.getLogicalScrollLeft(),
281
+ getCurrentDpr: () => this.viewportManager.getEffectiveDpr(),
282
+ getLeftLoadBufferWidth: () => this.dataManager.getLeftLoadBufferWidth(),
283
+ getContentWidth: () => this.dataManager.getContentWidth(),
284
+ getClientWidth: () =>
285
+ this.viewportManager.getViewport()?.viewWidth ?? this.dom.container?.clientWidth ?? 0,
286
+ setScrollLeft: (v) => {
287
+ this.viewportManager.setScrollLeft(v)
288
+ },
289
+ onZoomCommitted: (result) => {
290
+ this.opt = { ...this.opt, kWidth: result.kWidth, kGap: result.kGap }
488
291
  this.updateViewportSignal()
489
292
  this.scheduleDraw()
490
- }
491
-
492
- /** 获取总缩放级别数 */
493
- getZoomLevelCount(): number {
494
- return this.zoomController.zoomLevelCount
495
- }
496
-
497
- /** 获取所有 PaneRenderer */
498
- getPaneRenderers(): PaneRenderer[] {
499
- return this.paneRenderers
500
- }
501
-
502
- /** 获取 MarkerManager(供 InteractionController 使用) */
503
- getMarkerManager(): MarkerManager {
504
- return this.renderer.getMarkerManager()
505
- }
506
-
507
- /** 更新自定义标记 */
508
- updateCustomMarkers(markers: CustomMarkerEntity[]): void {
509
- this.renderer.getMarkerManager().setCustomMarkers(markers)
510
- this.scheduleDraw()
511
- }
512
-
513
- /** 清除自定义标记 */
514
- clearCustomMarkers(): void {
515
- this.renderer.getMarkerManager().clearCustomMarkers()
516
- this.scheduleDraw()
517
- }
518
-
519
- /** 获取 ChartDom(供 InteractionController 使用) */
520
- getDom() {
521
- return this.dom
522
- }
293
+ },
294
+ getKWidth: () => this.opt.kWidth,
295
+ getKGap: () => this.opt.kGap,
296
+ getMinKWidth: () => this.opt.minKWidth,
297
+ getMaxKWidth: () => this.opt.maxKWidth,
298
+ zoomLevelCount: Math.max(2, Math.round(this.opt.zoomLevels ?? 20)),
299
+ initialZoomLevel: this.opt.initialZoomLevel ?? 1,
300
+ })
301
+ // 注意:初始 kWidth/kGap 应由外部通过 applyRenderState() 传入
302
+
303
+ // 初始化指标管理器
304
+ this.indicatorManager = new ChartIndicatorManager({
305
+ getOption: () => this.opt,
306
+ getPluginHost: () => this.pluginHost,
307
+ getRenderer: (name) => this.getRenderer(name),
308
+ useRenderer: (plugin, config) => this.useRenderer(plugin, config),
309
+ removeRenderer: (name) => this.removeRenderer(name),
310
+ updateRendererConfig: (name, config) => this.updateRendererConfig(name, config),
311
+ setRendererEnabled: (name, enabled) => this.setRendererEnabled(name, enabled),
312
+ hasPane: (paneId) => this.layoutManager.hasPane(paneId),
313
+ upsertPane: (def) => this.layoutManager.upsertPane(def),
314
+ removePaneDefinition: (paneId) => this.layoutManager.removePaneDefinition(paneId),
315
+ getPaneSpecs: () => this.layoutManager.getPaneSpecs(),
316
+ getPaneRatiosSignal: () => this._paneRatiosSignal,
317
+ getInternalPaneRatios: () => this.layoutManager.getInternalPaneRatios(),
318
+ setInternalPaneRatio: (paneId, ratio) =>
319
+ this.layoutManager.setInternalPaneRatio(paneId, ratio),
320
+ deleteInternalPaneRatio: (paneId) => this.layoutManager.deleteInternalPaneRatio(paneId),
321
+ applyPaneLayoutSpecs: (specs) => this.layoutManager.applyPaneLayoutSpecs(specs),
322
+ getLastVisibleRange: () => this.dataManager.lastVisibleRange,
323
+ getCrosshairPos: () => this.interaction.crosshairPos,
324
+ getCrosshairPrice: () => this.interaction.crosshairPrice,
325
+ getActivePaneId: () => this.interaction.activePaneId,
326
+ scheduleDraw: (level) => this.scheduleDraw(level),
327
+ setPendingIndicatorDataUpdate: (v) => {
328
+ this.dataManager.pendingIndicatorDataUpdate = v
329
+ },
330
+ getRenderContext: (paneId) => this.renderer?.getPaneCtxMap()?.get(paneId) ?? null,
331
+ addLayer: (layer) => this.renderer?.getScene()?.addLayer(layer),
332
+ removeLayer: (id) => this.renderer?.getScene()?.removeLayer(id) ?? false,
333
+ getLayer: (id) => this.renderer?.getScene()?.getLayer(id) ?? null,
334
+ setLayerVisibility: (id, visible) =>
335
+ this.renderer?.getScene()?.setLayerVisibility(id, visible),
336
+ })
523
337
 
524
- /** 获取当前 ChartOptions(返回内部当前快照) */
525
- getOption() {
526
- return this.opt
527
- }
338
+ // Worker 异步结果就绪后串联 Alert 管线
339
+ this.indicatorManager.indicatorSchedulerAccessor.setOnResultsApplied(() => {
340
+ const data = this.dataManager.getInternalData()
341
+ this.evaluateAlerts(data, this.dataManager.lastVisibleRange)
342
+ })
528
343
 
529
- /**
530
- * 更新配置并触发布局/重绘
531
- * @param partial 部分配置项
532
- */
533
- updateOptions(partial: Partial<ChartOptions>) {
534
- // 缩放参数由 zoomLevel 派生,不允许直接修改
535
- if (partial.kWidth !== undefined) {
536
- console.warn('[Chart] kWidth cannot be set directly. Use applyRenderState() instead.')
537
- delete partial.kWidth
538
- }
539
- if (partial.kGap !== undefined) {
540
- delete partial.kGap
344
+ // 初始化渲染器
345
+ this.renderer = new ChartRenderer({
346
+ getDom: () => this.dom,
347
+ getOption: () => this.opt,
348
+ getPaneRenderers: () => this.paneRenderers,
349
+ getInteraction: () => this.interaction,
350
+ getSharedWebGLSurface: () => this.sharedWebGLSurface,
351
+ getPluginHost: () => this.pluginHost,
352
+ getRendererPluginManager: () => this.rendererPluginManager,
353
+ getTheme: () => this._themeSignal.peek(),
354
+ getCurrentZoomLevel: () => this.zoomController.currentZoomLevel,
355
+ getZoomLevelCount: () => this.zoomController.zoomLevelCount,
356
+ getViewportManager: () => this.viewportManager,
357
+ getDataManager: () => this.dataManager,
358
+ getIndicatorManager: () => this.indicatorManager,
359
+ getActiveMode: () => this._activeMode,
360
+ })
361
+ this.renderer.registerDrawingPlugins()
362
+ this.renderer.initCoreRenderers()
363
+ this.viewportManager.init()
364
+ }
365
+
366
+ getViewport(): Viewport | null {
367
+ return this.viewportManager.getViewport()
368
+ }
369
+
370
+ /** 获取当前活跃的模式处理器 */
371
+ get activeMode(): ChartModeHandler {
372
+ return this._activeMode
373
+ }
374
+
375
+ /** 切换模式处理器 */
376
+ setActiveMode(mode: ChartModeHandler): void {
377
+ if (this._activeMode === mode) return
378
+ const prev = this._activeMode
379
+
380
+ if (mode === this._timeShareMode) {
381
+ this._modeSavedKWidth = this.opt.kWidth
382
+ this._modeSavedKGap = this.opt.kGap
383
+ this._modeSavedZoomLevel = this.zoomController.currentZoomLevel
384
+ this._savedScaleTypes = new Map<string, ScaleType>()
385
+ for (const r of this.paneRenderers) {
386
+ this._savedScaleTypes.set(r.getPane().id, r.getPane().yAxis.getScaleType())
387
+ }
388
+ } else if (prev === this._timeShareMode) {
389
+ for (const renderer of this.paneRenderers) {
390
+ const p = renderer.getPane()
391
+ const saved = this._savedScaleTypes?.get(p.id) ?? 'linear'
392
+ p.yAxis.setScaleType(saved)
393
+ p.yAxis.setBasePrice(null)
394
+ }
395
+ this._savedScaleTypes = undefined
396
+ }
397
+
398
+ if (this._modeSavedKWidth > 0 && mode !== this._timeShareMode) {
399
+ this.applyRenderState(this._modeSavedKWidth, this._modeSavedKGap, this._modeSavedZoomLevel)
400
+ this._modeSavedKWidth = 0
401
+ }
402
+
403
+ prev.onDeactivate(
404
+ {
405
+ enableMainIndicator: (id, p) => this.enableMainIndicator(id, p),
406
+ disableMainIndicator: (id) => this.disableMainIndicator(id),
407
+ setRendererEnabled: (n, e) => this.setRendererEnabled(n, e),
408
+ dataManager: this.dataManager,
409
+ },
410
+ mode,
411
+ )
412
+ this._activeMode = mode
413
+ this._activeMode.onActivate(
414
+ {
415
+ enableMainIndicator: (id, p) => this.enableMainIndicator(id, p),
416
+ disableMainIndicator: (id) => this.disableMainIndicator(id),
417
+ setRendererEnabled: (n, e) => this.setRendererEnabled(n, e),
418
+ dataManager: this.dataManager,
419
+ currentPeriod: this.dataManager.currentPeriod,
420
+ },
421
+ prev,
422
+ )
423
+ }
424
+
425
+ getCurrentDpr(): number {
426
+ return this.viewportManager.getEffectiveDpr()
427
+ }
428
+
429
+ /** 获取当前周期 */
430
+ get currentPeriod(): string {
431
+ return this.dataManager.currentPeriod
432
+ }
433
+
434
+ /** 获取缓存的 scrollLeft(避免读取 DOM 触发强制回流) */
435
+ getCachedScrollLeft(): number {
436
+ return this.viewportManager.getCachedScrollLeft()
437
+ }
438
+
439
+ /** 同步程序性 scrollLeft 写入后的缓存,避免等待异步 scroll 事件 */
440
+ syncScrollLeft(scrollLeft: number): void {
441
+ this.viewportManager.setScrollLeft(scrollLeft)
442
+ }
443
+
444
+ setScrollLeft(v: number): void {
445
+ this.viewportManager.setScrollLeft(v)
446
+ }
447
+
448
+ /** 获取逻辑 scrollLeft(减去左侧加载缓冲宽度,可为负值) */
449
+ getLogicalScrollLeft(): number {
450
+ return this.viewportManager.getLogicalScrollLeft()
451
+ }
452
+
453
+ /** 获取插件宿主 */
454
+ get plugin(): PluginHostImpl {
455
+ return this.pluginHost
456
+ }
457
+
458
+ // ========== 渲染器插件 API ==========
459
+
460
+ /** 安装渲染器插件 */
461
+ useRenderer(
462
+ plugin: RendererPlugin | RendererPluginWithHost,
463
+ config?: Record<string, unknown>,
464
+ ): void {
465
+ this.rendererPluginManager.register(plugin)
466
+ if (config && plugin.setConfig) {
467
+ plugin.setConfig(config)
468
+ }
469
+ }
470
+
471
+ /** 移除渲染器插件 */
472
+ removeRenderer(name: string): void {
473
+ this.rendererPluginManager.unregister(name)
474
+ }
475
+
476
+ /** 获取渲染器插件 */
477
+ getRenderer<T extends RendererPlugin = RendererPlugin>(name: string): T | undefined {
478
+ return this.rendererPluginManager.getPlugin<T>(name)
479
+ }
480
+
481
+ /** 更新渲染器配置(自动重绘) */
482
+ updateRendererConfig(name: string, config: Record<string, unknown>): void {
483
+ this.rendererPluginManager.updateConfig(name, config)
484
+ }
485
+
486
+ /** 启用/禁用渲染器 */
487
+ setRendererEnabled(name: string, enabled: boolean): void {
488
+ this.rendererPluginManager.setEnabled(name, enabled)
489
+ }
490
+
491
+ /** 获取所有渲染器 */
492
+ getAllRenderers(): RendererPlugin[] {
493
+ return this.rendererPluginManager.getAllPlugins()
494
+ }
495
+
496
+ /** 更新用户设置(触发重绘) */
497
+ updateSettings(settings: ChartSettings): void {
498
+ this.renderer.updateSettings(settings)
499
+ this.interaction.updateSettings(settings)
500
+
501
+ // 同步右轴刻度类型设置到所有 pane(百分比仅用于主图)
502
+ if ('rightAxisType' in settings) {
503
+ const axisType = settings.rightAxisType as string
504
+ if (axisType !== 'none') {
505
+ for (const renderer of this.paneRenderers) {
506
+ const pane = renderer.getPane()
507
+ const scaleType =
508
+ axisType === 'percent' && pane.role !== 'price' ? 'linear' : (axisType as ScaleType)
509
+ pane.yAxis.setScaleType(scaleType)
541
510
  }
542
-
543
- if (partial.panes) {
544
- const nextPanes = partial.panes.map((pane) => ({ ...pane }))
545
- this.opt = { ...this.opt, ...partial, panes: nextPanes }
546
- this.layoutManager.applyPaneLayoutSpecs(nextPanes)
547
- return
511
+ }
512
+ }
513
+
514
+ this.scheduleDraw()
515
+ }
516
+
517
+ /**
518
+ * 绘制一帧
519
+ * @param level 更新级别,决定渲染哪些层
520
+ */
521
+ draw(level: UpdateLevel = UpdateLevel.All) {
522
+ this.renderer.draw(level)
523
+ }
524
+
525
+ // ========== Render State API (Vue SSOT) ==========
526
+
527
+ /**
528
+ * 应用渲染状态(由 Vue/Store 层在状态更新后调用)
529
+ * Chart 不拥有业务 SSOT,只负责接收参数并渲染
530
+ * 这是写入 opt.kWidth/kGap 和 currentZoomLevel 的唯一入口
531
+ */
532
+ applyRenderState(kWidth: number, kGap: number, zoomLevel?: number): void {
533
+ const nextZoomLevel =
534
+ zoomLevel !== undefined
535
+ ? Math.max(1, Math.min(this.zoomController.zoomLevelCount, zoomLevel))
536
+ : this.zoomController.currentZoomLevel
537
+ const renderStateChanged =
538
+ this.opt.kWidth !== kWidth ||
539
+ this.opt.kGap !== kGap ||
540
+ this.zoomController.currentZoomLevel !== nextZoomLevel
541
+
542
+ if (!renderStateChanged) {
543
+ return
544
+ }
545
+
546
+ this.opt = { ...this.opt, kWidth, kGap }
547
+ if (zoomLevel !== undefined) {
548
+ this.zoomController.setZoomLevel(nextZoomLevel)
549
+ }
550
+ this.updateViewportSignal()
551
+ this.scheduleDraw()
552
+ }
553
+
554
+ /** 获取总缩放级别数 */
555
+ getZoomLevelCount(): number {
556
+ return this.zoomController.zoomLevelCount
557
+ }
558
+
559
+ /** 获取所有 PaneRenderer */
560
+ getPaneRenderers(): PaneRenderer[] {
561
+ return this.paneRenderers
562
+ }
563
+
564
+ /** 获取 MarkerManager(供 InteractionController 使用) */
565
+ getMarkerManager(): MarkerManager {
566
+ return this.renderer.getMarkerManager()
567
+ }
568
+
569
+ /** 更新自定义标记 */
570
+ updateCustomMarkers(markers: CustomMarkerEntity[]): void {
571
+ this.renderer.getMarkerManager().setCustomMarkers(markers)
572
+ this.scheduleDraw()
573
+ }
574
+
575
+ /** 清除自定义标记 */
576
+ clearCustomMarkers(): void {
577
+ this.renderer.getMarkerManager().clearCustomMarkers()
578
+ this.scheduleDraw()
579
+ }
580
+
581
+ /** 获取 ChartDom(供 InteractionController 使用) */
582
+ getDom() {
583
+ return this.dom
584
+ }
585
+
586
+ /** 获取当前 ChartOptions(返回内部当前快照) */
587
+ getOption() {
588
+ return this.opt
589
+ }
590
+
591
+ /**
592
+ * 更新配置并触发布局/重绘
593
+ * @param partial 部分配置项
594
+ */
595
+ updateOptions(partial: Partial<ChartOptions>) {
596
+ // 缩放参数由 zoomLevel 派生,不允许直接修改
597
+ if (partial.kWidth !== undefined) {
598
+ console.warn('[Chart] kWidth cannot be set directly. Use applyRenderState() instead.')
599
+ delete partial.kWidth
600
+ }
601
+ if (partial.kGap !== undefined) {
602
+ delete partial.kGap
603
+ }
604
+
605
+ if (partial.panes) {
606
+ const nextPanes = partial.panes.map((pane) => ({ ...pane }))
607
+ this.opt = { ...this.opt, ...partial, panes: nextPanes }
608
+ this.layoutManager.applyPaneLayoutSpecs(nextPanes)
609
+ return
610
+ }
611
+
612
+ this.opt = { ...this.opt, ...partial }
613
+ this.resize()
614
+ }
615
+
616
+ updatePaneLayout(panes: PaneSpec[]): void {
617
+ this.layoutManager.updatePaneLayout(panes)
618
+ }
619
+
620
+ setPaneDefinitions(defs: PaneSpec[]): void {
621
+ this.layoutManager.setPaneDefinitions(defs)
622
+ }
623
+
624
+ upsertPane(def: PaneSpec): void {
625
+ this.layoutManager.upsertPane(def)
626
+ }
627
+
628
+ removePaneDefinition(paneId: string): void {
629
+ this.layoutManager.removePaneDefinition(paneId)
630
+ }
631
+
632
+ bindIndicatorToPane(
633
+ paneId: string,
634
+ indicatorId: SubIndicatorType,
635
+ params?: Record<string, number | boolean | string>,
636
+ ): void {
637
+ this.indicatorManager.bindIndicatorToPane(paneId, indicatorId, params)
638
+ }
639
+
640
+ /** 更新绘图对象 */
641
+ setDrawings(drawings: import('../plugin').DrawingObject[]): void {
642
+ this.renderer.getDrawingStore().setAll(drawings)
643
+ this._drawingsSignal.set(drawings)
644
+ this.scheduleDraw()
645
+ }
646
+
647
+ /** 更新选中的绘图 ID */
648
+ setSelectedDrawingId(id: string | null): void {
649
+ const store = this.renderer.getDrawingStore()
650
+ if (store.getSelectedId() === id) return
651
+ store.setSelectedId(id)
652
+ this.scheduleDraw()
653
+ }
654
+
655
+ getPaneLayoutSpecs(): PaneSpec[] {
656
+ return this.layoutManager.getPaneLayoutSpecs()
657
+ }
658
+
659
+ resizePaneBoundary(upperPaneId: string, deltaY: number): boolean {
660
+ return this.layoutManager.resizePaneBoundary(upperPaneId, deltaY)
661
+ }
662
+
663
+ addPane(paneId: string): void {
664
+ this.layoutManager.addPane(paneId)
665
+ }
666
+
667
+ removePane(paneId: string): void {
668
+ this.layoutManager.removePane(paneId)
669
+ }
670
+
671
+ hasPane(paneId: string): boolean {
672
+ return this.layoutManager.hasPane(paneId)
673
+ }
674
+
675
+ // ========== 副图管理 API ==========
676
+
677
+ createSubPane(
678
+ paneId: string,
679
+ indicatorId: SubIndicatorType,
680
+ params?: Record<string, number | boolean | string>,
681
+ ): boolean {
682
+ return this.indicatorManager.createSubPane(paneId, indicatorId, params)
683
+ }
684
+
685
+ removeSubPane(paneId: string): void {
686
+ this.indicatorManager.removeSubPane(paneId)
687
+ }
688
+
689
+ replaceSubPaneIndicator(
690
+ paneId: string,
691
+ newIndicatorId: SubIndicatorType,
692
+ params?: Record<string, number | boolean | string>,
693
+ ): void {
694
+ this.indicatorManager.replaceSubPaneIndicator(paneId, newIndicatorId, params)
695
+ }
696
+
697
+ updateSubPaneParams(paneId: string, params: Record<string, unknown>): void {
698
+ this.indicatorManager.updateSubPaneParams(paneId, params)
699
+ }
700
+
701
+ clearSubPanes(): void {
702
+ this.indicatorManager.clearSubPanes()
703
+ }
704
+
705
+ getSubPaneIndicators(): SubIndicatorType[] {
706
+ return this.indicatorManager.getSubPaneIndicators()
707
+ }
708
+
709
+ getSubPaneEntries(): SubPaneEntry[] {
710
+ return this.indicatorManager.getSubPaneEntries()
711
+ }
712
+
713
+ getSubPaneEntry(paneId: string): SubPaneEntry | undefined {
714
+ return this.indicatorManager.getSubPaneEntry(paneId)
715
+ }
716
+
717
+ /**
718
+ * 平移价格轴(用于主图区域上下拖动)
719
+ * @param paneId 目标 pane ID
720
+ * @param deltaY Y轴像素偏移(正数向下拖动)
721
+ */
722
+ translatePrice(paneId: string, deltaY: number): void {
723
+ const renderer = this.paneRenderers.find((r) => r.getPane().id === paneId)
724
+ if (!renderer) return
725
+
726
+ const pane = renderer.getPane()
727
+ if (!pane.capabilities.supportsPriceTranslate) return
728
+
729
+ const priceOffset = pane.yAxis.deltaYToPriceOffset(deltaY)
730
+ const currentOffset = pane.yAxis.getPriceOffset()
731
+ pane.yAxis.setPriceOffset(currentOffset + priceOffset)
732
+ this.scheduleDraw()
733
+ }
734
+
735
+ /**
736
+ * 重置价格轴垂直偏移
737
+ * @param paneId 目标 pane ID
738
+ */
739
+ resetPriceOffset(paneId: string): void {
740
+ const renderer = this.paneRenderers.find((r) => r.getPane().id === paneId)
741
+ if (!renderer) return
742
+ renderer.getPane().yAxis.resetPriceOffset()
743
+ this.scheduleDraw()
744
+ }
745
+
746
+ resetPriceTransform(paneId: string): void {
747
+ const renderer = this.paneRenderers.find((r) => r.getPane().id === paneId)
748
+ if (!renderer) return
749
+ renderer.getPane().yAxis.resetTransform()
750
+ this.scheduleDraw()
751
+ }
752
+
753
+ /**
754
+ * 缩放价格轴(用于右侧刻度栏上下拖动)
755
+ * @param paneId 目标 pane ID
756
+ * @param deltaY Y轴像素偏移(向上拖动放大,向下拖动缩小)
757
+ */
758
+ scalePrice(paneId: string, deltaY: number): void {
759
+ const renderer = this.paneRenderers.find((r) => r.getPane().id === paneId)
760
+ if (!renderer) return
761
+
762
+ const pane = renderer.getPane()
763
+ if (!pane.capabilities.supportsPriceTranslate) return
764
+
765
+ pane.yAxis.scaleByDelta(deltaY)
766
+ this.scheduleDraw()
767
+ }
768
+ /**
769
+ * 更新数据并请求重绘
770
+ * @param data K 线数据数组
771
+ */
772
+ updateData(data: KLineData[]) {
773
+ this.dataManager.updateData(data)
774
+ }
775
+
776
+ /** 获取当前数据源(供 renderers 和 interaction 使用) */
777
+ getData(): KLineData[] {
778
+ return this.dataManager.getData()
779
+ }
780
+
781
+ /** 获取渲染数据源(分时图下为 TimeShareData,K线图为 KLineData) */
782
+ getRenderData(): unknown[] {
783
+ return this.dataManager.getRenderData()
784
+ }
785
+
786
+ /** 获取指标调度器(供外部控制器更新指标配置) */
787
+ getIndicatorScheduler(): IndicatorScheduler {
788
+ return this.indicatorManager.indicatorSchedulerAccessor
789
+ }
790
+
791
+ /** 获取预警控制器 */
792
+ getAlertController(): AlertController {
793
+ return this.alertController
794
+ }
795
+
796
+ /** 数据就绪时触发预警评估 */
797
+ private evaluateAlerts(data: KLineData[], range: VisibleRange): void {
798
+ const latest = data[data.length - 1]
799
+ if (!latest) return
800
+ // 去重:同一根 K 线只评估一次(增量加载/Worker 重复回调时跳过)
801
+ if (latest.timestamp === this._lastAlertTimestamp) return
802
+ this._lastAlertTimestamp = latest.timestamp
803
+
804
+ // 推进滚动量滑窗(仅在新 K 线到达时)
805
+ let lookbacks = this._volumeLookbacks
806
+ if (!lookbacks) {
807
+ lookbacks = createVolumeLookbacks([5, 10, 20, 60])
808
+ this._volumeLookbacks = lookbacks
809
+ }
810
+ pushToVolumeLookbacks(lookbacks, latest.volume ?? 0)
811
+
812
+ const snapshot = this.buildMarketSnapshot(data)
813
+ if (!snapshot) return
814
+ const events = this.alertController.evaluate(snapshot, Date.now())
815
+ if (events.length > 0) {
816
+ console.log('[Alerts] fired:', events)
817
+ }
818
+ }
819
+
820
+ /** 构建预警引擎所需的当前市场快照 */
821
+ private buildMarketSnapshot(data: KLineData[]): MarketSnapshot | null {
822
+ const latest = data[data.length - 1]
823
+ if (!latest) return null
824
+
825
+ if (latest.volume === undefined) return null
826
+
827
+ const bar = {
828
+ timestamp: latest.timestamp,
829
+ open: latest.open,
830
+ high: latest.high,
831
+ low: latest.low,
832
+ close: latest.close,
833
+ volume: latest.volume,
834
+ }
835
+
836
+ const indicators: Record<string, number> = {}
837
+ const scheduler = this.getIndicatorScheduler()
838
+ for (const meta of scheduler.getAllIndicators()) {
839
+ const paneId = meta.defaultPaneId === 'main' ? 'main' : meta.defaultPaneId
840
+ const stateKey = resolveStateKey(meta.stateKey, paneId)
841
+ const state = this.pluginHost.getSharedState<any>(stateKey)
842
+ if (!state?.series) continue
843
+ const series = state.series
844
+ if (Array.isArray(series)) {
845
+ const val = series[series.length - 1]
846
+ if (typeof val === 'number' && Number.isFinite(val)) {
847
+ indicators[meta.name] = val
548
848
  }
549
-
550
- this.opt = { ...this.opt, ...partial }
551
- this.resize()
552
- }
553
-
554
- updatePaneLayout(panes: PaneSpec[]): void {
555
- this.layoutManager.updatePaneLayout(panes)
556
- }
557
-
558
- setPaneDefinitions(defs: PaneSpec[]): void {
559
- this.layoutManager.setPaneDefinitions(defs)
560
- }
561
-
562
- upsertPane(def: PaneSpec): void {
563
- this.layoutManager.upsertPane(def)
564
- }
565
-
566
- removePaneDefinition(paneId: string): void {
567
- this.layoutManager.removePaneDefinition(paneId)
568
- }
569
-
570
- bindIndicatorToPane(paneId: string, indicatorId: SubIndicatorType, params?: Record<string, number | boolean | string>): void {
571
- this.indicatorManager.bindIndicatorToPane(paneId, indicatorId, params)
572
- }
573
-
574
- /** 更新绘图对象 */
575
- setDrawings(drawings: import('../plugin').DrawingObject[]): void {
576
- this.renderer.getDrawingStore().setAll(drawings)
577
- this._drawingsSignal.set(drawings)
578
- this.scheduleDraw()
579
- }
580
-
581
- /** 更新选中的绘图 ID */
582
- setSelectedDrawingId(id: string | null): void {
583
- const store = this.renderer.getDrawingStore()
584
- if (store.getSelectedId() === id) return
585
- store.setSelectedId(id)
586
- this.scheduleDraw()
587
- }
588
-
589
- getPaneLayoutSpecs(): PaneSpec[] {
590
- return this.layoutManager.getPaneLayoutSpecs()
591
- }
592
-
593
- resizePaneBoundary(upperPaneId: string, deltaY: number): boolean {
594
- return this.layoutManager.resizePaneBoundary(upperPaneId, deltaY)
595
- }
596
-
597
- addPane(paneId: string): void {
598
- this.layoutManager.addPane(paneId)
599
- }
600
-
601
- removePane(paneId: string): void {
602
- this.layoutManager.removePane(paneId)
603
- }
604
-
605
- hasPane(paneId: string): boolean {
606
- return this.layoutManager.hasPane(paneId)
607
- }
608
-
609
- // ========== 副图管理 API ==========
610
-
611
- createSubPane(paneId: string, indicatorId: SubIndicatorType, params?: Record<string, number | boolean | string>): boolean {
612
- return this.indicatorManager.createSubPane(paneId, indicatorId, params)
613
- }
614
-
615
- removeSubPane(paneId: string): void {
616
- this.indicatorManager.removeSubPane(paneId)
617
- }
618
-
619
- replaceSubPaneIndicator(paneId: string, newIndicatorId: SubIndicatorType, params?: Record<string, number | boolean | string>): void {
620
- this.indicatorManager.replaceSubPaneIndicator(paneId, newIndicatorId, params)
621
- }
622
-
623
- updateSubPaneParams(paneId: string, params: Record<string, unknown>): void {
624
- this.indicatorManager.updateSubPaneParams(paneId, params)
625
- }
626
-
627
- clearSubPanes(): void {
628
- this.indicatorManager.clearSubPanes()
629
- }
630
-
631
- getSubPaneIndicators(): SubIndicatorType[] {
632
- return this.indicatorManager.getSubPaneIndicators()
633
- }
634
-
635
- getSubPaneEntries(): SubPaneEntry[] {
636
- return this.indicatorManager.getSubPaneEntries()
637
- }
638
-
639
- getSubPaneEntry(paneId: string): SubPaneEntry | undefined {
640
- return this.indicatorManager.getSubPaneEntry(paneId)
641
- }
642
-
643
-
644
-
645
- /**
646
- * 平移价格轴(用于主图区域上下拖动)
647
- * @param paneId 目标 pane ID
648
- * @param deltaY Y轴像素偏移(正数向下拖动)
649
- */
650
- translatePrice(paneId: string, deltaY: number): void {
651
- const renderer = this.paneRenderers.find(r => r.getPane().id === paneId)
652
- if (!renderer) return
653
-
654
- const pane = renderer.getPane()
655
- if (!pane.capabilities.supportsPriceTranslate) return
656
-
657
- const priceOffset = pane.yAxis.deltaYToPriceOffset(deltaY)
658
- const currentOffset = pane.yAxis.getPriceOffset()
659
- pane.yAxis.setPriceOffset(currentOffset + priceOffset)
660
- this.scheduleDraw()
661
- }
662
-
663
- /**
664
- * 重置价格轴垂直偏移
665
- * @param paneId 目标 pane ID
666
- */
667
- resetPriceOffset(paneId: string): void {
668
- const renderer = this.paneRenderers.find(r => r.getPane().id === paneId)
669
- if (!renderer) return
670
- renderer.getPane().yAxis.resetPriceOffset()
671
- this.scheduleDraw()
672
- }
673
-
674
- resetPriceTransform(paneId: string): void {
675
- const renderer = this.paneRenderers.find(r => r.getPane().id === paneId)
676
- if (!renderer) return
677
- renderer.getPane().yAxis.resetTransform()
678
- this.scheduleDraw()
679
- }
680
-
681
- /**
682
- * 缩放价格轴(用于右侧刻度栏上下拖动)
683
- * @param paneId 目标 pane ID
684
- * @param deltaY Y轴像素偏移(向上拖动放大,向下拖动缩小)
685
- */
686
- scalePrice(paneId: string, deltaY: number): void {
687
- const renderer = this.paneRenderers.find(r => r.getPane().id === paneId)
688
- if (!renderer) return
689
-
690
- const pane = renderer.getPane()
691
- if (!pane.capabilities.supportsPriceTranslate) return
692
-
693
- pane.yAxis.scaleByDelta(deltaY)
694
- this.scheduleDraw()
695
- }
696
- /**
697
- * 更新数据并请求重绘
698
- * @param data K 线数据数组
699
- */
700
- updateData(data: KLineData[]) {
701
- this.dataManager.updateData(data)
702
- }
703
-
704
- /** 获取当前数据源(供 renderers 和 interaction 使用) */
705
- getData(): KLineData[] {
706
- return this.dataManager.getData()
707
- }
708
-
709
- /** 获取渲染数据源(分时图下为 TimeShareData,K线图为 KLineData) */
710
- getRenderData(): unknown[] {
711
- return this.dataManager.getRenderData()
712
- }
713
-
714
- /** 获取指标调度器(供外部控制器更新指标配置) */
715
- getIndicatorScheduler(): IndicatorScheduler {
716
- return this.indicatorManager.indicatorSchedulerAccessor
717
- }
718
-
719
- /** 获取预警控制器 */
720
- getAlertController(): AlertController {
721
- return this.alertController
722
- }
723
-
724
- /** 数据就绪时触发预警评估 */
725
- private evaluateAlerts(data: KLineData[], range: VisibleRange): void {
726
- const latest = data[data.length - 1]
727
- if (!latest) return
728
- // 去重:同一根 K 线只评估一次(增量加载/Worker 重复回调时跳过)
729
- if (latest.timestamp === this._lastAlertTimestamp) return
730
- this._lastAlertTimestamp = latest.timestamp
731
-
732
- // 推进滚动量滑窗(仅在新 K 线到达时)
733
- let lookbacks = this._volumeLookbacks
734
- if (!lookbacks) {
735
- lookbacks = createVolumeLookbacks([5, 10, 20, 60])
736
- this._volumeLookbacks = lookbacks
849
+ } else if (typeof series === 'object') {
850
+ const keys = Object.keys(series)
851
+ if (keys.length > 0) {
852
+ const lastKey = keys[keys.length - 1]!
853
+ const arr = series[lastKey]
854
+ if (Array.isArray(arr)) {
855
+ const val = arr[arr.length - 1]
856
+ if (typeof val === 'number' && Number.isFinite(val)) {
857
+ indicators[meta.name] = val
858
+ }
859
+ }
737
860
  }
738
- pushToVolumeLookbacks(lookbacks, latest.volume ?? 0)
739
-
740
- const snapshot = this.buildMarketSnapshot(data)
741
- if (!snapshot) return
742
- const events = this.alertController.evaluate(snapshot, Date.now())
743
- if (events.length > 0) {
744
- console.log('[Alerts] fired:', events)
861
+ }
862
+ }
863
+
864
+ // 只读滚动量(由 evaluateAlerts 推进滑窗)
865
+ const rollingVolume: Record<number, number> = {}
866
+ if (this._volumeLookbacks) {
867
+ for (const [size, calc] of this._volumeLookbacks) {
868
+ rollingVolume[size] = calc.mean
869
+ }
870
+ }
871
+
872
+ return {
873
+ bar,
874
+ indicators,
875
+ rollingVolume,
876
+ volumeProfile: undefined,
877
+ orderBook: undefined,
878
+ footprint: undefined,
879
+ }
880
+ }
881
+
882
+ getLogicalSlotCount(): number {
883
+ return this.dataManager.getLogicalSlotCount()
884
+ }
885
+
886
+ getTimestampAtLogicalIndex(index: number): number | null {
887
+ return this.dataManager.getTimestampAtLogicalIndex(index)
888
+ }
889
+
890
+ /** 根据视口内 X 坐标反查逻辑索引(允许超出最后一根 K 线) */
891
+ getLogicalIndexAtX(mouseX: number): number | null {
892
+ return this.dataManager.getLogicalIndexAtX(mouseX)
893
+ }
894
+
895
+ /** 根据视口内 X 坐标反查数据索引(用于绘图落点) */
896
+ getDataIndexAtX(mouseX: number): number | null {
897
+ return this.dataManager.getDataIndexAtX(mouseX)
898
+ }
899
+
900
+ /** 获取内容总宽度(用于外部 scroll-content 撑开 scrollWidth) */
901
+ getContentWidth(): number {
902
+ return this.dataManager.getContentWidth()
903
+ }
904
+
905
+ /** 获取左侧加载缓冲宽度(视口宽度,用于计算 overlay 像素偏移) */
906
+ getLeftLoadBufferWidth(): number {
907
+ return this.dataManager.getLeftLoadBufferWidth()
908
+ }
909
+
910
+ /** 滚动到最右侧(最新数据位置) */
911
+ scrollToRight(): void {
912
+ this.dataManager.scrollToRight()
913
+ }
914
+
915
+ /** 容器尺寸变化时调用 */
916
+ resize() {
917
+ if (this._activeMode.debugName === 'TimeShare') {
918
+ const tsData = this.dataManager.getTimeShareData()
919
+ const vp = this.viewportManager.computeViewport()
920
+ if (!vp || vp.plotWidth <= 0) return
921
+ if (tsData.length > 0) {
922
+ const result = this._activeMode.computeKWidth(tsData.length, vp.plotWidth, vp.dpr)
923
+ if (result) {
924
+ this.applyRenderState(result.kWidth, result.kGap)
925
+ const container = this.dom.container
926
+ if (container) {
927
+ const leftBuffer = this.dataManager.getLeftLoadBufferWidth()
928
+ this.viewportManager.setScrollLeft(leftBuffer)
929
+ this.viewportManager.applyPendingScrollLeft(container)
930
+ }
745
931
  }
746
- }
747
-
748
- /** 构建预警引擎所需的当前市场快照 */
749
- private buildMarketSnapshot(data: KLineData[]): MarketSnapshot | null {
750
- const latest = data[data.length - 1]
751
- if (!latest) return null
752
-
753
- if (latest.volume === undefined) return null
754
-
755
- const bar = {
756
- timestamp: latest.timestamp,
757
- open: latest.open,
758
- high: latest.high,
759
- low: latest.low,
760
- close: latest.close,
761
- volume: latest.volume,
932
+ }
933
+ this.renderer.clearCachedFrame()
934
+ this.layoutManager.layoutPanes()
935
+ this.viewportManager.updateViewportSignal()
936
+ this.scheduleDraw()
937
+ return
938
+ }
939
+ const vp = this.viewportManager.computeViewport()
940
+ // 防御性检查:容器尺寸无效时跳过布局
941
+ if (!vp || vp.viewWidth < 10 || vp.viewHeight < 10) {
942
+ return
943
+ }
944
+ this.renderer.clearCachedFrame()
945
+ this.layoutManager.layoutPanes()
946
+ this.viewportManager.updateViewportSignal()
947
+ this.scheduleDraw()
948
+ }
949
+
950
+ /**
951
+ * 请求下一帧重绘(RAF 合并,支持分层更新)
952
+ * @param level 更新级别,默认为 All
953
+ */
954
+ scheduleDraw(level: UpdateLevel = UpdateLevel.All): void {
955
+ this.renderer.scheduleDraw(level)
956
+ }
957
+
958
+ /** 销毁图表实例 */
959
+ async destroy() {
960
+ this.renderer.destroy()
961
+ this.dataManager.destroy()
962
+ this.viewportManager.destroy()
963
+ this.layoutManager.destroy()
964
+ this.sharedWebGLSurface.destroy()
965
+ this.indicatorManager.destroy()
966
+ this.alertController.dispose()
967
+ await this.pluginHost.destroy()
968
+ }
969
+
970
+ private computeViewport(): Viewport | null {
971
+ return this.viewportManager.computeViewport()
972
+ }
973
+
974
+ // ==================== Facade API (High-level interface for adapters) ====================
975
+
976
+ private _themeSignal = createSignal<'light' | 'dark'>('light')
977
+ private _drawingToolSignal = createSignal<DrawingToolType | null>(null)
978
+ private _drawingsSignal = createSignal<ReadonlyArray<import('../plugin').DrawingObject>>([])
979
+ private _paneRatiosSignal = createSignal<Readonly<Record<string, number>>>({})
980
+ private _paneLayoutSignal = createSignal<PaneSpec[]>([])
981
+ private _interactionSignal = createSignal<InteractionSnapshot>({
982
+ crosshairPos: null,
983
+ crosshairIndex: null,
984
+ crosshairPrice: null,
985
+ hoveredIndex: null,
986
+ activePaneId: null,
987
+ tooltipPos: { x: 0, y: 0 },
988
+ tooltipAnchorPlacement: 'right-bottom',
989
+ hoveredMarkerData: null,
990
+ hoveredCustomMarker: null,
991
+ isDragging: false,
992
+ isResizingPaneBoundary: false,
993
+ isHoveringPaneBoundary: false,
994
+ hoveredPaneBoundaryId: null,
995
+ isHoveringRightAxis: false,
996
+ })
997
+
998
+ /** 视口状态信号 */
999
+ get viewport(): Signal<ViewportState> {
1000
+ return this.viewportManager.viewportSignal
1001
+ }
1002
+
1003
+ /** 数据信号 */
1004
+ get data(): Signal<ReadonlyArray<KLineData>> {
1005
+ return this.dataManager.data
1006
+ }
1007
+
1008
+ /** 加载信号 */
1009
+ get loading(): Signal<boolean> {
1010
+ return this.dataManager.loading
1011
+ }
1012
+
1013
+ /** 符号信号 */
1014
+ get symbols(): Signal<ReadonlyArray<SymbolSpec>> {
1015
+ return this.dataManager.symbols
1016
+ }
1017
+
1018
+ /** 可用品种目录信号 — 供 UI 品种选择器消费 */
1019
+ get symbolCatalog(): Signal<ReadonlyArray<SymbolInfo>> {
1020
+ return this.dataManager.symbolCatalog
1021
+ }
1022
+
1023
+ /** 注册品种到可用目录 */
1024
+ registerSymbols(infos: ReadonlyArray<SymbolInfo>): void {
1025
+ this.dataManager.registerSymbols(infos)
1026
+ }
1027
+
1028
+ /** 比较商品颜色信号 */
1029
+ get comparisonColors(): Signal<ReadonlyMap<string, string>> {
1030
+ return this.dataManager.comparisonColors
1031
+ }
1032
+
1033
+ /** 比较商品加载信号 */
1034
+ get comparisonLoading(): Signal<boolean> {
1035
+ return this.dataManager.comparisonLoading
1036
+ }
1037
+
1038
+ /** 主题信号 */
1039
+ get theme(): Signal<'light' | 'dark'> {
1040
+ return this._themeSignal
1041
+ }
1042
+
1043
+ /** 指标实例列表信号(派生信号,自动随主/副图状态更新) */
1044
+ get indicators(): Computed<ReadonlyArray<IndicatorInstance>> {
1045
+ return this.indicatorManager.indicatorsComputed
1046
+ }
1047
+
1048
+ /** 子图信息信号(派生信号,自动随副图条目/比例更新) */
1049
+ get subPanes(): Computed<ReadonlyArray<SubPaneInfo>> {
1050
+ return this.indicatorManager.subPanesComputed
1051
+ }
1052
+
1053
+ /** 当前绘图工具信号 */
1054
+ get drawingTool(): Signal<DrawingToolType | null> {
1055
+ return this._drawingToolSignal
1056
+ }
1057
+
1058
+ /** 绘图对象列表信号 */
1059
+ get drawings(): Signal<ReadonlyArray<import('../plugin').DrawingObject>> {
1060
+ return this._drawingsSignal
1061
+ }
1062
+
1063
+ /** 面板比例信号 */
1064
+ get paneRatios(): Signal<Readonly<Record<string, number>>> {
1065
+ return this._paneRatiosSignal
1066
+ }
1067
+
1068
+ get paneLayout(): Signal<PaneSpec[]> {
1069
+ return this._paneLayoutSignal
1070
+ }
1071
+
1072
+ /** 交互状态信号 */
1073
+ get interactionState(): Signal<InteractionSnapshot> {
1074
+ return this._interactionSignal
1075
+ }
1076
+
1077
+ // ---------- Data ----------
1078
+
1079
+ setData(data: KLineData[]): void {
1080
+ this.dataManager.setData(data)
1081
+ }
1082
+
1083
+ appendData(newData: KLineData[]): void {
1084
+ this.dataManager.appendData(newData)
1085
+ }
1086
+
1087
+ setDataFetcher(fetcher: import('../controllers/types').DataFetcher | null): void {
1088
+ this.dataManager.setDataFetcher(fetcher)
1089
+ }
1090
+
1091
+ get dataBuffer(): import('../data-fetchers/dataBuffer').DataBuffer {
1092
+ return this.dataManager.dataBuffer
1093
+ }
1094
+
1095
+ checkVisibleRangeGap(): void {
1096
+ this.dataManager.checkVisibleRangeGap()
1097
+ }
1098
+
1099
+ setSymbols(specs: ReadonlyArray<SymbolSpec>): void {
1100
+ // 品种/周期切换时重置最新 K 线时间戳,确保新数据触发预警
1101
+ this._lastAlertTimestamp = null
1102
+ const primaryPeriod = specs[0]?.period
1103
+ if (primaryPeriod) {
1104
+ this.setActiveMode(primaryPeriod === 'timeshare' ? this._timeShareMode : this._kLineMode)
1105
+ }
1106
+ this.dataManager.setSymbols(specs)
1107
+ }
1108
+
1109
+ addComparisonSymbol(spec: SymbolSpec): void {
1110
+ this.dataManager.addComparisonSymbol(spec)
1111
+ }
1112
+
1113
+ removeComparisonSymbol(symbol: string): void {
1114
+ this.dataManager.removeComparisonSymbol(symbol)
1115
+ }
1116
+
1117
+ setComparisonData(symbol: string, data: KLineData[]): void {
1118
+ this.dataManager.setComparisonData(symbol, data)
1119
+ }
1120
+
1121
+ setCurrentSymbol(symbol: string): void {
1122
+ this.dataManager.setCurrentSymbol(symbol)
1123
+ }
1124
+
1125
+ setCurrentPeriod(period: string): void {
1126
+ this.setActiveMode(period === 'timeshare' ? this._timeShareMode : this._kLineMode)
1127
+ this.dataManager.setCurrentPeriod(period)
1128
+ }
1129
+
1130
+ switchToTimeShareForDate(dateYYYYMMDD: number): void {
1131
+ this.dataManager.setTimeShareQueryDate(dateYYYYMMDD)
1132
+ this.setActiveMode(this._timeShareMode)
1133
+ this.dataManager.setCurrentPeriod('timeshare')
1134
+ }
1135
+
1136
+ applyCustomData(source: CustomDataSource): void {
1137
+ this.dataManager.applyCustomData(source)
1138
+ }
1139
+
1140
+ // ---------- Theme ----------
1141
+
1142
+ /**
1143
+ * 设置主题(高层 API)
1144
+ */
1145
+ setTheme(theme: 'light' | 'dark'): void {
1146
+ this._themeSignal.set(theme)
1147
+ this.scheduleDraw()
1148
+ }
1149
+
1150
+ // ---------- Zoom ----------
1151
+
1152
+ /**
1153
+ * 缩放到指定级别(高层 API)
1154
+ * 计算并应用新的 render state,更新 viewport signal
1155
+ */
1156
+ zoomToLevel(level: number, anchorX?: number): void {
1157
+ if (!this._activeMode.allowZoom) return
1158
+ this.zoomController.zoomToLevel(level, anchorX)
1159
+ }
1160
+
1161
+ /**
1162
+ * 放大(高层 API)
1163
+ */
1164
+ zoomIn(anchorX?: number): void {
1165
+ if (!this._activeMode.allowZoom) return
1166
+ this.zoomController.zoomIn(anchorX)
1167
+ }
1168
+
1169
+ /**
1170
+ * 缩小(高层 API)
1171
+ */
1172
+ zoomOut(anchorX?: number): void {
1173
+ if (!this._activeMode.allowZoom) return
1174
+ this.zoomController.zoomOut(anchorX)
1175
+ }
1176
+
1177
+ // ---------- Interaction (Zero-config unified entry) ----------
1178
+
1179
+ /**
1180
+ * 统一指针事件处理(零配置)
1181
+ * 自动判断区域并分发给 interaction controller
1182
+ *
1183
+ * @param e 指针事件
1184
+ * @param drawingController 可选的绘图控制器,如果提供,会优先让绘图控制器处理事件
1185
+ * @returns 是否被处理(如果 drawingController 处理了返回 true,否则返回 false)
1186
+ */
1187
+ handlePointerEvent(
1188
+ e: PointerEvent,
1189
+ drawingController?: {
1190
+ onPointerDown?: (e: PointerEvent, container: HTMLElement) => boolean
1191
+ onPointerMove?: (e: PointerEvent, container: HTMLElement) => boolean
1192
+ onPointerUp?: (e: PointerEvent, container: HTMLElement) => boolean
1193
+ },
1194
+ ): boolean {
1195
+ // 判断事件目标是否在右轴区域
1196
+ const isRightAxis = this.dom.rightAxisLayer.contains(e.target as Node)
1197
+
1198
+ switch (e.type) {
1199
+ case 'pointerdown':
1200
+ // 优先让绘图控制器处理
1201
+ if (drawingController?.onPointerDown) {
1202
+ const handled = drawingController.onPointerDown(e, this.dom.container)
1203
+ if (handled) return true
762
1204
  }
763
-
764
- const indicators: Record<string, number> = {}
765
- const scheduler = this.getIndicatorScheduler()
766
- for (const meta of scheduler.getAllIndicators()) {
767
- const paneId = meta.defaultPaneId === 'main' ? 'main' : meta.defaultPaneId
768
- const stateKey = resolveStateKey(meta.stateKey, paneId)
769
- const state = this.pluginHost.getSharedState<any>(stateKey)
770
- if (!state?.series) continue
771
- const series = state.series
772
- if (Array.isArray(series)) {
773
- const val = series[series.length - 1]
774
- if (typeof val === 'number' && Number.isFinite(val)) {
775
- indicators[meta.name] = val
776
- }
777
- } else if (typeof series === 'object') {
778
- const keys = Object.keys(series)
779
- if (keys.length > 0) {
780
- const lastKey = keys[keys.length - 1]!
781
- const arr = series[lastKey]
782
- if (Array.isArray(arr)) {
783
- const val = arr[arr.length - 1]
784
- if (typeof val === 'number' && Number.isFinite(val)) {
785
- indicators[meta.name] = val
786
- }
787
- }
788
- }
789
- }
1205
+ if (isRightAxis) {
1206
+ this.interaction.onRightAxisPointerDown(e)
1207
+ } else {
1208
+ this.interaction.onPointerDown(e)
790
1209
  }
791
-
792
- // 只读滚动量(由 evaluateAlerts 推进滑窗)
793
- const rollingVolume: Record<number, number> = {}
794
- if (this._volumeLookbacks) {
795
- for (const [size, calc] of this._volumeLookbacks) {
796
- rollingVolume[size] = calc.mean
797
- }
1210
+ return false
1211
+ case 'pointermove':
1212
+ // 优先让绘图控制器处理
1213
+ if (drawingController?.onPointerMove) {
1214
+ const handled = drawingController.onPointerMove(e, this.dom.container)
1215
+ if (handled) return true
798
1216
  }
799
-
800
- return {
801
- bar,
802
- indicators,
803
- rollingVolume,
804
- volumeProfile: undefined,
805
- orderBook: undefined,
806
- footprint: undefined,
1217
+ if (isRightAxis) {
1218
+ this.interaction.onRightAxisPointerMove(e)
1219
+ } else {
1220
+ this.interaction.onPointerMove(e)
807
1221
  }
808
- }
809
-
810
- getLogicalSlotCount(): number {
811
- return this.dataManager.getLogicalSlotCount()
812
- }
813
-
814
- getTimestampAtLogicalIndex(index: number): number | null {
815
- return this.dataManager.getTimestampAtLogicalIndex(index)
816
- }
817
-
818
- /** 根据视口内 X 坐标反查逻辑索引(允许超出最后一根 K 线) */
819
- getLogicalIndexAtX(mouseX: number): number | null {
820
- return this.dataManager.getLogicalIndexAtX(mouseX)
821
- }
822
-
823
- /** 根据视口内 X 坐标反查数据索引(用于绘图落点) */
824
- getDataIndexAtX(mouseX: number): number | null {
825
- return this.dataManager.getDataIndexAtX(mouseX)
826
- }
827
-
828
-
829
- /** 获取内容总宽度(用于外部 scroll-content 撑开 scrollWidth) */
830
- getContentWidth(): number {
831
- return this.dataManager.getContentWidth()
832
- }
833
-
834
- /** 获取左侧加载缓冲宽度(视口宽度,用于计算 overlay 像素偏移) */
835
- getLeftLoadBufferWidth(): number {
836
- return this.dataManager.getLeftLoadBufferWidth()
837
- }
838
-
839
- /** 滚动到最右侧(最新数据位置) */
840
- scrollToRight(): void {
841
- this.dataManager.scrollToRight()
842
- }
843
-
844
- /** 容器尺寸变化时调用 */
845
- resize() {
846
- if (this._activeMode.debugName === 'TimeShare') {
847
- const tsData = this.dataManager.getTimeShareData()
848
- const vp = this.viewportManager.computeViewport()
849
- if (!vp || vp.plotWidth <= 0) return
850
- if (tsData.length > 0) {
851
- const result = this._activeMode.computeKWidth(tsData.length, vp.plotWidth, vp.dpr)
852
- if (result) {
853
- this.applyRenderState(result.kWidth, result.kGap)
854
- const container = this.dom.container
855
- if (container) {
856
- const leftBuffer = this.dataManager.getLeftLoadBufferWidth()
857
- this.viewportManager.setScrollLeft(leftBuffer)
858
- this.viewportManager.applyPendingScrollLeft(container)
859
- }
860
- }
861
- }
862
- this.renderer.clearCachedFrame()
863
- this.layoutManager.layoutPanes()
864
- this.viewportManager.updateViewportSignal()
865
- this.scheduleDraw()
866
- return
1222
+ return false
1223
+ case 'pointerup':
1224
+ // 优先让绘图控制器处理
1225
+ if (drawingController?.onPointerUp) {
1226
+ const handled = drawingController.onPointerUp(e, this.dom.container)
1227
+ if (handled) return true
867
1228
  }
868
- const vp = this.viewportManager.computeViewport()
869
- // 防御性检查:容器尺寸无效时跳过布局
870
- if (!vp || vp.viewWidth < 10 || vp.viewHeight < 10) {
871
- return
872
- }
873
- this.renderer.clearCachedFrame()
874
- this.layoutManager.layoutPanes()
875
- this.viewportManager.updateViewportSignal()
876
- this.scheduleDraw()
877
- }
878
-
879
- /**
880
- * 请求下一帧重绘(RAF 合并,支持分层更新)
881
- * @param level 更新级别,默认为 All
882
- */
883
- scheduleDraw(level: UpdateLevel = UpdateLevel.All): void {
884
- this.renderer.scheduleDraw(level)
885
- }
886
-
887
- /** 销毁图表实例 */
888
- async destroy() {
889
- this.renderer.destroy()
890
- this.dataManager.destroy()
891
- this.viewportManager.destroy()
892
- this.layoutManager.destroy()
893
- this.sharedWebGLSurface.destroy()
894
- this.indicatorManager.destroy()
895
- this.alertController.dispose()
896
- await this.pluginHost.destroy()
897
- }
898
-
899
-
900
- private computeViewport(): Viewport | null {
901
- return this.viewportManager.computeViewport()
902
- }
903
-
904
- // ==================== Facade API (High-level interface for adapters) ====================
905
-
906
- private _themeSignal = createSignal<'light' | 'dark'>('light')
907
- private _drawingToolSignal = createSignal<DrawingToolType | null>(null)
908
- private _drawingsSignal = createSignal<ReadonlyArray<import('../plugin').DrawingObject>>([])
909
- private _paneRatiosSignal = createSignal<Readonly<Record<string, number>>>({})
910
- private _paneLayoutSignal = createSignal<PaneSpec[]>([])
911
- private _interactionSignal = createSignal<InteractionSnapshot>({
912
- crosshairPos: null,
913
- crosshairIndex: null,
914
- crosshairPrice: null,
915
- hoveredIndex: null,
916
- activePaneId: null,
917
- tooltipPos: { x: 0, y: 0 },
918
- tooltipAnchorPlacement: 'right-bottom',
919
- hoveredMarkerData: null,
920
- hoveredCustomMarker: null,
921
- isDragging: false,
922
- isResizingPaneBoundary: false,
923
- isHoveringPaneBoundary: false,
924
- hoveredPaneBoundaryId: null,
925
- isHoveringRightAxis: false,
926
- })
927
-
928
- /** 视口状态信号 */
929
- get viewport(): Signal<ViewportState> {
930
- return this.viewportManager.viewportSignal
931
- }
932
-
933
- /** 数据信号 */
934
- get data(): Signal<ReadonlyArray<KLineData>> {
935
- return this.dataManager.data
936
- }
937
-
938
- /** 加载信号 */
939
- get loading(): Signal<boolean> {
940
- return this.dataManager.loading
941
- }
942
-
943
- /** 符号信号 */
944
- get symbols(): Signal<ReadonlyArray<SymbolSpec>> {
945
- return this.dataManager.symbols
946
- }
947
-
948
- /** 比较商品颜色信号 */
949
- get comparisonColors(): Signal<ReadonlyMap<string, string>> {
950
- return this.dataManager.comparisonColors
951
- }
952
-
953
- /** 比较商品加载信号 */
954
- get comparisonLoading(): Signal<boolean> {
955
- return this.dataManager.comparisonLoading
956
- }
957
-
958
- /** 主题信号 */
959
- get theme(): Signal<'light' | 'dark'> {
960
- return this._themeSignal
961
- }
962
-
963
- /** 指标实例列表信号(派生信号,自动随主/副图状态更新) */
964
- get indicators(): Computed<ReadonlyArray<IndicatorInstance>> {
965
- return this.indicatorManager.indicatorsComputed
966
- }
967
-
968
- /** 子图信息信号(派生信号,自动随副图条目/比例更新) */
969
- get subPanes(): Computed<ReadonlyArray<SubPaneInfo>> {
970
- return this.indicatorManager.subPanesComputed
971
- }
972
-
973
- /** 当前绘图工具信号 */
974
- get drawingTool(): Signal<DrawingToolType | null> {
975
- return this._drawingToolSignal
976
- }
977
-
978
- /** 绘图对象列表信号 */
979
- get drawings(): Signal<ReadonlyArray<import('../plugin').DrawingObject>> {
980
- return this._drawingsSignal
981
- }
982
-
983
- /** 面板比例信号 */
984
- get paneRatios(): Signal<Readonly<Record<string, number>>> {
985
- return this._paneRatiosSignal
986
- }
987
-
988
- get paneLayout(): Signal<PaneSpec[]> {
989
- return this._paneLayoutSignal
990
- }
991
-
992
- /** 交互状态信号 */
993
- get interactionState(): Signal<InteractionSnapshot> {
994
- return this._interactionSignal
995
- }
996
-
997
- // ---------- Data ----------
998
-
999
- setData(data: KLineData[]): void {
1000
- this.dataManager.setData(data)
1001
- }
1002
-
1003
- appendData(newData: KLineData[]): void {
1004
- this.dataManager.appendData(newData)
1005
- }
1006
-
1007
- setDataFetcher(fetcher: import('../controllers/types').DataFetcher | null): void {
1008
- this.dataManager.setDataFetcher(fetcher)
1009
- }
1010
-
1011
- get dataBuffer(): import('../data-fetchers/dataBuffer').DataBuffer {
1012
- return this.dataManager.dataBuffer
1013
- }
1014
-
1015
- checkVisibleRangeGap(): void {
1016
- this.dataManager.checkVisibleRangeGap()
1017
- }
1018
-
1019
- setSymbols(specs: ReadonlyArray<SymbolSpec>): void {
1020
- // 品种/周期切换时重置最新 K 线时间戳,确保新数据触发预警
1021
- this._lastAlertTimestamp = null
1022
- const primaryPeriod = specs[0]?.period
1023
- if (primaryPeriod) {
1024
- this.setActiveMode(primaryPeriod === 'timeshare' ? this._timeShareMode : this._kLineMode)
1229
+ if (isRightAxis) {
1230
+ this.interaction.onRightAxisPointerUp(e)
1231
+ } else {
1232
+ this.interaction.onPointerUp(e)
1025
1233
  }
1026
- this.dataManager.setSymbols(specs)
1027
- }
1028
-
1029
- addComparisonSymbol(spec: SymbolSpec): void {
1030
- this.dataManager.addComparisonSymbol(spec)
1031
- }
1032
-
1033
- removeComparisonSymbol(symbol: string): void {
1034
- this.dataManager.removeComparisonSymbol(symbol)
1035
- }
1036
-
1037
- setComparisonData(symbol: string, data: KLineData[]): void {
1038
- this.dataManager.setComparisonData(symbol, data)
1039
- }
1040
-
1041
- setCurrentSymbol(symbol: string): void {
1042
- this.dataManager.setCurrentSymbol(symbol)
1043
- }
1044
-
1045
- setCurrentPeriod(period: string): void {
1046
- this.setActiveMode(period === 'timeshare' ? this._timeShareMode : this._kLineMode)
1047
- this.dataManager.setCurrentPeriod(period)
1048
- }
1049
-
1050
- switchToTimeShareForDate(dateYYYYMMDD: number): void {
1051
- this.dataManager.setTimeShareQueryDate(dateYYYYMMDD)
1052
- this.setActiveMode(this._timeShareMode)
1053
- this.dataManager.setCurrentPeriod('timeshare')
1054
- }
1055
-
1056
- applyCustomData(source: CustomDataSource): void {
1057
- this.dataManager.applyCustomData(source)
1058
- }
1059
-
1060
- // ---------- Theme ----------
1061
-
1062
- /**
1063
- * 设置主题(高层 API)
1064
- */
1065
- setTheme(theme: 'light' | 'dark'): void {
1066
- this._themeSignal.set(theme)
1067
- this.scheduleDraw()
1068
- }
1069
-
1070
- // ---------- Zoom ----------
1071
-
1072
- /**
1073
- * 缩放到指定级别(高层 API)
1074
- * 计算并应用新的 render state,更新 viewport signal
1075
- */
1076
- zoomToLevel(level: number, anchorX?: number): void {
1077
- if (!this._activeMode.allowZoom) return
1078
- this.zoomController.zoomToLevel(level, anchorX)
1079
- }
1080
-
1081
- /**
1082
- * 放大(高层 API)
1083
- */
1084
- zoomIn(anchorX?: number): void {
1085
- if (!this._activeMode.allowZoom) return
1086
- this.zoomController.zoomIn(anchorX)
1087
- }
1088
-
1089
- /**
1090
- * 缩小(高层 API)
1091
- */
1092
- zoomOut(anchorX?: number): void {
1093
- if (!this._activeMode.allowZoom) return
1094
- this.zoomController.zoomOut(anchorX)
1095
- }
1096
-
1097
- // ---------- Interaction (Zero-config unified entry) ----------
1098
-
1099
- /**
1100
- * 统一指针事件处理(零配置)
1101
- * 自动判断区域并分发给 interaction controller
1102
- *
1103
- * @param e 指针事件
1104
- * @param drawingController 可选的绘图控制器,如果提供,会优先让绘图控制器处理事件
1105
- * @returns 是否被处理(如果 drawingController 处理了返回 true,否则返回 false)
1106
- */
1107
- handlePointerEvent(e: PointerEvent, drawingController?: {
1108
- onPointerDown?: (e: PointerEvent, container: HTMLElement) => boolean
1109
- onPointerMove?: (e: PointerEvent, container: HTMLElement) => boolean
1110
- onPointerUp?: (e: PointerEvent, container: HTMLElement) => boolean
1111
- }): boolean {
1112
- // 判断事件目标是否在右轴区域
1113
- const isRightAxis = this.dom.rightAxisLayer.contains(e.target as Node)
1114
-
1115
- switch (e.type) {
1116
- case 'pointerdown':
1117
- // 优先让绘图控制器处理
1118
- if (drawingController?.onPointerDown) {
1119
- const handled = drawingController.onPointerDown(e, this.dom.container)
1120
- if (handled) return true
1121
- }
1122
- if (isRightAxis) {
1123
- this.interaction.onRightAxisPointerDown(e)
1124
- } else {
1125
- this.interaction.onPointerDown(e)
1126
- }
1127
- return false
1128
- case 'pointermove':
1129
- // 优先让绘图控制器处理
1130
- if (drawingController?.onPointerMove) {
1131
- const handled = drawingController.onPointerMove(e, this.dom.container)
1132
- if (handled) return true
1133
- }
1134
- if (isRightAxis) {
1135
- this.interaction.onRightAxisPointerMove(e)
1136
- } else {
1137
- this.interaction.onPointerMove(e)
1138
- }
1139
- return false
1140
- case 'pointerup':
1141
- // 优先让绘图控制器处理
1142
- if (drawingController?.onPointerUp) {
1143
- const handled = drawingController.onPointerUp(e, this.dom.container)
1144
- if (handled) return true
1145
- }
1146
- if (isRightAxis) {
1147
- this.interaction.onRightAxisPointerUp(e)
1148
- } else {
1149
- this.interaction.onPointerUp(e)
1150
- }
1151
- return false
1152
- case 'pointerleave':
1153
- // pointerleave 通常不用于绘图,直接交给 interaction
1154
- if (isRightAxis) {
1155
- this.interaction.onRightAxisPointerLeave(e)
1156
- } else {
1157
- this.interaction.onPointerLeave(e)
1158
- }
1159
- return false
1160
- default:
1161
- return false
1234
+ return false
1235
+ case 'pointerleave':
1236
+ // pointerleave 通常不用于绘图,直接交给 interaction
1237
+ if (isRightAxis) {
1238
+ this.interaction.onRightAxisPointerLeave(e)
1239
+ } else {
1240
+ this.interaction.onPointerLeave(e)
1162
1241
  }
1163
- }
1164
-
1165
- /**
1166
- * 滚轮事件处理(高层 API)
1167
- * 使用 computeZoom 计算精确的 scrollLeft,更新 viewport signal
1168
- */
1169
- handleWheelEvent(e: WheelEvent): void {
1170
- if (!this._activeMode.allowZoom) return
1171
- const rect = this.dom.container.getBoundingClientRect()
1172
- this.zoomController.handleWheel(e.deltaY, e.clientX - rect.left)
1173
- }
1174
-
1175
- /**
1176
- * 滚动事件处理(高层 API)
1177
- * 更新缓存的 scrollLeft 并触发交互 controller
1178
- */
1179
- handleScrollEvent(): void {
1180
- this.interaction.onScroll({ scheduleDraw: !this.dataManager.pendingIndicatorDataUpdate })
1181
- // 更新 viewport signal 中的 visible range
1182
- this.updateViewportSignal()
1183
- }
1184
-
1185
- /**
1186
- * 双指捏合缩放处理(高层 API)
1187
- * @param delta 缩放增量(+1 放大 / -1 缩小)
1188
- * @param centerClientX 捏合中心在视口中的 X 坐标
1189
- */
1190
- handlePinchZoom(delta: number, centerClientX: number): void {
1191
- if (!this._activeMode.allowZoom) return
1192
- this.zoomController.handlePinch(delta, centerClientX)
1193
- }
1194
-
1195
- /**
1196
- * 更新 viewport signal(用于滚动事件)
1197
- */
1198
- private updateViewportSignal(): void {
1199
- this.viewportManager.updateViewportSignal()
1200
- }
1201
-
1202
- // ---------- Indicators (Explicit role) ----------
1203
-
1204
- /**
1205
- * 添加指标(高层 API,显式指定 role)
1206
- * @param definitionId 指标定义 ID(如 'MA', 'MACD')
1207
- * @param role 'main' 主图指标 或 'sub' 副图指标
1208
- * @param params 指标参数
1209
- * @returns 实例 ID(成功)或 null(失败)
1210
- */
1211
- addIndicator(
1212
- definitionId: string,
1213
- role: 'main' | 'sub',
1214
- params?: Record<string, unknown>,
1215
- ): string | null {
1216
- return this.indicatorManager.addIndicator(definitionId, role, params)
1217
- }
1218
-
1219
- removeIndicator(instanceId: string): boolean {
1220
- return this.indicatorManager.removeIndicator(instanceId)
1221
- }
1222
-
1223
- updateIndicatorParams(instanceId: string, params: Record<string, unknown>): boolean {
1224
- return this.indicatorManager.updateIndicatorParams(instanceId, params)
1225
- }
1226
-
1227
- reorderIndicators(orderedInstanceIds: string[]): boolean {
1228
- return this.indicatorManager.reorderIndicators(orderedInstanceIds)
1229
- }
1230
-
1231
-
1232
-
1233
- // ---------- Sub Panes ----------
1234
-
1235
- /**
1236
- * 调整子图大小(高层 API)
1237
- * @param paneId 面板 ID
1238
- * @param deltaY 垂直偏移量
1239
- * @returns 是否成功
1240
- */
1241
- resizeSubPane(paneId: string, deltaY: number): boolean {
1242
- return this.resizePaneBoundary(paneId, deltaY)
1243
- }
1244
-
1245
- // ---------- Drawings ----------
1246
-
1247
- /**
1248
- * 设置当前绘图工具(高层 API)
1249
- * @param tool 工具类型或 null 取消选择
1250
- */
1251
- setDrawingTool(tool: DrawingToolType | null): void {
1252
- this._drawingToolSignal.set(tool)
1253
- // TODO: Chart 支持绘图工具切换时,在这里调用相应方法
1254
- }
1255
-
1256
- /**
1257
- * 移除绘图(高层 API)
1258
- * @param drawingId 绘图 ID
1259
- */
1260
- removeDrawing(drawingId: string): void {
1261
- // TODO: 实现绘图移除
1262
- console.warn('[Chart] removeDrawing not fully implemented yet')
1263
- }
1264
-
1265
- /**
1266
- * 清除所有绘图(高层 API)
1267
- */
1268
- clearDrawings(): void {
1269
- this.setDrawings([])
1270
- }
1271
-
1272
- // ---------- Settings ----------
1273
-
1274
- /**
1275
- * 更新设置(高层 API)
1276
- * 代理到现有的 updateSettings
1277
- */
1278
- updateSettingsFacade(settings: Record<string, unknown>): void {
1279
- this.updateSettings(settings as ChartSettings)
1280
- }
1281
-
1282
- /**
1283
- * 更新选项(高层 API)
1284
- * 代理到现有的 updateOptions
1285
- */
1286
- updateOptionsFacade(options: Partial<ChartOptions>): void {
1287
- this.updateOptions(options)
1288
- }
1289
-
1290
- // ---------- Lifecycle hooks ----------
1291
-
1292
- /**
1293
- * 销毁图表实例
1294
- */
1242
+ return false
1243
+ default:
1244
+ return false
1245
+ }
1246
+ }
1247
+
1248
+ /**
1249
+ * 滚轮事件处理(高层 API)
1250
+ * 使用 computeZoom 计算精确的 scrollLeft,更新 viewport signal
1251
+ */
1252
+ handleWheelEvent(e: WheelEvent): void {
1253
+ if (!this._activeMode.allowZoom) return
1254
+ const rect = this.dom.container.getBoundingClientRect()
1255
+ this.zoomController.handleWheel(e.deltaY, e.clientX - rect.left)
1256
+ }
1257
+
1258
+ /**
1259
+ * 滚动事件处理(高层 API)
1260
+ * 更新缓存的 scrollLeft 并触发交互 controller
1261
+ */
1262
+ handleScrollEvent(): void {
1263
+ this.interaction.onScroll({ scheduleDraw: !this.dataManager.pendingIndicatorDataUpdate })
1264
+ // 更新 viewport signal 中的 visible range
1265
+ this.updateViewportSignal()
1266
+ }
1267
+
1268
+ /**
1269
+ * 双指捏合缩放处理(高层 API)
1270
+ * @param delta 缩放增量(+1 放大 / -1 缩小)
1271
+ * @param centerClientX 捏合中心在视口中的 X 坐标
1272
+ */
1273
+ handlePinchZoom(delta: number, centerClientX: number): void {
1274
+ if (!this._activeMode.allowZoom) return
1275
+ this.zoomController.handlePinch(delta, centerClientX)
1276
+ }
1277
+
1278
+ /**
1279
+ * 更新 viewport signal(用于滚动事件)
1280
+ */
1281
+ private updateViewportSignal(): void {
1282
+ this.viewportManager.updateViewportSignal()
1283
+ }
1284
+
1285
+ // ---------- Indicators (Explicit role) ----------
1286
+
1287
+ /**
1288
+ * 添加指标(高层 API,显式指定 role)
1289
+ * @param definitionId 指标定义 ID(如 'MA', 'MACD')
1290
+ * @param role 'main' 主图指标 或 'sub' 副图指标
1291
+ * @param params 指标参数
1292
+ * @returns 实例 ID(成功)或 null(失败)
1293
+ */
1294
+ addIndicator(
1295
+ definitionId: string,
1296
+ role: 'main' | 'sub',
1297
+ params?: Record<string, unknown>,
1298
+ ): string | null {
1299
+ return this.indicatorManager.addIndicator(definitionId, role, params)
1300
+ }
1301
+
1302
+ removeIndicator(instanceId: string): boolean {
1303
+ return this.indicatorManager.removeIndicator(instanceId)
1304
+ }
1305
+
1306
+ updateIndicatorParams(instanceId: string, params: Record<string, unknown>): boolean {
1307
+ return this.indicatorManager.updateIndicatorParams(instanceId, params)
1308
+ }
1309
+
1310
+ reorderIndicators(orderedInstanceIds: string[]): boolean {
1311
+ return this.indicatorManager.reorderIndicators(orderedInstanceIds)
1312
+ }
1313
+
1314
+ // ---------- Sub Panes ----------
1315
+
1316
+ /**
1317
+ * 调整子图大小(高层 API)
1318
+ * @param paneId 面板 ID
1319
+ * @param deltaY 垂直偏移量
1320
+ * @returns 是否成功
1321
+ */
1322
+ resizeSubPane(paneId: string, deltaY: number): boolean {
1323
+ return this.resizePaneBoundary(paneId, deltaY)
1324
+ }
1325
+
1326
+ // ---------- Drawings ----------
1327
+
1328
+ /**
1329
+ * 设置当前绘图工具(高层 API)
1330
+ * @param tool 工具类型或 null 取消选择
1331
+ */
1332
+ setDrawingTool(tool: DrawingToolType | null): void {
1333
+ this._drawingToolSignal.set(tool)
1334
+ // TODO: 当 Chart 支持绘图工具切换时,在这里调用相应方法
1335
+ }
1336
+
1337
+ /**
1338
+ * 移除绘图(高层 API)
1339
+ * @param drawingId 绘图 ID
1340
+ */
1341
+ removeDrawing(drawingId: string): void {
1342
+ // TODO: 实现绘图移除
1343
+ console.warn('[Chart] removeDrawing not fully implemented yet')
1344
+ }
1345
+
1346
+ /**
1347
+ * 清除所有绘图(高层 API)
1348
+ */
1349
+ clearDrawings(): void {
1350
+ this.setDrawings([])
1351
+ }
1352
+
1353
+ // ---------- Settings ----------
1354
+
1355
+ /**
1356
+ * 更新设置(高层 API)
1357
+ * 代理到现有的 updateSettings
1358
+ */
1359
+ updateSettingsFacade(settings: Record<string, unknown>): void {
1360
+ this.updateSettings(settings as ChartSettings)
1361
+ }
1362
+
1363
+ /**
1364
+ * 更新选项(高层 API)
1365
+ * 代理到现有的 updateOptions
1366
+ */
1367
+ updateOptionsFacade(options: Partial<ChartOptions>): void {
1368
+ this.updateOptions(options)
1369
+ }
1370
+
1371
+ // ---------- Lifecycle hooks ----------
1372
+
1373
+ /**
1374
+ * 销毁图表实例
1375
+ */
1295
1376
  }
1296
-
1297
-
1298
-
1299
-