@363045841yyt/klinechart-core 0.7.6 → 0.7.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 (191) hide show
  1. package/dist/config/chartSettings.d.ts +27 -2
  2. package/dist/config/chartSettings.d.ts.map +1 -1
  3. package/dist/config/chartSettings.js +6 -0
  4. package/dist/config/chartSettings.js.map +1 -1
  5. package/dist/engine/chart.d.ts.map +1 -1
  6. package/dist/engine/chart.js +4 -0
  7. package/dist/engine/chart.js.map +1 -1
  8. package/dist/engine/draw/pixelAlign.d.ts.map +1 -1
  9. package/dist/engine/draw/pixelAlign.js.map +1 -1
  10. package/dist/engine/drawing/plugin.js +1 -1
  11. package/dist/engine/drawing/plugin.js.map +1 -1
  12. package/dist/engine/renderers/Indicator/atr.d.ts.map +1 -1
  13. package/dist/engine/renderers/Indicator/atr.js +7 -4
  14. package/dist/engine/renderers/Indicator/atr.js.map +1 -1
  15. package/dist/engine/renderers/Indicator/boll.js +12 -12
  16. package/dist/engine/renderers/Indicator/boll.js.map +1 -1
  17. package/dist/engine/renderers/Indicator/cci.d.ts +1 -2
  18. package/dist/engine/renderers/Indicator/cci.d.ts.map +1 -1
  19. package/dist/engine/renderers/Indicator/cci.js +9 -9
  20. package/dist/engine/renderers/Indicator/cci.js.map +1 -1
  21. package/dist/engine/renderers/Indicator/ene.js +12 -12
  22. package/dist/engine/renderers/Indicator/ene.js.map +1 -1
  23. package/dist/engine/renderers/Indicator/expma.js +6 -6
  24. package/dist/engine/renderers/Indicator/expma.js.map +1 -1
  25. package/dist/engine/renderers/Indicator/fastk.d.ts +1 -2
  26. package/dist/engine/renderers/Indicator/fastk.d.ts.map +1 -1
  27. package/dist/engine/renderers/Indicator/fastk.js +7 -7
  28. package/dist/engine/renderers/Indicator/fastk.js.map +1 -1
  29. package/dist/engine/renderers/Indicator/kst.d.ts +1 -2
  30. package/dist/engine/renderers/Indicator/kst.d.ts.map +1 -1
  31. package/dist/engine/renderers/Indicator/kst.js +10 -10
  32. package/dist/engine/renderers/Indicator/kst.js.map +1 -1
  33. package/dist/engine/renderers/Indicator/ma.js +5 -5
  34. package/dist/engine/renderers/Indicator/ma.js.map +1 -1
  35. package/dist/engine/renderers/Indicator/macd.d.ts +1 -2
  36. package/dist/engine/renderers/Indicator/macd.d.ts.map +1 -1
  37. package/dist/engine/renderers/Indicator/macd.js +24 -24
  38. package/dist/engine/renderers/Indicator/macd.js.map +1 -1
  39. package/dist/engine/renderers/Indicator/macdLegend.js +6 -6
  40. package/dist/engine/renderers/Indicator/macdLegend.js.map +1 -1
  41. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js +16 -16
  42. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js.map +1 -1
  43. package/dist/engine/renderers/Indicator/mom.d.ts +1 -2
  44. package/dist/engine/renderers/Indicator/mom.d.ts.map +1 -1
  45. package/dist/engine/renderers/Indicator/mom.js +8 -8
  46. package/dist/engine/renderers/Indicator/mom.js.map +1 -1
  47. package/dist/engine/renderers/Indicator/rsi.d.ts +2 -3
  48. package/dist/engine/renderers/Indicator/rsi.d.ts.map +1 -1
  49. package/dist/engine/renderers/Indicator/rsi.js +19 -15
  50. package/dist/engine/renderers/Indicator/rsi.js.map +1 -1
  51. package/dist/engine/renderers/Indicator/scale/indicator_scale.d.ts +1 -2
  52. package/dist/engine/renderers/Indicator/scale/indicator_scale.d.ts.map +1 -1
  53. package/dist/engine/renderers/Indicator/scale/indicator_scale.js +5 -5
  54. package/dist/engine/renderers/Indicator/scale/indicator_scale.js.map +1 -1
  55. package/dist/engine/renderers/Indicator/stoch.d.ts +1 -2
  56. package/dist/engine/renderers/Indicator/stoch.d.ts.map +1 -1
  57. package/dist/engine/renderers/Indicator/stoch.js +10 -10
  58. package/dist/engine/renderers/Indicator/stoch.js.map +1 -1
  59. package/dist/engine/renderers/Indicator/structure.js +5 -5
  60. package/dist/engine/renderers/Indicator/structure.js.map +1 -1
  61. package/dist/engine/renderers/Indicator/wmsr.d.ts +1 -2
  62. package/dist/engine/renderers/Indicator/wmsr.d.ts.map +1 -1
  63. package/dist/engine/renderers/Indicator/wmsr.js +10 -10
  64. package/dist/engine/renderers/Indicator/wmsr.js.map +1 -1
  65. package/dist/engine/renderers/Indicator/zones.js +6 -6
  66. package/dist/engine/renderers/Indicator/zones.js.map +1 -1
  67. package/dist/engine/renderers/candle.d.ts +1 -1
  68. package/dist/engine/renderers/candle.d.ts.map +1 -1
  69. package/dist/engine/renderers/candle.js +21 -21
  70. package/dist/engine/renderers/candle.js.map +1 -1
  71. package/dist/engine/renderers/crosshair.js +3 -3
  72. package/dist/engine/renderers/crosshair.js.map +1 -1
  73. package/dist/engine/renderers/extremaMarkers.d.ts.map +1 -1
  74. package/dist/engine/renderers/extremaMarkers.js +12 -12
  75. package/dist/engine/renderers/extremaMarkers.js.map +1 -1
  76. package/dist/engine/renderers/gridLines.js +3 -3
  77. package/dist/engine/renderers/gridLines.js.map +1 -1
  78. package/dist/engine/renderers/lastPrice.js +7 -7
  79. package/dist/engine/renderers/lastPrice.js.map +1 -1
  80. package/dist/engine/renderers/paneTitle.js +6 -6
  81. package/dist/engine/renderers/paneTitle.js.map +1 -1
  82. package/dist/engine/renderers/subVolume.d.ts.map +1 -1
  83. package/dist/engine/renderers/subVolume.js +23 -20
  84. package/dist/engine/renderers/subVolume.js.map +1 -1
  85. package/dist/engine/renderers/timeAxis.js +9 -9
  86. package/dist/engine/renderers/timeAxis.js.map +1 -1
  87. package/dist/engine/renderers/webgl/candleSurface.d.ts.map +1 -1
  88. package/dist/engine/renderers/webgl/candleSurface.js +39 -7
  89. package/dist/engine/renderers/webgl/candleSurface.js.map +1 -1
  90. package/dist/engine/renderers/yAxis.d.ts.map +1 -1
  91. package/dist/engine/renderers/yAxis.js +5 -5
  92. package/dist/engine/renderers/yAxis.js.map +1 -1
  93. package/dist/index.d.ts +1 -0
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/index.js +1 -0
  96. package/dist/index.js.map +1 -1
  97. package/dist/plugin/types.d.ts +5 -1
  98. package/dist/plugin/types.d.ts.map +1 -1
  99. package/dist/plugin/types.js.map +1 -1
  100. package/dist/tokens/colorPresetSettings.d.ts +15 -0
  101. package/dist/tokens/colorPresetSettings.d.ts.map +1 -0
  102. package/dist/tokens/colorPresetSettings.js +65 -0
  103. package/dist/tokens/colorPresetSettings.js.map +1 -0
  104. package/dist/tokens/index.d.ts +17 -0
  105. package/dist/tokens/index.d.ts.map +1 -0
  106. package/dist/tokens/index.js +16 -0
  107. package/dist/tokens/index.js.map +1 -0
  108. package/dist/tokens/mergeTheme.d.ts +17 -0
  109. package/dist/tokens/mergeTheme.d.ts.map +1 -0
  110. package/dist/tokens/mergeTheme.js +43 -0
  111. package/dist/tokens/mergeTheme.js.map +1 -0
  112. package/dist/tokens/theme-china.d.ts +45 -0
  113. package/dist/tokens/theme-china.d.ts.map +1 -0
  114. package/dist/tokens/theme-china.js +116 -0
  115. package/dist/tokens/theme-china.js.map +1 -0
  116. package/dist/tokens/theme-dark.d.ts +21 -0
  117. package/dist/tokens/theme-dark.d.ts.map +1 -0
  118. package/dist/tokens/theme-dark.js +228 -0
  119. package/dist/tokens/theme-dark.js.map +1 -0
  120. package/dist/tokens/theme-light.d.ts +23 -0
  121. package/dist/tokens/theme-light.d.ts.map +1 -0
  122. package/dist/tokens/theme-light.js +234 -0
  123. package/dist/tokens/theme-light.js.map +1 -0
  124. package/dist/tokens/themeToCssVars.d.ts +74 -0
  125. package/dist/tokens/themeToCssVars.d.ts.map +1 -0
  126. package/dist/tokens/themeToCssVars.js +108 -0
  127. package/dist/tokens/themeToCssVars.js.map +1 -0
  128. package/dist/tokens/types.d.ts +335 -0
  129. package/dist/tokens/types.d.ts.map +1 -0
  130. package/dist/tokens/types.js +20 -0
  131. package/dist/tokens/types.js.map +1 -0
  132. package/dist/utils/kLineDraw/axis.d.ts +8 -7
  133. package/dist/utils/kLineDraw/axis.d.ts.map +1 -1
  134. package/dist/utils/kLineDraw/axis.js +24 -24
  135. package/dist/utils/kLineDraw/axis.js.map +1 -1
  136. package/dist/version.d.ts +1 -1
  137. package/dist/version.js +1 -1
  138. package/package.json +1 -1
  139. package/src/config/chartSettings.ts +11 -2
  140. package/src/engine/chart.ts +4 -0
  141. package/src/engine/draw/pixelAlign.ts +0 -2
  142. package/src/engine/drawing/plugin.ts +1 -1
  143. package/src/engine/renderers/Indicator/atr.ts +7 -3
  144. package/src/engine/renderers/Indicator/boll.ts +12 -12
  145. package/src/engine/renderers/Indicator/cci.ts +11 -10
  146. package/src/engine/renderers/Indicator/ene.ts +12 -12
  147. package/src/engine/renderers/Indicator/expma.ts +6 -6
  148. package/src/engine/renderers/Indicator/fastk.ts +9 -8
  149. package/src/engine/renderers/Indicator/kst.ts +12 -11
  150. package/src/engine/renderers/Indicator/ma.ts +5 -5
  151. package/src/engine/renderers/Indicator/macd.ts +27 -25
  152. package/src/engine/renderers/Indicator/macdLegend.ts +6 -6
  153. package/src/engine/renderers/Indicator/mainIndicatorLegend.ts +16 -16
  154. package/src/engine/renderers/Indicator/mom.ts +11 -10
  155. package/src/engine/renderers/Indicator/rsi.ts +22 -15
  156. package/src/engine/renderers/Indicator/scale/indicator_scale.ts +6 -6
  157. package/src/engine/renderers/Indicator/stoch.ts +12 -11
  158. package/src/engine/renderers/Indicator/structure.ts +5 -5
  159. package/src/engine/renderers/Indicator/wmsr.ts +13 -12
  160. package/src/engine/renderers/Indicator/zones.ts +7 -7
  161. package/src/engine/renderers/candle.ts +21 -21
  162. package/src/engine/renderers/crosshair.ts +3 -3
  163. package/src/engine/renderers/extremaMarkers.ts +13 -12
  164. package/src/engine/renderers/gridLines.ts +3 -3
  165. package/src/engine/renderers/lastPrice.ts +7 -7
  166. package/src/engine/renderers/paneTitle.ts +6 -6
  167. package/src/engine/renderers/subVolume.ts +23 -20
  168. package/src/engine/renderers/timeAxis.ts +9 -9
  169. package/src/engine/renderers/webgl/candleSurface.ts +43 -7
  170. package/src/engine/renderers/yAxis.ts +6 -5
  171. package/src/index.ts +1 -0
  172. package/src/plugin/types.ts +5 -1
  173. package/src/tokens/__tests__/__snapshots__/baseline.test.ts.snap +393 -0
  174. package/src/tokens/__tests__/baseline.test.ts +183 -0
  175. package/src/tokens/__tests__/themeToCssVars.test.ts +175 -0
  176. package/src/tokens/__tests__/tokens.test.ts +215 -0
  177. package/src/tokens/colorPresetSettings.ts +128 -0
  178. package/src/tokens/index.ts +65 -0
  179. package/src/tokens/mergeTheme.ts +48 -0
  180. package/src/tokens/theme-china.ts +132 -0
  181. package/src/tokens/theme-dark.ts +244 -0
  182. package/src/tokens/theme-light.ts +250 -0
  183. package/src/tokens/themeToCssVars.ts +138 -0
  184. package/src/tokens/types.ts +394 -0
  185. package/src/utils/kLineDraw/axis.ts +31 -30
  186. package/src/version.ts +1 -1
  187. package/dist/engine/theme/colors.d.ts +0 -223
  188. package/dist/engine/theme/colors.d.ts.map +0 -1
  189. package/dist/engine/theme/colors.js +0 -375
  190. package/dist/engine/theme/colors.js.map +0 -1
  191. package/src/engine/theme/colors.ts +0 -642
