@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
@@ -10,939 +10,964 @@ import { UpdateLevel } from '../layout/pane'
10
10
  import type { ChartSettings } from '../../config/chartSettings'
11
11
 
12
12
  interface PointerLocation {
13
- mouseX: number
14
- mouseY: number
13
+ mouseX: number
14
+ mouseY: number
15
15
  }
16
16
 
17
17
  /** 悬停上下文 — 由 resolveHoverContext 创建,传递给后续所有子步骤 */
18
18
  interface HoverContext {
19
- mouseX: number
20
- mouseY: number
21
- plotWidth: number
22
- plotHeight: number
23
- viewWidth: number
24
- viewHeight: number
25
- scrollLeft: number
26
- dpr: number
27
- worldX: number
19
+ mouseX: number
20
+ mouseY: number
21
+ plotWidth: number
22
+ plotHeight: number
23
+ viewWidth: number
24
+ viewHeight: number
25
+ scrollLeft: number
26
+ dpr: number
27
+ worldX: number
28
28
  }
29
29
 
30
30
  /** 最近邻 K 线 bar — 由 findNearestBar 返回 */
31
31
  interface NearestBar {
32
- localIdx: number
33
- globalIdx: number
34
- kLineStartX: number
35
- widthLogical: number
32
+ localIdx: number
33
+ globalIdx: number
34
+ kLineStartX: number
35
+ widthLogical: number
36
36
  }
37
37
 
38
38
  export interface InteractionSnapshot {
39
- crosshairPos: { x: number; y: number } | null
40
- crosshairIndex: number | null
41
- crosshairPrice: number | null
42
- hoveredIndex: number | null
43
- activePaneId: string | null
44
- tooltipPos: { x: number; y: number }
45
- tooltipAnchorPlacement: 'right-bottom' | 'left-bottom'
46
- hoveredMarkerData: MarkerEntity | null
47
- hoveredCustomMarker: CustomMarkerEntity | null
48
- isDragging: boolean
49
- isResizingPaneBoundary: boolean
50
- isHoveringPaneBoundary: boolean
51
- hoveredPaneBoundaryId: string | null
52
- isHoveringRightAxis: boolean
39
+ crosshairPos: { x: number; y: number } | null
40
+ crosshairIndex: number | null
41
+ crosshairPrice: number | null
42
+ hoveredIndex: number | null
43
+ activePaneId: string | null
44
+ tooltipPos: { x: number; y: number }
45
+ tooltipAnchorPlacement: 'right-bottom' | 'left-bottom'
46
+ hoveredMarkerData: MarkerEntity | null
47
+ hoveredCustomMarker: CustomMarkerEntity | null
48
+ isDragging: boolean
49
+ isResizingPaneBoundary: boolean
50
+ isHoveringPaneBoundary: boolean
51
+ hoveredPaneBoundaryId: string | null
52
+ isHoveringRightAxis: boolean
53
53
  }
54
54
 
55
55
  /**
56
56
  * 交互控制器,处理拖拽滚动、缩放、十字线 hover 等交互逻辑
57
57
  */
