@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
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it, vi } from 'vitest'
2
- import { DrawingState } from '../DrawingState'
2
+ import { DrawingState, mergePaint, PREVIEW_ID } from '../DrawingState'
3
3
  import type { DrawingChartAdapter } from '../../../controllers/types'
4
4
  import type { DrawingObject } from '../../../foundation/plugin/index'
5
5
 
@@ -15,13 +15,34 @@ function mk(id: string): DrawingObject {
15
15
  }
16
16
  }
17
17
 
18
- function mockAdapter(): DrawingChartAdapter {
18
+ function mockAdapter(
19
+ initial: DrawingObject[] = [],
20
+ initialSelected: string | null = null,
21
+ ): DrawingChartAdapter & {
22
+ kernelList: DrawingObject[]
23
+ setDrawings: ReturnType<typeof vi.fn>
24
+ requestDraw: ReturnType<typeof vi.fn>
25
+ } {
26
+ let selected: string | null = initialSelected
27
+ let kernelList = [...initial]
28
+ const setDrawings = vi.fn((list: DrawingObject[]) => {
29
+ kernelList = list.filter((d) => d.id !== PREVIEW_ID).map((d) => ({ ...d }))
30
+ })
31
+ const requestDraw = vi.fn()
19
32
  return {
20
- setDrawings: vi.fn(),
21
- getFullDrawings: vi.fn(() => []),
22
- setSelectedDrawingId: vi.fn(),
33
+ kernelList: kernelList as DrawingObject[],
34
+ get kernel() {
35
+ return kernelList
36
+ },
37
+ setDrawings,
38
+ getFullDrawings: vi.fn(() => kernelList),
39
+ setSelectedDrawingId: vi.fn((id: string | null) => {
40
+ selected = id
41
+ }),
42
+ getSelectedDrawingId: vi.fn(() => selected),
23
43
  setDrawingToolId: vi.fn(),
24
44
  getDrawingToolId: vi.fn(() => 'cursor'),
45
+ requestDraw,
25
46
  getViewport: vi.fn(() => null),
26
47
  getKWidthKGap: vi.fn(() => ({ kWidth: 6, kGap: 2 })),
27
48
  getCurrentDpr: vi.fn(() => 1),
@@ -31,48 +52,86 @@ function mockAdapter(): DrawingChartAdapter {
31
52
  priceToY: vi.fn(() => 0),
32
53
  yToPrice: vi.fn(() => 0),
33
54
  getPaneInfo: vi.fn(() => undefined),
34
- }
55
+ } as any
35
56
  }
36
57
 
37
- describe('DrawingState work copy', () => {
38
- it('addOrUpdate works after setDrawings from frozen kernel snapshot', () => {
39
- const adapter = mockAdapter()
58
+ describe('DrawingState session SSOT', () => {
59
+ it('addOrUpdate commits to adapter without local full list', () => {
60
+ const adapter = mockAdapter([mk('a')])
40
61
  const state = new DrawingState(adapter)
41
- const frozen = Object.freeze([Object.freeze(mk('a'))]) as DrawingObject[]
42
- state.setDrawings(frozen)
43
- expect(() => state.addOrUpdate(mk('b'))).not.toThrow()
62
+ state.addOrUpdate(mk('b'))
63
+ expect(adapter.setDrawings).toHaveBeenCalled()
64
+ const last = adapter.setDrawings.mock.calls.at(-1)![0] as DrawingObject[]
65
+ expect(last.map((d) => d.id).sort()).toEqual(['a', 'b'])
44
66
  expect(state.getAll().map((d) => d.id).sort()).toEqual(['a', 'b'])
45
67
  })
46
68
 
47
- it('setPreview works after setDrawings from frozen snapshot', () => {
48
- const adapter = mockAdapter()
69
+ it('setPreview does not write kernel; only requestDraw', () => {
70
+ const adapter = mockAdapter([mk('a')])
49
71
  const state = new DrawingState(adapter)
50
- state.setDrawings(Object.freeze([Object.freeze(mk('a'))]) as DrawingObject[])
51
- expect(() =>
52
- state.setPreview({
53
- ...mk('__preview__'),
54
- id: '__preview__',
55
- }),
56
- ).not.toThrow()
72
+ adapter.setDrawings.mockClear()
73
+ state.setPreview({ ...mk(PREVIEW_ID), id: PREVIEW_ID })
74
+ expect(adapter.setDrawings).not.toHaveBeenCalled()
75
+ expect(adapter.requestDraw).toHaveBeenCalled()
57
76
  expect(state.hasPreview()).toBe(true)
77
+ expect(state.getPaintOverlay().map((d) => d.id)).toEqual([PREVIEW_ID])
78
+ expect(state.getAll().map((d) => d.id)).toEqual(['a', PREVIEW_ID])
58
79
  })
59
80
 
60
- it('nested fields from frozen snapshot are mutable after adopt', () => {
81
+ it('setDrawings strips preview id before kernel write', () => {
61
82
  const adapter = mockAdapter()
62
83
  const state = new DrawingState(adapter)
63
- const frozen = Object.freeze([
64
- Object.freeze({
65
- ...mk('a'),
66
- anchors: Object.freeze([Object.freeze({ id: 'p1', index: 0, price: 1 })]),
67
- style: Object.freeze({ stroke: '#f00' }),
68
- }),
69
- ]) as DrawingObject[]
70
- state.setDrawings(frozen)
71
- const d = state.getById('a')!
72
- expect(() => {
73
- d.anchors[0]!.price = 99
74
- d.style.stroke = '#0f0'
75
- }).not.toThrow()
76
- expect(d.anchors[0]!.price).toBe(99)
84
+ state.setDrawings([mk('a'), { ...mk(PREVIEW_ID), id: PREVIEW_ID }])
85
+ const last = adapter.setDrawings.mock.calls.at(-1)![0] as DrawingObject[]
86
+ expect(last.map((d) => d.id)).toEqual(['a'])
87
+ })
88
+
89
+ it('getAll returns merge of kernel + overlay without mutating kernel', () => {
90
+ const adapter = mockAdapter([mk('a')])
91
+ const state = new DrawingState(adapter)
92
+ state.setPreview({ ...mk(PREVIEW_ID), id: PREVIEW_ID })
93
+ const all = state.getAll()
94
+ all.push(mk('hack'))
95
+ expect(adapter.getFullDrawings()).toHaveLength(1)
96
+ })
97
+
98
+ it('setSelected only writes adapter; getSelectedId reads adapter', () => {
99
+ const adapter = mockAdapter([mk('a')])
100
+ const state = new DrawingState(adapter)
101
+ state.setSelected(mk('a'))
102
+ expect(adapter.setSelectedDrawingId).toHaveBeenCalledWith('a')
103
+ expect(state.getSelectedId()).toBe('a')
104
+ })
105
+
106
+ it('removeDrawing drops id and clears selection via adapter', () => {
107
+ const adapter = mockAdapter([mk('a'), mk('b')], 'a')
108
+ const state = new DrawingState(adapter)
109
+ state.removeDrawing('a')
110
+ expect(adapter.setSelectedDrawingId).toHaveBeenCalledWith(null)
111
+ const last = adapter.setDrawings.mock.calls.at(-1)![0] as DrawingObject[]
112
+ expect(last.map((d) => d.id)).toEqual(['b'])
113
+ })
114
+
115
+ it('setDragOverride does not write kernel; commitDrag writes once', () => {
116
+ const adapter = mockAdapter([mk('a')])
117
+ const state = new DrawingState(adapter)
118
+ adapter.setDrawings.mockClear()
119
+ const moved = { ...mk('a'), anchors: [{ id: 'p', index: 1, time: 1, price: 99 }] }
120
+ state.setDragOverride(moved)
121
+ expect(adapter.setDrawings).not.toHaveBeenCalled()
122
+ expect(adapter.requestDraw).toHaveBeenCalled()
123
+ state.commitDrag()
124
+ expect(adapter.setDrawings).toHaveBeenCalledTimes(1)
125
+ const last = adapter.setDrawings.mock.calls.at(-1)![0] as DrawingObject[]
126
+ expect(last[0]!.anchors[0]!.price).toBe(99)
127
+ expect(state.getPaintOverlay()).toEqual([])
128
+ })
129
+
130
+ it('mergePaint replaces by id and appends preview', () => {
131
+ const a = mk('a')
132
+ const a2 = { ...mk('a'), style: { stroke: '#f00' } }
133
+ const p = { ...mk(PREVIEW_ID), id: PREVIEW_ID }
134
+ expect(mergePaint([a], [a2, p]).map((d) => d.id)).toEqual(['a', PREVIEW_ID])
135
+ expect(mergePaint([a], [a2, p])[0]!.style.stroke).toBe('#f00')
77
136
  })
78
137
  })
@@ -3,6 +3,7 @@ import { describe, expect, it } from 'vitest'
3
3
  import type { DrawingObject } from '../../../foundation/plugin/index'
4
4
  import { createDrawingState } from '../../state/drawingState'
5
5
  import { DrawingStore } from '../index'
6
+ import { PREVIEW_ID } from '../DrawingState'
6
7
 
7
8
  function mk(id: string, paneId = 'main'): DrawingObject {
8
9
  return {
@@ -35,4 +36,25 @@ describe('DrawingStore projection', () => {
35
36
  expect(store.getAll().map((d) => d.id)).toEqual(['c'])
36
37
  expect(store.getSelectedId()).toBeNull()
37
38
  })
39
+
40
+ it('merges session overlay for paint without changing kernel signal', () => {
41
+ const state = createDrawingState()
42
+ state.actions.setDrawings([mk('a')])
43
+ let overlay: DrawingObject[] = []
44
+
45
+ const store = new DrawingStore({
46
+ drawings$: state.readonly.drawings,
47
+ selectedDrawingId$: state.readonly.selectedDrawingId,
48
+ getOverlay: () => overlay,
49
+ })
50
+
51
+ overlay = [{ ...mk(PREVIEW_ID), id: PREVIEW_ID }]
52
+ expect(store.getAll().map((d) => d.id)).toEqual(['a', PREVIEW_ID])
53
+ expect(state.readonly.drawings.peek().map((d) => d.id)).toEqual(['a'])
54
+
55
+ const moved = { ...mk('a'), style: { stroke: '#0f0' } }
56
+ overlay = [moved]
57
+ expect(store.getAll()).toHaveLength(1)
58
+ expect(store.getAll()[0]!.style.stroke).toBe('#0f0')
59
+ })
38
60
  })
@@ -26,14 +26,17 @@ export type {
26
26
  }
27
27
 
28
28
  import type { ReadonlySignal } from '../../foundation/reactivity/signal'
29
+ import { mergePaint } from './DrawingState'
29
30
 
30
31
  export interface DrawingStoreDeps {
31
32
  drawings$: ReadonlySignal<ReadonlyArray<DrawingObject>>
32
33
  selectedDrawingId$: ReadonlySignal<string | null>
34
+ /** 会话层覆盖(拖拽/预览);缺省为空 */
35
+ getOverlay?: () => ReadonlyArray<DrawingObject>
33
36
  }
34
37
 
35
38
  /**
36
- * 绘图投影器 —— 业务态在 kernel.drawing;此类只读 signal 供渲染插件使用。
39
+ * 绘图投影器 —— kernel 业务 SSOT ⊕ 会话 overlay,供渲染插件读取。
37
40
  */
38
41
  export class DrawingStore {
39
42
  constructor(private readonly deps: DrawingStoreDeps) {}
@@ -42,13 +45,18 @@ export class DrawingStore {
42
45
  return this.deps.selectedDrawingId$.peek()
43
46
  }
44
47
 
48
+ private paintList(): DrawingObject[] {
49
+ const committed = this.deps.drawings$.peek()
50
+ const overlay = this.deps.getOverlay?.() ?? []
51
+ return mergePaint(committed, overlay)
52
+ }
53
+
45
54
  getAll(): DrawingObject[] {
46
- return [...this.deps.drawings$.peek()]
55
+ return this.paintList()
47
56
  }
48
57
 
49
58
  getVisibleByPane(paneId: string): DrawingObject[] {
50
- return this.deps.drawings$
51
- .peek()
59
+ return this.paintList()
52
60
  .filter((drawing) => drawing.visible && drawing.paneId === paneId)
53
61
  .slice()
54
62
  .sort((a, b) => (a.zIndex ?? 0) - (b.zIndex ?? 0))
@@ -1,5 +1,5 @@
1
1
  import type { DrawingChartAdapter } from '../../controllers/types'
2
- import type { DrawingObject, DrawingKind, DrawingStyle } from '../../foundation/plugin/index'
2
+ import type { DrawingObject, DrawingStyle } from '../../foundation/plugin/index'
3
3
 
4
4
  import { AnchorCollector } from './AnchorCollector'
5
5
  import { DragHandler } from './DragHandler'
@@ -22,16 +22,9 @@ export interface DrawingInteractionCallbacks {
22
22
  }
23
23
 
24
24
  /**
25
- * 绘图交互控制器 v2 精简事件路由,组合子模块。
25
+ * 绘图交互控制器 —— 精简事件路由,组合子模块。
26
26
  *
27
- * ┌─────────────────────────────────────┐
28
- * │ DrawingInteractionController │
29
- * │ ├─ DrawingState (图元 CRUD) │
30
- * │ ├─ AnchorCollector (锚点累积) │
31
- * │ ├─ PreviewRenderer (预览构建) │
32
- * │ ├─ HitTester (命中检测) │
33
- * │ └─ DragHandler (拖拽管理) │
34
- * └─────────────────────────────────────┘
27
+ * 已确认图元只写 kernel;预览与拖拽覆盖只在 DrawingState 会话层。
35
28
  */
36
29
  export class DrawingInteractionController {
37
30
  private adapter: DrawingChartAdapter
@@ -52,16 +45,19 @@ export class DrawingInteractionController {
52
45
  this.dragHandler = new DragHandler()
53
46
  }
54
47
 
48
+ /** 渲染合成用:拖拽覆盖 + 预览 */
49
+ getPaintOverlay(): DrawingObject[] {
50
+ return this.drawingState.getPaintOverlay()
51
+ }
52
+
55
53
  // ============ 配置 ============
56
54
 
57
- /** 注册回调(创建/选中/工具切换事件通知) */
58
55
  setCallbacks(callbacks: DrawingInteractionCallbacks) {
59
56
  this.callbacks = callbacks
60
57
  }
61
58
 
62
59
  // ============ 工具状态 ============
63
60
 
64
- /** 返回当前激活的绘图工具 ID(读 kernel SSOT) */
65
61
  getActiveTool(): DrawingToolId {
66
62
  return this.adapter.getDrawingToolId()
67
63
  }
@@ -72,51 +68,48 @@ export class DrawingInteractionController {
72
68
  applyToolSession(toolId: DrawingToolId): void {
73
69
  this.anchorCollector.reset()
74
70
  this.drawingState.removePreview()
75
- this.dragHandler.endDrag()
71
+ if (this.dragHandler.isDragging()) {
72
+ this.drawingState.clearDragOverride()
73
+ this.dragHandler.endDrag()
74
+ }
76
75
  this.setSelected(null)
77
76
  this.callbacks.onToolChange?.(toolId)
78
77
  }
79
78
 
80
- /**
81
- * 切换绘图工具 —— 经 adapter 写 kernel(Chart 单写路径)。
82
- */
83
79
  setTool(toolId: DrawingToolId) {
84
80
  this.adapter.setDrawingToolId(toolId)
85
81
  }
86
82
 
87
- // ============ 图元 CRUD(委托 DrawingState) ============
83
+ // ============ 图元 CRUD ============
88
84
 
89
- /** 返回所有图元(含预览) */
90
85
  getDrawings(): DrawingObject[] {
91
86
  return this.drawingState.getAll()
92
87
  }
93
88
 
94
- /** 整体替换图元列表 */
95
89
  setDrawings(drawings: DrawingObject[]) {
96
90
  this.drawingState.setDrawings(drawings)
97
91
  }
98
92
 
99
- /** 清空锚点累积、预览、拖拽状态及所有图元 */
100
93
  clear() {
101
94
  this.anchorCollector.reset()
102
95
  this.drawingState.removePreview()
103
- this.dragHandler.endDrag()
96
+ if (this.dragHandler.isDragging()) {
97
+ this.drawingState.clearDragOverride()
98
+ this.dragHandler.endDrag()
99
+ }
104
100
  this.drawingState.clear()
105
101
  }
106
102
 
107
- /** 更新指定图元的样式(合并) */
108
103
  updateDrawingStyle(drawingId: string, style: Partial<DrawingStyle>): void {
109
104
  this.drawingState.updateDrawingStyle(drawingId, style)
110
105
  }
111
106
 
112
- /** 删除指定图元 */
113
107
  removeDrawing(drawingId: string): void {
114
108
  this.drawingState.removeDrawing(drawingId)
115
109
  }
116
110
 
117
111
  // ============ 选中状态 ============
118
112
 
119
- /** 返回当前选中的图元 */
120
113
  getSelectedDrawing(): DrawingObject | null {
121
114
  return this.drawingState.getSelected()
122
115
  }
@@ -124,25 +117,23 @@ export class DrawingInteractionController {
124
117
  // ============ 事件处理 ============
125
118
 
126
119
  /**
127
- * 指针移动事件入口。
128
- * 拖拽中 → 委托 DragHandler 更新锚点;绘图模式 → 构建预览图元。
120
+ * 指针移动:拖拽只写会话覆盖;绘图模式只写预览。均不写 kernel。
129
121
  * @returns true 表示事件已消费,需要重绘
130
122
  */
131
123
  onPointerMove(e: PointerEvent, container: HTMLElement): boolean {
132
- // 1) 正在拖拽
133
124
  if (this.dragHandler.isDragging()) {
134
125
  const drawing = this.drawingState.getById(this.dragHandler.getDraggingDrawingId() ?? '')
135
126
  if (!drawing) {
127
+ this.drawingState.clearDragOverride()
136
128
  this.dragHandler.endDrag()
137
129
  return false
138
130
  }
139
131
  const updated = this.dragHandler.handleDragMove(drawing, e, container, this.adapter)
140
132
  if (!updated) return false
141
- this.drawingState.addOrUpdate(updated)
133
+ this.drawingState.setDragOverride(updated)
142
134
  return true
143
135
  }
144
136
 
145
- // 2) 绘图工具预览
146
137
  const activeTool = this.getActiveTool()
147
138
  if (activeTool !== 'cursor') {
148
139
  const anchor = resolveAnchorFromPointer(e, container, this.adapter)
@@ -169,30 +160,25 @@ export class DrawingInteractionController {
169
160
  }
170
161
 
171
162
  /**
172
- * 指针按下事件入口。
173
- * 光标模式 → 命中检测 + 选中 + 拖拽开始;绘图模式 → 创建或累积锚点。
163
+ * 指针按下:光标模式命中+选中+开拖;绘图模式创建或累积锚点。
174
164
  * @returns true 表示事件已消费
175
165
  */
176
166
  onPointerDown(e: PointerEvent, container: HTMLElement): boolean {
177
167
  const activeTool = this.getActiveTool()
178
- // 光标模式:命中检测 → 选中 → 开始拖拽
179
168
  if (activeTool === 'cursor') {
180
169
  return this.handleCursorDown(e, container)
181
170
  }
182
171
 
183
- // 绘图模式
184
172
  const anchor = resolveAnchorFromPointer(e, container, this.adapter)
185
173
  if (!anchor) return false
186
174
 
187
175
  const anchorCount = getAnchorCountForTool(activeTool)
188
176
 
189
- // 单锚点工具:点击即创建
190
177
  if (anchorCount === 1) {
191
178
  this.createSingleAnchorDrawing(anchor, activeTool)
192
179
  return true
193
180
  }
194
181
 
195
- // 多锚点工具:累积
196
182
  if (anchorCount === 2 || anchorCount === 3) {
197
183
  const result = this.anchorCollector.addAnchor(anchor, activeTool)
198
184
  if (result) {
@@ -205,18 +191,18 @@ export class DrawingInteractionController {
205
191
  }
206
192
 
207
193
  /**
208
- * 指针抬起事件入口。结束拖拽。
194
+ * 指针抬起:拖拽结果一次 commit 到 kernel。
209
195
  * @returns true 表示事件已消费
210
196
  */
211
197
  onPointerUp(_e: PointerEvent, _container: HTMLElement): boolean {
212
198
  if (!this.dragHandler.isDragging()) return false
199
+ this.drawingState.commitDrag()
213
200
  this.dragHandler.endDrag()
214
201
  return true
215
202
  }
216
203
 
217
204
  // ============ 私有方法 ============
218
205
 
219
- /** 光标模式下指针按下:命中检测 → 选中 → 开始拖拽 */
220
206
  private handleCursorDown(e: PointerEvent, container: HTMLElement): boolean {
221
207
  const rect = container.getBoundingClientRect()
222
208
  const mouseX = e.clientX - rect.left
@@ -244,13 +230,11 @@ export class DrawingInteractionController {
244
230
  return true
245
231
  }
246
232
 
247
- /** 设置选中图元并通知回调 */
248
233
  private setSelected(drawing: DrawingObject | null) {
249
234
  this.drawingState.setSelected(drawing)
250
235
  this.callbacks.onDrawingSelected?.(drawing)
251
236
  }
252
237
 
253
- /** 单锚点工具:点击即创建图元,完成后切回光标模式 */
254
238
  private createSingleAnchorDrawing(anchor: DrawingAnchorInput, activeTool: DrawingToolId) {
255
239
  this.drawingState.removePreview()
256
240
 
@@ -280,7 +264,6 @@ export class DrawingInteractionController {
280
264
  this.adapter.setDrawingToolId('cursor')
281
265
  }
282
266
 
283
- /** 多锚点工具(2-3 锚点):锚点累积满后创建图元,完成后切回光标模式 */
284
267
  private createMultiAnchorDrawing(anchors: DrawingAnchorInput[], activeTool: DrawingToolId) {
285
268
  this.drawingState.removePreview()
286
269
 
@@ -327,3 +310,5 @@ export class DrawingInteractionController {
327
310
  this.adapter.setDrawingToolId('cursor')
328
311
  }
329
312
  }
313
+
314
+ export { PREVIEW_ID }
@@ -13,7 +13,6 @@ import {
13
13
  } from '../../foundation/reactivity/signal'
14
14
  import type { MainIndicatorEntry } from '../state/indicatorState'
15
15
  import type { SubPaneSpec } from '../state/subPaneState'
16
- import { createLayerFromPlugin } from '../../rendering/scene/createLayerFromPlugin'
17
16
  import type { Layer } from '../../rendering/scene/types'
18
17
  import type { KLineData } from '../../foundation/types/price'
19
18
  import type { IndicatorInstance, SubPaneInfo, PaneSpec, ChartOptions } from '../chartTypes'
@@ -371,29 +370,21 @@ export class ChartIndicatorManager {
371
370
 
372
371
  if (!existingLayer) {
373
372
  const plugin = definition.rendererFactory({ paneId: 'main', indicatorId })
374
- // register with old system for getRenderer compatibility
373
+ // useRenderer:注册表 + 唯一 Scene Layer
375
374
  this.deps.useRenderer(plugin)
376
- // disable old rendering to avoid double rendering (scene handles it)
377
- this.deps.setRendererEnabled(rendererName, false)
378
- // create bridge layer and add to scene
379
- const layer = createLayerFromPlugin(plugin, () => this.deps.getRenderContext('main'), 'main')
380
- this.deps.addLayer(layer)
381
375
  }
382
376
 
383
377
  this.deps.setLayerVisibility(layerId, true)
384
378
 
385
- if (!this.deps.getRenderer('mainIndicatorLegend')) {
379
+ // core 可能已挂 legend Layer 且未进 Manager;两者任一存在都不再注册第二实例
380
+ if (
381
+ !this.deps.getLayer('plugin:mainIndicatorLegend') &&
382
+ !this.deps.getRenderer('mainIndicatorLegend')
383
+ ) {
386
384
  const legend = createMainIndicatorLegendRendererPlugin({
387
385
  yPaddingPx: this.deps.getOption().yPaddingPx,
388
386
  })
389
387
  this.deps.useRenderer(legend)
390
- this.deps.setRendererEnabled('mainIndicatorLegend', false)
391
- const legendLayer = createLayerFromPlugin(
392
- legend,
393
- () => this.deps.getRenderContext('main'),
394
- 'main',
395
- )
396
- this.deps.addLayer(legendLayer)
397
388
  }
398
389
  }
399
390
 
@@ -402,7 +393,6 @@ export class ChartIndicatorManager {
402
393
  this.indicatorScheduler.getIndicatorMetadata(indicatorId)?.mainPane?.rendererName
403
394
  if (rendererName) {
404
395
  this.deps.setRendererEnabled(rendererName, false)
405
- this.deps.setLayerVisibility(`plugin:${rendererName}`, false)
406
396
  }
407
397
  }
408
398
 
@@ -1,7 +1,6 @@
1
1
  import type { PaneRole } from '../../foundation/plugin/index'
2
2
  import type { ChartDom, PaneSpec, Viewport } from '../chartTypes'
3
3
  import { PaneRenderer } from '../paneRenderer'
4
- import type { SharedWebGLSurface } from '../renderers/webgl/sharedWebGLSurface'
5
4
  import type { ScaleType } from '../utils/tickPosition'
6
5
 
7
6
  import { Pane, UpdateLevel } from './pane'
@@ -18,7 +17,6 @@ export interface PaneLayoutDependencies {
18
17
  defaultPaneMinHeightPx?: number
19
18
  }
20
19
  getViewport: () => Viewport | null
21
- getSharedWebGLSurface: () => SharedWebGLSurface
22
20
  setKnownPaneIds: (ids: string[]) => void
23
21
  notifyPaneResize: (paneId: string, pane: Pane) => void
24
22
  scheduleDraw: (level?: UpdateLevel) => void
@@ -140,6 +138,7 @@ export class ChartPaneLayout {
140
138
  mainCanvas.style.position = 'absolute'
141
139
  mainCanvas.style.left = '0'
142
140
  mainCanvas.style.top = '0'
141
+ mainCanvas.style.zIndex = '0'
143
142
 
144
143
  overlayCanvas.id = `${spec.id}-overlay`
145
144
  overlayCanvas.className = 'overlay-canvas'
@@ -148,6 +147,7 @@ export class ChartPaneLayout {
148
147
  overlayCanvas.style.top = '0'
149
148
  overlayCanvas.style.pointerEvents = 'none'
150
149
  overlayCanvas.style.backgroundColor = 'transparent'
150
+ overlayCanvas.style.zIndex = '2'
151
151
 
152
152
  const leftYAxisCanvas = this.createAxisCanvas(spec, pane, 'left')
153
153
 
@@ -160,7 +160,6 @@ export class ChartPaneLayout {
160
160
  yPaddingPx: this.deps.getOption().yPaddingPx,
161
161
  priceLabelWidth: this.deps.getOption().priceLabelWidth,
162
162
  },
163
- this.deps.getSharedWebGLSurface(),
164
163
  )
165
164
 
166
165
  return renderer
@@ -171,7 +170,10 @@ export class ChartPaneLayout {
171
170
  const rightAxisLayer = dom.rightAxisLayer
172
171
  const leftAxisLayer = dom.leftAxisLayer
173
172
  if (canvasLayer) {
174
- const existingCanvases = canvasLayer.querySelectorAll('canvas:not(.x-axis-canvas)')
173
+ // 保留 chart 级 WebGPU scene canvas(M2 hybrid DOM)
174
+ const existingCanvases = canvasLayer.querySelectorAll(
175
+ 'canvas:not(.x-axis-canvas):not(.gpu-scene-canvas)',
176
+ )
175
177
  existingCanvases.forEach((canvas) => canvas.remove())
176
178
  }
177
179
  if (rightAxisLayer) {
@@ -330,13 +332,6 @@ export class ChartPaneLayout {
330
332
  pane.setPadding(opt.yPaddingPx, opt.yPaddingPx)
331
333
 
332
334
  renderer.resize(vp.plotWidth, h, vp.dpr)
333
- renderer.setWebGLRegion({
334
- x: 0,
335
- y,
336
- width: vp.plotWidth,
337
- height: h,
338
- dpr: vp.dpr,
339
- })
340
335
  this.deps.notifyPaneResize(pane.id, pane)
341
336
  const domEls = renderer.getDom()
342
337
  domEls.mainCanvas.style.top = `${y}px`
@@ -1,6 +1,5 @@
1
1
  import type { PaneCapabilities, PaneRole } from '../../foundation/plugin/index'
2
2
  import type { KLineData } from '../../foundation/types/price'
3
- import type { MarkerManager } from '../marker/registry'
4
3
  import type { PriceRange } from '../scale/price'
5
4
  import { PriceScale } from '../scale/priceScale'
6
5
  import { getVisiblePriceRange } from '../viewport/viewport'
@@ -49,38 +48,6 @@ function defaultCapabilitiesByRole(role: PaneRole): PaneCapabilities {
49
48
  }
50
49
  }
51
50
 
52
- /**
53
- * Pane 级渲染器接口:在单个 pane 的坐标系中绘制内容
54
- */
55
- export interface PaneRenderer {
56
- /**
57
- * 在指定 pane 坐标系中绘制内容
58
- * @param ctx Canvas 绘图上下文,Chart 已执行 translate(0, pane.top),y=0 对应 pane 顶部
59
- * @param pane 当前 pane 实例
60
- * @param data 全量 K 线数据
61
- * @param range 当前视口可见的索引范围
62
- * @param scrollLeft 滚动偏移量,renderer 内部如需 world 坐标需执行 ctx.translate(-scrollLeft, 0)
63
- * @param kWidth K 线宽度
64
- * @param kGap K 线间隔
65
- * @param dpr 设备像素比
66
- * @param paneWidth pane 宽度
67
- * @param kLinePositions 可选,K 线起始 x 坐标数组(由 Chart 统一计算)
68
- */
69
- draw(args: {
70
- ctx: CanvasRenderingContext2D
71
- pane: Pane
72
- data: KLineData[]
73
- range: VisibleRange
74
- scrollLeft: number
75
- kWidth: number
76
- kGap: number
77
- dpr: number
78
- paneWidth: number
79
- kLinePositions: number[]
80
- markerManager?: MarkerManager
81
- }): void
82
- }
83
-
84
51
  /**
85
52
  * Pane:代表一个"窗口区域"(主图 / 副图)
86
53
  */
@@ -97,9 +64,6 @@ export class Pane {
97
64
  /** pane 独立 Y 轴 */
98
65
  readonly yAxis = new PriceScale()
99
66
 
100
- /** 该 pane 的渲染器列表 */
101
- readonly renderers: PaneRenderer[] = []
102
-
103
67
  /**
104
68
  * 创建 pane 实例
105
69
  * @param id pane 标识符(例如 'main'、'sub'),用于在 Chart/Interaction 中识别 pane
@@ -133,14 +97,6 @@ export class Pane {
133
97
  this.yAxis.setPadding(top, bottom)
134
98
  }
135
99
 
136
- /**
137
- * 注册一个 pane 级渲染器
138
- * @param renderer pane 级渲染器实例
139
- */
140
- addRenderer(renderer: PaneRenderer) {
141
- this.renderers.push(renderer)
142
- }
143
-
144
100
  /**
145
101
  * 根据当前可见索引区间更新 priceRange 并同步到 yAxis
146
102
  * @param data 全量 K 线数据