@363045841yyt/klinechart-core 0.7.5 → 0.7.6

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 (59) hide show
  1. package/README.md +8 -8
  2. package/README.zh-CN.md +8 -8
  3. package/dist/controllers/createChartController.d.ts.map +1 -1
  4. package/dist/controllers/createChartController.js +145 -21
  5. package/dist/controllers/createChartController.js.map +1 -1
  6. package/dist/controllers/index.d.ts +9 -1
  7. package/dist/controllers/index.d.ts.map +1 -1
  8. package/dist/controllers/index.js +9 -0
  9. package/dist/controllers/index.js.map +1 -1
  10. package/dist/controllers/types.d.ts +65 -8
  11. package/dist/controllers/types.d.ts.map +1 -1
  12. package/dist/engine/chart.d.ts +2 -12
  13. package/dist/engine/chart.d.ts.map +1 -1
  14. package/dist/engine/chart.js +28 -31
  15. package/dist/engine/chart.js.map +1 -1
  16. package/dist/engine/controller/interaction.d.ts +1 -1
  17. package/dist/engine/controller/interaction.d.ts.map +1 -1
  18. package/dist/engine/controller/interaction.js +10 -2
  19. package/dist/engine/controller/interaction.js.map +1 -1
  20. package/dist/engine/drawing/interaction.d.ts +3 -3
  21. package/dist/engine/drawing/interaction.d.ts.map +1 -1
  22. package/dist/engine/drawing/interaction.js +38 -46
  23. package/dist/engine/drawing/interaction.js.map +1 -1
  24. package/dist/engine/renderers/paneTitle.d.ts +5 -24
  25. package/dist/engine/renderers/paneTitle.d.ts.map +1 -1
  26. package/dist/engine/renderers/paneTitle.js +10 -5
  27. package/dist/engine/renderers/paneTitle.js.map +1 -1
  28. package/dist/engine/renderers/webgl/candleSurface.d.ts +4 -4
  29. package/dist/engine/renderers/webgl/candleSurface.d.ts.map +1 -1
  30. package/dist/engine/renderers/webgl/candleSurface.js +36 -56
  31. package/dist/engine/renderers/webgl/candleSurface.js.map +1 -1
  32. package/dist/engine/subPaneManager.d.ts +2 -0
  33. package/dist/engine/subPaneManager.d.ts.map +1 -1
  34. package/dist/engine/subPaneManager.js +25 -1
  35. package/dist/engine/subPaneManager.js.map +1 -1
  36. package/dist/semantic/controller.d.ts +1 -2
  37. package/dist/semantic/controller.d.ts.map +1 -1
  38. package/dist/semantic/index.d.ts +1 -1
  39. package/dist/semantic/index.d.ts.map +1 -1
  40. package/dist/version.d.ts +1 -1
  41. package/dist/version.js +1 -1
  42. package/package.json +6 -6
  43. package/src/controllers/createChartController.ts +158 -29
  44. package/src/controllers/index.ts +33 -0
  45. package/src/controllers/types.ts +79 -8
  46. package/src/engine/chart.ts +28 -37
  47. package/src/engine/controller/interaction.ts +9 -2
  48. package/src/engine/drawing/interaction.ts +38 -47
  49. package/src/engine/renderers/paneTitle.ts +16 -25
  50. package/src/engine/renderers/webgl/candleSurface.ts +40 -56
  51. package/src/engine/subPaneManager.ts +28 -1
  52. package/src/semantic/controller.ts +1 -1
  53. package/src/semantic/index.ts +1 -1
  54. package/src/version.ts +1 -1
  55. package/dist/engine/chart-store.d.ts +0 -75
  56. package/dist/engine/chart-store.d.ts.map +0 -1
  57. package/dist/engine/chart-store.js +0 -88
  58. package/dist/engine/chart-store.js.map +0 -1
  59. package/src/engine/chart-store.ts +0 -121
@@ -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
  }
