@363045841yyt/klinechart-core 0.8.1-alpha.3 → 0.8.1

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 (130) hide show
  1. package/dist/controllers/createChartController.d.ts.map +1 -1
  2. package/dist/controllers/createChartController.js +30 -4
  3. package/dist/controllers/createChartController.js.map +1 -1
  4. package/dist/controllers/types.d.ts +9 -2
  5. package/dist/controllers/types.d.ts.map +1 -1
  6. package/dist/data-fetchers/baostock.js +3 -3
  7. package/dist/data-fetchers/baostock.js.map +1 -1
  8. package/dist/data-fetchers/dataBuffer.d.ts +6 -1
  9. package/dist/data-fetchers/dataBuffer.d.ts.map +1 -1
  10. package/dist/data-fetchers/dataBuffer.js +88 -47
  11. package/dist/data-fetchers/dataBuffer.js.map +1 -1
  12. package/dist/data-fetchers/index.d.ts +1 -0
  13. package/dist/data-fetchers/index.d.ts.map +1 -1
  14. package/dist/data-fetchers/index.js +1 -0
  15. package/dist/data-fetchers/index.js.map +1 -1
  16. package/dist/data-fetchers/router.d.ts.map +1 -1
  17. package/dist/data-fetchers/router.js +3 -0
  18. package/dist/data-fetchers/router.js.map +1 -1
  19. package/dist/data-fetchers/tradingview.d.ts +3 -0
  20. package/dist/data-fetchers/tradingview.d.ts.map +1 -0
  21. package/dist/data-fetchers/tradingview.js +45 -0
  22. package/dist/data-fetchers/tradingview.js.map +1 -0
  23. package/dist/engine/chart.d.ts +34 -351
  24. package/dist/engine/chart.d.ts.map +1 -1
  25. package/dist/engine/chart.js +246 -1716
  26. package/dist/engine/chart.js.map +1 -1
  27. package/dist/engine/chartContext.d.ts +24 -0
  28. package/dist/engine/chartContext.d.ts.map +1 -0
  29. package/dist/engine/chartContext.js +19 -0
  30. package/dist/engine/chartContext.js.map +1 -0
  31. package/dist/engine/chartTypes.d.ts +77 -0
  32. package/dist/engine/chartTypes.d.ts.map +1 -0
  33. package/dist/engine/chartTypes.js +2 -0
  34. package/dist/engine/chartTypes.js.map +1 -0
  35. package/dist/engine/controller/interaction.d.ts +1 -0
  36. package/dist/engine/controller/interaction.d.ts.map +1 -1
  37. package/dist/engine/controller/interaction.js +9 -2
  38. package/dist/engine/controller/interaction.js.map +1 -1
  39. package/dist/engine/data/chartDataManager.d.ts +102 -0
  40. package/dist/engine/data/chartDataManager.d.ts.map +1 -0
  41. package/dist/engine/data/chartDataManager.js +590 -0
  42. package/dist/engine/data/chartDataManager.js.map +1 -0
  43. package/dist/engine/indicators/chartIndicatorManager.d.ts +102 -0
  44. package/dist/engine/indicators/chartIndicatorManager.d.ts.map +1 -0
  45. package/dist/engine/indicators/chartIndicatorManager.js +437 -0
  46. package/dist/engine/indicators/chartIndicatorManager.js.map +1 -0
  47. package/dist/engine/layout/chartPaneLayout.d.ts +53 -0
  48. package/dist/engine/layout/chartPaneLayout.d.ts.map +1 -0
  49. package/dist/engine/layout/chartPaneLayout.js +388 -0
  50. package/dist/engine/layout/chartPaneLayout.js.map +1 -0
  51. package/dist/engine/render/chartRenderer.d.ts +86 -0
  52. package/dist/engine/render/chartRenderer.d.ts.map +1 -0
  53. package/dist/engine/render/chartRenderer.js +438 -0
  54. package/dist/engine/render/chartRenderer.js.map +1 -0
  55. package/dist/engine/renderers/Indicator/mainIndicatorLegend.d.ts.map +1 -1
  56. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js +73 -7
  57. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js.map +1 -1
  58. package/dist/engine/renderers/comparisonLine.d.ts.map +1 -1
  59. package/dist/engine/renderers/comparisonLine.js +25 -11
  60. package/dist/engine/renderers/comparisonLine.js.map +1 -1
  61. package/dist/engine/subPaneManager.d.ts +27 -6
  62. package/dist/engine/subPaneManager.d.ts.map +1 -1
  63. package/dist/engine/subPaneManager.js +54 -56
  64. package/dist/engine/subPaneManager.js.map +1 -1
  65. package/dist/engine/utils/chartZoomController.d.ts +33 -0
  66. package/dist/engine/utils/chartZoomController.d.ts.map +1 -0
  67. package/dist/engine/utils/chartZoomController.js +66 -0
  68. package/dist/engine/utils/chartZoomController.js.map +1 -0
  69. package/dist/engine/viewport/chartViewportManager.d.ts +72 -0
  70. package/dist/engine/viewport/chartViewportManager.d.ts.map +1 -0
  71. package/dist/engine/viewport/chartViewportManager.js +249 -0
  72. package/dist/engine/viewport/chartViewportManager.js.map +1 -0
  73. package/dist/engine/viewport/viewport.js +1 -1
  74. package/dist/engine/viewport/viewport.js.map +1 -1
  75. package/dist/plugin/types.d.ts +1 -0
  76. package/dist/plugin/types.d.ts.map +1 -1
  77. package/dist/plugin/types.js.map +1 -1
  78. package/dist/tokens/theme-china.d.ts.map +1 -1
  79. package/dist/tokens/theme-china.js +0 -4
  80. package/dist/tokens/theme-china.js.map +1 -1
  81. package/dist/tokens/theme-dark.d.ts.map +1 -1
  82. package/dist/tokens/theme-dark.js +0 -4
  83. package/dist/tokens/theme-dark.js.map +1 -1
  84. package/dist/tokens/theme-light.d.ts.map +1 -1
  85. package/dist/tokens/theme-light.js +1 -5
  86. package/dist/tokens/theme-light.js.map +1 -1
  87. package/dist/tokens/types.d.ts +0 -4
  88. package/dist/tokens/types.d.ts.map +1 -1
  89. package/dist/types/price.d.ts +2 -0
  90. package/dist/types/price.d.ts.map +1 -1
  91. package/dist/types/price.js.map +1 -1
  92. package/dist/version.d.ts +1 -1
  93. package/dist/version.d.ts.map +1 -1
  94. package/dist/version.js +1 -1
  95. package/dist/version.js.map +1 -1
  96. package/package.json +1 -1
  97. package/src/controllers/createChartController.ts +49 -13
  98. package/src/controllers/types.ts +9 -2
  99. package/src/data-fetchers/__tests__/dataBuffer.test.ts +77 -0
  100. package/src/data-fetchers/baostock.ts +3 -3
  101. package/src/data-fetchers/dataBuffer.ts +70 -22
  102. package/src/data-fetchers/index.ts +1 -0
  103. package/src/data-fetchers/router.ts +3 -0
  104. package/src/data-fetchers/tradingview.ts +48 -0
  105. package/src/engine/__tests__/subPaneManager.test.ts +154 -0
  106. package/src/engine/chart.ts +260 -2103
  107. package/src/engine/chartContext.ts +34 -0
  108. package/src/engine/chartTypes.ts +88 -0
  109. package/src/engine/controller/__tests__/interaction.dpr.test.ts +1 -0
  110. package/src/engine/controller/interaction.ts +10 -2
  111. package/src/engine/data/chartDataManager.ts +691 -0
  112. package/src/engine/indicators/__tests__/chartIndicatorManager.test.ts +103 -0
  113. package/src/engine/indicators/chartIndicatorManager.ts +566 -0
  114. package/src/engine/layout/chartPaneLayout.ts +474 -0
  115. package/src/engine/render/chartRenderer.ts +579 -0
  116. package/src/engine/renderers/Indicator/mainIndicatorLegend.ts +99 -13
  117. package/src/engine/renderers/comparisonLine.ts +25 -11
  118. package/src/engine/subPaneManager.ts +75 -59
  119. package/src/engine/utils/chartZoomController.ts +104 -0
  120. package/src/engine/viewport/chartViewportManager.ts +310 -0
  121. package/src/engine/viewport/viewport.ts +1 -1
  122. package/src/plugin/types.ts +1 -0
  123. package/src/tokens/__tests__/__snapshots__/baseline.test.ts.snap +1 -9
  124. package/src/tokens/theme-china.ts +0 -4
  125. package/src/tokens/theme-dark.ts +0 -4
  126. package/src/tokens/theme-light.ts +2 -6
  127. package/src/tokens/types.ts +0 -4
  128. package/src/types/price.ts +2 -0
  129. package/src/version.ts +1 -1
  130. package/src/engine/chart.d.ts +0 -619
