@363045841yyt/klinechart-core 0.9.0-alpha.0 → 0.9.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. package/dist/controllers/createChartController.d.ts.map +1 -1
  2. package/dist/controllers/createChartController.js +31 -13
  3. package/dist/controllers/createChartController.js.map +1 -1
  4. package/dist/controllers/index.d.ts +1 -0
  5. package/dist/controllers/index.d.ts.map +1 -1
  6. package/dist/controllers/index.js.map +1 -1
  7. package/dist/controllers/types.d.ts +12 -0
  8. package/dist/controllers/types.d.ts.map +1 -1
  9. package/dist/engine/chart.d.ts +29 -11
  10. package/dist/engine/chart.d.ts.map +1 -1
  11. package/dist/engine/chart.js +147 -25
  12. package/dist/engine/chart.js.map +1 -1
  13. package/dist/engine/controller/interaction.d.ts +29 -4
  14. package/dist/engine/controller/interaction.d.ts.map +1 -1
  15. package/dist/engine/controller/interaction.js +78 -31
  16. package/dist/engine/controller/interaction.js.map +1 -1
  17. package/dist/engine/data/incrementalLoadHint.d.ts.map +1 -1
  18. package/dist/engine/data/incrementalLoadHint.js +5 -1
  19. package/dist/engine/data/incrementalLoadHint.js.map +1 -1
  20. package/dist/engine/drawing/DrawingState.d.ts +19 -34
  21. package/dist/engine/drawing/DrawingState.d.ts.map +1 -1
  22. package/dist/engine/drawing/DrawingState.js +110 -92
  23. package/dist/engine/drawing/DrawingState.js.map +1 -1
  24. package/dist/engine/drawing/index.d.ts +4 -1
  25. package/dist/engine/drawing/index.d.ts.map +1 -1
  26. package/dist/engine/drawing/index.js +9 -4
  27. package/dist/engine/drawing/index.js.map +1 -1
  28. package/dist/engine/drawing/interaction.d.ts +9 -29
  29. package/dist/engine/drawing/interaction.d.ts.map +1 -1
  30. package/dist/engine/drawing/interaction.js +23 -40
  31. package/dist/engine/drawing/interaction.js.map +1 -1
  32. package/dist/engine/indicators/chartIndicatorManager.d.ts.map +1 -1
  33. package/dist/engine/indicators/chartIndicatorManager.js +4 -12
  34. package/dist/engine/indicators/chartIndicatorManager.js.map +1 -1
  35. package/dist/engine/layout/chartPaneLayout.d.ts +0 -2
  36. package/dist/engine/layout/chartPaneLayout.d.ts.map +1 -1
  37. package/dist/engine/layout/chartPaneLayout.js +5 -9
  38. package/dist/engine/layout/chartPaneLayout.js.map +1 -1
  39. package/dist/engine/layout/pane.d.ts +0 -39
  40. package/dist/engine/layout/pane.d.ts.map +1 -1
  41. package/dist/engine/layout/pane.js +0 -9
  42. package/dist/engine/layout/pane.js.map +1 -1
  43. package/dist/engine/paneRenderer.d.ts +1 -10
  44. package/dist/engine/paneRenderer.d.ts.map +1 -1
  45. package/dist/engine/paneRenderer.js +2 -19
  46. package/dist/engine/paneRenderer.js.map +1 -1
  47. package/dist/engine/render/chartRenderer.d.ts +49 -8
  48. package/dist/engine/render/chartRenderer.d.ts.map +1 -1
  49. package/dist/engine/render/chartRenderer.js +143 -72
  50. package/dist/engine/render/chartRenderer.js.map +1 -1
  51. package/dist/engine/renderers/Indicator/atr.js +3 -13
  52. package/dist/engine/renderers/Indicator/atr.js.map +1 -1
  53. package/dist/engine/renderers/Indicator/boll.d.ts.map +1 -1
  54. package/dist/engine/renderers/Indicator/boll.js +12 -24
  55. package/dist/engine/renderers/Indicator/boll.js.map +1 -1
  56. package/dist/engine/renderers/Indicator/cci.js +6 -13
  57. package/dist/engine/renderers/Indicator/cci.js.map +1 -1
  58. package/dist/engine/renderers/Indicator/chaikinVol.js +3 -11
  59. package/dist/engine/renderers/Indicator/chaikinVol.js.map +1 -1
  60. package/dist/engine/renderers/Indicator/cmf.js +3 -11
  61. package/dist/engine/renderers/Indicator/cmf.js.map +1 -1
  62. package/dist/engine/renderers/Indicator/dema.js +3 -11
  63. package/dist/engine/renderers/Indicator/dema.js.map +1 -1
  64. package/dist/engine/renderers/Indicator/donchian.js +3 -11
  65. package/dist/engine/renderers/Indicator/donchian.js.map +1 -1
  66. package/dist/engine/renderers/Indicator/ene.d.ts.map +1 -1
  67. package/dist/engine/renderers/Indicator/ene.js +12 -24
  68. package/dist/engine/renderers/Indicator/ene.js.map +1 -1
  69. package/dist/engine/renderers/Indicator/expma.d.ts.map +1 -1
  70. package/dist/engine/renderers/Indicator/expma.js +5 -11
  71. package/dist/engine/renderers/Indicator/expma.js.map +1 -1
  72. package/dist/engine/renderers/Indicator/fastk.js +6 -13
  73. package/dist/engine/renderers/Indicator/fastk.js.map +1 -1
  74. package/dist/engine/renderers/Indicator/fib.js +3 -11
  75. package/dist/engine/renderers/Indicator/fib.js.map +1 -1
  76. package/dist/engine/renderers/Indicator/hma.js +3 -11
  77. package/dist/engine/renderers/Indicator/hma.js.map +1 -1
  78. package/dist/engine/renderers/Indicator/hv.js +3 -11
  79. package/dist/engine/renderers/Indicator/hv.js.map +1 -1
  80. package/dist/engine/renderers/Indicator/ichimoku.js +24 -18
  81. package/dist/engine/renderers/Indicator/ichimoku.js.map +1 -1
  82. package/dist/engine/renderers/Indicator/kama.js +3 -11
  83. package/dist/engine/renderers/Indicator/kama.js.map +1 -1
  84. package/dist/engine/renderers/Indicator/keltner.js +3 -11
  85. package/dist/engine/renderers/Indicator/keltner.js.map +1 -1
  86. package/dist/engine/renderers/Indicator/kst.js +9 -17
  87. package/dist/engine/renderers/Indicator/kst.js.map +1 -1
  88. package/dist/engine/renderers/Indicator/ma.d.ts.map +1 -1
  89. package/dist/engine/renderers/Indicator/ma.js +10 -21
  90. package/dist/engine/renderers/Indicator/ma.js.map +1 -1
  91. package/dist/engine/renderers/Indicator/macd.js +14 -44
  92. package/dist/engine/renderers/Indicator/macd.js.map +1 -1
  93. package/dist/engine/renderers/Indicator/mfi.js +3 -11
  94. package/dist/engine/renderers/Indicator/mfi.js.map +1 -1
  95. package/dist/engine/renderers/Indicator/mom.js +6 -13
  96. package/dist/engine/renderers/Indicator/mom.js.map +1 -1
  97. package/dist/engine/renderers/Indicator/obv.js +3 -11
  98. package/dist/engine/renderers/Indicator/obv.js.map +1 -1
  99. package/dist/engine/renderers/Indicator/parkinson.js +3 -11
  100. package/dist/engine/renderers/Indicator/parkinson.js.map +1 -1
  101. package/dist/engine/renderers/Indicator/pvt.js +3 -11
  102. package/dist/engine/renderers/Indicator/pvt.js.map +1 -1
  103. package/dist/engine/renderers/Indicator/roc.js +3 -11
  104. package/dist/engine/renderers/Indicator/roc.js.map +1 -1
  105. package/dist/engine/renderers/Indicator/rsi.js +12 -20
  106. package/dist/engine/renderers/Indicator/rsi.js.map +1 -1
  107. package/dist/engine/renderers/Indicator/shared/webglBand.d.ts +0 -2
  108. package/dist/engine/renderers/Indicator/shared/webglBand.d.ts.map +1 -1
  109. package/dist/engine/renderers/Indicator/shared/webglBand.js +0 -6
  110. package/dist/engine/renderers/Indicator/shared/webglBand.js.map +1 -1
  111. package/dist/engine/renderers/Indicator/stoch.js +9 -17
  112. package/dist/engine/renderers/Indicator/stoch.js.map +1 -1
  113. package/dist/engine/renderers/Indicator/tema.js +3 -11
  114. package/dist/engine/renderers/Indicator/tema.js.map +1 -1
  115. package/dist/engine/renderers/Indicator/trix.js +3 -11
  116. package/dist/engine/renderers/Indicator/trix.js.map +1 -1
  117. package/dist/engine/renderers/Indicator/vma.js +3 -11
  118. package/dist/engine/renderers/Indicator/vma.js.map +1 -1
  119. package/dist/engine/renderers/Indicator/vwap.js +3 -11
  120. package/dist/engine/renderers/Indicator/vwap.js.map +1 -1
  121. package/dist/engine/renderers/Indicator/wma.js +3 -11
  122. package/dist/engine/renderers/Indicator/wma.js.map +1 -1
  123. package/dist/engine/renderers/Indicator/wmsr.js +6 -13
  124. package/dist/engine/renderers/Indicator/wmsr.js.map +1 -1
  125. package/dist/engine/renderers/candle.d.ts.map +1 -1
  126. package/dist/engine/renderers/candle.js +21 -28
  127. package/dist/engine/renderers/candle.js.map +1 -1
  128. package/dist/engine/renderers/candleViaRenderer.d.ts +19 -0
  129. package/dist/engine/renderers/candleViaRenderer.d.ts.map +1 -0
  130. package/dist/engine/renderers/candleViaRenderer.js +15 -0
  131. package/dist/engine/renderers/candleViaRenderer.js.map +1 -0
  132. package/dist/engine/renderers/linesViaRenderer.d.ts +55 -0
  133. package/dist/engine/renderers/linesViaRenderer.d.ts.map +1 -0
  134. package/dist/engine/renderers/linesViaRenderer.js +169 -0
  135. package/dist/engine/renderers/linesViaRenderer.js.map +1 -0
  136. package/dist/engine/renderers/rectsViaRenderer.d.ts +18 -0
  137. package/dist/engine/renderers/rectsViaRenderer.d.ts.map +1 -0
  138. package/dist/engine/renderers/rectsViaRenderer.js +63 -0
  139. package/dist/engine/renderers/rectsViaRenderer.js.map +1 -0
  140. package/dist/engine/renderers/subVolume.js +7 -26
  141. package/dist/engine/renderers/subVolume.js.map +1 -1
  142. package/dist/engine/renderers/timeAxis.js +1 -1
  143. package/dist/engine/renderers/timeAxis.js.map +1 -1
  144. package/dist/engine/state/chartStateKernel.d.ts +11 -2
  145. package/dist/engine/state/chartStateKernel.d.ts.map +1 -1
  146. package/dist/engine/state/chartStateKernel.js +28 -12
  147. package/dist/engine/state/chartStateKernel.js.map +1 -1
  148. package/dist/engine/state/index.d.ts +1 -1
  149. package/dist/engine/state/index.d.ts.map +1 -1
  150. package/dist/engine/state/index.js +1 -1
  151. package/dist/engine/state/index.js.map +1 -1
  152. package/dist/engine/state/interactionState.d.ts +15 -7
  153. package/dist/engine/state/interactionState.d.ts.map +1 -1
  154. package/dist/engine/state/interactionState.js +55 -60
  155. package/dist/engine/state/interactionState.js.map +1 -1
  156. package/dist/engine/state/rendererState.d.ts +14 -0
  157. package/dist/engine/state/rendererState.d.ts.map +1 -0
  158. package/dist/engine/state/rendererState.js +25 -0
  159. package/dist/engine/state/rendererState.js.map +1 -0
  160. package/dist/engine/state/themeState.d.ts +11 -4
  161. package/dist/engine/state/themeState.d.ts.map +1 -1
  162. package/dist/engine/state/themeState.js +13 -5
  163. package/dist/engine/state/themeState.js.map +1 -1
  164. package/dist/engine/state/viewportState.d.ts.map +1 -1
  165. package/dist/engine/state/viewportState.js +7 -3
  166. package/dist/engine/state/viewportState.js.map +1 -1
  167. package/dist/engine/subPaneManager.d.ts.map +1 -1
  168. package/dist/engine/subPaneManager.js +2 -10
  169. package/dist/engine/subPaneManager.js.map +1 -1
  170. package/dist/foundation/config/chartSettings.d.ts +16 -4
  171. package/dist/foundation/config/chartSettings.d.ts.map +1 -1
  172. package/dist/foundation/config/chartSettings.js +21 -6
  173. package/dist/foundation/config/chartSettings.js.map +1 -1
  174. package/dist/foundation/plugin/index.d.ts +0 -1
  175. package/dist/foundation/plugin/index.d.ts.map +1 -1
  176. package/dist/foundation/plugin/rendererPluginManager.d.ts +1 -22
  177. package/dist/foundation/plugin/rendererPluginManager.d.ts.map +1 -1
  178. package/dist/foundation/plugin/rendererPluginManager.js +0 -84
  179. package/dist/foundation/plugin/rendererPluginManager.js.map +1 -1
  180. package/dist/foundation/plugin/types.d.ts +11 -17
  181. package/dist/foundation/plugin/types.d.ts.map +1 -1
  182. package/dist/foundation/plugin/types.js.map +1 -1
  183. package/dist/foundation/reactivity/frameTransaction.d.ts +71 -0
  184. package/dist/foundation/reactivity/frameTransaction.d.ts.map +1 -0
  185. package/dist/foundation/reactivity/frameTransaction.js +170 -0
  186. package/dist/foundation/reactivity/frameTransaction.js.map +1 -0
  187. package/dist/foundation/reactivity/index.d.ts +4 -2
  188. package/dist/foundation/reactivity/index.d.ts.map +1 -1
  189. package/dist/foundation/reactivity/index.js +2 -1
  190. package/dist/foundation/reactivity/index.js.map +1 -1
  191. package/dist/foundation/reactivity/signal.d.ts +20 -0
  192. package/dist/foundation/reactivity/signal.d.ts.map +1 -1
  193. package/dist/foundation/reactivity/signal.js +27 -0
  194. package/dist/foundation/reactivity/signal.js.map +1 -1
  195. package/dist/foundation/tokens/theme-dark.d.ts.map +1 -1
  196. package/dist/foundation/tokens/theme-dark.js +2 -1
  197. package/dist/foundation/tokens/theme-dark.js.map +1 -1
  198. package/dist/foundation/tokens/theme-light.d.ts.map +1 -1
  199. package/dist/foundation/tokens/theme-light.js +2 -1
  200. package/dist/foundation/tokens/theme-light.js.map +1 -1
  201. package/dist/rendering/render/Renderer.d.ts +29 -14
  202. package/dist/rendering/render/Renderer.d.ts.map +1 -1
  203. package/dist/rendering/render/Renderer.js +3 -10
  204. package/dist/rendering/render/Renderer.js.map +1 -1
  205. package/dist/rendering/render/SurfaceBackend.d.ts +5 -7
  206. package/dist/rendering/render/SurfaceBackend.d.ts.map +1 -1
  207. package/dist/rendering/render/SurfaceBackend.js +5 -7
  208. package/dist/rendering/render/SurfaceBackend.js.map +1 -1
  209. package/dist/rendering/render/createCanvas2DRenderer.d.ts +3 -0
  210. package/dist/rendering/render/createCanvas2DRenderer.d.ts.map +1 -0
  211. package/dist/rendering/render/createCanvas2DRenderer.js +74 -0
  212. package/dist/rendering/render/createCanvas2DRenderer.js.map +1 -0
  213. package/dist/rendering/render/createDefaultRendererHost.d.ts +4 -0
  214. package/dist/rendering/render/createDefaultRendererHost.d.ts.map +1 -0
  215. package/dist/rendering/render/createDefaultRendererHost.js +54 -0
  216. package/dist/rendering/render/createDefaultRendererHost.js.map +1 -0
  217. package/dist/rendering/render/createWebGLRenderer.d.ts.map +1 -1
  218. package/dist/rendering/render/createWebGLRenderer.js +42 -80
  219. package/dist/rendering/render/createWebGLRenderer.js.map +1 -1
  220. package/dist/rendering/render/createWebGPURenderer.d.ts +11 -0
  221. package/dist/rendering/render/createWebGPURenderer.d.ts.map +1 -0
  222. package/dist/rendering/render/createWebGPURenderer.js +619 -0
  223. package/dist/rendering/render/createWebGPURenderer.js.map +1 -0
  224. package/dist/rendering/render/createWebGPUSurfaceBackend.d.ts +15 -0
  225. package/dist/rendering/render/createWebGPUSurfaceBackend.d.ts.map +1 -0
  226. package/dist/rendering/render/createWebGPUSurfaceBackend.js +92 -0
  227. package/dist/rendering/render/createWebGPUSurfaceBackend.js.map +1 -0
  228. package/dist/rendering/render/frameMetrics.d.ts +19 -0
  229. package/dist/rendering/render/frameMetrics.d.ts.map +1 -0
  230. package/dist/rendering/render/frameMetrics.js +43 -0
  231. package/dist/rendering/render/frameMetrics.js.map +1 -0
  232. package/dist/rendering/render/index.d.ts +10 -0
  233. package/dist/rendering/render/index.d.ts.map +1 -1
  234. package/dist/rendering/render/index.js +6 -0
  235. package/dist/rendering/render/index.js.map +1 -1
  236. package/dist/rendering/render/rendererHost.d.ts +34 -0
  237. package/dist/rendering/render/rendererHost.d.ts.map +1 -0
  238. package/dist/rendering/render/rendererHost.js +144 -0
  239. package/dist/rendering/render/rendererHost.js.map +1 -0
  240. package/dist/rendering/render/webgpuResourceTable.d.ts +25 -0
  241. package/dist/rendering/render/webgpuResourceTable.d.ts.map +1 -0
  242. package/dist/rendering/render/webgpuResourceTable.js +54 -0
  243. package/dist/rendering/render/webgpuResourceTable.js.map +1 -0
  244. package/dist/rendering/scene/createLayerFromPlugin.d.ts.map +1 -1
  245. package/dist/rendering/scene/createLayerFromPlugin.js +10 -2
  246. package/dist/rendering/scene/createLayerFromPlugin.js.map +1 -1
  247. package/dist/rendering/scene/layerRegistry.d.ts +3 -5
  248. package/dist/rendering/scene/layerRegistry.d.ts.map +1 -1
  249. package/dist/rendering/scene/layerRegistry.js +1 -1
  250. package/dist/rendering/scene/layerRegistry.js.map +1 -1
  251. package/dist/rendering/scene/retainedScene.d.ts +60 -0
  252. package/dist/rendering/scene/retainedScene.d.ts.map +1 -0
  253. package/dist/rendering/scene/retainedScene.js +42 -0
  254. package/dist/rendering/scene/retainedScene.js.map +1 -0
  255. package/dist/version.d.ts +1 -1
  256. package/dist/version.js +1 -1
  257. package/package.json +2 -1
  258. package/src/__tests__/signal.test.ts +47 -1
  259. package/src/controllers/__tests__/createChartController.theme.test.ts +102 -0
  260. package/src/controllers/createChartController.ts +36 -12
  261. package/src/controllers/index.ts +5 -0
  262. package/src/controllers/types.ts +14 -0
  263. package/src/engine/__tests__/chart.dpr.test.ts +64 -0
  264. package/src/engine/__tests__/paneRenderer.resize.test.ts +0 -7
  265. package/src/engine/__tests__/renderSinglePath.test.ts +121 -0
  266. package/src/engine/chart.ts +172 -25
  267. package/src/engine/controller/__tests__/interaction.dpr.test.ts +45 -41
  268. package/src/engine/controller/interaction.ts +81 -30
  269. package/src/engine/data/__tests__/chartDataManager.incrementalLoad.test.ts +1 -0
  270. package/src/engine/data/incrementalLoadHint.ts +6 -1
  271. package/src/engine/drawing/DrawingState.ts +107 -89
  272. package/src/engine/drawing/__tests__/drawingState.workCopy.test.ts +95 -36
  273. package/src/engine/drawing/__tests__/drawingStore.projection.test.ts +22 -0
  274. package/src/engine/drawing/index.ts +12 -4
  275. package/src/engine/drawing/interaction.ts +25 -40
  276. package/src/engine/indicators/chartIndicatorManager.ts +6 -16
  277. package/src/engine/layout/chartPaneLayout.ts +6 -11
  278. package/src/engine/layout/pane.ts +0 -44
  279. package/src/engine/paneRenderer.ts +3 -34
  280. package/src/engine/render/chartRenderer.ts +181 -81
  281. package/src/engine/renderers/Indicator/atr.ts +5 -17
  282. package/src/engine/renderers/Indicator/boll.ts +15 -26
  283. package/src/engine/renderers/Indicator/cci.ts +7 -17
  284. package/src/engine/renderers/Indicator/chaikinVol.ts +3 -15
  285. package/src/engine/renderers/Indicator/cmf.ts +3 -15
  286. package/src/engine/renderers/Indicator/dema.ts +3 -15
  287. package/src/engine/renderers/Indicator/donchian.ts +3 -12
  288. package/src/engine/renderers/Indicator/ene.ts +15 -25
  289. package/src/engine/renderers/Indicator/expma.ts +4 -13
  290. package/src/engine/renderers/Indicator/fastk.ts +7 -17
  291. package/src/engine/renderers/Indicator/fib.ts +3 -12
  292. package/src/engine/renderers/Indicator/hma.ts +3 -15
  293. package/src/engine/renderers/Indicator/hv.ts +3 -15
  294. package/src/engine/renderers/Indicator/ichimoku.ts +21 -24
  295. package/src/engine/renderers/Indicator/kama.ts +3 -15
  296. package/src/engine/renderers/Indicator/keltner.ts +3 -12
  297. package/src/engine/renderers/Indicator/kst.ts +9 -20
  298. package/src/engine/renderers/Indicator/ma.ts +9 -21
  299. package/src/engine/renderers/Indicator/macd.ts +27 -102
  300. package/src/engine/renderers/Indicator/mfi.ts +3 -15
  301. package/src/engine/renderers/Indicator/mom.ts +7 -17
  302. package/src/engine/renderers/Indicator/obv.ts +3 -15
  303. package/src/engine/renderers/Indicator/parkinson.ts +3 -15
  304. package/src/engine/renderers/Indicator/pvt.ts +3 -15
  305. package/src/engine/renderers/Indicator/roc.ts +3 -15
  306. package/src/engine/renderers/Indicator/rsi.ts +12 -23
  307. package/src/engine/renderers/Indicator/shared/webglBand.ts +0 -13
  308. package/src/engine/renderers/Indicator/stoch.ts +9 -20
  309. package/src/engine/renderers/Indicator/tema.ts +3 -15
  310. package/src/engine/renderers/Indicator/trix.ts +3 -12
  311. package/src/engine/renderers/Indicator/vma.ts +3 -15
  312. package/src/engine/renderers/Indicator/vwap.ts +3 -15
  313. package/src/engine/renderers/Indicator/wma.ts +3 -15
  314. package/src/engine/renderers/Indicator/wmsr.ts +7 -17
  315. package/src/engine/renderers/__tests__/candle.sceneRenderer.test.ts +208 -0
  316. package/src/engine/renderers/__tests__/candleViaRenderer.test.ts +100 -0
  317. package/src/engine/renderers/__tests__/linesViaRenderer.test.ts +263 -0
  318. package/src/engine/renderers/__tests__/rectsViaRenderer.test.ts +87 -0
  319. package/src/engine/renderers/candle.ts +26 -69
  320. package/src/engine/renderers/candleViaRenderer.ts +38 -0
  321. package/src/engine/renderers/linesViaRenderer.ts +226 -0
  322. package/src/engine/renderers/rectsViaRenderer.ts +83 -0
  323. package/src/engine/renderers/subVolume.ts +9 -61
  324. package/src/engine/renderers/timeAxis.ts +1 -1
  325. package/src/engine/state/__tests__/effectiveTheme.test.ts +49 -0
  326. package/src/engine/state/__tests__/rendererState.test.ts +36 -0
  327. package/src/engine/state/__tests__/settingsState.test.ts +1 -1
  328. package/src/engine/state/chartStateKernel.ts +38 -17
  329. package/src/engine/state/index.ts +6 -1
  330. package/src/engine/state/interactionState.ts +73 -102
  331. package/src/engine/state/rendererState.ts +32 -0
  332. package/src/engine/state/themeState.ts +15 -8
  333. package/src/engine/state/viewportState.ts +6 -3
  334. package/src/engine/subPaneManager.ts +2 -16
  335. package/src/foundation/config/__tests__/chartSettings.test.ts +25 -0
  336. package/src/foundation/config/chartSettings.ts +24 -7
  337. package/src/foundation/plugin/index.ts +0 -1
  338. package/src/foundation/plugin/rendererPluginManager.ts +0 -99
  339. package/src/foundation/plugin/types.ts +11 -18
  340. package/src/foundation/reactivity/__tests__/frameTransaction.test.ts +306 -0
  341. package/src/foundation/reactivity/frameTransaction.ts +239 -0
  342. package/src/foundation/reactivity/index.ts +8 -0
  343. package/src/foundation/reactivity/signal.ts +39 -0
  344. package/src/foundation/tokens/__tests__/__snapshots__/baseline.test.ts.snap +2 -2
  345. package/src/foundation/tokens/theme-dark.ts +2 -1
  346. package/src/foundation/tokens/theme-light.ts +2 -1
  347. package/src/rendering/render/Renderer.ts +27 -14
  348. package/src/rendering/render/SurfaceBackend.ts +5 -7
  349. package/src/rendering/render/__tests__/canvas2DRenderer.test.ts +34 -0
  350. package/src/rendering/render/__tests__/contract.test.ts +2 -2
  351. package/src/rendering/render/__tests__/frameMetrics.test.ts +24 -0
  352. package/src/rendering/render/__tests__/rendererHost.test.ts +157 -0
  353. package/src/rendering/render/__tests__/webglRenderer.fallback.test.ts +14 -74
  354. package/src/rendering/render/__tests__/webglRenderer.test.ts +64 -6
  355. package/src/rendering/render/__tests__/webgpuRenderer.test.ts +370 -0
  356. package/src/rendering/render/__tests__/webgpuResourceTable.test.ts +62 -0
  357. package/src/rendering/render/__tests__/webgpuSurfaceBackend.test.ts +120 -0
  358. package/src/rendering/render/createCanvas2DRenderer.ts +83 -0
  359. package/src/rendering/render/createDefaultRendererHost.ts +74 -0
  360. package/src/rendering/render/createWebGLRenderer.ts +41 -87
  361. package/src/rendering/render/createWebGPURenderer.ts +677 -0
  362. package/src/rendering/render/createWebGPUSurfaceBackend.ts +106 -0
  363. package/src/rendering/render/frameMetrics.ts +54 -0
  364. package/src/rendering/render/index.ts +30 -0
  365. package/src/rendering/render/rendererHost.ts +210 -0
  366. package/src/rendering/render/webgpuResourceTable.ts +87 -0
  367. package/src/rendering/scene/__tests__/layerFromPlugin.test.ts +29 -2
  368. package/src/rendering/scene/__tests__/retainedScene.test.ts +59 -0
  369. package/src/rendering/scene/createLayerFromPlugin.ts +9 -2
  370. package/src/rendering/scene/layerRegistry.ts +4 -6
  371. package/src/rendering/scene/retainedScene.ts +101 -0
  372. package/src/version.ts +1 -1