@@ -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
 
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = "0.7.5"
1
+ export const VERSION = "0.7.6"
@@ -1,75 +0,0 @@
1
- import { type UnwrapNestedRefs } from 'vue';
2
- import type { DrawingObject } from '../plugin';
3
- /** 右侧空白绘制槽位数(逻辑 bar 数) */
4
- export declare const TRAILING_DRAWING_SLOTS = 24;
5
- export interface ChartStoreOptions {
6
- initialZoomLevel: number;
7
- minKWidth: number;
8
- maxKWidth: number;
9
- zoomLevels: number;
10
- rightAxisWidth: number;
11
- priceLabelWidth: number;
12
- }
13
- export declare function computeContentWidth(params: {
14
- dataLength: number;
15
- kWidth: number;
16
- kGap: number;
17
- viewWidth: number;
18
- viewportDpr: number;
19
- }): number;
20
- export declare function createChartStore(opts: ChartStoreOptions): {
21
- state: UnwrapNestedRefs<{
22
- zoomLevel: number;
23
- kWidth: number;
24
- kGap: number;
25
- viewportDpr: number;
26
- dataLength: number;
27
- dataVersion: number;
28
- paneRatios: Record<string, number>;
29
- drawings: {
30
- id: string;
31
- kind: import("./drawing").DrawingKind;
32
- paneId: string;
33
- visible: boolean;
34
- locked?: boolean | undefined;
35
- zIndex?: number | undefined;
36
- anchors: {
37
- id: string;
38
- index: number;
39
- time?: number | string | undefined;
40
- price: number;
41
- }[];
42
- params: Record<string, unknown>;
43
- style: {
44
- stroke?: string | undefined;
45
- strokeWidth?: number | undefined;
46
- strokeStyle?: "solid" | "dashed" | "dotted" | undefined;
47
- fill?: string | undefined;
48
- fillOpacity?: number | undefined;
49
- pointRadius?: number | undefined;
50
- textColor?: string | undefined;
51
- fontSize?: number | undefined;
52
- };
53
- }[];
54
- selectedDrawingId: string | null;
55
- drawingVersion: number;
56
- viewWidth: number;
57
- }>;
58
- computed: {
59
- axisHostWidth: import("vue").ComputedRef<number>;
60
- totalWidth: import("vue").ComputedRef<number>;
61
- };
62
- actions: {
63
- bumpDataVersion: () => void;
64
- bumpDrawingVersion: () => void;
65
- setDataLength: (length: number) => void;
66
- setViewportDpr: (dpr: number) => void;
67
- setViewWidth: (width: number) => void;
68
- setZoomState: (level: number, newKWidth: number, newKGap: number) => void;
69
- setPaneRatios: (ratios: Record<string, number>) => void;
70
- setDrawings: (newDrawings: DrawingObject[]) => void;
71
- setSelectedDrawingId: (id: string | null) => void;
72
- };
73
- };
74
- export type ChartStore = ReturnType<typeof createChartStore>;
75
- //# sourceMappingURL=chart-store.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chart-store.d.ts","sourceRoot":"","sources":["../../src/engine/chart-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,KAAK,CAAA;AAE/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAE9C,0BAA0B;AAC1B,eAAO,MAAM,sBAAsB,KAAK,CAAA;AAExC,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAC1C,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;CACpB,GAAG,MAAM,CAMT;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB;WAuEpC,gBAAgB;;;;;;;oBA/Dd,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;2BAEb,MAAM,GAAG,IAAI;;;MA6DM;;;;;;;;gCAnCjB,MAAM;8BAIR,MAAM;8BAIN,MAAM;8BAIN,MAAM,aAAa,MAAM,WAAW,MAAM;gCAMxC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;mCAInB,aAAa,EAAE;mCAQf,MAAM,GAAG,IAAI;;EAsBhD;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAA"}
@@ -1,88 +0,0 @@
1
- import { reactive, computed } from 'vue';
2
- import { getPhysicalKLineConfig } from './utils/klineConfig';
3
- /** 右侧空白绘制槽位数(逻辑 bar 数) */
4
- export const TRAILING_DRAWING_SLOTS = 24;
5
- export function computeContentWidth(params) {
6
- const { dataLength, kWidth, kGap, viewWidth, viewportDpr } = params;
7
- if (dataLength === 0)
8
- return 0;
9
- const { startXPx, unitPx } = getPhysicalKLineConfig(kWidth, kGap, viewportDpr);
10
- const dataPlotWidth = (startXPx + (dataLength + TRAILING_DRAWING_SLOTS) * unitPx) / viewportDpr;
11
- return Math.max(dataPlotWidth, viewWidth);
12
- }
13
- export function createChartStore(opts) {
14
- const state = reactive({
15
- zoomLevel: opts.initialZoomLevel,
16
- kWidth: 0,
17
- kGap: 1,
18
- viewportDpr: 1,
19
- dataLength: 0,
20
- dataVersion: 0,
21
- paneRatios: {},
22
- drawings: [],
23
- selectedDrawingId: null,
24
- drawingVersion: 0,
25
- viewWidth: 0,
26
- });
27
- // 右侧轴宽度
28
- const axisHostWidth = computed(() => opts.rightAxisWidth + opts.priceLabelWidth);
29
- const totalWidth = computed(() => computeContentWidth({
30
- dataLength: state.dataLength,
31
- kWidth: state.kWidth,
32
- kGap: state.kGap,
33
- viewWidth: state.viewWidth,
34
- viewportDpr: state.viewportDpr,
35
- }));
36
- function bumpDataVersion() {
37
- state.dataVersion++;
38
- }
39
- function bumpDrawingVersion() {
40
- state.drawingVersion++;
41
- }
42
- function setDataLength(length) {
43
- state.dataLength = length;
44
- }
45
- function setViewportDpr(dpr) {
46
- state.viewportDpr = dpr;
47
- }
48
- function setViewWidth(width) {
49
- state.viewWidth = width;
50
- }
51
- function setZoomState(level, newKWidth, newKGap) {
52
- state.zoomLevel = level;
53
- state.kWidth = newKWidth;
54
- state.kGap = newKGap;
55
- }
56
- function setPaneRatios(ratios) {
57
- state.paneRatios = ratios;
58
- }
59
- function setDrawings(newDrawings) {
60
- state.drawings = newDrawings;
61
- if (state.selectedDrawingId && !newDrawings.some((d) => d.id === state.selectedDrawingId)) {
62
- state.selectedDrawingId = null;
63
- }
64
- state.drawingVersion++;
65
- }
66
- function setSelectedDrawingId(id) {
67
- state.selectedDrawingId = id;
68
- }
69
- return {
70
- state: state,
71
- computed: {
72
- axisHostWidth,
73
- totalWidth,
74
- },
75
- actions: {
76
- bumpDataVersion,
77
- bumpDrawingVersion,
78
- setDataLength,
79
- setViewportDpr,
80
- setViewWidth,
81
- setZoomState,
82
- setPaneRatios,
83
- setDrawings,
84
- setSelectedDrawingId,
85
- },
86
- };
87
- }
88
- //# sourceMappingURL=chart-store.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chart-store.js","sourceRoot":"","sources":["../../src/engine/chart-store.ts"],"names":[],"mappings":"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"}
@@ -1,121 +0,0 @@
1
- import { reactive, computed, type UnwrapNestedRefs } from 'vue'
2
- import { getPhysicalKLineConfig } from './utils/klineConfig'
3
- import type { DrawingObject } from '../plugin'
4
-
5
- /** 右侧空白绘制槽位数(逻辑 bar 数) */
6
- export const TRAILING_DRAWING_SLOTS = 24
7
-
8
- export interface ChartStoreOptions {
9
- initialZoomLevel: number
10
- minKWidth: number
11
- maxKWidth: number
12
- zoomLevels: number
13
- rightAxisWidth: number
14
- priceLabelWidth: number
15
- }
16
-
17
- export function computeContentWidth(params: {
18
- dataLength: number
19
- kWidth: number
20
- kGap: number
21
- viewWidth: number
22
- viewportDpr: number
23
- }): number {
24
- const { dataLength, kWidth, kGap, viewWidth, viewportDpr } = params
25
- if (dataLength === 0) return 0
26
- const { startXPx, unitPx } = getPhysicalKLineConfig(kWidth, kGap, viewportDpr)
27
- const dataPlotWidth = (startXPx + (dataLength + TRAILING_DRAWING_SLOTS) * unitPx) / viewportDpr
28
- return Math.max(dataPlotWidth, viewWidth)
29
- }
30
-
31
- export function createChartStore(opts: ChartStoreOptions) {
32
- const state = reactive({
33
- zoomLevel: opts.initialZoomLevel,
34
- kWidth: 0,
35
- kGap: 1,
36
- viewportDpr: 1,
37
- dataLength: 0,
38
- dataVersion: 0,
39
- paneRatios: {} as Record<string, number>,
40
- drawings: [] as DrawingObject[],
41
- selectedDrawingId: null as string | null,
42
- drawingVersion: 0,
43
- viewWidth: 0,
44
- })
45
-
46
- // 右侧轴宽度
47
- const axisHostWidth = computed(() => opts.rightAxisWidth + opts.priceLabelWidth)
48
-
49
- const totalWidth = computed(() =>
50
- computeContentWidth({
51
- dataLength: state.dataLength,
52
- kWidth: state.kWidth,
53
- kGap: state.kGap,
54
- viewWidth: state.viewWidth,
55
- viewportDpr: state.viewportDpr,
56
- }),
57
- )
58
-
59
- function bumpDataVersion() {
60
- state.dataVersion++
61
- }
62
-
63
- function bumpDrawingVersion() {
64
- state.drawingVersion++
65
- }
66
-
67
- function setDataLength(length: number) {
68
- state.dataLength = length
69
- }
70
-
71
- function setViewportDpr(dpr: number) {
72
- state.viewportDpr = dpr
73
- }
74
-
75
- function setViewWidth(width: number) {
76
- state.viewWidth = width
77
- }
78
-
79
- function setZoomState(level: number, newKWidth: number, newKGap: number) {
80
- state.zoomLevel = level
81
- state.kWidth = newKWidth
82
- state.kGap = newKGap
83
- }
84
-
85
- function setPaneRatios(ratios: Record<string, number>) {
86
- state.paneRatios = ratios
87
- }
88
-
89
- function setDrawings(newDrawings: DrawingObject[]) {
90
- state.drawings = newDrawings
91
- if (state.selectedDrawingId && !newDrawings.some((d) => d.id === state.selectedDrawingId)) {
92
- state.selectedDrawingId = null
93
- }
94
- state.drawingVersion++
95
- }
96
-
97
- function setSelectedDrawingId(id: string | null) {
98
- state.selectedDrawingId = id
99
- }
100
-
101
- return {
102
- state: state as UnwrapNestedRefs<typeof state>,
103
- computed: {
104
- axisHostWidth,
105
- totalWidth,
106
- },
107
- actions: {
108
- bumpDataVersion,
109
- bumpDrawingVersion,
110
- setDataLength,
111
- setViewportDpr,
112
- setViewWidth,
113
- setZoomState,
114
- setPaneRatios,
115
- setDrawings,
116
- setSelectedDrawingId,
117
- },
118
- }
119
- }
120
-
121
- export type ChartStore = ReturnType<typeof createChartStore>