@363045841yyt/klinechart-core 0.7.3 → 0.7.5

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 (247) hide show
  1. package/README.md +201 -201
  2. package/README.zh-CN.md +201 -201
  3. package/dist/controllers/index.d.ts +1 -0
  4. package/dist/controllers/index.d.ts.map +1 -1
  5. package/dist/controllers/index.js +1 -0
  6. package/dist/controllers/index.js.map +1 -1
  7. package/dist/engine/chart.d.ts +11 -19
  8. package/dist/engine/chart.d.ts.map +1 -1
  9. package/dist/engine/chart.js +92 -109
  10. package/dist/engine/chart.js.map +1 -1
  11. package/dist/engine/renderers/Indicator/indicatorData.d.ts +1 -0
  12. package/dist/engine/renderers/Indicator/indicatorData.d.ts.map +1 -1
  13. package/dist/engine/renderers/Indicator/indicatorData.js +1 -1
  14. package/dist/engine/renderers/Indicator/indicatorData.js.map +1 -1
  15. package/dist/engine/renderers/webgl/candleSurface.js +47 -47
  16. package/dist/engine/subPaneManager.d.ts +4 -0
  17. package/dist/engine/subPaneManager.d.ts.map +1 -1
  18. package/dist/engine/subPaneManager.js +13 -0
  19. package/dist/engine/subPaneManager.js.map +1 -1
  20. package/dist/version.d.ts +1 -1
  21. package/dist/version.d.ts.map +1 -1
  22. package/dist/version.js +1 -2
  23. package/dist/version.js.map +1 -1
  24. package/package.json +129 -122
  25. package/src/__tests__/signal.test.ts +124 -124
  26. package/src/config/chartSettings.ts +66 -66
  27. package/src/controllers/__tests__/drawing.test.ts +214 -214
  28. package/src/controllers/__tests__/indicatorSelector.test.ts +481 -481
  29. package/src/controllers/__tests__/toolbar.test.ts +225 -225
  30. package/src/controllers/createChartController.ts +665 -665
  31. package/src/controllers/createDrawingController.ts +96 -96
  32. package/src/controllers/createIndicatorSelectorController.ts +307 -307
  33. package/src/controllers/createToolbarController.ts +146 -146
  34. package/src/controllers/index.ts +20 -19
  35. package/src/controllers/types.ts +284 -284
  36. package/src/engine/__tests__/chart.dpr.test.ts +401 -401
  37. package/src/engine/__tests__/paneRenderer.resize.test.ts +92 -92
  38. package/src/engine/chart-store.ts +121 -121
  39. package/src/engine/chart.d.ts +617 -617
  40. package/src/engine/chart.ts +2803 -2815
  41. package/src/engine/controller/__tests__/interaction.dpr.test.ts +259 -259
  42. package/src/engine/controller/interaction.ts +722 -722
  43. package/src/engine/controller/markerInteraction.ts +130 -130
  44. package/src/engine/controller/pinchTracker.ts +82 -82
  45. package/src/engine/controller/tooltipPosition.ts +48 -48
  46. package/src/engine/draw/__tests__/pixelAlign.spec.ts +176 -176
  47. package/src/engine/draw/pixelAlign.ts +259 -259
  48. package/src/engine/drawing/index.ts +655 -655
  49. package/src/engine/drawing/interaction.ts +842 -842
  50. package/src/engine/drawing/plugin.ts +343 -343
  51. package/src/engine/indicators/__tests__/__fixtures__/golden/atr.json +38 -38
  52. package/src/engine/indicators/__tests__/__fixtures__/golden/dema.json +14 -14
  53. package/src/engine/indicators/__tests__/__fixtures__/golden/hma.json +14 -14
  54. package/src/engine/indicators/__tests__/__fixtures__/golden/index.ts +55 -55
  55. package/src/engine/indicators/__tests__/__fixtures__/golden/kama.json +14 -14
  56. package/src/engine/indicators/__tests__/__fixtures__/golden/tema.json +14 -14
  57. package/src/engine/indicators/__tests__/__fixtures__/golden/wma.json +40 -40
  58. package/src/engine/indicators/__tests__/__fixtures__/synthetic.ts +65 -65
  59. package/src/engine/indicators/__tests__/_propertyAssertions.ts +76 -76
  60. package/src/engine/indicators/__tests__/atr.test.ts +153 -153
  61. package/src/engine/indicators/__tests__/calculators.test.ts +614 -614
  62. package/src/engine/indicators/__tests__/cmf-mfi.test.ts +100 -100
  63. package/src/engine/indicators/__tests__/dema.test.ts +73 -73
  64. package/src/engine/indicators/__tests__/donchian.test.ts +70 -70
  65. package/src/engine/indicators/__tests__/hma.test.ts +73 -73
  66. package/src/engine/indicators/__tests__/ichimoku.test.ts +105 -105
  67. package/src/engine/indicators/__tests__/kama.test.ts +80 -80
  68. package/src/engine/indicators/__tests__/keltner.test.ts +65 -65
  69. package/src/engine/indicators/__tests__/pivot-fib.test.ts +110 -110
  70. package/src/engine/indicators/__tests__/roc.test.ts +68 -68
  71. package/src/engine/indicators/__tests__/sar.test.ts +86 -86
  72. package/src/engine/indicators/__tests__/scheduler.test.ts +831 -831
  73. package/src/engine/indicators/__tests__/soa.test.ts +533 -533
  74. package/src/engine/indicators/__tests__/structure.test.ts +110 -110
  75. package/src/engine/indicators/__tests__/supertrend.test.ts +65 -65
  76. package/src/engine/indicators/__tests__/tema.test.ts +68 -68
  77. package/src/engine/indicators/__tests__/trix.test.ts +70 -70
  78. package/src/engine/indicators/__tests__/volatility.test.ts +117 -117
  79. package/src/engine/indicators/__tests__/volume.test.ts +115 -115
  80. package/src/engine/indicators/__tests__/volumeProfile.test.ts +74 -74
  81. package/src/engine/indicators/__tests__/vwap.test.ts +69 -69
  82. package/src/engine/indicators/__tests__/wma.test.ts +112 -112
  83. package/src/engine/indicators/__tests__/zones.test.ts +95 -95
  84. package/src/engine/indicators/atrState.ts +27 -27
  85. package/src/engine/indicators/bollState.ts +51 -51
  86. package/src/engine/indicators/calculators.ts +2593 -2593
  87. package/src/engine/indicators/cciState.ts +25 -25
  88. package/src/engine/indicators/chaikinVolState.ts +32 -32
  89. package/src/engine/indicators/cmfState.ts +27 -27
  90. package/src/engine/indicators/demaState.ts +27 -27
  91. package/src/engine/indicators/donchianState.ts +43 -43
  92. package/src/engine/indicators/eneState.ts +43 -43
  93. package/src/engine/indicators/expmaState.ts +43 -43
  94. package/src/engine/indicators/fastkState.ts +25 -25
  95. package/src/engine/indicators/fibState.ts +41 -41
  96. package/src/engine/indicators/hmaState.ts +27 -27
  97. package/src/engine/indicators/hvState.ts +28 -28
  98. package/src/engine/indicators/ichimokuState.ts +70 -70
  99. package/src/engine/indicators/indicator.worker.ts +169 -169
  100. package/src/engine/indicators/indicatorDefinitionRegistry.ts +62 -62
  101. package/src/engine/indicators/indicatorMetadata.ts +110 -110
  102. package/src/engine/indicators/indicatorRegistry.ts +106 -106
  103. package/src/engine/indicators/indicatorRuntime.ts +1548 -1548
  104. package/src/engine/indicators/kamaState.ts +34 -34
  105. package/src/engine/indicators/keltnerState.ts +49 -49
  106. package/src/engine/indicators/kstState.ts +42 -42
  107. package/src/engine/indicators/maState.ts +36 -36
  108. package/src/engine/indicators/macdState.ts +76 -76
  109. package/src/engine/indicators/mfiState.ts +27 -27
  110. package/src/engine/indicators/momState.ts +25 -25
  111. package/src/engine/indicators/obvState.ts +25 -25
  112. package/src/engine/indicators/parkinsonState.ts +28 -28
  113. package/src/engine/indicators/pivotState.ts +51 -51
  114. package/src/engine/indicators/pvtState.ts +25 -25
  115. package/src/engine/indicators/rocState.ts +27 -27
  116. package/src/engine/indicators/rsiState.ts +65 -65
  117. package/src/engine/indicators/sarState.ts +41 -41
  118. package/src/engine/indicators/scheduler.ts +1205 -1205
  119. package/src/engine/indicators/soa.ts +352 -352
  120. package/src/engine/indicators/stateComposer.ts +1262 -1262
  121. package/src/engine/indicators/stochState.ts +26 -26
  122. package/src/engine/indicators/structureState.ts +69 -69
  123. package/src/engine/indicators/supertrendState.ts +37 -37
  124. package/src/engine/indicators/temaState.ts +27 -27
  125. package/src/engine/indicators/trixState.ts +35 -35
  126. package/src/engine/indicators/vmaState.ts +27 -27
  127. package/src/engine/indicators/volumeProfileState.ts +63 -63
  128. package/src/engine/indicators/vwapState.ts +29 -29
  129. package/src/engine/indicators/wmaState.ts +27 -27
  130. package/src/engine/indicators/wmsrState.ts +25 -25
  131. package/src/engine/indicators/workerProtocol.ts +613 -613
  132. package/src/engine/indicators/zonesState.ts +47 -47
  133. package/src/engine/layout/pane.ts +161 -161
  134. package/src/engine/marker/registry.ts +265 -265
  135. package/src/engine/paneRenderer.ts +169 -169
  136. package/src/engine/renderers/Indicator/atr.ts +237 -237
  137. package/src/engine/renderers/Indicator/boll.ts +317 -317
  138. package/src/engine/renderers/Indicator/cci.ts +275 -275
  139. package/src/engine/renderers/Indicator/chaikinVol.ts +138 -138
  140. package/src/engine/renderers/Indicator/cmf.ts +137 -137
  141. package/src/engine/renderers/Indicator/dema.ts +136 -136
  142. package/src/engine/renderers/Indicator/donchian.ts +137 -137
  143. package/src/engine/renderers/Indicator/ene.ts +271 -271
  144. package/src/engine/renderers/Indicator/expma.ts +197 -197
  145. package/src/engine/renderers/Indicator/fastk.ts +316 -316
  146. package/src/engine/renderers/Indicator/fib.ts +141 -141
  147. package/src/engine/renderers/Indicator/hma.ts +136 -136
  148. package/src/engine/renderers/Indicator/hv.ts +124 -124
  149. package/src/engine/renderers/Indicator/ichimoku.ts +181 -181
  150. package/src/engine/renderers/Indicator/index.ts +241 -241
  151. package/src/engine/renderers/Indicator/indicatorData.ts +650 -650
  152. package/src/engine/renderers/Indicator/kama.ts +136 -136
  153. package/src/engine/renderers/Indicator/keltner.ts +137 -137
  154. package/src/engine/renderers/Indicator/kst.ts +302 -302
  155. package/src/engine/renderers/Indicator/ma.ts +200 -200
  156. package/src/engine/renderers/Indicator/macd.ts +477 -477
  157. package/src/engine/renderers/Indicator/macdLegend.ts +141 -141
  158. package/src/engine/renderers/Indicator/mainIndicatorLegend.ts +272 -272
  159. package/src/engine/renderers/Indicator/mfi.ts +142 -142
  160. package/src/engine/renderers/Indicator/mom.ts +311 -311
  161. package/src/engine/renderers/Indicator/obv.ts +123 -123
  162. package/src/engine/renderers/Indicator/parkinson.ts +124 -124
  163. package/src/engine/renderers/Indicator/pivot.ts +131 -131
  164. package/src/engine/renderers/Indicator/pvt.ts +123 -123
  165. package/src/engine/renderers/Indicator/roc.ts +143 -143
  166. package/src/engine/renderers/Indicator/rsi.ts +390 -390
  167. package/src/engine/renderers/Indicator/sar.ts +113 -113
  168. package/src/engine/renderers/Indicator/scale/atr_scale.ts +19 -19
  169. package/src/engine/renderers/Indicator/scale/cci_scale.ts +19 -19
  170. package/src/engine/renderers/Indicator/scale/fastk_scale.ts +19 -19
  171. package/src/engine/renderers/Indicator/scale/indicator_scale.ts +204 -204
  172. package/src/engine/renderers/Indicator/scale/kst_scale.ts +19 -19
  173. package/src/engine/renderers/Indicator/scale/macd_scale.ts +22 -22
  174. package/src/engine/renderers/Indicator/scale/mom_scale.ts +19 -19
  175. package/src/engine/renderers/Indicator/scale/rsi_scale.ts +19 -19
  176. package/src/engine/renderers/Indicator/scale/stoch_scale.ts +19 -19
  177. package/src/engine/renderers/Indicator/scale/volume_scale.ts +26 -26
  178. package/src/engine/renderers/Indicator/scale/wmsr_scale.ts +19 -19
  179. package/src/engine/renderers/Indicator/stoch.ts +359 -359
  180. package/src/engine/renderers/Indicator/structure.ts +126 -126
  181. package/src/engine/renderers/Indicator/subPaneConfig.ts +265 -265
  182. package/src/engine/renderers/Indicator/supertrend.ts +115 -115
  183. package/src/engine/renderers/Indicator/tema.ts +136 -136
  184. package/src/engine/renderers/Indicator/trix.ts +158 -158
  185. package/src/engine/renderers/Indicator/vma.ts +124 -124
  186. package/src/engine/renderers/Indicator/volumeProfile.ts +125 -125
  187. package/src/engine/renderers/Indicator/vwap.ts +123 -123
  188. package/src/engine/renderers/Indicator/wma.ts +136 -136
  189. package/src/engine/renderers/Indicator/wmsr.ts +328 -328
  190. package/src/engine/renderers/Indicator/zones.ts +104 -104
  191. package/src/engine/renderers/__tests__/boll.renderer.test.ts +314 -314
  192. package/src/engine/renderers/__tests__/ene.renderer.test.ts +305 -305
  193. package/src/engine/renderers/__tests__/expma.renderer.test.ts +279 -279
  194. package/src/engine/renderers/__tests__/ma.renderer.test.ts +426 -426
  195. package/src/engine/renderers/__tests__/mainIndicatorLegend.renderer.test.ts +502 -502
  196. package/src/engine/renderers/__tests__/yAxis.renderer.test.ts +173 -173
  197. package/src/engine/renderers/candle.ts +459 -459
  198. package/src/engine/renderers/crosshair.ts +69 -69
  199. package/src/engine/renderers/customMarkers.ts +162 -162
  200. package/src/engine/renderers/extremaMarkers.ts +246 -246
  201. package/src/engine/renderers/gridLines.ts +90 -90
  202. package/src/engine/renderers/lastPrice.ts +97 -97
  203. package/src/engine/renderers/paneTitle.ts +136 -136
  204. package/src/engine/renderers/subVolume.ts +236 -236
  205. package/src/engine/renderers/timeAxis.ts +121 -121
  206. package/src/engine/renderers/webgl/candleSurface.ts +955 -955
  207. package/src/engine/renderers/webgl/sharedWebGLSurface.ts +146 -146
  208. package/src/engine/renderers/yAxis.ts +105 -105
  209. package/src/engine/scale/__tests__/logFormula.spec.ts +148 -148
  210. package/src/engine/scale/logFormula.ts +130 -130
  211. package/src/engine/scale/price.ts +39 -39
  212. package/src/engine/scale/priceScale.ts +264 -264
  213. package/src/engine/subPaneManager.ts +442 -427
  214. package/src/engine/theme/colors.ts +642 -642
  215. package/src/engine/theme/fonts.ts +20 -20
  216. package/src/engine/utils/klineConfig.ts +49 -49
  217. package/src/engine/utils/tickCount.ts +11 -11
  218. package/src/engine/utils/tickPosition.ts +214 -214
  219. package/src/engine/utils/zoom.ts +83 -83
  220. package/src/engine/viewport/viewport.ts +67 -67
  221. package/src/index.ts +3 -3
  222. package/src/plugin/ConfigManager.ts +93 -93
  223. package/src/plugin/EventBus.ts +77 -77
  224. package/src/plugin/HookSystem.ts +106 -106
  225. package/src/plugin/PluginHost.ts +243 -243
  226. package/src/plugin/PluginRegistry.ts +92 -92
  227. package/src/plugin/StateStore.ts +73 -73
  228. package/src/plugin/index.ts +19 -19
  229. package/src/plugin/rendererPluginManager.ts +368 -368
  230. package/src/plugin/stateKeys.ts +8 -8
  231. package/src/plugin/types.ts +526 -526
  232. package/src/reactivity/index.ts +2 -2
  233. package/src/reactivity/signal.ts +119 -119
  234. package/src/semantic/controller.ts +251 -251
  235. package/src/semantic/drawShape.ts +260 -260
  236. package/src/semantic/index.ts +28 -28
  237. package/src/semantic/schema.json +256 -256
  238. package/src/semantic/types.ts +251 -251
  239. package/src/semantic/validator.ts +349 -349
  240. package/src/types/kLine.ts +13 -13
  241. package/src/types/price.ts +56 -56
  242. package/src/types/volumePrice.ts +33 -33
  243. package/src/utils/dateFormat.ts +208 -208
  244. package/src/utils/kLineDraw/axis.ts +562 -562
  245. package/src/utils/priceToY.ts +34 -34
  246. package/src/utils/volumePrice.ts +202 -202
  247. package/src/version.ts +1 -1