58
58
  export class InteractionController {
59
- private chart: Chart
60
- private isDragging = false
61
- private dragMode: 'none' | 'pan' | 'resize-separator' | 'scale-price' | 'explore' = 'none'
62
- private dragStartX = 0
63
- private scrollStartX = 0
64
-
65
- private applyPanScroll(container: HTMLDivElement, nextScrollLeft: number) {
66
- const maxScrollLeft = Math.max(0, container.scrollWidth - container.clientWidth)
67
- const clampedScrollLeft = Math.min(Math.max(0, nextScrollLeft), maxScrollLeft)
68
- const dpr = this.chart.getCurrentDpr()
69
- const rounded = Math.round(clampedScrollLeft * dpr) / dpr
70
- container.scrollLeft = rounded
71
- this.chart.setScrollLeft(container.scrollLeft)
72
- }
73
-
74
- /** 垂直拖动相关 */
75
- private dragStartY = 0
76
- private activePaneIdOnDrag: string | null = null
77
-
78
- /** 分隔线拖拽相关 */
79
- private activeSeparatorUpperPaneId: string | null = null
80
- private hoveredSeparatorUpperPaneId: string | null = null
81
-
82
- /** 右轴悬浮相关 */
83
- private hoveredRightAxisPaneId: string | null = null
84
-
85
- /** [触屏]:触摸会话标记,避免触摸触发的模拟 mouse 事件干扰 */
86
- private isTouchSession = false
87
-
88
- /** 触屏探索模式:true=长按出十字线不滚动,false=直接滚动 */
89
- private exploreMode = true
90
- /** 触屏按下时的时间戳/位置(用于 tap 检测) */
91
- private touchStartTime = 0
92
- private touchStartX = 0
93
- private touchStartY = 0
94
-
95
- private pinchTracker = new PinchTracker()
96
-
97
- /** 十字线位置 */
98
- crosshairPos: { x: number; y: number } | null = null
99
- /** 十字线当前指向的 K 线索引 */
100
- crosshairIndex: number | null = null
101
- /** 十字线指向的价格(用于价格轴平移时跟随) */
102
- crosshairPrice: number | null = null
103
- /** 鼠标悬停的 K 线索引(命中 candle 时有效) */
104
- hoveredIndex: number | null = null
105
- /** 当前活跃的 pane ID */
106
- activePaneId: string | null = null
107
- /** tooltip 位置 */
108
- tooltipPos: { x: number; y: number } = { x: 0, y: 0 }
109
- /** tooltip 尺寸 */
110
- tooltipSize: { width: number; height: number } = { width: 220, height: 180 }
111
- /** tooltip 锚定位放置方向 */
112
- tooltipAnchorPlacement: 'right-bottom' | 'left-bottom' = 'right-bottom'
113
- /** 是否使用 CSS 锚定位 */
114
- private useTooltipAnchorPositioning = false
115
- /** 统一交互状态变更回调 */
116
- private onInteractionChangeCallback?: (snapshot: InteractionSnapshot) => void
117
- /** 用户设置 */
118
- private settings: ChartSettings = {}
119
-
120
- private markerState = new MarkerInteractionState()
121
-
122
- /** 当前帧的 K 线起始 x 坐标数组 */
123
- private kLinePositions: number[] | null = null
124
- /** 当前帧的 K 线中心 x 坐标数组(物理像素对齐) */
125
- private kLineCenters: number[] | null = null
126
- /** 当前帧的可见 K 线索引范围 */
127
- private visibleRange: { start: number; end: number } | null = null
128
-
129
- /** hover 去重快照 */
130
- private lastHoverRenderKey = ''
131
-
132
- /** K 线宽度(物理像素),用于计算 K 线中心偏移 */
133
- private kWidthPx: number | null = null
134
-
135
- /** 触屏长按判定时间 (ms) */
136
- private static readonly LONG_PRESS_MS = 400
137
-
138
- constructor(chart: Chart) {
139
- this.chart = chart
140
- this.setupPinchZoom()
141
- }
142
-
143
- private setupPinchZoom(): void {
144
- this.pinchTracker.setOnPinchZoom((delta, centerClientX) => {
145
- const container = this.chart.getDom().container
146
- if (!container) return
147
- const rect = container.getBoundingClientRect()
148
- const centerX = centerClientX - rect.left
149
- this.chart.handlePinchZoom(delta, centerX)
150
- })
151
- }
152
-
153
- /** 更新用户设置 */
154
- updateSettings(settings: ChartSettings): void {
155
- const prev = this.settings.disableMainPaneVerticalScroll
156
- this.settings = { ...settings }
157
- // 开启自适应时,重置主图垂直偏移
158
- if (!prev && this.settings.disableMainPaneVerticalScroll) {
159
- this.chart.resetPriceTransform('main')
160
- }
161
- }
162
-
163
- getInteractionSnapshot(): InteractionSnapshot {
164
- return {
165
- crosshairPos: this.crosshairPos ? { ...this.crosshairPos } : null,
166
- crosshairIndex: this.crosshairIndex,
167
- crosshairPrice: this.crosshairPrice,
168
- hoveredIndex: this.hoveredIndex,
169
- activePaneId: this.activePaneId,
170
- tooltipPos: { ...this.tooltipPos },
171
- tooltipAnchorPlacement: this.tooltipAnchorPlacement,
172
- hoveredMarkerData: this.markerState.hoveredMarkerData,
173
- hoveredCustomMarker: this.markerState.hoveredCustomMarker,
174
- isDragging: this.isDragging,
175
- isResizingPaneBoundary: this.dragMode === 'resize-separator',
176
- isHoveringPaneBoundary: this.hoveredSeparatorUpperPaneId !== null,
177
- hoveredPaneBoundaryId: this.hoveredSeparatorUpperPaneId,
178
- isHoveringRightAxis: this.hoveredRightAxisPaneId !== null,
179
- }
180
- }
181
-
182
- isPointerDown(): boolean {
183
- return this.isDragging || this.pinchTracker.getPointerCount() > 0
184
- }
185
-
186
- setOnInteractionChange(callback: (snapshot: InteractionSnapshot) => void) {
187
- this.onInteractionChangeCallback = callback
188
- }
189
-
190
- private notifyInteractionChange() {
191
- this.onInteractionChangeCallback?.(this.getInteractionSnapshot())
192
- }
193
-
194
- private getHoverRenderKey(): string {
195
- const crosshairX = this.crosshairPos ? Math.round(this.crosshairPos.x * this.chart.getCurrentDpr()) : 'n'
196
- const crosshairY = this.crosshairPos ? Math.round(this.crosshairPos.y * this.chart.getCurrentDpr()) : 'n'
197
- return [
198
- this.crosshairIndex ?? 'n',
199
- this.hoveredIndex ?? 'n',
200
- this.activePaneId ?? 'n',
201
- this.hoveredRightAxisPaneId ?? 'n',
202
- this.hoveredSeparatorUpperPaneId ?? 'n',
203
- this.markerState.hoveredMarkerId ?? 'n',
204
- this.markerState.hoveredCustomMarker?.id ?? 'n',
205
- crosshairX,
206
- crosshairY,
207
- ].join('|')
208
- }
209
-
210
- /**
211
- * [触屏]:处理 Pointer 按下事件
212
- * @param e PointerEvent
213
- */
214
- onPointerDown(e: PointerEvent) {
215
- this.isTouchSession = e.pointerType === 'touch'
216
- if (this.pinchTracker.handlePointerDown(e, this.isTouchSession)) {
217
- this.isDragging = false
218
- this.dragMode = 'none'
219
- return
220
- }
221
-
222
- // 单指操作(需要是主指针且不在捏合中,且不是捏合后的残余手指)
223
- if (e.isPrimary === false || this.pinchTracker.getIsPinching()) return
224
- if (this.pinchTracker.getPointerCount() > 1) return
225
-
226
- const location = this.getPlotPointerLocation(e.clientX, e.clientY)
227
- if (!location) return
228
-
229
- const { mouseX, mouseY } = location
230
- const scrollLeft = this.chart.getLogicalScrollLeft()
231
-
232
- const markerManager = this.chart.getMarkerManager()
233
- const worldX = scrollLeft + mouseX
234
- const hitMarker = markerManager.hitTest(worldX, mouseY, 3)
235
-
236
- if (hitMarker) {
237
- this.markerState.handleClick(hitMarker)
238
- return
239
- }
240
-
241
- const separatorUpperPaneId = this.hitTestPaneSeparator(mouseY)
242
- if (separatorUpperPaneId) {
243
- this.isDragging = true
244
- this.dragMode = 'resize-separator'
245
- this.dragStartY = e.clientY
246
- this.activeSeparatorUpperPaneId = separatorUpperPaneId
247
- this.hoveredSeparatorUpperPaneId = separatorUpperPaneId
248
- this.clearHover()
249
- this.chart.scheduleDraw()
250
- return
251
- }
252
-
253
- // 分时模式下禁止拖拽平移
254
- if (!this.chart.activeMode.allowPan) {
255
- this.clearHover()
256
- this.chart.scheduleDraw()
257
- return
258
- }
259
-
260
- const pane = this.getPaneByY(mouseY)
261
- this.isDragging = true
262
- this.touchStartTime = Date.now()
263
- this.touchStartX = e.clientX
264
- this.touchStartY = e.clientY
265
- // 触屏始终以 pan 模式开始,长按后才切换为 explore
266
- this.dragMode = 'pan'
267
- this.dragStartX = e.clientX
268
- this.dragStartY = e.clientY
269
- this.scrollStartX = this.chart.getCachedScrollLeft()
270
- this.activePaneIdOnDrag = pane?.id || null
271
-
59
+ private chart: Chart
60
+ private isDragging = false
61
+ private dragMode: 'none' | 'pan' | 'resize-separator' | 'scale-price' | 'explore' = 'none'
62
+ private dragStartX = 0
63
+ private scrollStartX = 0
64
+
65
+ private applyPanScroll(container: HTMLDivElement, nextScrollLeft: number) {
66
+ const maxScrollLeft = Math.max(0, container.scrollWidth - container.clientWidth)
67
+ const clampedScrollLeft = Math.min(Math.max(0, nextScrollLeft), maxScrollLeft)
68
+ const dpr = this.chart.getCurrentDpr()
69
+ const rounded = Math.round(clampedScrollLeft * dpr) / dpr
70
+ container.scrollLeft = rounded
71
+ this.chart.setScrollLeft(container.scrollLeft)
72
+ }
73
+
74
+ /** 垂直拖动相关 */
75
+ private dragStartY = 0
76
+ private activePaneIdOnDrag: string | null = null
77
+
78
+ /** 分隔线拖拽相关 */
79
+ private activeSeparatorUpperPaneId: string | null = null
80
+ private hoveredSeparatorUpperPaneId: string | null = null
81
+
82
+ /** 右轴悬浮相关 */
83
+ private hoveredRightAxisPaneId: string | null = null
84
+
85
+ /** [触屏]:触摸会话标记,避免触摸触发的模拟 mouse 事件干扰 */
86
+ private isTouchSession = false
87
+
88
+ /** 触屏探索模式:true=长按出十字线不滚动,false=直接滚动 */
89
+ private exploreMode = true
90
+ /** 触屏按下时的时间戳/位置(用于 tap 检测) */
91
+ private touchStartTime = 0
92
+ private touchStartX = 0
93
+ private touchStartY = 0
94
+
95
+ private pinchTracker = new PinchTracker()
96
+
97
+ /** 十字线位置 */
98
+ crosshairPos: { x: number; y: number } | null = null
99
+ /** 十字线当前指向的 K 线索引 */
100
+ crosshairIndex: number | null = null
101
+ /** 十字线指向的价格(用于价格轴平移时跟随) */
102
+ crosshairPrice: number | null = null
103
+ /** 鼠标悬停的 K 线索引(命中 candle 时有效) */
104
+ hoveredIndex: number | null = null
105
+ /** 当前活跃的 pane ID */
106
+ activePaneId: string | null = null
107
+ /** tooltip 位置 */
108
+ tooltipPos: { x: number; y: number } = { x: 0, y: 0 }
109
+ /** tooltip 尺寸 */
110
+ tooltipSize: { width: number; height: number } = { width: 220, height: 180 }
111
+ /** tooltip 锚定位放置方向 */
112
+ tooltipAnchorPlacement: 'right-bottom' | 'left-bottom' = 'right-bottom'
113
+ /** 是否使用 CSS 锚定位 */
114
+ private useTooltipAnchorPositioning = false
115
+ /** 统一交互状态变更回调 */
116
+ private onInteractionChangeCallback?: (snapshot: InteractionSnapshot) => void
117
+ /** 用户设置 */
118
+ private settings: ChartSettings = {}
119
+
120
+ private markerState = new MarkerInteractionState()
121
+
122
+ /** 当前帧的 K 线起始 x 坐标数组 */
123
+ private kLinePositions: number[] | null = null
124
+ /** 当前帧的 K 线中心 x 坐标数组(物理像素对齐) */
125
+ private kLineCenters: number[] | null = null
126
+ /** 当前帧的可见 K 线索引范围 */
127
+ private visibleRange: { start: number; end: number } | null = null
128
+
129
+ /** hover 去重快照 */
130
+ private lastHoverRenderKey = ''
131
+
132
+ /** K 线宽度(物理像素),用于计算 K 线中心偏移 */
133
+ private kWidthPx: number | null = null
134
+
135
+ /** 触屏长按判定时间 (ms) */
136
+ private static readonly LONG_PRESS_MS = 400
137
+
138
+ constructor(chart: Chart) {
139
+ this.chart = chart
140
+ this.setupPinchZoom()
141
+ }
142
+
143
+ private setupPinchZoom(): void {
144
+ this.pinchTracker.setOnPinchZoom((delta, centerClientX) => {
145
+ const container = this.chart.getDom().container
146
+ if (!container) return
147
+ const rect = container.getBoundingClientRect()
148
+ const centerX = centerClientX - rect.left
149
+ this.chart.handlePinchZoom(delta, centerX)
150
+ })
151
+ }
152
+
153
+ /** 更新用户设置 */
154
+ updateSettings(settings: ChartSettings): void {
155
+ const prev = this.settings.disableMainPaneVerticalScroll
156
+ this.settings = { ...settings }
157
+ // 开启自适应时,重置主图垂直偏移
158
+ if (!prev && this.settings.disableMainPaneVerticalScroll) {
159
+ this.chart.resetPriceTransform('main')
160
+ }
161
+ }
162
+
163
+ getInteractionSnapshot(): InteractionSnapshot {
164
+ return {
165
+ crosshairPos: this.crosshairPos ? { ...this.crosshairPos } : null,
166
+ crosshairIndex: this.crosshairIndex,
167
+ crosshairPrice: this.crosshairPrice,
168
+ hoveredIndex: this.hoveredIndex,
169
+ activePaneId: this.activePaneId,
170
+ tooltipPos: { ...this.tooltipPos },
171
+ tooltipAnchorPlacement: this.tooltipAnchorPlacement,
172
+ hoveredMarkerData: this.markerState.hoveredMarkerData,
173
+ hoveredCustomMarker: this.markerState.hoveredCustomMarker,
174
+ isDragging: this.isDragging,
175
+ isResizingPaneBoundary: this.dragMode === 'resize-separator',
176
+ isHoveringPaneBoundary: this.hoveredSeparatorUpperPaneId !== null,
177
+ hoveredPaneBoundaryId: this.hoveredSeparatorUpperPaneId,
178
+ isHoveringRightAxis: this.hoveredRightAxisPaneId !== null,
179
+ }
180
+ }
181
+
182
+ isPointerDown(): boolean {
183
+ return this.isDragging || this.pinchTracker.getPointerCount() > 0
184
+ }
185
+
186
+ setOnInteractionChange(callback: (snapshot: InteractionSnapshot) => void) {
187
+ this.onInteractionChangeCallback = callback
188
+ }
189
+
190
+ private notifyInteractionChange() {
191
+ this.onInteractionChangeCallback?.(this.getInteractionSnapshot())
192
+ }
193
+
194
+ private getHoverRenderKey(): string {
195
+ const crosshairX = this.crosshairPos
196
+ ? Math.round(this.crosshairPos.x * this.chart.getCurrentDpr())
197
+ : 'n'
198
+ const crosshairY = this.crosshairPos
199
+ ? Math.round(this.crosshairPos.y * this.chart.getCurrentDpr())
200
+ : 'n'
201
+ return [
202
+ this.crosshairIndex ?? 'n',
203
+ this.hoveredIndex ?? 'n',
204
+ this.activePaneId ?? 'n',
205
+ this.hoveredRightAxisPaneId ?? 'n',
206
+ this.hoveredSeparatorUpperPaneId ?? 'n',
207
+ this.markerState.hoveredMarkerId ?? 'n',
208
+ this.markerState.hoveredCustomMarker?.id ?? 'n',
209
+ crosshairX,
210
+ crosshairY,
211
+ ].join('|')
212
+ }
213
+
214
+ /**
215
+ * [触屏]:处理 Pointer 按下事件
216
+ * @param e PointerEvent
217
+ */
218
+ onPointerDown(e: PointerEvent) {
219
+ this.isTouchSession = e.pointerType === 'touch'
220
+ if (this.pinchTracker.handlePointerDown(e, this.isTouchSession)) {
221
+ this.isDragging = false
222
+ this.dragMode = 'none'
223
+ return
224
+ }
225
+
226
+ // 单指操作(需要是主指针且不在捏合中,且不是捏合后的残余手指)
227
+ if (e.isPrimary === false || this.pinchTracker.getIsPinching()) return
228
+ if (this.pinchTracker.getPointerCount() > 1) return
229
+
230
+ const location = this.getPlotPointerLocation(e.clientX, e.clientY)
231
+ if (!location) return
232
+
233
+ const { mouseX, mouseY } = location
234
+ const scrollLeft = this.chart.getLogicalScrollLeft()
235
+
236
+ const markerManager = this.chart.getMarkerManager()
237
+ const worldX = scrollLeft + mouseX
238
+ const hitMarker = markerManager.hitTest(worldX, mouseY, 3)
239
+
240
+ if (hitMarker) {
241
+ this.markerState.handleClick(hitMarker)
242
+ return
243
+ }
244
+
245
+ const separatorUpperPaneId = this.hitTestPaneSeparator(mouseY)
246
+ if (separatorUpperPaneId) {
247
+ this.isDragging = true
248
+ this.dragMode = 'resize-separator'
249
+ this.dragStartY = e.clientY
250
+ this.activeSeparatorUpperPaneId = separatorUpperPaneId
251
+ this.hoveredSeparatorUpperPaneId = separatorUpperPaneId
252
+ this.clearHover()
253
+ this.chart.scheduleDraw()
254
+ return
255
+ }
256
+
257
+ // 分时模式下禁止拖拽平移
258
+ if (!this.chart.activeMode.allowPan) {
259
+ this.clearHover()
260
+ this.chart.scheduleDraw()
261
+ return
262
+ }
263
+
264
+ const pane = this.getPaneByY(mouseY)
265
+ this.isDragging = true
266
+ this.touchStartTime = Date.now()
267
+ this.touchStartX = e.clientX
268
+ this.touchStartY = e.clientY
269
+ // 触屏始终以 pan 模式开始,长按后才切换为 explore
270
+ this.dragMode = 'pan'
271
+ this.dragStartX = e.clientX
272
+ this.dragStartY = e.clientY
273
+ this.scrollStartX = this.chart.getCachedScrollLeft()
274
+ this.activePaneIdOnDrag = pane?.id || null
275
+
276
+ this.chart.scheduleDraw()
277
+ }
278
+
279
+ /**
280
+ * 设置 tooltip 尺寸
281
+ * @param size 宽高对象
282
+ */
283
+ setTooltipSize(size: { width: number; height: number }) {
284
+ this.tooltipSize = size
285
+ }
286
+
287
+ setTooltipAnchorPositioning(enabled: boolean) {
288
+ this.useTooltipAnchorPositioning = enabled
289
+ }
290
+
291
+ /**
292
+ * 处理 Pointer 抬起事件
293
+ * @param e PointerEvent
294
+ */
295
+ onPointerUp(e: PointerEvent) {
296
+ this.pinchTracker.handlePointerUp(e)
297
+
298
+ if (e.isPrimary === false) return
299
+ const wasPanning = this.dragMode === 'pan'
300
+ const wasExploring = this.dragMode === 'explore'
301
+
302
+ if (this.isTouchSession) {
303
+ if (wasExploring) {
304
+ // 长按触发了 explore → 保持十字线
305
+ this.exploreMode = true
306
+ this.updatePlotHoverFromPoint(e.clientX, e.clientY)
272
307
  this.chart.scheduleDraw()
273
- }
274
-
275
-
276
-
277
- /**
278
- * 设置 tooltip 尺寸
279
- * @param size 宽高对象
280
- */
281
- setTooltipSize(size: { width: number; height: number }) {
282
- this.tooltipSize = size
283
- }
284
-
285
- setTooltipAnchorPositioning(enabled: boolean) {
286
- this.useTooltipAnchorPositioning = enabled
287
- }
288
-
289
- /**
290
- * 处理 Pointer 抬起事件
291
- * @param e PointerEvent
292
- */
293
- onPointerUp(e: PointerEvent) {
294
- this.pinchTracker.handlePointerUp(e)
295
-
296
- if (e.isPrimary === false) return
297
- const wasPanning = this.dragMode === 'pan'
298
- const wasExploring = this.dragMode === 'explore'
299
-
300
- if (this.isTouchSession) {
301
- if (wasExploring) {
302
- // 长按触发了 explore → 保持十字线
303
- this.exploreMode = true
304
- this.updatePlotHoverFromPoint(e.clientX, e.clientY)
305
- this.chart.scheduleDraw()
306
- this.notifyInteractionChange()
307
- } else if (wasPanning) {
308
- // 有实际滑动 → 下次支持长按
309
- this.exploreMode = true
310
- } else {
311
- // 既未触发 explore 也未滑动
312
- const elapsed = Date.now() - this.touchStartTime
313
- const dx = e.clientX - this.touchStartX
314
- const dy = e.clientY - this.touchStartY
315
- if (elapsed < InteractionController.LONG_PRESS_MS && Math.abs(dx) < 10 && Math.abs(dy) < 10) {
316
- // 快速点击 → 锁定滚动模式,下次触摸不触发长按
317
- this.exploreMode = false
318
- this.clearHover()
319
- this.chart.scheduleDraw()
320
- this.notifyInteractionChange()
321
- } else {
322
- this.exploreMode = true
323
- }
324
- }
325
- }
326
-
327
- // 鼠标和触屏拖拽结束后都检查左侧缺口 → 触发增量加载
328
- if (wasPanning) {
329
- this.chart.checkVisibleRangeGap()
330
- }
331
-
332
- this.isDragging = false
333
- this.dragMode = 'none'
334
- this.activePaneIdOnDrag = null
335
- this.activeSeparatorUpperPaneId = null
336
308
  this.notifyInteractionChange()
337
- }
338
-
339
- /**
340
- * 处理 Pointer 离开事件
341
- * @param e PointerEvent
342
- */
343
- onPointerLeave(e: PointerEvent) {
344
- this.pinchTracker.handlePointerLeave(e)
345
-
346
- if (e.isPrimary === false) return
347
-
348
- this.isDragging = false
349
- this.dragMode = 'none'
350
- this.activePaneIdOnDrag = null
351
- this.clearSeparatorState()
352
- if (!this.isTouchSession) {
353
- this.clearHover()
354
- this.chart.scheduleDraw()
355
- this.notifyInteractionChange()
309
+ } else if (wasPanning) {
310
+ // 有实际滑动 → 下次支持长按
311
+ this.exploreMode = true
312
+ } else {
313
+ // 既未触发 explore 也未滑动
314
+ const elapsed = Date.now() - this.touchStartTime
315
+ const dx = e.clientX - this.touchStartX
316
+ const dy = e.clientY - this.touchStartY
317
+ if (
318
+ elapsed < InteractionController.LONG_PRESS_MS &&
319
+ Math.abs(dx) < 10 &&
320
+ Math.abs(dy) < 10
321
+ ) {
322
+ // 快速点击 → 锁定滚动模式,下次触摸不触发长按
323
+ this.exploreMode = false
324
+ this.clearHover()
325
+ this.chart.scheduleDraw()
326
+ this.notifyInteractionChange()
327
+ } else {
328
+ this.exploreMode = true
356
329
  }
357
- this.isTouchSession = false
330
+ }
358
331
  }
359
332
 
360
- /** 处理滚动事件 */
361
- onScroll(options: { scheduleDraw?: boolean } = {}) {
362
- this.kLinePositions = null
363
- this.kLineCenters = null
364
- this.visibleRange = null
365
- this.clearHover()
366
- if (options.scheduleDraw !== false) {
367
- this.chart.scheduleDraw()
368
- }
369
- this.notifyInteractionChange()
333
+ // 鼠标和触屏拖拽结束后都检查左侧缺口 → 触发增量加载
334
+ if (wasPanning) {
335
+ this.chart.checkVisibleRangeGap()
370
336
  }
371
337
 
372
- /**
373
- * 处理 Pointer 移动事件(支持鼠标和触屏)
374
- * @param e PointerEvent
375
- */
376
- onPointerMove(e: PointerEvent) {
377
- if (this.pinchTracker.handlePointerMove(e)) return
338
+ this.isDragging = false
339
+ this.dragMode = 'none'
340
+ this.activePaneIdOnDrag = null
341
+ this.activeSeparatorUpperPaneId = null
342
+ this.notifyInteractionChange()
343
+ }
378
344
 
379
- if (!e.isPrimary) return
345
+ /**
346
+ * 处理 Pointer 离开事件
347
+ * @param e PointerEvent
348
+ */
349
+ onPointerLeave(e: PointerEvent) {
350
+ this.pinchTracker.handlePointerLeave(e)
380
351
 
381
- if (e.pointerType === 'touch') {
382
- this.isTouchSession = true
383
- }
384
-
385
- const container = this.chart.getDom().container
386
-
387
- if (this.isDragging) {
388
- if (this.dragMode === 'resize-separator') {
389
- const deltaY = e.clientY - this.dragStartY
390
- if (deltaY !== 0 && this.activeSeparatorUpperPaneId) {
391
- const resized = this.chart.resizePaneBoundary(this.activeSeparatorUpperPaneId, deltaY)
392
- if (resized) {
393
- this.dragStartY = e.clientY
394
- }
395
- }
396
- return
397
- }
398
-
399
- if (this.dragMode === 'scale-price') {
400
- const deltaY = e.clientY - this.dragStartY
401
- if (deltaY !== 0 && this.activePaneIdOnDrag) {
402
- this.chart.scalePrice(this.activePaneIdOnDrag, deltaY)
403
- this.dragStartY = e.clientY
404
- }
405
- return
406
- }
407
-
408
- // 触屏:长按达到阈值后从 pan 切换到 explore
409
- if (this.isTouchSession && this.dragMode === 'pan' && this.exploreMode) {
410
- const elapsed = Date.now() - this.touchStartTime
411
- const dx = Math.abs(e.clientX - this.touchStartX)
412
- const dy = Math.abs(e.clientY - this.touchStartY)
413
- if (elapsed >= InteractionController.LONG_PRESS_MS && dx < 10 && dy < 10) {
414
- this.dragMode = 'explore'
415
- this.updatePlotHoverFromPoint(e.clientX, e.clientY)
416
- this.chart.scheduleDraw()
417
- this.notifyInteractionChange()
418
- return
419
- }
420
- }
421
-
422
- if (this.dragMode === 'explore') {
423
- this.updatePlotHoverFromPoint(e.clientX, e.clientY)
424
- this.chart.scheduleDraw()
425
- this.notifyInteractionChange()
426
- return
427
- }
428
-
429
- if (this.dragMode === 'pan') {
430
- const deltaX = this.dragStartX - e.clientX
431
- this.applyPanScroll(container, this.scrollStartX + deltaX)
432
-
433
- const deltaY = e.clientY - this.dragStartY
434
- this.dragStartY = e.clientY
435
- if (deltaY !== 0 && this.activePaneIdOnDrag === 'main') {
436
- if (!this.settings.disableMainPaneVerticalScroll) {
437
- this.chart.translatePrice(this.activePaneIdOnDrag, deltaY)
438
- }
439
- }
440
- }
441
- return
442
- }
443
-
444
- const location = this.getPlotPointerLocation(e.clientX, e.clientY)
445
- if (!location) return
446
- this.hoveredSeparatorUpperPaneId = this.hitTestPaneSeparator(location.mouseY)
352
+ if (e.isPrimary === false) return
447
353
 
448
- this.updatePlotHoverFromPoint(e.clientX, e.clientY)
449
- const hoverRenderKey = this.getHoverRenderKey()
450
- if (hoverRenderKey !== this.lastHoverRenderKey) {
451
- this.lastHoverRenderKey = hoverRenderKey
452
- this.chart.scheduleDraw(UpdateLevel.Overlay)
453
- }
454
- this.notifyInteractionChange()
354
+ this.isDragging = false
355
+ this.dragMode = 'none'
356
+ this.activePaneIdOnDrag = null
357
+ this.clearSeparatorState()
358
+ if (!this.isTouchSession) {
359
+ this.clearHover()
360
+ this.chart.scheduleDraw()
361
+ this.notifyInteractionChange()
455
362
  }
363
+ this.isTouchSession = false
364
+ }
456
365
 
457
-
458
- /**
459
- * 设置当前帧的 K 线起始 x 坐标数组和可见范围
460
- * @param positions K 线起始 x 坐标数组
461
- * @param visibleRange 可见 K 线索引范围
462
- * @param kWidthPx K 线宽度(物理像素)
463
- * @param centers K 线中心 x 坐标数组(物理像素对齐后)
464
- */
465
- setKLinePositions(
466
- positions: number[] | null,
467
- visibleRange: { start: number; end: number } | null,
468
- kWidthPx?: number,
469
- centers?: number[] | null
470
- ) {
471
- this.kLinePositions = positions
472
- this.kLineCenters = centers ?? null
473
- this.visibleRange = visibleRange
474
- if (kWidthPx !== undefined) {
475
- this.kWidthPx = kWidthPx
476
- }
366
+ /** 处理滚动事件 */
367
+ onScroll(options: { scheduleDraw?: boolean } = {}) {
368
+ this.kLinePositions = null
369
+ this.kLineCenters = null
370
+ this.visibleRange = null
371
+ this.clearHover()
372
+ if (options.scheduleDraw !== false) {
373
+ this.chart.scheduleDraw()
477
374
  }
375
+ this.notifyInteractionChange()
376
+ }
478
377
 
479
- onRightAxisPointerDown(e: PointerEvent) {
480
- if (e.isPrimary === false) return
481
- this.isTouchSession = e.pointerType === 'touch'
482
- const location = this.getRightAxisPointerLocation(e.clientX, e.clientY)
483
- if (!location) return
484
- if (this.beginScalePriceDrag(e.clientY, location.mouseY)) {
485
- this.chart.scheduleDraw()
486
- this.notifyInteractionChange()
487
- }
488
- }
378
+ /**
379
+ * 处理 Pointer 移动事件(支持鼠标和触屏)
380
+ * @param e PointerEvent
381
+ */
382
+ onPointerMove(e: PointerEvent) {
383
+ if (this.pinchTracker.handlePointerMove(e)) return
489
384
 
490
- onRightAxisPointerMove(e: PointerEvent) {
491
- if (!e.isPrimary) return
492
- if (e.pointerType === 'touch') {
493
- this.isTouchSession = true
494
- }
385
+ if (!e.isPrimary) return
495
386
 
496
- if (this.isDragging && this.dragMode === 'scale-price') {
497
- const deltaY = e.clientY - this.dragStartY
498
- if (deltaY !== 0 && this.activePaneIdOnDrag) {
499
- this.chart.scalePrice(this.activePaneIdOnDrag, deltaY)
500
- this.dragStartY = e.clientY
501
- }
502
- return
503
- }
504
-
505
- this.updateRightAxisHoverFromPoint(e.clientX, e.clientY)
506
- const hoverRenderKey = this.getHoverRenderKey()
507
- if (hoverRenderKey !== this.lastHoverRenderKey) {
508
- this.lastHoverRenderKey = hoverRenderKey
509
- this.chart.scheduleDraw(UpdateLevel.Overlay)
510
- }
511
- this.notifyInteractionChange()
387
+ if (e.pointerType === 'touch') {
388
+ this.isTouchSession = true
512
389
  }
513
390
 
514
- onRightAxisPointerUp(e: PointerEvent) {
515
- this.onPointerUp(e)
516
- }
391
+ const container = this.chart.getDom().container
517
392
 
518
- onRightAxisPointerLeave(e: PointerEvent) {
519
- if (e.isPrimary === false) return
520
- if (this.isDragging && this.dragMode === 'scale-price') return
521
- this.hoveredRightAxisPaneId = null
393
+ if (this.isDragging) {
394
+ if (this.dragMode === 'resize-separator') {
395
+ const deltaY = e.clientY - this.dragStartY
396
+ if (deltaY !== 0 && this.activeSeparatorUpperPaneId) {
397
+ const resized = this.chart.resizePaneBoundary(this.activeSeparatorUpperPaneId, deltaY)
398
+ if (resized) {
399
+ this.dragStartY = e.clientY
400
+ }
401
+ }
402
+ return
403
+ }
404
+
405
+ if (this.dragMode === 'scale-price') {
406
+ const deltaY = e.clientY - this.dragStartY
407
+ if (deltaY !== 0 && this.activePaneIdOnDrag) {
408
+ this.chart.scalePrice(this.activePaneIdOnDrag, deltaY)
409
+ this.dragStartY = e.clientY
410
+ }
411
+ return
412
+ }
413
+
414
+ // 触屏:长按达到阈值后从 pan 切换到 explore
415
+ if (this.isTouchSession && this.dragMode === 'pan' && this.exploreMode) {
416
+ const elapsed = Date.now() - this.touchStartTime
417
+ const dx = Math.abs(e.clientX - this.touchStartX)
418
+ const dy = Math.abs(e.clientY - this.touchStartY)
419
+ if (elapsed >= InteractionController.LONG_PRESS_MS && dx < 10 && dy < 10) {
420
+ this.dragMode = 'explore'
421
+ this.updatePlotHoverFromPoint(e.clientX, e.clientY)
422
+ this.chart.scheduleDraw()
423
+ this.notifyInteractionChange()
424
+ return
425
+ }
426
+ }
427
+
428
+ if (this.dragMode === 'explore') {
429
+ this.updatePlotHoverFromPoint(e.clientX, e.clientY)
430
+ this.chart.scheduleDraw()
522
431
  this.notifyInteractionChange()
523
- }
524
-
525
- /** 检查是否正在拖拽 */
526
- isDraggingState(): boolean {
527
- return this.isDragging
528
- }
529
-
530
- setOnMarkerHover(callback: (marker: MarkerEntity | null) => void) {
531
- this.markerState.setOnMarkerHover(callback)
532
- }
533
-
534
- setOnMarkerClick(callback: (marker: MarkerEntity) => void) {
535
- this.markerState.setOnMarkerClick(callback)
536
- }
537
-
538
- setOnCustomMarkerHover(callback: (marker: CustomMarkerEntity | null) => void) {
539
- this.markerState.setOnCustomMarkerHover(callback)
540
- }
541
-
542
- setOnCustomMarkerClick(callback: (marker: CustomMarkerEntity) => void) {
543
- this.markerState.setOnCustomMarkerClick(callback)
544
- }
545
-
546
- /** 命中可拖拽分隔线(返回上方 paneId) */
547
- private hitTestPaneSeparator(mouseY: number): string | null {
548
- const paneRenderers = this.chart.getPaneRenderers()
549
- if (paneRenderers.length < 2) return null
550
-
551
- const SEP_HIT_HALF = 5
552
- for (let i = 0; i < paneRenderers.length - 1; i++) {
553
- const upper = paneRenderers[i]?.getPane()
554
- const lower = paneRenderers[i + 1]?.getPane()
555
- if (!upper || !lower) continue
556
- const boundaryY = upper.top + upper.height
557
- if (Math.abs(mouseY - boundaryY) <= SEP_HIT_HALF) {
558
- return upper.id
559
- }
560
- }
561
- return null
562
- }
563
-
564
- private getPaneByY(mouseY: number) {
565
- const paneRenderers = this.chart.getPaneRenderers()
566
- const renderer = paneRenderers.find((r) => {
567
- const pane = r.getPane()
568
- return mouseY >= pane.top && mouseY <= pane.top + pane.height
569
- })
570
- return renderer?.getPane() || null
571
- }
572
-
573
- private getPlotPointerLocation(clientX: number, clientY: number): PointerLocation | null {
574
- const container = this.chart.getDom().container
575
- const rect = container.getBoundingClientRect()
576
- const mouseX = clientX - rect.left
577
- const mouseY = clientY - rect.top
578
- return { mouseX, mouseY }
579
- }
580
-
581
- private getRightAxisPointerLocation(clientX: number, clientY: number): PointerLocation {
582
- const rightAxisLayer = this.chart.getDom().rightAxisLayer
583
- const rect = rightAxisLayer.getBoundingClientRect()
584
- const mouseX = clientX - rect.left
585
- const mouseY = clientY - rect.top
586
- return { mouseX, mouseY }
587
- }
588
-
589
- private beginScalePriceDrag(clientY: number, mouseY: number) {
590
- const pane = this.getPaneByY(mouseY)
591
- if (!pane) return false
592
- // 主图禁用垂直滚动时,禁止价格轴缩放
593
- if (pane.id === 'main' && this.settings.disableMainPaneVerticalScroll) {
594
- return false
595
- }
596
- this.isDragging = true
597
- this.dragMode = 'scale-price'
598
- this.dragStartY = clientY
599
- this.activePaneIdOnDrag = pane.id
600
- this.hoveredRightAxisPaneId = pane.id
601
- this.hoveredSeparatorUpperPaneId = null
602
- this.crosshairPos = null
603
- this.crosshairIndex = null
604
- this.crosshairPrice = null
605
- this.hoveredIndex = null
606
- this.activePaneId = pane.id
607
- return true
608
- }
609
-
610
- clearHover() {
611
- this.lastHoverRenderKey = ''
612
- this.hoveredRightAxisPaneId = null
613
- this.crosshairPos = null
614
- this.crosshairIndex = null
615
- this.crosshairPrice = null
616
- this.hoveredIndex = null
617
- this.activePaneId = null
618
-
619
- this.markerState.clearAll(this.chart.getMarkerManager())
620
- }
621
-
622
-
623
- private clearSeparatorState() {
624
- this.activeSeparatorUpperPaneId = null
625
- this.hoveredSeparatorUpperPaneId = null
626
- this.hoveredRightAxisPaneId = null
627
- }
628
-
629
- /**
630
- * 从屏幕坐标更新 hover 状态
631
- * @param clientX 屏幕 x 坐标
632
- * @param clientY 屏幕 y 坐标
633
- */
634
-
635
- private updateRightAxisHoverFromPoint(clientX: number, clientY: number) {
636
- const location = this.getRightAxisPointerLocation(clientX, clientY)
637
- if (!location) return
638
-
639
- const { mouseY } = location
640
- const viewport = this.chart.getViewport()
641
- const plotHeight = viewport?.plotHeight ?? Math.max(1, Math.round(this.chart.getDom().container.clientHeight))
642
- if (mouseY < 0 || mouseY > plotHeight) {
643
- this.hoveredRightAxisPaneId = null
644
- return
645
- }
646
-
647
- const pane = this.getPaneByY(mouseY)
648
- this.hoveredRightAxisPaneId = pane?.id || null
649
- this.hoveredSeparatorUpperPaneId = null
650
- this.crosshairPos = null
651
- this.crosshairIndex = null
652
- this.crosshairPrice = null
653
- this.hoveredIndex = null
654
- this.activePaneId = pane?.id || null
655
- }
656
-
657
- /**
658
- * 指针悬停检测(coordinator)
659
- *
660
- * 每次指针移动时触发,按优先级依次检测:
661
- * 边界 → pane 分隔器 → marker → K 线 bar → 十字线定位 → candle 命中 → tooltip。
662
- * 每个步骤都可能提前 return,无需执行后续检测。
663
- */
664
- private updatePlotHoverFromPoint(clientX: number, clientY: number) {
665
- const ctx = this.resolveHoverContext(clientX, clientY)
666
- if (!ctx) return
667
-
668
- if (this.handleSeparatorHit(ctx)) return
669
- if (this.handleMarkerHit(ctx)) return
670
-
671
- const bar = this.findNearestBar(ctx)
672
- if (!bar) {
673
- this.clearHover()
674
- return
675
- }
676
-
677
- this.positionCrosshair(ctx, bar)
678
-
679
- if (this.chart.currentPeriod === 'timeshare') {
680
- this.handleTimeshareHover(ctx, bar)
681
- return
682
- }
683
-
684
- if (!this.hitTestCandle(ctx, bar)) {
685
- this.hoveredIndex = null
686
- return
687
- }
688
-
689
- this.hoveredIndex = bar.globalIdx
690
- this.updateTooltip(ctx)
691
- }
692
-
693
- /**
694
- * 解析悬停上下文
695
- *
696
- * 将 client 坐标转换为 plot 坐标,并做边界检查。
697
- * 返回 null 表示指针不在 plot 区域内。
698
- */
699
- private resolveHoverContext(clientX: number, clientY: number): HoverContext | null {
700
- const location = this.getPlotPointerLocation(clientX, clientY)
701
- if (!location) return null
702
-
703
- const { mouseX, mouseY } = location
704
- const container = this.chart.getDom().container
705
- const viewport = this.chart.getViewport()
706
- const viewWidth = viewport?.viewWidth ?? Math.max(1, Math.round(container.clientWidth))
707
- const viewHeight = viewport?.viewHeight ?? Math.max(1, Math.round(container.clientHeight))
708
- const plotWidth = viewport?.plotWidth ?? viewWidth
709
- const plotHeight = viewport?.plotHeight ?? viewHeight
710
-
711
- if (mouseX < 0 || mouseY < 0 || mouseX > plotWidth || mouseY > plotHeight) {
712
- this.clearHover()
713
- return null
714
- }
715
-
716
- const scrollLeft = this.chart.getLogicalScrollLeft()
717
- const dpr = this.chart.getCurrentDpr()
718
-
719
- return { mouseX, mouseY, plotWidth, plotHeight, viewWidth, viewHeight, scrollLeft, dpr, worldX: scrollLeft + mouseX }
720
- }
721
-
722
- /**
723
- * 检测 pane 分隔器悬停
724
- *
725
- * 若指针悬浮在 pane 分隔条上,清除十字线状态并返回 true。
726
- */
727
- private handleSeparatorHit(ctx: HoverContext): boolean {
728
- this.hoveredRightAxisPaneId = null
729
- const separatorUpperPaneId = this.hitTestPaneSeparator(ctx.mouseY)
730
- this.hoveredSeparatorUpperPaneId = separatorUpperPaneId
731
- if (separatorUpperPaneId) {
732
- this.crosshairPos = null
733
- this.crosshairIndex = null
734
- this.crosshairPrice = null
735
- this.hoveredIndex = null
736
- this.activePaneId = null
737
- return true
738
- }
739
- return false
740
- }
741
-
742
- /**
743
- * 检测 marker 悬停
744
- *
745
- * 若指针悬浮在 marker 上,清除十字线状态并返回 true。
746
- */
747
- private handleMarkerHit(ctx: HoverContext): boolean {
748
- const markerManager = this.chart.getMarkerManager()
749
- if (this.markerState.updateHoverFromPoint(ctx.worldX, ctx.mouseX, ctx.mouseY, markerManager)) {
750
- this.crosshairPos = null
751
- this.crosshairIndex = null
752
- this.crosshairPrice = null
753
- this.hoveredIndex = null
754
- return true
755
- }
756
- return false
757
- }
758
-
759
- /**
760
- * 查找最近邻 K 线 bar
761
- *
762
- * 使用二分搜索在 kLinePositions 中定位指针最近的 K 线 bar。
763
- * 若无 kLinePositions、visibleRange 或 kWidthPx,返回 null。
764
- */
765
- private findNearestBar(ctx: HoverContext): NearestBar | null {
766
- if (!this.kLinePositions || !this.visibleRange || !this.kWidthPx) return null
767
-
768
- const { worldX, mouseY, dpr } = ctx
769
- const kWidthLogical = this.kWidthPx / dpr
770
- const positions = this.kLinePositions
771
-
772
- let lo = 0, hi = positions.length
773
- while (lo < hi) {
774
- const mid = (lo + hi) >> 1
775
- if (positions[mid]! < worldX) {
776
- lo = mid + 1
777
- } else {
778
- hi = mid
779
- }
780
- }
781
-
782
- let localIdx = lo
783
- if (lo > 0 && lo < positions.length) {
784
- const prevCenter = positions[lo - 1]! + kWidthLogical / 2
785
- const currCenter = positions[lo]! + kWidthLogical / 2
786
- if (Math.abs(worldX - prevCenter) < Math.abs(worldX - currCenter)) {
787
- localIdx = lo - 1
788
- }
789
- } else if (lo === positions.length && positions.length > 0) {
790
- localIdx = positions.length - 1
791
- }
792
-
793
- return {
794
- localIdx,
795
- globalIdx: localIdx + this.visibleRange.start,
796
- kLineStartX: positions[localIdx]!,
797
- widthLogical: kWidthLogical,
798
- }
799
- }
800
-
801
- /**
802
- * 定位十字线
803
- *
804
- * 根据最近邻 bar 设置 crosshairIndex、crosshairPos(snap 到 K 线中心)
805
- * 以及 crosshairPrice(鼠标 Y → 价格)。
806
- * 索引无效时清除十字线状态。
807
- */
808
- private positionCrosshair(ctx: HoverContext, bar: NearestBar): void {
809
- const { mouseX, mouseY, scrollLeft, plotWidth, plotHeight, dpr } = ctx
810
- const pane = this.getPaneByY(mouseY)
811
- this.activePaneId = pane?.id || null
812
-
813
- if (bar.globalIdx < 0 || bar.globalIdx >= (this.chart.getRenderData()?.length ?? 0)) {
814
- this.crosshairIndex = null
815
- this.crosshairPos = null
816
- this.crosshairPrice = null
817
- return
818
- }
432
+ return
433
+ }
819
434
 
820
- this.crosshairIndex = bar.globalIdx
435
+ if (this.dragMode === 'pan') {
436
+ const deltaX = this.dragStartX - e.clientX
437
+ this.applyPanScroll(container, this.scrollStartX + deltaX)
821
438
 
822
- const centerX = this.kLineCenters?.[bar.localIdx] ?? bar.kLineStartX + bar.widthLogical / 2
823
- const snappedX = centerX - scrollLeft
824
-
825
- this.crosshairPos = {
826
- x: Math.min(Math.max(snappedX, 0), plotWidth),
827
- y: Math.min(Math.max(mouseY, 0), plotHeight),
828
- }
829
-
830
- if (pane) {
831
- const localY = mouseY - pane.top
832
- this.crosshairPrice = pane.yAxis.yToPrice(localY)
833
- } else {
834
- this.crosshairPrice = null
835
- }
836
- }
837
-
838
- /**
839
- * 分时模式悬停处理
840
- *
841
- * 分时模式下直接设置 hoveredIndex 并计算 tooltip 位置后返回,
842
- * 不执行 candle body/wick 命中检测。
843
- */
844
- private handleTimeshareHover(ctx: HoverContext, bar: NearestBar): void {
845
- this.hoveredIndex = bar.globalIdx
846
- this.updateTooltip(ctx)
847
- }
848
-
849
- /**
850
- * Candle 实体/影线命中检测
851
- *
852
- * 检测指针是否落在 K 线实体内或影线上。
853
- * 小实体(< 8px)会扩展命中区域以保证可用性。
854
- * 未命中时返回 false。
855
- */
856
- private hitTestCandle(ctx: HoverContext, bar: NearestBar): boolean {
857
- const { mouseY, worldX, dpr } = ctx
858
- const data = this.chart.getRenderData()
859
- const k = typeof this.crosshairIndex === 'number' ? data?.[this.crosshairIndex] as KLineData | undefined : undefined
860
- const pane = this.getPaneByY(mouseY)
861
-
862
- if (!k || !pane || !pane.capabilities.candleHitTest) return false
863
-
864
- const localY = mouseY - pane.top
865
- const openY = pane.yAxis.priceToY(k.open)
866
- const closeY = pane.yAxis.priceToY(k.close)
867
- const highY = pane.yAxis.priceToY(k.high)
868
- const lowY = pane.yAxis.priceToY(k.low)
869
- const bodyTop = Math.min(openY, closeY)
870
- const bodyBottom = Math.max(openY, closeY)
871
-
872
- const inUnitX = worldX - bar.kLineStartX
873
- const cxLogical = bar.widthLogical / 2
874
-
875
- const MIN_BODY_HIT_HEIGHT = 8
876
- const bodyHeight = Math.abs(bodyBottom - bodyTop)
877
- const effectiveBodyTop = bodyHeight < MIN_BODY_HIT_HEIGHT
878
- ? (bodyTop + bodyBottom) / 2 - MIN_BODY_HIT_HEIGHT / 2
879
- : bodyTop
880
- const effectiveBodyBottom = bodyHeight < MIN_BODY_HIT_HEIGHT
881
- ? (bodyTop + bodyBottom) / 2 + MIN_BODY_HIT_HEIGHT / 2
882
- : bodyBottom
883
-
884
- const HIT_WICK_HALF_EXTENDED = 3
885
-
886
- const hitBody = localY >= effectiveBodyTop && localY <= effectiveBodyBottom
887
- && inUnitX >= 0 && inUnitX <= bar.widthLogical
888
- const hitWick = Math.abs(inUnitX - cxLogical) <= HIT_WICK_HALF_EXTENDED
889
- && localY >= Math.min(highY, lowY) && localY <= Math.max(highY, lowY)
890
-
891
- return hitBody || hitWick
892
- }
893
-
894
- /**
895
- * 更新 tooltip 位置
896
- *
897
- * 使用 computeTooltipPosition 计算 tooltip 的显示位置和锚点方向。
898
- */
899
- private updateTooltip(ctx: HoverContext): void {
900
- const { mouseX, mouseY, viewWidth, viewHeight, plotWidth, plotHeight } = ctx
901
- const tooltipResult = computeTooltipPosition({
902
- mouseX,
903
- mouseY,
904
- viewWidth,
905
- viewHeight,
906
- plotWidth,
907
- plotHeight,
908
- tooltipSize: this.tooltipSize,
909
- useAnchorPositioning: this.useTooltipAnchorPositioning,
910
- })
911
- if (tooltipResult.anchorPlacement) {
912
- this.tooltipAnchorPlacement = tooltipResult.anchorPlacement
913
- }
914
- this.tooltipPos = tooltipResult.pos
915
- }
916
-
917
-
918
- /**
919
- * 重置所有交互状态(数据更新时调用)
920
- */
921
- reset(): void {
922
- this.isDragging = false
923
- this.dragMode = 'none'
924
- this.dragStartX = 0
925
- this.dragStartY = 0
926
- this.scrollStartX = 0
927
- this.activePaneIdOnDrag = null
928
- this.clearSeparatorState()
929
- this.isTouchSession = false
930
- this.pinchTracker.reset()
931
- this.crosshairPos = null
932
- this.crosshairIndex = null
933
- this.crosshairPrice = null
934
- this.hoveredIndex = null
935
- this.activePaneId = null
936
- this.markerState.reset()
937
- this.kLinePositions = null
938
- this.kLineCenters = null
939
- this.visibleRange = null
940
- this.lastHoverRenderKey = ''
941
- this.kWidthPx = null
942
- }
943
-
944
- /** 获取十字线指向的 K 线索引 */
945
- getCrosshairIndex(): number | null {
946
- return this.crosshairIndex
947
- }
439
+ const deltaY = e.clientY - this.dragStartY
440
+ this.dragStartY = e.clientY
441
+ if (deltaY !== 0 && this.activePaneIdOnDrag === 'main') {
442
+ if (!this.settings.disableMainPaneVerticalScroll) {
443
+ this.chart.translatePrice(this.activePaneIdOnDrag, deltaY)
444
+ }
445
+ }
446
+ }
447
+ return
448
+ }
449
+
450
+ const location = this.getPlotPointerLocation(e.clientX, e.clientY)
451
+ if (!location) return
452
+ this.hoveredSeparatorUpperPaneId = this.hitTestPaneSeparator(location.mouseY)
453
+
454
+ this.updatePlotHoverFromPoint(e.clientX, e.clientY)
455
+ const hoverRenderKey = this.getHoverRenderKey()
456
+ if (hoverRenderKey !== this.lastHoverRenderKey) {
457
+ this.lastHoverRenderKey = hoverRenderKey
458
+ this.chart.scheduleDraw(UpdateLevel.Overlay)
459
+ }
460
+ this.notifyInteractionChange()
461
+ }
462
+
463
+ /**
464
+ * 设置当前帧的 K 线起始 x 坐标数组和可见范围
465
+ * @param positions K 线起始 x 坐标数组
466
+ * @param visibleRange 可见 K 线索引范围
467
+ * @param kWidthPx K 线宽度(物理像素)
468
+ * @param centers K 线中心 x 坐标数组(物理像素对齐后)
469
+ */
470
+ setKLinePositions(
471
+ positions: number[] | null,
472
+ visibleRange: { start: number; end: number } | null,
473
+ kWidthPx?: number,
474
+ centers?: number[] | null,
475
+ ) {
476
+ this.kLinePositions = positions
477
+ this.kLineCenters = centers ?? null
478
+ this.visibleRange = visibleRange
479
+ if (kWidthPx !== undefined) {
480
+ this.kWidthPx = kWidthPx
481
+ }
482
+ }
483
+
484
+ onRightAxisPointerDown(e: PointerEvent) {
485
+ if (e.isPrimary === false) return
486
+ this.isTouchSession = e.pointerType === 'touch'
487
+ const location = this.getRightAxisPointerLocation(e.clientX, e.clientY)
488
+ if (!location) return
489
+ if (this.beginScalePriceDrag(e.clientY, location.mouseY)) {
490
+ this.chart.scheduleDraw()
491
+ this.notifyInteractionChange()
492
+ }
493
+ }
494
+
495
+ onRightAxisPointerMove(e: PointerEvent) {
496
+ if (!e.isPrimary) return
497
+ if (e.pointerType === 'touch') {
498
+ this.isTouchSession = true
499
+ }
500
+
501
+ if (this.isDragging && this.dragMode === 'scale-price') {
502
+ const deltaY = e.clientY - this.dragStartY
503
+ if (deltaY !== 0 && this.activePaneIdOnDrag) {
504
+ this.chart.scalePrice(this.activePaneIdOnDrag, deltaY)
505
+ this.dragStartY = e.clientY
506
+ }
507
+ return
508
+ }
509
+
510
+ this.updateRightAxisHoverFromPoint(e.clientX, e.clientY)
511
+ const hoverRenderKey = this.getHoverRenderKey()
512
+ if (hoverRenderKey !== this.lastHoverRenderKey) {
513
+ this.lastHoverRenderKey = hoverRenderKey
514
+ this.chart.scheduleDraw(UpdateLevel.Overlay)
515
+ }
516
+ this.notifyInteractionChange()
517
+ }
518
+
519
+ onRightAxisPointerUp(e: PointerEvent) {
520
+ this.onPointerUp(e)
521
+ }
522
+
523
+ onRightAxisPointerLeave(e: PointerEvent) {
524
+ if (e.isPrimary === false) return
525
+ if (this.isDragging && this.dragMode === 'scale-price') return
526
+ this.hoveredRightAxisPaneId = null
527
+ this.notifyInteractionChange()
528
+ }
529
+
530
+ /** 检查是否正在拖拽 */
531
+ isDraggingState(): boolean {
532
+ return this.isDragging
533
+ }
534
+
535
+ setOnMarkerHover(callback: (marker: MarkerEntity | null) => void) {
536
+ this.markerState.setOnMarkerHover(callback)
537
+ }
538
+
539
+ setOnMarkerClick(callback: (marker: MarkerEntity) => void) {
540
+ this.markerState.setOnMarkerClick(callback)
541
+ }
542
+
543
+ setOnCustomMarkerHover(callback: (marker: CustomMarkerEntity | null) => void) {
544
+ this.markerState.setOnCustomMarkerHover(callback)
545
+ }
546
+
547
+ setOnCustomMarkerClick(callback: (marker: CustomMarkerEntity) => void) {
548
+ this.markerState.setOnCustomMarkerClick(callback)
549
+ }
550
+
551
+ /** 命中可拖拽分隔线(返回上方 paneId) */
552
+ private hitTestPaneSeparator(mouseY: number): string | null {
553
+ const paneRenderers = this.chart.getPaneRenderers()
554
+ if (paneRenderers.length < 2) return null
555
+
556
+ const SEP_HIT_HALF = 5
557
+ for (let i = 0; i < paneRenderers.length - 1; i++) {
558
+ const upper = paneRenderers[i]?.getPane()
559
+ const lower = paneRenderers[i + 1]?.getPane()
560
+ if (!upper || !lower) continue
561
+ const boundaryY = upper.top + upper.height
562
+ if (Math.abs(mouseY - boundaryY) <= SEP_HIT_HALF) {
563
+ return upper.id
564
+ }
565
+ }
566
+ return null
567
+ }
568
+
569
+ private getPaneByY(mouseY: number) {
570
+ const paneRenderers = this.chart.getPaneRenderers()
571
+ const renderer = paneRenderers.find((r) => {
572
+ const pane = r.getPane()
573
+ return mouseY >= pane.top && mouseY <= pane.top + pane.height
574
+ })
575
+ return renderer?.getPane() || null
576
+ }
577
+
578
+ private getPlotPointerLocation(clientX: number, clientY: number): PointerLocation | null {
579
+ const container = this.chart.getDom().container
580
+ const rect = container.getBoundingClientRect()
581
+ const mouseX = clientX - rect.left
582
+ const mouseY = clientY - rect.top
583
+ return { mouseX, mouseY }
584
+ }
585
+
586
+ private getRightAxisPointerLocation(clientX: number, clientY: number): PointerLocation {
587
+ const rightAxisLayer = this.chart.getDom().rightAxisLayer
588
+ const rect = rightAxisLayer.getBoundingClientRect()
589
+ const mouseX = clientX - rect.left
590
+ const mouseY = clientY - rect.top
591
+ return { mouseX, mouseY }
592
+ }
593
+
594
+ private beginScalePriceDrag(clientY: number, mouseY: number) {
595
+ const pane = this.getPaneByY(mouseY)
596
+ if (!pane) return false
597
+ // 主图禁用垂直滚动时,禁止价格轴缩放
598
+ if (pane.id === 'main' && this.settings.disableMainPaneVerticalScroll) {
599
+ return false
600
+ }
601
+ this.isDragging = true
602
+ this.dragMode = 'scale-price'
603
+ this.dragStartY = clientY
604
+ this.activePaneIdOnDrag = pane.id
605
+ this.hoveredRightAxisPaneId = pane.id
606
+ this.hoveredSeparatorUpperPaneId = null
607
+ this.crosshairPos = null
608
+ this.crosshairIndex = null
609
+ this.crosshairPrice = null
610
+ this.hoveredIndex = null
611
+ this.activePaneId = pane.id
612
+ return true
613
+ }
614
+
615
+ clearHover() {
616
+ this.lastHoverRenderKey = ''
617
+ this.hoveredRightAxisPaneId = null
618
+ this.crosshairPos = null
619
+ this.crosshairIndex = null
620
+ this.crosshairPrice = null
621
+ this.hoveredIndex = null
622
+ this.activePaneId = null
623
+
624
+ this.markerState.clearAll(this.chart.getMarkerManager())
625
+ }
626
+
627
+ private clearSeparatorState() {
628
+ this.activeSeparatorUpperPaneId = null
629
+ this.hoveredSeparatorUpperPaneId = null
630
+ this.hoveredRightAxisPaneId = null
631
+ }
632
+
633
+ /**
634
+ * 从屏幕坐标更新 hover 状态
635
+ * @param clientX 屏幕 x 坐标
636
+ * @param clientY 屏幕 y 坐标
637
+ */
638
+
639
+ private updateRightAxisHoverFromPoint(clientX: number, clientY: number) {
640
+ const location = this.getRightAxisPointerLocation(clientX, clientY)
641
+ if (!location) return
642
+
643
+ const { mouseY } = location
644
+ const viewport = this.chart.getViewport()
645
+ const plotHeight =
646
+ viewport?.plotHeight ?? Math.max(1, Math.round(this.chart.getDom().container.clientHeight))
647
+ if (mouseY < 0 || mouseY > plotHeight) {
648
+ this.hoveredRightAxisPaneId = null
649
+ return
650
+ }
651
+
652
+ const pane = this.getPaneByY(mouseY)
653
+ this.hoveredRightAxisPaneId = pane?.id || null
654
+ this.hoveredSeparatorUpperPaneId = null
655
+ this.crosshairPos = null
656
+ this.crosshairIndex = null
657
+ this.crosshairPrice = null
658
+ this.hoveredIndex = null
659
+ this.activePaneId = pane?.id || null
660
+ }
661
+
662
+ /**
663
+ * 指针悬停检测(coordinator)
664
+ *
665
+ * 每次指针移动时触发,按优先级依次检测:
666
+ * 边界 → pane 分隔器 → marker → K 线 bar → 十字线定位 → candle 命中 → tooltip。
667
+ * 每个步骤都可能提前 return,无需执行后续检测。
668
+ */
669
+ private updatePlotHoverFromPoint(clientX: number, clientY: number) {
670
+ const ctx = this.resolveHoverContext(clientX, clientY)
671
+ if (!ctx) return
672
+
673
+ if (this.handleSeparatorHit(ctx)) return
674
+ if (this.handleMarkerHit(ctx)) return
675
+
676
+ const bar = this.findNearestBar(ctx)
677
+ if (!bar) {
678
+ this.clearHover()
679
+ return
680
+ }
681
+
682
+ this.positionCrosshair(ctx, bar)
683
+
684
+ if (this.chart.currentPeriod === 'timeshare') {
685
+ this.handleTimeshareHover(ctx, bar)
686
+ return
687
+ }
688
+
689
+ if (!this.hitTestCandle(ctx, bar)) {
690
+ this.hoveredIndex = null
691
+ return
692
+ }
693
+
694
+ this.hoveredIndex = bar.globalIdx
695
+ this.updateTooltip(ctx)
696
+ }
697
+
698
+ /**
699
+ * 解析悬停上下文
700
+ *
701
+ * 将 client 坐标转换为 plot 坐标,并做边界检查。
702
+ * 返回 null 表示指针不在 plot 区域内。
703
+ */
704
+ private resolveHoverContext(clientX: number, clientY: number): HoverContext | null {
705
+ const location = this.getPlotPointerLocation(clientX, clientY)
706
+ if (!location) return null
707
+
708
+ const { mouseX, mouseY } = location
709
+ const container = this.chart.getDom().container
710
+ const viewport = this.chart.getViewport()
711
+ const viewWidth = viewport?.viewWidth ?? Math.max(1, Math.round(container.clientWidth))
712
+ const viewHeight = viewport?.viewHeight ?? Math.max(1, Math.round(container.clientHeight))
713
+ const plotWidth = viewport?.plotWidth ?? viewWidth
714
+ const plotHeight = viewport?.plotHeight ?? viewHeight
715
+
716
+ if (mouseX < 0 || mouseY < 0 || mouseX > plotWidth || mouseY > plotHeight) {
717
+ this.clearHover()
718
+ return null
719
+ }
720
+
721
+ const scrollLeft = this.chart.getLogicalScrollLeft()
722
+ const dpr = this.chart.getCurrentDpr()
723
+
724
+ return {
725
+ mouseX,
726
+ mouseY,
727
+ plotWidth,
728
+ plotHeight,
729
+ viewWidth,
730
+ viewHeight,
731
+ scrollLeft,
732
+ dpr,
733
+ worldX: scrollLeft + mouseX,
734
+ }
735
+ }
736
+
737
+ /**
738
+ * 检测 pane 分隔器悬停
739
+ *
740
+ * 若指针悬浮在 pane 分隔条上,清除十字线状态并返回 true。
741
+ */
742
+ private handleSeparatorHit(ctx: HoverContext): boolean {
743
+ this.hoveredRightAxisPaneId = null
744
+ const separatorUpperPaneId = this.hitTestPaneSeparator(ctx.mouseY)
745
+ this.hoveredSeparatorUpperPaneId = separatorUpperPaneId
746
+ if (separatorUpperPaneId) {
747
+ this.crosshairPos = null
748
+ this.crosshairIndex = null
749
+ this.crosshairPrice = null
750
+ this.hoveredIndex = null
751
+ this.activePaneId = null
752
+ return true
753
+ }
754
+ return false
755
+ }
756
+
757
+ /**
758
+ * 检测 marker 悬停
759
+ *
760
+ * 若指针悬浮在 marker 上,清除十字线状态并返回 true。
761
+ */
762
+ private handleMarkerHit(ctx: HoverContext): boolean {
763
+ const markerManager = this.chart.getMarkerManager()
764
+ if (this.markerState.updateHoverFromPoint(ctx.worldX, ctx.mouseX, ctx.mouseY, markerManager)) {
765
+ this.crosshairPos = null
766
+ this.crosshairIndex = null
767
+ this.crosshairPrice = null
768
+ this.hoveredIndex = null
769
+ return true
770
+ }
771
+ return false
772
+ }
773
+
774
+ /**
775
+ * 查找最近邻 K 线 bar
776
+ *
777
+ * 使用二分搜索在 kLinePositions 中定位指针最近的 K 线 bar。
778
+ * 若无 kLinePositions、visibleRange 或 kWidthPx,返回 null。
779
+ */
780
+ private findNearestBar(ctx: HoverContext): NearestBar | null {
781
+ if (!this.kLinePositions || !this.visibleRange || !this.kWidthPx) return null
782
+
783
+ const { worldX, mouseY, dpr } = ctx
784
+ const kWidthLogical = this.kWidthPx / dpr
785
+ const positions = this.kLinePositions
786
+
787
+ let lo = 0,
788
+ hi = positions.length
789
+ while (lo < hi) {
790
+ const mid = (lo + hi) >> 1
791
+ if (positions[mid]! < worldX) {
792
+ lo = mid + 1
793
+ } else {
794
+ hi = mid
795
+ }
796
+ }
797
+
798
+ let localIdx = lo
799
+ if (lo > 0 && lo < positions.length) {
800
+ const prevCenter = positions[lo - 1]! + kWidthLogical / 2
801
+ const currCenter = positions[lo]! + kWidthLogical / 2
802
+ if (Math.abs(worldX - prevCenter) < Math.abs(worldX - currCenter)) {
803
+ localIdx = lo - 1
804
+ }
805
+ } else if (lo === positions.length && positions.length > 0) {
806
+ localIdx = positions.length - 1
807
+ }
808
+
809
+ return {
810
+ localIdx,
811
+ globalIdx: localIdx + this.visibleRange.start,
812
+ kLineStartX: positions[localIdx]!,
813
+ widthLogical: kWidthLogical,
814
+ }
815
+ }
816
+
817
+ /**
818
+ * 定位十字线
819
+ *
820
+ * 根据最近邻 bar 设置 crosshairIndex、crosshairPos(snap 到 K 线中心)
821
+ * 以及 crosshairPrice(鼠标 Y → 价格)。
822
+ * 索引无效时清除十字线状态。
823
+ */
824
+ private positionCrosshair(ctx: HoverContext, bar: NearestBar): void {
825
+ const { mouseX, mouseY, scrollLeft, plotWidth, plotHeight, dpr } = ctx
826
+ const pane = this.getPaneByY(mouseY)
827
+ this.activePaneId = pane?.id || null
828
+
829
+ if (bar.globalIdx < 0 || bar.globalIdx >= (this.chart.getRenderData()?.length ?? 0)) {
830
+ this.crosshairIndex = null
831
+ this.crosshairPos = null
832
+ this.crosshairPrice = null
833
+ return
834
+ }
835
+
836
+ this.crosshairIndex = bar.globalIdx
837
+
838
+ const centerX = this.kLineCenters?.[bar.localIdx] ?? bar.kLineStartX + bar.widthLogical / 2
839
+ const snappedX = centerX - scrollLeft
840
+
841
+ this.crosshairPos = {
842
+ x: Math.min(Math.max(snappedX, 0), plotWidth),
843
+ y: Math.min(Math.max(mouseY, 0), plotHeight),
844
+ }
845
+
846
+ if (pane) {
847
+ const localY = mouseY - pane.top
848
+ this.crosshairPrice = pane.yAxis.yToPrice(localY)
849
+ } else {
850
+ this.crosshairPrice = null
851
+ }
852
+ }
853
+
854
+ /**
855
+ * 分时模式悬停处理
856
+ *
857
+ * 分时模式下直接设置 hoveredIndex 并计算 tooltip 位置后返回,
858
+ * 不执行 candle body/wick 命中检测。
859
+ */
860
+ private handleTimeshareHover(ctx: HoverContext, bar: NearestBar): void {
861
+ this.hoveredIndex = bar.globalIdx
862
+ this.updateTooltip(ctx)
863
+ }
864
+
865
+ /**
866
+ * Candle 实体/影线命中检测
867
+ *
868
+ * 检测指针是否落在 K 线实体内或影线上。
869
+ * 小实体(< 8px)会扩展命中区域以保证可用性。
870
+ * 未命中时返回 false。
871
+ */
872
+ private hitTestCandle(ctx: HoverContext, bar: NearestBar): boolean {
873
+ const { mouseY, worldX, dpr } = ctx
874
+ const data = this.chart.getRenderData()
875
+ const k =
876
+ typeof this.crosshairIndex === 'number'
877
+ ? (data?.[this.crosshairIndex] as KLineData | undefined)
878
+ : undefined
879
+ const pane = this.getPaneByY(mouseY)
880
+
881
+ if (!k || !pane || !pane.capabilities.candleHitTest) return false
882
+
883
+ const localY = mouseY - pane.top
884
+ const openY = pane.yAxis.priceToY(k.open)
885
+ const closeY = pane.yAxis.priceToY(k.close)
886
+ const highY = pane.yAxis.priceToY(k.high)
887
+ const lowY = pane.yAxis.priceToY(k.low)
888
+ const bodyTop = Math.min(openY, closeY)
889
+ const bodyBottom = Math.max(openY, closeY)
890
+
891
+ const inUnitX = worldX - bar.kLineStartX
892
+ const cxLogical = bar.widthLogical / 2
893
+
894
+ const MIN_BODY_HIT_HEIGHT = 8
895
+ const bodyHeight = Math.abs(bodyBottom - bodyTop)
896
+ const effectiveBodyTop =
897
+ bodyHeight < MIN_BODY_HIT_HEIGHT
898
+ ? (bodyTop + bodyBottom) / 2 - MIN_BODY_HIT_HEIGHT / 2
899
+ : bodyTop
900
+ const effectiveBodyBottom =
901
+ bodyHeight < MIN_BODY_HIT_HEIGHT
902
+ ? (bodyTop + bodyBottom) / 2 + MIN_BODY_HIT_HEIGHT / 2
903
+ : bodyBottom
904
+
905
+ const HIT_WICK_HALF_EXTENDED = 3
906
+
907
+ const hitBody =
908
+ localY >= effectiveBodyTop &&
909
+ localY <= effectiveBodyBottom &&
910
+ inUnitX >= 0 &&
911
+ inUnitX <= bar.widthLogical
912
+ const hitWick =
913
+ Math.abs(inUnitX - cxLogical) <= HIT_WICK_HALF_EXTENDED &&
914
+ localY >= Math.min(highY, lowY) &&
915
+ localY <= Math.max(highY, lowY)
916
+
917
+ return hitBody || hitWick
918
+ }
919
+
920
+ /**
921
+ * 更新 tooltip 位置
922
+ *
923
+ * 使用 computeTooltipPosition 计算 tooltip 的显示位置和锚点方向。
924
+ */
925
+ private updateTooltip(ctx: HoverContext): void {
926
+ const { mouseX, mouseY, viewWidth, viewHeight, plotWidth, plotHeight } = ctx
927
+ const tooltipResult = computeTooltipPosition({
928
+ mouseX,
929
+ mouseY,
930
+ viewWidth,
931
+ viewHeight,
932
+ plotWidth,
933
+ plotHeight,
934
+ tooltipSize: this.tooltipSize,
935
+ useAnchorPositioning: this.useTooltipAnchorPositioning,
936
+ })
937
+ if (tooltipResult.anchorPlacement) {
938
+ this.tooltipAnchorPlacement = tooltipResult.anchorPlacement
939
+ }
940
+ this.tooltipPos = tooltipResult.pos
941
+ }
942
+
943
+ /**
944
+ * 重置所有交互状态(数据更新时调用)
945
+ */
946
+ reset(): void {
947
+ this.isDragging = false
948
+ this.dragMode = 'none'
949
+ this.dragStartX = 0
950
+ this.dragStartY = 0
951
+ this.scrollStartX = 0
952
+ this.activePaneIdOnDrag = null
953
+ this.clearSeparatorState()
954
+ this.isTouchSession = false
955
+ this.pinchTracker.reset()
956
+ this.crosshairPos = null
957
+ this.crosshairIndex = null
958
+ this.crosshairPrice = null
959
+ this.hoveredIndex = null
960
+ this.activePaneId = null
961
+ this.markerState.reset()
962
+ this.kLinePositions = null
963
+ this.kLineCenters = null
964
+ this.visibleRange = null
965
+ this.lastHoverRenderKey = ''
966
+ this.kWidthPx = null
967
+ }
968
+
969
+ /** 获取十字线指向的 K 线索引 */
970
+ getCrosshairIndex(): number | null {
971
+ return this.crosshairIndex
972
+ }
948
973
  }