@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.
- package/README.md +8 -8
- package/README.zh-CN.md +8 -8
- 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/controllers/createChartController.d.ts.map +1 -1
- package/dist/controllers/createChartController.js +145 -21
- package/dist/controllers/createChartController.js.map +1 -1
- package/dist/controllers/index.d.ts +9 -1
- package/dist/controllers/index.d.ts.map +1 -1
- package/dist/controllers/index.js +9 -0
- package/dist/controllers/index.js.map +1 -1
- package/dist/controllers/types.d.ts +65 -8
- package/dist/controllers/types.d.ts.map +1 -1
- package/dist/engine/chart.d.ts +2 -12
- package/dist/engine/chart.d.ts.map +1 -1
- package/dist/engine/chart.js +32 -31
- package/dist/engine/chart.js.map +1 -1
- package/dist/engine/controller/interaction.d.ts +1 -1
- package/dist/engine/controller/interaction.d.ts.map +1 -1
- package/dist/engine/controller/interaction.js +10 -2
- package/dist/engine/controller/interaction.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/interaction.d.ts +3 -3
- package/dist/engine/drawing/interaction.d.ts.map +1 -1
- package/dist/engine/drawing/interaction.js +38 -46
- package/dist/engine/drawing/interaction.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 +15 -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.d.ts +5 -24
- package/dist/engine/renderers/paneTitle.d.ts.map +1 -1
- package/dist/engine/renderers/paneTitle.js +16 -11
- 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 +4 -4
- package/dist/engine/renderers/webgl/candleSurface.d.ts.map +1 -1
- package/dist/engine/renderers/webgl/candleSurface.js +72 -60
- 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/engine/subPaneManager.d.ts +2 -0
- package/dist/engine/subPaneManager.d.ts.map +1 -1
- package/dist/engine/subPaneManager.js +25 -1
- package/dist/engine/subPaneManager.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/semantic/controller.d.ts +1 -2
- package/dist/semantic/controller.d.ts.map +1 -1
- package/dist/semantic/index.d.ts +1 -1
- package/dist/semantic/index.d.ts.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 +6 -6
- package/src/config/chartSettings.ts +11 -2
- package/src/controllers/createChartController.ts +158 -29
- package/src/controllers/index.ts +33 -0
- package/src/controllers/types.ts +79 -8
- package/src/engine/chart.ts +32 -37
- package/src/engine/controller/interaction.ts +9 -2
- package/src/engine/draw/pixelAlign.ts +0 -2
- package/src/engine/drawing/interaction.ts +38 -47
- 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 +18 -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 +22 -31
- package/src/engine/renderers/subVolume.ts +23 -20
- package/src/engine/renderers/timeAxis.ts +9 -9
- package/src/engine/renderers/webgl/candleSurface.ts +80 -60
- package/src/engine/renderers/yAxis.ts +6 -5
- package/src/engine/subPaneManager.ts +28 -1
- package/src/index.ts +1 -0
- package/src/plugin/types.ts +5 -1
- package/src/semantic/controller.ts +1 -1
- package/src/semantic/index.ts +1 -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/chart-store.d.ts +0 -75
- package/dist/engine/chart-store.d.ts.map +0 -1
- package/dist/engine/chart-store.js +0 -88
- package/dist/engine/chart-store.js.map +0 -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/chart-store.ts +0 -121
- package/src/engine/theme/colors.ts +0 -642
|
@@ -3,7 +3,7 @@ import { RENDERER_PRIORITY } from '../../plugin'
|
|
|
3
3
|
import type { KLineData } from '../../types/price'
|
|
4
4
|
import { getKLineTrend, type kLineTrend } from '../../types/kLine'
|
|
5
5
|
import { createAlignedKLineFromPx, createVerticalLineRect } from '../draw/pixelAlign'
|
|
6
|
-
import {
|
|
6
|
+
import { resolveThemeColors, type VolumePriceColors } from '../../tokens'
|
|
7
7
|
import { getPhysicalKLineConfig } from '../chart'
|
|
8
8
|
import { VolumePriceRelation } from '../../types/volumePrice'
|
|
9
9
|
import { analyzeVolumePriceRelationBatch, DEFAULT_VOLUME_PRICE_CONFIG } from '../../utils/volumePrice'
|
|
@@ -52,7 +52,7 @@ export function createCandleRenderer(): RendererPlugin {
|
|
|
52
52
|
|
|
53
53
|
draw(context: RenderContext) {
|
|
54
54
|
const { ctx, pane, data, range, scrollLeft, kWidth, kGap, dpr, kLinePositions, markerManager, settings } = context
|
|
55
|
-
const colors =
|
|
55
|
+
const colors = resolveThemeColors(context.theme, context.isAsiaMarket, context.colorPresetSettings)
|
|
56
56
|
const klineData = data as KLineData[]
|
|
57
57
|
if (!klineData.length) return
|
|
58
58
|
|
|
@@ -67,9 +67,9 @@ export function createCandleRenderer(): RendererPlugin {
|
|
|
67
67
|
settings,
|
|
68
68
|
})
|
|
69
69
|
|
|
70
|
-
const usedWebGL = drawCandlesWithWebGL(context, prepared, colors.
|
|
70
|
+
const usedWebGL = drawCandlesWithWebGL(context, prepared, colors.candleUpBody, colors.candleDownBody)
|
|
71
71
|
if (!usedWebGL) {
|
|
72
|
-
drawCandlesWithCanvas2D(ctx, scrollLeft, prepared, colors.
|
|
72
|
+
drawCandlesWithCanvas2D(ctx, scrollLeft, prepared, colors.candleUpBody, colors.candleDownBody)
|
|
73
73
|
} else {
|
|
74
74
|
compositeWebGLToMainCanvas(ctx, context)
|
|
75
75
|
}
|
|
@@ -238,29 +238,29 @@ function prepareCandles(args: {
|
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
-
function drawCandlesWithCanvas2D(ctx: CanvasRenderingContext2D, scrollLeft: number, prepared: PreparedCandles,
|
|
241
|
+
function drawCandlesWithCanvas2D(ctx: CanvasRenderingContext2D, scrollLeft: number, prepared: PreparedCandles, upColor: string, downColor: string): void {
|
|
242
242
|
ctx.save()
|
|
243
243
|
ctx.translate(-scrollLeft, 0)
|
|
244
244
|
|
|
245
|
-
ctx.fillStyle =
|
|
245
|
+
ctx.fillStyle = upColor
|
|
246
246
|
for (let i = 0; i < prepared.upBodyCount; i++) {
|
|
247
247
|
const off = i * 4
|
|
248
248
|
ctx.fillRect(prepared.upBodyBuf[off], prepared.upBodyBuf[off + 1], prepared.upBodyBuf[off + 2], prepared.upBodyBuf[off + 3])
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
ctx.fillStyle =
|
|
251
|
+
ctx.fillStyle = downColor
|
|
252
252
|
for (let i = 0; i < prepared.downBodyCount; i++) {
|
|
253
253
|
const off = i * 4
|
|
254
254
|
ctx.fillRect(prepared.downBodyBuf[off], prepared.downBodyBuf[off + 1], prepared.downBodyBuf[off + 2], prepared.downBodyBuf[off + 3])
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
-
ctx.fillStyle =
|
|
257
|
+
ctx.fillStyle = upColor
|
|
258
258
|
for (let i = 0; i < prepared.upWickCount; i++) {
|
|
259
259
|
const off = i * 4
|
|
260
260
|
ctx.fillRect(prepared.upWickBuf[off], prepared.upWickBuf[off + 1], prepared.wickWidth, prepared.upWickBuf[off + 3])
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
-
ctx.fillStyle =
|
|
263
|
+
ctx.fillStyle = downColor
|
|
264
264
|
for (let i = 0; i < prepared.downWickCount; i++) {
|
|
265
265
|
const off = i * 4
|
|
266
266
|
ctx.fillRect(prepared.downWickBuf[off], prepared.downWickBuf[off + 1], prepared.wickWidth, prepared.downWickBuf[off + 3])
|
|
@@ -269,17 +269,17 @@ function drawCandlesWithCanvas2D(ctx: CanvasRenderingContext2D, scrollLeft: numb
|
|
|
269
269
|
ctx.restore()
|
|
270
270
|
}
|
|
271
271
|
|
|
272
|
-
function drawCandlesWithWebGL(context: RenderContext, prepared: PreparedCandles,
|
|
272
|
+
function drawCandlesWithWebGL(context: RenderContext, prepared: PreparedCandles, upColor: string, downColor: string): boolean {
|
|
273
273
|
if (context.settings?.enableWebGLRendering === false) return false
|
|
274
274
|
const surface = context.candleWebGLSurface
|
|
275
275
|
if (!surface || !surface.isAvailable()) return false
|
|
276
276
|
|
|
277
277
|
surface.clear()
|
|
278
278
|
|
|
279
|
-
const bodyUpOk = prepared.upBodyCount === 0 || surface.drawRectBuffer(prepared.upBodyBuf.subarray(0, prepared.upBodyCount * 4), prepared.upBodyCount,
|
|
280
|
-
const bodyDownOk = prepared.downBodyCount === 0 || surface.drawRectBuffer(prepared.downBodyBuf.subarray(0, prepared.downBodyCount * 4), prepared.downBodyCount,
|
|
281
|
-
const wickUpOk = prepared.upWickCount === 0 || surface.drawRectBuffer(prepared.upWickBuf.subarray(0, prepared.upWickCount * 4), prepared.upWickCount,
|
|
282
|
-
const wickDownOk = prepared.downWickCount === 0 || surface.drawRectBuffer(prepared.downWickBuf.subarray(0, prepared.downWickCount * 4), prepared.downWickCount,
|
|
279
|
+
const bodyUpOk = prepared.upBodyCount === 0 || surface.drawRectBuffer(prepared.upBodyBuf.subarray(0, prepared.upBodyCount * 4), prepared.upBodyCount, upColor, context.scrollLeft)
|
|
280
|
+
const bodyDownOk = prepared.downBodyCount === 0 || surface.drawRectBuffer(prepared.downBodyBuf.subarray(0, prepared.downBodyCount * 4), prepared.downBodyCount, downColor, context.scrollLeft)
|
|
281
|
+
const wickUpOk = prepared.upWickCount === 0 || surface.drawRectBuffer(prepared.upWickBuf.subarray(0, prepared.upWickCount * 4), prepared.upWickCount, upColor, context.scrollLeft)
|
|
282
|
+
const wickDownOk = prepared.downWickCount === 0 || surface.drawRectBuffer(prepared.downWickBuf.subarray(0, prepared.downWickCount * 4), prepared.downWickCount, downColor, context.scrollLeft)
|
|
283
283
|
|
|
284
284
|
return bodyUpOk && bodyDownOk && wickUpOk && wickDownOk
|
|
285
285
|
}
|
|
@@ -297,7 +297,7 @@ function drawVolumePriceMarkers(
|
|
|
297
297
|
markerManager: MarkerManager | undefined
|
|
298
298
|
): void {
|
|
299
299
|
const { ctx, range, kWidth, dpr } = context
|
|
300
|
-
const colors =
|
|
300
|
+
const colors = resolveThemeColors(context.theme, context.isAsiaMarket, context.colorPresetSettings)
|
|
301
301
|
if (!prepared.showVolumePriceMarkers || !markerManager || (context.zoomLevel ?? 1) < 2) {
|
|
302
302
|
return
|
|
303
303
|
}
|
|
@@ -312,7 +312,7 @@ function drawVolumePriceMarkers(
|
|
|
312
312
|
const markerY = isRising ? k.alignedHighY - 15 : k.alignedLowY + 15
|
|
313
313
|
const posIndex = k.i - range.start
|
|
314
314
|
const markerX = context.kLineCenters[posIndex]!
|
|
315
|
-
drawVolumePriceMarker(ctx, markerX, markerY, relation, k.i, kWidth, 4, markerManager, dpr, colors.
|
|
315
|
+
drawVolumePriceMarker(ctx, markerX, markerY, relation, k.i, kWidth, 4, markerManager, dpr, colors.volumePrice)
|
|
316
316
|
}
|
|
317
317
|
}
|
|
318
318
|
|
|
@@ -323,7 +323,7 @@ function drawVolumePriceMarkers(
|
|
|
323
323
|
const markerY = isRising ? k.alignedHighY - 15 : k.alignedLowY + 15
|
|
324
324
|
const posIndex = k.i - range.start
|
|
325
325
|
const markerX = context.kLineCenters[posIndex]!
|
|
326
|
-
drawVolumePriceMarker(ctx, markerX, markerY, relation, k.i, kWidth, 4, markerManager, dpr, colors.
|
|
326
|
+
drawVolumePriceMarker(ctx, markerX, markerY, relation, k.i, kWidth, 4, markerManager, dpr, colors.volumePrice)
|
|
327
327
|
}
|
|
328
328
|
}
|
|
329
329
|
|
|
@@ -366,19 +366,19 @@ export function drawVolumePriceMarker(
|
|
|
366
366
|
|
|
367
367
|
switch (relation) {
|
|
368
368
|
case VolumePriceRelation.RISE_WITH_VOLUME:
|
|
369
|
-
color = volumePriceColors.
|
|
369
|
+
color = volumePriceColors.riseWith
|
|
370
370
|
isUp = true
|
|
371
371
|
break
|
|
372
372
|
case VolumePriceRelation.RISE_WITHOUT_VOLUME:
|
|
373
|
-
color = volumePriceColors.
|
|
373
|
+
color = volumePriceColors.riseWithout
|
|
374
374
|
isUp = true
|
|
375
375
|
break
|
|
376
376
|
case VolumePriceRelation.FALL_WITH_VOLUME:
|
|
377
|
-
color = volumePriceColors.
|
|
377
|
+
color = volumePriceColors.fallWith
|
|
378
378
|
isUp = false
|
|
379
379
|
break
|
|
380
380
|
case VolumePriceRelation.FALL_WITHOUT_VOLUME:
|
|
381
|
-
color = volumePriceColors.
|
|
381
|
+
color = volumePriceColors.fallWithout
|
|
382
382
|
isUp = false
|
|
383
383
|
break
|
|
384
384
|
default:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { RendererPlugin, RenderContext } from '../../plugin'
|
|
2
2
|
import { RENDERER_PRIORITY, GLOBAL_PANE_ID } from '../../plugin'
|
|
3
3
|
import { createHorizontalLineRect, createVerticalLineRect } from '../draw/pixelAlign'
|
|
4
|
-
import {
|
|
4
|
+
import { resolveThemeColors } from '../../tokens'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* 创建十字线渲染器插件
|
|
@@ -27,7 +27,7 @@ export function createCrosshairRendererPlugin(options: {
|
|
|
27
27
|
|
|
28
28
|
draw(context: RenderContext) {
|
|
29
29
|
const { pane, dpr, paneWidth, overlayCtx } = context
|
|
30
|
-
const colors =
|
|
30
|
+
const colors = resolveThemeColors(context.theme, context.isAsiaMarket, context.colorPresetSettings)
|
|
31
31
|
const state = options.getCrosshairState()
|
|
32
32
|
|
|
33
33
|
if (state.isDragging || !state.pos) return
|
|
@@ -50,7 +50,7 @@ export function createCrosshairRendererPlugin(options: {
|
|
|
50
50
|
ctx.rect(0, 0, paneWidth, pane.height)
|
|
51
51
|
ctx.clip()
|
|
52
52
|
|
|
53
|
-
ctx.fillStyle = colors.
|
|
53
|
+
ctx.fillStyle = colors.crosshairLine
|
|
54
54
|
|
|
55
55
|
// 绘制垂直线
|
|
56
56
|
const v = createVerticalLineRect(x, 0, pane.height, dpr)
|
|
@@ -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,7 +1,9 @@
|
|
|
1
|
-
import type {
|
|
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
|
+
import { SUB_PANE_INDICATOR_CONFIGS } from './Indicator/subPaneConfig'
|
|
6
|
+
import type { SubIndicatorType } from './Indicator'
|
|
5
7
|
|
|
6
8
|
const textWidthCache = new Map<string, number>()
|
|
7
9
|
const TEXT_WIDTH_CACHE_LIMIT = 256
|
|
@@ -21,49 +23,30 @@ function measureTextWidth(ctx: CanvasRenderingContext2D, text: string): number {
|
|
|
21
23
|
return width
|
|
22
24
|
}
|
|
23
25
|
|
|
24
|
-
/**
|
|
25
|
-
* 单个数值项
|
|
26
|
-
*/
|
|
27
26
|
export interface TitleValueItem {
|
|
28
|
-
/** 标签(如 "DIF"、"DEA") */
|
|
29
27
|
label: string
|
|
30
|
-
/** 数值 */
|
|
31
28
|
value: number
|
|
32
|
-
/** 颜色 */
|
|
33
29
|
color: string
|
|
34
30
|
}
|
|
35
31
|
|
|
36
|
-
/**
|
|
37
|
-
* 标题信息(由指标渲染器提供)
|
|
38
|
-
*/
|
|
39
32
|
export interface TitleInfo {
|
|
40
|
-
/** 指标名称(如 "MACD") */
|
|
41
33
|
name: string
|
|
42
|
-
/** 参数列表(如 [12, 26, 9]) */
|
|
43
34
|
params?: number[]
|
|
44
|
-
/** 数值项列表 */
|
|
45
35
|
values?: TitleValueItem[]
|
|
46
36
|
}
|
|
47
37
|
|
|
48
38
|
export interface PaneTitleOptions {
|
|
49
|
-
/** 面板 ID */
|
|
50
39
|
paneId: string
|
|
51
|
-
/** 标题文本(静态模式) */
|
|
52
40
|
title: string
|
|
53
|
-
/** 副标题/描述 */
|
|
54
41
|
description?: string
|
|
55
|
-
/** Y 偏移(逻辑像素) */
|
|
56
42
|
yOffset?: number
|
|
57
|
-
|
|
58
|
-
|
|
43
|
+
indicatorId: SubIndicatorType
|
|
44
|
+
params: Record<string, unknown>
|
|
59
45
|
}
|
|
60
46
|
|
|
61
|
-
|
|
62
|
-
* 创建面板标题渲染器插件
|
|
63
|
-
* 在面板左上角显示标题,支持动态指标数值显示
|
|
64
|
-
*/
|
|
65
|
-
export function createPaneTitleRendererPlugin(options: PaneTitleOptions): RendererPlugin {
|
|
47
|
+
export function createPaneTitleRendererPlugin(options: PaneTitleOptions): RendererPluginWithHost {
|
|
66
48
|
let currentOptions = { ...options }
|
|
49
|
+
let pluginHost: PluginHost | null = null
|
|
67
50
|
|
|
68
51
|
return {
|
|
69
52
|
name: `paneTitle_${options.paneId}`,
|
|
@@ -74,9 +57,13 @@ export function createPaneTitleRendererPlugin(options: PaneTitleOptions): Render
|
|
|
74
57
|
priority: RENDERER_PRIORITY.FOREGROUND,
|
|
75
58
|
layer: 'overlay',
|
|
76
59
|
|
|
60
|
+
onInstall(host: PluginHost) {
|
|
61
|
+
pluginHost = host
|
|
62
|
+
},
|
|
63
|
+
|
|
77
64
|
draw(context: RenderContext) {
|
|
78
65
|
const { overlayCtx, pane, paneWidth } = context
|
|
79
|
-
const colors =
|
|
66
|
+
const colors = resolveThemeColors(context.theme, context.isAsiaMarket, context.colorPresetSettings)
|
|
80
67
|
if (pane.id !== currentOptions.paneId || !overlayCtx) return
|
|
81
68
|
|
|
82
69
|
const fontSize = 12
|
|
@@ -89,18 +76,22 @@ export function createPaneTitleRendererPlugin(options: PaneTitleOptions): Render
|
|
|
89
76
|
overlayCtx.textAlign = 'left'
|
|
90
77
|
overlayCtx.textBaseline = 'top'
|
|
91
78
|
|
|
92
|
-
const
|
|
79
|
+
const config = SUB_PANE_INDICATOR_CONFIGS[currentOptions.indicatorId]
|
|
80
|
+
const crosshairIndex = context.crosshairIndex ?? null
|
|
81
|
+
const titleInfo = config && pluginHost
|
|
82
|
+
? config.getTitleInfo(context.data, crosshairIndex, currentOptions.params as Record<string, number | boolean | string>, pluginHost, currentOptions.paneId)
|
|
83
|
+
: null
|
|
93
84
|
|
|
94
85
|
if (titleInfo) {
|
|
95
86
|
let currentX = x
|
|
96
87
|
|
|
97
|
-
overlayCtx.fillStyle = colors.
|
|
88
|
+
overlayCtx.fillStyle = colors.text.primary
|
|
98
89
|
overlayCtx.fillText(titleInfo.name, currentX, y)
|
|
99
90
|
currentX += measureTextWidth(overlayCtx, titleInfo.name)
|
|
100
91
|
|
|
101
92
|
if (titleInfo.params && titleInfo.params.length > 0) {
|
|
102
93
|
const paramText = `(${titleInfo.params.join(',')})`
|
|
103
|
-
overlayCtx.fillStyle = colors.
|
|
94
|
+
overlayCtx.fillStyle = colors.text.tertiary
|
|
104
95
|
overlayCtx.fillText(paramText, currentX, y)
|
|
105
96
|
currentX += measureTextWidth(overlayCtx, paramText) + gap
|
|
106
97
|
} else {
|
|
@@ -116,12 +107,12 @@ export function createPaneTitleRendererPlugin(options: PaneTitleOptions): Render
|
|
|
116
107
|
}
|
|
117
108
|
}
|
|
118
109
|
} else {
|
|
119
|
-
overlayCtx.fillStyle = colors.
|
|
110
|
+
overlayCtx.fillStyle = colors.text.primary
|
|
120
111
|
overlayCtx.fillText(currentOptions.title, x, y)
|
|
121
112
|
|
|
122
113
|
if (currentOptions.description) {
|
|
123
114
|
const titleWidth = measureTextWidth(overlayCtx, currentOptions.title)
|
|
124
|
-
overlayCtx.fillStyle = colors.
|
|
115
|
+
overlayCtx.fillStyle = colors.text.weak
|
|
125
116
|
overlayCtx.fillText(` - ${currentOptions.description}`, x + titleWidth, y)
|
|
126
117
|
}
|
|
127
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
|
}
|