@@ -2,7 +2,7 @@ import type { RendererPlugin, RenderContext } from '../../plugin'
2
2
  import { RENDERER_PRIORITY, GLOBAL_PANE_ID } from '../../plugin'
3
3
  import type { KLineData } from '../../types/price'
4
4
  import { roundToPhysicalPixel, alignToPhysicalPixelCenter, createHorizontalLineRect } from '../draw/pixelAlign'
5
- import { getColors, type ThemeColors } from '../theme/colors'
5
+ import { resolveThemeColors } from '../../tokens'
6
6
  import { getFont, setCanvasFont } from '../theme/fonts'
7
7
 
8
8
  const textWidthCache = new Map<string, number>()
@@ -58,14 +58,15 @@ function drawAllMarkers(
58
58
  ctx: CanvasRenderingContext2D,
59
59
  markers: MarkerData[],
60
60
  dpr: number,
61
- colors: ThemeColors
61
+ lineColor: string,
62
+ textColor: string
62
63
  ) {
63
64
  if (markers.length === 0) return
64
65
 
65
66
  ctx.save()
66
67
 
67
68
  // ========== 阶段1:批量绘制所有线条(同一 fillStyle)==========
68
- ctx.fillStyle = colors.TEXT.WEAK
69
+ ctx.fillStyle = lineColor
69
70
  for (const m of markers) {
70
71
  const lineRect = createHorizontalLineRect(m.lineStartX, m.lineEndX, m.y, dpr)
71
72
  if (lineRect) {
@@ -84,7 +85,7 @@ function drawAllMarkers(
84
85
  // ========== 阶段3:批量绘制所有文字(同一 font/baseline/fillStyle)==========
85
86
  setCanvasFont(ctx, MARKER_FONT)
86
87
  ctx.textBaseline = 'middle'
87
- ctx.fillStyle = colors.PRICE.NEUTRAL
88
+ ctx.fillStyle = textColor
88
89
 
89
90
  for (const m of markers) {
90
91
  ctx.textAlign = m.drawLeft ? 'right' : 'left'
@@ -108,7 +109,7 @@ export function createExtremaMarkersRendererPlugin(): RendererPlugin {
108
109
 
109
110
  draw(context: RenderContext) {
110
111
  const { ctx, pane, data, range, scrollLeft, dpr, paneWidth, kLineCenters } = context
111
- const colors = getColors(context.theme)
112
+ const colors = resolveThemeColors(context.theme, context.isAsiaMarket, context.colorPresetSettings)
112
113
  const klineData = data as KLineData[]
113
114
  if (!klineData.length) return
114
115
  if (pane.role !== 'price') return
@@ -150,9 +151,9 @@ export function createExtremaMarkersRendererPlugin(): RendererPlugin {
150
151
  price: max,
151
152
  y: pane.yAxis.priceToY(max),
152
153
  style: {
153
- bgColor: colors.LAST_PRICE_LABEL.BG,
154
- borderColor: colors.PRICE.LAST_PRICE,
155
- textColor: colors.PRICE.LAST_PRICE,
154
+ bgColor: colors.lastPriceLabel.bg,
155
+ borderColor: colors.price.lastPrice,
156
+ textColor: colors.price.lastPrice,
156
157
  }
157
158
  })
158
159
 
@@ -161,9 +162,9 @@ export function createExtremaMarkersRendererPlugin(): RendererPlugin {
161
162
  price: min,
162
163
  y: pane.yAxis.priceToY(min),
163
164
  style: {
164
- bgColor: colors.LAST_PRICE_LABEL.BG,
165
- borderColor: colors.PRICE.LAST_PRICE,
166
- textColor: colors.PRICE.LAST_PRICE,
165
+ bgColor: colors.lastPriceLabel.bg,
166
+ borderColor: colors.price.lastPrice,
167
+ textColor: colors.price.lastPrice,
167
168
  }
168
169
  })
169
170
 
@@ -193,7 +194,7 @@ export function createExtremaMarkersRendererPlugin(): RendererPlugin {
193
194
  // 批量绘制所有 markers
194
195
  ctx.save()
195
196
  ctx.translate(-scrollLeft, 0)
196
- drawAllMarkers(ctx, markers, dpr, colors)
197
+ drawAllMarkers(ctx, markers, dpr, colors.text.weak, colors.text.primary)
197
198
  ctx.restore()
198
199
  },
199
200
  }
@@ -3,7 +3,7 @@ import { RENDERER_PRIORITY, GLOBAL_PANE_ID } from '../../plugin'
3
3
  import type { KLineData } from '../../types/price'
4
4
  import { createHorizontalLineRect, createVerticalLineRect } from '../draw/pixelAlign'
5
5
  import { findMonthBoundaries } from '../../utils/dateFormat'
6
- import { getColors } from '../theme/colors'
6
+ import { resolveThemeColors } from '../../tokens'
7
7
  import { calculateTickPositions, calculateValueTickPositions, type ScaleType } from '../utils/tickPosition'
8
8
 
9
9
  /**
@@ -22,13 +22,13 @@ export function createGridLinesRendererPlugin(): RendererPlugin {
22
22
 
23
23
  draw(context: RenderContext) {
24
24
  const { ctx, pane, data, range, scrollLeft, kWidth, dpr, kLinePositions, settings } = context
25
- const colors = getColors(context.theme)
25
+ const colors = resolveThemeColors(context.theme, context.isAsiaMarket, context.colorPresetSettings)
26
26
  const klineData = data as KLineData[]
27
27
  if (!klineData.length) return
28
28
  if (settings?.showGridLines === false) return
29
29
 
30
30
  ctx.save()
31
- ctx.fillStyle = colors.GRID.HORIZONTAL
31
+ ctx.fillStyle = colors.gridMajor
32
32
  ctx.translate(-scrollLeft, 0)
33
33
 
34
34
  const plotWidth = ctx.canvas.width / dpr
@@ -1,7 +1,7 @@
1
1
  import type { RendererPlugin, RenderContext } from '../../plugin'
2
2
  import { RENDERER_PRIORITY } from '../../plugin'
3
3
  import type { KLineData } from '../../types/price'
4
- import { getColors } from '../theme/colors'
4
+ import { resolveThemeColors } from '../../tokens'
5
5
 
6
6
  function getLastPriceInfo(context: RenderContext) {
7
7
  const { pane, data } = context
@@ -35,7 +35,7 @@ export function createLastPriceLabelRegistrarPlugin(): RendererPlugin {
35
35
  priority: RENDERER_PRIORITY.LAST_PRICE_LABEL,
36
36
 
37
37
  draw(context: RenderContext) {
38
- const colors = getColors(context.theme)
38
+ const colors = resolveThemeColors(context.theme, context.isAsiaMarket, context.colorPresetSettings)
39
39
  const info = getLastPriceInfo(context)
40
40
  if (!info) return
41
41
 
@@ -46,9 +46,9 @@ export function createLastPriceLabelRegistrarPlugin(): RendererPlugin {
46
46
  y: info.y,
47
47
  type: 'lastPrice',
48
48
  style: {
49
- bgColor: colors.LAST_PRICE_LABEL.BG,
50
- borderColor: colors.PRICE.LAST_PRICE,
51
- textColor: colors.PRICE.LAST_PRICE,
49
+ bgColor: colors.lastPriceLabel.bg,
50
+ borderColor: colors.price.lastPrice,
51
+ textColor: colors.price.lastPrice,
52
52
  }
53
53
  })
54
54
  },
@@ -69,7 +69,7 @@ export function createLastPriceLineRendererPlugin(): RendererPlugin {
69
69
 
70
70
  draw(context: RenderContext) {
71
71
  const { ctx, scrollLeft, dpr, kLinePositions, paneWidth } = context
72
- const colors = getColors(context.theme)
72
+ const colors = resolveThemeColors(context.theme, context.isAsiaMarket, context.colorPresetSettings)
73
73
  const info = getLastPriceInfo(context)
74
74
  if (!info) return
75
75
 
@@ -81,7 +81,7 @@ export function createLastPriceLineRendererPlugin(): RendererPlugin {
81
81
  const startX = kLinePositions[0] ?? 0
82
82
  const endX = paneWidth + scrollLeft
83
83
 
84
- ctx.strokeStyle = colors.PRICE.LAST_PRICE
84
+ ctx.strokeStyle = colors.price.lastPrice
85
85
  ctx.lineWidth = 1
86
86
  ctx.setLineDash([4, 3])
87
87
  ctx.beginPath()
@@ -1,6 +1,6 @@
1
1
  import type { RendererPluginWithHost, RenderContext, PluginHost } from '../../plugin'
2
2
  import { RENDERER_PRIORITY } from '../../plugin'
3
- import { getColors } from '../theme/colors'
3
+ import { resolveThemeColors } from '../../tokens'
4
4
  import { getFont, setCanvasFont } from '../theme/fonts'
5
5
  import { SUB_PANE_INDICATOR_CONFIGS } from './Indicator/subPaneConfig'
6
6
  import type { SubIndicatorType } from './Indicator'
@@ -63,7 +63,7 @@ export function createPaneTitleRendererPlugin(options: PaneTitleOptions): Render
63
63
 
64
64
  draw(context: RenderContext) {
65
65
  const { overlayCtx, pane, paneWidth } = context
66
- const colors = getColors(context.theme)
66
+ const colors = resolveThemeColors(context.theme, context.isAsiaMarket, context.colorPresetSettings)
67
67
  if (pane.id !== currentOptions.paneId || !overlayCtx) return
68
68
 
69
69
  const fontSize = 12
@@ -85,13 +85,13 @@ export function createPaneTitleRendererPlugin(options: PaneTitleOptions): Render
85
85
  if (titleInfo) {
86
86
  let currentX = x
87
87
 
88
- overlayCtx.fillStyle = colors.TEXT.PRIMARY
88
+ overlayCtx.fillStyle = colors.text.primary
89
89
  overlayCtx.fillText(titleInfo.name, currentX, y)
90
90
  currentX += measureTextWidth(overlayCtx, titleInfo.name)
91
91
 
92
92
  if (titleInfo.params && titleInfo.params.length > 0) {
93
93
  const paramText = `(${titleInfo.params.join(',')})`
94
- overlayCtx.fillStyle = colors.TEXT.TERTIARY
94
+ overlayCtx.fillStyle = colors.text.tertiary
95
95
  overlayCtx.fillText(paramText, currentX, y)
96
96
  currentX += measureTextWidth(overlayCtx, paramText) + gap
97
97
  } else {
@@ -107,12 +107,12 @@ export function createPaneTitleRendererPlugin(options: PaneTitleOptions): Render
107
107
  }
108
108
  }
109
109
  } else {
110
- overlayCtx.fillStyle = colors.TEXT.PRIMARY
110
+ overlayCtx.fillStyle = colors.text.primary
111
111
  overlayCtx.fillText(currentOptions.title, x, y)
112
112
 
113
113
  if (currentOptions.description) {
114
114
  const titleWidth = measureTextWidth(overlayCtx, currentOptions.title)
115
- overlayCtx.fillStyle = colors.TEXT.WEAK
115
+ overlayCtx.fillStyle = colors.text.weak
116
116
  overlayCtx.fillText(` - ${currentOptions.description}`, x + titleWidth, y)
117
117
  }
118
118
  }
@@ -2,7 +2,7 @@ import type { RendererPluginWithHost, RenderContext, PluginHost, BaseIndicatorSt
2
2
  import { RENDERER_PRIORITY } from '../../plugin'
3
3
  import { createIndicatorStateKey } from '../../plugin/stateKeys'
4
4
  import type { KLineData } from '../../types/price'
5
- import { getColors, type VolumeColors } from '../theme/colors'
5
+ import { resolveThemeColors } from '../../tokens'
6
6
  import { Indicator } from '../indicators/indicatorDefinitionRegistry'
7
7
  import { resolveStateKey } from '../indicators/indicatorMetadata'
8
8
  import type { IndicatorScheduler } from '../indicators/scheduler'
@@ -61,7 +61,10 @@ export function createVolumeRendererPlugin(options: VolumeRendererOptions = {}):
61
61
 
62
62
  draw(context: RenderContext) {
63
63
  const { ctx, pane, data, range, dpr } = context
64
- const colors = getColors(context.theme)
64
+ const colors = resolveThemeColors(context.theme, context.isAsiaMarket, context.colorPresetSettings)
65
+ const upVolume = colors.volumeUp
66
+ const downVolume = colors.volumeDown
67
+ const neutralVolume = colors.candleDojiBorder
65
68
  const klineData = data as KLineData[]
66
69
  if (!klineData.length) return
67
70
 
@@ -124,13 +127,13 @@ export function createVolumeRendererPlugin(options: VolumeRendererOptions = {}):
124
127
  const finalH = rawH <= 0 ? minBarHPx : Math.max(rawH, minBarHPx)
125
128
  const finalY = rawH <= 0 ? alignedBaseY - minBarHPx : alignedBaseY - finalH
126
129
 
127
- const color = judgeColor(item, colors.VOLUME)
130
+ const color = judgeColor(item, upVolume, downVolume, neutralVolume)
128
131
 
129
132
  let buf: Float32Array
130
133
  let idx: number
131
- if (color === colors.VOLUME.UP) {
134
+ if (color === upVolume) {
132
135
  buf = upBuf; idx = upCount++
133
- } else if (color === colors.VOLUME.DOWN) {
136
+ } else if (color === downVolume) {
134
137
  buf = downBuf; idx = downCount++
135
138
  } else {
136
139
  buf = neutralBuf; idx = neutralCount++
@@ -142,9 +145,9 @@ export function createVolumeRendererPlugin(options: VolumeRendererOptions = {}):
142
145
  buf[off + 3] = finalH
143
146
  }
144
147
 
145
- const usedWebGL = drawVolumeWithWebGL(context, upBuf, upCount, downBuf, downCount, neutralBuf, neutralCount, colors.VOLUME)
148
+ const usedWebGL = drawVolumeWithWebGL(context, upBuf, upCount, downBuf, downCount, neutralBuf, neutralCount, upVolume, downVolume, neutralVolume)
146
149
  if (!usedWebGL) {
147
- drawVolumeWithCanvas2D(ctx, context.scrollLeft, upBuf, upCount, downBuf, downCount, neutralBuf, neutralCount, colors.VOLUME)
150
+ drawVolumeWithCanvas2D(ctx, context.scrollLeft, upBuf, upCount, downBuf, downCount, neutralBuf, neutralCount, upVolume, downVolume, neutralVolume)
148
151
  } else {
149
152
  compositeVolumeWebGL(ctx, context)
150
153
  }
@@ -157,7 +160,7 @@ function drawVolumeWithWebGL(
157
160
  upBuf: Float32Array, upCount: number,
158
161
  downBuf: Float32Array, downCount: number,
159
162
  neutralBuf: Float32Array, neutralCount: number,
160
- volumeColors: VolumeColors
163
+ upColor: string, downColor: string, neutralColor: string
161
164
  ): boolean {
162
165
  if (context.settings?.enableWebGLRendering === false) return false
163
166
  const surface = context.candleWebGLSurface
@@ -165,9 +168,9 @@ function drawVolumeWithWebGL(
165
168
 
166
169
  surface.clear()
167
170
 
168
- const ok1 = upCount === 0 || surface.drawRectBuffer(upBuf.subarray(0, upCount * 4), upCount, volumeColors.UP, context.scrollLeft)
169
- const ok2 = downCount === 0 || surface.drawRectBuffer(downBuf.subarray(0, downCount * 4), downCount, volumeColors.DOWN, context.scrollLeft)
170
- const ok3 = neutralCount === 0 || surface.drawRectBuffer(neutralBuf.subarray(0, neutralCount * 4), neutralCount, volumeColors.NEUTRAL, context.scrollLeft)
171
+ const ok1 = upCount === 0 || surface.drawRectBuffer(upBuf.subarray(0, upCount * 4), upCount, upColor, context.scrollLeft)
172
+ const ok2 = downCount === 0 || surface.drawRectBuffer(downBuf.subarray(0, downCount * 4), downCount, downColor, context.scrollLeft)
173
+ const ok3 = neutralCount === 0 || surface.drawRectBuffer(neutralBuf.subarray(0, neutralCount * 4), neutralCount, neutralColor, context.scrollLeft)
171
174
 
172
175
  return ok1 && ok2 && ok3
173
176
  }
@@ -178,24 +181,24 @@ function drawVolumeWithCanvas2D(
178
181
  upBuf: Float32Array, upCount: number,
179
182
  downBuf: Float32Array, downCount: number,
180
183
  neutralBuf: Float32Array, neutralCount: number,
181
- volumeColors: VolumeColors
184
+ upColor: string, downColor: string, neutralColor: string
182
185
  ): void {
183
186
  ctx.save()
184
187
  ctx.translate(-scrollLeft, 0)
185
188
 
186
- ctx.fillStyle = volumeColors.UP
189
+ ctx.fillStyle = upColor
187
190
  for (let i = 0; i < upCount; i++) {
188
191
  const off = i * 4
189
192
  ctx.fillRect(upBuf[off], upBuf[off + 1], upBuf[off + 2], upBuf[off + 3])
190
193
  }
191
194
 
192
- ctx.fillStyle = volumeColors.DOWN
195
+ ctx.fillStyle = downColor
193
196
  for (let i = 0; i < downCount; i++) {
194
197
  const off = i * 4
195
198
  ctx.fillRect(downBuf[off], downBuf[off + 1], downBuf[off + 2], downBuf[off + 3])
196
199
  }
197
200
 
198
- ctx.fillStyle = volumeColors.NEUTRAL
201
+ ctx.fillStyle = neutralColor
199
202
  for (let i = 0; i < neutralCount; i++) {
200
203
  const off = i * 4
201
204
  ctx.fillRect(neutralBuf[off], neutralBuf[off + 1], neutralBuf[off + 2], neutralBuf[off + 3])
@@ -212,15 +215,15 @@ function compositeVolumeWebGL(ctx: CanvasRenderingContext2D, context: RenderCont
212
215
  }
213
216
 
214
217
  /**
215
- * 判断成交量柱子颜色(使用 MACD 配色风格)
218
+ * 判断成交量柱子颜色
216
219
  */
217
- function judgeColor(dayData: KLineData, volumeColors: VolumeColors): string {
220
+ function judgeColor(dayData: KLineData, upColor: string, downColor: string, neutralColor: string): string {
218
221
  if (dayData.close > dayData.open) {
219
- return volumeColors.UP
222
+ return upColor
220
223
  } else if (dayData.close < dayData.open) {
221
- return volumeColors.DOWN
224
+ return downColor
222
225
  } else {
223
- return volumeColors.NEUTRAL
226
+ return neutralColor
224
227
  }
225
228
  }
226
229
 
@@ -1,4 +1,4 @@
1
- import { getColors } from '../theme/colors'
1
+ import { resolveThemeColors } from '../../tokens'
2
2
  import type { RendererPlugin, RenderContext } from '../../plugin'
3
3
  import { RENDERER_PRIORITY } from '../../plugin'
4
4
  import type { KLineData } from '../../types/price'
@@ -26,7 +26,7 @@ export function createTimeAxisRendererPlugin(options: {
26
26
 
27
27
  draw(context: RenderContext) {
28
28
  const { ctx, data, range, scrollLeft, kWidth, kGap, dpr, paneWidth } = context
29
- const colors = getColors(context.theme)
29
+ const colors = resolveThemeColors(context.theme, context.isAsiaMarket, context.colorPresetSettings)
30
30
  const klineData = data as KLineData[]
31
31
 
32
32
  // 时间轴绘制到传入的 ctx
@@ -52,11 +52,11 @@ export function createTimeAxisRendererPlugin(options: {
52
52
  startIndex: range.start,
53
53
  endIndex: range.end,
54
54
  dpr,
55
- textColor: colors.TEXT.SECONDARY,
56
- lineColor: colors.BORDER.DARK,
55
+ textColor: colors.text.secondary,
56
+ lineColor: colors.border.dark,
57
57
  drawTopBorder: false,
58
58
  drawBottomBorder: false,
59
- })
59
+ }, context.theme, context.isAsiaMarket, context.colorPresetSettings)
60
60
 
61
61
  // 绘制来自 xAxisRanges 的时间范围带(先于标签绘制)
62
62
  if (context.xAxisRanges) {
@@ -87,9 +87,9 @@ export function createTimeAxisRendererPlugin(options: {
87
87
  timestamp: k.timestamp,
88
88
  dpr,
89
89
  fontSize: 12,
90
- bgColor: colors.CROSSHAIR.LABEL_BG,
91
- textColor: colors.CROSSHAIR.LABEL_TEXT,
92
- })
90
+ bgColor: colors.crosshairLabelBg,
91
+ textColor: colors.crosshairLabelText,
92
+ }, context.theme, context.isAsiaMarket, context.colorPresetSettings)
93
93
  }
94
94
  }
95
95
 
@@ -112,7 +112,7 @@ export function createTimeAxisRendererPlugin(options: {
112
112
  fontSize: 12,
113
113
  bgColor: label.style?.bgColor,
114
114
  textColor: label.style?.textColor,
115
- })
115
+ }, context.theme, context.isAsiaMarket, context.colorPresetSettings)
116
116
  }
