@363045841yyt/klinechart 0.7.5-alpha.2 → 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.
- package/dist/components/DrawingStyleToolbar.vue.d.ts +1 -15
- package/dist/components/DrawingStyleToolbar.vue.d.ts.map +1 -1
- package/dist/components/IndicatorParams.vue.d.ts.map +1 -1
- package/dist/components/IndicatorSelector.vue.d.ts.map +1 -1
- package/dist/components/KLineChart.vue.d.ts +5 -6
- package/dist/components/KLineChart.vue.d.ts.map +1 -1
- package/dist/components/KLineTooltip.vue.d.ts +1 -1
- package/dist/components/KLineTooltip.vue.d.ts.map +1 -1
- package/dist/components/MarkerTooltip.vue.d.ts +1 -12
- package/dist/components/MarkerTooltip.vue.d.ts.map +1 -1
- package/dist/composables/useFullscreenTeleportTarget.d.ts.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/{klinechart.css → index.css} +1 -2
- package/dist/index.d.cts +25 -4
- package/dist/index.d.ts +25 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +792 -841
- package/dist/version.d.ts +1 -1
- package/dist/web-component.d.ts +18 -0
- package/dist/web-component.d.ts.map +1 -0
- package/package.json +10 -2
- package/src/__tests__/_mockController.ts +11 -1
- package/src/components/DrawingStyleToolbar.vue +1 -14
- package/src/components/IndicatorParams.vue +2 -1
- package/src/components/IndicatorSelector.vue +63 -63
- package/src/components/KLineChart.vue +248 -546
- package/src/components/KLineTooltip.vue +2 -2
- package/src/components/MarkerTooltip.vue +1 -12
- package/src/composables/useFullscreenTeleportTarget.ts +0 -2
- package/src/index.ts +72 -0
- package/src/web-component.ts +14 -0
package/dist/version.d.ts
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SemanticChartConfig, DataFetcher } from '@363045841yyt/klinechart-core/semantic';
|
|
2
|
+
declare const KLineChartElement: import('vue').VueElementConstructor<{
|
|
3
|
+
semanticConfig: SemanticChartConfig;
|
|
4
|
+
dataFetcher: DataFetcher;
|
|
5
|
+
yPaddingPx?: number;
|
|
6
|
+
minKWidth?: number;
|
|
7
|
+
maxKWidth?: number;
|
|
8
|
+
rightAxisWidth?: number;
|
|
9
|
+
bottomAxisHeight?: number;
|
|
10
|
+
priceLabelWidth?: number;
|
|
11
|
+
zoomLevels?: number;
|
|
12
|
+
initialZoomLevel?: number;
|
|
13
|
+
isFullscreen?: boolean;
|
|
14
|
+
}>;
|
|
15
|
+
export { KLineChartElement };
|
|
16
|
+
export default KLineChartElement;
|
|
17
|
+
export type { SemanticChartConfig, DataFetcher };
|
|
18
|
+
//# sourceMappingURL=web-component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-component.d.ts","sourceRoot":"","sources":["../src/web-component.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAA;AAE9F,QAAA,MAAM,iBAAiB;;;;;;;;;;;;EAErB,CAAA;AAIF,OAAO,EAAE,iBAAiB,EAAE,CAAA;AAC5B,eAAe,iBAAiB,CAAA;AAEhC,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@363045841yyt/klinechart",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.6",
|
|
4
4
|
"description": "Vue 3 bindings for @363045841yyt/klinechart-core. Idiomatic composables, SFC components.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -28,6 +28,11 @@
|
|
|
28
28
|
"default": "./dist/index.cjs"
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
|
+
"./web-component": {
|
|
32
|
+
"import": {
|
|
33
|
+
"default": "./dist/kline-chart.js"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
31
36
|
"./style.css": "./dist/klinechart.css"
|
|
32
37
|
},
|
|
33
38
|
"files": [
|
|
@@ -39,7 +44,8 @@
|
|
|
39
44
|
},
|
|
40
45
|
"scripts": {
|
|
41
46
|
"dev": "vite --config preview/vite.config.ts",
|
|
42
|
-
"build": "vite build
|
|
47
|
+
"build": "vite build",
|
|
48
|
+
"build:wc": "cross-env BUILD_TARGET=web-component vite build",
|
|
43
49
|
"postbuild": "node -e \"require('fs').copyFileSync('dist/index.d.ts','dist/index.d.cts')\"",
|
|
44
50
|
"test": "vitest run",
|
|
45
51
|
"test:watch": "vitest",
|
|
@@ -69,6 +75,7 @@
|
|
|
69
75
|
"@size-limit/preset-small-lib": "^12.1.0",
|
|
70
76
|
"@vitejs/plugin-vue": "^6.0.0",
|
|
71
77
|
"@vue/test-utils": "^2.4.10",
|
|
78
|
+
"cross-env": "^7.0.3",
|
|
72
79
|
"jsdom": "^29.1.1",
|
|
73
80
|
"publint": "^0.3.0",
|
|
74
81
|
"size-limit": "^12.1.0",
|
|
@@ -76,6 +83,7 @@
|
|
|
76
83
|
"unplugin-icons": "^23.0.1",
|
|
77
84
|
"vite": "^8.0.14",
|
|
78
85
|
"vite-plugin-babel": "^1.3.2",
|
|
86
|
+
"vite-plugin-css-injected-by-js": "^5.0.1",
|
|
79
87
|
"vite-plugin-dts": "^5.0.1",
|
|
80
88
|
"vitest": "^4.1.5",
|
|
81
89
|
"vue": "^3.5.0"
|
|
@@ -20,13 +20,14 @@ import type {
|
|
|
20
20
|
IndicatorDefinition,
|
|
21
21
|
IndicatorSelectorController,
|
|
22
22
|
KLineData,
|
|
23
|
+
PaneSpec,
|
|
23
24
|
ToolbarController,
|
|
24
25
|
ToolDefinition,
|
|
25
26
|
ToolId,
|
|
26
27
|
} from '@363045841yyt/klinechart-core'
|
|
27
28
|
|
|
28
29
|
// ---------------------------------------------------------------------------
|
|
29
|
-
// Inline mini-signal �?Object.is-equality, sync notify. Drop-in compatible
|
|
30
|
+
// Inline mini-signal �?Object.is-equality, sync notify. Drop-in compatible
|
|
30
31
|
// with `@363045841yyt/klinechart-core/reactivity` for shape-only test purposes.
|
|
31
32
|
// ---------------------------------------------------------------------------
|
|
32
33
|
|
|
@@ -132,6 +133,7 @@ export function createMockChartController(
|
|
|
132
133
|
})
|
|
133
134
|
const data = createSignal<ReadonlyArray<KLineData>>(opts.data ?? [])
|
|
134
135
|
const theme = createSignal<'light' | 'dark'>(opts.theme ?? 'light')
|
|
136
|
+
const paneLayout = createSignal<ReadonlyArray<PaneSpec>>([])
|
|
135
137
|
const indicatorSelector = createMockIndicatorSelector()
|
|
136
138
|
const toolbar = createMockToolbar()
|
|
137
139
|
const drawing = createMockDrawing()
|
|
@@ -140,12 +142,15 @@ export function createMockChartController(
|
|
|
140
142
|
viewport,
|
|
141
143
|
data,
|
|
142
144
|
theme,
|
|
145
|
+
paneLayout,
|
|
143
146
|
indicatorSelector,
|
|
144
147
|
toolbar,
|
|
145
148
|
drawing,
|
|
146
149
|
setData: (next) => data.set(next),
|
|
147
150
|
appendData: (next) => data.set([...data.peek(), ...next]),
|
|
148
151
|
updateData: (next) => data.set(next),
|
|
152
|
+
getData: () => data.peek(),
|
|
153
|
+
getZoomLevelCount: () => 10,
|
|
149
154
|
setTheme: (next) => theme.set(next),
|
|
150
155
|
zoomToLevel: (level) =>
|
|
151
156
|
viewport.set({ ...viewport.peek(), zoomLevel: level }),
|
|
@@ -167,12 +172,17 @@ export function createMockChartController(
|
|
|
167
172
|
removeIndicator: () => false,
|
|
168
173
|
updateIndicatorParams: () => false,
|
|
169
174
|
updateRendererConfig: () => {},
|
|
175
|
+
setTooltipSize: () => {},
|
|
176
|
+
setTooltipAnchorPositioning: () => {},
|
|
177
|
+
getIndicatorTitle: () => undefined,
|
|
170
178
|
setDrawingTool: (tool) => drawing.setActiveTool(tool),
|
|
171
179
|
clearDrawings: () => drawing.clearAll(),
|
|
172
180
|
removeDrawing: () => {},
|
|
173
181
|
resizeSubPane: () => false,
|
|
174
182
|
createSubPane: () => false,
|
|
175
183
|
clearSubPanes: () => {},
|
|
184
|
+
replaceSubPaneIndicator: () => false,
|
|
185
|
+
updatePaneLayout: (_panes: PaneSpec[]) => {},
|
|
176
186
|
updateCustomMarkers: () => {},
|
|
177
187
|
clearCustomMarkers: () => {},
|
|
178
188
|
updateSettingsFacade: () => {},
|
|
@@ -50,20 +50,7 @@
|
|
|
50
50
|
|
|
51
51
|
<script setup lang="ts">
|
|
52
52
|
import { onMounted, onUnmounted } from 'vue'
|
|
53
|
-
|
|
54
|
-
export interface DrawingStyle {
|
|
55
|
-
stroke?: string
|
|
56
|
-
strokeWidth?: number
|
|
57
|
-
strokeStyle?: 'solid' | 'dashed' | 'dotted'
|
|
58
|
-
fill?: string
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export interface DrawingObject {
|
|
62
|
-
id: string
|
|
63
|
-
type: string
|
|
64
|
-
points: { x: number; y: number }[]
|
|
65
|
-
style: DrawingStyle
|
|
66
|
-
}
|
|
53
|
+
import type { DrawingObject, DrawingStyle } from '@363045841yyt/klinechart-core/plugin'
|
|
67
54
|
|
|
68
55
|
const props = defineProps<{
|
|
69
56
|
drawing: DrawingObject
|
|
@@ -117,6 +117,7 @@
|
|
|
117
117
|
|
|
118
118
|
<script setup lang="ts">
|
|
119
119
|
import { ref, watch, computed } from 'vue'
|
|
120
|
+
import { useFullscreenTeleportTarget } from '../composables/useFullscreenTeleportTarget'
|
|
120
121
|
|
|
121
122
|
export interface ParamConfig {
|
|
122
123
|
key: string
|
|
@@ -146,7 +147,7 @@ const emit = defineEmits<{
|
|
|
146
147
|
const localValues = ref<Record<string, number>>({ ...props.values })
|
|
147
148
|
const showDescription = ref(true)
|
|
148
149
|
|
|
149
|
-
const teleportTarget =
|
|
150
|
+
const teleportTarget = useFullscreenTeleportTarget()
|
|
150
151
|
|
|
151
152
|
watch(
|
|
152
153
|
() => props.values,
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
|
|
75
75
|
<!-- 添加按钮 -->
|
|
76
76
|
<div class="indicator-item">
|
|
77
|
-
<button ref="addBtnRef" class="add-btn" @click="
|
|
77
|
+
<button ref="addBtnRef" class="add-btn" @click.stop="controller.toggleMenu()" title="添加指标">
|
|
78
78
|
<svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
|
|
79
79
|
<path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" />
|
|
80
80
|
</svg>
|
|
@@ -86,14 +86,14 @@
|
|
|
86
86
|
<!-- 添加指标弹窗 -->
|
|
87
87
|
<Teleport :to="teleportTarget">
|
|
88
88
|
<Transition name="overlay">
|
|
89
|
-
<div v-if="
|
|
89
|
+
<div v-if="menuOpen" class="selector-overlay" @click="controller.closeMenu()">
|
|
90
90
|
<Transition name="modal">
|
|
91
|
-
<div v-if="
|
|
91
|
+
<div v-if="menuOpen" class="selector-modal" @click.stop>
|
|
92
92
|
<!-- 弹窗头部 -->
|
|
93
93
|
<div class="modal-header">
|
|
94
94
|
<div class="header-title">
|
|
95
95
|
<span class="title-text">添加指标</span>
|
|
96
|
-
<span class="title-sub">{{
|
|
96
|
+
<span class="title-sub">{{ catalogLen }} 个可用指标</span>
|
|
97
97
|
</div>
|
|
98
98
|
<div class="header-actions">
|
|
99
99
|
<button
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
/>
|
|
118
118
|
</svg>
|
|
119
119
|
</button>
|
|
120
|
-
<button class="modal-close" @click="
|
|
120
|
+
<button class="modal-close" @click="controller.closeMenu()" title="关闭">
|
|
121
121
|
<svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor">
|
|
122
122
|
<path
|
|
123
123
|
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
|
|
@@ -143,21 +143,21 @@
|
|
|
143
143
|
/>
|
|
144
144
|
</svg>
|
|
145
145
|
<input
|
|
146
|
-
|
|
146
|
+
:value="searchQuery" @input="controller.setSearchQuery(($event.target as HTMLInputElement).value)"
|
|
147
147
|
type="text"
|
|
148
148
|
class="search-input"
|
|
149
149
|
placeholder="搜索指标名称..."
|
|
150
150
|
/>
|
|
151
151
|
</div>
|
|
152
152
|
<!-- 主图指标区域 -->
|
|
153
|
-
<div v-if="
|
|
153
|
+
<div v-if="filteredMain.length > 0" class="indicator-section">
|
|
154
154
|
<div class="section-header">
|
|
155
155
|
<span class="section-title">主图指标</span>
|
|
156
|
-
<span class="section-count">{{
|
|
156
|
+
<span class="section-count">{{ filteredMain.length }}</span>
|
|
157
157
|
</div>
|
|
158
158
|
<div class="indicator-grid" :class="{ compact: isCompactView }">
|
|
159
159
|
<button
|
|
160
|
-
v-for="indicator in
|
|
160
|
+
v-for="indicator in filteredMain"
|
|
161
161
|
:key="indicator.id"
|
|
162
162
|
class="indicator-card"
|
|
163
163
|
:class="{ active: isActive(indicator.id), compact: isCompactView }"
|
|
@@ -197,7 +197,7 @@
|
|
|
197
197
|
|
|
198
198
|
<!-- 分隔线 -->
|
|
199
199
|
<div
|
|
200
|
-
v-if="
|
|
200
|
+
v-if="filteredMain.length > 0 && filteredSub.length > 0"
|
|
201
201
|
class="section-divider"
|
|
202
202
|
></div>
|
|
203
203
|
|
|
@@ -213,14 +213,14 @@
|
|
|
213
213
|
</div>
|
|
214
214
|
|
|
215
215
|
<!-- 副图指标区域 -->
|
|
216
|
-
<div v-if="
|
|
216
|
+
<div v-if="filteredSub.length > 0" class="indicator-section">
|
|
217
217
|
<div class="section-header">
|
|
218
218
|
<span class="section-title">副图指标</span>
|
|
219
|
-
<span class="section-count">{{
|
|
219
|
+
<span class="section-count">{{ filteredSub.length }}</span>
|
|
220
220
|
</div>
|
|
221
221
|
<div class="indicator-grid" :class="{ compact: isCompactView }">
|
|
222
222
|
<button
|
|
223
|
-
v-for="indicator in
|
|
223
|
+
v-for="indicator in filteredSub"
|
|
224
224
|
:key="indicator.id"
|
|
225
225
|
class="indicator-card"
|
|
226
226
|
:class="{ active: isActive(indicator.id), compact: isCompactView }"
|
|
@@ -264,7 +264,7 @@
|
|
|
264
264
|
<div class="footer-info">
|
|
265
265
|
<span class="info-text">已激活 {{ activeCount }} 个指标</span>
|
|
266
266
|
</div>
|
|
267
|
-
<button class="btn btn-confirm" @click="
|
|
267
|
+
<button class="btn btn-confirm" @click="controller.closeMenu()">确认</button>
|
|
268
268
|
</div>
|
|
269
269
|
</div>
|
|
270
270
|
</Transition>
|
|
@@ -291,13 +291,15 @@
|
|
|
291
291
|
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
|
292
292
|
import IndicatorParams from './IndicatorParams.vue'
|
|
293
293
|
import { useFullscreenTeleportTarget } from '../composables/useFullscreenTeleportTarget'
|
|
294
|
+
import { coreSignalToVueRef } from '../index'
|
|
294
295
|
import {
|
|
295
|
-
|
|
296
|
-
|
|
296
|
+
createIndicatorSelectorController,
|
|
297
|
+
type IndicatorDefinition,
|
|
298
|
+
allIndicators,
|
|
297
299
|
findIndicator,
|
|
298
300
|
isSubIndicatorId,
|
|
299
|
-
|
|
300
|
-
|
|
301
|
+
type Indicator,
|
|
302
|
+
} from '@363045841yyt/klinechart-core/controllers'
|
|
301
303
|
|
|
302
304
|
const props = defineProps<{
|
|
303
305
|
activeIndicators?: string[]
|
|
@@ -310,15 +312,51 @@ const emit = defineEmits<{
|
|
|
310
312
|
reorderSubIndicators: [orderedIndicatorIds: string[]]
|
|
311
313
|
}>()
|
|
312
314
|
|
|
315
|
+
// ── 将 Indicator[] 转换为 IndicatorDefinition[] ──
|
|
316
|
+
function toIndicatorDefinitions(source: typeof allIndicators): IndicatorDefinition[] {
|
|
317
|
+
return source.map((i) => ({
|
|
318
|
+
id: i.id,
|
|
319
|
+
label: i.label,
|
|
320
|
+
name: i.name,
|
|
321
|
+
description: i.description,
|
|
322
|
+
role: i.pane,
|
|
323
|
+
params: (i.params ?? []).map((p) => ({
|
|
324
|
+
key: p.key,
|
|
325
|
+
label: p.label,
|
|
326
|
+
type: p.type,
|
|
327
|
+
default: p.default ?? (p.type === 'number' ? 0 : ''),
|
|
328
|
+
min: p.min,
|
|
329
|
+
max: p.max,
|
|
330
|
+
step: p.step,
|
|
331
|
+
})),
|
|
332
|
+
}))
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// ── Controller ──
|
|
336
|
+
const controller = createIndicatorSelectorController({
|
|
337
|
+
catalog: toIndicatorDefinitions(allIndicators),
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
// ── 从 Controller Signal 桥接的 Vue 响应式状态 ──
|
|
341
|
+
const menuOpen = coreSignalToVueRef(controller.menuOpen)
|
|
342
|
+
const searchQuery = coreSignalToVueRef(controller.searchQuery)
|
|
343
|
+
const filteredMain = coreSignalToVueRef(controller.filteredMain)
|
|
344
|
+
const filteredSub = coreSignalToVueRef(controller.filteredSub)
|
|
345
|
+
|
|
346
|
+
const hasSearchResults = computed(
|
|
347
|
+
() => filteredMain.value.length > 0 || filteredSub.value.length > 0,
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
const catalogLen = controller.catalog.peek().length
|
|
351
|
+
|
|
352
|
+
// ── 本地 UI 状态(非 Controller 管理的纯 UI 状态) ──
|
|
313
353
|
const addBtnRef = ref<HTMLButtonElement | null>(null)
|
|
314
354
|
const paramsVisible = ref(false)
|
|
315
355
|
const currentIndicatorId = ref<string | null>(null)
|
|
316
356
|
const hoveredIndicator = ref<string | null>(null)
|
|
317
|
-
const showAddMenu = ref(false)
|
|
318
357
|
const dragOverIndicatorId = ref<string | null>(null)
|
|
319
358
|
const draggingIndicatorId = ref<string | null>(null)
|
|
320
359
|
const isCompactView = ref(false)
|
|
321
|
-
const searchQuery = ref('')
|
|
322
360
|
|
|
323
361
|
// Teleport target for fullscreen modal visibility
|
|
324
362
|
const teleportTarget = useFullscreenTeleportTarget()
|
|
@@ -346,39 +384,8 @@ const currentIndicator = computed(() => {
|
|
|
346
384
|
return findIndicator(currentIndicatorId.value)
|
|
347
385
|
})
|
|
348
386
|
|
|
349
|
-
const totalIndicatorsCount = computed(() => mainIndicators.length + subIndicators.length)
|
|
350
|
-
|
|
351
387
|
const activeCount = computed(() => props.activeIndicators?.length ?? 0)
|
|
352
388
|
|
|
353
|
-
// 过滤后的主图指标
|
|
354
|
-
const filteredMainIndicators = computed(() => {
|
|
355
|
-
if (!searchQuery.value.trim()) return mainIndicators
|
|
356
|
-
const query = searchQuery.value.toLowerCase().trim()
|
|
357
|
-
return mainIndicators.filter(
|
|
358
|
-
(i) =>
|
|
359
|
-
i.label.toLowerCase().includes(query) ||
|
|
360
|
-
i.name.toLowerCase().includes(query) ||
|
|
361
|
-
i.id.toLowerCase().includes(query),
|
|
362
|
-
)
|
|
363
|
-
})
|
|
364
|
-
|
|
365
|
-
// 过滤后的副图指标
|
|
366
|
-
const filteredSubIndicators = computed(() => {
|
|
367
|
-
if (!searchQuery.value.trim()) return subIndicators
|
|
368
|
-
const query = searchQuery.value.toLowerCase().trim()
|
|
369
|
-
return subIndicators.filter(
|
|
370
|
-
(i) =>
|
|
371
|
-
i.label.toLowerCase().includes(query) ||
|
|
372
|
-
i.name.toLowerCase().includes(query) ||
|
|
373
|
-
i.id.toLowerCase().includes(query),
|
|
374
|
-
)
|
|
375
|
-
})
|
|
376
|
-
|
|
377
|
-
// 是否有搜索结果
|
|
378
|
-
const hasSearchResults = computed(
|
|
379
|
-
() => filteredMainIndicators.value.length > 0 || filteredSubIndicators.value.length > 0,
|
|
380
|
-
)
|
|
381
|
-
|
|
382
389
|
function isActive(indicatorId: string): boolean {
|
|
383
390
|
return props.activeIndicators?.includes(indicatorId) ?? false
|
|
384
391
|
}
|
|
@@ -390,8 +397,9 @@ function addIndicator(indicatorId: string) {
|
|
|
390
397
|
if (!indicator) return
|
|
391
398
|
|
|
392
399
|
if (indicator.pane === 'main') {
|
|
393
|
-
|
|
394
|
-
|
|
400
|
+
const allItems = allIndicators
|
|
401
|
+
allItems
|
|
402
|
+
.filter((i) => i.id !== indicatorId && isActive(i.id) && i.pane === 'main')
|
|
395
403
|
.forEach((i) => emit('toggle', i.id, false))
|
|
396
404
|
}
|
|
397
405
|
|
|
@@ -407,10 +415,6 @@ function showParams(indicatorId: string) {
|
|
|
407
415
|
paramsVisible.value = true
|
|
408
416
|
}
|
|
409
417
|
|
|
410
|
-
function closeAddMenu() {
|
|
411
|
-
showAddMenu.value = false
|
|
412
|
-
}
|
|
413
|
-
|
|
414
418
|
function getParamValues(indicatorId: string): Record<string, number> {
|
|
415
419
|
const indicator = findIndicator(indicatorId)
|
|
416
420
|
if (!indicator?.params) return {}
|
|
@@ -510,13 +514,9 @@ function onDragEnd() {
|
|
|
510
514
|
draggingIndicatorId.value = null
|
|
511
515
|
}
|
|
512
516
|
|
|
513
|
-
function toggleAddMenu() {
|
|
514
|
-
showAddMenu.value = !showAddMenu.value
|
|
515
|
-
}
|
|
516
|
-
|
|
517
517
|
function handleKeydown(event: KeyboardEvent) {
|
|
518
|
-
if (event.key === 'Escape' &&
|
|
519
|
-
|
|
518
|
+
if (event.key === 'Escape' && controller.menuOpen.peek()) {
|
|
519
|
+
controller.closeMenu()
|
|
520
520
|
}
|
|
521
521
|
}
|
|
522
522
|
|