@363045841yyt/klinechart-core 0.8.6 → 0.8.8

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 (501) hide show
  1. package/dist/config/chartSettings.d.ts +18 -2
  2. package/dist/config/chartSettings.d.ts.map +1 -1
  3. package/dist/config/chartSettings.js +8 -1
  4. package/dist/config/chartSettings.js.map +1 -1
  5. package/dist/controllers/createChartController.d.ts.map +1 -1
  6. package/dist/controllers/createChartController.js +56 -2
  7. package/dist/controllers/createChartController.js.map +1 -1
  8. package/dist/controllers/types.d.ts +36 -23
  9. package/dist/controllers/types.d.ts.map +1 -1
  10. package/dist/data-fetchers/baostock.d.ts +0 -3
  11. package/dist/data-fetchers/baostock.d.ts.map +1 -1
  12. package/dist/data-fetchers/baostock.js +0 -1
  13. package/dist/data-fetchers/baostock.js.map +1 -1
  14. package/dist/data-fetchers/dataBuffer.d.ts +13 -2
  15. package/dist/data-fetchers/dataBuffer.d.ts.map +1 -1
  16. package/dist/data-fetchers/dataBuffer.js +41 -7
  17. package/dist/data-fetchers/dataBuffer.js.map +1 -1
  18. package/dist/data-fetchers/dataBufferTypes.d.ts +11 -0
  19. package/dist/data-fetchers/dataBufferTypes.d.ts.map +1 -0
  20. package/dist/data-fetchers/dataBufferTypes.js +2 -0
  21. package/dist/data-fetchers/dataBufferTypes.js.map +1 -0
  22. package/dist/data-fetchers/fetcherDefinitionRegistry.d.ts +4 -3
  23. package/dist/data-fetchers/fetcherDefinitionRegistry.d.ts.map +1 -1
  24. package/dist/data-fetchers/fetcherDefinitionRegistry.js +9 -2
  25. package/dist/data-fetchers/fetcherDefinitionRegistry.js.map +1 -1
  26. package/dist/data-fetchers/gotdx/gotdx.d.ts +7 -0
  27. package/dist/data-fetchers/gotdx/gotdx.d.ts.map +1 -0
  28. package/dist/data-fetchers/gotdx/gotdx.js +7 -0
  29. package/dist/data-fetchers/gotdx/gotdx.js.map +1 -0
  30. package/dist/data-fetchers/gotdx.d.ts +0 -8
  31. package/dist/data-fetchers/gotdx.d.ts.map +1 -1
  32. package/dist/data-fetchers/gotdx.js +40 -3
  33. package/dist/data-fetchers/gotdx.js.map +1 -1
  34. package/dist/data-fetchers/hundred-mock.d.ts +0 -3
  35. package/dist/data-fetchers/hundred-mock.d.ts.map +1 -1
  36. package/dist/data-fetchers/hundred-mock.js +0 -1
  37. package/dist/data-fetchers/hundred-mock.js.map +1 -1
  38. package/dist/data-fetchers/index.d.ts +10 -8
  39. package/dist/data-fetchers/index.d.ts.map +1 -1
  40. package/dist/data-fetchers/index.js +8 -7
  41. package/dist/data-fetchers/index.js.map +1 -1
  42. package/dist/data-fetchers/router.d.ts +2 -0
  43. package/dist/data-fetchers/router.d.ts.map +1 -1
  44. package/dist/data-fetchers/router.js +8 -1
  45. package/dist/data-fetchers/router.js.map +1 -1
  46. package/dist/data-fetchers/thousand-mock.d.ts +0 -3
  47. package/dist/data-fetchers/thousand-mock.d.ts.map +1 -1
  48. package/dist/data-fetchers/thousand-mock.js +0 -1
  49. package/dist/data-fetchers/thousand-mock.js.map +1 -1
  50. package/dist/data-fetchers/timeShareBuffer.d.ts +27 -0
  51. package/dist/data-fetchers/timeShareBuffer.d.ts.map +1 -0
  52. package/dist/data-fetchers/timeShareBuffer.js +79 -0
  53. package/dist/data-fetchers/timeShareBuffer.js.map +1 -0
  54. package/dist/data-fetchers/tradingview.d.ts +0 -8
  55. package/dist/data-fetchers/tradingview.d.ts.map +1 -1
  56. package/dist/data-fetchers/tradingview.js +1 -2
  57. package/dist/data-fetchers/tradingview.js.map +1 -1
  58. package/dist/data-fetchers/types.d.ts +9 -1
  59. package/dist/data-fetchers/types.d.ts.map +1 -1
  60. package/dist/engine/chart.d.ts +32 -1
  61. package/dist/engine/chart.d.ts.map +1 -1
  62. package/dist/engine/chart.js +148 -7
  63. package/dist/engine/chart.js.map +1 -1
  64. package/dist/engine/chartTypes.d.ts +3 -0
  65. package/dist/engine/chartTypes.d.ts.map +1 -1
  66. package/dist/engine/controller/interaction.d.ts +6 -1
  67. package/dist/engine/controller/interaction.d.ts.map +1 -1
  68. package/dist/engine/controller/interaction.js +76 -28
  69. package/dist/engine/controller/interaction.js.map +1 -1
  70. package/dist/engine/data/chartDataManager.d.ts +39 -14
  71. package/dist/engine/data/chartDataManager.d.ts.map +1 -1
  72. package/dist/engine/data/chartDataManager.js +494 -202
  73. package/dist/engine/data/chartDataManager.js.map +1 -1
  74. package/dist/engine/draw/pixelAlign.d.ts +0 -27
  75. package/dist/engine/draw/pixelAlign.d.ts.map +1 -1
  76. package/dist/engine/draw/pixelAlign.js +1 -1
  77. package/dist/engine/draw/pixelAlign.js.map +1 -1
  78. package/dist/engine/indicators/calculators.d.ts +0 -104
  79. package/dist/engine/indicators/calculators.d.ts.map +1 -1
  80. package/dist/engine/indicators/calculators.js +57 -168
  81. package/dist/engine/indicators/calculators.js.map +1 -1
  82. package/dist/engine/indicators/chartIndicatorManager.d.ts.map +1 -1
  83. package/dist/engine/indicators/chartIndicatorManager.js +3 -2
  84. package/dist/engine/indicators/chartIndicatorManager.js.map +1 -1
  85. package/dist/engine/indicators/macdState.d.ts +0 -5
  86. package/dist/engine/indicators/macdState.d.ts.map +1 -1
  87. package/dist/engine/indicators/macdState.js +1 -1
  88. package/dist/engine/indicators/macdState.js.map +1 -1
  89. package/dist/engine/indicators/registerBuiltins.d.ts.map +1 -1
  90. package/dist/engine/indicators/registerBuiltins.js +1 -0
  91. package/dist/engine/indicators/registerBuiltins.js.map +1 -1
  92. package/dist/engine/indicators/rsiState.d.ts +0 -4
  93. package/dist/engine/indicators/rsiState.d.ts.map +1 -1
  94. package/dist/engine/indicators/rsiState.js +1 -1
  95. package/dist/engine/indicators/rsiState.js.map +1 -1
  96. package/dist/engine/indicators/scheduler.d.ts.map +1 -1
  97. package/dist/engine/indicators/scheduler.js +1 -7
  98. package/dist/engine/indicators/scheduler.js.map +1 -1
  99. package/dist/engine/layout/chartPaneLayout.d.ts +2 -0
  100. package/dist/engine/layout/chartPaneLayout.d.ts.map +1 -1
  101. package/dist/engine/layout/chartPaneLayout.js +24 -6
  102. package/dist/engine/layout/chartPaneLayout.js.map +1 -1
  103. package/dist/engine/modes/kLineMode.d.ts +37 -0
  104. package/dist/engine/modes/kLineMode.d.ts.map +1 -0
  105. package/dist/engine/modes/kLineMode.js +22 -0
  106. package/dist/engine/modes/kLineMode.js.map +1 -0
  107. package/dist/engine/modes/timeShareMode.d.ts +37 -0
  108. package/dist/engine/modes/timeShareMode.d.ts.map +1 -0
  109. package/dist/engine/modes/timeShareMode.js +59 -0
  110. package/dist/engine/modes/timeShareMode.js.map +1 -0
  111. package/dist/engine/modes/types.d.ts +47 -0
  112. package/dist/engine/modes/types.d.ts.map +1 -0
  113. package/dist/engine/modes/types.js +2 -0
  114. package/dist/engine/modes/types.js.map +1 -0
  115. package/dist/engine/paneRenderer.d.ts +4 -0
  116. package/dist/engine/paneRenderer.d.ts.map +1 -1
  117. package/dist/engine/paneRenderer.js +27 -40
  118. package/dist/engine/paneRenderer.js.map +1 -1
  119. package/dist/engine/render/chartRenderer.d.ts +4 -23
  120. package/dist/engine/render/chartRenderer.d.ts.map +1 -1
  121. package/dist/engine/render/chartRenderer.js +113 -18
  122. package/dist/engine/render/chartRenderer.js.map +1 -1
  123. package/dist/engine/renderers/Indicator/atr.d.ts +1 -18
  124. package/dist/engine/renderers/Indicator/atr.d.ts.map +1 -1
  125. package/dist/engine/renderers/Indicator/atr.js +3 -22
  126. package/dist/engine/renderers/Indicator/atr.js.map +1 -1
  127. package/dist/engine/renderers/Indicator/boll.d.ts +1 -4
  128. package/dist/engine/renderers/Indicator/boll.d.ts.map +1 -1
  129. package/dist/engine/renderers/Indicator/boll.js +3 -18
  130. package/dist/engine/renderers/Indicator/boll.js.map +1 -1
  131. package/dist/engine/renderers/Indicator/cci.d.ts +1 -22
  132. package/dist/engine/renderers/Indicator/cci.d.ts.map +1 -1
  133. package/dist/engine/renderers/Indicator/cci.js +8 -20
  134. package/dist/engine/renderers/Indicator/cci.js.map +1 -1
  135. package/dist/engine/renderers/Indicator/chaikinVol.d.ts +1 -7
  136. package/dist/engine/renderers/Indicator/chaikinVol.d.ts.map +1 -1
  137. package/dist/engine/renderers/Indicator/chaikinVol.js +3 -16
  138. package/dist/engine/renderers/Indicator/chaikinVol.js.map +1 -1
  139. package/dist/engine/renderers/Indicator/cmf.d.ts +1 -7
  140. package/dist/engine/renderers/Indicator/cmf.d.ts.map +1 -1
  141. package/dist/engine/renderers/Indicator/cmf.js +3 -15
  142. package/dist/engine/renderers/Indicator/cmf.js.map +1 -1
  143. package/dist/engine/renderers/Indicator/dema.d.ts +1 -7
  144. package/dist/engine/renderers/Indicator/dema.d.ts.map +1 -1
  145. package/dist/engine/renderers/Indicator/dema.js +3 -17
  146. package/dist/engine/renderers/Indicator/dema.js.map +1 -1
  147. package/dist/engine/renderers/Indicator/donchian.d.ts +1 -8
  148. package/dist/engine/renderers/Indicator/donchian.d.ts.map +1 -1
  149. package/dist/engine/renderers/Indicator/donchian.js +2 -2
  150. package/dist/engine/renderers/Indicator/donchian.js.map +1 -1
  151. package/dist/engine/renderers/Indicator/ene.d.ts +1 -12
  152. package/dist/engine/renderers/Indicator/ene.d.ts.map +1 -1
  153. package/dist/engine/renderers/Indicator/ene.js +3 -18
  154. package/dist/engine/renderers/Indicator/ene.js.map +1 -1
  155. package/dist/engine/renderers/Indicator/expma.d.ts +1 -4
  156. package/dist/engine/renderers/Indicator/expma.d.ts.map +1 -1
  157. package/dist/engine/renderers/Indicator/expma.js +2 -2
  158. package/dist/engine/renderers/Indicator/expma.js.map +1 -1
  159. package/dist/engine/renderers/Indicator/fastk.d.ts +1 -22
  160. package/dist/engine/renderers/Indicator/fastk.d.ts.map +1 -1
  161. package/dist/engine/renderers/Indicator/fastk.js +11 -64
  162. package/dist/engine/renderers/Indicator/fastk.js.map +1 -1
  163. package/dist/engine/renderers/Indicator/fib.d.ts +1 -6
  164. package/dist/engine/renderers/Indicator/fib.d.ts.map +1 -1
  165. package/dist/engine/renderers/Indicator/fib.js +2 -2
  166. package/dist/engine/renderers/Indicator/fib.js.map +1 -1
  167. package/dist/engine/renderers/Indicator/hma.d.ts +1 -7
  168. package/dist/engine/renderers/Indicator/hma.d.ts.map +1 -1
  169. package/dist/engine/renderers/Indicator/hma.js +3 -17
  170. package/dist/engine/renderers/Indicator/hma.js.map +1 -1
  171. package/dist/engine/renderers/Indicator/hv.d.ts +1 -7
  172. package/dist/engine/renderers/Indicator/hv.d.ts.map +1 -1
  173. package/dist/engine/renderers/Indicator/hv.js +3 -16
  174. package/dist/engine/renderers/Indicator/hv.js.map +1 -1
  175. package/dist/engine/renderers/Indicator/ichimoku.d.ts +1 -8
  176. package/dist/engine/renderers/Indicator/ichimoku.d.ts.map +1 -1
  177. package/dist/engine/renderers/Indicator/ichimoku.js +2 -2
  178. package/dist/engine/renderers/Indicator/ichimoku.js.map +1 -1
  179. package/dist/engine/renderers/Indicator/kama.d.ts +1 -7
  180. package/dist/engine/renderers/Indicator/kama.d.ts.map +1 -1
  181. package/dist/engine/renderers/Indicator/kama.js +3 -17
  182. package/dist/engine/renderers/Indicator/kama.js.map +1 -1
  183. package/dist/engine/renderers/Indicator/keltner.d.ts +1 -8
  184. package/dist/engine/renderers/Indicator/keltner.d.ts.map +1 -1
  185. package/dist/engine/renderers/Indicator/keltner.js +2 -2
  186. package/dist/engine/renderers/Indicator/keltner.js.map +1 -1
  187. package/dist/engine/renderers/Indicator/kst.d.ts +1 -22
  188. package/dist/engine/renderers/Indicator/kst.d.ts.map +1 -1
  189. package/dist/engine/renderers/Indicator/kst.js +2 -2
  190. package/dist/engine/renderers/Indicator/kst.js.map +1 -1
  191. package/dist/engine/renderers/Indicator/ma.d.ts +1 -4
  192. package/dist/engine/renderers/Indicator/ma.d.ts.map +1 -1
  193. package/dist/engine/renderers/Indicator/ma.js +1 -1
  194. package/dist/engine/renderers/Indicator/ma.js.map +1 -1
  195. package/dist/engine/renderers/Indicator/macd.d.ts +1 -49
  196. package/dist/engine/renderers/Indicator/macd.d.ts.map +1 -1
  197. package/dist/engine/renderers/Indicator/macd.js +2 -12
  198. package/dist/engine/renderers/Indicator/macd.js.map +1 -1
  199. package/dist/engine/renderers/Indicator/mainIndicatorLegend.d.ts.map +1 -1
  200. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js +114 -1
  201. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js.map +1 -1
  202. package/dist/engine/renderers/Indicator/mfi.d.ts +1 -7
  203. package/dist/engine/renderers/Indicator/mfi.d.ts.map +1 -1
  204. package/dist/engine/renderers/Indicator/mfi.js +3 -15
  205. package/dist/engine/renderers/Indicator/mfi.js.map +1 -1
  206. package/dist/engine/renderers/Indicator/mom.d.ts +1 -22
  207. package/dist/engine/renderers/Indicator/mom.d.ts.map +1 -1
  208. package/dist/engine/renderers/Indicator/mom.js +8 -23
  209. package/dist/engine/renderers/Indicator/mom.js.map +1 -1
  210. package/dist/engine/renderers/Indicator/obv.d.ts +1 -7
  211. package/dist/engine/renderers/Indicator/obv.d.ts.map +1 -1
  212. package/dist/engine/renderers/Indicator/obv.js +3 -14
  213. package/dist/engine/renderers/Indicator/obv.js.map +1 -1
  214. package/dist/engine/renderers/Indicator/parkinson.d.ts +1 -7
  215. package/dist/engine/renderers/Indicator/parkinson.d.ts.map +1 -1
  216. package/dist/engine/renderers/Indicator/parkinson.js +3 -16
  217. package/dist/engine/renderers/Indicator/parkinson.js.map +1 -1
  218. package/dist/engine/renderers/Indicator/pivot.d.ts +1 -6
  219. package/dist/engine/renderers/Indicator/pivot.d.ts.map +1 -1
  220. package/dist/engine/renderers/Indicator/pivot.js +2 -2
  221. package/dist/engine/renderers/Indicator/pivot.js.map +1 -1
  222. package/dist/engine/renderers/Indicator/pvt.d.ts +1 -7
  223. package/dist/engine/renderers/Indicator/pvt.d.ts.map +1 -1
  224. package/dist/engine/renderers/Indicator/pvt.js +3 -14
  225. package/dist/engine/renderers/Indicator/pvt.js.map +1 -1
  226. package/dist/engine/renderers/Indicator/roc.d.ts +1 -8
  227. package/dist/engine/renderers/Indicator/roc.d.ts.map +1 -1
  228. package/dist/engine/renderers/Indicator/roc.js +3 -15
  229. package/dist/engine/renderers/Indicator/roc.js.map +1 -1
  230. package/dist/engine/renderers/Indicator/rsi.d.ts +0 -32
  231. package/dist/engine/renderers/Indicator/rsi.d.ts.map +1 -1
  232. package/dist/engine/renderers/Indicator/rsi.js +3 -3
  233. package/dist/engine/renderers/Indicator/rsi.js.map +1 -1
  234. package/dist/engine/renderers/Indicator/sar.d.ts +1 -8
  235. package/dist/engine/renderers/Indicator/sar.d.ts.map +1 -1
  236. package/dist/engine/renderers/Indicator/sar.js +2 -2
  237. package/dist/engine/renderers/Indicator/sar.js.map +1 -1
  238. package/dist/engine/renderers/Indicator/scale/indicator_scale.d.ts +2 -0
  239. package/dist/engine/renderers/Indicator/scale/indicator_scale.d.ts.map +1 -1
  240. package/dist/engine/renderers/Indicator/scale/indicator_scale.js +10 -6
  241. package/dist/engine/renderers/Indicator/scale/indicator_scale.js.map +1 -1
  242. package/dist/engine/renderers/Indicator/shared/dashedLines.d.ts +4 -0
  243. package/dist/engine/renderers/Indicator/shared/dashedLines.d.ts.map +1 -0
  244. package/dist/engine/renderers/Indicator/shared/dashedLines.js +50 -0
  245. package/dist/engine/renderers/Indicator/shared/dashedLines.js.map +1 -0
  246. package/dist/engine/renderers/Indicator/shared/titleInfo.d.ts +14 -0
  247. package/dist/engine/renderers/Indicator/shared/titleInfo.d.ts.map +1 -0
  248. package/dist/engine/renderers/Indicator/shared/titleInfo.js +25 -0
  249. package/dist/engine/renderers/Indicator/shared/titleInfo.js.map +1 -0
  250. package/dist/engine/renderers/Indicator/shared/webglBand.d.ts +5 -0
  251. package/dist/engine/renderers/Indicator/shared/webglBand.d.ts.map +1 -0
  252. package/dist/engine/renderers/Indicator/shared/webglBand.js +17 -0
  253. package/dist/engine/renderers/Indicator/shared/webglBand.js.map +1 -0
  254. package/dist/engine/renderers/Indicator/stoch.d.ts +1 -22
  255. package/dist/engine/renderers/Indicator/stoch.d.ts.map +1 -1
  256. package/dist/engine/renderers/Indicator/stoch.js +5 -46
  257. package/dist/engine/renderers/Indicator/stoch.js.map +1 -1
  258. package/dist/engine/renderers/Indicator/structure.d.ts +1 -7
  259. package/dist/engine/renderers/Indicator/structure.d.ts.map +1 -1
  260. package/dist/engine/renderers/Indicator/structure.js +2 -2
  261. package/dist/engine/renderers/Indicator/structure.js.map +1 -1
  262. package/dist/engine/renderers/Indicator/supertrend.d.ts +1 -8
  263. package/dist/engine/renderers/Indicator/supertrend.d.ts.map +1 -1
  264. package/dist/engine/renderers/Indicator/supertrend.js +2 -2
  265. package/dist/engine/renderers/Indicator/supertrend.js.map +1 -1
  266. package/dist/engine/renderers/Indicator/tema.d.ts +1 -7
  267. package/dist/engine/renderers/Indicator/tema.d.ts.map +1 -1
  268. package/dist/engine/renderers/Indicator/tema.js +3 -17
  269. package/dist/engine/renderers/Indicator/tema.js.map +1 -1
  270. package/dist/engine/renderers/Indicator/trix.d.ts +1 -8
  271. package/dist/engine/renderers/Indicator/trix.d.ts.map +1 -1
  272. package/dist/engine/renderers/Indicator/trix.js +2 -2
  273. package/dist/engine/renderers/Indicator/trix.js.map +1 -1
  274. package/dist/engine/renderers/Indicator/vma.d.ts +1 -7
  275. package/dist/engine/renderers/Indicator/vma.d.ts.map +1 -1
  276. package/dist/engine/renderers/Indicator/vma.js +3 -15
  277. package/dist/engine/renderers/Indicator/vma.js.map +1 -1
  278. package/dist/engine/renderers/Indicator/volumeProfile.d.ts +1 -7
  279. package/dist/engine/renderers/Indicator/volumeProfile.d.ts.map +1 -1
  280. package/dist/engine/renderers/Indicator/volumeProfile.js +2 -2
  281. package/dist/engine/renderers/Indicator/volumeProfile.js.map +1 -1
  282. package/dist/engine/renderers/Indicator/vwap.d.ts +1 -7
  283. package/dist/engine/renderers/Indicator/vwap.d.ts.map +1 -1
  284. package/dist/engine/renderers/Indicator/vwap.js +3 -14
  285. package/dist/engine/renderers/Indicator/vwap.js.map +1 -1
  286. package/dist/engine/renderers/Indicator/wma.d.ts +1 -7
  287. package/dist/engine/renderers/Indicator/wma.d.ts.map +1 -1
  288. package/dist/engine/renderers/Indicator/wma.js +3 -17
  289. package/dist/engine/renderers/Indicator/wma.js.map +1 -1
  290. package/dist/engine/renderers/Indicator/wmsr.d.ts +1 -22
  291. package/dist/engine/renderers/Indicator/wmsr.d.ts.map +1 -1
  292. package/dist/engine/renderers/Indicator/wmsr.js +8 -23
  293. package/dist/engine/renderers/Indicator/wmsr.js.map +1 -1
  294. package/dist/engine/renderers/Indicator/zones.d.ts +1 -6
  295. package/dist/engine/renderers/Indicator/zones.d.ts.map +1 -1
  296. package/dist/engine/renderers/Indicator/zones.js +2 -2
  297. package/dist/engine/renderers/Indicator/zones.js.map +1 -1
  298. package/dist/engine/renderers/candle.d.ts +0 -16
  299. package/dist/engine/renderers/candle.d.ts.map +1 -1
  300. package/dist/engine/renderers/candle.js +1 -1
  301. package/dist/engine/renderers/candle.js.map +1 -1
  302. package/dist/engine/renderers/comparisonLine.d.ts.map +1 -1
  303. package/dist/engine/renderers/comparisonLine.js +2 -0
  304. package/dist/engine/renderers/comparisonLine.js.map +1 -1
  305. package/dist/engine/renderers/extremaMarkers.d.ts.map +1 -1
  306. package/dist/engine/renderers/extremaMarkers.js +2 -0
  307. package/dist/engine/renderers/extremaMarkers.js.map +1 -1
  308. package/dist/engine/renderers/gridLines.d.ts.map +1 -1
  309. package/dist/engine/renderers/gridLines.js +7 -35
  310. package/dist/engine/renderers/gridLines.js.map +1 -1
  311. package/dist/engine/renderers/lastPrice.d.ts.map +1 -1
  312. package/dist/engine/renderers/lastPrice.js +7 -2
  313. package/dist/engine/renderers/lastPrice.js.map +1 -1
  314. package/dist/engine/renderers/leftYAxis.d.ts +11 -0
  315. package/dist/engine/renderers/leftYAxis.d.ts.map +1 -0
  316. package/dist/engine/renderers/leftYAxis.js +79 -0
  317. package/dist/engine/renderers/leftYAxis.js.map +1 -0
  318. package/dist/engine/renderers/subVolume.d.ts +1 -13
  319. package/dist/engine/renderers/subVolume.d.ts.map +1 -1
  320. package/dist/engine/renderers/subVolume.js +1 -1
  321. package/dist/engine/renderers/subVolume.js.map +1 -1
  322. package/dist/engine/renderers/timeAxis.d.ts +0 -2
  323. package/dist/engine/renderers/timeAxis.d.ts.map +1 -1
  324. package/dist/engine/renderers/timeAxis.js +4 -1
  325. package/dist/engine/renderers/timeAxis.js.map +1 -1
  326. package/dist/engine/renderers/timeShare.d.ts +3 -0
  327. package/dist/engine/renderers/timeShare.d.ts.map +1 -0
  328. package/dist/engine/renderers/timeShare.js +260 -0
  329. package/dist/engine/renderers/timeShare.js.map +1 -0
  330. package/dist/engine/renderers/yAxis.d.ts.map +1 -1
  331. package/dist/engine/renderers/yAxis.js +25 -23
  332. package/dist/engine/renderers/yAxis.js.map +1 -1
  333. package/dist/engine/scale/price.d.ts +0 -7
  334. package/dist/engine/scale/price.d.ts.map +1 -1
  335. package/dist/engine/scale/price.js +3 -2
  336. package/dist/engine/scale/price.js.map +1 -1
  337. package/dist/engine/theme/fonts.d.ts +0 -2
  338. package/dist/engine/theme/fonts.d.ts.map +1 -1
  339. package/dist/engine/theme/fonts.js +1 -1
  340. package/dist/engine/theme/fonts.js.map +1 -1
  341. package/dist/engine/utils/klineConfig.d.ts.map +1 -1
  342. package/dist/engine/utils/klineConfig.js +1 -5
  343. package/dist/engine/utils/klineConfig.js.map +1 -1
  344. package/dist/engine/utils/tickPosition.d.ts +12 -0
  345. package/dist/engine/utils/tickPosition.d.ts.map +1 -1
  346. package/dist/engine/utils/tickPosition.js +15 -0
  347. package/dist/engine/utils/tickPosition.js.map +1 -1
  348. package/dist/engine/viewport/chartViewportManager.d.ts +0 -4
  349. package/dist/engine/viewport/chartViewportManager.d.ts.map +1 -1
  350. package/dist/engine/viewport/chartViewportManager.js +10 -13
  351. package/dist/engine/viewport/chartViewportManager.js.map +1 -1
  352. package/dist/plugin/types.d.ts +10 -0
  353. package/dist/plugin/types.d.ts.map +1 -1
  354. package/dist/plugin/types.js.map +1 -1
  355. package/dist/semantic/types.d.ts +1 -1
  356. package/dist/semantic/types.d.ts.map +1 -1
  357. package/dist/tokens/theme-base.d.ts +5 -0
  358. package/dist/tokens/theme-base.d.ts.map +1 -0
  359. package/dist/tokens/theme-base.js +31 -0
  360. package/dist/tokens/theme-base.js.map +1 -0
  361. package/dist/tokens/theme-china.d.ts.map +1 -1
  362. package/dist/tokens/theme-china.js +3 -0
  363. package/dist/tokens/theme-china.js.map +1 -1
  364. package/dist/tokens/theme-dark.d.ts.map +1 -1
  365. package/dist/tokens/theme-dark.js +11 -30
  366. package/dist/tokens/theme-dark.js.map +1 -1
  367. package/dist/tokens/theme-light.d.ts.map +1 -1
  368. package/dist/tokens/theme-light.js +11 -30
  369. package/dist/tokens/theme-light.js.map +1 -1
  370. package/dist/tokens/types.d.ts +7 -0
  371. package/dist/tokens/types.d.ts.map +1 -1
  372. package/dist/types/price.d.ts +8 -0
  373. package/dist/types/price.d.ts.map +1 -1
  374. package/dist/types/price.js +4 -0
  375. package/dist/types/price.js.map +1 -1
  376. package/dist/utils/dateFormat.d.ts +5 -42
  377. package/dist/utils/dateFormat.d.ts.map +1 -1
  378. package/dist/utils/dateFormat.js +24 -4
  379. package/dist/utils/dateFormat.js.map +1 -1
  380. package/dist/utils/kLineDraw/axis.d.ts +9 -28
  381. package/dist/utils/kLineDraw/axis.d.ts.map +1 -1
  382. package/dist/utils/kLineDraw/axis.js +33 -58
  383. package/dist/utils/kLineDraw/axis.js.map +1 -1
  384. package/dist/utils/volumePrice.d.ts +0 -40
  385. package/dist/utils/volumePrice.d.ts.map +1 -1
  386. package/dist/utils/volumePrice.js +2 -2
  387. package/dist/utils/volumePrice.js.map +1 -1
  388. package/dist/version.d.ts +1 -1
  389. package/dist/version.js +1 -1
  390. package/package.json +1 -1
  391. package/src/config/chartSettings.ts +8 -1
  392. package/src/controllers/createChartController.ts +59 -2
  393. package/src/controllers/types.ts +38 -17
  394. package/src/data-fetchers/__tests__/dataBuffer.test.ts +39 -5
  395. package/src/data-fetchers/baostock.ts +1 -1
  396. package/src/data-fetchers/dataBuffer.ts +48 -11
  397. package/src/data-fetchers/dataBufferTypes.ts +11 -0
  398. package/src/data-fetchers/fetcherDefinitionRegistry.ts +14 -4
  399. package/src/data-fetchers/gotdx/gotdx.ts +6 -0
  400. package/src/data-fetchers/gotdx.ts +45 -7
  401. package/src/data-fetchers/hundred-mock.ts +1 -1
  402. package/src/data-fetchers/index.ts +10 -20
  403. package/src/data-fetchers/router.ts +12 -1
  404. package/src/data-fetchers/thousand-mock.ts +1 -1
  405. package/src/data-fetchers/timeShareBuffer.ts +92 -0
  406. package/src/data-fetchers/tradingview.ts +2 -2
  407. package/src/data-fetchers/types.ts +15 -2
  408. package/src/engine/__tests__/chart.dpr.test.ts +1 -0
  409. package/src/engine/chart.ts +167 -9
  410. package/src/engine/chartTypes.ts +3 -0
  411. package/src/engine/controller/__tests__/interaction.dpr.test.ts +2 -0
  412. package/src/engine/controller/interaction.ts +80 -28
  413. package/src/engine/data/chartDataManager.ts +560 -229
  414. package/src/engine/draw/pixelAlign.ts +1 -1
  415. package/src/engine/indicators/__tests__/_propertyAssertions.ts +2 -2
  416. package/src/engine/indicators/__tests__/registerBuiltins.test.ts +1 -1
  417. package/src/engine/indicators/calculators.ts +83 -233
  418. package/src/engine/indicators/chartIndicatorManager.ts +3 -2
  419. package/src/engine/indicators/macdState.ts +1 -1
  420. package/src/engine/indicators/registerBuiltins.ts +1 -0
  421. package/src/engine/indicators/rsiState.ts +1 -1
  422. package/src/engine/indicators/scheduler.ts +1 -7
  423. package/src/engine/layout/chartPaneLayout.ts +26 -6
  424. package/src/engine/modes/kLineMode.ts +57 -0
  425. package/src/engine/modes/timeShareMode.ts +95 -0
  426. package/src/engine/modes/types.ts +63 -0
  427. package/src/engine/paneRenderer.ts +37 -46
  428. package/src/engine/render/chartRenderer.ts +120 -22
  429. package/src/engine/renderers/Indicator/atr.ts +4 -29
  430. package/src/engine/renderers/Indicator/boll.ts +3 -24
  431. package/src/engine/renderers/Indicator/cci.ts +9 -27
  432. package/src/engine/renderers/Indicator/chaikinVol.ts +3 -23
  433. package/src/engine/renderers/Indicator/cmf.ts +3 -22
  434. package/src/engine/renderers/Indicator/dema.ts +5 -26
  435. package/src/engine/renderers/Indicator/donchian.ts +3 -3
  436. package/src/engine/renderers/Indicator/ene.ts +3 -24
  437. package/src/engine/renderers/Indicator/expma.ts +2 -2
  438. package/src/engine/renderers/Indicator/fastk.ts +12 -95
  439. package/src/engine/renderers/Indicator/fib.ts +2 -2
  440. package/src/engine/renderers/Indicator/hma.ts +5 -26
  441. package/src/engine/renderers/Indicator/hv.ts +3 -23
  442. package/src/engine/renderers/Indicator/ichimoku.ts +3 -3
  443. package/src/engine/renderers/Indicator/kama.ts +5 -26
  444. package/src/engine/renderers/Indicator/keltner.ts +3 -3
  445. package/src/engine/renderers/Indicator/kst.ts +3 -3
  446. package/src/engine/renderers/Indicator/ma.ts +1 -1
  447. package/src/engine/renderers/Indicator/macd.ts +4 -21
  448. package/src/engine/renderers/Indicator/mainIndicatorLegend.ts +127 -2
  449. package/src/engine/renderers/Indicator/mfi.ts +3 -22
  450. package/src/engine/renderers/Indicator/mom.ts +9 -30
  451. package/src/engine/renderers/Indicator/obv.ts +3 -21
  452. package/src/engine/renderers/Indicator/parkinson.ts +3 -23
  453. package/src/engine/renderers/Indicator/pivot.ts +2 -2
  454. package/src/engine/renderers/Indicator/pvt.ts +3 -21
  455. package/src/engine/renderers/Indicator/roc.ts +4 -23
  456. package/src/engine/renderers/Indicator/rsi.ts +4 -4
  457. package/src/engine/renderers/Indicator/sar.ts +3 -3
  458. package/src/engine/renderers/Indicator/scale/indicator_scale.ts +11 -4
  459. package/src/engine/renderers/Indicator/shared/dashedLines.ts +81 -0
  460. package/src/engine/renderers/Indicator/shared/titleInfo.ts +52 -0
  461. package/src/engine/renderers/Indicator/shared/webglBand.ts +23 -0
  462. package/src/engine/renderers/Indicator/stoch.ts +6 -71
  463. package/src/engine/renderers/Indicator/structure.ts +2 -2
  464. package/src/engine/renderers/Indicator/supertrend.ts +3 -3
  465. package/src/engine/renderers/Indicator/tema.ts +5 -26
  466. package/src/engine/renderers/Indicator/trix.ts +3 -3
  467. package/src/engine/renderers/Indicator/vma.ts +3 -22
  468. package/src/engine/renderers/Indicator/volumeProfile.ts +2 -2
  469. package/src/engine/renderers/Indicator/vwap.ts +3 -21
  470. package/src/engine/renderers/Indicator/wma.ts +5 -26
  471. package/src/engine/renderers/Indicator/wmsr.ts +9 -30
  472. package/src/engine/renderers/Indicator/zones.ts +2 -2
  473. package/src/engine/renderers/__tests__/yAxis.renderer.test.ts +30 -26
  474. package/src/engine/renderers/candle.ts +1 -1
  475. package/src/engine/renderers/comparisonLine.ts +1 -0
  476. package/src/engine/renderers/extremaMarkers.ts +1 -0
  477. package/src/engine/renderers/gridLines.ts +7 -36
  478. package/src/engine/renderers/lastPrice.ts +5 -2
  479. package/src/engine/renderers/leftYAxis.ts +93 -0
  480. package/src/engine/renderers/subVolume.ts +3 -3
  481. package/src/engine/renderers/timeAxis.ts +16 -13
  482. package/src/engine/renderers/timeShare.ts +271 -0
  483. package/src/engine/renderers/yAxis.ts +28 -24
  484. package/src/engine/scale/price.ts +2 -2
  485. package/src/engine/theme/fonts.ts +1 -1
  486. package/src/engine/utils/klineConfig.ts +1 -5
  487. package/src/engine/utils/tickPosition.ts +34 -0
  488. package/src/engine/viewport/chartViewportManager.ts +11 -15
  489. package/src/plugin/types.ts +11 -0
  490. package/src/semantic/types.ts +1 -1
  491. package/src/tokens/__tests__/__snapshots__/baseline.test.ts.snap +14 -0
  492. package/src/tokens/theme-base.ts +36 -0
  493. package/src/tokens/theme-china.ts +4 -0
  494. package/src/tokens/theme-dark.ts +12 -32
  495. package/src/tokens/theme-light.ts +13 -33
  496. package/src/tokens/types.ts +9 -0
  497. package/src/types/price.ts +13 -0
  498. package/src/utils/dateFormat.ts +27 -4
  499. package/src/utils/kLineDraw/axis.ts +40 -107
  500. package/src/utils/volumePrice.ts +2 -2
  501. package/src/version.ts +1 -1
