@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.
- package/dist/config/chartSettings.d.ts +27 -2
- package/dist/config/chartSettings.d.ts.map +1 -1
- package/dist/config/chartSettings.js +6 -0
- package/dist/config/chartSettings.js.map +1 -1
- package/dist/engine/chart.d.ts.map +1 -1
- package/dist/engine/chart.js +4 -0
- package/dist/engine/chart.js.map +1 -1
- package/dist/engine/draw/pixelAlign.d.ts.map +1 -1
- package/dist/engine/draw/pixelAlign.js.map +1 -1
- package/dist/engine/drawing/plugin.js +1 -1
- package/dist/engine/drawing/plugin.js.map +1 -1
- package/dist/engine/renderers/Indicator/atr.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/atr.js +7 -4
- package/dist/engine/renderers/Indicator/atr.js.map +1 -1
- package/dist/engine/renderers/Indicator/boll.js +12 -12
- package/dist/engine/renderers/Indicator/boll.js.map +1 -1
- package/dist/engine/renderers/Indicator/cci.d.ts +1 -2
- package/dist/engine/renderers/Indicator/cci.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/cci.js +9 -9
- package/dist/engine/renderers/Indicator/cci.js.map +1 -1
- package/dist/engine/renderers/Indicator/ene.js +12 -12
- package/dist/engine/renderers/Indicator/ene.js.map +1 -1
- package/dist/engine/renderers/Indicator/expma.js +6 -6
- package/dist/engine/renderers/Indicator/expma.js.map +1 -1
- package/dist/engine/renderers/Indicator/fastk.d.ts +1 -2
- package/dist/engine/renderers/Indicator/fastk.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/fastk.js +7 -7
- package/dist/engine/renderers/Indicator/fastk.js.map +1 -1
- package/dist/engine/renderers/Indicator/kst.d.ts +1 -2
- package/dist/engine/renderers/Indicator/kst.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/kst.js +10 -10
- package/dist/engine/renderers/Indicator/kst.js.map +1 -1
- package/dist/engine/renderers/Indicator/ma.js +5 -5
- package/dist/engine/renderers/Indicator/ma.js.map +1 -1
- package/dist/engine/renderers/Indicator/macd.d.ts +1 -2
- package/dist/engine/renderers/Indicator/macd.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/macd.js +24 -24
- package/dist/engine/renderers/Indicator/macd.js.map +1 -1
- package/dist/engine/renderers/Indicator/macdLegend.js +6 -6
- package/dist/engine/renderers/Indicator/macdLegend.js.map +1 -1
- package/dist/engine/renderers/Indicator/mainIndicatorLegend.js +16 -16
- package/dist/engine/renderers/Indicator/mainIndicatorLegend.js.map +1 -1
- package/dist/engine/renderers/Indicator/mom.d.ts +1 -2
- package/dist/engine/renderers/Indicator/mom.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/mom.js +8 -8
- package/dist/engine/renderers/Indicator/mom.js.map +1 -1
- package/dist/engine/renderers/Indicator/rsi.d.ts +2 -3
- package/dist/engine/renderers/Indicator/rsi.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/rsi.js +19 -15
- package/dist/engine/renderers/Indicator/rsi.js.map +1 -1
- package/dist/engine/renderers/Indicator/scale/indicator_scale.d.ts +1 -2
- package/dist/engine/renderers/Indicator/scale/indicator_scale.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/scale/indicator_scale.js +5 -5
- package/dist/engine/renderers/Indicator/scale/indicator_scale.js.map +1 -1
- package/dist/engine/renderers/Indicator/stoch.d.ts +1 -2
- package/dist/engine/renderers/Indicator/stoch.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/stoch.js +10 -10
- package/dist/engine/renderers/Indicator/stoch.js.map +1 -1
- package/dist/engine/renderers/Indicator/structure.js +5 -5
- package/dist/engine/renderers/Indicator/structure.js.map +1 -1
- package/dist/engine/renderers/Indicator/wmsr.d.ts +1 -2
- package/dist/engine/renderers/Indicator/wmsr.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/wmsr.js +10 -10
- package/dist/engine/renderers/Indicator/wmsr.js.map +1 -1
- package/dist/engine/renderers/Indicator/zones.js +6 -6
- package/dist/engine/renderers/Indicator/zones.js.map +1 -1
- package/dist/engine/renderers/candle.d.ts +1 -1
- package/dist/engine/renderers/candle.d.ts.map +1 -1
- package/dist/engine/renderers/candle.js +21 -21
- package/dist/engine/renderers/candle.js.map +1 -1
- package/dist/engine/renderers/crosshair.js +3 -3
- package/dist/engine/renderers/crosshair.js.map +1 -1
- package/dist/engine/renderers/extremaMarkers.d.ts.map +1 -1
- package/dist/engine/renderers/extremaMarkers.js +12 -12
- package/dist/engine/renderers/extremaMarkers.js.map +1 -1
- package/dist/engine/renderers/gridLines.js +3 -3
- package/dist/engine/renderers/gridLines.js.map +1 -1
- package/dist/engine/renderers/lastPrice.js +7 -7
- package/dist/engine/renderers/lastPrice.js.map +1 -1
- package/dist/engine/renderers/paneTitle.js +6 -6
- package/dist/engine/renderers/paneTitle.js.map +1 -1
- package/dist/engine/renderers/subVolume.d.ts.map +1 -1
- package/dist/engine/renderers/subVolume.js +23 -20
- package/dist/engine/renderers/subVolume.js.map +1 -1
- package/dist/engine/renderers/timeAxis.js +9 -9
- package/dist/engine/renderers/timeAxis.js.map +1 -1
- package/dist/engine/renderers/webgl/candleSurface.d.ts.map +1 -1
- package/dist/engine/renderers/webgl/candleSurface.js +39 -7
- package/dist/engine/renderers/webgl/candleSurface.js.map +1 -1
- package/dist/engine/renderers/yAxis.d.ts.map +1 -1
- package/dist/engine/renderers/yAxis.js +5 -5
- package/dist/engine/renderers/yAxis.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/plugin/types.d.ts +5 -1
- package/dist/plugin/types.d.ts.map +1 -1
- package/dist/plugin/types.js.map +1 -1
- package/dist/tokens/colorPresetSettings.d.ts +15 -0
- package/dist/tokens/colorPresetSettings.d.ts.map +1 -0
- package/dist/tokens/colorPresetSettings.js +65 -0
- package/dist/tokens/colorPresetSettings.js.map +1 -0
- package/dist/tokens/index.d.ts +17 -0
- package/dist/tokens/index.d.ts.map +1 -0
- package/dist/tokens/index.js +16 -0
- package/dist/tokens/index.js.map +1 -0
- package/dist/tokens/mergeTheme.d.ts +17 -0
- package/dist/tokens/mergeTheme.d.ts.map +1 -0
- package/dist/tokens/mergeTheme.js +43 -0
- package/dist/tokens/mergeTheme.js.map +1 -0
- package/dist/tokens/theme-china.d.ts +45 -0
- package/dist/tokens/theme-china.d.ts.map +1 -0
- package/dist/tokens/theme-china.js +116 -0
- package/dist/tokens/theme-china.js.map +1 -0
- package/dist/tokens/theme-dark.d.ts +21 -0
- package/dist/tokens/theme-dark.d.ts.map +1 -0
- package/dist/tokens/theme-dark.js +228 -0
- package/dist/tokens/theme-dark.js.map +1 -0
- package/dist/tokens/theme-light.d.ts +23 -0
- package/dist/tokens/theme-light.d.ts.map +1 -0
- package/dist/tokens/theme-light.js +234 -0
- package/dist/tokens/theme-light.js.map +1 -0
- package/dist/tokens/themeToCssVars.d.ts +74 -0
- package/dist/tokens/themeToCssVars.d.ts.map +1 -0
- package/dist/tokens/themeToCssVars.js +108 -0
- package/dist/tokens/themeToCssVars.js.map +1 -0
- package/dist/tokens/types.d.ts +335 -0
- package/dist/tokens/types.d.ts.map +1 -0
- package/dist/tokens/types.js +20 -0
- package/dist/tokens/types.js.map +1 -0
- package/dist/utils/kLineDraw/axis.d.ts +8 -7
- package/dist/utils/kLineDraw/axis.d.ts.map +1 -1
- package/dist/utils/kLineDraw/axis.js +24 -24
- package/dist/utils/kLineDraw/axis.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/src/config/chartSettings.ts +11 -2
- package/src/engine/chart.ts +4 -0
- package/src/engine/draw/pixelAlign.ts +0 -2
- package/src/engine/drawing/plugin.ts +1 -1
- package/src/engine/renderers/Indicator/atr.ts +7 -3
- package/src/engine/renderers/Indicator/boll.ts +12 -12
- package/src/engine/renderers/Indicator/cci.ts +11 -10
- package/src/engine/renderers/Indicator/ene.ts +12 -12
- package/src/engine/renderers/Indicator/expma.ts +6 -6
- package/src/engine/renderers/Indicator/fastk.ts +9 -8
- package/src/engine/renderers/Indicator/kst.ts +12 -11
- package/src/engine/renderers/Indicator/ma.ts +5 -5
- package/src/engine/renderers/Indicator/macd.ts +27 -25
- package/src/engine/renderers/Indicator/macdLegend.ts +6 -6
- package/src/engine/renderers/Indicator/mainIndicatorLegend.ts +16 -16
- package/src/engine/renderers/Indicator/mom.ts +11 -10
- package/src/engine/renderers/Indicator/rsi.ts +22 -15
- package/src/engine/renderers/Indicator/scale/indicator_scale.ts +6 -6
- package/src/engine/renderers/Indicator/stoch.ts +12 -11
- package/src/engine/renderers/Indicator/structure.ts +5 -5
- package/src/engine/renderers/Indicator/wmsr.ts +13 -12
- package/src/engine/renderers/Indicator/zones.ts +7 -7
- package/src/engine/renderers/candle.ts +21 -21
- package/src/engine/renderers/crosshair.ts +3 -3
- package/src/engine/renderers/extremaMarkers.ts +13 -12
- package/src/engine/renderers/gridLines.ts +3 -3
- package/src/engine/renderers/lastPrice.ts +7 -7
- package/src/engine/renderers/paneTitle.ts +6 -6
- package/src/engine/renderers/subVolume.ts +23 -20
- package/src/engine/renderers/timeAxis.ts +9 -9
- package/src/engine/renderers/webgl/candleSurface.ts +43 -7
- package/src/engine/renderers/yAxis.ts +6 -5
- package/src/index.ts +1 -0
- package/src/plugin/types.ts +5 -1
- package/src/tokens/__tests__/__snapshots__/baseline.test.ts.snap +393 -0
- package/src/tokens/__tests__/baseline.test.ts +183 -0
- package/src/tokens/__tests__/themeToCssVars.test.ts +175 -0
- package/src/tokens/__tests__/tokens.test.ts +215 -0
- package/src/tokens/colorPresetSettings.ts +128 -0
- package/src/tokens/index.ts +65 -0
- package/src/tokens/mergeTheme.ts +48 -0
- package/src/tokens/theme-china.ts +132 -0
- package/src/tokens/theme-dark.ts +244 -0
- package/src/tokens/theme-light.ts +250 -0
- package/src/tokens/themeToCssVars.ts +138 -0
- package/src/tokens/types.ts +394 -0
- package/src/utils/kLineDraw/axis.ts +31 -30
- package/src/version.ts +1 -1
- package/dist/engine/theme/colors.d.ts +0 -223
- package/dist/engine/theme/colors.d.ts.map +0 -1
- package/dist/engine/theme/colors.js +0 -375
- package/dist/engine/theme/colors.js.map +0 -1
- 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 {
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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.
|
|
154
|
-
borderColor: colors.
|
|
155
|
-
textColor: colors.
|
|
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.
|
|
165
|
-
borderColor: colors.
|
|
166
|
-
textColor: colors.
|
|
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 {
|
|
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 =
|
|
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.
|
|
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 {
|
|
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 =
|
|
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.
|
|
50
|
-
borderColor: colors.
|
|
51
|
-
textColor: colors.
|
|
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 =
|
|
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.
|
|
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 {
|
|
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 =
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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 {
|
|
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 =
|
|
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,
|
|
130
|
+
const color = judgeColor(item, upVolume, downVolume, neutralVolume)
|
|
128
131
|
|
|
129
132
|
let buf: Float32Array
|
|
130
133
|
let idx: number
|
|
131
|
-
if (color ===
|
|
134
|
+
if (color === upVolume) {
|
|
132
135
|
buf = upBuf; idx = upCount++
|
|
133
|
-
} else if (color ===
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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,
|
|
169
|
-
const ok2 = downCount === 0 || surface.drawRectBuffer(downBuf.subarray(0, downCount * 4), downCount,
|
|
170
|
-
const ok3 = neutralCount === 0 || surface.drawRectBuffer(neutralBuf.subarray(0, neutralCount * 4), neutralCount,
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
*
|
|
218
|
+
* 判断成交量柱子颜色
|
|
216
219
|
*/
|
|
217
|
-
function judgeColor(dayData: KLineData,
|
|
220
|
+
function judgeColor(dayData: KLineData, upColor: string, downColor: string, neutralColor: string): string {
|
|
218
221
|
if (dayData.close > dayData.open) {
|
|
219
|
-
return
|
|
222
|
+
return upColor
|
|
220
223
|
} else if (dayData.close < dayData.open) {
|
|
221
|
-
return
|
|
224
|
+
return downColor
|
|
222
225
|
} else {
|
|
223
|
-
return
|
|
226
|
+
return neutralColor
|
|
224
227
|
}
|
|
225
228
|
}
|
|
226
229
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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 =
|
|
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.
|
|
56
|
-
lineColor: colors.
|
|
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.
|
|
91
|
-
textColor: colors.
|
|
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({
|
|
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
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
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(
|
|
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(
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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
package/src/plugin/types.ts
CHANGED
|
@@ -309,7 +309,11 @@ export interface RenderContext {
|
|
|
309
309
|
/** 需要在X轴上绘制的范围带列表(由绘图渲染器填充,先于标签绘制) */
|
|
310
310
|
xAxisRanges?: XAxisRange[]
|
|
311
311
|
/** 当前主题 */
|
|
312
|
-
theme:
|
|
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 = {
|