@363045841yyt/klinechart 0.7.4 → 0.7.5-alpha.2
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 +149 -153
- package/dist/index.cjs +2 -2
- package/dist/index.js +15 -9
- package/dist/klinechart.css +1 -1
- package/package.json +82 -76
- package/src/__tests__/_mockController.ts +192 -192
- package/src/__tests__/contract.test.ts +132 -132
- package/src/components/DrawingStyleToolbar.vue +199 -199
- package/src/components/IndicatorParams.vue +570 -570
- package/src/components/IndicatorSelector.vue +1169 -1169
- package/src/components/KLineChart.vue +1570 -1570
- package/src/components/KLineTooltip.vue +200 -200
- package/src/components/LeftToolbar.vue +844 -844
- package/src/components/MarkerTooltip.vue +155 -155
- package/src/components/index.ts +7 -7
- package/src/composables/useFullscreenTeleportTarget.ts +18 -18
- package/src/debug/canvasProfiler.ts +296 -296
- package/src/index.ts +402 -402
- package/src/version.ts +3 -3
package/package.json
CHANGED
|
@@ -1,77 +1,83 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@363045841yyt/klinechart",
|
|
3
|
-
"version": "0.7.
|
|
4
|
-
"description": "Vue 3 bindings for @363045841yyt/klinechart-core. Idiomatic composables, SFC components.",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
},
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
"@
|
|
65
|
-
"
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@363045841yyt/klinechart",
|
|
3
|
+
"version": "0.7.5-alpha.2",
|
|
4
|
+
"description": "Vue 3 bindings for @363045841yyt/klinechart-core. Idiomatic composables, SFC components.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/363045841/KLineChartQuant.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": "https://github.com/363045841/KLineChartQuant/issues",
|
|
11
|
+
"homepage": "https://363045841.github.io/KLineChartQuant/",
|
|
12
|
+
"type": "module",
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": "^20.19.0 || >=22.12.0"
|
|
15
|
+
},
|
|
16
|
+
"sideEffects": false,
|
|
17
|
+
"main": "./dist/index.js",
|
|
18
|
+
"module": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"import": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"default": "./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"require": {
|
|
27
|
+
"types": "./dist/index.d.cts",
|
|
28
|
+
"default": "./dist/index.cjs"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"./style.css": "./dist/klinechart.css"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"src"
|
|
36
|
+
],
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"dev": "vite --config preview/vite.config.ts",
|
|
42
|
+
"build": "vite build && node -e \"require('fs').copyFileSync('dist/index.d.ts','dist/index.d.cts')\"",
|
|
43
|
+
"postbuild": "node -e \"require('fs').copyFileSync('dist/index.d.ts','dist/index.d.cts')\"",
|
|
44
|
+
"test": "vitest run",
|
|
45
|
+
"test:watch": "vitest",
|
|
46
|
+
"size": "size-limit",
|
|
47
|
+
"lint:publish": "publint --strict .",
|
|
48
|
+
"prepublishOnly": "npm run build",
|
|
49
|
+
"lint:types": "attw --pack ."
|
|
50
|
+
},
|
|
51
|
+
"size-limit": [
|
|
52
|
+
{
|
|
53
|
+
"name": "vue (entry, pre-build src measurement)",
|
|
54
|
+
"path": "src/index.ts",
|
|
55
|
+
"limit": "8 KB",
|
|
56
|
+
"gzip": true,
|
|
57
|
+
"ignore": [
|
|
58
|
+
"vue",
|
|
59
|
+
"@363045841yyt/klinechart-core"
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
"peerDependencies": {
|
|
64
|
+
"@363045841yyt/klinechart-core": "^",
|
|
65
|
+
"vue": "^3.4.0"
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@arethetypeswrong/cli": "^0.18.3",
|
|
69
|
+
"@size-limit/preset-small-lib": "^12.1.0",
|
|
70
|
+
"@vitejs/plugin-vue": "^6.0.0",
|
|
71
|
+
"@vue/test-utils": "^2.4.10",
|
|
72
|
+
"jsdom": "^29.1.1",
|
|
73
|
+
"publint": "^0.3.0",
|
|
74
|
+
"size-limit": "^12.1.0",
|
|
75
|
+
"typescript": "~6.0.3",
|
|
76
|
+
"unplugin-icons": "^23.0.1",
|
|
77
|
+
"vite": "^8.0.14",
|
|
78
|
+
"vite-plugin-babel": "^1.3.2",
|
|
79
|
+
"vite-plugin-dts": "^5.0.1",
|
|
80
|
+
"vitest": "^4.1.5",
|
|
81
|
+
"vue": "^3.5.0"
|
|
82
|
+
}
|
|
77
83
|
}
|
|
@@ -1,192 +1,192 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Mock ChartController for Vue adapter tests.
|
|
3
|
-
*
|
|
4
|
-
* Mirrors the framework-agnostic signal-bearing shape from
|
|
5
|
-
* @363045841yyt/klinechart-core without spinning up the real Chart engine.
|
|
6
|
-
*
|
|
7
|
-
* To keep this test file runnable from the repo root vitest (which does not
|
|
8
|
-
* alias @363045841yyt/klinechart-core), we inline a tiny `Signal` implementation
|
|
9
|
-
* that is shape-compatible with `packages/core/src/reactivity/signal.ts`.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import type { Signal } from '@363045841yyt/klinechart-core/reactivity'
|
|
13
|
-
import type {
|
|
14
|
-
ActiveIndicator,
|
|
15
|
-
ChartController,
|
|
16
|
-
ChartMountOptions,
|
|
17
|
-
ChartViewport,
|
|
18
|
-
DrawingController,
|
|
19
|
-
DrawingState,
|
|
20
|
-
IndicatorDefinition,
|
|
21
|
-
IndicatorSelectorController,
|
|
22
|
-
KLineData,
|
|
23
|
-
ToolbarController,
|
|
24
|
-
ToolDefinition,
|
|
25
|
-
ToolId,
|
|
26
|
-
} from '@363045841yyt/klinechart-core'
|
|
27
|
-
|
|
28
|
-
// ---------------------------------------------------------------------------
|
|
29
|
-
// Inline mini-signal �?Object.is-equality, sync notify. Drop-in compatible
|
|
30
|
-
// with `@363045841yyt/klinechart-core/reactivity` for shape-only test purposes.
|
|
31
|
-
// ---------------------------------------------------------------------------
|
|
32
|
-
|
|
33
|
-
function createSignal<T>(initial: T): Signal<T> {
|
|
34
|
-
let value = initial
|
|
35
|
-
const subs = new Set<() => void>()
|
|
36
|
-
const read = (): T => value
|
|
37
|
-
const peek = (): T => value
|
|
38
|
-
const set = (next: T): void => {
|
|
39
|
-
if (Object.is(value, next)) return
|
|
40
|
-
value = next
|
|
41
|
-
for (const listener of [...subs]) listener()
|
|
42
|
-
}
|
|
43
|
-
const subscribe = (listener: () => void): (() => void) => {
|
|
44
|
-
subs.add(listener)
|
|
45
|
-
return () => {
|
|
46
|
-
subs.delete(listener)
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return Object.assign(read, { peek, set, subscribe }) as Signal<T>
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export interface MockChartController extends ChartController {
|
|
53
|
-
/** spy: how many times `dispose` was called */
|
|
54
|
-
disposeCalls: () => number
|
|
55
|
-
/** test-only signal mutators */
|
|
56
|
-
_setViewport: (vp: ChartViewport) => void
|
|
57
|
-
_setData: (data: ReadonlyArray<KLineData>) => void
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function createMockIndicatorSelector(): IndicatorSelectorController {
|
|
61
|
-
const catalog = createSignal<ReadonlyArray<IndicatorDefinition>>([])
|
|
62
|
-
const active = createSignal<ReadonlyArray<ActiveIndicator>>([])
|
|
63
|
-
const menuOpen = createSignal<boolean>(false)
|
|
64
|
-
const searchQuery = createSignal<string>('')
|
|
65
|
-
const filteredMain = createSignal<ReadonlyArray<IndicatorDefinition>>([])
|
|
66
|
-
const filteredSub = createSignal<ReadonlyArray<IndicatorDefinition>>([])
|
|
67
|
-
|
|
68
|
-
return {
|
|
69
|
-
catalog,
|
|
70
|
-
active,
|
|
71
|
-
menuOpen,
|
|
72
|
-
searchQuery,
|
|
73
|
-
filteredMain,
|
|
74
|
-
filteredSub,
|
|
75
|
-
add: () => null,
|
|
76
|
-
remove: () => false,
|
|
77
|
-
updateParams: () => false,
|
|
78
|
-
reorder: () => false,
|
|
79
|
-
openMenu: () => menuOpen.set(true),
|
|
80
|
-
closeMenu: () => menuOpen.set(false),
|
|
81
|
-
toggleMenu: () => menuOpen.set(!menuOpen.peek()),
|
|
82
|
-
setSearchQuery: (q: string) => searchQuery.set(q),
|
|
83
|
-
isActive: () => false,
|
|
84
|
-
dispose: () => {},
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function createMockToolbar(): ToolbarController {
|
|
89
|
-
const tools = createSignal<ReadonlyArray<ToolDefinition>>([])
|
|
90
|
-
const activeTool = createSignal<ToolId | null>(null)
|
|
91
|
-
const disabledTools = createSignal<ReadonlySet<ToolId>>(new Set())
|
|
92
|
-
return {
|
|
93
|
-
tools,
|
|
94
|
-
activeTool,
|
|
95
|
-
disabledTools,
|
|
96
|
-
selectTool: (id) => activeTool.set(id),
|
|
97
|
-
clearSelection: () => activeTool.set(null),
|
|
98
|
-
setDisabled: () => {},
|
|
99
|
-
dispose: () => {},
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function createMockDrawing(): DrawingController {
|
|
104
|
-
const state = createSignal<DrawingState>({
|
|
105
|
-
activeTool: null,
|
|
106
|
-
drawingCount: 0,
|
|
107
|
-
})
|
|
108
|
-
return {
|
|
109
|
-
state,
|
|
110
|
-
setActiveTool: (tool) =>
|
|
111
|
-
state.set({ ...state.peek(), activeTool: tool }),
|
|
112
|
-
clearAll: () => state.set({ ...state.peek(), drawingCount: 0 }),
|
|
113
|
-
deleteLast: () =>
|
|
114
|
-
state.set({
|
|
115
|
-
...state.peek(),
|
|
116
|
-
drawingCount: Math.max(0, state.peek().drawingCount - 1),
|
|
117
|
-
}),
|
|
118
|
-
dispose: () => {},
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export function createMockChartController(
|
|
123
|
-
opts: Partial<ChartMountOptions> = {},
|
|
124
|
-
): MockChartController {
|
|
125
|
-
let disposeCalls = 0
|
|
126
|
-
|
|
127
|
-
const viewport = createSignal<ChartViewport>({
|
|
128
|
-
zoomLevel: opts.initialZoomLevel ?? 3,
|
|
129
|
-
kWidth: 6,
|
|
130
|
-
visibleFrom: 0,
|
|
131
|
-
visibleTo: 0,
|
|
132
|
-
})
|
|
133
|
-
const data = createSignal<ReadonlyArray<KLineData>>(opts.data ?? [])
|
|
134
|
-
const theme = createSignal<'light' | 'dark'>(opts.theme ?? 'light')
|
|
135
|
-
const indicatorSelector = createMockIndicatorSelector()
|
|
136
|
-
const toolbar = createMockToolbar()
|
|
137
|
-
const drawing = createMockDrawing()
|
|
138
|
-
|
|
139
|
-
return {
|
|
140
|
-
viewport,
|
|
141
|
-
data,
|
|
142
|
-
theme,
|
|
143
|
-
indicatorSelector,
|
|
144
|
-
toolbar,
|
|
145
|
-
drawing,
|
|
146
|
-
setData: (next) => data.set(next),
|
|
147
|
-
appendData: (next) => data.set([...data.peek(), ...next]),
|
|
148
|
-
updateData: (next) => data.set(next),
|
|
149
|
-
setTheme: (next) => theme.set(next),
|
|
150
|
-
zoomToLevel: (level) =>
|
|
151
|
-
viewport.set({ ...viewport.peek(), zoomLevel: level }),
|
|
152
|
-
zoomIn: () =>
|
|
153
|
-
viewport.set({
|
|
154
|
-
...viewport.peek(),
|
|
155
|
-
zoomLevel: viewport.peek().zoomLevel + 1,
|
|
156
|
-
}),
|
|
157
|
-
zoomOut: () =>
|
|
158
|
-
viewport.set({
|
|
159
|
-
...viewport.peek(),
|
|
160
|
-
zoomLevel: viewport.peek().zoomLevel - 1,
|
|
161
|
-
}),
|
|
162
|
-
handlePointerEvent: () => false,
|
|
163
|
-
handleWheelEvent: () => {},
|
|
164
|
-
handleScrollEvent: () => {},
|
|
165
|
-
handlePinchZoom: () => {},
|
|
166
|
-
addIndicator: () => null,
|
|
167
|
-
removeIndicator: () => false,
|
|
168
|
-
updateIndicatorParams: () => false,
|
|
169
|
-
updateRendererConfig: () => {},
|
|
170
|
-
setDrawingTool: (tool) => drawing.setActiveTool(tool),
|
|
171
|
-
clearDrawings: () => drawing.clearAll(),
|
|
172
|
-
removeDrawing: () => {},
|
|
173
|
-
resizeSubPane: () => false,
|
|
174
|
-
createSubPane: () => false,
|
|
175
|
-
clearSubPanes: () => {},
|
|
176
|
-
updateCustomMarkers: () => {},
|
|
177
|
-
clearCustomMarkers: () => {},
|
|
178
|
-
updateSettingsFacade: () => {},
|
|
179
|
-
updateOptionsFacade: () => {},
|
|
180
|
-
dispose: () => {
|
|
181
|
-
disposeCalls += 1
|
|
182
|
-
},
|
|
183
|
-
disposeCalls: () => disposeCalls,
|
|
184
|
-
_setViewport: (vp) => viewport.set(vp),
|
|
185
|
-
_setData: (next) => data.set(next),
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/** Signal helper used by reactivity bridge tests. */
|
|
190
|
-
export function createTestSignal<T>(initial: T): Signal<T> {
|
|
191
|
-
return createSignal(initial)
|
|
192
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Mock ChartController for Vue adapter tests.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the framework-agnostic signal-bearing shape from
|
|
5
|
+
* @363045841yyt/klinechart-core without spinning up the real Chart engine.
|
|
6
|
+
*
|
|
7
|
+
* To keep this test file runnable from the repo root vitest (which does not
|
|
8
|
+
* alias @363045841yyt/klinechart-core), we inline a tiny `Signal` implementation
|
|
9
|
+
* that is shape-compatible with `packages/core/src/reactivity/signal.ts`.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { Signal } from '@363045841yyt/klinechart-core/reactivity'
|
|
13
|
+
import type {
|
|
14
|
+
ActiveIndicator,
|
|
15
|
+
ChartController,
|
|
16
|
+
ChartMountOptions,
|
|
17
|
+
ChartViewport,
|
|
18
|
+
DrawingController,
|
|
19
|
+
DrawingState,
|
|
20
|
+
IndicatorDefinition,
|
|
21
|
+
IndicatorSelectorController,
|
|
22
|
+
KLineData,
|
|
23
|
+
ToolbarController,
|
|
24
|
+
ToolDefinition,
|
|
25
|
+
ToolId,
|
|
26
|
+
} from '@363045841yyt/klinechart-core'
|
|
27
|
+
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Inline mini-signal �?Object.is-equality, sync notify. Drop-in compatible
|
|
30
|
+
// with `@363045841yyt/klinechart-core/reactivity` for shape-only test purposes.
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
function createSignal<T>(initial: T): Signal<T> {
|
|
34
|
+
let value = initial
|
|
35
|
+
const subs = new Set<() => void>()
|
|
36
|
+
const read = (): T => value
|
|
37
|
+
const peek = (): T => value
|
|
38
|
+
const set = (next: T): void => {
|
|
39
|
+
if (Object.is(value, next)) return
|
|
40
|
+
value = next
|
|
41
|
+
for (const listener of [...subs]) listener()
|
|
42
|
+
}
|
|
43
|
+
const subscribe = (listener: () => void): (() => void) => {
|
|
44
|
+
subs.add(listener)
|
|
45
|
+
return () => {
|
|
46
|
+
subs.delete(listener)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return Object.assign(read, { peek, set, subscribe }) as Signal<T>
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface MockChartController extends ChartController {
|
|
53
|
+
/** spy: how many times `dispose` was called */
|
|
54
|
+
disposeCalls: () => number
|
|
55
|
+
/** test-only signal mutators */
|
|
56
|
+
_setViewport: (vp: ChartViewport) => void
|
|
57
|
+
_setData: (data: ReadonlyArray<KLineData>) => void
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function createMockIndicatorSelector(): IndicatorSelectorController {
|
|
61
|
+
const catalog = createSignal<ReadonlyArray<IndicatorDefinition>>([])
|
|
62
|
+
const active = createSignal<ReadonlyArray<ActiveIndicator>>([])
|
|
63
|
+
const menuOpen = createSignal<boolean>(false)
|
|
64
|
+
const searchQuery = createSignal<string>('')
|
|
65
|
+
const filteredMain = createSignal<ReadonlyArray<IndicatorDefinition>>([])
|
|
66
|
+
const filteredSub = createSignal<ReadonlyArray<IndicatorDefinition>>([])
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
catalog,
|
|
70
|
+
active,
|
|
71
|
+
menuOpen,
|
|
72
|
+
searchQuery,
|
|
73
|
+
filteredMain,
|
|
74
|
+
filteredSub,
|
|
75
|
+
add: () => null,
|
|
76
|
+
remove: () => false,
|
|
77
|
+
updateParams: () => false,
|
|
78
|
+
reorder: () => false,
|
|
79
|
+
openMenu: () => menuOpen.set(true),
|
|
80
|
+
closeMenu: () => menuOpen.set(false),
|
|
81
|
+
toggleMenu: () => menuOpen.set(!menuOpen.peek()),
|
|
82
|
+
setSearchQuery: (q: string) => searchQuery.set(q),
|
|
83
|
+
isActive: () => false,
|
|
84
|
+
dispose: () => {},
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function createMockToolbar(): ToolbarController {
|
|
89
|
+
const tools = createSignal<ReadonlyArray<ToolDefinition>>([])
|
|
90
|
+
const activeTool = createSignal<ToolId | null>(null)
|
|
91
|
+
const disabledTools = createSignal<ReadonlySet<ToolId>>(new Set())
|
|
92
|
+
return {
|
|
93
|
+
tools,
|
|
94
|
+
activeTool,
|
|
95
|
+
disabledTools,
|
|
96
|
+
selectTool: (id) => activeTool.set(id),
|
|
97
|
+
clearSelection: () => activeTool.set(null),
|
|
98
|
+
setDisabled: () => {},
|
|
99
|
+
dispose: () => {},
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function createMockDrawing(): DrawingController {
|
|
104
|
+
const state = createSignal<DrawingState>({
|
|
105
|
+
activeTool: null,
|
|
106
|
+
drawingCount: 0,
|
|
107
|
+
})
|
|
108
|
+
return {
|
|
109
|
+
state,
|
|
110
|
+
setActiveTool: (tool) =>
|
|
111
|
+
state.set({ ...state.peek(), activeTool: tool }),
|
|
112
|
+
clearAll: () => state.set({ ...state.peek(), drawingCount: 0 }),
|
|
113
|
+
deleteLast: () =>
|
|
114
|
+
state.set({
|
|
115
|
+
...state.peek(),
|
|
116
|
+
drawingCount: Math.max(0, state.peek().drawingCount - 1),
|
|
117
|
+
}),
|
|
118
|
+
dispose: () => {},
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function createMockChartController(
|
|
123
|
+
opts: Partial<ChartMountOptions> = {},
|
|
124
|
+
): MockChartController {
|
|
125
|
+
let disposeCalls = 0
|
|
126
|
+
|
|
127
|
+
const viewport = createSignal<ChartViewport>({
|
|
128
|
+
zoomLevel: opts.initialZoomLevel ?? 3,
|
|
129
|
+
kWidth: 6,
|
|
130
|
+
visibleFrom: 0,
|
|
131
|
+
visibleTo: 0,
|
|
132
|
+
})
|
|
133
|
+
const data = createSignal<ReadonlyArray<KLineData>>(opts.data ?? [])
|
|
134
|
+
const theme = createSignal<'light' | 'dark'>(opts.theme ?? 'light')
|
|
135
|
+
const indicatorSelector = createMockIndicatorSelector()
|
|
136
|
+
const toolbar = createMockToolbar()
|
|
137
|
+
const drawing = createMockDrawing()
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
viewport,
|
|
141
|
+
data,
|
|
142
|
+
theme,
|
|
143
|
+
indicatorSelector,
|
|
144
|
+
toolbar,
|
|
145
|
+
drawing,
|
|
146
|
+
setData: (next) => data.set(next),
|
|
147
|
+
appendData: (next) => data.set([...data.peek(), ...next]),
|
|
148
|
+
updateData: (next) => data.set(next),
|
|
149
|
+
setTheme: (next) => theme.set(next),
|
|
150
|
+
zoomToLevel: (level) =>
|
|
151
|
+
viewport.set({ ...viewport.peek(), zoomLevel: level }),
|
|
152
|
+
zoomIn: () =>
|
|
153
|
+
viewport.set({
|
|
154
|
+
...viewport.peek(),
|
|
155
|
+
zoomLevel: viewport.peek().zoomLevel + 1,
|
|
156
|
+
}),
|
|
157
|
+
zoomOut: () =>
|
|
158
|
+
viewport.set({
|
|
159
|
+
...viewport.peek(),
|
|
160
|
+
zoomLevel: viewport.peek().zoomLevel - 1,
|
|
161
|
+
}),
|
|
162
|
+
handlePointerEvent: () => false,
|
|
163
|
+
handleWheelEvent: () => {},
|
|
164
|
+
handleScrollEvent: () => {},
|
|
165
|
+
handlePinchZoom: () => {},
|
|
166
|
+
addIndicator: () => null,
|
|
167
|
+
removeIndicator: () => false,
|
|
168
|
+
updateIndicatorParams: () => false,
|
|
169
|
+
updateRendererConfig: () => {},
|
|
170
|
+
setDrawingTool: (tool) => drawing.setActiveTool(tool),
|
|
171
|
+
clearDrawings: () => drawing.clearAll(),
|
|
172
|
+
removeDrawing: () => {},
|
|
173
|
+
resizeSubPane: () => false,
|
|
174
|
+
createSubPane: () => false,
|
|
175
|
+
clearSubPanes: () => {},
|
|
176
|
+
updateCustomMarkers: () => {},
|
|
177
|
+
clearCustomMarkers: () => {},
|
|
178
|
+
updateSettingsFacade: () => {},
|
|
179
|
+
updateOptionsFacade: () => {},
|
|
180
|
+
dispose: () => {
|
|
181
|
+
disposeCalls += 1
|
|
182
|
+
},
|
|
183
|
+
disposeCalls: () => disposeCalls,
|
|
184
|
+
_setViewport: (vp) => viewport.set(vp),
|
|
185
|
+
_setData: (next) => data.set(next),
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** Signal helper used by reactivity bridge tests. */
|
|
190
|
+
export function createTestSignal<T>(initial: T): Signal<T> {
|
|
191
|
+
return createSignal(initial)
|
|
192
|
+
}
|