@363045841yyt/klinechart-core 0.7.5 → 0.7.7

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 (235) hide show
  1. package/README.md +8 -8
  2. package/README.zh-CN.md +8 -8
  3. package/dist/config/chartSettings.d.ts +27 -2
  4. package/dist/config/chartSettings.d.ts.map +1 -1
  5. package/dist/config/chartSettings.js +6 -0
  6. package/dist/config/chartSettings.js.map +1 -1
  7. package/dist/controllers/createChartController.d.ts.map +1 -1
  8. package/dist/controllers/createChartController.js +145 -21
  9. package/dist/controllers/createChartController.js.map +1 -1
  10. package/dist/controllers/index.d.ts +9 -1
  11. package/dist/controllers/index.d.ts.map +1 -1
  12. package/dist/controllers/index.js +9 -0
  13. package/dist/controllers/index.js.map +1 -1
  14. package/dist/controllers/types.d.ts +65 -8
  15. package/dist/controllers/types.d.ts.map +1 -1
  16. package/dist/engine/chart.d.ts +2 -12
  17. package/dist/engine/chart.d.ts.map +1 -1
  18. package/dist/engine/chart.js +32 -31
  19. package/dist/engine/chart.js.map +1 -1
  20. package/dist/engine/controller/interaction.d.ts +1 -1
  21. package/dist/engine/controller/interaction.d.ts.map +1 -1
  22. package/dist/engine/controller/interaction.js +10 -2
  23. package/dist/engine/controller/interaction.js.map +1 -1
  24. package/dist/engine/draw/pixelAlign.d.ts.map +1 -1
  25. package/dist/engine/draw/pixelAlign.js.map +1 -1
  26. package/dist/engine/drawing/interaction.d.ts +3 -3
  27. package/dist/engine/drawing/interaction.d.ts.map +1 -1
  28. package/dist/engine/drawing/interaction.js +38 -46
  29. package/dist/engine/drawing/interaction.js.map +1 -1
  30. package/dist/engine/drawing/plugin.js +1 -1
  31. package/dist/engine/drawing/plugin.js.map +1 -1
  32. package/dist/engine/renderers/Indicator/atr.d.ts.map +1 -1
  33. package/dist/engine/renderers/Indicator/atr.js +7 -4
  34. package/dist/engine/renderers/Indicator/atr.js.map +1 -1
  35. package/dist/engine/renderers/Indicator/boll.js +12 -12
  36. package/dist/engine/renderers/Indicator/boll.js.map +1 -1
  37. package/dist/engine/renderers/Indicator/cci.d.ts +1 -2
  38. package/dist/engine/renderers/Indicator/cci.d.ts.map +1 -1
  39. package/dist/engine/renderers/Indicator/cci.js +9 -9
  40. package/dist/engine/renderers/Indicator/cci.js.map +1 -1
  41. package/dist/engine/renderers/Indicator/ene.js +12 -12
  42. package/dist/engine/renderers/Indicator/ene.js.map +1 -1
  43. package/dist/engine/renderers/Indicator/expma.js +6 -6
  44. package/dist/engine/renderers/Indicator/expma.js.map +1 -1
  45. package/dist/engine/renderers/Indicator/fastk.d.ts +1 -2
  46. package/dist/engine/renderers/Indicator/fastk.d.ts.map +1 -1
  47. package/dist/engine/renderers/Indicator/fastk.js +7 -7
  48. package/dist/engine/renderers/Indicator/fastk.js.map +1 -1
  49. package/dist/engine/renderers/Indicator/kst.d.ts +1 -2
  50. package/dist/engine/renderers/Indicator/kst.d.ts.map +1 -1
  51. package/dist/engine/renderers/Indicator/kst.js +10 -10
  52. package/dist/engine/renderers/Indicator/kst.js.map +1 -1
  53. package/dist/engine/renderers/Indicator/ma.js +5 -5
  54. package/dist/engine/renderers/Indicator/ma.js.map +1 -1
  55. package/dist/engine/renderers/Indicator/macd.d.ts +1 -2
  56. package/dist/engine/renderers/Indicator/macd.d.ts.map +1 -1
  57. package/dist/engine/renderers/Indicator/macd.js +24 -24
  58. package/dist/engine/renderers/Indicator/macd.js.map +1 -1
  59. package/dist/engine/renderers/Indicator/macdLegend.js +6 -6
  60. package/dist/engine/renderers/Indicator/macdLegend.js.map +1 -1
  61. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js +16 -16
  62. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js.map +1 -1
  63. package/dist/engine/renderers/Indicator/mom.d.ts +1 -2
  64. package/dist/engine/renderers/Indicator/mom.d.ts.map +1 -1
  65. package/dist/engine/renderers/Indicator/mom.js +8 -8
  66. package/dist/engine/renderers/Indicator/mom.js.map +1 -1
  67. package/dist/engine/renderers/Indicator/rsi.d.ts +2 -3
  68. package/dist/engine/renderers/Indicator/rsi.d.ts.map +1 -1
  69. package/dist/engine/renderers/Indicator/rsi.js +15 -15
  70. package/dist/engine/renderers/Indicator/rsi.js.map +1 -1
  71. package/dist/engine/renderers/Indicator/scale/indicator_scale.d.ts +1 -2
  72. package/dist/engine/renderers/Indicator/scale/indicator_scale.d.ts.map +1 -1
  73. package/dist/engine/renderers/Indicator/scale/indicator_scale.js +5 -5
  74. package/dist/engine/renderers/Indicator/scale/indicator_scale.js.map +1 -1
  75. package/dist/engine/renderers/Indicator/stoch.d.ts +1 -2
  76. package/dist/engine/renderers/Indicator/stoch.d.ts.map +1 -1
  77. package/dist/engine/renderers/Indicator/stoch.js +10 -10
  78. package/dist/engine/renderers/Indicator/stoch.js.map +1 -1
  79. package/dist/engine/renderers/Indicator/structure.js +5 -5
  80. package/dist/engine/renderers/Indicator/structure.js.map +1 -1
  81. package/dist/engine/renderers/Indicator/wmsr.d.ts +1 -2
  82. package/dist/engine/renderers/Indicator/wmsr.d.ts.map +1 -1
  83. package/dist/engine/renderers/Indicator/wmsr.js +10 -10
  84. package/dist/engine/renderers/Indicator/wmsr.js.map +1 -1
  85. package/dist/engine/renderers/Indicator/zones.js +6 -6
  86. package/dist/engine/renderers/Indicator/zones.js.map +1 -1
  87. package/dist/engine/renderers/candle.d.ts +1 -1
  88. package/dist/engine/renderers/candle.d.ts.map +1 -1
  89. package/dist/engine/renderers/candle.js +21 -21
  90. package/dist/engine/renderers/candle.js.map +1 -1
  91. package/dist/engine/renderers/crosshair.js +3 -3
  92. package/dist/engine/renderers/crosshair.js.map +1 -1
  93. package/dist/engine/renderers/extremaMarkers.d.ts.map +1 -1
  94. package/dist/engine/renderers/extremaMarkers.js +12 -12
  95. package/dist/engine/renderers/extremaMarkers.js.map +1 -1
  96. package/dist/engine/renderers/gridLines.js +3 -3
  97. package/dist/engine/renderers/gridLines.js.map +1 -1
  98. package/dist/engine/renderers/lastPrice.js +7 -7
  99. package/dist/engine/renderers/lastPrice.js.map +1 -1
  100. package/dist/engine/renderers/paneTitle.d.ts +5 -24
  101. package/dist/engine/renderers/paneTitle.d.ts.map +1 -1
  102. package/dist/engine/renderers/paneTitle.js +16 -11
  103. package/dist/engine/renderers/paneTitle.js.map +1 -1
  104. package/dist/engine/renderers/subVolume.d.ts.map +1 -1
  105. package/dist/engine/renderers/subVolume.js +23 -20
  106. package/dist/engine/renderers/subVolume.js.map +1 -1
  107. package/dist/engine/renderers/timeAxis.js +9 -9
  108. package/dist/engine/renderers/timeAxis.js.map +1 -1
  109. package/dist/engine/renderers/webgl/candleSurface.d.ts +4 -4
  110. package/dist/engine/renderers/webgl/candleSurface.d.ts.map +1 -1
  111. package/dist/engine/renderers/webgl/candleSurface.js +72 -60
  112. package/dist/engine/renderers/webgl/candleSurface.js.map +1 -1
  113. package/dist/engine/renderers/yAxis.d.ts.map +1 -1
  114. package/dist/engine/renderers/yAxis.js +5 -5
  115. package/dist/engine/renderers/yAxis.js.map +1 -1
  116. package/dist/engine/subPaneManager.d.ts +2 -0
  117. package/dist/engine/subPaneManager.d.ts.map +1 -1
  118. package/dist/engine/subPaneManager.js +25 -1
  119. package/dist/engine/subPaneManager.js.map +1 -1
  120. package/dist/index.d.ts +1 -0
  121. package/dist/index.d.ts.map +1 -1
  122. package/dist/index.js +1 -0
  123. package/dist/index.js.map +1 -1
  124. package/dist/plugin/types.d.ts +5 -1
  125. package/dist/plugin/types.d.ts.map +1 -1
  126. package/dist/plugin/types.js.map +1 -1
  127. package/dist/semantic/controller.d.ts +1 -2
  128. package/dist/semantic/controller.d.ts.map +1 -1
  129. package/dist/semantic/index.d.ts +1 -1
  130. package/dist/semantic/index.d.ts.map +1 -1
  131. package/dist/tokens/colorPresetSettings.d.ts +15 -0
  132. package/dist/tokens/colorPresetSettings.d.ts.map +1 -0
  133. package/dist/tokens/colorPresetSettings.js +65 -0
  134. package/dist/tokens/colorPresetSettings.js.map +1 -0
  135. package/dist/tokens/index.d.ts +17 -0
  136. package/dist/tokens/index.d.ts.map +1 -0
  137. package/dist/tokens/index.js +16 -0
  138. package/dist/tokens/index.js.map +1 -0
  139. package/dist/tokens/mergeTheme.d.ts +17 -0
  140. package/dist/tokens/mergeTheme.d.ts.map +1 -0
  141. package/dist/tokens/mergeTheme.js +43 -0
  142. package/dist/tokens/mergeTheme.js.map +1 -0
  143. package/dist/tokens/theme-china.d.ts +45 -0
  144. package/dist/tokens/theme-china.d.ts.map +1 -0
  145. package/dist/tokens/theme-china.js +116 -0
  146. package/dist/tokens/theme-china.js.map +1 -0
  147. package/dist/tokens/theme-dark.d.ts +21 -0
  148. package/dist/tokens/theme-dark.d.ts.map +1 -0
  149. package/dist/tokens/theme-dark.js +228 -0
  150. package/dist/tokens/theme-dark.js.map +1 -0
  151. package/dist/tokens/theme-light.d.ts +23 -0
  152. package/dist/tokens/theme-light.d.ts.map +1 -0
  153. package/dist/tokens/theme-light.js +234 -0
  154. package/dist/tokens/theme-light.js.map +1 -0
  155. package/dist/tokens/themeToCssVars.d.ts +74 -0
  156. package/dist/tokens/themeToCssVars.d.ts.map +1 -0
  157. package/dist/tokens/themeToCssVars.js +108 -0
  158. package/dist/tokens/themeToCssVars.js.map +1 -0
  159. package/dist/tokens/types.d.ts +335 -0
  160. package/dist/tokens/types.d.ts.map +1 -0
  161. package/dist/tokens/types.js +20 -0
  162. package/dist/tokens/types.js.map +1 -0
  163. package/dist/utils/kLineDraw/axis.d.ts +8 -7
  164. package/dist/utils/kLineDraw/axis.d.ts.map +1 -1
  165. package/dist/utils/kLineDraw/axis.js +24 -24
  166. package/dist/utils/kLineDraw/axis.js.map +1 -1
  167. package/dist/version.d.ts +1 -1
  168. package/dist/version.js +1 -1
  169. package/package.json +6 -6
  170. package/src/config/chartSettings.ts +11 -2
  171. package/src/controllers/createChartController.ts +158 -29
  172. package/src/controllers/index.ts +33 -0
  173. package/src/controllers/types.ts +79 -8
  174. package/src/engine/chart.ts +32 -37
  175. package/src/engine/controller/interaction.ts +9 -2
  176. package/src/engine/draw/pixelAlign.ts +0 -2
  177. package/src/engine/drawing/interaction.ts +38 -47
  178. package/src/engine/drawing/plugin.ts +1 -1
  179. package/src/engine/renderers/Indicator/atr.ts +7 -3
  180. package/src/engine/renderers/Indicator/boll.ts +12 -12
  181. package/src/engine/renderers/Indicator/cci.ts +11 -10
  182. package/src/engine/renderers/Indicator/ene.ts +12 -12
  183. package/src/engine/renderers/Indicator/expma.ts +6 -6
  184. package/src/engine/renderers/Indicator/fastk.ts +9 -8
  185. package/src/engine/renderers/Indicator/kst.ts +12 -11
  186. package/src/engine/renderers/Indicator/ma.ts +5 -5
  187. package/src/engine/renderers/Indicator/macd.ts +27 -25
  188. package/src/engine/renderers/Indicator/macdLegend.ts +6 -6
  189. package/src/engine/renderers/Indicator/mainIndicatorLegend.ts +16 -16
  190. package/src/engine/renderers/Indicator/mom.ts +11 -10
  191. package/src/engine/renderers/Indicator/rsi.ts +18 -15
  192. package/src/engine/renderers/Indicator/scale/indicator_scale.ts +6 -6
  193. package/src/engine/renderers/Indicator/stoch.ts +12 -11
  194. package/src/engine/renderers/Indicator/structure.ts +5 -5
  195. package/src/engine/renderers/Indicator/wmsr.ts +13 -12
  196. package/src/engine/renderers/Indicator/zones.ts +7 -7
  197. package/src/engine/renderers/candle.ts +21 -21
  198. package/src/engine/renderers/crosshair.ts +3 -3
  199. package/src/engine/renderers/extremaMarkers.ts +13 -12
  200. package/src/engine/renderers/gridLines.ts +3 -3
  201. package/src/engine/renderers/lastPrice.ts +7 -7
  202. package/src/engine/renderers/paneTitle.ts +22 -31
  203. package/src/engine/renderers/subVolume.ts +23 -20
  204. package/src/engine/renderers/timeAxis.ts +9 -9
  205. package/src/engine/renderers/webgl/candleSurface.ts +80 -60
  206. package/src/engine/renderers/yAxis.ts +6 -5
  207. package/src/engine/subPaneManager.ts +28 -1
  208. package/src/index.ts +1 -0
  209. package/src/plugin/types.ts +5 -1
  210. package/src/semantic/controller.ts +1 -1
  211. package/src/semantic/index.ts +1 -1
  212. package/src/tokens/__tests__/__snapshots__/baseline.test.ts.snap +393 -0
  213. package/src/tokens/__tests__/baseline.test.ts +183 -0
  214. package/src/tokens/__tests__/themeToCssVars.test.ts +175 -0
  215. package/src/tokens/__tests__/tokens.test.ts +215 -0
  216. package/src/tokens/colorPresetSettings.ts +128 -0
  217. package/src/tokens/index.ts +65 -0
  218. package/src/tokens/mergeTheme.ts +48 -0
  219. package/src/tokens/theme-china.ts +132 -0
  220. package/src/tokens/theme-dark.ts +244 -0
  221. package/src/tokens/theme-light.ts +250 -0
  222. package/src/tokens/themeToCssVars.ts +138 -0
  223. package/src/tokens/types.ts +394 -0
  224. package/src/utils/kLineDraw/axis.ts +31 -30
  225. package/src/version.ts +1 -1
  226. package/dist/engine/chart-store.d.ts +0 -75
  227. package/dist/engine/chart-store.d.ts.map +0 -1
  228. package/dist/engine/chart-store.js +0 -88
  229. package/dist/engine/chart-store.js.map +0 -1
  230. package/dist/engine/theme/colors.d.ts +0 -223
  231. package/dist/engine/theme/colors.d.ts.map +0 -1
  232. package/dist/engine/theme/colors.js +0 -375
  233. package/dist/engine/theme/colors.js.map +0 -1
  234. package/src/engine/chart-store.ts +0 -121
  235. package/src/engine/theme/colors.ts +0 -642
