react-klinecharts-ui 0.6.0 → 1.1.0
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 +186 -6
- package/dist/chart.cjs +70 -0
- package/dist/chart.cjs.map +1 -0
- package/dist/chart.d.cts +45 -0
- package/dist/chart.d.ts +45 -0
- package/dist/chart.js +68 -0
- package/dist/chart.js.map +1 -0
- package/dist/chunk-F24D6PWY.cjs +98 -0
- package/dist/chunk-F24D6PWY.cjs.map +1 -0
- package/dist/chunk-O7E57I66.js +92 -0
- package/dist/chunk-O7E57I66.js.map +1 -0
- package/dist/chunk-PZ5AY32C.js +9 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/chunk-Q7SFCCGT.cjs +11 -0
- package/dist/chunk-Q7SFCCGT.cjs.map +1 -0
- package/dist/{chunk-MVD3ILJT.js → chunk-RIT2LJQT.js} +35 -22
- package/dist/chunk-RIT2LJQT.js.map +1 -0
- package/dist/{chunk-FSHI2ZDB.cjs → chunk-SZDU2D3D.cjs} +46 -33
- package/dist/chunk-SZDU2D3D.cjs.map +1 -0
- package/dist/extensions.cjs +10 -9
- package/dist/extensions.d.cts +10 -7
- package/dist/extensions.d.ts +10 -7
- package/dist/extensions.js +2 -1
- package/dist/index.cjs +657 -323
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +246 -9
- package/dist/index.d.ts +246 -9
- package/dist/index.js +555 -240
- package/dist/index.js.map +1 -1
- package/package.json +31 -5
- package/dist/chunk-FSHI2ZDB.cjs.map +0 -1
- package/dist/chunk-MVD3ILJT.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,32 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkSZDU2D3D_cjs = require('./chunk-SZDU2D3D.cjs');
|
|
4
|
+
var chunkF24D6PWY_cjs = require('./chunk-F24D6PWY.cjs');
|
|
5
|
+
require('./chunk-Q7SFCCGT.cjs');
|
|
4
6
|
var react = require('react');
|
|
5
|
-
var
|
|
7
|
+
var klinecharts = require('klinecharts');
|
|
6
8
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
9
|
|
|
8
|
-
var KlinechartsUIStateContext = react.createContext(null);
|
|
9
|
-
var KlinechartsUIDispatchContext = react.createContext(null);
|
|
10
|
-
function useKlinechartsUIDispatch() {
|
|
11
|
-
const ctx = react.useContext(KlinechartsUIDispatchContext);
|
|
12
|
-
if (!ctx) {
|
|
13
|
-
throw new Error(
|
|
14
|
-
"useKlinechartsUI must be used within a <KlinechartsUIProvider>"
|
|
15
|
-
);
|
|
16
|
-
}
|
|
17
|
-
return ctx;
|
|
18
|
-
}
|
|
19
|
-
function useKlinechartsUI() {
|
|
20
|
-
const state = react.useContext(KlinechartsUIStateContext);
|
|
21
|
-
const dispatch = react.useContext(KlinechartsUIDispatchContext);
|
|
22
|
-
if (!state || !dispatch) {
|
|
23
|
-
throw new Error(
|
|
24
|
-
"useKlinechartsUI must be used within a <KlinechartsUIProvider>"
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
return { state, ...dispatch };
|
|
28
|
-
}
|
|
29
|
-
|
|
30
10
|
// src/data/periods.ts
|
|
31
11
|
var DEFAULT_PERIODS = [
|
|
32
12
|
{ span: 1, type: "minute", label: "1m" },
|
|
@@ -40,6 +20,50 @@ var DEFAULT_PERIODS = [
|
|
|
40
20
|
{ span: 1, type: "month", label: "M" },
|
|
41
21
|
{ span: 1, type: "year", label: "Y" }
|
|
42
22
|
];
|
|
23
|
+
|
|
24
|
+
// src/storage/types.ts
|
|
25
|
+
var DEFAULT_STORAGE_NAMESPACES = [
|
|
26
|
+
"alerts",
|
|
27
|
+
"settings",
|
|
28
|
+
"indicators"
|
|
29
|
+
];
|
|
30
|
+
var DEFAULT_STORAGE_KEY_PREFIX = "rkui:";
|
|
31
|
+
|
|
32
|
+
// src/storage/createDefaultStorage.ts
|
|
33
|
+
var NOOP_ADAPTER = {
|
|
34
|
+
getItem: () => null,
|
|
35
|
+
setItem: () => {
|
|
36
|
+
},
|
|
37
|
+
removeItem: () => {
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
function createDefaultStorage() {
|
|
41
|
+
if (typeof localStorage === "undefined") return NOOP_ADAPTER;
|
|
42
|
+
try {
|
|
43
|
+
const probe = localStorage.getItem("__rkui_probe__");
|
|
44
|
+
return probe === null ? localStorage : localStorage;
|
|
45
|
+
} catch {
|
|
46
|
+
return NOOP_ADAPTER;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function resolveStorage(options) {
|
|
50
|
+
const adapter = options?.adapter ?? createDefaultStorage();
|
|
51
|
+
const keyPrefix = options?.keyPrefix ?? DEFAULT_STORAGE_KEY_PREFIX;
|
|
52
|
+
const namespaces = new Set(
|
|
53
|
+
options?.namespaces ?? DEFAULT_STORAGE_NAMESPACES
|
|
54
|
+
);
|
|
55
|
+
return {
|
|
56
|
+
adapter,
|
|
57
|
+
namespaces,
|
|
58
|
+
keyPrefix,
|
|
59
|
+
key(namespace) {
|
|
60
|
+
return `${keyPrefix}${namespace}`;
|
|
61
|
+
},
|
|
62
|
+
persists(namespace) {
|
|
63
|
+
return namespaces.has(namespace);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
43
67
|
function reducer(state, action) {
|
|
44
68
|
switch (action.type) {
|
|
45
69
|
case "SET_CHART":
|
|
@@ -64,6 +88,25 @@ function reducer(state, action) {
|
|
|
64
88
|
return { ...state, indicatorVisibility: action.visibility };
|
|
65
89
|
case "SET_ALERTS":
|
|
66
90
|
return { ...state, alerts: action.alerts };
|
|
91
|
+
case "ADD_ALERT":
|
|
92
|
+
return { ...state, alerts: [...state.alerts, action.alert] };
|
|
93
|
+
case "REMOVE_ALERT":
|
|
94
|
+
return {
|
|
95
|
+
...state,
|
|
96
|
+
alerts: state.alerts.filter((a) => a.id !== action.id)
|
|
97
|
+
};
|
|
98
|
+
case "CLEAR_ALERTS":
|
|
99
|
+
return { ...state, alerts: [] };
|
|
100
|
+
case "MARK_ALERT_TRIGGERED": {
|
|
101
|
+
if (action.ids.length === 0) return state;
|
|
102
|
+
const triggered = new Set(action.ids);
|
|
103
|
+
return {
|
|
104
|
+
...state,
|
|
105
|
+
alerts: state.alerts.map(
|
|
106
|
+
(a) => triggered.has(a.id) ? { ...a, triggered: true } : a
|
|
107
|
+
)
|
|
108
|
+
};
|
|
109
|
+
}
|
|
67
110
|
case "SET_MEASURE":
|
|
68
111
|
return { ...state, measure: { ...state.measure, ...action.measure } };
|
|
69
112
|
case "SET_REPLAY":
|
|
@@ -84,13 +127,16 @@ function KlinechartsUIProvider({
|
|
|
84
127
|
defaultPeriod,
|
|
85
128
|
defaultTheme = "light",
|
|
86
129
|
defaultTimezone = "Asia/Shanghai",
|
|
87
|
-
|
|
88
|
-
|
|
130
|
+
// NOTE: no destructuring default here — the init function must distinguish
|
|
131
|
+
// "consumer passed default*" (wins) from "use stored value" (hydrate).
|
|
132
|
+
defaultMainIndicators,
|
|
133
|
+
defaultSubIndicators,
|
|
89
134
|
defaultLocale = "en-US",
|
|
90
135
|
periods,
|
|
91
136
|
styles,
|
|
92
137
|
registerExtensions: shouldRegister = true,
|
|
93
138
|
overlays: extraOverlays,
|
|
139
|
+
storage: storageOptions,
|
|
94
140
|
children,
|
|
95
141
|
onStateChange,
|
|
96
142
|
onSymbolChange,
|
|
@@ -101,6 +147,11 @@ function KlinechartsUIProvider({
|
|
|
101
147
|
onSubIndicatorsChange,
|
|
102
148
|
onSettingsChange
|
|
103
149
|
}) {
|
|
150
|
+
const resolvedStorage = react.useMemo(
|
|
151
|
+
() => storageOptions ? resolveStorage(storageOptions) : null,
|
|
152
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
153
|
+
[]
|
|
154
|
+
);
|
|
104
155
|
const [state, dispatch] = react.useReducer(
|
|
105
156
|
reducer,
|
|
106
157
|
{
|
|
@@ -113,47 +164,66 @@ function KlinechartsUIProvider({
|
|
|
113
164
|
defaultSubIndicators,
|
|
114
165
|
defaultLocale,
|
|
115
166
|
periods,
|
|
116
|
-
styles
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
167
|
+
styles,
|
|
168
|
+
storage: resolvedStorage
|
|
169
|
+
},
|
|
170
|
+
(opts) => {
|
|
171
|
+
const s = opts.storage;
|
|
172
|
+
const read = (ns, fallback) => {
|
|
173
|
+
if (!s || !s.persists(ns)) return fallback;
|
|
174
|
+
try {
|
|
175
|
+
const raw = s.adapter.getItem(s.key(ns));
|
|
176
|
+
return raw ? JSON.parse(raw) : fallback;
|
|
177
|
+
} catch {
|
|
178
|
+
return fallback;
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
const storedIndicators = read("indicators", {});
|
|
182
|
+
return {
|
|
183
|
+
chart: null,
|
|
184
|
+
datafeed: opts.datafeed,
|
|
185
|
+
symbol: opts.defaultSymbol ?? null,
|
|
186
|
+
period: opts.defaultPeriod ?? (opts.periods ?? DEFAULT_PERIODS)[0],
|
|
187
|
+
theme: opts.defaultTheme ?? "light",
|
|
188
|
+
timezone: opts.defaultTimezone ?? "Asia/Shanghai",
|
|
189
|
+
isLoading: false,
|
|
190
|
+
locale: opts.defaultLocale ?? "en-US",
|
|
191
|
+
periods: opts.periods ?? DEFAULT_PERIODS,
|
|
192
|
+
// Persistence semantics: STORED values win over `default*` props —
|
|
193
|
+
// the user's saved configuration should survive reload even when the
|
|
194
|
+
// app passes defaults. Only when storage is empty/unconfigured do the
|
|
195
|
+
// `default*` props apply, falling back to the built-ins last.
|
|
196
|
+
// (Settings live in useKlinechartsUISettings useState and hydrate
|
|
197
|
+
// separately via the dispatch-context `storage`.)
|
|
198
|
+
mainIndicators: storedIndicators.main ?? opts.defaultMainIndicators ?? ["MA"],
|
|
199
|
+
subIndicators: storedIndicators.sub ?? (opts.defaultSubIndicators ? opts.defaultSubIndicators.reduce(
|
|
200
|
+
(acc, name) => ({ ...acc, [name]: "" }),
|
|
201
|
+
{}
|
|
202
|
+
) : { VOL: "" }),
|
|
203
|
+
indicatorAxes: storedIndicators.axes ?? {},
|
|
204
|
+
indicatorVisibility: storedIndicators.visibility ?? {},
|
|
205
|
+
alerts: read("alerts", []),
|
|
206
|
+
measure: { isActive: false, fromPoint: null, result: null },
|
|
207
|
+
replay: {
|
|
208
|
+
isReplaying: false,
|
|
209
|
+
isPaused: false,
|
|
210
|
+
speed: 1,
|
|
211
|
+
barIndex: 0,
|
|
212
|
+
totalBars: 0
|
|
213
|
+
},
|
|
214
|
+
styles: opts.styles,
|
|
215
|
+
screenshotUrl: null
|
|
216
|
+
};
|
|
217
|
+
}
|
|
147
218
|
);
|
|
148
219
|
const fullscreenContainerRef = react.useRef(null);
|
|
149
220
|
const undoRedoListenerRef = react.useRef(null);
|
|
150
|
-
const
|
|
221
|
+
const alertTriggeredListenersRef = react.useRef(/* @__PURE__ */ new Set());
|
|
151
222
|
const replayIntervalRef = react.useRef(null);
|
|
152
223
|
const replaySavedDataRef = react.useRef([]);
|
|
153
224
|
const replayIndexRef = react.useRef(0);
|
|
154
225
|
const alertPrevCloseRef = react.useRef(null);
|
|
155
226
|
const stateRef = react.useRef(state);
|
|
156
|
-
stateRef.current = state;
|
|
157
227
|
const callbacksRef = react.useRef({
|
|
158
228
|
onStateChange,
|
|
159
229
|
onSymbolChange,
|
|
@@ -163,15 +233,18 @@ function KlinechartsUIProvider({
|
|
|
163
233
|
onMainIndicatorsChange,
|
|
164
234
|
onSubIndicatorsChange
|
|
165
235
|
});
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
236
|
+
react.useEffect(() => {
|
|
237
|
+
stateRef.current = state;
|
|
238
|
+
callbacksRef.current = {
|
|
239
|
+
onStateChange,
|
|
240
|
+
onSymbolChange,
|
|
241
|
+
onPeriodChange,
|
|
242
|
+
onThemeChange,
|
|
243
|
+
onTimezoneChange,
|
|
244
|
+
onMainIndicatorsChange,
|
|
245
|
+
onSubIndicatorsChange
|
|
246
|
+
};
|
|
247
|
+
});
|
|
175
248
|
const enhancedDispatch = react.useCallback((action) => {
|
|
176
249
|
const prevState = stateRef.current;
|
|
177
250
|
const newState = reducer(prevState, action);
|
|
@@ -201,11 +274,17 @@ function KlinechartsUIProvider({
|
|
|
201
274
|
}
|
|
202
275
|
}, []);
|
|
203
276
|
const extraOverlaysRef = react.useRef(extraOverlays);
|
|
277
|
+
const datafeedRef = react.useRef(datafeed);
|
|
278
|
+
const onSettingsChangeRef = react.useRef(onSettingsChange);
|
|
279
|
+
react.useEffect(() => {
|
|
280
|
+
datafeedRef.current = datafeed;
|
|
281
|
+
onSettingsChangeRef.current = onSettingsChange;
|
|
282
|
+
});
|
|
204
283
|
react.useEffect(() => {
|
|
205
284
|
if (shouldRegister) {
|
|
206
|
-
|
|
285
|
+
chunkSZDU2D3D_cjs.registerExtensions();
|
|
207
286
|
}
|
|
208
|
-
extraOverlaysRef.current?.forEach((overlay) =>
|
|
287
|
+
extraOverlaysRef.current?.forEach((overlay) => klinecharts.registerOverlay(overlay));
|
|
209
288
|
}, [shouldRegister]);
|
|
210
289
|
react.useEffect(() => {
|
|
211
290
|
if (state.chart && state.styles) {
|
|
@@ -217,34 +296,97 @@ function KlinechartsUIProvider({
|
|
|
217
296
|
const chart = state.chart;
|
|
218
297
|
if (!chart || !hasAlerts) return;
|
|
219
298
|
alertPrevCloseRef.current = null;
|
|
299
|
+
const prevValueByAlert = /* @__PURE__ */ new Map();
|
|
220
300
|
const interval = setInterval(() => {
|
|
221
301
|
const dataList = chart.getDataList();
|
|
222
302
|
if (!dataList || dataList.length === 0) return;
|
|
223
|
-
const
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
303
|
+
const lastIdx = dataList.length - 1;
|
|
304
|
+
const indicatorCache = /* @__PURE__ */ new Map();
|
|
305
|
+
const readIndicatorValue = (indicatorId, figureKey) => {
|
|
306
|
+
const cacheKey = `${indicatorId}:${figureKey}`;
|
|
307
|
+
if (indicatorCache.has(cacheKey)) return indicatorCache.get(cacheKey);
|
|
308
|
+
let value = null;
|
|
309
|
+
try {
|
|
310
|
+
const indicators2 = chart.getIndicators({ id: indicatorId });
|
|
311
|
+
const ind = indicators2?.[0];
|
|
312
|
+
const result = ind?.result;
|
|
313
|
+
const last = Array.isArray(result) ? result[lastIdx] : null;
|
|
314
|
+
if (last && typeof last === "object") {
|
|
315
|
+
const v = last[figureKey];
|
|
316
|
+
value = typeof v === "number" ? v : null;
|
|
317
|
+
}
|
|
318
|
+
} catch {
|
|
319
|
+
value = null;
|
|
320
|
+
}
|
|
321
|
+
indicatorCache.set(cacheKey, value);
|
|
322
|
+
return value;
|
|
323
|
+
};
|
|
227
324
|
const alerts = stateRef.current.alerts;
|
|
228
|
-
|
|
229
|
-
const
|
|
230
|
-
if (alert.triggered)
|
|
231
|
-
const
|
|
232
|
-
|
|
325
|
+
const triggeredIds = [];
|
|
326
|
+
for (const alert of alerts) {
|
|
327
|
+
if (alert.triggered) continue;
|
|
328
|
+
const target = alert.target ?? { type: "price" };
|
|
329
|
+
let currentValue;
|
|
330
|
+
if (target.type === "indicator") {
|
|
331
|
+
currentValue = readIndicatorValue(target.indicatorId, target.figureKey);
|
|
332
|
+
} else {
|
|
333
|
+
currentValue = dataList[lastIdx].close;
|
|
334
|
+
}
|
|
335
|
+
if (currentValue === null || !Number.isFinite(currentValue)) continue;
|
|
336
|
+
const prevValue = prevValueByAlert.get(alert.id) ?? null;
|
|
337
|
+
prevValueByAlert.set(alert.id, currentValue);
|
|
338
|
+
if (prevValue === null) continue;
|
|
339
|
+
const crossedUp = prevValue < alert.price && currentValue >= alert.price;
|
|
340
|
+
const crossedDown = prevValue > alert.price && currentValue <= alert.price;
|
|
233
341
|
const shouldTrigger = alert.condition === "crossing_up" ? crossedUp : alert.condition === "crossing_down" ? crossedDown : crossedUp || crossedDown;
|
|
234
342
|
if (shouldTrigger) {
|
|
235
|
-
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
return triggered;
|
|
343
|
+
triggeredIds.push(alert.id);
|
|
344
|
+
const fired = { ...alert, triggered: true };
|
|
345
|
+
alertTriggeredListenersRef.current.forEach((cb) => cb(fired));
|
|
239
346
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
347
|
+
}
|
|
348
|
+
if (triggeredIds.length > 0) {
|
|
349
|
+
enhancedDispatch({
|
|
350
|
+
type: "MARK_ALERT_TRIGGERED",
|
|
351
|
+
ids: triggeredIds
|
|
352
|
+
});
|
|
244
353
|
}
|
|
245
354
|
}, 1e3);
|
|
246
355
|
return () => clearInterval(interval);
|
|
247
356
|
}, [state.chart, hasAlerts, enhancedDispatch]);
|
|
357
|
+
react.useEffect(() => {
|
|
358
|
+
alertPrevCloseRef.current = null;
|
|
359
|
+
}, [state.symbol, state.period]);
|
|
360
|
+
const writeNs = react.useCallback(
|
|
361
|
+
(ns, value) => {
|
|
362
|
+
if (!resolvedStorage || !resolvedStorage.persists(ns)) return;
|
|
363
|
+
try {
|
|
364
|
+
resolvedStorage.adapter.setItem(
|
|
365
|
+
resolvedStorage.key(ns),
|
|
366
|
+
JSON.stringify(value)
|
|
367
|
+
);
|
|
368
|
+
} catch {
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
[resolvedStorage]
|
|
372
|
+
);
|
|
373
|
+
react.useEffect(() => {
|
|
374
|
+
writeNs("alerts", state.alerts);
|
|
375
|
+
}, [state.alerts, writeNs]);
|
|
376
|
+
react.useEffect(() => {
|
|
377
|
+
writeNs("indicators", {
|
|
378
|
+
main: state.mainIndicators,
|
|
379
|
+
sub: state.subIndicators,
|
|
380
|
+
axes: state.indicatorAxes,
|
|
381
|
+
visibility: state.indicatorVisibility
|
|
382
|
+
});
|
|
383
|
+
}, [
|
|
384
|
+
state.mainIndicators,
|
|
385
|
+
state.subIndicators,
|
|
386
|
+
state.indicatorAxes,
|
|
387
|
+
state.indicatorVisibility,
|
|
388
|
+
writeNs
|
|
389
|
+
]);
|
|
248
390
|
react.useEffect(() => {
|
|
249
391
|
return () => {
|
|
250
392
|
if (replayIntervalRef.current !== null) {
|
|
@@ -256,21 +398,23 @@ function KlinechartsUIProvider({
|
|
|
256
398
|
const dispatchValue = react.useMemo(
|
|
257
399
|
() => ({
|
|
258
400
|
dispatch: enhancedDispatch,
|
|
259
|
-
datafeed,
|
|
260
|
-
onSettingsChange,
|
|
401
|
+
datafeed: datafeedRef.current,
|
|
402
|
+
onSettingsChange: onSettingsChangeRef.current,
|
|
261
403
|
fullscreenContainerRef,
|
|
262
404
|
undoRedoListenerRef,
|
|
263
|
-
|
|
405
|
+
alertTriggeredListenersRef,
|
|
264
406
|
replayIntervalRef,
|
|
265
407
|
replaySavedDataRef,
|
|
266
|
-
replayIndexRef
|
|
408
|
+
replayIndexRef,
|
|
409
|
+
storage: resolvedStorage
|
|
267
410
|
}),
|
|
268
|
-
|
|
411
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
412
|
+
[enhancedDispatch, resolvedStorage]
|
|
269
413
|
);
|
|
270
|
-
return /* @__PURE__ */ jsxRuntime.jsx(KlinechartsUIStateContext.Provider, { value: state, children: /* @__PURE__ */ jsxRuntime.jsx(KlinechartsUIDispatchContext.Provider, { value: dispatchValue, children }) });
|
|
414
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkF24D6PWY_cjs.KlinechartsUIStateContext.Provider, { value: state, children: /* @__PURE__ */ jsxRuntime.jsx(chunkF24D6PWY_cjs.KlinechartsUIDispatchContext.Provider, { value: dispatchValue, children }) });
|
|
271
415
|
}
|
|
272
416
|
function useKlinechartsUITheme() {
|
|
273
|
-
const { state, dispatch } = useKlinechartsUI();
|
|
417
|
+
const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
274
418
|
const setTheme = react.useCallback(
|
|
275
419
|
(theme) => {
|
|
276
420
|
state.chart?.setStyles(theme);
|
|
@@ -291,11 +435,11 @@ function useKlinechartsUITheme() {
|
|
|
291
435
|
|
|
292
436
|
// src/hooks/useKlinechartsUILoading.ts
|
|
293
437
|
function useKlinechartsUILoading() {
|
|
294
|
-
const { state } = useKlinechartsUI();
|
|
438
|
+
const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
295
439
|
return { isLoading: state.isLoading };
|
|
296
440
|
}
|
|
297
441
|
function usePeriods() {
|
|
298
|
-
const { state, dispatch } = useKlinechartsUI();
|
|
442
|
+
const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
299
443
|
const setPeriod = react.useCallback(
|
|
300
444
|
(period) => {
|
|
301
445
|
dispatch({ type: "SET_PERIOD", period });
|
|
@@ -333,7 +477,7 @@ var TIMEZONES = [
|
|
|
333
477
|
|
|
334
478
|
// src/hooks/useTimezone.ts
|
|
335
479
|
function useTimezone() {
|
|
336
|
-
const { state, dispatch } = useKlinechartsUI();
|
|
480
|
+
const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
337
481
|
const timezones = react.useMemo(
|
|
338
482
|
() => TIMEZONES.map((tz) => ({
|
|
339
483
|
key: tz.key,
|
|
@@ -355,7 +499,7 @@ function useTimezone() {
|
|
|
355
499
|
};
|
|
356
500
|
}
|
|
357
501
|
function useSymbolSearch(debounceMs = 300) {
|
|
358
|
-
const { state, dispatch, datafeed } = useKlinechartsUI();
|
|
502
|
+
const { state, dispatch, datafeed } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
359
503
|
const [query, setQueryState] = react.useState("");
|
|
360
504
|
const [results, setResults] = react.useState([]);
|
|
361
505
|
const [isSearching, setIsSearching] = react.useState(false);
|
|
@@ -717,8 +861,8 @@ var INDICATOR_PARAMS = {
|
|
|
717
861
|
// src/hooks/useIndicators.ts
|
|
718
862
|
var COLLAPSED_HEIGHT = 30;
|
|
719
863
|
function useIndicators() {
|
|
720
|
-
const { state, dispatch } = useKlinechartsUI();
|
|
721
|
-
const { undoRedoListenerRef } = useKlinechartsUIDispatch();
|
|
864
|
+
const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
865
|
+
const { undoRedoListenerRef } = chunkF24D6PWY_cjs.useKlinechartsUIDispatch();
|
|
722
866
|
const paneHeightsRef = react.useRef({});
|
|
723
867
|
const collapsedPanesRef = react.useRef(/* @__PURE__ */ new Set());
|
|
724
868
|
const mainIndicators = react.useMemo(() => {
|
|
@@ -1215,23 +1359,25 @@ var DRAWING_CATEGORIES = [
|
|
|
1215
1359
|
// src/hooks/useDrawingTools.ts
|
|
1216
1360
|
var DRAWING_GROUP_ID = "drawing_tools";
|
|
1217
1361
|
function useDrawingTools() {
|
|
1218
|
-
const { state } = useKlinechartsUI();
|
|
1219
|
-
const { undoRedoListenerRef } = useKlinechartsUIDispatch();
|
|
1362
|
+
const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
1363
|
+
const { undoRedoListenerRef } = chunkF24D6PWY_cjs.useKlinechartsUIDispatch();
|
|
1220
1364
|
const [activeTool, setActiveTool] = react.useState(null);
|
|
1221
1365
|
const [magnetMode, setMagnetModeState] = react.useState("normal");
|
|
1222
1366
|
const [isLocked, setIsLocked] = react.useState(false);
|
|
1223
1367
|
const [isVisible, setIsVisible] = react.useState(true);
|
|
1224
1368
|
const [autoRetrigger, setAutoRetrigger] = react.useState(true);
|
|
1225
1369
|
const activeToolRef = react.useRef(activeTool);
|
|
1226
|
-
activeToolRef.current = activeTool;
|
|
1227
1370
|
const autoRetriggerRef = react.useRef(autoRetrigger);
|
|
1228
|
-
autoRetriggerRef.current = autoRetrigger;
|
|
1229
1371
|
const isLockedRef = react.useRef(isLocked);
|
|
1230
|
-
isLockedRef.current = isLocked;
|
|
1231
1372
|
const isVisibleRef = react.useRef(isVisible);
|
|
1232
|
-
isVisibleRef.current = isVisible;
|
|
1233
1373
|
const magnetModeRef = react.useRef(magnetMode);
|
|
1234
|
-
|
|
1374
|
+
react.useEffect(() => {
|
|
1375
|
+
activeToolRef.current = activeTool;
|
|
1376
|
+
autoRetriggerRef.current = autoRetrigger;
|
|
1377
|
+
isLockedRef.current = isLocked;
|
|
1378
|
+
isVisibleRef.current = isVisible;
|
|
1379
|
+
magnetModeRef.current = magnetMode;
|
|
1380
|
+
});
|
|
1235
1381
|
const categories = react.useMemo(
|
|
1236
1382
|
() => DRAWING_CATEGORIES.map((cat) => ({
|
|
1237
1383
|
key: cat.key,
|
|
@@ -1242,6 +1388,8 @@ function useDrawingTools() {
|
|
|
1242
1388
|
})),
|
|
1243
1389
|
[]
|
|
1244
1390
|
);
|
|
1391
|
+
const createOverlayForToolRef = react.useRef(() => {
|
|
1392
|
+
});
|
|
1245
1393
|
const createOverlayForTool = react.useCallback(
|
|
1246
1394
|
(name) => {
|
|
1247
1395
|
const mode = magnetModeRef.current === "strong" ? "strong_magnet" : magnetModeRef.current === "weak" ? "weak_magnet" : "normal";
|
|
@@ -1267,7 +1415,7 @@ function useDrawingTools() {
|
|
|
1267
1415
|
});
|
|
1268
1416
|
if (autoRetriggerRef.current && activeToolRef.current === name) {
|
|
1269
1417
|
requestAnimationFrame(() => {
|
|
1270
|
-
|
|
1418
|
+
createOverlayForToolRef.current(name);
|
|
1271
1419
|
});
|
|
1272
1420
|
}
|
|
1273
1421
|
}
|
|
@@ -1275,6 +1423,9 @@ function useDrawingTools() {
|
|
|
1275
1423
|
},
|
|
1276
1424
|
[state.chart, undoRedoListenerRef]
|
|
1277
1425
|
);
|
|
1426
|
+
react.useEffect(() => {
|
|
1427
|
+
createOverlayForToolRef.current = createOverlayForTool;
|
|
1428
|
+
});
|
|
1278
1429
|
const selectTool = react.useCallback(
|
|
1279
1430
|
(name) => {
|
|
1280
1431
|
setActiveTool(name);
|
|
@@ -1399,8 +1550,18 @@ var defaultSettings = {
|
|
|
1399
1550
|
tooltipShowRule: "always"
|
|
1400
1551
|
};
|
|
1401
1552
|
function useKlinechartsUISettings() {
|
|
1402
|
-
const { state, onSettingsChange } = useKlinechartsUI();
|
|
1403
|
-
const
|
|
1553
|
+
const { state, onSettingsChange } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
1554
|
+
const { storage } = chunkF24D6PWY_cjs.useKlinechartsUIDispatch();
|
|
1555
|
+
const [settings, setSettings] = react.useState(() => {
|
|
1556
|
+
if (storage && storage.persists("settings")) {
|
|
1557
|
+
try {
|
|
1558
|
+
const raw = storage.adapter.getItem(storage.key("settings"));
|
|
1559
|
+
if (raw) return { ...defaultSettings, ...JSON.parse(raw) };
|
|
1560
|
+
} catch {
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
return defaultSettings;
|
|
1564
|
+
});
|
|
1404
1565
|
const isInitialMount = react.useRef(true);
|
|
1405
1566
|
react.useEffect(() => {
|
|
1406
1567
|
if (isInitialMount.current) {
|
|
@@ -1409,6 +1570,14 @@ function useKlinechartsUISettings() {
|
|
|
1409
1570
|
}
|
|
1410
1571
|
onSettingsChange?.({ ...settings });
|
|
1411
1572
|
}, [settings, onSettingsChange]);
|
|
1573
|
+
react.useEffect(() => {
|
|
1574
|
+
if (!storage || !storage.persists("settings")) return;
|
|
1575
|
+
if (isInitialMount.current) return;
|
|
1576
|
+
try {
|
|
1577
|
+
storage.adapter.setItem(storage.key("settings"), JSON.stringify(settings));
|
|
1578
|
+
} catch {
|
|
1579
|
+
}
|
|
1580
|
+
}, [settings, storage]);
|
|
1412
1581
|
const candleTypes = react.useMemo(
|
|
1413
1582
|
() => CANDLE_TYPES.map((ct) => ({
|
|
1414
1583
|
key: ct.key,
|
|
@@ -1650,7 +1819,7 @@ function useKlinechartsUISettings() {
|
|
|
1650
1819
|
};
|
|
1651
1820
|
}
|
|
1652
1821
|
function useScreenshot() {
|
|
1653
|
-
const { state, dispatch } = useKlinechartsUI();
|
|
1822
|
+
const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
1654
1823
|
const capture = react.useCallback(() => {
|
|
1655
1824
|
if (!state.chart) return;
|
|
1656
1825
|
const url = state.chart.getConvertPictureUrl(true, "jpeg", state.theme === "dark" ? "#151517" : "#ffffff");
|
|
@@ -1679,12 +1848,12 @@ function useScreenshot() {
|
|
|
1679
1848
|
};
|
|
1680
1849
|
}
|
|
1681
1850
|
function useHotkeys() {
|
|
1682
|
-
const { state } = useKlinechartsUI();
|
|
1851
|
+
const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
1683
1852
|
const registerHotkey = react.useCallback((template) => {
|
|
1684
|
-
|
|
1853
|
+
klinecharts.registerHotkey(template);
|
|
1685
1854
|
}, []);
|
|
1686
1855
|
const getHotkey = react.useCallback(
|
|
1687
|
-
(name) =>
|
|
1856
|
+
(name) => klinecharts.getHotkey(name) ?? null,
|
|
1688
1857
|
[]
|
|
1689
1858
|
);
|
|
1690
1859
|
const setHotkeysEnabled = react.useCallback(
|
|
@@ -1702,13 +1871,13 @@ function useHotkeys() {
|
|
|
1702
1871
|
return {
|
|
1703
1872
|
registerHotkey,
|
|
1704
1873
|
getHotkey,
|
|
1705
|
-
supportedHotkeys:
|
|
1874
|
+
supportedHotkeys: klinecharts.getSupportedHotkeys(),
|
|
1706
1875
|
setHotkeysEnabled,
|
|
1707
1876
|
getHotkeysConfig
|
|
1708
1877
|
};
|
|
1709
1878
|
}
|
|
1710
1879
|
function useChartAxes() {
|
|
1711
|
-
const { state } = useKlinechartsUI();
|
|
1880
|
+
const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
1712
1881
|
const overrideXAxis = react.useCallback(
|
|
1713
1882
|
(override) => {
|
|
1714
1883
|
if (!state.chart) return;
|
|
@@ -1726,27 +1895,33 @@ function useChartAxes() {
|
|
|
1726
1895
|
return { overrideXAxis, overrideYAxis };
|
|
1727
1896
|
}
|
|
1728
1897
|
function useFullscreen() {
|
|
1729
|
-
const { fullscreenContainerRef } = useKlinechartsUIDispatch();
|
|
1898
|
+
const { fullscreenContainerRef } = chunkF24D6PWY_cjs.useKlinechartsUIDispatch();
|
|
1730
1899
|
const [isFullscreen, setIsFullscreen] = react.useState(false);
|
|
1731
1900
|
const enter = react.useCallback(() => {
|
|
1732
1901
|
const el = fullscreenContainerRef.current;
|
|
1733
1902
|
if (!el) return;
|
|
1903
|
+
let result;
|
|
1734
1904
|
if (el.requestFullscreen) {
|
|
1735
|
-
el.requestFullscreen();
|
|
1905
|
+
result = el.requestFullscreen();
|
|
1736
1906
|
} else if ("webkitRequestFullscreen" in el) {
|
|
1737
1907
|
el.webkitRequestFullscreen();
|
|
1738
1908
|
} else if ("msRequestFullscreen" in el) {
|
|
1739
1909
|
el.msRequestFullscreen();
|
|
1740
1910
|
}
|
|
1911
|
+
result?.catch(() => {
|
|
1912
|
+
});
|
|
1741
1913
|
}, [fullscreenContainerRef]);
|
|
1742
1914
|
const exit = react.useCallback(() => {
|
|
1915
|
+
let result;
|
|
1743
1916
|
if (document.exitFullscreen) {
|
|
1744
|
-
document.exitFullscreen();
|
|
1917
|
+
result = document.exitFullscreen();
|
|
1745
1918
|
} else if ("webkitExitFullscreen" in document) {
|
|
1746
1919
|
document.webkitExitFullscreen();
|
|
1747
1920
|
} else if ("msExitFullscreen" in document) {
|
|
1748
1921
|
document.msExitFullscreen();
|
|
1749
1922
|
}
|
|
1923
|
+
result?.catch(() => {
|
|
1924
|
+
});
|
|
1750
1925
|
}, []);
|
|
1751
1926
|
const toggle = react.useCallback(() => {
|
|
1752
1927
|
if (isFullscreen) {
|
|
@@ -1775,8 +1950,9 @@ function useFullscreen() {
|
|
|
1775
1950
|
};
|
|
1776
1951
|
}
|
|
1777
1952
|
function useOrderLines() {
|
|
1778
|
-
const { state } = useKlinechartsUI();
|
|
1953
|
+
const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
1779
1954
|
const callbacksRef = react.useRef(/* @__PURE__ */ new Map());
|
|
1955
|
+
const ownedIdsRef = react.useRef(/* @__PURE__ */ new Set());
|
|
1780
1956
|
const createOrderLine = react.useCallback(
|
|
1781
1957
|
(options) => {
|
|
1782
1958
|
if (!state.chart) return null;
|
|
@@ -1807,6 +1983,7 @@ function useOrderLines() {
|
|
|
1807
1983
|
}
|
|
1808
1984
|
}
|
|
1809
1985
|
});
|
|
1986
|
+
ownedIdsRef.current.add(id);
|
|
1810
1987
|
return id;
|
|
1811
1988
|
},
|
|
1812
1989
|
[state.chart]
|
|
@@ -1838,12 +2015,28 @@ function useOrderLines() {
|
|
|
1838
2015
|
(id) => {
|
|
1839
2016
|
state.chart?.removeOverlay({ id });
|
|
1840
2017
|
callbacksRef.current.delete(id);
|
|
2018
|
+
ownedIdsRef.current.delete(id);
|
|
1841
2019
|
},
|
|
1842
2020
|
[state.chart]
|
|
1843
2021
|
);
|
|
1844
2022
|
const removeAllOrderLines = react.useCallback(() => {
|
|
1845
2023
|
state.chart?.removeOverlay({ name: "orderLine" });
|
|
1846
2024
|
callbacksRef.current.clear();
|
|
2025
|
+
ownedIdsRef.current.clear();
|
|
2026
|
+
}, [state.chart]);
|
|
2027
|
+
react.useEffect(() => {
|
|
2028
|
+
const chart = state.chart;
|
|
2029
|
+
const owned = ownedIdsRef.current;
|
|
2030
|
+
return () => {
|
|
2031
|
+
owned.forEach((id) => {
|
|
2032
|
+
try {
|
|
2033
|
+
chart?.removeOverlay({ id });
|
|
2034
|
+
} catch {
|
|
2035
|
+
}
|
|
2036
|
+
});
|
|
2037
|
+
owned.clear();
|
|
2038
|
+
callbacksRef.current.clear();
|
|
2039
|
+
};
|
|
1847
2040
|
}, [state.chart]);
|
|
1848
2041
|
return {
|
|
1849
2042
|
createOrderLine,
|
|
@@ -1854,13 +2047,21 @@ function useOrderLines() {
|
|
|
1854
2047
|
}
|
|
1855
2048
|
var DRAWING_GROUP_ID2 = "drawing_tools";
|
|
1856
2049
|
function useUndoRedo() {
|
|
1857
|
-
const { state, dispatch } = useKlinechartsUI();
|
|
1858
|
-
const { undoRedoListenerRef } = useKlinechartsUIDispatch();
|
|
2050
|
+
const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
2051
|
+
const { undoRedoListenerRef } = chunkF24D6PWY_cjs.useKlinechartsUIDispatch();
|
|
1859
2052
|
const [undoStack, setUndoStack] = react.useState([]);
|
|
1860
2053
|
const [redoStack, setRedoStack] = react.useState([]);
|
|
1861
2054
|
const isProcessingRef = react.useRef(false);
|
|
1862
2055
|
const canUndo = undoStack.length > 0;
|
|
1863
2056
|
const canRedo = redoStack.length > 0;
|
|
2057
|
+
const undoStackRef = react.useRef([]);
|
|
2058
|
+
const redoStackRef = react.useRef([]);
|
|
2059
|
+
react.useEffect(() => {
|
|
2060
|
+
undoStackRef.current = undoStack;
|
|
2061
|
+
}, [undoStack]);
|
|
2062
|
+
react.useEffect(() => {
|
|
2063
|
+
redoStackRef.current = redoStack;
|
|
2064
|
+
}, [redoStack]);
|
|
1864
2065
|
const pushAction = react.useCallback((action) => {
|
|
1865
2066
|
if (isProcessingRef.current) return;
|
|
1866
2067
|
setUndoStack((prev) => [...prev, action]);
|
|
@@ -1877,10 +2078,11 @@ function useUndoRedo() {
|
|
|
1877
2078
|
setRedoStack([]);
|
|
1878
2079
|
}, []);
|
|
1879
2080
|
const undo = react.useCallback(() => {
|
|
1880
|
-
|
|
2081
|
+
const stack = undoStackRef.current;
|
|
2082
|
+
if (stack.length === 0 || !state.chart || isProcessingRef.current)
|
|
1881
2083
|
return;
|
|
1882
2084
|
isProcessingRef.current = true;
|
|
1883
|
-
const action =
|
|
2085
|
+
const action = stack[stack.length - 1];
|
|
1884
2086
|
setUndoStack((prev) => prev.slice(0, -1));
|
|
1885
2087
|
try {
|
|
1886
2088
|
switch (action.type) {
|
|
@@ -2001,12 +2203,13 @@ function useUndoRedo() {
|
|
|
2001
2203
|
} finally {
|
|
2002
2204
|
isProcessingRef.current = false;
|
|
2003
2205
|
}
|
|
2004
|
-
}, [
|
|
2206
|
+
}, [state.chart, state.mainIndicators, state.subIndicators, state.indicatorAxes, dispatch]);
|
|
2005
2207
|
const redo = react.useCallback(() => {
|
|
2006
|
-
|
|
2208
|
+
const stack = redoStackRef.current;
|
|
2209
|
+
if (stack.length === 0 || !state.chart || isProcessingRef.current)
|
|
2007
2210
|
return;
|
|
2008
2211
|
isProcessingRef.current = true;
|
|
2009
|
-
const action =
|
|
2212
|
+
const action = stack[stack.length - 1];
|
|
2010
2213
|
setRedoStack((prev) => prev.slice(0, -1));
|
|
2011
2214
|
try {
|
|
2012
2215
|
switch (action.type) {
|
|
@@ -2131,7 +2334,7 @@ function useUndoRedo() {
|
|
|
2131
2334
|
} finally {
|
|
2132
2335
|
isProcessingRef.current = false;
|
|
2133
2336
|
}
|
|
2134
|
-
}, [
|
|
2337
|
+
}, [state.chart, state.mainIndicators, state.subIndicators, state.indicatorAxes, dispatch]);
|
|
2135
2338
|
react.useEffect(() => {
|
|
2136
2339
|
const handleKeyDown = (e) => {
|
|
2137
2340
|
const isCtrlOrMeta = e.ctrlKey || e.metaKey;
|
|
@@ -2169,6 +2372,7 @@ function generateId() {
|
|
|
2169
2372
|
);
|
|
2170
2373
|
}
|
|
2171
2374
|
function getLayoutIds() {
|
|
2375
|
+
if (typeof localStorage === "undefined") return [];
|
|
2172
2376
|
try {
|
|
2173
2377
|
const raw = localStorage.getItem(INDEX_KEY);
|
|
2174
2378
|
return raw ? JSON.parse(raw) : [];
|
|
@@ -2177,6 +2381,7 @@ function getLayoutIds() {
|
|
|
2177
2381
|
}
|
|
2178
2382
|
}
|
|
2179
2383
|
function getEntry(id) {
|
|
2384
|
+
if (typeof localStorage === "undefined") return null;
|
|
2180
2385
|
try {
|
|
2181
2386
|
const raw = localStorage.getItem(STORAGE_KEY_PREFIX + id);
|
|
2182
2387
|
return raw ? JSON.parse(raw) : null;
|
|
@@ -2185,36 +2390,32 @@ function getEntry(id) {
|
|
|
2185
2390
|
}
|
|
2186
2391
|
}
|
|
2187
2392
|
function useLayoutManager() {
|
|
2188
|
-
const { state, dispatch } = useKlinechartsUI();
|
|
2189
|
-
const [layouts, setLayouts] = react.useState(
|
|
2393
|
+
const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
2394
|
+
const [layouts, setLayouts] = react.useState(
|
|
2395
|
+
() => getLayoutIds().map((id) => getEntry(id)).filter((e) => e !== null)
|
|
2396
|
+
);
|
|
2190
2397
|
const [autoSaveEnabled, setAutoSaveEnabled] = react.useState(false);
|
|
2191
2398
|
const autoSaveTimerRef = react.useRef(null);
|
|
2192
2399
|
const autoSaveIdRef = react.useRef(null);
|
|
2193
2400
|
const refreshLayouts = react.useCallback(() => {
|
|
2194
|
-
|
|
2195
|
-
|
|
2401
|
+
setLayouts(
|
|
2402
|
+
getLayoutIds().map((id) => getEntry(id)).filter((e) => e !== null)
|
|
2403
|
+
);
|
|
2196
2404
|
}, []);
|
|
2197
|
-
react.useEffect(() => {
|
|
2198
|
-
refreshLayouts();
|
|
2199
|
-
}, [refreshLayouts]);
|
|
2200
2405
|
const serializeState = react.useCallback(() => {
|
|
2201
2406
|
const chart = state.chart;
|
|
2202
2407
|
if (!chart) return null;
|
|
2203
2408
|
const indicators2 = [];
|
|
2204
|
-
const
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
...indicator.styles ? { styles: indicator.styles } : {},
|
|
2215
|
-
...yAxisId ? { yAxisId } : {}
|
|
2216
|
-
});
|
|
2217
|
-
});
|
|
2409
|
+
const allIndicators = chart.getIndicators();
|
|
2410
|
+
for (const indicator of allIndicators) {
|
|
2411
|
+
const yAxisId = state.indicatorAxes[indicator.id];
|
|
2412
|
+
indicators2.push({
|
|
2413
|
+
paneId: indicator.paneId,
|
|
2414
|
+
name: indicator.name,
|
|
2415
|
+
calcParams: indicator.calcParams,
|
|
2416
|
+
visible: indicator.visible,
|
|
2417
|
+
...indicator.styles ? { styles: indicator.styles } : {},
|
|
2418
|
+
...yAxisId ? { yAxisId } : {}
|
|
2218
2419
|
});
|
|
2219
2420
|
}
|
|
2220
2421
|
const drawings = [];
|
|
@@ -2278,13 +2479,8 @@ function useLayoutManager() {
|
|
|
2278
2479
|
if (chartState.version !== STATE_VERSION) return false;
|
|
2279
2480
|
const chart = state.chart;
|
|
2280
2481
|
chart.removeOverlay();
|
|
2281
|
-
const
|
|
2282
|
-
|
|
2283
|
-
indicatorMap.forEach((_paneIndicators, paneId) => {
|
|
2284
|
-
_paneIndicators.forEach((_, indicatorName) => {
|
|
2285
|
-
chart.removeIndicator({ paneId, name: indicatorName });
|
|
2286
|
-
});
|
|
2287
|
-
});
|
|
2482
|
+
for (const indicator of chart.getIndicators()) {
|
|
2483
|
+
chart.removeIndicator({ id: indicator.id });
|
|
2288
2484
|
}
|
|
2289
2485
|
const newMainIndicators = [];
|
|
2290
2486
|
const newSubIndicators = {};
|
|
@@ -2302,7 +2498,12 @@ function useLayoutManager() {
|
|
|
2302
2498
|
visible: ind.visible
|
|
2303
2499
|
},
|
|
2304
2500
|
{
|
|
2305
|
-
|
|
2501
|
+
// Main indicators stack OVER the candle series on the candle
|
|
2502
|
+
// pane (isStack: true), exactly as useIndicators does on the
|
|
2503
|
+
// add path. The previous `ind.paneId !== "candle_pane"` inverted
|
|
2504
|
+
// this, so loading a layout with main indicators replaced the
|
|
2505
|
+
// candles instead of overlaying them.
|
|
2506
|
+
isStack: isMain,
|
|
2306
2507
|
pane: { id: ind.paneId },
|
|
2307
2508
|
...ind.yAxisId ? { yAxis: { id: ind.yAxisId } } : {}
|
|
2308
2509
|
}
|
|
@@ -2493,7 +2694,7 @@ var SHADOW_KEYS = [
|
|
|
2493
2694
|
];
|
|
2494
2695
|
var scriptCounter = 0;
|
|
2495
2696
|
function useScriptEditor() {
|
|
2496
|
-
const { state } = useKlinechartsUI();
|
|
2697
|
+
const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
2497
2698
|
const [code, setCode] = react.useState(DEFAULT_SCRIPT);
|
|
2498
2699
|
const [scriptName, setScriptName] = react.useState("");
|
|
2499
2700
|
const [params, setParams] = react.useState("14");
|
|
@@ -2502,8 +2703,10 @@ function useScriptEditor() {
|
|
|
2502
2703
|
const [status, setStatus] = react.useState("");
|
|
2503
2704
|
const [isRunning, setIsRunning] = react.useState(false);
|
|
2504
2705
|
const activeIdRef = react.useRef(null);
|
|
2706
|
+
const [activeName, setActiveName] = react.useState(null);
|
|
2505
2707
|
const activeNameRef = react.useRef(null);
|
|
2506
|
-
|
|
2708
|
+
activeNameRef.current = activeName;
|
|
2709
|
+
const hasActiveScript = activeName !== null;
|
|
2507
2710
|
const runScript = react.useCallback(() => {
|
|
2508
2711
|
const chart = state.chart;
|
|
2509
2712
|
if (!chart) {
|
|
@@ -2524,31 +2727,38 @@ function useScriptEditor() {
|
|
|
2524
2727
|
`"use strict";
|
|
2525
2728
|
${code}`
|
|
2526
2729
|
];
|
|
2527
|
-
const
|
|
2730
|
+
const compiledFn = new Function(...allArgs);
|
|
2528
2731
|
const shadowValues = SHADOW_KEYS.map(() => void 0);
|
|
2529
|
-
const
|
|
2530
|
-
|
|
2732
|
+
const sampleResult = compiledFn(
|
|
2733
|
+
...shadowValues,
|
|
2734
|
+
chunkSZDU2D3D_cjs.TA_default,
|
|
2735
|
+
dataList,
|
|
2736
|
+
parsedParams
|
|
2737
|
+
);
|
|
2738
|
+
if (!Array.isArray(sampleResult)) {
|
|
2531
2739
|
throw new Error("Script must return an Array.");
|
|
2532
2740
|
}
|
|
2533
|
-
const sample =
|
|
2741
|
+
const sample = sampleResult.find(
|
|
2742
|
+
(v) => v !== null && v !== void 0
|
|
2743
|
+
);
|
|
2534
2744
|
const seriesKeys = sample ? Object.keys(sample) : ["value"];
|
|
2535
2745
|
if (seriesKeys.length === 0) {
|
|
2536
2746
|
throw new Error("Returned objects have no keys.");
|
|
2537
2747
|
}
|
|
2538
2748
|
scriptCounter++;
|
|
2539
|
-
const indicatorName = `
|
|
2749
|
+
const indicatorName = `_custom_script_active`;
|
|
2540
2750
|
const figures = seriesKeys.map((key, i) => ({
|
|
2541
2751
|
key,
|
|
2542
2752
|
title: `${key}: `,
|
|
2543
2753
|
type: "line",
|
|
2544
2754
|
styles: () => ({ color: SERIES_COLORS[i % SERIES_COLORS.length] })
|
|
2545
2755
|
}));
|
|
2546
|
-
|
|
2756
|
+
klinecharts.registerIndicator({
|
|
2547
2757
|
name: indicatorName,
|
|
2548
2758
|
shortName: (scriptName.trim() || `Script #${scriptCounter}`) + (placement === "main" ? " (Main)" : " (Sub)"),
|
|
2549
2759
|
calcParams: parsedParams,
|
|
2550
2760
|
figures,
|
|
2551
|
-
calc: () =>
|
|
2761
|
+
calc: (liveDataList) => compiledFn(...shadowValues, chunkSZDU2D3D_cjs.TA_default, liveDataList, parsedParams),
|
|
2552
2762
|
extendData: {
|
|
2553
2763
|
isCustomScript: true,
|
|
2554
2764
|
code,
|
|
@@ -2574,7 +2784,7 @@ ${code}`
|
|
|
2574
2784
|
paneId = chart.createIndicator({ name: indicatorName });
|
|
2575
2785
|
}
|
|
2576
2786
|
activeIdRef.current = typeof paneId === "string" ? paneId : null;
|
|
2577
|
-
|
|
2787
|
+
setActiveName(indicatorName);
|
|
2578
2788
|
const title = scriptName.trim() || `Script #${scriptCounter}`;
|
|
2579
2789
|
setStatus(
|
|
2580
2790
|
`${title} applied to ${placement === "main" ? "Main Chart" : "Sub Pane"} \u2014 ${seriesKeys.length} series: ${seriesKeys.join(", ")}`
|
|
@@ -2596,7 +2806,7 @@ ${code}`
|
|
|
2596
2806
|
} catch {
|
|
2597
2807
|
}
|
|
2598
2808
|
activeIdRef.current = null;
|
|
2599
|
-
|
|
2809
|
+
setActiveName(null);
|
|
2600
2810
|
setStatus("Indicator removed.");
|
|
2601
2811
|
}
|
|
2602
2812
|
}, [state.chart]);
|
|
@@ -2659,7 +2869,7 @@ ${code}`
|
|
|
2659
2869
|
};
|
|
2660
2870
|
}
|
|
2661
2871
|
function useCrosshair() {
|
|
2662
|
-
const { state } = useKlinechartsUI();
|
|
2872
|
+
const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
2663
2873
|
const [barData, setBarData] = react.useState(null);
|
|
2664
2874
|
const rafRef = react.useRef(0);
|
|
2665
2875
|
const handler = react.useCallback(
|
|
@@ -2709,11 +2919,11 @@ function useCrosshair() {
|
|
|
2709
2919
|
}
|
|
2710
2920
|
var alertCounter = 0;
|
|
2711
2921
|
function useAlerts() {
|
|
2712
|
-
const { state, dispatch } = useKlinechartsUI();
|
|
2713
|
-
const {
|
|
2922
|
+
const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
2923
|
+
const { alertTriggeredListenersRef } = chunkF24D6PWY_cjs.useKlinechartsUIDispatch();
|
|
2714
2924
|
const alerts = state.alerts;
|
|
2715
2925
|
const addAlert = react.useCallback(
|
|
2716
|
-
(price, condition, message, extendData) => {
|
|
2926
|
+
(price, condition, message, extendData, target) => {
|
|
2717
2927
|
const id = `alert_${++alertCounter}`;
|
|
2718
2928
|
const precision = state.chart?.getSymbol()?.pricePrecision ?? 2;
|
|
2719
2929
|
const resolvedExtendData = {
|
|
@@ -2726,11 +2936,14 @@ function useAlerts() {
|
|
|
2726
2936
|
condition,
|
|
2727
2937
|
message,
|
|
2728
2938
|
triggered: false,
|
|
2729
|
-
extendData: resolvedExtendData
|
|
2939
|
+
extendData: resolvedExtendData,
|
|
2940
|
+
// Persist the target only when it's an indicator alert; omit for the
|
|
2941
|
+
// default price target so existing serialized alerts stay compatible.
|
|
2942
|
+
...target && target.type === "indicator" ? { target } : {}
|
|
2730
2943
|
};
|
|
2731
|
-
dispatch({ type: "
|
|
2944
|
+
dispatch({ type: "ADD_ALERT", alert });
|
|
2732
2945
|
if (state.chart) {
|
|
2733
|
-
|
|
2946
|
+
chunkSZDU2D3D_cjs.ensureAlertLineRegistered();
|
|
2734
2947
|
state.chart.createOverlay({
|
|
2735
2948
|
name: "alertLine",
|
|
2736
2949
|
id,
|
|
@@ -2742,29 +2955,28 @@ function useAlerts() {
|
|
|
2742
2955
|
}
|
|
2743
2956
|
return id;
|
|
2744
2957
|
},
|
|
2745
|
-
[state.chart,
|
|
2958
|
+
[state.chart, dispatch]
|
|
2746
2959
|
);
|
|
2747
2960
|
const removeAlert = react.useCallback(
|
|
2748
2961
|
(id) => {
|
|
2749
|
-
dispatch({
|
|
2750
|
-
type: "SET_ALERTS",
|
|
2751
|
-
alerts: state.alerts.filter((a) => a.id !== id)
|
|
2752
|
-
});
|
|
2962
|
+
dispatch({ type: "REMOVE_ALERT", id });
|
|
2753
2963
|
state.chart?.removeOverlay({ id });
|
|
2754
2964
|
},
|
|
2755
|
-
[state.chart,
|
|
2965
|
+
[state.chart, dispatch]
|
|
2756
2966
|
);
|
|
2757
2967
|
const clearAlerts = react.useCallback(() => {
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
dispatch({ type: "SET_ALERTS", alerts: [] });
|
|
2762
|
-
}, [state.chart, state.alerts, dispatch]);
|
|
2968
|
+
state.chart?.removeOverlay({ groupId: "price_alerts" });
|
|
2969
|
+
dispatch({ type: "CLEAR_ALERTS" });
|
|
2970
|
+
}, [state.chart, dispatch]);
|
|
2763
2971
|
const onAlertTriggered = react.useCallback(
|
|
2764
2972
|
(callback) => {
|
|
2765
|
-
|
|
2973
|
+
const set = alertTriggeredListenersRef.current;
|
|
2974
|
+
set.add(callback);
|
|
2975
|
+
return () => {
|
|
2976
|
+
set.delete(callback);
|
|
2977
|
+
};
|
|
2766
2978
|
},
|
|
2767
|
-
[
|
|
2979
|
+
[alertTriggeredListenersRef]
|
|
2768
2980
|
);
|
|
2769
2981
|
return {
|
|
2770
2982
|
alerts,
|
|
@@ -2775,7 +2987,7 @@ function useAlerts() {
|
|
|
2775
2987
|
};
|
|
2776
2988
|
}
|
|
2777
2989
|
function useDataExport() {
|
|
2778
|
-
const { state } = useKlinechartsUI();
|
|
2990
|
+
const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
2779
2991
|
const exportAll = react.useCallback(
|
|
2780
2992
|
(format) => {
|
|
2781
2993
|
if (!state.chart) return;
|
|
@@ -2841,8 +3053,8 @@ function downloadData(dataList, format, ticker) {
|
|
|
2841
3053
|
URL.revokeObjectURL(url);
|
|
2842
3054
|
}
|
|
2843
3055
|
function useWatchlist() {
|
|
2844
|
-
const { state } = useKlinechartsUI();
|
|
2845
|
-
const { dispatch, datafeed } = useKlinechartsUIDispatch();
|
|
3056
|
+
const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
3057
|
+
const { dispatch, datafeed } = chunkF24D6PWY_cjs.useKlinechartsUIDispatch();
|
|
2846
3058
|
const [items, setItems] = react.useState([]);
|
|
2847
3059
|
const subscriptionsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
2848
3060
|
const activeSymbol = state.symbol?.ticker ?? null;
|
|
@@ -2911,8 +3123,8 @@ function useWatchlist() {
|
|
|
2911
3123
|
};
|
|
2912
3124
|
}
|
|
2913
3125
|
function useReplay() {
|
|
2914
|
-
const { state, dispatch } = useKlinechartsUI();
|
|
2915
|
-
const { replayIntervalRef, replaySavedDataRef, replayIndexRef } = useKlinechartsUIDispatch();
|
|
3126
|
+
const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
3127
|
+
const { replayIntervalRef, replaySavedDataRef, replayIndexRef } = chunkF24D6PWY_cjs.useKlinechartsUIDispatch();
|
|
2916
3128
|
const { isReplaying, isPaused, speed, barIndex, totalBars } = state.replay;
|
|
2917
3129
|
const clearInterval_ = react.useCallback(() => {
|
|
2918
3130
|
if (replayIntervalRef.current !== null) {
|
|
@@ -2943,6 +3155,7 @@ function useReplay() {
|
|
|
2943
3155
|
);
|
|
2944
3156
|
const startReplay = react.useCallback(() => {
|
|
2945
3157
|
if (!state.chart) return;
|
|
3158
|
+
if (isReplaying) return;
|
|
2946
3159
|
const dataList = state.chart.getDataList();
|
|
2947
3160
|
if (!dataList || dataList.length === 0) return;
|
|
2948
3161
|
replaySavedDataRef.current = [...dataList];
|
|
@@ -2958,7 +3171,12 @@ function useReplay() {
|
|
|
2958
3171
|
});
|
|
2959
3172
|
state.chart.clearData?.();
|
|
2960
3173
|
startInterval(speed);
|
|
2961
|
-
}, [state.chart, speed, startInterval, replaySavedDataRef, replayIndexRef, dispatch]);
|
|
3174
|
+
}, [state.chart, state.symbol, state.period, speed, startInterval, isReplaying, replaySavedDataRef, replayIndexRef, dispatch]);
|
|
3175
|
+
react.useEffect(() => {
|
|
3176
|
+
if (isReplaying) {
|
|
3177
|
+
stopReplay();
|
|
3178
|
+
}
|
|
3179
|
+
}, [state.symbol, state.period]);
|
|
2962
3180
|
const stopReplay = react.useCallback(() => {
|
|
2963
3181
|
if (!state.chart) return;
|
|
2964
3182
|
clearInterval_();
|
|
@@ -3054,24 +3272,29 @@ var DEFAULT_COLORS = [
|
|
|
3054
3272
|
"#ff5722",
|
|
3055
3273
|
"#8bc34a"
|
|
3056
3274
|
];
|
|
3057
|
-
var colorIndex = 0;
|
|
3058
|
-
var compareCounter = 0;
|
|
3059
3275
|
function useCompare() {
|
|
3060
|
-
const { state, datafeed } = useKlinechartsUI();
|
|
3276
|
+
const { state, datafeed } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
3061
3277
|
const [symbols, setSymbols] = react.useState([]);
|
|
3062
3278
|
const indicatorsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
3279
|
+
const instanceSalt = react.useId().replace(/[^a-zA-Z0-9]/g, "");
|
|
3063
3280
|
const addSymbol = react.useCallback(
|
|
3064
3281
|
async (ticker, color) => {
|
|
3065
3282
|
if (!state.chart || !datafeed) return;
|
|
3066
3283
|
if (indicatorsRef.current.has(ticker)) return;
|
|
3067
|
-
const assignedColor = color ?? DEFAULT_COLORS[
|
|
3284
|
+
const assignedColor = color ?? DEFAULT_COLORS[symbols.length % DEFAULT_COLORS.length];
|
|
3068
3285
|
const mainDataList = state.chart.getDataList();
|
|
3069
3286
|
if (!mainDataList || mainDataList.length === 0) return;
|
|
3070
3287
|
const from = mainDataList[0].timestamp;
|
|
3071
3288
|
const to = mainDataList[mainDataList.length - 1].timestamp;
|
|
3289
|
+
const mainSymbol = state.symbol;
|
|
3290
|
+
const symbol = {
|
|
3291
|
+
ticker,
|
|
3292
|
+
pricePrecision: mainSymbol?.pricePrecision ?? 2,
|
|
3293
|
+
volumePrecision: mainSymbol?.volumePrecision ?? 8
|
|
3294
|
+
};
|
|
3072
3295
|
const compareData = await datafeed.getHistoryKLineData(
|
|
3073
|
-
|
|
3074
|
-
|
|
3296
|
+
symbol,
|
|
3297
|
+
state.period,
|
|
3075
3298
|
from,
|
|
3076
3299
|
to
|
|
3077
3300
|
);
|
|
@@ -3090,14 +3313,8 @@ function useCompare() {
|
|
|
3090
3313
|
}
|
|
3091
3314
|
if (basePrice === null || basePrice === 0) return;
|
|
3092
3315
|
const bp = basePrice;
|
|
3093
|
-
const
|
|
3094
|
-
|
|
3095
|
-
return {
|
|
3096
|
-
pct: close != null ? (close - bp) / bp * 100 : NaN
|
|
3097
|
-
};
|
|
3098
|
-
});
|
|
3099
|
-
const indicatorName = `__cmp_${++compareCounter}_${ticker}`;
|
|
3100
|
-
reactKlinecharts.registerIndicator({
|
|
3316
|
+
const indicatorName = `__cmp_${instanceSalt}_${ticker}`;
|
|
3317
|
+
klinecharts.registerIndicator({
|
|
3101
3318
|
name: indicatorName,
|
|
3102
3319
|
shortName: ticker,
|
|
3103
3320
|
figures: [
|
|
@@ -3108,7 +3325,16 @@ function useCompare() {
|
|
|
3108
3325
|
styles: () => ({ color: assignedColor })
|
|
3109
3326
|
}
|
|
3110
3327
|
],
|
|
3111
|
-
calc: () =>
|
|
3328
|
+
calc: (dataList) => {
|
|
3329
|
+
let lastPct = null;
|
|
3330
|
+
return dataList.map((bar) => {
|
|
3331
|
+
const close = compareMap.get(bar.timestamp);
|
|
3332
|
+
if (close != null) {
|
|
3333
|
+
lastPct = (close - bp) / bp * 100;
|
|
3334
|
+
}
|
|
3335
|
+
return { pct: lastPct };
|
|
3336
|
+
});
|
|
3337
|
+
}
|
|
3112
3338
|
});
|
|
3113
3339
|
const paneId = state.chart.createIndicator(
|
|
3114
3340
|
{ name: indicatorName },
|
|
@@ -3126,7 +3352,7 @@ function useCompare() {
|
|
|
3126
3352
|
];
|
|
3127
3353
|
});
|
|
3128
3354
|
},
|
|
3129
|
-
[state.chart, state.period, datafeed]
|
|
3355
|
+
[state.chart, state.symbol, state.period, datafeed, symbols.length, instanceSalt]
|
|
3130
3356
|
);
|
|
3131
3357
|
const removeSymbol = react.useCallback(
|
|
3132
3358
|
(ticker) => {
|
|
@@ -3193,7 +3419,7 @@ function computeResult(from, to) {
|
|
|
3193
3419
|
return { from, to, priceDiff, pricePercent, bars, timeDiff };
|
|
3194
3420
|
}
|
|
3195
3421
|
function useMeasure() {
|
|
3196
|
-
const { state, dispatch } = useKlinechartsUI();
|
|
3422
|
+
const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
3197
3423
|
const { isActive, fromPoint, result } = state.measure;
|
|
3198
3424
|
const cleanup = react.useCallback(() => {
|
|
3199
3425
|
state.chart?.removeOverlay({ id: MEASURE_OVERLAY_ID });
|
|
@@ -3274,7 +3500,7 @@ function useMeasure() {
|
|
|
3274
3500
|
}
|
|
3275
3501
|
var annotationCounter = 0;
|
|
3276
3502
|
function useAnnotations() {
|
|
3277
|
-
const { state } = useKlinechartsUI();
|
|
3503
|
+
const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
3278
3504
|
const [annotations, setAnnotations] = react.useState([]);
|
|
3279
3505
|
const addAnnotation = react.useCallback(
|
|
3280
3506
|
(text, price, timestamp, color) => {
|
|
@@ -3336,13 +3562,11 @@ function useAnnotations() {
|
|
|
3336
3562
|
[state.chart]
|
|
3337
3563
|
);
|
|
3338
3564
|
const clearAnnotations = react.useCallback(() => {
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
});
|
|
3345
|
-
}, [state.chart]);
|
|
3565
|
+
for (const annotation of annotations) {
|
|
3566
|
+
state.chart?.removeOverlay({ id: annotation.id });
|
|
3567
|
+
}
|
|
3568
|
+
setAnnotations([]);
|
|
3569
|
+
}, [state.chart, annotations]);
|
|
3346
3570
|
react.useEffect(() => {
|
|
3347
3571
|
return () => {
|
|
3348
3572
|
state.chart?.removeOverlay({ groupId: "annotations" });
|
|
@@ -3356,265 +3580,375 @@ function useAnnotations() {
|
|
|
3356
3580
|
clearAnnotations
|
|
3357
3581
|
};
|
|
3358
3582
|
}
|
|
3583
|
+
var WorkspaceContext = react.createContext(null);
|
|
3584
|
+
function useWorkspace() {
|
|
3585
|
+
const ctx = react.useContext(WorkspaceContext);
|
|
3586
|
+
if (!ctx) {
|
|
3587
|
+
throw new Error("useWorkspace must be used within a <WorkspaceProvider>");
|
|
3588
|
+
}
|
|
3589
|
+
return ctx;
|
|
3590
|
+
}
|
|
3359
3591
|
|
|
3360
|
-
// src/
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3592
|
+
// src/workspace/types.ts
|
|
3593
|
+
var DEFAULT_SYNC_CONFIG = {
|
|
3594
|
+
crosshair: true,
|
|
3595
|
+
scroll: true,
|
|
3596
|
+
zoom: true,
|
|
3597
|
+
symbol: true,
|
|
3598
|
+
period: true
|
|
3599
|
+
};
|
|
3600
|
+
function reducer2(state, action) {
|
|
3601
|
+
switch (action.type) {
|
|
3602
|
+
case "SET_CELLS":
|
|
3603
|
+
return { ...state, cells: action.cells };
|
|
3604
|
+
case "ADD_CELL":
|
|
3605
|
+
return { ...state, cells: [...state.cells, action.cell] };
|
|
3606
|
+
case "REMOVE_CELL": {
|
|
3607
|
+
const cells = state.cells.filter((c) => c.id !== action.id);
|
|
3608
|
+
return {
|
|
3609
|
+
cells,
|
|
3610
|
+
activeCellId: state.activeCellId === action.id ? cells[0]?.id ?? null : state.activeCellId
|
|
3611
|
+
};
|
|
3612
|
+
}
|
|
3613
|
+
case "SET_CELL_SYMBOL":
|
|
3614
|
+
return {
|
|
3615
|
+
...state,
|
|
3616
|
+
cells: state.cells.map(
|
|
3617
|
+
(c) => c.id === action.id ? { ...c, symbol: action.symbol } : c
|
|
3618
|
+
)
|
|
3619
|
+
};
|
|
3620
|
+
case "SET_CELL_PERIOD":
|
|
3621
|
+
return {
|
|
3622
|
+
...state,
|
|
3623
|
+
cells: state.cells.map(
|
|
3624
|
+
(c) => c.id === action.id ? { ...c, period: action.period } : c
|
|
3625
|
+
)
|
|
3626
|
+
};
|
|
3627
|
+
case "SET_ACTIVE_CELL":
|
|
3628
|
+
return { ...state, activeCellId: action.id };
|
|
3629
|
+
default:
|
|
3630
|
+
return state;
|
|
3631
|
+
}
|
|
3632
|
+
}
|
|
3633
|
+
function WorkspaceProvider({
|
|
3634
|
+
defaultCells,
|
|
3635
|
+
sync,
|
|
3636
|
+
children
|
|
3637
|
+
}) {
|
|
3638
|
+
const [state, dispatch] = react.useReducer(reducer2, defaultCells, (cells) => ({
|
|
3639
|
+
cells,
|
|
3640
|
+
activeCellId: cells[0]?.id ?? null
|
|
3641
|
+
}));
|
|
3642
|
+
const chartsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
3643
|
+
const broadcastingRef = react.useRef(false);
|
|
3644
|
+
const resolvedSync = react.useMemo(
|
|
3645
|
+
() => ({ ...DEFAULT_SYNC_CONFIG, ...sync }),
|
|
3646
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3647
|
+
[]
|
|
3648
|
+
);
|
|
3649
|
+
const value = react.useMemo(
|
|
3650
|
+
() => ({
|
|
3651
|
+
state,
|
|
3652
|
+
dispatch,
|
|
3653
|
+
chartsRef,
|
|
3654
|
+
broadcastingRef,
|
|
3655
|
+
sync: resolvedSync
|
|
3656
|
+
}),
|
|
3657
|
+
[state, resolvedSync]
|
|
3658
|
+
);
|
|
3659
|
+
return /* @__PURE__ */ jsxRuntime.jsx(WorkspaceContext.Provider, { value, children });
|
|
3660
|
+
}
|
|
3661
|
+
function useChartSync({ cellId }) {
|
|
3662
|
+
const { chartsRef, broadcastingRef, sync, dispatch: workspaceDispatch } = useWorkspace();
|
|
3663
|
+
const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
|
|
3664
|
+
const chart = state.chart;
|
|
3665
|
+
react.useEffect(() => {
|
|
3666
|
+
if (!chart) return;
|
|
3667
|
+
chartsRef.current.set(cellId, chart);
|
|
3668
|
+
return () => {
|
|
3669
|
+
chartsRef.current.delete(cellId);
|
|
3670
|
+
};
|
|
3671
|
+
}, [chart, cellId, chartsRef]);
|
|
3672
|
+
react.useEffect(() => {
|
|
3673
|
+
if (!chart) return;
|
|
3674
|
+
const broadcast = (fn) => {
|
|
3675
|
+
if (broadcastingRef.current) return;
|
|
3676
|
+
broadcastingRef.current = true;
|
|
3366
3677
|
try {
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
{ ...params.period, label: "" },
|
|
3374
|
-
0,
|
|
3375
|
-
Date.now()
|
|
3376
|
-
);
|
|
3377
|
-
if (gen !== currentGen) return;
|
|
3378
|
-
if (data.length > 0) {
|
|
3379
|
-
oldestTimestamp = data[0].timestamp;
|
|
3380
|
-
}
|
|
3381
|
-
params.callback(data, {
|
|
3382
|
-
forward: data.length > 0,
|
|
3383
|
-
backward: false
|
|
3384
|
-
});
|
|
3385
|
-
} else if (params.type === "forward" && oldestTimestamp !== null) {
|
|
3386
|
-
const gen = currentGen;
|
|
3387
|
-
const data = await datafeed.getHistoryKLineData(
|
|
3388
|
-
params.symbol,
|
|
3389
|
-
{ ...params.period, label: "" },
|
|
3390
|
-
0,
|
|
3391
|
-
oldestTimestamp - 1
|
|
3392
|
-
);
|
|
3393
|
-
if (gen !== currentGen) return;
|
|
3394
|
-
if (data.length > 0) {
|
|
3395
|
-
oldestTimestamp = data[0].timestamp;
|
|
3678
|
+
chartsRef.current.forEach((target, id) => {
|
|
3679
|
+
if (id !== cellId) {
|
|
3680
|
+
try {
|
|
3681
|
+
fn(target);
|
|
3682
|
+
} catch {
|
|
3683
|
+
}
|
|
3396
3684
|
}
|
|
3397
|
-
|
|
3398
|
-
forward: data.length > 0,
|
|
3399
|
-
backward: false
|
|
3400
|
-
});
|
|
3401
|
-
} else if (params.type === "backward") {
|
|
3402
|
-
params.callback([], { forward: false, backward: false });
|
|
3403
|
-
}
|
|
3404
|
-
} catch (error) {
|
|
3405
|
-
console.error("Failed to load chart data:", error);
|
|
3406
|
-
params.callback([], { forward: false, backward: false });
|
|
3685
|
+
});
|
|
3407
3686
|
} finally {
|
|
3408
|
-
|
|
3687
|
+
broadcastingRef.current = false;
|
|
3409
3688
|
}
|
|
3410
|
-
}
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3689
|
+
};
|
|
3690
|
+
const onCrosshairChange = (data) => {
|
|
3691
|
+
if (!sync.crosshair) return;
|
|
3692
|
+
const crosshair = data;
|
|
3693
|
+
if (!crosshair) return;
|
|
3694
|
+
broadcast((target) => target.executeAction("onCrosshairChange", crosshair));
|
|
3695
|
+
};
|
|
3696
|
+
const onScroll = () => {
|
|
3697
|
+
if (!sync.scroll) return;
|
|
3698
|
+
let range = null;
|
|
3699
|
+
try {
|
|
3700
|
+
range = chart.getVisibleRange();
|
|
3701
|
+
} catch {
|
|
3702
|
+
return;
|
|
3703
|
+
}
|
|
3704
|
+
if (!range || range.realTo == null) return;
|
|
3705
|
+
broadcast(
|
|
3706
|
+
(target) => target.scrollToTimestamp(range.realTo, 0)
|
|
3416
3707
|
);
|
|
3417
|
-
}
|
|
3418
|
-
|
|
3419
|
-
|
|
3708
|
+
};
|
|
3709
|
+
const onZoom = () => {
|
|
3710
|
+
if (!sync.zoom) return;
|
|
3711
|
+
let bar = 0;
|
|
3712
|
+
try {
|
|
3713
|
+
bar = chart.getBarSpace().bar;
|
|
3714
|
+
} catch {
|
|
3715
|
+
return;
|
|
3716
|
+
}
|
|
3717
|
+
broadcast((target) => target.setBarSpace(bar));
|
|
3718
|
+
};
|
|
3719
|
+
chart.subscribeAction("onCrosshairChange", onCrosshairChange);
|
|
3720
|
+
chart.subscribeAction("onScroll", onScroll);
|
|
3721
|
+
chart.subscribeAction("onZoom", onZoom);
|
|
3722
|
+
return () => {
|
|
3723
|
+
chart.unsubscribeAction("onCrosshairChange", onCrosshairChange);
|
|
3724
|
+
chart.unsubscribeAction("onScroll", onScroll);
|
|
3725
|
+
chart.unsubscribeAction("onZoom", onZoom);
|
|
3726
|
+
};
|
|
3727
|
+
}, [chart, cellId, chartsRef, broadcastingRef, sync.crosshair, sync.scroll, sync.zoom]);
|
|
3728
|
+
react.useEffect(() => {
|
|
3729
|
+
if (state.symbol) {
|
|
3730
|
+
workspaceDispatch({ type: "SET_CELL_SYMBOL", id: cellId, symbol: state.symbol });
|
|
3420
3731
|
}
|
|
3421
|
-
};
|
|
3732
|
+
}, [state.symbol]);
|
|
3733
|
+
react.useEffect(() => {
|
|
3734
|
+
workspaceDispatch({ type: "SET_CELL_PERIOD", id: cellId, period: state.period });
|
|
3735
|
+
}, [state.period]);
|
|
3422
3736
|
}
|
|
3423
3737
|
|
|
3424
3738
|
Object.defineProperty(exports, "TA", {
|
|
3425
3739
|
enumerable: true,
|
|
3426
|
-
get: function () { return
|
|
3740
|
+
get: function () { return chunkSZDU2D3D_cjs.TA_default; }
|
|
3427
3741
|
});
|
|
3428
3742
|
Object.defineProperty(exports, "abcd", {
|
|
3429
3743
|
enumerable: true,
|
|
3430
|
-
get: function () { return
|
|
3744
|
+
get: function () { return chunkSZDU2D3D_cjs.abcd_default; }
|
|
3431
3745
|
});
|
|
3432
3746
|
Object.defineProperty(exports, "alertLine", {
|
|
3433
3747
|
enumerable: true,
|
|
3434
|
-
get: function () { return
|
|
3748
|
+
get: function () { return chunkSZDU2D3D_cjs.alertLine_default; }
|
|
3435
3749
|
});
|
|
3436
3750
|
Object.defineProperty(exports, "anyWaves", {
|
|
3437
3751
|
enumerable: true,
|
|
3438
|
-
get: function () { return
|
|
3752
|
+
get: function () { return chunkSZDU2D3D_cjs.anyWaves_default; }
|
|
3439
3753
|
});
|
|
3440
3754
|
Object.defineProperty(exports, "arrow", {
|
|
3441
3755
|
enumerable: true,
|
|
3442
|
-
get: function () { return
|
|
3756
|
+
get: function () { return chunkSZDU2D3D_cjs.arrow_default; }
|
|
3443
3757
|
});
|
|
3444
3758
|
Object.defineProperty(exports, "bollTv", {
|
|
3445
3759
|
enumerable: true,
|
|
3446
|
-
get: function () { return
|
|
3760
|
+
get: function () { return chunkSZDU2D3D_cjs.bollTv_default; }
|
|
3447
3761
|
});
|
|
3448
3762
|
Object.defineProperty(exports, "brush", {
|
|
3449
3763
|
enumerable: true,
|
|
3450
|
-
get: function () { return
|
|
3764
|
+
get: function () { return chunkSZDU2D3D_cjs.brush_default; }
|
|
3451
3765
|
});
|
|
3452
3766
|
Object.defineProperty(exports, "cci", {
|
|
3453
3767
|
enumerable: true,
|
|
3454
|
-
get: function () { return
|
|
3768
|
+
get: function () { return chunkSZDU2D3D_cjs.cci_default; }
|
|
3455
3769
|
});
|
|
3456
3770
|
Object.defineProperty(exports, "circle", {
|
|
3457
3771
|
enumerable: true,
|
|
3458
|
-
get: function () { return
|
|
3772
|
+
get: function () { return chunkSZDU2D3D_cjs.circle_default; }
|
|
3459
3773
|
});
|
|
3460
3774
|
Object.defineProperty(exports, "depthOverlay", {
|
|
3461
3775
|
enumerable: true,
|
|
3462
|
-
get: function () { return
|
|
3776
|
+
get: function () { return chunkSZDU2D3D_cjs.depthOverlay_default; }
|
|
3463
3777
|
});
|
|
3464
3778
|
Object.defineProperty(exports, "eightWaves", {
|
|
3465
3779
|
enumerable: true,
|
|
3466
|
-
get: function () { return
|
|
3780
|
+
get: function () { return chunkSZDU2D3D_cjs.eightWaves_default; }
|
|
3467
3781
|
});
|
|
3468
3782
|
Object.defineProperty(exports, "elliottWave", {
|
|
3469
3783
|
enumerable: true,
|
|
3470
|
-
get: function () { return
|
|
3784
|
+
get: function () { return chunkSZDU2D3D_cjs.elliottWave_default; }
|
|
3471
3785
|
});
|
|
3472
3786
|
Object.defineProperty(exports, "fibRetracement", {
|
|
3473
3787
|
enumerable: true,
|
|
3474
|
-
get: function () { return
|
|
3788
|
+
get: function () { return chunkSZDU2D3D_cjs.fibRetracement_default; }
|
|
3475
3789
|
});
|
|
3476
3790
|
Object.defineProperty(exports, "fibonacciCircle", {
|
|
3477
3791
|
enumerable: true,
|
|
3478
|
-
get: function () { return
|
|
3792
|
+
get: function () { return chunkSZDU2D3D_cjs.fibonacciCircle_default; }
|
|
3479
3793
|
});
|
|
3480
3794
|
Object.defineProperty(exports, "fibonacciExtension", {
|
|
3481
3795
|
enumerable: true,
|
|
3482
|
-
get: function () { return
|
|
3796
|
+
get: function () { return chunkSZDU2D3D_cjs.fibonacciExtension_default; }
|
|
3483
3797
|
});
|
|
3484
3798
|
Object.defineProperty(exports, "fibonacciSegment", {
|
|
3485
3799
|
enumerable: true,
|
|
3486
|
-
get: function () { return
|
|
3800
|
+
get: function () { return chunkSZDU2D3D_cjs.fibonacciSegment_default; }
|
|
3487
3801
|
});
|
|
3488
3802
|
Object.defineProperty(exports, "fibonacciSpeedResistanceFan", {
|
|
3489
3803
|
enumerable: true,
|
|
3490
|
-
get: function () { return
|
|
3804
|
+
get: function () { return chunkSZDU2D3D_cjs.fibonacciSpeedResistanceFan_default; }
|
|
3491
3805
|
});
|
|
3492
3806
|
Object.defineProperty(exports, "fibonacciSpiral", {
|
|
3493
3807
|
enumerable: true,
|
|
3494
|
-
get: function () { return
|
|
3808
|
+
get: function () { return chunkSZDU2D3D_cjs.fibonacciSpiral_default; }
|
|
3495
3809
|
});
|
|
3496
3810
|
Object.defineProperty(exports, "fiveWaves", {
|
|
3497
3811
|
enumerable: true,
|
|
3498
|
-
get: function () { return
|
|
3812
|
+
get: function () { return chunkSZDU2D3D_cjs.fiveWaves_default; }
|
|
3499
3813
|
});
|
|
3500
3814
|
Object.defineProperty(exports, "gannBox", {
|
|
3501
3815
|
enumerable: true,
|
|
3502
|
-
get: function () { return
|
|
3816
|
+
get: function () { return chunkSZDU2D3D_cjs.gannBox_default; }
|
|
3503
3817
|
});
|
|
3504
3818
|
Object.defineProperty(exports, "gannFan", {
|
|
3505
3819
|
enumerable: true,
|
|
3506
|
-
get: function () { return
|
|
3820
|
+
get: function () { return chunkSZDU2D3D_cjs.gannFan_default; }
|
|
3507
3821
|
});
|
|
3508
3822
|
Object.defineProperty(exports, "hma", {
|
|
3509
3823
|
enumerable: true,
|
|
3510
|
-
get: function () { return
|
|
3824
|
+
get: function () { return chunkSZDU2D3D_cjs.hma_default; }
|
|
3511
3825
|
});
|
|
3512
3826
|
Object.defineProperty(exports, "ichimoku", {
|
|
3513
3827
|
enumerable: true,
|
|
3514
|
-
get: function () { return
|
|
3828
|
+
get: function () { return chunkSZDU2D3D_cjs.ichimoku_default; }
|
|
3515
3829
|
});
|
|
3516
3830
|
Object.defineProperty(exports, "indicators", {
|
|
3517
3831
|
enumerable: true,
|
|
3518
|
-
get: function () { return
|
|
3832
|
+
get: function () { return chunkSZDU2D3D_cjs.indicators; }
|
|
3519
3833
|
});
|
|
3520
3834
|
Object.defineProperty(exports, "longPosition", {
|
|
3521
3835
|
enumerable: true,
|
|
3522
|
-
get: function () { return
|
|
3836
|
+
get: function () { return chunkSZDU2D3D_cjs.longPosition_default; }
|
|
3523
3837
|
});
|
|
3524
3838
|
Object.defineProperty(exports, "maRibbon", {
|
|
3525
3839
|
enumerable: true,
|
|
3526
|
-
get: function () { return
|
|
3840
|
+
get: function () { return chunkSZDU2D3D_cjs.maRibbon_default; }
|
|
3527
3841
|
});
|
|
3528
3842
|
Object.defineProperty(exports, "macdTv", {
|
|
3529
3843
|
enumerable: true,
|
|
3530
|
-
get: function () { return
|
|
3844
|
+
get: function () { return chunkSZDU2D3D_cjs.macdTv_default; }
|
|
3531
3845
|
});
|
|
3532
3846
|
Object.defineProperty(exports, "measure", {
|
|
3533
3847
|
enumerable: true,
|
|
3534
|
-
get: function () { return
|
|
3848
|
+
get: function () { return chunkSZDU2D3D_cjs.measure_default; }
|
|
3535
3849
|
});
|
|
3536
3850
|
Object.defineProperty(exports, "orderLine", {
|
|
3537
3851
|
enumerable: true,
|
|
3538
|
-
get: function () { return
|
|
3852
|
+
get: function () { return chunkSZDU2D3D_cjs.orderLine_default; }
|
|
3539
3853
|
});
|
|
3540
3854
|
Object.defineProperty(exports, "overlays", {
|
|
3541
3855
|
enumerable: true,
|
|
3542
|
-
get: function () { return
|
|
3856
|
+
get: function () { return chunkSZDU2D3D_cjs.overlays; }
|
|
3543
3857
|
});
|
|
3544
3858
|
Object.defineProperty(exports, "parallelChannel", {
|
|
3545
3859
|
enumerable: true,
|
|
3546
|
-
get: function () { return
|
|
3860
|
+
get: function () { return chunkSZDU2D3D_cjs.parallelChannel_default; }
|
|
3547
3861
|
});
|
|
3548
3862
|
Object.defineProperty(exports, "parallelogram", {
|
|
3549
3863
|
enumerable: true,
|
|
3550
|
-
get: function () { return
|
|
3864
|
+
get: function () { return chunkSZDU2D3D_cjs.parallelogram_default; }
|
|
3551
3865
|
});
|
|
3552
3866
|
Object.defineProperty(exports, "pivotPoints", {
|
|
3553
3867
|
enumerable: true,
|
|
3554
|
-
get: function () { return
|
|
3868
|
+
get: function () { return chunkSZDU2D3D_cjs.pivotPoints_default; }
|
|
3555
3869
|
});
|
|
3556
3870
|
Object.defineProperty(exports, "ray", {
|
|
3557
3871
|
enumerable: true,
|
|
3558
|
-
get: function () { return
|
|
3872
|
+
get: function () { return chunkSZDU2D3D_cjs.ray_default; }
|
|
3559
3873
|
});
|
|
3560
3874
|
Object.defineProperty(exports, "rect", {
|
|
3561
3875
|
enumerable: true,
|
|
3562
|
-
get: function () { return
|
|
3876
|
+
get: function () { return chunkSZDU2D3D_cjs.rect_default; }
|
|
3563
3877
|
});
|
|
3564
3878
|
Object.defineProperty(exports, "registerExtensions", {
|
|
3565
3879
|
enumerable: true,
|
|
3566
|
-
get: function () { return
|
|
3880
|
+
get: function () { return chunkSZDU2D3D_cjs.registerExtensions; }
|
|
3567
3881
|
});
|
|
3568
3882
|
Object.defineProperty(exports, "rsiTv", {
|
|
3569
3883
|
enumerable: true,
|
|
3570
|
-
get: function () { return
|
|
3884
|
+
get: function () { return chunkSZDU2D3D_cjs.rsiTv_default; }
|
|
3571
3885
|
});
|
|
3572
3886
|
Object.defineProperty(exports, "shortPosition", {
|
|
3573
3887
|
enumerable: true,
|
|
3574
|
-
get: function () { return
|
|
3888
|
+
get: function () { return chunkSZDU2D3D_cjs.shortPosition_default; }
|
|
3575
3889
|
});
|
|
3576
3890
|
Object.defineProperty(exports, "stochastic", {
|
|
3577
3891
|
enumerable: true,
|
|
3578
|
-
get: function () { return
|
|
3892
|
+
get: function () { return chunkSZDU2D3D_cjs.stochastic_default; }
|
|
3579
3893
|
});
|
|
3580
3894
|
Object.defineProperty(exports, "superTrend", {
|
|
3581
3895
|
enumerable: true,
|
|
3582
|
-
get: function () { return
|
|
3896
|
+
get: function () { return chunkSZDU2D3D_cjs.superTrend_default; }
|
|
3583
3897
|
});
|
|
3584
3898
|
Object.defineProperty(exports, "threeWaves", {
|
|
3585
3899
|
enumerable: true,
|
|
3586
|
-
get: function () { return
|
|
3900
|
+
get: function () { return chunkSZDU2D3D_cjs.threeWaves_default; }
|
|
3587
3901
|
});
|
|
3588
3902
|
Object.defineProperty(exports, "triangle", {
|
|
3589
3903
|
enumerable: true,
|
|
3590
|
-
get: function () { return
|
|
3904
|
+
get: function () { return chunkSZDU2D3D_cjs.triangle_default; }
|
|
3591
3905
|
});
|
|
3592
3906
|
Object.defineProperty(exports, "vwap", {
|
|
3593
3907
|
enumerable: true,
|
|
3594
|
-
get: function () { return
|
|
3908
|
+
get: function () { return chunkSZDU2D3D_cjs.vwap_default; }
|
|
3595
3909
|
});
|
|
3596
3910
|
Object.defineProperty(exports, "xabcd", {
|
|
3597
3911
|
enumerable: true,
|
|
3598
|
-
get: function () { return
|
|
3912
|
+
get: function () { return chunkSZDU2D3D_cjs.xabcd_default; }
|
|
3913
|
+
});
|
|
3914
|
+
Object.defineProperty(exports, "KlinechartsUIDispatchContext", {
|
|
3915
|
+
enumerable: true,
|
|
3916
|
+
get: function () { return chunkF24D6PWY_cjs.KlinechartsUIDispatchContext; }
|
|
3917
|
+
});
|
|
3918
|
+
Object.defineProperty(exports, "KlinechartsUIStateContext", {
|
|
3919
|
+
enumerable: true,
|
|
3920
|
+
get: function () { return chunkF24D6PWY_cjs.KlinechartsUIStateContext; }
|
|
3921
|
+
});
|
|
3922
|
+
Object.defineProperty(exports, "createDataLoader", {
|
|
3923
|
+
enumerable: true,
|
|
3924
|
+
get: function () { return chunkF24D6PWY_cjs.createDataLoader; }
|
|
3925
|
+
});
|
|
3926
|
+
Object.defineProperty(exports, "useKlinechartsUI", {
|
|
3927
|
+
enumerable: true,
|
|
3928
|
+
get: function () { return chunkF24D6PWY_cjs.useKlinechartsUI; }
|
|
3599
3929
|
});
|
|
3600
3930
|
exports.CANDLE_TYPES = CANDLE_TYPES;
|
|
3601
3931
|
exports.COMPARE_RULES = COMPARE_RULES;
|
|
3602
3932
|
exports.DEFAULT_PERIODS = DEFAULT_PERIODS;
|
|
3933
|
+
exports.DEFAULT_STORAGE_KEY_PREFIX = DEFAULT_STORAGE_KEY_PREFIX;
|
|
3934
|
+
exports.DEFAULT_STORAGE_NAMESPACES = DEFAULT_STORAGE_NAMESPACES;
|
|
3935
|
+
exports.DEFAULT_SYNC_CONFIG = DEFAULT_SYNC_CONFIG;
|
|
3603
3936
|
exports.DRAWING_CATEGORIES = DRAWING_CATEGORIES;
|
|
3604
3937
|
exports.INDICATOR_PARAMS = INDICATOR_PARAMS;
|
|
3605
|
-
exports.KlinechartsUIDispatchContext = KlinechartsUIDispatchContext;
|
|
3606
3938
|
exports.KlinechartsUIProvider = KlinechartsUIProvider;
|
|
3607
|
-
exports.KlinechartsUIStateContext = KlinechartsUIStateContext;
|
|
3608
3939
|
exports.MAIN_INDICATORS = MAIN_INDICATORS;
|
|
3609
3940
|
exports.PRICE_AXIS_TYPES = PRICE_AXIS_TYPES;
|
|
3610
3941
|
exports.SUB_INDICATORS = SUB_INDICATORS;
|
|
3611
3942
|
exports.TIMEZONES = TIMEZONES;
|
|
3612
3943
|
exports.TOOLTIP_SHOW_RULES = TOOLTIP_SHOW_RULES;
|
|
3944
|
+
exports.WorkspaceProvider = WorkspaceProvider;
|
|
3613
3945
|
exports.YAXIS_POSITIONS = YAXIS_POSITIONS;
|
|
3614
|
-
exports.
|
|
3946
|
+
exports.createDefaultStorage = createDefaultStorage;
|
|
3947
|
+
exports.resolveStorage = resolveStorage;
|
|
3615
3948
|
exports.useAlerts = useAlerts;
|
|
3616
3949
|
exports.useAnnotations = useAnnotations;
|
|
3617
3950
|
exports.useChartAxes = useChartAxes;
|
|
3951
|
+
exports.useChartSync = useChartSync;
|
|
3618
3952
|
exports.useCompare = useCompare;
|
|
3619
3953
|
exports.useCrosshair = useCrosshair;
|
|
3620
3954
|
exports.useDataExport = useDataExport;
|
|
@@ -3622,7 +3956,6 @@ exports.useDrawingTools = useDrawingTools;
|
|
|
3622
3956
|
exports.useFullscreen = useFullscreen;
|
|
3623
3957
|
exports.useHotkeys = useHotkeys;
|
|
3624
3958
|
exports.useIndicators = useIndicators;
|
|
3625
|
-
exports.useKlinechartsUI = useKlinechartsUI;
|
|
3626
3959
|
exports.useKlinechartsUILoading = useKlinechartsUILoading;
|
|
3627
3960
|
exports.useKlinechartsUISettings = useKlinechartsUISettings;
|
|
3628
3961
|
exports.useKlinechartsUITheme = useKlinechartsUITheme;
|
|
@@ -3637,5 +3970,6 @@ exports.useSymbolSearch = useSymbolSearch;
|
|
|
3637
3970
|
exports.useTimezone = useTimezone;
|
|
3638
3971
|
exports.useUndoRedo = useUndoRedo;
|
|
3639
3972
|
exports.useWatchlist = useWatchlist;
|
|
3973
|
+
exports.useWorkspace = useWorkspace;
|
|
3640
3974
|
//# sourceMappingURL=index.cjs.map
|
|
3641
3975
|
//# sourceMappingURL=index.cjs.map
|