@@ -27,77 +27,30 @@ export interface InteractionDeps {
27
27
  scheduleDraw: (level?: unknown) => void
28
28
  }
29
29
 
30
- function computeCrosshairIndex(
31
- crosshairPos: { x: number; y: number } | null,
32
- kLinePositions: number[] | null,
33
- kWidthPx: number | null,
34
- visibleRange: { start: number; end: number } | null,
35
- scrollLeftLogical: number,
36
- dpr: number,
37
- ): number | null {
38
- if (!crosshairPos || !kLinePositions || !kWidthPx || !visibleRange) return null
39
- const kWidthLogical = kWidthPx / dpr
40
- const worldX = scrollLeftLogical + crosshairPos.x
41
- const positions = kLinePositions
42
-
43
- let lo = 0
44
- let hi = positions.length
45
- while (lo < hi) {
46
- const mid = (lo + hi) >> 1
47
- if (positions[mid]! < worldX) lo = mid + 1
48
- else hi = mid
49
- }
50
- let localIdx = lo
51
- if (lo > 0 && lo < positions.length) {
52
- const prevCenter = positions[lo - 1]! + kWidthLogical / 2
53
- const currCenter = positions[lo]! + kWidthLogical / 2
54
- if (Math.abs(worldX - prevCenter) < Math.abs(worldX - currCenter)) {
55
- localIdx = lo - 1
56
- }
57
- } else if (lo === positions.length && positions.length > 0) {
58
- localIdx = positions.length - 1
59
- }
60
- return localIdx + visibleRange.start
61
- }
62
-
63
- export function createInteractionState(deps: InteractionDeps) {
64
- const { signals, readonly } = createSubState(
65
- {
66
- crosshairPos: null as { x: number; y: number } | null,
67
- crosshairPrice: null as number | null,
68
- hoveredIndex: null as number | null,
69
- activePaneId: null as string | null,
70
- isDragging: false,
71
- dragMode: 'none' as DragMode,
72
- hoveredSeparatorUpperPaneId: null as string | null,
73
- hoveredRightAxisPaneId: null as string | null,
74
- tooltipPos: { x: 0, y: 0 },
75
- tooltipAnchorPlacement: 'right-bottom' as 'right-bottom' | 'left-bottom',
76
- hoveredMarkerData: null as MarkerEntity | null,
77
- hoveredCustomMarker: null as CustomMarkerEntity | null,
78
- hoveredMarkerId: null as string | null,
79
- kLinePositions: null as number[] | null,
80
- kLineCenters: null as number[] | null,
81
- kWidthPx: null as number | null,
82
- },
83
- {
84
- crosshairIndex: (s) => {
85
- if (!s.crosshairPos()) return null
86
- return computeCrosshairIndex(
87
- s.crosshairPos(),
88
- s.kLinePositions(),
89
- s.kWidthPx(),
90
- deps.visibleRange$(),
91
- deps.scrollLeftLogical$(),
92
- deps.dpr$(),
93
- )
94
- },
95
- },
96
- )
30
+ /**
31
+ * 交互业务态(kernel)。
32
+ * 帧几何 kLinePositions/centers/kWidth 不在此模块,由 InteractionController 私有持有。
33
+ */
34
+ export function createInteractionState(_deps: InteractionDeps) {
35
+ const { signals, readonly } = createSubState({
36
+ crosshairPos: null as { x: number; y: number } | null,
37
+ crosshairPrice: null as number | null,
38
+ /** controller flush hover 时写入,不再从几何 signal 推导 */
39
+ crosshairIndex: null as number | null,
40
+ hoveredIndex: null as number | null,
41
+ activePaneId: null as string | null,
42
+ isDragging: false,
43
+ dragMode: 'none' as DragMode,
44
+ hoveredSeparatorUpperPaneId: null as string | null,
45
+ hoveredRightAxisPaneId: null as string | null,
46
+ tooltipPos: { x: 0, y: 0 },
47
+ tooltipAnchorPlacement: 'right-bottom' as 'right-bottom' | 'left-bottom',
48
+ hoveredMarkerData: null as MarkerEntity | null,
49
+ hoveredCustomMarker: null as CustomMarkerEntity | null,
50
+ hoveredMarkerId: null as string | null,
51
+ })
97
52
 
98
- // ── 带引用缓存 + deps 收紧的 interactionSnapshot ──
99
- // crosshairPos 为 null 时跳过 visibleRange$/scrollLeftLogical$ 读取,
100
- // 避免滚动事件触发无十字线状态下的虚假重算
53
+ // ── 带引用缓存的 interactionSnapshot ──
101
54
  let _cachedSnapshot: InteractionSnapshot | null = null
102
55
  const cachedInteractionSnapshot = computed<InteractionSnapshot>(() => {
103
56
  const crosshairPos = readonly.crosshairPos()
@@ -106,20 +59,9 @@ export function createInteractionState(deps: InteractionDeps) {
106
59
  const hoveredSep = readonly.hoveredSeparatorUpperPaneId()
107
60
  const hoveredRight = readonly.hoveredRightAxisPaneId()
108
61
 
109
- const crosshairIndex = crosshairPos
110
- ? computeCrosshairIndex(
111
- crosshairPos,
112
- readonly.kLinePositions(),
113
- readonly.kWidthPx(),
114
- deps.visibleRange$(),
115
- deps.scrollLeftLogical$(),
116
- deps.dpr$(),
117
- )
118
- : null
119
-
120
62
  const next: InteractionSnapshot = {
121
63
  crosshairPos,
122
- crosshairIndex,
64
+ crosshairIndex: readonly.crosshairIndex(),
123
65
  crosshairPrice: readonly.crosshairPrice(),
124
66
  hoveredIndex,
125
67
  activePaneId: readonly.activePaneId(),
@@ -168,13 +110,39 @@ export function createInteractionState(deps: InteractionDeps) {
168
110
  readonly: mergedReadonly,
169
111
 
170
112
  actions: {
171
- updateCrosshair(pos: { x: number; y: number } | null, price: number | null) {
113
+ /**
114
+ * 更新十字线位置与价格。坐标结构相等时保留旧对象引用。
115
+ * @param index 可选;传入时同步写入 crosshairIndex(与几何同帧)
116
+ */
117
+ updateCrosshair(
118
+ pos: { x: number; y: number } | null,
119
+ price: number | null,
120
+ index?: number | null,
121
+ ) {
122
+ const prevPos = signals.crosshairPos.peek()
123
+ const prevPrice = signals.crosshairPrice.peek()
124
+ const prevIndex = signals.crosshairIndex.peek()
125
+ const nextIndex = index === undefined ? prevIndex : index
126
+ const posUnchanged =
127
+ prevPos === pos ||
128
+ (prevPos === null && pos === null) ||
129
+ (prevPos !== null &&
130
+ pos !== null &&
131
+ prevPos.x === pos.x &&
132
+ prevPos.y === pos.y)
133
+ if (posUnchanged && prevPrice === price && prevIndex === nextIndex) return
172
134
  batch(() => {
173
- signals.crosshairPos.set(pos)
174
- signals.crosshairPrice.set(price)
135
+ if (!posUnchanged) signals.crosshairPos.set(pos)
136
+ if (prevPrice !== price) signals.crosshairPrice.set(price)
137
+ if (prevIndex !== nextIndex) signals.crosshairIndex.set(nextIndex)
175
138
  })
176
139
  },
177
140
 
141
+ setCrosshairIndex(index: number | null) {
142
+ if (signals.crosshairIndex.peek() === index) return
143
+ signals.crosshairIndex.set(index)
144
+ },
145
+
178
146
  updateHover(index: number | null, paneId: string | null) {
179
147
  batch(() => {
180
148
  signals.hoveredIndex.set(index)
@@ -190,18 +158,6 @@ export function createInteractionState(deps: InteractionDeps) {
190
158
  signals.activePaneId.set(paneId)
191
159
  },
192
160
 
193
- updateFramePositions(
194
- positions: number[] | null,
195
- centers: number[] | null,
196
- kWidthPx: number | null,
197
- ) {
198
- batch(() => {
199
- signals.kLinePositions.set(positions)
200
- signals.kLineCenters.set(centers)
201
- signals.kWidthPx.set(kWidthPx)
202
- })
203
- },
204
-
205
161
  startDrag(mode: DragMode) {
206
162
  batch(() => {
207
163
  signals.isDragging.set(true)
@@ -228,13 +184,29 @@ export function createInteractionState(deps: InteractionDeps) {
228
184
  signals.hoveredRightAxisPaneId.set(paneId)
229
185
  },
230
186
 
187
+ /**
188
+ * 更新 tooltip。位置与锚点均未变时跳过写入。
189
+ */
231
190
  updateTooltip(
232
191
  pos: { x: number; y: number },
233
192
  placement: 'right-bottom' | 'left-bottom',
234
193
  ) {
194
+ const prevPos = signals.tooltipPos.peek()
195
+ const prevPlacement = signals.tooltipAnchorPlacement.peek()
196
+ if (
197
+ prevPos.x === pos.x &&
198
+ prevPos.y === pos.y &&
199
+ prevPlacement === placement
200
+ ) {
201
+ return
202
+ }
235
203
  batch(() => {
236
- signals.tooltipPos.set(pos)
237
- signals.tooltipAnchorPlacement.set(placement)
204
+ if (prevPos.x !== pos.x || prevPos.y !== pos.y) {
205
+ signals.tooltipPos.set(pos)
206
+ }
207
+ if (prevPlacement !== placement) {
208
+ signals.tooltipAnchorPlacement.set(placement)
209
+ }
238
210
  })
239
211
  },
240
212
 
@@ -254,6 +226,7 @@ export function createInteractionState(deps: InteractionDeps) {
254
226
  batch(() => {
255
227
  signals.crosshairPos.set(null)
256
228
  signals.crosshairPrice.set(null)
229
+ signals.crosshairIndex.set(null)
257
230
  signals.hoveredIndex.set(null)
258
231
  signals.activePaneId.set(null)
259
232
  signals.isDragging.set(false)
@@ -273,6 +246,7 @@ export function createInteractionState(deps: InteractionDeps) {
273
246
  batch(() => {
274
247
  signals.crosshairPos.set(null)
275
248
  signals.crosshairPrice.set(null)
249
+ signals.crosshairIndex.set(null)
276
250
  signals.hoveredIndex.set(null)
277
251
  signals.activePaneId.set(null)
278
252
  signals.isDragging.set(false)
@@ -284,9 +258,6 @@ export function createInteractionState(deps: InteractionDeps) {
284
258
  signals.hoveredMarkerData.set(null)
285
259
  signals.hoveredCustomMarker.set(null)
286
260
  signals.hoveredMarkerId.set(null)
287
- signals.kLinePositions.set(null)
288
- signals.kLineCenters.set(null)
289
- signals.kWidthPx.set(null)
290
261
  })
291
262
  },
292
263
  }
@@ -0,0 +1,32 @@
1
+ import type { RendererBackendRuntime } from '../../rendering/render/rendererHost'
2
+ import { createSubState } from '../../foundation/reactivity/signal'
3
+
4
+ function snapshot(runtime: RendererBackendRuntime): Readonly<RendererBackendRuntime> {
5
+ return Object.freeze({ ...runtime })
6
+ }
7
+
8
+ function equal(left: RendererBackendRuntime, right: RendererBackendRuntime): boolean {
9
+ return (
10
+ left.effective === right.effective && left.status === right.status && left.error === right.error
11
+ )
12
+ }
13
+
14
+ export function createRendererState(initial: RendererBackendRuntime) {
15
+ const initialSnapshot = snapshot(initial)
16
+ const { signals, readonly } = createSubState({ runtime: initialSnapshot })
17
+
18
+ return {
19
+ readonly,
20
+ actions: {
21
+ setRuntime(runtime: RendererBackendRuntime): void {
22
+ if (equal(signals.runtime.peek(), runtime)) return
23
+ signals.runtime.set(snapshot(runtime))
24
+ },
25
+ },
26
+ dispose(): void {
27
+ signals.runtime.set(initialSnapshot)
28
+ },
29
+ }
30
+ }
31
+
32
+ export type RendererStateModule = ReturnType<typeof createRendererState>
@@ -1,23 +1,30 @@
1
1
  import { createSubState } from '../../foundation/reactivity/signal'
2
2
 
3
- export function createThemeState() {
3
+ /**
4
+ * 系统主题(OS / matchMedia)注入点。
5
+ * 用户偏好在 settings.theme(含 auto);生效主题由 kernel effectiveTheme computed 推导。
6
+ */
7
+ export function createSystemThemeState() {
4
8
  const { signals, readonly } = createSubState({
5
- theme: 'light' as 'light' | 'dark',
9
+ systemTheme: 'light' as 'light' | 'dark',
6
10
  })
7
11
 
8
12
  return {
9
13
  readonly,
10
-
11
14
  actions: {
12
- setTheme(theme: 'light' | 'dark') {
13
- signals.theme.set(theme)
15
+ setSystemTheme(theme: 'light' | 'dark') {
16
+ if (signals.systemTheme.peek() === theme) return
17
+ signals.systemTheme.set(theme)
14
18
  },
15
19
  },
16
-
17
20
  dispose() {
18
- signals.theme.set('light')
21
+ signals.systemTheme.set('light')
19
22
  },
20
23
  }
21
24
  }
22
25
 
23
- export type ThemeStateModule = ReturnType<typeof createThemeState>
26
+ export type SystemThemeStateModule = ReturnType<typeof createSystemThemeState>
27
+
28
+ /** @deprecated 使用 createSystemThemeState;偏好主题在 settingsState */
29
+ export const createThemeState = createSystemThemeState
30
+ export type ThemeStateModule = SystemThemeStateModule
@@ -256,11 +256,14 @@ export function createViewportState(signalDeps: ViewportSignalDeps) {
256
256
  let webglEffect: (() => void) | null = null
257
257
  let scrollDomEffect: (() => void) | null = null
258
258
 
259
+ /**
260
+ * 写入请求 scrollLeft;与当前值相等时跳过,避免 pan 重复事件空通知。
261
+ */
259
262
  const setRequestedScrollLeft = (value: number): void => {
260
263
  const normalized = Number.isFinite(value) ? value : 0
261
- batch(() => {
262
- signals.requestedScrollLeft.set(Math.max(0, Math.min(normalized, maxScrollLeft.peek())))
263
- })
264
+ const clamped = Math.max(0, Math.min(normalized, maxScrollLeft.peek()))
265
+ if (signals.requestedScrollLeft.peek() === clamped) return
266
+ signals.requestedScrollLeft.set(clamped)
264
267
  }
265
268
 
266
269
  const syncFromDomScroll = () => {
@@ -4,7 +4,6 @@ import type {
4
4
  RendererPluginWithHost,
5
5
  RenderContext,
6
6
  } from '../foundation/plugin/index'
7
- import { createLayerFromPlugin } from '../rendering/scene/createLayerFromPlugin'
8
7
  import type { Layer } from '../rendering/scene/types'
9
8
  import type { IndicatorScheduler } from './indicators/scheduler'
10
9
  import { findIndicator } from './renderers/Indicator/indicatorCatalog'
@@ -192,11 +191,8 @@ export class SubPaneManager {
192
191
  definition,
193
192
  params: { ...entry.params },
194
193
  })
194
+ // useRenderer:注册表 + 唯一 Scene Layer
195
195
  ctx.useRenderer(renderer, { ...entry.params })
196
- ctx.setRendererEnabled(entry.rendererName, false)
197
- ctx.addLayer(
198
- createLayerFromPlugin(renderer, () => ctx.getRenderContext(entry.paneId), entry.paneId),
199
- )
200
196
  }
201
197
  this.mountScaleRenderer(ctx, entry)
202
198
  }
@@ -232,10 +228,6 @@ export class SubPaneManager {
232
228
  : null
233
229
  if (!plugin) return
234
230
  ctx.useRenderer(plugin)
235
- ctx.setRendererEnabled(entry.scaleRendererName, false)
236
- ctx.addLayer(
237
- createLayerFromPlugin(plugin, () => ctx.getRenderContext(entry.paneId), entry.paneId),
238
- )
239
231
  }
240
232
 
241
233
  private mountPaneTitleRenderer(ctx: SubPaneContext, entry: ProjectedSubPaneEntry): void {
@@ -254,10 +246,6 @@ export class SubPaneManager {
254
246
  params: { ...entry.params },
255
247
  })
256
248
  ctx.useRenderer(renderer)
257
- ctx.setRendererEnabled(entry.paneTitleRendererName, false)
258
- ctx.addLayer(
259
- createLayerFromPlugin(renderer, () => ctx.getRenderContext(entry.paneId), entry.paneId),
260
- )
261
249
  }
262
250
 
263
251
  private updateParams(ctx: SubPaneContext, resources: SubPaneResources, spec: SubPaneSpec): void {
@@ -271,13 +259,11 @@ export class SubPaneManager {
271
259
  }
272
260
 
273
261
  private unmount(ctx: SubPaneContext, entry: SubPaneResources, preserveTitle = false): void {
262
+ // removeRenderer 已同步卸 Scene Layer + Manager onUninstall,勿再 removeLayer
274
263
  ctx.removeRenderer(entry.rendererName)
275
264
  ctx.removeRenderer(entry.scaleRendererName)
276
- ctx.removeLayer(entry.layerId)
277
- ctx.removeLayer(entry.scaleLayerId)
278
265
  if (!preserveTitle) {
279
266
  ctx.removeRenderer(entry.paneTitleRendererName)
280
- ctx.removeLayer(entry.paneTitleLayerId)
281
267
  }
282
268
  }
283
269
 
@@ -0,0 +1,25 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { migrateStoredSettings, resolveSettings } from '../chartSettings'
4
+
5
+ describe('chart renderer settings', () => {
6
+ it('defaults to WebGL', () => {
7
+ expect(resolveSettings().rendererBackend).toBe('webgl')
8
+ })
9
+
10
+ it('migrates the old WebGL toggle without retaining it', () => {
11
+ expect(migrateStoredSettings({ enableWebGLRendering: true, showGridLines: false })).toEqual({
12
+ rendererBackend: 'webgl',
13
+ showGridLines: false,
14
+ })
15
+ expect(migrateStoredSettings({ enableWebGLRendering: false })).toEqual({
16
+ rendererBackend: 'canvas',
17
+ })
18
+ })
19
+
20
+ it('prefers an existing rendererBackend during migration', () => {
21
+ expect(
22
+ migrateStoredSettings({ rendererBackend: 'webgpu', enableWebGLRendering: false }),
23
+ ).toEqual({ rendererBackend: 'webgpu' })
24
+ })
25
+ })
@@ -44,9 +44,6 @@ export function getDeviceType(): 'mobile' | 'tablet' | 'desktop' {
44
44
  return 'desktop'
45
45
  }
46
46
 
47
- /** 移动端(含平板)默认不开启 WebGL */
48
- const ENABLE_WEBGL_DEFAULT = getDeviceType() === 'desktop'
49
-
50
47
  /** 默认设置配置 */
51
48
  export const DEFAULT_SETTINGS = [
52
49
  { key: 'showGridLines', label: '显示网格', type: 'boolean', default: true, group: 'main' },
@@ -96,11 +93,16 @@ export const DEFAULT_SETTINGS = [
96
93
  group: 'style',
97
94
  },
98
95
  {
99
- key: 'enableWebGLRendering',
100
- label: '启用 WebGL 硬件加速渲染',
101
- type: 'boolean',
102
- default: ENABLE_WEBGL_DEFAULT,
96
+ key: 'rendererBackend',
97
+ label: '渲染后端',
98
+ type: 'select',
99
+ default: 'webgl',
103
100
  group: 'main',
101
+ options: [
102
+ { value: 'webgl', label: 'WebGL' },
103
+ { value: 'webgpu', label: 'WebGPU' },
104
+ { value: 'canvas', label: 'Canvas' },
105
+ ],
104
106
  },
105
107
  {
106
108
  key: 'theme',
@@ -171,6 +173,21 @@ export function resolveSettings(partial?: Partial<ChartSettings>): ChartSettings
171
173
  return result as ChartSettings
172
174
  }
173
175
 
176
+ /** 将旧版持久设置迁移为 rendererBackend,返回结果不保留旧字段。 */
177
+ export function migrateStoredSettings(stored: Record<string, unknown>): Partial<ChartSettings> {
178
+ const { enableWebGLRendering, rendererBackend, ...rest } = stored
179
+ const validBackend =
180
+ rendererBackend === 'webgpu' || rendererBackend === 'webgl' || rendererBackend === 'canvas'
181
+ ? rendererBackend
182
+ : typeof enableWebGLRendering === 'boolean'
183
+ ? enableWebGLRendering
184
+ ? 'webgl'
185
+ : 'canvas'
186
+ : undefined
187
+
188
+ return validBackend ? { ...rest, rendererBackend: validBackend } : rest
189
+ }
190
+
174
191
  /** localStorage 存储键名 */
175
192
  export const SETTINGS_STORAGE_KEY = 'kline-chart-settings'
176
193
  import {
@@ -16,4 +16,3 @@ export { ConfigManager } from './ConfigManager'
16
16
 
17
17
  // 渲染器插件
18
18
  export { RendererPluginManager } from './rendererPluginManager'
19
- export type { RendererErrorEvent } from './rendererPluginManager'
@@ -2,24 +2,13 @@
2
2
  * 渲染器插件管理器
3
3
  */
4
4
 
5
- import { UpdateLevel } from '../../engine/layout/pane'
6
-
7
5
  import type {
8
6
  RendererPlugin,
9
- RenderContext,
10
7
  PaneInfo,
11
8
  RendererPluginWithHost,
12
9
  PluginHost,
13
10
  } from './types'
14
11
 
15
- /** 渲染器错误事件(裁剪后,不含大数据) */
16
- export interface RendererErrorEvent {
17
- name: string
18
- error: { message: string; stack?: string }
19
- paneId: string
20
- timestamp: number
21
- }
22
-
23
12
  /** 内部缓存 key(模块私有,避免与外部 paneId 冲突) */
24
13
  const GLOBAL_CACHE_KEY = Symbol('renderer:global-cache')
25
14
 
@@ -256,78 +245,6 @@ export class RendererPluginManager {
256
245
  return cached
257
246
  }
258
247
 
259
- /** 获取指定 pane 的渲染器(已缓存,无穿透) */
260
- getRenderers(paneId: string): RendererPlugin[] {
261
- const cached = this.getMergedRenderers(paneId)
262
-
263
- // 根据启用状态过滤,同时排除系统渲染器
264
- return cached.filter((p) => {
265
- // 系统渲染器不通过 getRenderers 返回,只能通过 renderPlugin 单独渲染
266
- if (p.isSystem) return false
267
- return this.isRendererEnabled(p)
268
- })
269
- }
270
-
271
- /** 渲染指定 pane(带错误隔离,支持按 UpdateLevel 过滤) */
272
- render(paneId: string, context: RenderContext, level?: UpdateLevel): RendererErrorEvent[] {
273
- const renderers = this.getRenderers(paneId)
274
- const errors: RendererErrorEvent[] = []
275
-
276
- for (const renderer of renderers) {
277
- // UpdateLevel 过滤:未传 level 或为 All 时不过滤
278
- if (level) {
279
- const rendererLayer = renderer.layer ?? 'main'
280
- if (level === UpdateLevel.Overlay && rendererLayer !== 'overlay') {
281
- continue // Overlay 更新时跳过非 overlay 渲染器
282
- }
283
- if (level === UpdateLevel.Main && rendererLayer === 'overlay') {
284
- continue // Main 更新时跳过 overlay 渲染器
285
- }
286
- }
287
-
288
- try {
289
- renderer.draw(context)
290
- } catch (e) {
291
- const error = e instanceof Error ? e : new Error(String(e))
292
- console.error(`[RendererPlugin] ${renderer.name} draw error:`, error)
293
- // 裁剪错误事件,不含大数据
294
- errors.push({
295
- name: renderer.name,
296
- error: { message: error.message, stack: error.stack },
297
- paneId: context.pane.id,
298
- timestamp: Date.now(),
299
- })
300
- }
301
- }
302
-
303
- return errors
304
- }
305
-
306
- /** 渲染指定名称的插件(带错误隔离,用于系统渲染器) */
307
- renderPlugin(name: string, context: RenderContext): RendererErrorEvent[] {
308
- const plugin = this.plugins.get(name)
309
- if (!plugin) return []
310
-
311
- // 检查启用状态
312
- if (!this.isRendererEnabled(plugin)) return []
313
-
314
- const errors: RendererErrorEvent[] = []
315
- try {
316
- plugin.draw(context)
317
- } catch (e) {
318
- const error = e instanceof Error ? e : new Error(String(e))
319
- console.error(`[RendererPlugin] ${name} draw error:`, error)
320
- errors.push({
321
- name,
322
- error: { message: error.message, stack: error.stack },
323
- paneId: context.pane.id,
324
- timestamp: Date.now(),
325
- })
326
- }
327
-
328
- return errors
329
- }
330
-
331
248
  /** 启用/禁用渲染器(修改独立状态,不影响原始插件对象) */
332
249
  setEnabled(name: string, enabled: boolean): void {
333
250
  if (!this.plugins.has(name)) return
@@ -355,22 +272,6 @@ export class RendererPluginManager {
355
272
  return this.plugins.get(name) as T | undefined
356
273
  }
357
274
 
358
- /* 调用 onDataUpdate 钩子通知数据更新 */
359
- notifyDataUpdate(data: unknown[], range: { start: number; end: number }): void {
360
- for (const plugin of this.plugins.values()) {
361
- if (!plugin.onDataUpdate) continue
362
-
363
- // 检查启用状态,跳过禁用的插件
364
- if (!this.isRendererEnabled(plugin)) continue
365
-
366
- try {
367
- plugin.onDataUpdate(data, range)
368
- } catch (e) {
369
- console.error(`[RendererPlugin] ${plugin.name} onDataUpdate error:`, e)
370
- }
371
- }
372
- }
373
-
374
275
  /** 通知尺寸变化 */
375
276
  notifyResize(paneId: string, pane: PaneInfo): void {
376
277
  const renderers = this.getMergedRenderers(paneId).filter((renderer) =>
@@ -2,10 +2,6 @@
2
2
  * 插件系统核心类型定义
3
3
  */
4
4
 
5
- import type {
6
- CandleWebGLSurface,
7
- LineWebGLSurface,
8
- } from '../../engine/renderers/webgl/candleSurface'
9
5
  import type { KLineData } from '../types/price'
10
6
 
11
7
  /** 插件生命周期状态 */
@@ -313,10 +309,11 @@ export interface RenderContext {
313
309
  borderCtx?: CanvasRenderingContext2D
314
310
  /** 覆盖层 Canvas 上下文(用于十字线、Tooltip 等动态内容) */
315
311
  overlayCtx?: CanvasRenderingContext2D
316
- /** price pane 可选的 WebGL candle surface */
317
- candleWebGLSurface?: CandleWebGLSurface
318
- /** line indicator 可选的 WebGL line surface */
319
- lineWebGLSurface?: LineWebGLSurface
312
+ /**
313
+ * Scene 本帧 Renderer(createLayerFromPlugin 注入)。
314
+ * 业务绘制经 drawInstances / drawLines;失败 fail-closed 2D。
315
+ */
316
+ sceneRenderer?: import('../../rendering/render/Renderer').Renderer
320
317
  /** 当前缩放级别(1 ~ zoomLevels) */
321
318
  zoomLevel?: number
322
319
  /** 总缩放级别数 */
@@ -516,26 +513,22 @@ export interface RendererPlugin {
516
513
  enabled?: boolean
517
514
 
518
515
  /**
519
- * 是否为系统渲染器
520
- * 系统渲染器不会通过 getRenderers() 返回,只能通过 renderPlugin() 单独渲染
521
- * 用于时间轴、全局边框等需要单独控制渲染时机的场景
516
+ * 是否为系统渲染器(时间轴等)。
517
+ * 调度由 Scene Layer 负责;Manager 仅作注册表。
522
518
  */
523
519
  isSystem?: boolean
524
520
 
525
521
  /**
526
- * 渲染器所属层,决定 UpdateLevel 过滤行为
527
- * - 'main': 低频/静态内容,随主画布一起渲染
528
- * - 'overlay': 高频/动态内容,可在 overlay-only 更新时独立重绘
529
- * 未指定时默认为 'main'(向后兼容)
522
+ * 渲染器所属层,供 Scene role 过滤
523
+ * - 'main': 低频/静态内容
524
+ * - 'overlay': 高频/动态内容
525
+ * 未指定时默认为 'main'
530
526
  */
531
527
  layer?: 'main' | 'overlay'
532
528
 
533
529
  /** 渲染方法 */
534
530
  draw(context: RenderContext): void
535
531
 
536
- /** 数据更新时回调 */
537
- onDataUpdate?(data: unknown[], range: { start: number; end: number }): void
538
-
539
532
  /** 容器尺寸变化时回调 */
540
533
  onResize?(pane: PaneInfo): void
541
534