@@ -1,24 +1,36 @@
1
1
  import { createSignal } from '../../reactivity/signal';
2
2
  import { DataBuffer } from '../../data-fetchers/dataBuffer';
3
+ import { TimeShareBuffer } from '../../data-fetchers/timeShareBuffer';
3
4
  import { getVisibleRange } from '../viewport/viewport';
4
5
  import { getPhysicalKLineConfig } from '../utils/klineConfig';
5
6
  const COMPARISON_PALETTE = ['#f59e0b', '#8b5cf6', '#06b6d4', '#ec4899', '#84cc16', '#f97316'];
6
7
  const DEFAULT_COMPARISON_COLOR = '#f59e0b';
8
+ const BUF_PRIMARY = 'main';
9
+ const BUF_COMPARISON = 'cmp';
10
+ const BUF_TIMESHARE = 'ts';
11
+ function bufKey(type, symbol, period) {
12
+ if (type === BUF_TIMESHARE)
13
+ return `ts:${symbol}`;
14
+ return `${type}:${symbol}:${period ?? 'daily'}`;
15
+ }
7
16
  export class ChartDataManager {
8
- _internalData = [];
9
17
  _dataFetcher = null;
10
- _dataBuffer = new DataBuffer();
11
- _dataBufferUnsub = null;
18
+ _timeShareFetcher = null;
19
+ _buffers = new Map();
20
+ _activeBufferKey = null;
21
+ _activeBufferUnsub = null;
22
+ _dataSignal = createSignal([]);
23
+ _loadingSignal = createSignal(false);
24
+ _symbolsSignal = createSignal([]);
25
+ _currentSpec = null;
26
+ // Comparison-specific state (still needed for rendering pass-through)
12
27
  _comparisonSpecs = [];
13
28
  _comparisonData = new Map();
14
- _comparisonBuffers = new Map();
15
- _comparisonBufferUnsubs = new Map();
16
29
  _comparisonColors = new Map();
17
30
  _comparisonColorsSignal = createSignal(new Map());
18
- _comparisonLoadingUnsubs = new Map();
19
31
  _comparisonLoadingSignal = createSignal(false);
20
- _dataSignal = createSignal([]);
21
- _symbolsSignal = createSignal([]);
32
+ // Track loading per-comparison buffer (keyed by buffer key)
33
+ _cmpLoadingUnsubs = new Map();
22
34
  _pendingFetches = [];
23
35
  _batchFlushScheduled = false;
24
36
  incrementalLoadHintEl = null;
@@ -31,31 +43,160 @@ export class ChartDataManager {
31
43
  constructor(deps) {
32
44
  this.deps = deps;
33
45
  }
46
+ // ── Buffer helpers ──
47
+ activateBuffer(key) {
48
+ if (this._activeBufferKey === key)
49
+ return;
50
+ this._activeBufferUnsub?.();
51
+ this._activeBufferKey = key;
52
+ const buf = this._buffers.get(key);
53
+ if (buf) {
54
+ this._dataSignal.set([...buf.data.peek()]);
55
+ this._loadingSignal.set(buf.loading.peek());
56
+ const unsubData = buf.data.subscribe(() => {
57
+ const prevDataLength = this._dataSignal.peek().length;
58
+ this._dataSignal.set([...buf.data.peek()]);
59
+ this.onBufferDataChanged(key, prevDataLength);
60
+ });
61
+ const unsubLoading = buf.loading.subscribe(() => {
62
+ this._loadingSignal.set(buf.loading.peek());
63
+ });
64
+ this._activeBufferUnsub = () => {
65
+ unsubData();
66
+ unsubLoading();
67
+ };
68
+ }
69
+ else {
70
+ this._dataSignal.set([]);
71
+ this._loadingSignal.set(false);
72
+ this._activeBufferUnsub = null;
73
+ }
74
+ }
75
+ disposeBuffer(key) {
76
+ const buf = this._buffers.get(key);
77
+ if (!buf)
78
+ return;
79
+ const unsub = this._cmpLoadingUnsubs.get(key);
80
+ unsub?.();
81
+ const loadingUnsub = this._cmpLoadingUnsubs.get(`loading:${key}`);
82
+ loadingUnsub?.();
83
+ this._cmpLoadingUnsubs.delete(key);
84
+ this._cmpLoadingUnsubs.delete(`loading:${key}`);
85
+ buf.dispose();
86
+ this._buffers.delete(key);
87
+ }
88
+ getActiveDataBuffer() {
89
+ const buf = this._activeBufferKey ? this._buffers.get(this._activeBufferKey) : null;
90
+ return buf instanceof DataBuffer ? buf : null;
91
+ }
92
+ getActiveTimeShareBuffer() {
93
+ const buf = this._activeBufferKey ? this._buffers.get(this._activeBufferKey) : null;
94
+ return buf instanceof TimeShareBuffer ? buf : null;
95
+ }
96
+ getPrimaryDataBuffer(symbol, period) {
97
+ const key = bufKey(BUF_PRIMARY, symbol, period);
98
+ let buf = this._buffers.get(key);
99
+ if (!buf) {
100
+ buf = new DataBuffer();
101
+ buf.setFetcher(this._dataFetcher);
102
+ if (this._dataFetcher) {
103
+ buf.setRequestFetch(this._createBatchHandler(this._dataFetcher));
104
+ }
105
+ this._buffers.set(key, buf);
106
+ }
107
+ else {
108
+ buf.setFetcher(this._dataFetcher);
109
+ if (this._dataFetcher) {
110
+ buf.setRequestFetch(this._createBatchHandler(this._dataFetcher));
111
+ }
112
+ }
113
+ return buf;
114
+ }
115
+ // ── Buffer data change handler ──
116
+ onBufferDataChanged(key, prevDataLength) {
117
+ const buf = this._buffers.get(key);
118
+ if (!buf)
119
+ return;
120
+ if (buf instanceof DataBuffer) {
121
+ this.onKLineBufferChanged(key, buf, prevDataLength);
122
+ }
123
+ else if (buf instanceof TimeShareBuffer) {
124
+ this.onTimeShareBufferChanged(key, buf);
125
+ }
126
+ }
127
+ onKLineBufferChanged(key, buf, prevDataLength) {
128
+ if (!key.startsWith('main:'))
129
+ return;
130
+ const bufferData = buf.getRawData();
131
+ const prependedCount = this.pendingPrependedCount;
132
+ this.pendingPrependedCount = 0;
133
+ if (prependedCount === 0 && this.deps.getCachedScrollLeft() < this.getLeftLoadBufferWidth()) {
134
+ this.deps.setScrollLeft(this.getLeftLoadBufferWidth());
135
+ }
136
+ if ((prevDataLength ?? this._dataSignal.peek().length) === 0 && bufferData.length > 0) {
137
+ this.scrollToRight();
138
+ }
139
+ this.deps.resetInteraction();
140
+ if (this.lastVisibleRange.start === 0 && this.lastVisibleRange.end === 0 && bufferData.length > 0) {
141
+ const plotWidth = this.deps.getObservedSize().width > 0
142
+ ? this.deps.getObservedSize().width
143
+ : Math.max(1, Math.round(this.deps.getDom().container?.clientWidth ?? 800));
144
+ const dpr = this.deps.getEffectiveDpr();
145
+ const opt = this.deps.getOption();
146
+ const { start, end } = getVisibleRange(this.deps.getLogicalScrollLeft(), plotWidth, opt.kWidth, opt.kGap, bufferData.length, dpr);
147
+ this.lastRawVisibleRange = { start, end };
148
+ this.lastVisibleRange = { start: Math.max(0, start), end };
149
+ }
150
+ const scheduler = this.deps.getIndicatorScheduler();
151
+ const indicatorsReady = scheduler.update(bufferData, this.lastVisibleRange);
152
+ if (indicatorsReady) {
153
+ this.pendingIndicatorDataUpdate = false;
154
+ this.deps.scheduleDraw();
155
+ }
156
+ else {
157
+ this.pendingIndicatorDataUpdate = true;
158
+ }
159
+ this.showIncrementalLoadHint(prependedCount);
160
+ }
161
+ onTimeShareBufferChanged(_key, _buf) {
162
+ const data = this._dataSignal.peek();
163
+ this.lastVisibleRange = { start: 0, end: data.length };
164
+ this.lastRawVisibleRange = { start: 0, end: data.length };
165
+ this.deps.resetInteraction();
166
+ this.deps.onTimeShareDataReady(data.length);
167
+ }
168
+ // ── Internal helpers ──
34
169
  getScrollContentHost() {
35
170
  return this.deps.getDom().scrollContent ?? this.deps.getDom().container ?? null;
36
171
  }
37
172
  getLeftLoadBufferWidth() {
38
- if (this._internalData.length === 0)
173
+ const buf = this.getActiveDataBuffer();
174
+ const dataLength = buf ? buf.getRawData().length : 0;
175
+ if (dataLength === 0)
39
176
  return 0;
40
177
  const plotWidth = this.deps.getViewport()?.plotWidth
41
178
  ?? (this.deps.getObservedSize().width > 0 ? this.deps.getObservedSize().width : undefined)
42
179
  ?? Math.round(this.deps.getDom().container?.clientWidth ?? 0);
43
180
  return Math.max(0, plotWidth);
44
181
  }
182
+ getActiveKLineLength() {
183
+ const buf = this.getActiveDataBuffer();
184
+ return buf ? buf.getRawData().length : 0;
185
+ }
45
186
  computeRawVisibleRange() {
46
- if (this._internalData.length === 0)
187
+ const buf = this.getActiveDataBuffer();
188
+ const dataLength = buf ? buf.getRawData().length : 0;
189
+ if (dataLength === 0)
47
190
  return null;
48
191
  const vp = this.deps.getViewport();
49
192
  if (!vp)
50
193
  return null;
51
194
  const opt = this.deps.getOption();
52
- return getVisibleRange(vp.scrollLeft, vp.plotWidth, opt.kWidth, opt.kGap, this._internalData.length, vp.dpr);
195
+ return getVisibleRange(vp.scrollLeft, vp.plotWidth, opt.kWidth, opt.kGap, dataLength, vp.dpr);
53
196
  }
54
197
  getTrailingSlotCount() {
55
198
  return 24;
56
199
  }
57
- static LEADING_SLOTS = 60;
58
- static TRAILING_DRAWING_SLOTS = 24;
59
200
  clearIncrementalLoadHintTimer() {
60
201
  if (this.incrementalLoadHintTimer !== null) {
61
202
  window.clearTimeout(this.incrementalLoadHintTimer);
@@ -82,7 +223,6 @@ export class ChartDataManager {
82
223
  const hint = ownerDoc.createElement('div');
83
224
  hint.className = 'klc-incremental-load-hint';
84
225
  hint.style.position = 'absolute';
85
- hint.style.left = '0';
86
226
  hint.style.top = '0';
87
227
  hint.style.height = '0px';
88
228
  hint.style.width = '0px';
@@ -107,7 +247,8 @@ export class ChartDataManager {
107
247
  const dpr = this.deps.getEffectiveDpr();
108
248
  const opt = this.deps.getOption();
109
249
  const { unitPx, startXPx } = getPhysicalKLineConfig(opt.kWidth, opt.kGap, dpr);
110
- const width = this.getLeftLoadBufferWidth() + (startXPx + count * unitPx) / dpr;
250
+ hint.style.left = `${this.getLeftLoadBufferWidth()}px`;
251
+ const width = (startXPx + count * unitPx) / dpr;
111
252
  hint.style.width = `${Math.max(0, width)}px`;
112
253
  hint.style.height = `${Math.max(0, this.deps.getViewport()?.viewHeight ?? this.deps.getDom().container?.clientHeight ?? 0)}px`;
113
254
  hint.getBoundingClientRect();
@@ -118,17 +259,43 @@ export class ChartDataManager {
118
259
  this.incrementalLoadHintTimer = null;
119
260
  }, 900);
120
261
  }
262
+ // ── Public accessors ──
263
+ /** Unified data signal — always reflects the active buffer's data */
121
264
  get data() {
122
265
  return this._dataSignal;
123
266
  }
267
+ /** Loading signal — mirrors the active buffer's loading state */
268
+ get loading() {
269
+ return this._loadingSignal;
270
+ }
124
271
  get symbols() {
125
272
  return this._symbolsSignal;
126
273
  }
127
274
  get currentPeriod() {
128
- return this._dataBuffer.currentSpec?.period ?? 'daily';
275
+ return this._currentSpec?.period ?? 'daily';
129
276
  }
277
+ /** Internal KLine data for indicator scheduler (empty in timeshare mode) */
130
278
  getInternalData() {
131
- return this._internalData;
279
+ const buf = this.getActiveDataBuffer();
280
+ return buf ? buf.getRawData() : [];
281
+ }
282
+ getRenderData() {
283
+ return [...this._dataSignal.peek()];
284
+ }
285
+ getTimeShareData() {
286
+ const buf = this.getActiveTimeShareBuffer();
287
+ return buf ? buf.getRawData() : [];
288
+ }
289
+ getTimeShareSignal() {
290
+ const buf = this.getActiveTimeShareBuffer();
291
+ return (buf?.data ?? createSignal([]));
292
+ }
293
+ getTimeShareLoadingSignal() {
294
+ const buf = this.getActiveTimeShareBuffer();
295
+ return (buf?.loading ?? createSignal(false));
296
+ }
297
+ setTimeShareFetcher(fetcher) {
298
+ this._timeShareFetcher = fetcher;
132
299
  }
133
300
  getComparisonData() {
134
301
  return this._comparisonData;
@@ -137,7 +304,17 @@ export class ChartDataManager {
137
304
  return this._comparisonSpecs;
138
305
  }
139
306
  get dataBuffer() {
140
- return this._dataBuffer;
307
+ const buf = this.getActiveDataBuffer();
308
+ if (buf)
309
+ return buf;
310
+ // Fallback: create a primary buffer if none exists yet
311
+ const key = bufKey(BUF_PRIMARY, '', 'daily');
312
+ let fallback = this._buffers.get(key);
313
+ if (!fallback) {
314
+ fallback = new DataBuffer();
315
+ this._buffers.set(key, fallback);
316
+ }
317
+ return fallback;
141
318
  }
142
319
  get comparisonColors() {
143
320
  return this._comparisonColorsSignal;
@@ -149,70 +326,59 @@ export class ChartDataManager {
149
326
  return this._comparisonColors;
150
327
  }
151
328
  recomputeComparisonLoading() {
152
- const anyLoading = Array.from(this._comparisonBuffers.values()).some((b) => b.loading.peek());
329
+ const anyLoading = Array.from(this._buffers.entries()).some(([k, b]) => k.startsWith(BUF_COMPARISON) && b instanceof DataBuffer && b.loading.peek());
153
330
  this._comparisonLoadingSignal.set(anyLoading);
154
331
  }
332
+ // ── Data updates (KLine) ──
155
333
  updateData(data) {
156
- this._internalData = data ?? [];
157
- this._dataSignal.set([...this._internalData]);
158
- const container = this.deps.getDom().container;
159
- if (container) {
160
- const minScrollLeft = this.getLeftLoadBufferWidth();
161
- if (this.deps.getCachedScrollLeft() < minScrollLeft) {
162
- this.deps.setCachedScrollLeft(minScrollLeft);
163
- this.deps.setPendingScrollLeft(minScrollLeft);
164
- }
165
- const contentWidth = this.getContentWidth();
166
- const maxScrollLeft = Math.max(0, contentWidth - container.clientWidth);
167
- if (this.deps.getCachedScrollLeft() > maxScrollLeft) {
168
- this.deps.setCachedScrollLeft(maxScrollLeft);
169
- this.deps.setPendingScrollLeft(maxScrollLeft);
170
- }
171
- }
172
- this.deps.resetInteraction();
173
- if (this.lastVisibleRange.start === 0 && this.lastVisibleRange.end === 0 && this._internalData.length > 0) {
174
- const plotWidth = this.deps.getObservedSize().width > 0
175
- ? this.deps.getObservedSize().width
176
- : Math.max(1, Math.round(this.deps.getDom().container?.clientWidth ?? 800));
177
- const dpr = this.deps.getEffectiveDpr();
178
- const opt = this.deps.getOption();
179
- const { start, end } = getVisibleRange(this.deps.getLogicalScrollLeft(), plotWidth, opt.kWidth, opt.kGap, this._internalData.length, dpr);
180
- this.lastRawVisibleRange = { start, end };
181
- this.lastVisibleRange = { start: Math.max(0, start), end };
334
+ if (this.currentPeriod === 'timeshare')
335
+ return;
336
+ const buf = this.getActiveDataBuffer();
337
+ if (buf) {
338
+ buf.setInlineData(data);
182
339
  }
183
- const scheduler = this.deps.getIndicatorScheduler();
184
- const indicatorsReady = scheduler.update(this._internalData, this.lastVisibleRange);
185
- if (indicatorsReady) {
186
- this.pendingIndicatorDataUpdate = false;
187
- this.deps.scheduleDraw();
340
+ }
341
+ setData(data) {
342
+ const buf = this.getActiveDataBuffer();
343
+ if (buf) {
344
+ buf.setInlineData(data);
188
345
  }
189
346
  else {
190
- this.pendingIndicatorDataUpdate = true;
347
+ this._dataSignal.set([...data]);
191
348
  }
192
349
  }
193
- setData(data) {
194
- this.updateData(data);
195
- }
196
350
  appendData(newData) {
197
- const merged = [...this._internalData, ...newData];
198
- this.setData(merged);
351
+ const buf = this.getActiveDataBuffer();
352
+ if (buf) {
353
+ const merged = [...buf.getRawData(), ...newData];
354
+ buf.setInlineData(merged);
355
+ }
356
+ else {
357
+ this._dataSignal.set([...this._dataSignal.peek(), ...newData]);
358
+ }
199
359
  }
200
360
  getData() {
201
- return this._internalData;
361
+ const buf = this.getActiveDataBuffer();
362
+ return buf ? buf.getRawData() : [];
202
363
  }
364
+ // ── Fetcher ──
203
365
  setDataFetcher(fetcher) {
204
366
  this._dataFetcher = fetcher;
205
367
  if (!fetcher) {
206
- this._dataBuffer.setRequestFetch(null);
207
- for (const buffer of this._comparisonBuffers.values()) {
208
- buffer.setRequestFetch(null);
368
+ for (const [key, buf] of this._buffers) {
369
+ if (buf instanceof DataBuffer) {
370
+ const dataBuf = buf;
371
+ dataBuf.setRequestFetch(null);
372
+ }
209
373
  }
210
374
  return;
211
375
  }
212
376
  const handler = this._createBatchHandler(fetcher);
213
- this._dataBuffer.setRequestFetch(handler);
214
- for (const buffer of this._comparisonBuffers.values()) {
215
- buffer.setRequestFetch(handler);
377
+ for (const [key, buf] of this._buffers) {
378
+ if (buf instanceof DataBuffer) {
379
+ const dataBuf = buf;
380
+ dataBuf.setRequestFetch(handler);
381
+ }
216
382
  }
217
383
  }
218
384
  _createBatchHandler(fetcher) {
@@ -254,9 +420,13 @@ export class ChartDataManager {
254
420
  }
255
421
  }
256
422
  checkVisibleRangeGap() {
257
- if (this._internalData.length === 0)
423
+ const buf = this.getActiveDataBuffer();
424
+ if (!buf)
425
+ return;
426
+ const data = buf.getRawData();
427
+ if (data.length === 0)
258
428
  return;
259
- const window = this._dataBuffer.loadedWindow;
429
+ const window = buf.loadedWindow;
260
430
  if (!window)
261
431
  return;
262
432
  const range = this.computeRawVisibleRange() ?? this.lastRawVisibleRange;
@@ -264,74 +434,77 @@ export class ChartDataManager {
264
434
  let firstVisibleTs;
265
435
  if (range.start < 0 && this._dataFetcher) {
266
436
  const earlierThanEarliest = window.earliestTs - 365 * MS_PER_DAY;
267
- this._dataBuffer.ensureRange(earlierThanEarliest, window.earliestTs);
268
- firstVisibleTs = this._internalData[0]?.timestamp;
437
+ buf.ensureRange(earlierThanEarliest, window.earliestTs);
438
+ firstVisibleTs = data[0]?.timestamp;
269
439
  }
270
- else if (range.start < this._internalData.length) {
271
- firstVisibleTs = this._internalData[Math.max(0, range.start)]?.timestamp;
440
+ else if (range.start < data.length) {
441
+ firstVisibleTs = data[Math.max(0, range.start)]?.timestamp;
272
442
  if (firstVisibleTs !== undefined && firstVisibleTs < window.earliestTs) {
273
- this._dataBuffer.ensureRange(firstVisibleTs, window.earliestTs);
443
+ buf.ensureRange(firstVisibleTs, window.earliestTs);
274
444
  }
275
445
  }
276
446
  if (firstVisibleTs === undefined)
277
447
  return;
278
- for (const buffer of this._comparisonBuffers.values()) {
279
- buffer.ensureRange(firstVisibleTs, window.earliestTs);
448
+ for (const [key, b] of this._buffers) {
449
+ if (key.startsWith(BUF_COMPARISON) && b instanceof DataBuffer) {
450
+ b.ensureRange(firstVisibleTs, window.earliestTs);
451
+ }
280
452
  }
281
453
  }
454
+ // ── Comparison management ──
282
455
  syncComparisonBuffers(specs) {
283
456
  this._comparisonSpecs = [...specs];
284
457
  const nextKeys = new Set(specs.map((spec) => spec.symbol));
285
- for (const [key, buffer] of this._comparisonBuffers) {
286
- if (nextKeys.has(key))
458
+ // Remove buffers for removed comparisons
459
+ for (const [key, buf] of this._buffers) {
460
+ if (!key.startsWith(BUF_COMPARISON))
461
+ continue;
462
+ const symbol = key.split(':')[1];
463
+ if (nextKeys.has(symbol))
287
464
  continue;
288
- this._comparisonBufferUnsubs.get(key)?.();
289
- this._comparisonBufferUnsubs.delete(key);
290
- buffer.dispose();
291
- this._comparisonBuffers.delete(key);
292
- this._comparisonData.delete(key);
465
+ this.disposeBuffer(key);
466
+ this._comparisonData.delete(symbol);
293
467
  }
294
468
  if (!this._dataFetcher)
295
469
  return;
470
+ const primaryBuf = this.getActiveDataBuffer();
296
471
  for (const spec of specs) {
297
- const key = spec.symbol;
298
- let buffer = this._comparisonBuffers.get(key);
299
- if (!buffer) {
472
+ const key = bufKey(BUF_COMPARISON, spec.symbol, spec.period);
473
+ const symbol = spec.symbol;
474
+ let buf = this._buffers.get(key);
475
+ if (!buf) {
300
476
  const newBuffer = new DataBuffer();
301
477
  newBuffer.setFetcher(this._dataFetcher);
302
478
  if (this._dataFetcher) {
303
479
  newBuffer.setRequestFetch(this._createBatchHandler(this._dataFetcher));
304
480
  }
305
- this._comparisonBuffers.set(key, newBuffer);
481
+ this._buffers.set(key, newBuffer);
306
482
  const unsubscribe = newBuffer.data.subscribe(() => {
307
- this._comparisonData.set(key, [...newBuffer.data.peek()]);
483
+ this._comparisonData.set(symbol, [...newBuffer.getRawData()]);
308
484
  this.deps.scheduleDraw();
309
485
  });
310
- this._comparisonBufferUnsubs.set(key, unsubscribe);
486
+ this._cmpLoadingUnsubs.set(key, unsubscribe);
311
487
  const unsubLoading = newBuffer.loading.subscribe(() => this.recomputeComparisonLoading());
312
- this._comparisonLoadingUnsubs.set(key, unsubLoading);
313
- buffer = newBuffer;
488
+ // Store loading unsubscribe with a special key
489
+ this._cmpLoadingUnsubs.set(`loading:${key}`, unsubLoading);
490
+ buf = newBuffer;
314
491
  }
315
492
  else {
316
- buffer.setFetcher(this._dataFetcher);
493
+ buf.setFetcher(this._dataFetcher);
317
494
  if (this._dataFetcher) {
318
- buffer.setRequestFetch(this._createBatchHandler(this._dataFetcher));
495
+ buf.setRequestFetch(this._createBatchHandler(this._dataFetcher));
319
496
  }
320
497
  }
321
- const mainEarliest = this._dataBuffer.loadedWindow?.earliestTs;
322
- buffer.setSymbol(spec, mainEarliest);
498
+ const mainEarliest = primaryBuf?.loadedWindow?.earliestTs;
499
+ buf.setSymbol(spec, mainEarliest);
323
500
  }
324
501
  }
325
502
  clearComparisonBuffers() {
326
- for (const unsubscribe of this._comparisonBufferUnsubs.values())
327
- unsubscribe();
328
- this._comparisonBufferUnsubs.clear();
329
- for (const unsub of this._comparisonLoadingUnsubs.values())
330
- unsub();
331
- this._comparisonLoadingUnsubs.clear();
332
- for (const buffer of this._comparisonBuffers.values())
333
- buffer.dispose();
334
- this._comparisonBuffers.clear();
503
+ for (const [key, buf] of this._buffers) {
504
+ if (key.startsWith(BUF_COMPARISON)) {
505
+ this.disposeBuffer(key);
506
+ }
507
+ }
335
508
  this._comparisonData.clear();
336
509
  this._comparisonColors.clear();
337
510
  this._comparisonColorsSignal.set(new Map());
@@ -339,12 +512,16 @@ export class ChartDataManager {
339
512
  this._comparisonSpecs = [];
340
513
  }
341
514
  addComparisonSymbol(spec) {
342
- const key = spec.symbol;
343
- if (this._comparisonBuffers.has(key))
344
- return;
515
+ const symbol = spec.symbol;
516
+ const key = bufKey(BUF_COMPARISON, symbol, spec.period);
517
+ // Check if already exists
518
+ for (const k of this._buffers.keys()) {
519
+ if (k.startsWith(BUF_COMPARISON) && k.split(':')[1] === symbol)
520
+ return;
521
+ }
345
522
  this._comparisonSpecs.push(spec);
346
523
  const color = COMPARISON_PALETTE[this._comparisonColors.size % COMPARISON_PALETTE.length] ?? DEFAULT_COMPARISON_COLOR;
347
- this._comparisonColors.set(key, color);
524
+ this._comparisonColors.set(symbol, color);
348
525
  this._comparisonColorsSignal.set(new Map(this._comparisonColors));
349
526
  if (!this._dataFetcher)
350
527
  return;
@@ -353,140 +530,243 @@ export class ChartDataManager {
353
530
  if (this._dataFetcher) {
354
531
  newBuffer.setRequestFetch(this._createBatchHandler(this._dataFetcher));
355
532
  }
356
- this._comparisonBuffers.set(key, newBuffer);
533
+ this._buffers.set(key, newBuffer);
357
534
  const unsubscribe = newBuffer.data.subscribe(() => {
358
- this._comparisonData.set(key, [...newBuffer.data.peek()]);
535
+ this._comparisonData.set(symbol, [...newBuffer.getRawData()]);
359
536
  this.deps.scheduleDraw();
360
537
  });
361
- this._comparisonBufferUnsubs.set(key, unsubscribe);
538
+ this._cmpLoadingUnsubs.set(key, unsubscribe);
362
539
  const unsubLoading = newBuffer.loading.subscribe(() => this.recomputeComparisonLoading());
363
- this._comparisonLoadingUnsubs.set(key, unsubLoading);
364
- const mainEarliest = this._dataBuffer.loadedWindow?.earliestTs;
540
+ this._cmpLoadingUnsubs.set(`loading:${key}`, unsubLoading);
541
+ const primaryBuf = this.getActiveDataBuffer();
542
+ const mainEarliest = primaryBuf?.loadedWindow?.earliestTs;
365
543
  newBuffer.setSymbol(spec, mainEarliest);
366
544
  this._symbolsSignal.set([this._symbolsSignal.peek()[0], ...this._comparisonSpecs]);
367
545
  }
546
+ setComparisonData(symbol, data) {
547
+ const period = this.currentPeriod;
548
+ const key = bufKey(BUF_COMPARISON, symbol, period);
549
+ const existing = this._buffers.get(key);
550
+ if (!existing) {
551
+ const buffer = new DataBuffer();
552
+ this._buffers.set(key, buffer);
553
+ const unsub = buffer.data.subscribe(() => {
554
+ this._comparisonData.set(symbol, [...buffer.getRawData()]);
555
+ this.deps.scheduleDraw();
556
+ });
557
+ this._cmpLoadingUnsubs.set(key, unsub);
558
+ const unsubLoading = buffer.loading.subscribe(() => this.recomputeComparisonLoading());
559
+ this._cmpLoadingUnsubs.set(`loading:${key}`, unsubLoading);
560
+ const color = COMPARISON_PALETTE[this._comparisonColors.size % COMPARISON_PALETTE.length] ??
561
+ DEFAULT_COMPARISON_COLOR;
562
+ this._comparisonColors.set(symbol, color);
563
+ this._comparisonColorsSignal.set(new Map(this._comparisonColors));
564
+ const spec = { symbol, period };
565
+ this._comparisonSpecs.push(spec);
566
+ const mainSpec = this._symbolsSignal.peek()[0];
567
+ this._symbolsSignal.set(mainSpec ? [mainSpec, ...this._comparisonSpecs] : [...this._comparisonSpecs]);
568
+ buffer.setInlineData(data);
569
+ return;
570
+ }
571
+ existing.setInlineData(data);
572
+ }
368
573
  removeComparisonSymbol(symbol) {
369
- const key = symbol;
370
- if (!this._comparisonBuffers.has(key))
574
+ let found = false;
575
+ for (const [key, buf] of this._buffers) {
576
+ if (key.startsWith(BUF_COMPARISON) && key.split(':')[1] === symbol) {
577
+ this.disposeBuffer(key);
578
+ found = true;
579
+ break;
580
+ }
581
+ }
582
+ if (!found)
371
583
  return;
372
- this._comparisonBufferUnsubs.get(key)?.();
373
- this._comparisonBufferUnsubs.delete(key);
374
- this._comparisonLoadingUnsubs.get(key)?.();
375
- this._comparisonLoadingUnsubs.delete(key);
376
- this._comparisonBuffers.get(key)?.dispose();
377
- this._comparisonBuffers.delete(key);
378
- this._comparisonData.delete(key);
379
- this._comparisonColors.delete(key);
584
+ this._comparisonData.delete(symbol);
585
+ this._comparisonColors.delete(symbol);
380
586
  this._comparisonColorsSignal.set(new Map(this._comparisonColors));
381
587
  this._comparisonSpecs = this._comparisonSpecs.filter((s) => s.symbol !== symbol);
382
588
  this._symbolsSignal.set([this._symbolsSignal.peek()[0], ...this._comparisonSpecs]);
383
589
  this.recomputeComparisonLoading();
590
+ this.deps.scheduleDraw();
591
+ }
592
+ // ── Symbol / Period ──
593
+ setCurrentSymbol(symbol) {
594
+ const current = this._currentSpec ?? { symbol };
595
+ this._currentSpec = { ...current, symbol };
596
+ const specs = this._symbolsSignal.peek();
597
+ if (specs.length > 0) {
598
+ const updated = [{ ...specs[0], symbol }, ...specs.slice(1)];
599
+ this._symbolsSignal.set(updated);
600
+ }
601
+ }
602
+ setTimeShareQueryDate(date) {
603
+ const buf = this.getActiveTimeShareBuffer();
604
+ if (buf) {
605
+ buf.setQueryDate(date);
606
+ }
607
+ else {
608
+ // Store for later when buffer is created
609
+ const tsBuf = new TimeShareBuffer();
610
+ tsBuf.setFetcher(this._timeShareFetcher);
611
+ tsBuf.setQueryDate(date);
612
+ const spec = this._currentSpec;
613
+ if (spec) {
614
+ const key = bufKey(BUF_TIMESHARE, spec.symbol);
615
+ this._buffers.set(key, tsBuf);
616
+ this.activateBuffer(key);
617
+ tsBuf.load(spec);
618
+ }
619
+ }
620
+ }
621
+ setCurrentPeriod(period) {
622
+ const current = this._currentSpec;
623
+ if (!current) {
624
+ this._currentSpec = { symbol: '', period };
625
+ return;
626
+ }
627
+ const next = { ...current, period };
628
+ this.setSymbols([next, ...this._comparisonSpecs]);
629
+ }
630
+ applyCustomData(source) {
631
+ if (source.symbol)
632
+ this.setCurrentSymbol(source.symbol);
633
+ if (source.period)
634
+ this.setCurrentPeriod(source.period);
635
+ const specs = this._symbolsSignal.peek();
636
+ if (specs.length === 0 && source.symbol) {
637
+ const mainSpec = {
638
+ symbol: source.symbol,
639
+ period: source.period ?? 'daily',
640
+ };
641
+ this._symbolsSignal.set([mainSpec]);
642
+ }
643
+ const plainData = source.data.map((d) => ({ ...d }));
644
+ this.setData(plainData);
645
+ if (source.comparisons) {
646
+ for (const key of this._comparisonData.keys()) {
647
+ if (!source.comparisons[key])
648
+ this.removeComparisonSymbol(key);
649
+ }
650
+ for (const [symbol, data] of Object.entries(source.comparisons)) {
651
+ this.setComparisonData(symbol, data.map((d) => ({ ...d })));
652
+ }
653
+ }
384
654
  }
655
+ // ── Main symbol switching ──
385
656
  setSymbols(specs) {
386
657
  this._symbolsSignal.set(specs);
387
658
  if (specs.length === 0) {
659
+ this._currentSpec = null;
660
+ this.disposeAllBuffers();
661
+ this._dataSignal.set([]);
662
+ this.lastVisibleRange = { start: 0, end: 0 };
663
+ this.lastRawVisibleRange = { start: 0, end: 0 };
664
+ return;
665
+ }
666
+ const primary = specs[0];
667
+ this._currentSpec = primary;
668
+ if (primary.period === 'timeshare') {
669
+ // Switch to timeshare mode
388
670
  this.clearComparisonBuffers();
671
+ // Dispose primary KLine buffer
672
+ for (const [key, buf] of this._buffers) {
673
+ if (key.startsWith(BUF_PRIMARY)) {
674
+ this.disposeBuffer(key);
675
+ }
676
+ }
677
+ this._dataSignal.set([]);
678
+ this.lastVisibleRange = { start: 0, end: 0 };
679
+ this.lastRawVisibleRange = { start: 0, end: 0 };
680
+ // Get or create timeshare buffer
681
+ const tsKey = bufKey(BUF_TIMESHARE, primary.symbol);
682
+ let tsBuf = this._buffers.get(tsKey);
683
+ if (!tsBuf) {
684
+ tsBuf = new TimeShareBuffer();
685
+ tsBuf.setFetcher(this._timeShareFetcher);
686
+ this._buffers.set(tsKey, tsBuf);
687
+ }
688
+ this.activateBuffer(tsKey);
689
+ tsBuf.load(primary);
389
690
  return;
390
691
  }
692
+ // KLine mode
693
+ // Dispose timeshare buffer
694
+ for (const [key, buf] of this._buffers) {
695
+ if (key.startsWith(BUF_TIMESHARE)) {
696
+ this.disposeBuffer(key);
697
+ }
698
+ }
699
+ this.loadKLineSymbols(specs);
700
+ }
701
+ // ── KLine loading ──
702
+ loadKLineSymbols(specs) {
391
703
  const spec = specs[0];
392
704
  this.syncComparisonBuffers(specs.slice(1));
393
705
  if (!this._dataFetcher)
394
706
  return;
395
- this._dataBuffer.setFetcher(this._dataFetcher);
396
- this._dataBuffer.onPrepend = (count) => {
707
+ const buf = this.getPrimaryDataBuffer(spec.symbol, spec.period);
708
+ this.activateBuffer(bufKey(BUF_PRIMARY, spec.symbol, spec.period));
709
+ buf.onPrepend = (count) => {
397
710
  this.pendingPrependedCount = count;
398
711
  const dpr = this.deps.getEffectiveDpr();
399
712
  const opt = this.deps.getOption();
400
713
  const { unitPx } = getPhysicalKLineConfig(opt.kWidth, opt.kGap, dpr);
401
714
  const compensation = (count * unitPx) / dpr;
402
- const container = this.deps.getDom().container;
403
- if (container) {
404
- container.scrollLeft += compensation;
405
- this.deps.setCachedScrollLeft(container.scrollLeft);
406
- }
715
+ const nextScrollLeft = this.deps.getCachedScrollLeft() + compensation;
716
+ this.deps.setScrollLeft(nextScrollLeft);
407
717
  };
408
- if (!this._dataBufferUnsub) {
409
- this._dataBufferUnsub = this._dataBuffer.data.subscribe(() => {
410
- const prevLength = this._internalData.length;
411
- const bufferData = this._dataBuffer.data.peek();
412
- this._internalData = [...bufferData];
413
- this._dataSignal.set([...this._internalData]);
414
- const prependedCount = this.pendingPrependedCount;
415
- this.pendingPrependedCount = 0;
416
- if (this.deps.getCachedScrollLeft() < this.getLeftLoadBufferWidth()) {
417
- const desiredScrollLeft = this.getLeftLoadBufferWidth();
418
- this.deps.setCachedScrollLeft(desiredScrollLeft);
419
- this.deps.setPendingScrollLeft(desiredScrollLeft);
420
- }
421
- if (prevLength === 0 && this._internalData.length > 0) {
422
- const dpr = this.deps.getEffectiveDpr();
423
- const opt = this.deps.getOption();
424
- const { unitPx, startXPx } = getPhysicalKLineConfig(opt.kWidth, opt.kGap, dpr);
425
- const lastKLineEndPx = (startXPx + this._internalData.length * unitPx) / dpr;
426
- const container = this.deps.getDom().container;
427
- if (container) {
428
- const target = this.getLeftLoadBufferWidth() + Math.max(0, lastKLineEndPx - container.clientWidth);
429
- const contentWidth = this.getContentWidth();
430
- const maxScroll = Math.max(0, contentWidth - container.clientWidth);
431
- const scrollLeft = Math.round(Math.min(target, maxScroll) * dpr) / dpr;
432
- this.deps.setCachedScrollLeft(scrollLeft);
433
- this.deps.setPendingScrollLeft(scrollLeft);
434
- }
435
- }
436
- this.deps.resetInteraction();
437
- if (this.lastVisibleRange.start === 0 && this.lastVisibleRange.end === 0 && this._internalData.length > 0) {
438
- const plotWidth = this.deps.getObservedSize().width > 0
439
- ? this.deps.getObservedSize().width
440
- : Math.max(1, Math.round(this.deps.getDom().container?.clientWidth ?? 800));
441
- const dpr = this.deps.getEffectiveDpr();
442
- const opt = this.deps.getOption();
443
- const { start, end } = getVisibleRange(this.deps.getLogicalScrollLeft(), plotWidth, opt.kWidth, opt.kGap, this._internalData.length, dpr);
444
- this.lastRawVisibleRange = { start, end };
445
- this.lastVisibleRange = { start: Math.max(0, start), end };
446
- }
447
- const scheduler = this.deps.getIndicatorScheduler();
448
- const indicatorsReady = scheduler.update(this._internalData, this.lastVisibleRange);
449
- if (indicatorsReady) {
450
- this.pendingIndicatorDataUpdate = false;
451
- this.deps.scheduleDraw();
452
- }
453
- else {
454
- this.pendingIndicatorDataUpdate = true;
455
- }
456
- this.showIncrementalLoadHint(prependedCount);
457
- });
458
- }
459
- this._dataBuffer.setSymbol(spec);
718
+ buf.setSymbol(spec);
460
719
  }
720
+ // ── Content width ──
461
721
  getContentWidth() {
462
- const dataLength = this._internalData.length;
722
+ if (this.currentPeriod === 'timeshare') {
723
+ const tsData = this.getTimeShareData();
724
+ if (tsData.length === 0)
725
+ return 0;
726
+ const viewWidth = this.deps.getViewport()?.plotWidth ?? 0;
727
+ return this.getLeftLoadBufferWidth() + Math.max(viewWidth, 1);
728
+ }
729
+ const buf = this.getActiveDataBuffer();
730
+ const dataLength = buf ? buf.getRawData().length : 0;
463
731
  if (dataLength === 0)
464
732
  return 0;
465
733
  const opt = this.deps.getOption();
466
734
  const viewWidth = this.deps.getViewport()?.plotWidth ?? 0;
467
735
  const dpr = this.deps.getEffectiveDpr();
468
736
  const { startXPx, unitPx } = getPhysicalKLineConfig(opt.kWidth, opt.kGap, dpr);
469
- const dataPlotWidth = (startXPx + (ChartDataManager.LEADING_SLOTS + dataLength + ChartDataManager.TRAILING_DRAWING_SLOTS) * unitPx) / dpr;
737
+ const dataPlotWidth = (startXPx + dataLength * unitPx) / dpr;
470
738
  return this.getLeftLoadBufferWidth() + Math.max(dataPlotWidth, viewWidth);
471
739
  }
472
740
  scrollToRight() {
473
- const container = this.deps.getDom().container;
474
- if (!container || this._internalData.length === 0)
741
+ const buf = this.getActiveDataBuffer();
742
+ const dataLength = buf ? buf.getRawData().length : 0;
743
+ if (dataLength === 0)
475
744
  return;
476
745
  const dpr = this.deps.getEffectiveDpr();
477
746
  const opt = this.deps.getOption();
478
747
  const { unitPx, startXPx } = getPhysicalKLineConfig(opt.kWidth, opt.kGap, dpr);
479
- const lastKLineEndPx = (startXPx + this._internalData.length * unitPx) / dpr;
480
- const target = this.getLeftLoadBufferWidth() + Math.max(0, lastKLineEndPx - container.clientWidth);
481
- const maxScroll = Math.max(0, container.scrollWidth - container.clientWidth);
482
- container.scrollLeft = Math.round(Math.min(target, maxScroll) * dpr) / dpr;
483
- this.deps.setCachedScrollLeft(container.scrollLeft);
484
- }
748
+ const lastKLineEndPx = (startXPx + dataLength * unitPx) / dpr;
749
+ const viewport = this.deps.getViewport();
750
+ const clientWidth = viewport?.viewWidth
751
+ ?? (this.deps.getObservedSize().width > 0 ? this.deps.getObservedSize().width : undefined)
752
+ ?? Math.round(this.deps.getDom().container?.clientWidth ?? 0);
753
+ if (clientWidth <= 0)
754
+ return;
755
+ const target = this.getLeftLoadBufferWidth() + Math.max(0, lastKLineEndPx - clientWidth);
756
+ const contentWidth = this.getContentWidth();
757
+ const maxScroll = Math.max(0, contentWidth - clientWidth);
758
+ const scrollLeft = Math.round(Math.min(target, maxScroll) * dpr) / dpr;
759
+ this.deps.setScrollLeft(scrollLeft);
760
+ this.deps.scheduleDraw();
761
+ }
762
+ // ── Comparison price range ──
485
763
  getComparisonEquivalentPriceRange(range) {
486
764
  if (this._comparisonSpecs.length === 0 || this._comparisonData.size === 0)
487
765
  return null;
766
+ const buf = this.getActiveDataBuffer();
767
+ const internalData = buf ? buf.getRawData() : [];
488
768
  const baseIndex = Math.max(0, range.start);
489
- const baseItem = this._internalData[baseIndex];
769
+ const baseItem = internalData[baseIndex];
490
770
  if (!baseItem || !Number.isFinite(baseItem.close) || baseItem.close <= 0)
491
771
  return null;
492
772
  const mainBase = baseItem.close;
@@ -509,8 +789,8 @@ export class ChartDataManager {
509
789
  else
510
790
  byDate.set(String(item.timestamp), item);
511
791
  }
512
- for (let i = Math.max(0, range.start); i < range.end && i < this._internalData.length; i++) {
513
- const mainItem = this._internalData[i];
792
+ for (let i = Math.max(0, range.start); i < range.end && i < internalData.length; i++) {
793
+ const mainItem = internalData[i];
514
794
  if (!mainItem)
515
795
  continue;
516
796
  const key = mainItem.date ?? String(mainItem.timestamp);
@@ -529,17 +809,26 @@ export class ChartDataManager {
529
809
  return null;
530
810
  return { min, max };
531
811
  }
812
+ // ── Index helpers ──
532
813
  getLogicalSlotCount() {
533
- return this._internalData.length + this.getTrailingSlotCount();
814
+ const buf = this.getActiveDataBuffer();
815
+ const dataLength = buf ? buf.getRawData().length : 0;
816
+ return dataLength + this.getTrailingSlotCount();
534
817
  }
535
818
  getTimestampAtLogicalIndex(index) {
536
- if (!Number.isInteger(index) || index < 0 || index >= this._internalData.length)
819
+ const buf = this.getActiveDataBuffer();
820
+ const data = buf ? buf.getRawData() : [];
821
+ if (!Number.isInteger(index) || index < 0 || index >= data.length)
537
822
  return null;
538
- return this._internalData[index]?.timestamp ?? null;
823
+ return data[index]?.timestamp ?? null;
539
824
  }
540
825
  getLogicalIndexAtX(mouseX) {
541
826
  const vp = this.deps.getViewport();
542
- if (!vp || this._internalData.length === 0)
827
+ if (!vp)
828
+ return null;
829
+ const buf = this.getActiveDataBuffer();
830
+ const data = buf ? buf.getRawData() : [];
831
+ if (data.length === 0)
543
832
  return null;
544
833
  const dpr = this.deps.getEffectiveDpr();
545
834
  const opt = this.deps.getOption();
@@ -552,21 +841,24 @@ export class ChartDataManager {
552
841
  }
553
842
  getDataIndexAtX(mouseX) {
554
843
  const index = this.getLogicalIndexAtX(mouseX);
555
- if (index === null || index >= this._internalData.length)
844
+ const buf = this.getActiveDataBuffer();
845
+ const dataLength = buf ? buf.getRawData().length : 0;
846
+ if (index === null || index >= dataLength)
556
847
  return null;
557
848
  return index;
558
849
  }
559
- destroy() {
560
- if (this._dataBufferUnsub) {
561
- this._dataBufferUnsub();
562
- this._dataBufferUnsub = null;
850
+ disposeAllBuffers() {
851
+ for (const key of this._buffers.keys()) {
852
+ this.disposeBuffer(key);
563
853
  }
854
+ }
855
+ destroy() {
856
+ this._activeBufferUnsub?.();
857
+ this.disposeAllBuffers();
564
858
  this.clearIncrementalLoadHintTimer();
565
859
  this.incrementalLoadHintEl?.remove();
566
860
  this.incrementalLoadHintEl = null;
567
861
  this.pendingPrependedCount = 0;
568
- this._dataBuffer.dispose();
569
- this.clearComparisonBuffers();
570
862
  }
571
863
  }
572
864
  function findComparisonBaselineByDate(data, date) {