@@ -1,526 +1,526 @@
1
- /**
2
- * 插件系统核心类型定义
3
- */
4
-
5
- import type { KLineData } from '../types/price'
6
- import type { CandleWebGLSurface, LineWebGLSurface } from '../engine/renderers/webgl/candleSurface'
7
-
8
- /** 插件生命周期状态 */
9
- export enum PluginState {
10
- Registered = 'registered',
11
- Installed = 'installed',
12
- Error = 'error',
13
- }
14
-
15
- /** 插件配置 */
16
- export interface PluginConfig {
17
- enabled?: boolean
18
- priority?: number
19
- [key: string]: unknown
20
- }
21
-
22
- /** 插件元信息 */
23
- export interface PluginMeta {
24
- name: string
25
- version: string
26
- description?: string
27
- author?: string
28
- }
29
-
30
- /** 插件接口 */
31
- export interface Plugin extends PluginMeta {
32
- /** 安装插件 */
33
- install(host: PluginHost, config?: Record<string, unknown>): void | Promise<void>
34
- /** 卸载插件 */
35
- uninstall?(): void | Promise<void>
36
- }
37
-
38
- /** 插件描述符(注册时使用) */
39
- export interface PluginDescriptor {
40
- plugin: Plugin
41
- config?: PluginConfig
42
- state: PluginState
43
- error?: Error
44
- }
45
-
46
- /** Hook 函数类型 */
47
- export type HookFn<T = unknown, R = unknown> = (context: T) => R | Promise<R>
48
-
49
- /** Hook 调用选项 */
50
- export interface HookCallOptions {
51
- throwOnError?: boolean
52
- }
53
-
54
- /** Hook 描述符 */
55
- export interface HookDescriptor<T = unknown, R = unknown> {
56
- name: string
57
- fn: HookFn<T, R>
58
- priority: number
59
- }
60
-
61
- /** 事件处理器 */
62
- export type EventHandler<T = unknown> = (data: T) => void
63
-
64
- /** 插件日志器 */
65
- export interface PluginLogger {
66
- info(message?: unknown, ...optionalParams: unknown[]): void
67
- warn(message?: unknown, ...optionalParams: unknown[]): void
68
- error(message?: unknown, ...optionalParams: unknown[]): void
69
- }
70
-
71
- /** 插件宿主接口(暴露给插件使用的 API) */
72
- export interface PluginHost {
73
- /** 事件总线 */
74
- readonly events: {
75
- on<T = unknown>(event: string, handler: EventHandler<T>): void
76
- off<T = unknown>(event: string, handler: EventHandler<T>): void
77
- emit<T = unknown>(event: string, data: T): void
78
- once<T = unknown>(event: string, handler: EventHandler<T>): void
79
- }
80
-
81
- /** Hook 系统 */
82
- readonly hooks: {
83
- tap<T = unknown, R = unknown>(
84
- hookName: string,
85
- fn: HookFn<T, R>,
86
- priority?: number
87
- ): void
88
- untap(hookName: string, fn: HookFn): void
89
- call<T = unknown, R = unknown>(hookName: string, context: T, options?: HookCallOptions): Promise<R[]>
90
- callSync<T = unknown, R = unknown>(hookName: string, context: T, options?: HookCallOptions): R[]
91
- }
92
-
93
- /** 获取配置 */
94
- getConfig<K = unknown>(pluginName: string, key: string, defaultValue?: K): K
95
-
96
- /** 设置配置 */
97
- setConfig(pluginName: string, key: string, value: unknown): void
98
-
99
- /** 获取其他插件 */
100
- getPlugin<T extends Plugin = Plugin>(name: string): T | undefined
101
-
102
- /** 日志工具 */
103
- log(level: 'info' | 'warn' | 'error', message: string, ...args: unknown[]): void
104
-
105
- // ============ 状态存储 API ============
106
-
107
- /** 设置共享状态 */
108
- setSharedState<T extends BaseIndicatorState>(namespace: string, state: T, ownerId?: string): void
109
-
110
- /** 获取共享状态 */
111
- getSharedState<T extends BaseIndicatorState>(namespace: string): T | undefined
112
-
113
- /** 清除共享状态 */
114
- clearSharedState(namespace: string): void
115
-
116
- /** 注册状态拥有者 */
117
- registerStateOwner(ownerId: string, namespaces: string[]): void
118
-
119
- /** 按拥有者清除状态 */
120
- clearByOwner(ownerId: string): void
121
-
122
- /** 注册服务 */
123
- registerService(name: string, service: unknown): void
124
-
125
- /** 获取已注册的服务 */
126
- getService<T = unknown>(name: string): T | undefined
127
- }
128
-
129
- // ============ 渲染器插件类型 ============
130
-
131
- /** Pane 角色 */
132
- export type PaneRole = 'price' | 'indicator' | 'auxiliary'
133
-
134
- /** Pane 能力开关 */
135
- export interface PaneCapabilities {
136
- showPriceAxisTicks: boolean
137
- showCrosshairPriceLabel: boolean
138
- candleHitTest: boolean
139
- supportsPriceTranslate: boolean
140
- }
141
-
142
- /** Pane 信息接口 */
143
- export interface PaneInfo {
144
- id: string
145
- role: PaneRole
146
- capabilities: PaneCapabilities
147
- top: number
148
- height: number
149
- yAxis: {
150
- priceToY(price: number): number
151
- yToPrice(y: number): number
152
- getPaddingTop(): number
153
- getPaddingBottom(): number
154
- getPriceOffset(): number
155
- getDisplayRange(baseRange?: { maxPrice: number; minPrice: number }): { maxPrice: number; minPrice: number }
156
- getScaleType(): 'linear' | 'log'
157
- }
158
- priceRange: {
159
- maxPrice: number
160
- minPrice: number
161
- }
162
- }
163
-
164
- /**
165
- * 创建 PaneInfo 的只读包装
166
- *
167
- * 设计决策:
168
- * - 使用 Readonly<T> 类型标注而非 Object.freeze,避免热路径上的运行时开销
169
- * - yAxis 方法通过闭包包装,隔离原始函数引用
170
- * - 依赖团队代码规范约束插件行为,而非运行时强制
171
- */
172
- export function wrapPaneInfo(pane: {
173
- id: string
174
- role: PaneRole
175
- capabilities: PaneCapabilities
176
- top: number
177
- height: number
178
- yAxis: PaneInfo['yAxis']
179
- priceRange: PaneInfo['priceRange']
180
- }): Readonly<PaneInfo> {
181
- return {
182
- id: pane.id,
183
- role: pane.role,
184
- capabilities: { ...pane.capabilities },
185
- top: pane.top,
186
- height: pane.height,
187
- yAxis: {
188
- priceToY: (price) => pane.yAxis.priceToY(price),
189
- yToPrice: (y) => pane.yAxis.yToPrice(y),
190
- getPaddingTop: () => pane.yAxis.getPaddingTop(),
191
- getPaddingBottom: () => pane.yAxis.getPaddingBottom(),
192
- getPriceOffset: () => pane.yAxis.getPriceOffset(),
193
- getDisplayRange: (baseRange) => pane.yAxis.getDisplayRange(baseRange),
194
- getScaleType: () => pane.yAxis.getScaleType(),
195
- },
196
- priceRange: pane.priceRange,
197
- }
198
- }
199
-
200
- /** Y轴标签(价格标签) */
201
- export interface YAxisLabel {
202
- /** 关联的数据索引 */
203
- dataIndex: number
204
- /** 价格值 */
205
- price: number
206
- /** 标签在轴上的Y坐标(世界坐标,相对pane) */
207
- y: number
208
- /** 标签类型,用于区分不同渲染外观 */
209
- type?: 'lastPrice' | 'extrema' | 'anchor' | string
210
- /** 标签样式覆盖 */
211
- style?: {
212
- bgColor?: string
213
- borderColor?: string
214
- textColor?: string
215
- }
216
- }
217
-
218
- /** X轴标签(时间标签) */
219
- export interface XAxisLabel {
220
- /** 关联的数据索引 */
221
- dataIndex: number
222
- /** 时间戳(毫秒) */
223
- timestamp: number
224
- /** 标签在轴上的X坐标(世界坐标,未减去scrollLeft) */
225
- x: number
226
- /** 标签样式覆盖 */
227
- style?: {
228
- bgColor?: string
229
- textColor?: string
230
- }
231
- }
232
-
233
- /** Y轴范围带(半透明填充区域) */
234
- export interface YAxisRange {
235
- /** 范围上界Y坐标(相对pane,canvas方向:小值=上方) */
236
- topY: number
237
- /** 范围下界Y坐标(相对pane,canvas方向:大值=下方) */
238
- bottomY: number
239
- /** 填充颜色(hex 或 rgba) */
240
- color: string
241
- /** 填充不透明度 */
242
- opacity: number
243
- }
244
-
245
- /** X轴范围带(半透明填充区域) */
246
- export interface XAxisRange {
247
- /** 范围左界X坐标(世界坐标,未减去scrollLeft) */
248
- leftX: number
249
- /** 范围右界X坐标(世界坐标,未减去scrollLeft) */
250
- rightX: number
251
- /** 填充颜色(hex 或 rgba) */
252
- color: string
253
- /** 填充不透明度 */
254
- opacity: number
255
- }
256
-
257
- /** 渲染上下文 */
258
- /** MarkerManager 接口(用于 RenderContext) */
259
- export interface MarkerManagerLike {
260
- getCustomMarkers(): unknown[]
261
- setCustomMarkerPosition(id: string, x: number, y: number, size: number, shape: string): void
262
- }
263
-
264
- export interface RenderContext {
265
- ctx: CanvasRenderingContext2D
266
- pane: PaneInfo
267
- data: unknown[]
268
- range: { start: number; end: number }
269
- scrollLeft: number
270
- kWidth: number
271
- kGap: number
272
- dpr: number
273
- paneWidth: number
274
- kLinePositions: number[]
275
- /** 每根K线柱中心的X坐标(物理像素对齐后,逻辑像素) */
276
- kLineCenters: number[]
277
- /** 每根K线对应柱的X/宽度(物理像素对齐后,逻辑像素),供柱状图使用 */
278
- kBarRects: Array<{ x: number; width: number }>
279
- markerManager?: MarkerManagerLike
280
- /** 十字线指向的 K 线索引(无十字线时为 null) */
281
- crosshairIndex?: number | null
282
- // 可选的其他 Canvas 上下文
283
- yAxisCtx?: CanvasRenderingContext2D
284
- xAxisCtx?: CanvasRenderingContext2D
285
- borderCtx?: CanvasRenderingContext2D
286
- /** 覆盖层 Canvas 上下文(用于十字线、Tooltip 等动态内容) */
287
- overlayCtx?: CanvasRenderingContext2D
288
- /** price pane 可选的 WebGL candle surface */
289
- candleWebGLSurface?: CandleWebGLSurface
290
- /** line indicator 可选的 WebGL line surface */
291
- lineWebGLSurface?: LineWebGLSurface
292
- /** 当前缩放级别(1 ~ zoomLevels) */
293
- zoomLevel?: number
294
- /** 总缩放级别数 */
295
- zoomLevelCount?: number
296
- viewport?: {
297
- scrollLeft: number
298
- plotWidth: number
299
- plotHeight: number
300
- }
301
- /** 用户设置配置(渲染器只读) */
302
- settings?: import('../config/chartSettings').ChartSettings
303
- /** 需要在Y轴上绘制的标签列表(由各类标记渲染器填充) */
304
- yAxisLabels?: YAxisLabel[]
305
- /** 需要在X轴上绘制的标签列表(由各类标记渲染器填充) */
306
- xAxisLabels?: XAxisLabel[]
307
- /** 需要在Y轴上绘制的范围带列表(由绘图渲染器填充,先于标签绘制) */
308
- yAxisRanges?: YAxisRange[]
309
- /** 需要在X轴上绘制的范围带列表(由绘图渲染器填充,先于标签绘制) */
310
- xAxisRanges?: XAxisRange[]
311
- /** 当前主题 */
312
- theme: import('../engine/theme/colors').ChartTheme
313
- }
314
-
315
- export type DrawingAnchor = {
316
- id: string
317
- index: number
318
- time?: number | string
319
- price: number
320
- }
321
-
322
- export type DrawingKind =
323
- | 'trend-line'
324
- | 'ray'
325
- | 'extended-line'
326
- | 'horizontal-line'
327
- | 'horizontal-ray'
328
- | 'vertical-line'
329
- | 'cross-line'
330
- | 'info-line'
331
- | 'parallel-channel'
332
- | 'regression-channel'
333
- | 'flat-line'
334
- | 'disjoint-channel'
335
-
336
- export type DrawingStyle = {
337
- stroke?: string
338
- strokeWidth?: number
339
- strokeStyle?: 'solid' | 'dashed' | 'dotted'
340
- fill?: string
341
- fillOpacity?: number
342
- pointRadius?: number
343
- textColor?: string
344
- fontSize?: number
345
- }
346
-
347
- export type DrawingObject<TParams = Record<string, unknown>> = {
348
- id: string
349
- kind: DrawingKind
350
- paneId: string
351
- visible: boolean
352
- locked?: boolean
353
- zIndex?: number
354
- anchors: DrawingAnchor[]
355
- params: TParams
356
- style: DrawingStyle
357
- }
358
-
359
- export type ScreenPoint = { x: number; y: number }
360
-
361
- export type PointPrimitive = {
362
- kind: 'point'
363
- point: ScreenPoint
364
- role?: 'anchor' | 'handle' | 'marker' | 'center'
365
- style?: DrawingStyle
366
- }
367
-
368
- export type LinePrimitive = {
369
- kind: 'line'
370
- a: ScreenPoint
371
- b: ScreenPoint
372
- extend?: 'none' | 'left' | 'right' | 'both'
373
- showEndpoints?: boolean
374
- style?: DrawingStyle
375
- }
376
-
377
- export type AreaPrimitive = {
378
- kind: 'area'
379
- points: ScreenPoint[]
380
- closed: boolean
381
- style?: DrawingStyle
382
- }
383
-
384
- export type TextPrimitive = {
385
- kind: 'text'
386
- point: ScreenPoint
387
- text: string
388
- align?: 'left' | 'center' | 'right'
389
- baseline?: 'top' | 'middle' | 'bottom'
390
- style?: DrawingStyle
391
- }
392
-
393
- export type DrawingPrimitive = PointPrimitive | LinePrimitive | AreaPrimitive | TextPrimitive
394
-
395
- export type DrawingGeometry = {
396
- primitives: DrawingPrimitive[]
397
- bounds?: { left: number; top: number; right: number; bottom: number }
398
- meta?: Record<string, unknown>
399
- computedAnchors?: DrawingAnchor[]
400
- }
401
-
402
- export type DrawingComputeContext = {
403
- pane: PaneInfo
404
- visibleData: KLineData[]
405
- seriesData: KLineData[]
406
- range: { start: number; end: number }
407
- kLinePositions: number[]
408
- kLineCenters: number[]
409
- kBarRects: Array<{ x: number; width: number }>
410
- kWidth: number
411
- kGap: number
412
- dpr: number
413
- paneWidth: number
414
- viewport: {
415
- scrollLeft: number
416
- plotWidth: number
417
- plotHeight: number
418
- }
419
- toScreen(anchor: DrawingAnchor): ScreenPoint
420
- }
421
-
422
- export interface DrawingDefinition<TParams = Record<string, unknown>> {
423
- kind: DrawingKind
424
- minAnchors: number
425
- maxAnchors: number
426
- compute(drawing: DrawingObject<TParams>, context: DrawingComputeContext): DrawingGeometry
427
- }
428
-
429
- /** 全局 Pane ID(渲染到所有 pane) */
430
- export const GLOBAL_PANE_ID = Symbol('global-pane')
431
-
432
- /** 优先级推荐范围 */
433
- export const RENDERER_PRIORITY = {
434
- LAST_PRICE_LABEL: -25, // 最新价格 label 注册(必须在 SYSTEM_YAXIS 之前)
435
- SYSTEM_YAXIS: -20, // Y轴(系统级)
436
- SYSTEM_XAXIS: -20, // X轴(系统级)
437
- BACKGROUND: 0, // 背景层
438
- GRID: 10, // 网格线
439
- /**
440
- * 指标渲染器(MACD, RSI 等)
441
- * 所有指标渲染器必须使用此优先级或 ≤30 的值
442
- */
443
- INDICATOR: 30,
444
- MAIN: 50, // 主图(K线)
445
- /**
446
- * 指标刻度渲染器(依赖于前方指标写入的共享状态)
447
- * 必须晚于 INDICATOR 和 MAIN,确保每次绘制时先更新指标状态再绘制刻度。
448
- */
449
- INDICATOR_SCALE: 55,
450
- OVERLAY: 80, // 叠加层(标记点)
451
- FOREGROUND: 100, // 前景层(价格线)
452
- SYSTEM_BORDER: 120, // 边框(系统级)
453
- SYSTEM_CROSSHAIR: 150, // 十字线(系统级)
454
- } as const
455
-
456
- /** 渲染器插件接口(独立定义,不继承 Plugin) */
457
- export interface RendererPlugin {
458
- /** 唯一标识 */
459
- readonly name: string
460
-
461
- /** 版本号 */
462
- readonly version?: string
463
-
464
- /** 描述 */
465
- readonly description?: string
466
-
467
- /** 调试用显示名称 */
468
- readonly debugName?: string
469
-
470
- /** 渲染目标 pane('main' | 'sub' | GLOBAL_PANE_ID 表示所有) */
471
- paneId: string | symbol
472
-
473
- /** 渲染优先级(数字越大越后渲染) */
474
- priority: number
475
-
476
- /** 是否启用(仅作为初始值,运行时状态由 Manager 管理) */
477
- enabled?: boolean
478
-
479
- /**
480
- * 是否为系统渲染器
481
- * 系统渲染器不会通过 getRenderers() 返回,只能通过 renderPlugin() 单独渲染
482
- * 用于时间轴、全局边框等需要单独控制渲染时机的场景
483
- */
484
- isSystem?: boolean
485
-
486
- /**
487
- * 渲染器所属层,决定 UpdateLevel 过滤行为
488
- * - 'main': 低频/静态内容,随主画布一起渲染
489
- * - 'overlay': 高频/动态内容,可在 overlay-only 更新时独立重绘
490
- * 未指定时默认为 'main'(向后兼容)
491
- */
492
- layer?: 'main' | 'overlay'
493
-
494
- /** 渲染方法 */
495
- draw(context: RenderContext): void
496
-
497
- /** 数据更新时回调 */
498
- onDataUpdate?(data: unknown[], range: { start: number; end: number }): void
499
-
500
- /** 容器尺寸变化时回调 */
501
- onResize?(pane: PaneInfo): void
502
-
503
- /** 获取配置 */
504
- getConfig?(): Record<string, unknown>
505
-
506
- /** 设置配置 */
507
- setConfig?(config: Record<string, unknown>): void
508
-
509
- /** 卸载时清理资源 */
510
- onUninstall?(): void
511
- }
512
-
513
- /** 带插件系统能力的渲染器(可选) */
514
- export interface RendererPluginWithHost extends RendererPlugin {
515
- /** 安装时获取 PluginHost 访问权限 */
516
- onInstall?(host: PluginHost): void
517
- /** 声明该渲染器所拥有的状态命名空间,卸载时框架会自动清理 */
518
- getDeclaredNamespaces?(): string[]
519
- }
520
-
521
- // ============ 状态存储类型 ============
522
-
523
- /** 指标渲染器状态基类 */
524
- export interface BaseIndicatorState {
525
- timestamp: number
526
- }
1
+ /**
2
+ * 插件系统核心类型定义
3
+ */
4
+
5
+ import type { KLineData } from '../types/price'
6
+ import type { CandleWebGLSurface, LineWebGLSurface } from '../engine/renderers/webgl/candleSurface'
7
+
8
+ /** 插件生命周期状态 */
9
+ export enum PluginState {
10
+ Registered = 'registered',
11
+ Installed = 'installed',
12
+ Error = 'error',
13
+ }
14
+
15
+ /** 插件配置 */
16
+ export interface PluginConfig {
17
+ enabled?: boolean
18
+ priority?: number
19
+ [key: string]: unknown
20
+ }
21
+
22
+ /** 插件元信息 */
23
+ export interface PluginMeta {
24
+ name: string
25
+ version: string
26
+ description?: string
27
+ author?: string
28
+ }
29
+
30
+ /** 插件接口 */
31
+ export interface Plugin extends PluginMeta {
32
+ /** 安装插件 */
33
+ install(host: PluginHost, config?: Record<string, unknown>): void | Promise<void>
34
+ /** 卸载插件 */
35
+ uninstall?(): void | Promise<void>
36
+ }
37
+
38
+ /** 插件描述符(注册时使用) */
39
+ export interface PluginDescriptor {
40
+ plugin: Plugin
41
+ config?: PluginConfig
42
+ state: PluginState
43
+ error?: Error
44
+ }
45
+
46
+ /** Hook 函数类型 */
47
+ export type HookFn<T = unknown, R = unknown> = (context: T) => R | Promise<R>
48
+
49
+ /** Hook 调用选项 */
50
+ export interface HookCallOptions {
51
+ throwOnError?: boolean
52
+ }
53
+
54
+ /** Hook 描述符 */
55
+ export interface HookDescriptor<T = unknown, R = unknown> {
56
+ name: string
57
+ fn: HookFn<T, R>
58
+ priority: number
59
+ }
60
+
61
+ /** 事件处理器 */
62
+ export type EventHandler<T = unknown> = (data: T) => void
63
+
64
+ /** 插件日志器 */
65
+ export interface PluginLogger {
66
+ info(message?: unknown, ...optionalParams: unknown[]): void
67
+ warn(message?: unknown, ...optionalParams: unknown[]): void
68
+ error(message?: unknown, ...optionalParams: unknown[]): void
69
+ }
70
+
71
+ /** 插件宿主接口(暴露给插件使用的 API) */
72
+ export interface PluginHost {
73
+ /** 事件总线 */
74
+ readonly events: {
75
+ on<T = unknown>(event: string, handler: EventHandler<T>): void
76
+ off<T = unknown>(event: string, handler: EventHandler<T>): void
77
+ emit<T = unknown>(event: string, data: T): void
78
+ once<T = unknown>(event: string, handler: EventHandler<T>): void
79
+ }
80
+
81
+ /** Hook 系统 */
82
+ readonly hooks: {
83
+ tap<T = unknown, R = unknown>(
84
+ hookName: string,
85
+ fn: HookFn<T, R>,
86
+ priority?: number
87
+ ): void
88
+ untap(hookName: string, fn: HookFn): void
89
+ call<T = unknown, R = unknown>(hookName: string, context: T, options?: HookCallOptions): Promise<R[]>
90
+ callSync<T = unknown, R = unknown>(hookName: string, context: T, options?: HookCallOptions): R[]
91
+ }
92
+
93
+ /** 获取配置 */
94
+ getConfig<K = unknown>(pluginName: string, key: string, defaultValue?: K): K
95
+
96
+ /** 设置配置 */
97
+ setConfig(pluginName: string, key: string, value: unknown): void
98
+
99
+ /** 获取其他插件 */
100
+ getPlugin<T extends Plugin = Plugin>(name: string): T | undefined
101
+
102
+ /** 日志工具 */
103
+ log(level: 'info' | 'warn' | 'error', message: string, ...args: unknown[]): void
104
+
105
+ // ============ 状态存储 API ============
106
+
107
+ /** 设置共享状态 */
108
+ setSharedState<T extends BaseIndicatorState>(namespace: string, state: T, ownerId?: string): void
109
+
110
+ /** 获取共享状态 */
111
+ getSharedState<T extends BaseIndicatorState>(namespace: string): T | undefined
112
+
113
+ /** 清除共享状态 */
114
+ clearSharedState(namespace: string): void
115
+
116
+ /** 注册状态拥有者 */
117
+ registerStateOwner(ownerId: string, namespaces: string[]): void
118
+
119
+ /** 按拥有者清除状态 */
120
+ clearByOwner(ownerId: string): void
121
+
122
+ /** 注册服务 */
123
+ registerService(name: string, service: unknown): void
124
+
125
+ /** 获取已注册的服务 */
126
+ getService<T = unknown>(name: string): T | undefined
127
+ }
128
+
129
+ // ============ 渲染器插件类型 ============
130
+
131
+ /** Pane 角色 */
132
+ export type PaneRole = 'price' | 'indicator' | 'auxiliary'
133
+
134
+ /** Pane 能力开关 */
135
+ export interface PaneCapabilities {
136
+ showPriceAxisTicks: boolean
137
+ showCrosshairPriceLabel: boolean
138
+ candleHitTest: boolean
139
+ supportsPriceTranslate: boolean
140
+ }
141
+
142
+ /** Pane 信息接口 */
143
+ export interface PaneInfo {
144
+ id: string
145
+ role: PaneRole
146
+ capabilities: PaneCapabilities
147
+ top: number
148
+ height: number
149
+ yAxis: {
150
+ priceToY(price: number): number
151
+ yToPrice(y: number): number
152
+ getPaddingTop(): number
153
+ getPaddingBottom(): number
154
+ getPriceOffset(): number
155
+ getDisplayRange(baseRange?: { maxPrice: number; minPrice: number }): { maxPrice: number; minPrice: number }
156
+ getScaleType(): 'linear' | 'log'
157
+ }
158
+ priceRange: {
159
+ maxPrice: number
160
+ minPrice: number
161
+ }
162
+ }
163
+
164
+ /**
165
+ * 创建 PaneInfo 的只读包装
166
+ *
167
+ * 设计决策:
168
+ * - 使用 Readonly<T> 类型标注而非 Object.freeze,避免热路径上的运行时开销
169
+ * - yAxis 方法通过闭包包装,隔离原始函数引用
170
+ * - 依赖团队代码规范约束插件行为,而非运行时强制
171
+ */
172
+ export function wrapPaneInfo(pane: {
173
+ id: string
174
+ role: PaneRole
175
+ capabilities: PaneCapabilities
176
+ top: number
177
+ height: number
178
+ yAxis: PaneInfo['yAxis']
179
+ priceRange: PaneInfo['priceRange']
180
+ }): Readonly<PaneInfo> {
181
+ return {
182
+ id: pane.id,
183
+ role: pane.role,
184
+ capabilities: { ...pane.capabilities },
185
+ top: pane.top,
186
+ height: pane.height,
187
+ yAxis: {
188
+ priceToY: (price) => pane.yAxis.priceToY(price),
189
+ yToPrice: (y) => pane.yAxis.yToPrice(y),
190
+ getPaddingTop: () => pane.yAxis.getPaddingTop(),
191
+ getPaddingBottom: () => pane.yAxis.getPaddingBottom(),
192
+ getPriceOffset: () => pane.yAxis.getPriceOffset(),
193
+ getDisplayRange: (baseRange) => pane.yAxis.getDisplayRange(baseRange),
194
+ getScaleType: () => pane.yAxis.getScaleType(),
195
+ },
196
+ priceRange: pane.priceRange,
197
+ }
198
+ }
199
+
200
+ /** Y轴标签(价格标签) */
201
+ export interface YAxisLabel {
202
+ /** 关联的数据索引 */
203
+ dataIndex: number
204
+ /** 价格值 */
205
+ price: number
206
+ /** 标签在轴上的Y坐标(世界坐标,相对pane) */
207
+ y: number
208
+ /** 标签类型,用于区分不同渲染外观 */
209
+ type?: 'lastPrice' | 'extrema' | 'anchor' | string
210
+ /** 标签样式覆盖 */
211
+ style?: {
212
+ bgColor?: string
213
+ borderColor?: string
214
+ textColor?: string
215
+ }
216
+ }
217
+
218
+ /** X轴标签(时间标签) */
219
+ export interface XAxisLabel {
220
+ /** 关联的数据索引 */
221
+ dataIndex: number
222
+ /** 时间戳(毫秒) */
223
+ timestamp: number
224
+ /** 标签在轴上的X坐标(世界坐标,未减去scrollLeft) */
225
+ x: number
226
+ /** 标签样式覆盖 */
227
+ style?: {
228
+ bgColor?: string
229
+ textColor?: string
230
+ }
231
+ }
232
+
233
+ /** Y轴范围带(半透明填充区域) */
234
+ export interface YAxisRange {
235
+ /** 范围上界Y坐标(相对pane,canvas方向:小值=上方) */
236
+ topY: number
237
+ /** 范围下界Y坐标(相对pane,canvas方向:大值=下方) */
238
+ bottomY: number
239
+ /** 填充颜色(hex 或 rgba) */
240
+ color: string
241
+ /** 填充不透明度 */
242
+ opacity: number
243
+ }
244
+
245
+ /** X轴范围带(半透明填充区域) */
246
+ export interface XAxisRange {
247
+ /** 范围左界X坐标(世界坐标,未减去scrollLeft) */
248
+ leftX: number
249
+ /** 范围右界X坐标(世界坐标,未减去scrollLeft) */
250
+ rightX: number
251
+ /** 填充颜色(hex 或 rgba) */
252
+ color: string
253
+ /** 填充不透明度 */
254
+ opacity: number
255
+ }
256
+
257
+ /** 渲染上下文 */
258
+ /** MarkerManager 接口(用于 RenderContext) */
259
+ export interface MarkerManagerLike {
260
+ getCustomMarkers(): unknown[]
261
+ setCustomMarkerPosition(id: string, x: number, y: number, size: number, shape: string): void
262
+ }
263
+
264
+ export interface RenderContext {
265
+ ctx: CanvasRenderingContext2D
266
+ pane: PaneInfo
267
+ data: unknown[]
268
+ range: { start: number; end: number }
269
+ scrollLeft: number
270
+ kWidth: number
271
+ kGap: number
272
+ dpr: number
273
+ paneWidth: number
274
+ kLinePositions: number[]
275
+ /** 每根K线柱中心的X坐标(物理像素对齐后,逻辑像素) */
276
+ kLineCenters: number[]
277
+ /** 每根K线对应柱的X/宽度(物理像素对齐后,逻辑像素),供柱状图使用 */
278
+ kBarRects: Array<{ x: number; width: number }>
279
+ markerManager?: MarkerManagerLike
280
+ /** 十字线指向的 K 线索引(无十字线时为 null) */
281
+ crosshairIndex?: number | null
282
+ // 可选的其他 Canvas 上下文
283
+ yAxisCtx?: CanvasRenderingContext2D
284
+ xAxisCtx?: CanvasRenderingContext2D
285
+ borderCtx?: CanvasRenderingContext2D
286
+ /** 覆盖层 Canvas 上下文(用于十字线、Tooltip 等动态内容) */
287
+ overlayCtx?: CanvasRenderingContext2D
288
+ /** price pane 可选的 WebGL candle surface */
289
+ candleWebGLSurface?: CandleWebGLSurface
290
+ /** line indicator 可选的 WebGL line surface */
291
+ lineWebGLSurface?: LineWebGLSurface
292
+ /** 当前缩放级别(1 ~ zoomLevels) */
293
+ zoomLevel?: number
294
+ /** 总缩放级别数 */
295
+ zoomLevelCount?: number
296
+ viewport?: {
297
+ scrollLeft: number
298
+ plotWidth: number
299
+ plotHeight: number
300
+ }
301
+ /** 用户设置配置(渲染器只读) */
302
+ settings?: import('../config/chartSettings').ChartSettings
303
+ /** 需要在Y轴上绘制的标签列表(由各类标记渲染器填充) */
304
+ yAxisLabels?: YAxisLabel[]
305
+ /** 需要在X轴上绘制的标签列表(由各类标记渲染器填充) */
306
+ xAxisLabels?: XAxisLabel[]
307
+ /** 需要在Y轴上绘制的范围带列表(由绘图渲染器填充,先于标签绘制) */
308
+ yAxisRanges?: YAxisRange[]
309
+ /** 需要在X轴上绘制的范围带列表(由绘图渲染器填充,先于标签绘制) */
310
+ xAxisRanges?: XAxisRange[]
311
+ /** 当前主题 */
312
+ theme: import('../engine/theme/colors').ChartTheme
313
+ }
314
+
315
+ export type DrawingAnchor = {
316
+ id: string
317
+ index: number
318
+ time?: number | string
319
+ price: number
320
+ }
321
+
322
+ export type DrawingKind =
323
+ | 'trend-line'
324
+ | 'ray'
325
+ | 'extended-line'
326
+ | 'horizontal-line'
327
+ | 'horizontal-ray'
328
+ | 'vertical-line'
329
+ | 'cross-line'
330
+ | 'info-line'
331
+ | 'parallel-channel'
332
+ | 'regression-channel'
333
+ | 'flat-line'
334
+ | 'disjoint-channel'
335
+
336
+ export type DrawingStyle = {
337
+ stroke?: string
338
+ strokeWidth?: number
339
+ strokeStyle?: 'solid' | 'dashed' | 'dotted'
340
+ fill?: string
341
+ fillOpacity?: number
342
+ pointRadius?: number
343
+ textColor?: string
344
+ fontSize?: number
345
+ }
346
+
347
+ export type DrawingObject<TParams = Record<string, unknown>> = {
348
+ id: string
349
+ kind: DrawingKind
350
+ paneId: string
351
+ visible: boolean
352
+ locked?: boolean
353
+ zIndex?: number
354
+ anchors: DrawingAnchor[]
355
+ params: TParams
356
+ style: DrawingStyle
357
+ }
358
+
359
+ export type ScreenPoint = { x: number; y: number }
360
+
361
+ export type PointPrimitive = {
362
+ kind: 'point'
363
+ point: ScreenPoint
364
+ role?: 'anchor' | 'handle' | 'marker' | 'center'
365
+ style?: DrawingStyle
366
+ }
367
+
368
+ export type LinePrimitive = {
369
+ kind: 'line'
370
+ a: ScreenPoint
371
+ b: ScreenPoint
372
+ extend?: 'none' | 'left' | 'right' | 'both'
373
+ showEndpoints?: boolean
374
+ style?: DrawingStyle
375
+ }
376
+
377
+ export type AreaPrimitive = {
378
+ kind: 'area'
379
+ points: ScreenPoint[]
380
+ closed: boolean
381
+ style?: DrawingStyle
382
+ }
383
+
384
+ export type TextPrimitive = {
385
+ kind: 'text'
386
+ point: ScreenPoint
387
+ text: string
388
+ align?: 'left' | 'center' | 'right'
389
+ baseline?: 'top' | 'middle' | 'bottom'
390
+ style?: DrawingStyle
391
+ }
392
+
393
+ export type DrawingPrimitive = PointPrimitive | LinePrimitive | AreaPrimitive | TextPrimitive
394
+
395
+ export type DrawingGeometry = {
396
+ primitives: DrawingPrimitive[]
397
+ bounds?: { left: number; top: number; right: number; bottom: number }
398
+ meta?: Record<string, unknown>
399
+ computedAnchors?: DrawingAnchor[]
400
+ }
401
+
402
+ export type DrawingComputeContext = {
403
+ pane: PaneInfo
404
+ visibleData: KLineData[]
405
+ seriesData: KLineData[]
406
+ range: { start: number; end: number }
407
+ kLinePositions: number[]
408
+ kLineCenters: number[]
409
+ kBarRects: Array<{ x: number; width: number }>
410
+ kWidth: number
411
+ kGap: number
412
+ dpr: number
413
+ paneWidth: number
414
+ viewport: {
415
+ scrollLeft: number
416
+ plotWidth: number
417
+ plotHeight: number
418
+ }
419
+ toScreen(anchor: DrawingAnchor): ScreenPoint
420
+ }
421
+
422
+ export interface DrawingDefinition<TParams = Record<string, unknown>> {
423
+ kind: DrawingKind
424
+ minAnchors: number
425
+ maxAnchors: number
426
+ compute(drawing: DrawingObject<TParams>, context: DrawingComputeContext): DrawingGeometry
427
+ }
428
+
429
+ /** 全局 Pane ID(渲染到所有 pane) */
430
+ export const GLOBAL_PANE_ID = Symbol('global-pane')
431
+
432
+ /** 优先级推荐范围 */
433
+ export const RENDERER_PRIORITY = {
434
+ LAST_PRICE_LABEL: -25, // 最新价格 label 注册(必须在 SYSTEM_YAXIS 之前)
435
+ SYSTEM_YAXIS: -20, // Y轴(系统级)
436
+ SYSTEM_XAXIS: -20, // X轴(系统级)
437
+ BACKGROUND: 0, // 背景层
438
+ GRID: 10, // 网格线
439
+ /**
440
+ * 指标渲染器(MACD, RSI 等)
441
+ * 所有指标渲染器必须使用此优先级或 ≤30 的值
442
+ */
443
+ INDICATOR: 30,
444
+ MAIN: 50, // 主图(K线)
445
+ /**
446
+ * 指标刻度渲染器(依赖于前方指标写入的共享状态)
447
+ * 必须晚于 INDICATOR 和 MAIN,确保每次绘制时先更新指标状态再绘制刻度。
448
+ */
449
+ INDICATOR_SCALE: 55,
450
+ OVERLAY: 80, // 叠加层(标记点)
451
+ FOREGROUND: 100, // 前景层(价格线)
452
+ SYSTEM_BORDER: 120, // 边框(系统级)
453
+ SYSTEM_CROSSHAIR: 150, // 十字线(系统级)
454
+ } as const
455
+
456
+ /** 渲染器插件接口(独立定义,不继承 Plugin) */
457
+ export interface RendererPlugin {
458
+ /** 唯一标识 */
459
+ readonly name: string
460
+
461
+ /** 版本号 */
462
+ readonly version?: string
463
+
464
+ /** 描述 */
465
+ readonly description?: string
466
+
467
+ /** 调试用显示名称 */
468
+ readonly debugName?: string
469
+
470
+ /** 渲染目标 pane('main' | 'sub' | GLOBAL_PANE_ID 表示所有) */
471
+ paneId: string | symbol
472
+
473
+ /** 渲染优先级(数字越大越后渲染) */
474
+ priority: number
475
+
476
+ /** 是否启用(仅作为初始值,运行时状态由 Manager 管理) */
477
+ enabled?: boolean
478
+
479
+ /**
480
+ * 是否为系统渲染器
481
+ * 系统渲染器不会通过 getRenderers() 返回,只能通过 renderPlugin() 单独渲染
482
+ * 用于时间轴、全局边框等需要单独控制渲染时机的场景
483
+ */
484
+ isSystem?: boolean
485
+
486
+ /**
487
+ * 渲染器所属层,决定 UpdateLevel 过滤行为
488
+ * - 'main': 低频/静态内容,随主画布一起渲染
489
+ * - 'overlay': 高频/动态内容,可在 overlay-only 更新时独立重绘
490
+ * 未指定时默认为 'main'(向后兼容)
491
+ */
492
+ layer?: 'main' | 'overlay'
493
+
494
+ /** 渲染方法 */
495
+ draw(context: RenderContext): void
496
+
497
+ /** 数据更新时回调 */
498
+ onDataUpdate?(data: unknown[], range: { start: number; end: number }): void
499
+
500
+ /** 容器尺寸变化时回调 */
501
+ onResize?(pane: PaneInfo): void
502
+
503
+ /** 获取配置 */
504
+ getConfig?(): Record<string, unknown>
505
+
506
+ /** 设置配置 */
507
+ setConfig?(config: Record<string, unknown>): void
508
+
509
+ /** 卸载时清理资源 */
510
+ onUninstall?(): void
511
+ }
512
+
513
+ /** 带插件系统能力的渲染器(可选) */
514
+ export interface RendererPluginWithHost extends RendererPlugin {
515
+ /** 安装时获取 PluginHost 访问权限 */
516
+ onInstall?(host: PluginHost): void
517
+ /** 声明该渲染器所拥有的状态命名空间,卸载时框架会自动清理 */
518
+ getDeclaredNamespaces?(): string[]
519
+ }
520
+
521
+ // ============ 状态存储类型 ============
522
+
523
+ /** 指标渲染器状态基类 */
524
+ export interface BaseIndicatorState {
525
+ timestamp: number
526
+ }