@@ -0,0 +1,310 @@
1
+ import type { ChartDom, Viewport, ViewportState } from '../chartTypes'
2
+ import type { VisibleRange, UpdateLevel } from '../layout/pane'
3
+ import { createSignal, type Signal } from '../../reactivity/signal'
4
+
5
+ export interface ViewportDependencies {
6
+ getDom: () => ChartDom
7
+ getBottomAxisHeight: () => number
8
+ getLeftLoadBufferWidth: () => number
9
+ getZoomLevel: () => number
10
+ getLastVisibleRange: () => VisibleRange
11
+ getKWidth: () => number
12
+ getKGap: () => number
13
+ scheduleDraw: (level?: UpdateLevel) => void
14
+ onResizeCompleted: () => void
15
+ resizeSharedWebGLSurface: (plotWidth: number, plotHeight: number, dpr: number) => void
16
+ }
17
+
18
+ export class ChartViewportManager {
19
+ private deps: ViewportDependencies
20
+
21
+ /** 精确 DPR(来自 ResizeObserver 的 devicePixelContentBoxSize) */
22
+ private preciseDpr = 0
23
+
24
+ /** 统一监听容器尺寸与 DPR 变化 */
25
+ private resizeObserver?: ResizeObserver
26
+
27
+ /** scroll 事件处理器引用(用于 cleanup) */
28
+ private onScroll?: () => void
29
+
30
+ /** 最近一次观测到的容器尺寸 */
31
+ private observedSize = { width: 0, height: 0 }
32
+
33
+ /** 缓存的 scrollLeft(通过 scroll 事件同步,避免每帧读取 DOM 触发强制回流) */
34
+ private cachedScrollLeft = 0
35
+
36
+ /** 待写入 DOM 的 scrollLeft(在 RAF 回调中应用,确保 Vue 已完成 DOM 更新) */
37
+ private _pendingScrollLeft: number | null = null
38
+
39
+ /** 内部视口状态 */
40
+ private _internalViewport: Viewport | null = null
41
+
42
+ /** 视口状态信号 */
43
+ private _viewportSignal = createSignal<ViewportState>({
44
+ zoomLevel: 1,
45
+ plotWidth: 0,
46
+ plotHeight: 0,
47
+ dpr: 1,
48
+ visibleFrom: 0,
49
+ visibleTo: 0,
50
+ kWidth: 0,
51
+ kGap: 1,
52
+ })
53
+
54
+ constructor(deps: ViewportDependencies) {
55
+ this.deps = deps
56
+ }
57
+
58
+ /** 视口状态信号 */
59
+ get viewportSignal(): Signal<ViewportState> {
60
+ return this._viewportSignal
61
+ }
62
+
63
+ /** 获取缓存的 scrollLeft(避免读取 DOM 触发强制回流) */
64
+ getCachedScrollLeft(): number {
65
+ return this.cachedScrollLeft
66
+ }
67
+
68
+ /** 获取逻辑 scrollLeft(减去左侧加载缓冲宽度,可为负值) */
69
+ getLogicalScrollLeft(): number {
70
+ return this.cachedScrollLeft - this.deps.getLeftLoadBufferWidth()
71
+ }
72
+
73
+ /** 获取当前视口 */
74
+ getViewport(): Viewport | null {
75
+ return this._internalViewport
76
+ }
77
+
78
+ /** 获取有效 DPR */
79
+ getEffectiveDpr(): number {
80
+ let dpr = this.preciseDpr > 0
81
+ ? this.preciseDpr
82
+ : Math.round((window.devicePixelRatio || 1) * 64) / 64
83
+ if (dpr < 1) dpr = 1
84
+ return dpr
85
+ }
86
+
87
+ /** 获取观测到的容器尺寸 */
88
+ getObservedSize(): { width: number; height: number } {
89
+ return this.observedSize
90
+ }
91
+
92
+ /** 设置滚动位置(缓存 + 待写入) */
93
+ setScrollLeft(v: number): void {
94
+ this.cachedScrollLeft = v
95
+ this._pendingScrollLeft = v
96
+ }
97
+
98
+ /** 仅设置缓存 scrollLeft(由 DataManager 内部使用) */
99
+ setCachedScrollLeft(v: number): void {
100
+ this.cachedScrollLeft = v
101
+ }
102
+
103
+ /** 仅设置待写入 scrollLeft(由 DataManager 内部使用) */
104
+ setPendingScrollLeft(v: number): void {
105
+ this._pendingScrollLeft = v
106
+ }
107
+
108
+ /** 在 RAF 回调中应用待写入的 scrollLeft */
109
+ applyPendingScrollLeft(container: HTMLElement): void {
110
+ if (this._pendingScrollLeft !== null) {
111
+ container.scrollLeft = this._pendingScrollLeft
112
+ this.cachedScrollLeft = container.scrollLeft
113
+ this._pendingScrollLeft = null
114
+ }
115
+ }
116
+
117
+ /** 初始化 ResizeObserver 和 scroll 监听 */
118
+ init(): void {
119
+ if (typeof ResizeObserver === 'undefined') return
120
+
121
+ const target = this.deps.getDom().container
122
+ if (!target) return
123
+
124
+ // 初始化 scrollLeft 缓存
125
+ this.cachedScrollLeft = target.scrollLeft
126
+ this.onScroll = () => { this.cachedScrollLeft = target.scrollLeft }
127
+ target.addEventListener('scroll', this.onScroll, { passive: true })
128
+
129
+ this.resizeObserver = new ResizeObserver((entries) => {
130
+ const entry = entries[0]
131
+ if (!entry) return
132
+
133
+ const prevWidth = this.observedSize.width
134
+ const prevHeight = this.observedSize.height
135
+ const prevDpr = this.preciseDpr
136
+
137
+ this.updateObservedMetrics(entry)
138
+
139
+ const widthChanged = this.observedSize.width !== prevWidth
140
+ const heightChanged = this.observedSize.height !== prevHeight
141
+ const dprChanged = this.preciseDpr !== prevDpr
142
+ if ((import.meta as any).env?.MODE !== 'production') {
143
+ console.log(
144
+ `[Chart] resize observer: ` +
145
+ `size ${prevWidth}x${prevHeight} -> ${this.observedSize.width}x${this.observedSize.height} ` +
146
+ `dpr ${prevDpr} -> ${this.preciseDpr} ` +
147
+ `changed: ${widthChanged || heightChanged ? 'size' : ''}${widthChanged || heightChanged && dprChanged ? '+' : ''}${dprChanged ? 'dpr' : ''}`
148
+ )
149
+ }
150
+ if (widthChanged || heightChanged || dprChanged) {
151
+ this.deps.onResizeCompleted()
152
+ }
153
+ })
154
+
155
+ try {
156
+ this.resizeObserver.observe(target, { box: 'device-pixel-content-box' as ResizeObserverBoxOptions })
157
+ } catch {
158
+ this.resizeObserver.observe(target)
159
+ }
160
+ }
161
+
162
+ /** 销毁 */
163
+ destroy(): void {
164
+ this.resizeObserver?.disconnect()
165
+ this.resizeObserver = undefined
166
+ this.preciseDpr = 0
167
+ this.observedSize = { width: 0, height: 0 }
168
+
169
+ if (this.onScroll) {
170
+ this.deps.getDom().container?.removeEventListener('scroll', this.onScroll)
171
+ this.onScroll = undefined
172
+ }
173
+
174
+ this._internalViewport = null
175
+ }
176
+
177
+ /**
178
+ * 计算视口
179
+ */
180
+ computeViewport(): Viewport | null {
181
+ const container = this.deps.getDom().container
182
+ if (!container) return null
183
+
184
+ const observedWidth = this.observedSize.width
185
+ const observedHeight = this.observedSize.height
186
+ const viewWidth = observedWidth > 0
187
+ ? observedWidth
188
+ : Math.max(1, Math.round(container.clientWidth))
189
+ const viewHeight = observedHeight > 0
190
+ ? observedHeight
191
+ : Math.max(1, Math.round(container.clientHeight))
192
+
193
+ const plotWidth = Math.round(viewWidth)
194
+ const plotHeight = Math.round(viewHeight - this.deps.getBottomAxisHeight())
195
+
196
+ let dpr = this.getEffectiveDpr()
197
+
198
+ const MAX_CANVAS_PIXELS = 16 * 1024 * 1024
199
+ const requestedPixels = viewWidth * dpr * (viewHeight * dpr)
200
+ if (requestedPixels > MAX_CANVAS_PIXELS) {
201
+ dpr = Math.sqrt(MAX_CANVAS_PIXELS / (viewWidth * viewHeight))
202
+ }
203
+
204
+ // 对齐 scrollLeft,消除 translate 亚像素偏移
205
+ const scrollLeft = Math.round(this.getLogicalScrollLeft() * dpr) / dpr
206
+
207
+ const dom = this.deps.getDom()
208
+
209
+ const canvasLayerWidth = `${viewWidth}px`
210
+ if (dom.canvasLayer.style.width !== canvasLayerWidth) {
211
+ dom.canvasLayer.style.width = canvasLayerWidth
212
+ }
213
+
214
+ const canvasLayerHeight = `${viewHeight}px`
215
+ if (dom.canvasLayer.style.height !== canvasLayerHeight) {
216
+ dom.canvasLayer.style.height = canvasLayerHeight
217
+ }
218
+
219
+ const xAxisWidth = Math.round(plotWidth * dpr)
220
+ if (dom.xAxisCanvas.width !== xAxisWidth) {
221
+ dom.xAxisCanvas.width = xAxisWidth
222
+ }
223
+
224
+ const xAxisHeight = Math.round(this.deps.getBottomAxisHeight() * dpr)
225
+ if (dom.xAxisCanvas.height !== xAxisHeight) {
226
+ dom.xAxisCanvas.height = xAxisHeight
227
+ }
228
+
229
+ const xAxisCssWidth = `${xAxisWidth / dpr}px`
230
+ if (dom.xAxisCanvas.style.width !== xAxisCssWidth) {
231
+ dom.xAxisCanvas.style.width = xAxisCssWidth
232
+ }
233
+
234
+ const xAxisCssHeight = `${xAxisHeight / dpr}px`
235
+ if (dom.xAxisCanvas.style.height !== xAxisCssHeight) {
236
+ dom.xAxisCanvas.style.height = xAxisCssHeight
237
+ }
238
+
239
+ this.deps.resizeSharedWebGLSurface(plotWidth, plotHeight, dpr)
240
+
241
+ const vp: Viewport = {
242
+ viewWidth,
243
+ viewHeight,
244
+ plotWidth,
245
+ plotHeight,
246
+ scrollLeft,
247
+ dpr,
248
+ }
249
+ const prevViewport = this._internalViewport
250
+ const viewportChanged = !prevViewport
251
+ || prevViewport.viewWidth !== vp.viewWidth
252
+ || prevViewport.viewHeight !== vp.viewHeight
253
+ || prevViewport.plotWidth !== vp.plotWidth
254
+ || prevViewport.plotHeight !== vp.plotHeight
255
+ || prevViewport.scrollLeft !== vp.scrollLeft
256
+ || prevViewport.dpr !== vp.dpr
257
+
258
+ this._internalViewport = vp
259
+ if (viewportChanged) {
260
+ const current = this._viewportSignal.peek()
261
+ this._viewportSignal.set({
262
+ zoomLevel: current.zoomLevel,
263
+ plotWidth: vp.plotWidth,
264
+ plotHeight: vp.plotHeight,
265
+ dpr: vp.dpr > 0 ? vp.dpr : current.dpr,
266
+ visibleFrom: current.visibleFrom,
267
+ visibleTo: current.visibleTo,
268
+ kWidth: current.kWidth,
269
+ kGap: current.kGap,
270
+ })
271
+ }
272
+ return vp
273
+ }
274
+
275
+ /**
276
+ * 更新 viewport signal(用于滚动事件/缩放后的信号同步)
277
+ */
278
+ updateViewportSignal(): void {
279
+ const vp = this._internalViewport
280
+ if (!vp) return
281
+
282
+ this._viewportSignal.set({
283
+ zoomLevel: this.deps.getZoomLevel(),
284
+ plotWidth: vp.plotWidth,
285
+ plotHeight: vp.plotHeight,
286
+ dpr: vp.dpr,
287
+ visibleFrom: this.deps.getLastVisibleRange().start,
288
+ visibleTo: this.deps.getLastVisibleRange().end,
289
+ kWidth: this.deps.getKWidth(),
290
+ kGap: this.deps.getKGap(),
291
+ })
292
+ }
293
+
294
+ private updateObservedMetrics(entry: ResizeObserverEntry) {
295
+ const cssWidth = Math.max(1, Math.round(entry.contentRect.width))
296
+ const cssHeight = Math.max(1, Math.round(entry.contentRect.height))
297
+ this.observedSize.width = cssWidth
298
+ this.observedSize.height = cssHeight
299
+
300
+ const pixelSize = entry.devicePixelContentBoxSize?.[0]
301
+ const cssSize = entry.contentBoxSize?.[0]
302
+ if (!pixelSize || !cssSize || cssSize.inlineSize <= 0) {
303
+ this.preciseDpr = 0
304
+ return
305
+ }
306
+
307
+ const raw = pixelSize.inlineSize / cssSize.inlineSize
308
+ this.preciseDpr = Math.round(raw * 64) / 64
309
+ }
310
+ }
@@ -31,7 +31,7 @@ export function getVisibleRange(
31
31
  const viewWidthPx = viewWidth * dpr
32
32
 
33
33
  // 计算可见范围(物理像素空间整数运算)
34
- const start = Math.max(0, Math.floor((scrollLeftPx - startXPx) / unitPx) - 1)
34
+ const start = Math.floor((scrollLeftPx - startXPx) / unitPx) - 1
35
35
  const end = Math.min(totalDataCount, Math.ceil((scrollLeftPx + viewWidthPx - startXPx) / unitPx) + 1)
36
36
 
37
37
  return { start, end }
@@ -275,6 +275,7 @@ export interface RenderContext {
275
275
  data: unknown[]
276
276
  comparisonData?: ReadonlyMap<string, ReadonlyArray<KLineData>>
277
277
  comparisonSymbols?: ReadonlyArray<import('../controllers/types').SymbolSpec>
278
+ comparisonColors?: ReadonlyMap<string, string>
278
279
  range: { start: number; end: number }
279
280
  scrollLeft: number
280
281
  kWidth: number
@@ -57,10 +57,6 @@ exports[`theme baseline — dark > CSS declaration block (snapshot) 1`] = `
57
57
  --klc-color-text-tertiary: hsl(210, 6%, 60%);
58
58
  --klc-color-text-weak: hsl(210, 5%, 45%);
59
59
  --klc-color-text-white: rgba(255, 255, 255, 0.95);
60
- --klc-color-price-up-light: rgba(255, 80, 100, 0.85);
61
- --klc-color-price-up-tick: hsl(0, 70%, 60%);
62
- --klc-color-price-down-light: rgba(60, 200, 160, 0.85);
63
- --klc-color-price-down-tick: hsl(150, 50%, 65%);
64
60
  --klc-color-price-last-price: rgba(230, 100, 115, 0.95);
65
61
  --klc-color-tag-bg-white: rgb(40, 40, 55);
66
62
  --klc-color-tag-bg-light-gray: rgba(50, 50, 65, 0.92);
@@ -254,11 +250,7 @@ exports[`theme baseline — light > CSS declaration block (snapshot) 1`] = `
254
250
  --klc-color-text-tertiary: hsl(210, 8%, 50%);
255
251
  --klc-color-text-weak: hsl(210, 7%, 65%);
256
252
  --klc-color-text-white: rgba(255, 255, 255, 0.92);
257
- --klc-color-price-up-light: rgba(214, 10, 34, 0.92);
258
- --klc-color-price-up-tick: hsl(0, 60%, 50%);
259
- --klc-color-price-down-light: rgba(3, 123, 102, 0.92);
260
- --klc-color-price-down-tick: hsl(150, 30%, 60%);
261
- --klc-color-price-last-price: rgba(196, 74, 86, 0.95);
253
+ --klc-color-price-last-price: rgba(230, 100, 115, 0.95);
262
254
  --klc-color-tag-bg-white: rgb(255, 255, 255);
263
255
  --klc-color-tag-bg-light-gray: rgba(255, 255, 255, 0.92);
264
256
  --klc-color-tag-bg-pure-white: #ffffff;
@@ -56,10 +56,6 @@ export function withAsiaMarketColors(theme: Theme): Theme {
56
56
  // ── Nested: price accents ──
57
57
  price: {
58
58
  ...theme.colors.price,
59
- upLight: theme.colors.price.downLight,
60
- downLight: theme.colors.price.upLight,
61
- upTick: theme.colors.price.downTick,
62
- downTick: theme.colors.price.upTick,
63
59
  },
64
60
 
65
61
  // ── Nested: MACD histogram bars ──
@@ -96,10 +96,6 @@ export const darkTheme: Theme = {
96
96
  white: 'rgba(255, 255, 255, 0.95)',
97
97
  },
98
98
  price: {
99
- upLight: 'rgba(255, 80, 100, 0.85)',
100
- upTick: 'hsl(0, 70%, 60%)',
101
- downLight: 'rgba(60, 200, 160, 0.85)',
102
- downTick: 'hsl(150, 50%, 65%)',
103
99
  lastPrice: 'rgba(230, 100, 115, 0.95)',
104
100
  },
105
101
  tagBg: {
@@ -101,12 +101,8 @@ export const lightTheme: Theme = {
101
101
  weak: 'hsl(210, 7%, 65%)',
102
102
  white: 'rgba(255, 255, 255, 0.92)',
103
103
  },
104
- price: {
105
- upLight: 'rgba(214, 10, 34, 0.92)',
106
- upTick: 'hsl(0, 60%, 50%)',
107
- downLight: 'rgba(3, 123, 102, 0.92)',
108
- downTick: 'hsl(150, 30%, 60%)',
109
- lastPrice: 'rgba(196, 74, 86, 0.95)',
104
+ price: {
105
+ lastPrice: 'rgba(230, 100, 115, 0.95)',
110
106
  },
111
107
  tagBg: {
112
108
  white: 'rgb(255, 255, 255)',
@@ -85,10 +85,6 @@ export interface TextColors {
85
85
  * (candleUpBody / candleDownBody); this group covers extras.
86
86
  */
87
87
  export interface PriceColors {
88
- readonly upLight: ColorValue
89
- readonly upTick: ColorValue
90
- readonly downLight: ColorValue
91
- readonly downTick: ColorValue
92
88
  readonly lastPrice: ColorValue
93
89
  }
94
90
 
@@ -1,6 +1,8 @@
1
1
  export interface KLineData {
2
2
  /* 时间戳(毫秒) */
3
3
  timestamp: number
4
+ /** 日期字符串(如 "2025-06-16"),用于跨品种精确匹配 */
5
+ date?: string
4
6
  /* 开盘价 */
5
7
  open: number
6
8
  /* 最高价 */
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = "0.8.1-alpha.3"
1
+ export const VERSION = "0.8.1"