117
117
  }
118
118
  }
@@ -118,6 +118,8 @@ const UNIT_QUAD = new Float32Array([
118
118
  1, 1,
119
119
  ])
120
120
 
121
+ const MITER_DOT_MIN = 0.5
122
+
121
123
  export class CandleWebGLSurface {
122
124
  private shared: SharedWebGLSurface
123
125
  private handles: RectWebGLHandles | null = null
@@ -375,6 +377,8 @@ export class LineWebGLSurface {
375
377
  mode: number
376
378
  firstVertex: number
377
379
  pointCount: number
380
+ vertices?: Float32Array
381
+ points?: Array<{ x: number; y: number }>
378
382
  }
379
383
 
380
384
  const gl = this.shared.getGL()
@@ -383,6 +387,7 @@ export class LineWebGLSurface {
383
387
 
384
388
  const drawCmds: DrawCmd[] = []
385
389
  let totalFloats = 0
390
+ let hasNativeLines = false
386
391
 
387
392
  for (const line of lines) {
388
393
  if (line.points.length < 2) return false
@@ -390,9 +395,28 @@ export class LineWebGLSurface {
390
395
  const colorValue = parseColor(line.color)
391
396
  if (!colorValue) return false
392
397
 
398
+ if (line.width <= 1) {
399
+ hasNativeLines = true
400
+ drawCmds.push({
401
+ colorValue,
402
+ mode: gl.LINE_STRIP,
403
+ firstVertex: totalFloats / 2,
404
+ pointCount: line.points.length,
405
+ points: line.points,
406
+ })
407
+ totalFloats += line.points.length * 2
408
+ continue
409
+ }
410
+
393
411
  const geometry = this.getLineGeometry(line)
394
412
  if (!geometry) return false
395
- drawCmds.push({ colorValue, mode: gl.TRIANGLES, firstVertex: totalFloats / 2, pointCount: geometry.vertexCount })
413
+ drawCmds.push({
414
+ colorValue,
415
+ mode: gl.TRIANGLES,
416
+ firstVertex: totalFloats / 2,
417
+ pointCount: geometry.vertexCount,
418
+ vertices: geometry.vertices,
419
+ })
396
420
  totalFloats += geometry.vertices.length
397
421
  }
398
422
 
@@ -400,10 +424,19 @@ export class LineWebGLSurface {
400
424
  this.lineScratch = new Float32Array(nextBufferFloatCapacity(totalFloats))
401
425
  }
402
426
  let floatOffset = 0
403
- for (const line of lines) {
404
- const vertices = this.getLineGeometry(line)!.vertices
405
- this.lineScratch.set(vertices, floatOffset)
406
- floatOffset += vertices.length
427
+ for (const cmd of drawCmds) {
428
+ if (cmd.vertices) {
429
+ this.lineScratch.set(cmd.vertices, floatOffset)
430
+ floatOffset += cmd.vertices.length
431
+ continue
432
+ }
433
+
434
+ const points = cmd.points
435
+ if (!points) return false
436
+ for (const point of points) {
437
+ this.lineScratch[floatOffset++] = point.x
438
+ this.lineScratch[floatOffset++] = point.y
439
+ }
407
440
  }
408
441
 
409
442
  const msaaRender = this.beginMsaaRender(gl, region)
@@ -423,6 +456,9 @@ export class LineWebGLSurface {
423
456
 
424
457
  gl.uniform2f(handles.basic.resolutionLocation, this.logicalWidth, this.logicalHeight)
425
458
  gl.uniform1f(handles.basic.scrollXLocation, scrollLeft)
459
+ if (hasNativeLines) {
460
+ gl.lineWidth(1)
461
+ }
426
462
 
427
463
  for (const cmd of drawCmds) {
428
464
  gl.uniform4f(handles.basic.colorLocation, cmd.colorValue[0], cmd.colorValue[1], cmd.colorValue[2], cmd.colorValue[3])
@@ -793,7 +829,7 @@ function buildJoinedPolylineGeometry(points: Array<{ x: number; y: number }>, ha
793
829
  miterNX *= invMiter
794
830
  miterNY *= invMiter
795
831
  const dot = miterNX * currNormal.nx + miterNY * currNormal.ny
796
- const scale = 1 / Math.max(0.2, Math.abs(dot))
832
+ const scale = 1 / Math.max(MITER_DOT_MIN, Math.abs(dot))
797
833
  miterNX *= scale
798
834
  miterNY *= scale
799
835
  } else {
@@ -823,7 +859,7 @@ function buildJoinedPolylineGeometry(points: Array<{ x: number; y: number }>, ha
823
859
  nextMiterNX *= invMiter
824
860
  nextMiterNY *= invMiter
825
861
  const dot = nextMiterNX * nextNormal.nx + nextMiterNY * nextNormal.ny
826
- const scale = 1 / Math.max(0.2, Math.abs(dot))
862
+ const scale = 1 / Math.max(MITER_DOT_MIN, Math.abs(dot))
827
863
  nextMiterNX *= scale
828
864
  nextMiterNY *= scale
829
865
  } else {
@@ -2,7 +2,8 @@ import type { RendererPlugin, RenderContext } from '../../plugin'
2
2
  import { RENDERER_PRIORITY, GLOBAL_PANE_ID } from '../../plugin'
3
3
  import { drawCrosshairPriceLabel, drawAxisPriceLabel } from '../../utils/kLineDraw/axis'
4
4
  import { drawScaleTicks } from '../renderers/Indicator/scale/indicator_scale'
5
- import { getColors } from '../theme/colors'
5
+ import { resolveThemeColors } from '../../tokens'
6
+
6
7
  import type { KLineData } from '../../types/price'
7
8
  import type { ScaleType } from '../utils/tickPosition'
8
9
 
@@ -25,7 +26,7 @@ export function createYAxisRendererPlugin(options: {
25
26
 
26
27
  draw(context: RenderContext) {
27
28
  const { ctx, pane, dpr, yAxisCtx, data } = context
28
- const colors = getColors(context.theme)
29
+ const tokenColors = resolveThemeColors(context.theme, context.isAsiaMarket, context.colorPresetSettings)
29
30
  const scaleType = pane.yAxis.getScaleType()
30
31
 
31
32
  const targetCtx = yAxisCtx || ctx
@@ -34,7 +35,7 @@ export function createYAxisRendererPlugin(options: {
34
35
 
35
36
  if (pane.capabilities.showPriceAxisTicks) {
36
37
  drawScaleTicks({
37
- colors,
38
+ tickColor: tokenColors.text.secondary,
38
39
  ctx: targetCtx,
39
40
  dpr,
40
41
  axisWidth,
@@ -80,7 +81,7 @@ export function createYAxisRendererPlugin(options: {
80
81
  borderColor: label.style?.borderColor,
81
82
  textColor: label.style?.textColor ?? '#ffffff',
82
83
  fontSize: isLastPrice ? 12 : 11,
83
- })
84
+ }, context.theme, context.isAsiaMarket, context.colorPresetSettings)
84
85
  }
85
86
  }
86
87
 
@@ -98,7 +99,7 @@ export function createYAxisRendererPlugin(options: {
98
99
  fontSize: 12,
99
100
  priceOffset: 0,
100
101
  price: crosshair.price,
101
- })
102
+ }, context.theme, context.isAsiaMarket, context.colorPresetSettings)
102
103
  }
103
104
  },
104
105
  }
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './reactivity'
2
2
  export * from './controllers'
3
3
  export { VERSION } from './version'
4
+ export * from './tokens'
@@ -309,7 +309,11 @@ export interface RenderContext {
309
309
  /** 需要在X轴上绘制的范围带列表(由绘图渲染器填充,先于标签绘制) */
310
310
  xAxisRanges?: XAxisRange[]
311
311
  /** 当前主题 */
312
- theme: import('../engine/theme/colors').ChartTheme
312
+ theme: 'light' | 'dark'
313
+ /** 亚洲市场惯例(红涨绿跌);为 true 时自动交换所有 bull/bear 颜色 */
314
+ isAsiaMarket?: boolean
315
+ /** 用户颜色预设覆盖项 */
316
+ colorPresetSettings?: import('../tokens').ColorPresetSettings
313
317
  }
314
318
 
315
319
  export type DrawingAnchor = {