@@ -46,7 +46,7 @@ type LineWebGLHandles = {
46
46
  basic: BasicLineWebGLHandles
47
47
  }
48
48
 
49
- type LineMsaaTargets = {
49
+ type MsaaTargets = {
50
50
  samples: number
51
51
  widthPx: number
52
52
  heightPx: number
@@ -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
@@ -325,7 +327,7 @@ export class LineWebGLSurface {
325
327
  private fillScratch = new Float32Array(0)
326
328
  private lineScratch = new Float32Array(0)
327
329
  private region: WebGLRegion | null = null
328
- private msaaTargets: LineMsaaTargets | null = null
330
+ private msaaTargets: MsaaTargets | null = null
329
331
 
330
332
  // Geometry cache: 以 points 数组引用 + halfWidth 为 key,避免每帧重算法线/miter
331
333
  private geoCache = new WeakMap<Array<{ x: number; y: number }>, Map<number, { vertices: Float32Array; vertexCount: number }>>()
@@ -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,41 +395,52 @@ export class LineWebGLSurface {
390
395
  const colorValue = parseColor(line.color)
391
396
  if (!colorValue) return false
392
397
 
393
- if (line.width === 1) {
394
- const { vertexCount, vertices } = this.getThinLineVertices(line.points)
395
- drawCmds.push({ colorValue, mode: gl.LINE_STRIP, firstVertex: totalFloats / 2, pointCount: vertexCount })
396
- totalFloats += vertices.length
397
- } else {
398
- const geometry = this.getLineGeometry(line)
399
- if (!geometry) return false
400
- drawCmds.push({ colorValue, mode: gl.TRIANGLES, firstVertex: totalFloats / 2, pointCount: geometry.vertexCount })
401
- totalFloats += geometry.vertices.length
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
402
409
  }
410
+
411
+ const geometry = this.getLineGeometry(line)
412
+ if (!geometry) return false
413
+ drawCmds.push({
414
+ colorValue,
415
+ mode: gl.TRIANGLES,
416
+ firstVertex: totalFloats / 2,
417
+ pointCount: geometry.vertexCount,
418
+ vertices: geometry.vertices,
419
+ })
420
+ totalFloats += geometry.vertices.length
403
421
  }
404
422
 
405
423
  if (this.lineScratch.length < totalFloats) {
406
424
  this.lineScratch = new Float32Array(nextBufferFloatCapacity(totalFloats))
407
425
  }
408
426
  let floatOffset = 0
409
- for (const line of lines) {
410
- const vertices = line.width === 1
411
- ? this.getThinLineVertices(line.points).vertices
412
- : this.getLineGeometry(line)!.vertices
413
- this.lineScratch.set(vertices, floatOffset)
414
- 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
+ }
415
440
  }
416
441
 
417
- const physical = this.shared.getPhysicalRegion(region)
418
- const msaaTargets = physical ? this.ensureLineMsaaTargets(gl, physical) : null
419
- const useMsaa = msaaTargets !== null
420
-
421
- if (useMsaa) {
422
- gl.bindFramebuffer(gl.FRAMEBUFFER, msaaTargets.msaaFramebuffer)
423
- gl.viewport(0, 0, msaaTargets.widthPx, msaaTargets.heightPx)
424
- gl.disable(gl.SCISSOR_TEST)
425
- gl.clearColor(0, 0, 0, 0)
426
- gl.clear(gl.COLOR_BUFFER_BIT)
427
- } else if (!this.shared.bindRegion(region)) {
442
+ const msaaRender = this.beginMsaaRender(gl, region)
443
+ if (!msaaRender && !this.shared.bindRegion(region)) {
428
444
  return false
429
445
  }
430
446
 
@@ -440,6 +456,9 @@ export class LineWebGLSurface {
440
456
 
441
457
  gl.uniform2f(handles.basic.resolutionLocation, this.logicalWidth, this.logicalHeight)
442
458
  gl.uniform1f(handles.basic.scrollXLocation, scrollLeft)
459
+ if (hasNativeLines) {
460
+ gl.lineWidth(1)
461
+ }
443
462
 
444
463
  for (const cmd of drawCmds) {
445
464
  gl.uniform4f(handles.basic.colorLocation, cmd.colorValue[0], cmd.colorValue[1], cmd.colorValue[2], cmd.colorValue[3])
@@ -448,36 +467,14 @@ export class LineWebGLSurface {
448
467
 
449
468
  gl.bindVertexArray(null)
450
469
 
451
- if (useMsaa && msaaTargets && physical) {
452
- this.resolveLineMsaaToSharedRegion(gl, msaaTargets, physical)
470
+ if (msaaRender) {
471
+ this.resolveMsaaToSharedRegion(gl, msaaRender.targets, msaaRender.physical)
453
472
  }
454
473
 
455
474
  gl.bindFramebuffer(gl.FRAMEBUFFER, null)
456
475
  return true
457
476
  }
458
477
 
459
- private getThinLineVertices(points: Array<{ x: number; y: number }>): { vertices: Float32Array; vertexCount: number } {
460
- let widthMap = this.geoCache.get(points)
461
- if (widthMap) {
462
- const cached = widthMap.get(0)
463
- if (cached) return cached
464
- } else {
465
- widthMap = new Map()
466
- this.geoCache.set(points, widthMap)
467
- }
468
-
469
- const vertexCount = points.length
470
- const vertices = new Float32Array(vertexCount * 2)
471
- let writeIndex = 0
472
- for (const point of points) {
473
- vertices[writeIndex++] = point.x
474
- vertices[writeIndex++] = point.y
475
- }
476
- const result = { vertices, vertexCount }
477
- widthMap.set(0, result)
478
- return result
479
- }
480
-
481
478
  private getLineGeometry(line: LineStrip): { vertices: Float32Array; vertexCount: number } | null {
482
479
  const halfWidth = line.width / 2
483
480
  let widthMap = this.geoCache.get(line.points)
@@ -521,7 +518,11 @@ export class LineWebGLSurface {
521
518
  }
522
519
 
523
520
  const gl = this.shared.getGL()
524
- if (!gl || !this.region || !this.shared.bindRegion(this.region)) return false
521
+ const region = this.region
522
+ if (!gl || !region) return false
523
+
524
+ const msaaRender = this.beginMsaaRender(gl, region)
525
+ if (!msaaRender && !this.shared.bindRegion(region)) return false
525
526
 
526
527
  gl.useProgram(handles.basic.program)
527
528
  gl.bindVertexArray(handles.basic.vao)
@@ -538,6 +539,12 @@ export class LineWebGLSurface {
538
539
  gl.uniform4f(handles.basic.colorLocation, colorValue[0], colorValue[1], colorValue[2], colorValue[3])
539
540
  gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertexCount)
540
541
  gl.bindVertexArray(null)
542
+
543
+ if (msaaRender) {
544
+ this.resolveMsaaToSharedRegion(gl, msaaRender.targets, msaaRender.physical)
545
+ }
546
+
547
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null)
541
548
  return true
542
549
  }
543
550
 
@@ -545,7 +552,7 @@ export class LineWebGLSurface {
545
552
  const handles = this.handles
546
553
  const gl = this.shared.getGL()
547
554
  if (gl) {
548
- this.destroyLineMsaaTargets(gl)
555
+ this.destroyMsaaTargets(gl)
549
556
  }
550
557
  if (!handles) {
551
558
  this.vertexCapacity = 0
@@ -563,7 +570,20 @@ export class LineWebGLSurface {
563
570
  this.vertexCapacity = 0
564
571
  }
565
572
 
566
- private ensureLineMsaaTargets(gl: WebGL2RenderingContext, physical: PhysicalRegion): LineMsaaTargets | null {
573
+ private beginMsaaRender(gl: WebGL2RenderingContext, region: WebGLRegion): { targets: MsaaTargets; physical: PhysicalRegion } | null {
574
+ const physical = this.shared.getPhysicalRegion(region)
575
+ const targets = physical ? this.ensureMsaaTargets(gl, physical) : null
576
+ if (!physical || !targets) return null
577
+
578
+ gl.bindFramebuffer(gl.FRAMEBUFFER, targets.msaaFramebuffer)
579
+ gl.viewport(0, 0, targets.widthPx, targets.heightPx)
580
+ gl.disable(gl.SCISSOR_TEST)
581
+ gl.clearColor(0, 0, 0, 0)
582
+ gl.clear(gl.COLOR_BUFFER_BIT)
583
+ return { targets, physical }
584
+ }
585
+
586
+ private ensureMsaaTargets(gl: WebGL2RenderingContext, physical: PhysicalRegion): MsaaTargets | null {
567
587
  const preferredSamples = 4
568
588
  const maxSamples = Number(gl.getParameter(gl.MAX_SAMPLES)) || 0
569
589
  const samples = Math.max(1, Math.min(preferredSamples, maxSamples))
@@ -579,7 +599,7 @@ export class LineWebGLSurface {
579
599
  return existing
580
600
  }
581
601
 
582
- this.destroyLineMsaaTargets(gl)
602
+ this.destroyMsaaTargets(gl)
583
603
 
584
604
  const msaaFramebuffer = gl.createFramebuffer()
585
605
  const msaaColorRenderbuffer = gl.createRenderbuffer()
@@ -643,7 +663,7 @@ export class LineWebGLSurface {
643
663
  return targets
644
664
  }
645
665
 
646
- private destroyLineMsaaTargets(gl: WebGL2RenderingContext): void {
666
+ private destroyMsaaTargets(gl: WebGL2RenderingContext): void {
647
667
  const targets = this.msaaTargets
648
668
  if (!targets) return
649
669
  gl.deleteFramebuffer(targets.msaaFramebuffer)
@@ -653,7 +673,7 @@ export class LineWebGLSurface {
653
673
  this.msaaTargets = null
654
674
  }
655
675
 
656
- private resolveLineMsaaToSharedRegion(gl: WebGL2RenderingContext, targets: LineMsaaTargets, physical: PhysicalRegion): void {
676
+ private resolveMsaaToSharedRegion(gl: WebGL2RenderingContext, targets: MsaaTargets, physical: PhysicalRegion): void {
657
677
  gl.bindFramebuffer(gl.READ_FRAMEBUFFER, targets.msaaFramebuffer)
658
678
  gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, targets.resolveFramebuffer)
659
679
  gl.blitFramebuffer(
@@ -809,7 +829,7 @@ function buildJoinedPolylineGeometry(points: Array<{ x: number; y: number }>, ha
809
829
  miterNX *= invMiter
810
830
  miterNY *= invMiter
811
831
  const dot = miterNX * currNormal.nx + miterNY * currNormal.ny
812
- const scale = 1 / Math.max(0.2, Math.abs(dot))
832
+ const scale = 1 / Math.max(MITER_DOT_MIN, Math.abs(dot))
813
833
  miterNX *= scale
814
834
  miterNY *= scale
815
835
  } else {
@@ -839,7 +859,7 @@ function buildJoinedPolylineGeometry(points: Array<{ x: number; y: number }>, ha
839
859
  nextMiterNX *= invMiter
840
860
  nextMiterNY *= invMiter
841
861
  const dot = nextMiterNX * nextNormal.nx + nextMiterNY * nextNormal.ny
842
- const scale = 1 / Math.max(0.2, Math.abs(dot))
862
+ const scale = 1 / Math.max(MITER_DOT_MIN, Math.abs(dot))
843
863
  nextMiterNX *= scale
844
864
  nextMiterNY *= scale
845
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
  }
@@ -2,6 +2,7 @@ import type { Chart } from './chart'
2
2
  import type { SubIndicatorType } from './renderers/Indicator'
3
3
  import { createSignal, type Signal } from '../reactivity/signal'
4
4
  import { createSubIndicatorRenderer } from './renderers/Indicator'
5
+ import { createPaneTitleRendererPlugin } from './renderers/paneTitle'
5
6
  import { createVolumeScaleRendererPlugin } from './renderers/Indicator/scale/volume_scale'
6
7
  import { createMacdScaleRendererPlugin } from './renderers/Indicator/scale/macd_scale'
7
8
  import { createRsiScaleRendererPlugin } from './renderers/Indicator/scale/rsi_scale'
@@ -57,6 +58,7 @@ export interface SubPaneEntry {
57
58
  params: Record<string, unknown>
58
59
  rendererName: string
59
60
  scaleRendererName: string
61
+ paneTitleRendererName: string
60
62
  }
61
63
 
62
64
  export class SubPaneManager {
@@ -78,6 +80,7 @@ export class SubPaneManager {
78
80
 
79
81
  const rendererName = `${indicatorId.toLowerCase()}_${paneId}`
80
82
  const scaleRendererName = `${indicatorId.toLowerCase()}_scale_${paneId}`
83
+ const paneTitleRendererName = `paneTitle_${paneId}`
81
84
 
82
85
  const paneExists = chart.hasPane(paneId)
83
86
  if (!paneExists) {
@@ -91,10 +94,11 @@ export class SubPaneManager {
91
94
  }
92
95
 
93
96
  this.mountScaleRenderer(chart, paneId, indicatorId, scaleRendererName)
97
+ this.mountPaneTitleRenderer(chart, paneId, indicatorId, params)
94
98
 
95
99
  // 必须在 syncSchedulerConfig 之前注册 entry,
96
100
  // 否则 scheduler 的 buildActiveConfig 读不到新 paneId,会将新指标的 show* 标志置为 false
97
- this.entries.set(paneId, { paneId, indicatorId, params, rendererName, scaleRendererName })
101
+ this.entries.set(paneId, { paneId, indicatorId, params, rendererName, scaleRendererName, paneTitleRendererName })
98
102
 
99
103
  this.syncSchedulerConfig(chart, paneId, indicatorId, params)
100
104
 
@@ -110,6 +114,7 @@ export class SubPaneManager {
110
114
 
111
115
  chart.removeRenderer(entry.rendererName)
112
116
  chart.removeRenderer(entry.scaleRendererName)
117
+ chart.removeRenderer(entry.paneTitleRendererName)
113
118
 
114
119
  this.entries.delete(paneId)
115
120
 
@@ -129,14 +134,17 @@ export class SubPaneManager {
129
134
 
130
135
  chart.removeRenderer(entry.rendererName)
131
136
  chart.removeRenderer(entry.scaleRendererName)
137
+ chart.removeRenderer(entry.paneTitleRendererName)
132
138
 
133
139
  const newRendererName = `${newIndicatorId.toLowerCase()}_${paneId}`
134
140
  const newScaleRendererName = `${newIndicatorId.toLowerCase()}_scale_${paneId}`
141
+ const newPaneTitleRendererName = `paneTitle_${paneId}`
135
142
 
136
143
  const renderer = createSubIndicatorRenderer({ indicatorId: newIndicatorId, paneId })
137
144
  chart.useRenderer(renderer, newParams as Record<string, number | boolean | string>)
138
145
 
139
146
  this.mountScaleRenderer(chart, paneId, newIndicatorId, newScaleRendererName)
147
+ this.mountPaneTitleRenderer(chart, paneId, newIndicatorId, newParams)
140
148
 
141
149
  this.syncSchedulerConfig(chart, paneId, newIndicatorId, newParams)
142
150
 
@@ -146,6 +154,7 @@ export class SubPaneManager {
146
154
  params: newParams,
147
155
  rendererName: newRendererName,
148
156
  scaleRendererName: newScaleRendererName,
157
+ paneTitleRendererName: newPaneTitleRendererName,
149
158
  })
150
159
 
151
160
  chart.getIndicatorScheduler().onSubPaneChanged()
@@ -180,6 +189,7 @@ export class SubPaneManager {
180
189
  for (const entry of this.entries.values()) {
181
190
  chart.removeRenderer(entry.rendererName)
182
191
  chart.removeRenderer(entry.scaleRendererName)
192
+ chart.removeRenderer(entry.paneTitleRendererName)
183
193
  }
184
194
  this.entries.clear()
185
195
  chart.getIndicatorScheduler().onSubPaneChanged()
@@ -439,4 +449,21 @@ export class SubPaneManager {
439
449
 
440
450
  chart.useRenderer(renderer)
441
451
  }
452
+
453
+ private mountPaneTitleRenderer(chart: Chart, paneId: string, indicatorId: SubIndicatorType, params: Record<string, unknown>): void {
454
+ const rendererName = `paneTitle_${paneId}`
455
+ const existing = chart.getRenderer(rendererName)
456
+ if (existing) {
457
+ chart.updateRendererConfig(rendererName, { params, indicatorId })
458
+ return
459
+ }
460
+
461
+ const renderer = createPaneTitleRendererPlugin({
462
+ paneId,
463
+ title: indicatorId,
464
+ indicatorId,
465
+ params,
466
+ })
467
+ chart.useRenderer(renderer)
468
+ }
442
469
  }
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 = {
@@ -41,7 +41,7 @@ async function getDataFetcher(): Promise<DataFetcher> {
41
41
  return _dataFetcher
42
42
  }
43
43
 
44
- interface SemanticChartAdapter {
44
+ export interface SemanticChartAdapter {
45
45
  updateData(data: ReadonlyArray<KLineData>): void
46
46
  updateRendererConfig(name: string, config: Record<string, unknown>): void
47
47
  clearSubPanes(): void
@@ -21,7 +21,7 @@ export type {
21
21
  } from './types'
22
22
 
23
23
  export { SemanticChartController, type SemanticEventType, __setDataFetcher } from './controller'
24
- export type { DataFetcher } from './controller'
24
+ export type { DataFetcher, SemanticChartAdapter } from './controller'
25
25
 
26
26
  export { SemanticConfigValidator, sanitizeParams, sanitizeColor, validateColor, validateSymbol } from './validator'
27
27