velo-plot 1.12.0 → 1.19.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 +14 -0
- package/dist/{index.core-xiNcuFfJ.js → ChartCore-DQ691eXH.js} +1807 -1287
- package/dist/ChartCore-DQ691eXH.js.map +1 -0
- package/dist/assets/downsample.worker-C70QJ04y.js +2 -0
- package/dist/assets/downsample.worker-C70QJ04y.js.map +1 -0
- package/dist/assets/indicator.worker-bv0zC4EX.js +2 -0
- package/dist/assets/indicator.worker-bv0zC4EX.js.map +1 -0
- package/dist/core/OverlayRenderer.d.ts +2 -0
- package/dist/core/chart/ChartAlerts.d.ts +42 -0
- package/dist/core/chart/ChartCore.d.ts +20 -1
- package/dist/core/chart/ChartRenderLoop.d.ts +4 -2
- package/dist/core/chart/ChartRenderer.d.ts +3 -2
- package/dist/core/chart/candlestickMarkers.d.ts +23 -0
- package/dist/core/chart/exporter/SVGExporter.d.ts +7 -2
- package/dist/core/chart/heikinAshi.d.ts +10 -0
- package/dist/core/chart/series/types.d.ts +2 -2
- package/dist/core/chart/types.d.ts +9 -0
- package/dist/core/indicator/addIndicator.d.ts +36 -0
- package/dist/core/indicator/index.d.ts +2 -0
- package/dist/core/indicator/indicatorPresets.d.ts +37 -0
- package/dist/core/render/pixelSnap.d.ts +8 -0
- package/dist/core/series/Series.d.ts +3 -0
- package/dist/core/stacked/index.d.ts +3 -1
- package/dist/core/stacked/paneResize.d.ts +15 -18
- package/dist/core/stacked/stackExport.d.ts +18 -0
- package/dist/core/stacked/types.d.ts +42 -5
- package/dist/core/time/TimeScale.d.ts +31 -0
- package/dist/createStackedChart-BPooTQ9z.js +1164 -0
- package/dist/createStackedChart-BPooTQ9z.js.map +1 -0
- package/dist/gpu/adapter/gpuRenderer.d.ts +21 -0
- package/dist/gpu/backends/webgpu/WebGPUBackend.d.ts +2 -1
- package/dist/gpuRenderer-BpaMYz-k.js +1848 -0
- package/dist/gpuRenderer-BpaMYz-k.js.map +1 -0
- package/dist/index-CUGS98p4.js +277 -0
- package/dist/index-CUGS98p4.js.map +1 -0
- package/dist/index-D7dTq6VB.js +503 -0
- package/dist/index-D7dTq6VB.js.map +1 -0
- package/dist/{index-Ce2JgkH_.js → index-DoYxf1cV.js} +86 -43
- package/dist/{index-Ce2JgkH_.js.map → index-DoYxf1cV.js.map} +1 -1
- package/dist/index.core-BtGFYMOu.js +167 -0
- package/dist/index.core-BtGFYMOu.js.map +1 -0
- package/dist/index.d.ts +12 -4
- package/dist/indicators--eJGmVox.js +302 -0
- package/dist/indicators--eJGmVox.js.map +1 -0
- package/dist/math-Ddm2EZjj.js +85 -0
- package/dist/math-Ddm2EZjj.js.map +1 -0
- package/dist/plugins/analysis.js +543 -818
- package/dist/plugins/analysis.js.map +1 -1
- package/dist/plugins/anomaly-detection.d.ts +1 -0
- package/dist/plugins/anomaly-detection.js +221 -0
- package/dist/plugins/anomaly-detection.js.map +1 -0
- package/dist/plugins/broken-axis.d.ts +3 -0
- package/dist/plugins/broken-axis.js +262 -0
- package/dist/plugins/broken-axis.js.map +1 -0
- package/dist/plugins/caching.d.ts +3 -0
- package/dist/plugins/caching.js +187 -0
- package/dist/plugins/caching.js.map +1 -0
- package/dist/plugins/data-transform.d.ts +3 -0
- package/dist/plugins/data-transform.js +146 -0
- package/dist/plugins/data-transform.js.map +1 -0
- package/dist/plugins/debug.js +12 -11
- package/dist/plugins/debug.js.map +1 -1
- package/dist/plugins/drawing-tools/index.d.ts +16 -0
- package/dist/plugins/forecasting.d.ts +1 -0
- package/dist/plugins/forecasting.js +236 -0
- package/dist/plugins/forecasting.js.map +1 -0
- package/dist/plugins/gpu.js +202 -1895
- package/dist/plugins/gpu.js.map +1 -1
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/keyboard/index.d.ts +1 -7
- package/dist/plugins/keyboard.js +1 -1
- package/dist/plugins/latex.d.ts +1 -0
- package/dist/plugins/latex.js +454 -0
- package/dist/plugins/latex.js.map +1 -0
- package/dist/plugins/lazy-load/types.d.ts +7 -0
- package/dist/plugins/lazy-load.d.ts +3 -0
- package/dist/plugins/lazy-load.js +212 -0
- package/dist/plugins/lazy-load.js.map +1 -0
- package/dist/plugins/ml-integration.d.ts +3 -0
- package/dist/plugins/ml-integration.js +355 -0
- package/dist/plugins/ml-integration.js.map +1 -0
- package/dist/plugins/offscreen.d.ts +3 -0
- package/dist/plugins/offscreen.js +169 -0
- package/dist/plugins/offscreen.js.map +1 -0
- package/dist/plugins/pattern-recognition.d.ts +3 -0
- package/dist/plugins/pattern-recognition.js +690 -0
- package/dist/plugins/pattern-recognition.js.map +1 -0
- package/dist/plugins/radar.d.ts +3 -0
- package/dist/plugins/radar.js +103 -0
- package/dist/plugins/radar.js.map +1 -0
- package/dist/plugins/regression.d.ts +3 -0
- package/dist/plugins/regression.js +634 -0
- package/dist/plugins/regression.js.map +1 -0
- package/dist/plugins/replay/index.d.ts +19 -0
- package/dist/plugins/roi.d.ts +1 -0
- package/dist/plugins/roi.js +223 -0
- package/dist/plugins/roi.js.map +1 -0
- package/dist/plugins/snapshot/types.d.ts +1 -1
- package/dist/plugins/snapshot.d.ts +3 -0
- package/dist/plugins/snapshot.js +90 -0
- package/dist/plugins/snapshot.js.map +1 -0
- package/dist/plugins/sync/index.d.ts +2 -1
- package/dist/plugins/sync.js +13 -269
- package/dist/plugins/sync.js.map +1 -1
- package/dist/plugins/video-recorder.d.ts +3 -0
- package/dist/plugins/video-recorder.js +104 -0
- package/dist/plugins/video-recorder.js.map +1 -0
- package/dist/plugins/virtualization/types.d.ts +12 -0
- package/dist/plugins/virtualization.d.ts +3 -0
- package/dist/plugins/virtualization.js +6 -0
- package/dist/plugins/virtualization.js.map +1 -0
- package/dist/pool-15HMCNv8.js +88 -0
- package/dist/pool-15HMCNv8.js.map +1 -0
- package/dist/react.d.ts +1 -0
- package/dist/react.js +31 -0
- package/dist/react.js.map +1 -0
- package/dist/renderer/CandlestickRenderer.d.ts +1 -1
- package/dist/renderer/ChartSeriesRenderer.d.ts +6 -0
- package/dist/renderer/GpuChartRenderer.d.ts +23 -0
- package/dist/renderer/index.d.ts +3 -0
- package/dist/renderer/spike/WebGLGridSpike.d.ts +40 -0
- package/dist/testing/baselines/v1.15.0.json.d.ts +51 -0
- package/dist/testing/gridSpikeBenchmark.d.ts +49 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/rendererBenchmark.d.ts +13 -0
- package/dist/testing/stage1BrowserBench.d.ts +42 -0
- package/dist/types.d.ts +21 -1
- package/dist/utils-BK5UUXxj.js +172 -0
- package/dist/utils-BK5UUXxj.js.map +1 -0
- package/dist/velo-plot.full.js +1382 -5932
- package/dist/velo-plot.full.js.map +1 -1
- package/dist/velo-plot.js +26 -25
- package/dist/velo-plot.js.map +1 -1
- package/dist/workers/downsample.d.ts +38 -0
- package/dist/workers/downsampleAsync.d.ts +6 -0
- package/dist/workers/indicator.worker.d.ts +32 -0
- package/dist/workers/indicatorsAsync.d.ts +26 -0
- package/dist/workers/pool.d.ts +36 -0
- package/package.json +19 -2
- package/dist/core/OverlayRenderer.test.d.ts +0 -1
- package/dist/core/chart/ChartScaling.test.d.ts +0 -1
- package/dist/core/chart/NavigationUtils.test.d.ts +0 -1
- package/dist/core/format/axisFormat.test.d.ts +0 -1
- package/dist/core/indicator/buildIndicatorSeries.test.d.ts +0 -1
- package/dist/core/series/SeriesBounds.test.d.ts +0 -1
- package/dist/core/stacked/createStackedChart.test.d.ts +0 -1
- package/dist/core/stacked/paneAxis.test.d.ts +0 -1
- package/dist/core/stacked/paneResize.test.d.ts +0 -1
- package/dist/core/sync/index.test.d.ts +0 -1
- package/dist/index.core-xiNcuFfJ.js.map +0 -1
- package/dist/plugins/tools/tooltip/format.test.d.ts +0 -1
- package/dist/utils-Dbro9-qM.js +0 -254
- package/dist/utils-Dbro9-qM.js.map +0 -1
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
const D = {
|
|
2
|
+
name: "velo-plot-lazy-load",
|
|
3
|
+
version: "1.0.0",
|
|
4
|
+
description: "Lazy loading for large datasets with viewport-based chunking",
|
|
5
|
+
provides: ["lazy-load", "data-streaming"],
|
|
6
|
+
tags: ["performance", "data", "optimization"]
|
|
7
|
+
}, T = {
|
|
8
|
+
enabled: !0,
|
|
9
|
+
chunkSize: 1e4,
|
|
10
|
+
viewportBuffer: 2,
|
|
11
|
+
autoLoad: !0,
|
|
12
|
+
autoUnload: !0,
|
|
13
|
+
unloadThreshold: 5,
|
|
14
|
+
preloadAdjacent: !0,
|
|
15
|
+
maxLoadedChunks: 100,
|
|
16
|
+
onLoadStart: () => {
|
|
17
|
+
},
|
|
18
|
+
onLoadProgress: () => {
|
|
19
|
+
},
|
|
20
|
+
onLoadComplete: () => {
|
|
21
|
+
},
|
|
22
|
+
onLoadError: () => {
|
|
23
|
+
},
|
|
24
|
+
debug: !1
|
|
25
|
+
};
|
|
26
|
+
function B(w = {}) {
|
|
27
|
+
const a = { ...T, ...w };
|
|
28
|
+
let l = null;
|
|
29
|
+
const h = /* @__PURE__ */ new Map();
|
|
30
|
+
function L(t) {
|
|
31
|
+
return Math.floor(t / a.chunkSize);
|
|
32
|
+
}
|
|
33
|
+
function m() {
|
|
34
|
+
if (!l) return null;
|
|
35
|
+
const t = l.data.getViewBounds();
|
|
36
|
+
return t ? { xMin: t.xMin, xMax: t.xMax } : null;
|
|
37
|
+
}
|
|
38
|
+
async function M(t, n) {
|
|
39
|
+
if (!(t.chunks.has(n) || t.loading.has(n))) {
|
|
40
|
+
t.loading.add(n);
|
|
41
|
+
try {
|
|
42
|
+
const o = n * a.chunkSize, r = Math.min(
|
|
43
|
+
o + a.chunkSize,
|
|
44
|
+
t.totalPoints
|
|
45
|
+
);
|
|
46
|
+
a.debug && console.log(`[LazyLoad] Loading chunk ${n} for ${t.id} (${o}-${r})`);
|
|
47
|
+
const e = await t.provider.loadChunk(o, r);
|
|
48
|
+
t.chunks.set(n, e), t.loading.delete(n), await z(t);
|
|
49
|
+
const s = Array.from(t.chunks.values()).reduce(
|
|
50
|
+
(c, f) => c + (f.endIndex - f.startIndex),
|
|
51
|
+
0
|
|
52
|
+
), i = Math.ceil(t.totalPoints / a.chunkSize), u = {
|
|
53
|
+
seriesId: t.id,
|
|
54
|
+
loadedPoints: s,
|
|
55
|
+
totalPoints: t.totalPoints,
|
|
56
|
+
progress: s / t.totalPoints,
|
|
57
|
+
currentChunk: n,
|
|
58
|
+
totalChunks: i
|
|
59
|
+
};
|
|
60
|
+
s === t.totalPoints ? a.onLoadComplete(u) : a.onLoadProgress(u);
|
|
61
|
+
} catch (o) {
|
|
62
|
+
t.loading.delete(n), a.onLoadError(o, t.id), a.debug && console.error(`[LazyLoad] Error loading chunk ${n}:`, o);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function z(t) {
|
|
67
|
+
var i, u;
|
|
68
|
+
if (!l) return;
|
|
69
|
+
const n = Array.from(t.chunks.entries()).sort((c, f) => c[0] - f[0]);
|
|
70
|
+
if (n.length === 0) return;
|
|
71
|
+
let o = 0;
|
|
72
|
+
for (const [, c] of n)
|
|
73
|
+
o += c.x.length;
|
|
74
|
+
const r = new Float32Array(o), e = new Float32Array(o);
|
|
75
|
+
let s = 0;
|
|
76
|
+
for (const [, c] of n)
|
|
77
|
+
r.set(c.x, s), e.set(c.y, s), s += c.x.length;
|
|
78
|
+
(u = (i = l.chart).updateSeries) == null || u.call(i, t.id, { x: r, y: e });
|
|
79
|
+
}
|
|
80
|
+
async function g() {
|
|
81
|
+
if (!a.enabled || !l) return;
|
|
82
|
+
const t = m();
|
|
83
|
+
if (!t) return;
|
|
84
|
+
const n = a.viewportBuffer, o = t.xMax - t.xMin, r = {
|
|
85
|
+
xMin: t.xMin - o * n,
|
|
86
|
+
xMax: t.xMax + o * n
|
|
87
|
+
};
|
|
88
|
+
for (const [, e] of h) {
|
|
89
|
+
const s = [], i = Math.ceil(e.totalPoints / a.chunkSize), u = Math.max(0, Math.floor(r.xMin / a.chunkSize)), c = Math.min(i - 1, Math.floor(r.xMax / a.chunkSize));
|
|
90
|
+
for (let d = u; d <= c; d++)
|
|
91
|
+
!e.chunks.has(d) && !e.loading.has(d) && s.push(d);
|
|
92
|
+
const f = Math.min(s.length, 10);
|
|
93
|
+
for (let d = 0; d < f; d++)
|
|
94
|
+
await M(e, s[d]);
|
|
95
|
+
if (a.preloadAdjacent && c + 1 < i) {
|
|
96
|
+
const d = c + 1;
|
|
97
|
+
!e.chunks.has(d) && !e.loading.has(d) && M(e, d);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function b(t, n) {
|
|
102
|
+
const o = a.viewportBuffer, r = n.xMax - n.xMin, e = {
|
|
103
|
+
xMin: n.xMin - r * o,
|
|
104
|
+
xMax: n.xMax + r * o
|
|
105
|
+
}, s = Math.ceil(t.totalPoints / a.chunkSize), i = Math.max(0, Math.floor(e.xMin / a.chunkSize)), u = Math.min(s - 1, Math.floor(e.xMax / a.chunkSize));
|
|
106
|
+
return { startChunk: i, endChunk: u };
|
|
107
|
+
}
|
|
108
|
+
function x() {
|
|
109
|
+
if (!a.autoUnload || !l) return 0;
|
|
110
|
+
const t = m();
|
|
111
|
+
if (!t) return 0;
|
|
112
|
+
let n = 0;
|
|
113
|
+
for (const [, o] of h) {
|
|
114
|
+
let r = 0;
|
|
115
|
+
const { startChunk: e, endChunk: s } = b(o, t), i = Math.max(1, s - e + 1), u = Math.ceil(a.unloadThreshold * i), c = Math.max(0, e - u), f = s + u;
|
|
116
|
+
for (const d of Array.from(o.chunks.keys()))
|
|
117
|
+
(d < c || d > f) && (o.chunks.delete(d), r++);
|
|
118
|
+
if (o.chunks.size > a.maxLoadedChunks) {
|
|
119
|
+
const d = Array.from(o.chunks.entries()).sort(
|
|
120
|
+
(k, $) => k[1].loadedAt - $[1].loadedAt
|
|
121
|
+
), U = o.chunks.size - a.maxLoadedChunks;
|
|
122
|
+
for (let k = 0; k < U; k++)
|
|
123
|
+
o.chunks.delete(d[k][0]), r++;
|
|
124
|
+
}
|
|
125
|
+
r > 0 && (z(o), n += r);
|
|
126
|
+
}
|
|
127
|
+
return a.debug && n > 0 && console.log(`[LazyLoad] Unloaded ${n} chunks`), n;
|
|
128
|
+
}
|
|
129
|
+
function P(t, n) {
|
|
130
|
+
const o = n.getTotalCount();
|
|
131
|
+
h.set(t, {
|
|
132
|
+
id: t,
|
|
133
|
+
provider: n,
|
|
134
|
+
chunks: /* @__PURE__ */ new Map(),
|
|
135
|
+
loading: /* @__PURE__ */ new Set(),
|
|
136
|
+
totalPoints: o
|
|
137
|
+
}), a.debug && console.log(`[LazyLoad] Registered series ${t} with ${o} points`), a.onLoadStart({
|
|
138
|
+
seriesId: t,
|
|
139
|
+
loadedPoints: 0,
|
|
140
|
+
totalPoints: o,
|
|
141
|
+
progress: 0,
|
|
142
|
+
currentChunk: 0,
|
|
143
|
+
totalChunks: Math.ceil(o / a.chunkSize)
|
|
144
|
+
}), a.autoLoad && g();
|
|
145
|
+
}
|
|
146
|
+
function v(t) {
|
|
147
|
+
h.delete(t), a.debug && console.log(`[LazyLoad] Unregistered series ${t}`);
|
|
148
|
+
}
|
|
149
|
+
async function C(t, n, o) {
|
|
150
|
+
const r = h.get(t);
|
|
151
|
+
if (!r) return;
|
|
152
|
+
const e = L(n), s = L(o);
|
|
153
|
+
for (let i = e; i <= s; i++)
|
|
154
|
+
await M(r, i);
|
|
155
|
+
}
|
|
156
|
+
function A(t) {
|
|
157
|
+
const n = h.get(t);
|
|
158
|
+
return n ? {
|
|
159
|
+
loadedPoints: Array.from(n.chunks.values()).reduce(
|
|
160
|
+
(r, e) => r + (e.endIndex - e.startIndex),
|
|
161
|
+
0
|
|
162
|
+
),
|
|
163
|
+
totalPoints: n.totalPoints,
|
|
164
|
+
loadedChunks: n.chunks.size,
|
|
165
|
+
totalChunks: Math.ceil(n.totalPoints / a.chunkSize)
|
|
166
|
+
} : null;
|
|
167
|
+
}
|
|
168
|
+
function y() {
|
|
169
|
+
for (const [, t] of h)
|
|
170
|
+
t.chunks.clear(), t.loading.clear();
|
|
171
|
+
}
|
|
172
|
+
async function p(t) {
|
|
173
|
+
if (!l || !a.enabled) return;
|
|
174
|
+
const n = t.buffer ?? a.viewportBuffer, o = t.to - t.from, r = Math.max(0, Math.floor(t.from - o * n)), e = Math.ceil(t.to + o * n), s = t.seriesId ? [[t.seriesId, h.get(t.seriesId)]] : Array.from(h.entries()).map(([i, u]) => [i, u]);
|
|
175
|
+
for (const [i, u] of s)
|
|
176
|
+
u && await C(i, r, e);
|
|
177
|
+
a.autoUnload && x();
|
|
178
|
+
}
|
|
179
|
+
const S = {
|
|
180
|
+
registerSeries: P,
|
|
181
|
+
unregisterSeries: v,
|
|
182
|
+
loadRange: C,
|
|
183
|
+
loadVisible: g,
|
|
184
|
+
unloadDistant: x,
|
|
185
|
+
setDataWindow: p,
|
|
186
|
+
getLoadingStatus: A,
|
|
187
|
+
clear: y,
|
|
188
|
+
updateConfig(t) {
|
|
189
|
+
Object.assign(a, t);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
return {
|
|
193
|
+
manifest: D,
|
|
194
|
+
onInit(t) {
|
|
195
|
+
var n, o, r, e;
|
|
196
|
+
l = t, l.chart.lazyLoad = S, l.chart.setDataWindow = (s) => p(s), a.autoLoad && ((o = (n = l.chart).on) == null || o.call(n, "zoom", () => {
|
|
197
|
+
g(), a.autoUnload && x();
|
|
198
|
+
}), (e = (r = l.chart).on) == null || e.call(r, "pan", () => {
|
|
199
|
+
g(), a.autoUnload && x();
|
|
200
|
+
}));
|
|
201
|
+
},
|
|
202
|
+
onDestroy(t) {
|
|
203
|
+
y(), delete t.chart.lazyLoad, delete t.chart.setDataWindow, l = null;
|
|
204
|
+
},
|
|
205
|
+
api: S
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
export {
|
|
209
|
+
B as PluginLazyLoad,
|
|
210
|
+
B as default
|
|
211
|
+
};
|
|
212
|
+
//# sourceMappingURL=lazy-load.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lazy-load.js","sources":["../../src/plugins/lazy-load/index.ts"],"sourcesContent":["/**\n * @fileoverview Lazy loading plugin for large datasets\n * @module plugins/lazy-load\n */\n\nimport type {\n PluginLazyLoadConfig,\n LazyLoadAPI,\n DataProvider,\n LazyLoadedSeries,\n LoadProgressEvent,\n} from './types';\nimport type {\n ChartPlugin,\n PluginContext,\n PluginManifest,\n} from '../types';\n\nconst manifest: PluginManifest = {\n name: 'velo-plot-lazy-load',\n version: '1.0.0',\n description: 'Lazy loading for large datasets with viewport-based chunking',\n provides: ['lazy-load', 'data-streaming'],\n tags: ['performance', 'data', 'optimization'],\n};\n\nconst DEFAULT_CONFIG: Required<PluginLazyLoadConfig> = {\n enabled: true,\n chunkSize: 10000,\n viewportBuffer: 2,\n autoLoad: true,\n autoUnload: true,\n unloadThreshold: 5,\n preloadAdjacent: true,\n maxLoadedChunks: 100,\n onLoadStart: () => {},\n onLoadProgress: () => {},\n onLoadComplete: () => {},\n onLoadError: () => {},\n debug: false,\n};\n\nexport function PluginLazyLoad(\n userConfig: Partial<PluginLazyLoadConfig> = {}\n): ChartPlugin<PluginLazyLoadConfig> {\n const config = { ...DEFAULT_CONFIG, ...userConfig };\n let ctx: PluginContext | null = null;\n\n // Registered series\n const series = new Map<string, LazyLoadedSeries>();\n\n /**\n * Calculate chunk index from point index\n */\n function getChunkIndex(pointIndex: number): number {\n return Math.floor(pointIndex / config.chunkSize);\n }\n\n /**\n * Get visible range from chart\n */\n function getVisibleRange(): { xMin: number; xMax: number } | null {\n if (!ctx) return null;\n \n // Get current view bounds from data context\n const bounds = ctx.data.getViewBounds();\n if (bounds) {\n return { xMin: bounds.xMin, xMax: bounds.xMax };\n }\n \n return null;\n }\n\n /**\n * Load a specific chunk\n */\n async function loadChunk(\n seriesInfo: LazyLoadedSeries,\n chunkIndex: number\n ): Promise<void> {\n // Already loaded or loading\n if (seriesInfo.chunks.has(chunkIndex) || seriesInfo.loading.has(chunkIndex)) {\n return;\n }\n\n seriesInfo.loading.add(chunkIndex);\n\n try {\n const startIndex = chunkIndex * config.chunkSize;\n const endIndex = Math.min(\n startIndex + config.chunkSize,\n seriesInfo.totalPoints\n );\n\n if (config.debug) {\n console.log(`[LazyLoad] Loading chunk ${chunkIndex} for ${seriesInfo.id} (${startIndex}-${endIndex})`);\n }\n\n const chunk = await seriesInfo.provider.loadChunk(startIndex, endIndex);\n \n seriesInfo.chunks.set(chunkIndex, chunk);\n seriesInfo.loading.delete(chunkIndex);\n\n // Update chart data\n await updateSeriesData(seriesInfo);\n\n // Fire progress event\n const loadedPoints = Array.from(seriesInfo.chunks.values()).reduce(\n (sum, c) => sum + (c.endIndex - c.startIndex),\n 0\n );\n\n const totalChunks = Math.ceil(seriesInfo.totalPoints / config.chunkSize);\n \n const event: LoadProgressEvent = {\n seriesId: seriesInfo.id,\n loadedPoints,\n totalPoints: seriesInfo.totalPoints,\n progress: loadedPoints / seriesInfo.totalPoints,\n currentChunk: chunkIndex,\n totalChunks,\n };\n\n if (loadedPoints === seriesInfo.totalPoints) {\n config.onLoadComplete(event);\n } else {\n config.onLoadProgress(event);\n }\n\n } catch (error) {\n seriesInfo.loading.delete(chunkIndex);\n config.onLoadError(error as Error, seriesInfo.id);\n \n if (config.debug) {\n console.error(`[LazyLoad] Error loading chunk ${chunkIndex}:`, error);\n }\n }\n }\n\n /**\n * Update series data from loaded chunks\n */\n async function updateSeriesData(seriesInfo: LazyLoadedSeries): Promise<void> {\n if (!ctx) return;\n\n // Merge all loaded chunks\n const sortedChunks = Array.from(seriesInfo.chunks.entries()).sort((a, b) => a[0] - b[0]);\n \n if (sortedChunks.length === 0) return;\n\n // Calculate total size\n let totalSize = 0;\n for (const [, chunk] of sortedChunks) {\n totalSize += chunk.x.length;\n }\n\n // Allocate arrays\n const x = new Float32Array(totalSize);\n const y = new Float32Array(totalSize);\n\n // Copy data\n let offset = 0;\n for (const [, chunk] of sortedChunks) {\n x.set(chunk.x, offset);\n y.set(chunk.y, offset);\n offset += chunk.x.length;\n }\n\n // Update series\n (ctx.chart as any).updateSeries?.(seriesInfo.id, { x, y });\n }\n\n /**\n * Load visible data\n */\n async function loadVisible(): Promise<void> {\n if (!config.enabled || !ctx) return;\n\n const visibleRange = getVisibleRange();\n if (!visibleRange) return;\n\n const buffer = config.viewportBuffer;\n const rangeWidth = visibleRange.xMax - visibleRange.xMin;\n const buffered = {\n xMin: visibleRange.xMin - rangeWidth * buffer,\n xMax: visibleRange.xMax + rangeWidth * buffer,\n };\n\n for (const [, seriesInfo] of series) {\n const chunksToLoad: number[] = [];\n const totalChunks = Math.ceil(seriesInfo.totalPoints / config.chunkSize);\n\n // Identify chunks within the buffered viewport\n const startIdx = Math.max(0, Math.floor(buffered.xMin / config.chunkSize));\n const endIdx = Math.min(totalChunks - 1, Math.floor(buffered.xMax / config.chunkSize));\n\n for (let i = startIdx; i <= endIdx; i++) {\n if (!seriesInfo.chunks.has(i) && !seriesInfo.loading.has(i)) {\n chunksToLoad.push(i);\n }\n }\n\n // Load chunks sequentially (limit to avoid flood)\n const maxToLoad = Math.min(chunksToLoad.length, 10);\n for (let i = 0; i < maxToLoad; i++) {\n await loadChunk(seriesInfo, chunksToLoad[i]);\n }\n\n // Preload next adjacent chunk if enabled\n if (config.preloadAdjacent && endIdx + 1 < totalChunks) {\n const nextChunk = endIdx + 1;\n if (!seriesInfo.chunks.has(nextChunk) && !seriesInfo.loading.has(nextChunk)) {\n loadChunk(seriesInfo, nextChunk); // Fire and forget\n }\n }\n }\n }\n\n /**\n * Chunk index range that should stay loaded for the current viewport.\n */\n function getKeepChunkRange(\n seriesInfo: LazyLoadedSeries,\n visibleRange: { xMin: number; xMax: number },\n ): { startChunk: number; endChunk: number } {\n const buffer = config.viewportBuffer;\n const rangeWidth = visibleRange.xMax - visibleRange.xMin;\n const buffered = {\n xMin: visibleRange.xMin - rangeWidth * buffer,\n xMax: visibleRange.xMax + rangeWidth * buffer,\n };\n const totalChunks = Math.ceil(seriesInfo.totalPoints / config.chunkSize);\n const startChunk = Math.max(0, Math.floor(buffered.xMin / config.chunkSize));\n const endChunk = Math.min(totalChunks - 1, Math.floor(buffered.xMax / config.chunkSize));\n return { startChunk, endChunk };\n }\n\n /**\n * Unload distant chunks\n */\n function unloadDistant(): number {\n if (!config.autoUnload || !ctx) return 0;\n\n const visibleRange = getVisibleRange();\n if (!visibleRange) return 0;\n\n let unloadedCount = 0;\n\n for (const [, seriesInfo] of series) {\n let seriesUnloaded = 0;\n const { startChunk, endChunk } = getKeepChunkRange(seriesInfo, visibleRange);\n const visibleSpan = Math.max(1, endChunk - startChunk + 1);\n const thresholdChunks = Math.ceil(config.unloadThreshold * visibleSpan);\n const keepStart = Math.max(0, startChunk - thresholdChunks);\n const keepEnd = endChunk + thresholdChunks;\n\n for (const chunkIndex of Array.from(seriesInfo.chunks.keys())) {\n if (chunkIndex < keepStart || chunkIndex > keepEnd) {\n seriesInfo.chunks.delete(chunkIndex);\n seriesUnloaded++;\n }\n }\n\n // Enforce max chunks limit (LRU eviction)\n if (seriesInfo.chunks.size > config.maxLoadedChunks) {\n const sortedChunks = Array.from(seriesInfo.chunks.entries()).sort(\n (a, b) => a[1].loadedAt - b[1].loadedAt,\n );\n\n const toRemove = seriesInfo.chunks.size - config.maxLoadedChunks;\n for (let i = 0; i < toRemove; i++) {\n seriesInfo.chunks.delete(sortedChunks[i][0]);\n seriesUnloaded++;\n }\n }\n\n if (seriesUnloaded > 0) {\n void updateSeriesData(seriesInfo);\n unloadedCount += seriesUnloaded;\n }\n }\n\n if (config.debug && unloadedCount > 0) {\n console.log(`[LazyLoad] Unloaded ${unloadedCount} chunks`);\n }\n\n return unloadedCount;\n }\n\n /**\n * Register a series\n */\n function registerSeries(seriesId: string, provider: DataProvider): void {\n const totalPoints = provider.getTotalCount();\n \n series.set(seriesId, {\n id: seriesId,\n provider,\n chunks: new Map(),\n loading: new Set(),\n totalPoints,\n });\n\n if (config.debug) {\n console.log(`[LazyLoad] Registered series ${seriesId} with ${totalPoints} points`);\n }\n\n // Fire load start event\n config.onLoadStart({\n seriesId,\n loadedPoints: 0,\n totalPoints,\n progress: 0,\n currentChunk: 0,\n totalChunks: Math.ceil(totalPoints / config.chunkSize),\n });\n\n // Auto-load if enabled\n if (config.autoLoad) {\n loadVisible();\n }\n }\n\n /**\n * Unregister a series\n */\n function unregisterSeries(seriesId: string): void {\n series.delete(seriesId);\n \n if (config.debug) {\n console.log(`[LazyLoad] Unregistered series ${seriesId}`);\n }\n }\n\n /**\n * Load specific range\n */\n async function loadRange(\n seriesId: string,\n startIndex: number,\n endIndex: number\n ): Promise<void> {\n const seriesInfo = series.get(seriesId);\n if (!seriesInfo) return;\n\n const startChunk = getChunkIndex(startIndex);\n const endChunk = getChunkIndex(endIndex);\n\n for (let i = startChunk; i <= endChunk; i++) {\n await loadChunk(seriesInfo, i);\n }\n }\n\n /**\n * Get loading status\n */\n function getLoadingStatus(seriesId: string) {\n const seriesInfo = series.get(seriesId);\n if (!seriesInfo) return null;\n\n const loadedPoints = Array.from(seriesInfo.chunks.values()).reduce(\n (sum, c) => sum + (c.endIndex - c.startIndex),\n 0\n );\n\n return {\n loadedPoints,\n totalPoints: seriesInfo.totalPoints,\n loadedChunks: seriesInfo.chunks.size,\n totalChunks: Math.ceil(seriesInfo.totalPoints / config.chunkSize),\n };\n }\n\n /**\n * Clear all data\n */\n function clear(): void {\n for (const [, seriesInfo] of series) {\n seriesInfo.chunks.clear();\n seriesInfo.loading.clear();\n }\n }\n\n /**\n * Load a data window with optional buffer (viewport-aware windowing API).\n */\n async function setDataWindow(opts: {\n from: number;\n to: number;\n buffer?: number;\n seriesId?: string;\n }): Promise<void> {\n if (!ctx || !config.enabled) return;\n\n const buffer = opts.buffer ?? config.viewportBuffer;\n const span = opts.to - opts.from;\n const startIndex = Math.max(0, Math.floor(opts.from - span * buffer));\n const endIndex = Math.ceil(opts.to + span * buffer);\n\n const targets = opts.seriesId\n ? [[opts.seriesId, series.get(opts.seriesId)] as const]\n : Array.from(series.entries()).map(([id, info]) => [id, info] as const);\n\n for (const [seriesId, seriesInfo] of targets) {\n if (!seriesInfo) continue;\n await loadRange(seriesId, startIndex, endIndex);\n }\n\n if (config.autoUnload) {\n unloadDistant();\n }\n }\n\n // API implementation\n const api: LazyLoadAPI & Record<string, unknown> = {\n registerSeries,\n unregisterSeries,\n loadRange,\n loadVisible,\n unloadDistant,\n setDataWindow,\n getLoadingStatus,\n clear,\n updateConfig(newConfig: Partial<PluginLazyLoadConfig>) {\n Object.assign(config, newConfig);\n },\n };\n\n return {\n manifest,\n\n onInit(pluginCtx: PluginContext) {\n ctx = pluginCtx;\n\n // Attach to chart API\n (ctx.chart as any).lazyLoad = api;\n (ctx.chart as any).setDataWindow = (opts: {\n from: number;\n to: number;\n buffer?: number;\n seriesId?: string;\n }) => setDataWindow(opts);\n\n // Listen for zoom/pan if auto-load enabled\n if (config.autoLoad) {\n ctx.chart.on?.('zoom', () => {\n loadVisible();\n if (config.autoUnload) {\n unloadDistant();\n }\n });\n\n ctx.chart.on?.('pan', () => {\n loadVisible();\n if (config.autoUnload) {\n unloadDistant();\n }\n });\n }\n },\n\n onDestroy(pluginCtx: PluginContext) {\n // Clear all data\n clear();\n\n // Remove from chart API\n delete (pluginCtx.chart as any).lazyLoad;\n delete (pluginCtx.chart as any).setDataWindow;\n\n ctx = null;\n },\n\n api,\n };\n}\n\nexport default PluginLazyLoad;\n\n// Type exports\nexport type {\n PluginLazyLoadConfig,\n LazyLoadAPI,\n DataProvider,\n DataChunk,\n LoadProgressEvent,\n} from './types';\n"],"names":["manifest","DEFAULT_CONFIG","PluginLazyLoad","userConfig","config","ctx","series","getChunkIndex","pointIndex","getVisibleRange","bounds","loadChunk","seriesInfo","chunkIndex","startIndex","endIndex","chunk","updateSeriesData","loadedPoints","sum","c","totalChunks","event","error","_a","_b","sortedChunks","a","b","totalSize","x","y","offset","loadVisible","visibleRange","buffer","rangeWidth","buffered","chunksToLoad","startIdx","endIdx","i","maxToLoad","nextChunk","getKeepChunkRange","startChunk","endChunk","unloadDistant","unloadedCount","seriesUnloaded","visibleSpan","thresholdChunks","keepStart","keepEnd","toRemove","registerSeries","seriesId","provider","totalPoints","unregisterSeries","loadRange","getLoadingStatus","clear","setDataWindow","opts","span","targets","id","info","api","newConfig","pluginCtx","_c","_d"],"mappings":"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"}
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
var A = Object.defineProperty;
|
|
2
|
+
var X = (i, t, n) => t in i ? A(i, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : i[t] = n;
|
|
3
|
+
var h = (i, t, n) => X(i, typeof t != "symbol" ? t + "" : t, n);
|
|
4
|
+
class b {
|
|
5
|
+
constructor(t) {
|
|
6
|
+
h(this, "network");
|
|
7
|
+
h(this, "config");
|
|
8
|
+
h(this, "ready", !1);
|
|
9
|
+
this.config = t, this.network = {
|
|
10
|
+
layers: [],
|
|
11
|
+
learningRate: 0.01,
|
|
12
|
+
epochs: 100
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
get id() {
|
|
16
|
+
return this.config.id;
|
|
17
|
+
}
|
|
18
|
+
get name() {
|
|
19
|
+
return this.config.name;
|
|
20
|
+
}
|
|
21
|
+
get type() {
|
|
22
|
+
return this.config.type;
|
|
23
|
+
}
|
|
24
|
+
async predict(t) {
|
|
25
|
+
const n = performance.now(), e = Array.from(t.data), r = this.forwardPass(e), o = performance.now() - n;
|
|
26
|
+
return {
|
|
27
|
+
modelId: this.config.id,
|
|
28
|
+
output: new Float32Array(r),
|
|
29
|
+
outputShape: [r.length],
|
|
30
|
+
timestamp: Date.now(),
|
|
31
|
+
processingTime: o
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
forwardPass(t) {
|
|
35
|
+
let n = t;
|
|
36
|
+
for (const e of this.network.layers)
|
|
37
|
+
e.type === "dense" && (n = this.denseLayer(n, e.weights, e.biases)), e.activation && (n = this.applyActivation(n, e.activation));
|
|
38
|
+
return n;
|
|
39
|
+
}
|
|
40
|
+
denseLayer(t, n, e) {
|
|
41
|
+
const r = [];
|
|
42
|
+
for (let o = 0; o < n.length; o++) {
|
|
43
|
+
let s = e[o];
|
|
44
|
+
for (let l = 0; l < t.length; l++)
|
|
45
|
+
s += t[l] * n[o][l];
|
|
46
|
+
r.push(s);
|
|
47
|
+
}
|
|
48
|
+
return r;
|
|
49
|
+
}
|
|
50
|
+
applyActivation(t, n) {
|
|
51
|
+
switch (n) {
|
|
52
|
+
case "relu":
|
|
53
|
+
return t.map((e) => Math.max(0, e));
|
|
54
|
+
case "sigmoid":
|
|
55
|
+
return t.map((e) => 1 / (1 + Math.exp(-e)));
|
|
56
|
+
case "tanh":
|
|
57
|
+
return t.map((e) => Math.tanh(e));
|
|
58
|
+
default:
|
|
59
|
+
return t;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
getInfo() {
|
|
63
|
+
return { ...this.config };
|
|
64
|
+
}
|
|
65
|
+
isReady() {
|
|
66
|
+
return this.ready;
|
|
67
|
+
}
|
|
68
|
+
async warmup() {
|
|
69
|
+
const t = new Array(10).fill(0.1);
|
|
70
|
+
await this.predict({ data: t }), this.ready = !0;
|
|
71
|
+
}
|
|
72
|
+
dispose() {
|
|
73
|
+
this.ready = !1;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
class R {
|
|
77
|
+
constructor(t) {
|
|
78
|
+
h(this, "config");
|
|
79
|
+
h(this, "coefficients", []);
|
|
80
|
+
h(this, "intercept", 0);
|
|
81
|
+
h(this, "ready", !1);
|
|
82
|
+
this.config = t;
|
|
83
|
+
}
|
|
84
|
+
get id() {
|
|
85
|
+
return this.config.id;
|
|
86
|
+
}
|
|
87
|
+
get name() {
|
|
88
|
+
return this.config.name;
|
|
89
|
+
}
|
|
90
|
+
get type() {
|
|
91
|
+
return this.config.type;
|
|
92
|
+
}
|
|
93
|
+
async predict(t) {
|
|
94
|
+
const n = performance.now(), r = Array.from(t.data).map((s) => {
|
|
95
|
+
let l = this.intercept;
|
|
96
|
+
for (let a = 0; a < this.coefficients.length && a < s; a++)
|
|
97
|
+
l += this.coefficients[a] * s;
|
|
98
|
+
return l;
|
|
99
|
+
}), o = performance.now() - n;
|
|
100
|
+
return {
|
|
101
|
+
modelId: this.config.id,
|
|
102
|
+
output: new Float32Array(r),
|
|
103
|
+
outputShape: [r.length],
|
|
104
|
+
timestamp: Date.now(),
|
|
105
|
+
processingTime: o
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
train(t) {
|
|
109
|
+
const n = t.x.length, e = [];
|
|
110
|
+
for (let a = 0; a < n; a++)
|
|
111
|
+
e.push([1, ...t.x[a]]);
|
|
112
|
+
const r = this.matrixMultiply(this.transpose(e), e), o = this.matrixMultiply(this.transpose(e), t.y.map((a) => [a])), s = this.matrixInverse(r), l = this.matrixMultiply(s, o);
|
|
113
|
+
this.intercept = l[0][0], this.coefficients = l.slice(1).map((a) => a[0]), this.ready = !0;
|
|
114
|
+
}
|
|
115
|
+
transpose(t) {
|
|
116
|
+
return t[0].map((n, e) => t.map((r) => r[e]));
|
|
117
|
+
}
|
|
118
|
+
matrixMultiply(t, n) {
|
|
119
|
+
const e = [];
|
|
120
|
+
for (let r = 0; r < t.length; r++) {
|
|
121
|
+
e[r] = [];
|
|
122
|
+
for (let o = 0; o < n[0].length; o++) {
|
|
123
|
+
let s = 0;
|
|
124
|
+
for (let l = 0; l < n.length; l++)
|
|
125
|
+
s += t[r][l] * n[l][o];
|
|
126
|
+
e[r][o] = s;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return e;
|
|
130
|
+
}
|
|
131
|
+
matrixInverse(t) {
|
|
132
|
+
if (t.length === 2 && t[0].length === 2) {
|
|
133
|
+
const n = t[0][0] * t[1][1] - t[0][1] * t[1][0];
|
|
134
|
+
if (Math.abs(n) < 1e-10)
|
|
135
|
+
return [[1, 0], [0, 1]];
|
|
136
|
+
const e = 1 / n;
|
|
137
|
+
return [
|
|
138
|
+
[e * t[1][1], -e * t[0][1]],
|
|
139
|
+
[-e * t[1][0], e * t[0][0]]
|
|
140
|
+
];
|
|
141
|
+
}
|
|
142
|
+
return t.map((n, e) => n.map((r, o) => e === o ? 1 : 0));
|
|
143
|
+
}
|
|
144
|
+
getInfo() {
|
|
145
|
+
return { ...this.config };
|
|
146
|
+
}
|
|
147
|
+
isReady() {
|
|
148
|
+
return this.ready;
|
|
149
|
+
}
|
|
150
|
+
async warmup() {
|
|
151
|
+
this.coefficients = [1], this.intercept = 0, this.ready = !0;
|
|
152
|
+
}
|
|
153
|
+
dispose() {
|
|
154
|
+
this.ready = !1;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
class k {
|
|
158
|
+
constructor(t) {
|
|
159
|
+
h(this, "config");
|
|
160
|
+
h(this, "filterType");
|
|
161
|
+
h(this, "cutoffFrequency");
|
|
162
|
+
h(this, "sampleRate");
|
|
163
|
+
h(this, "ready", !1);
|
|
164
|
+
var n, e, r;
|
|
165
|
+
this.config = t, this.filterType = ((n = t.metadata) == null ? void 0 : n.filterType) || "lowpass", this.cutoffFrequency = ((e = t.metadata) == null ? void 0 : e.cutoffFrequency) || 1e3, this.sampleRate = ((r = t.metadata) == null ? void 0 : r.sampleRate) || 44100;
|
|
166
|
+
}
|
|
167
|
+
get id() {
|
|
168
|
+
return this.config.id;
|
|
169
|
+
}
|
|
170
|
+
get name() {
|
|
171
|
+
return this.config.name;
|
|
172
|
+
}
|
|
173
|
+
get type() {
|
|
174
|
+
return this.config.type;
|
|
175
|
+
}
|
|
176
|
+
async predict(t) {
|
|
177
|
+
const n = performance.now(), e = Array.from(t.data), r = this.applyFilter(e), o = performance.now() - n;
|
|
178
|
+
return {
|
|
179
|
+
modelId: this.config.id,
|
|
180
|
+
output: new Float32Array(r),
|
|
181
|
+
outputShape: [r.length],
|
|
182
|
+
timestamp: Date.now(),
|
|
183
|
+
processingTime: o
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
applyFilter(t) {
|
|
187
|
+
switch (this.filterType) {
|
|
188
|
+
case "lowpass":
|
|
189
|
+
return this.lowpassFilter(t);
|
|
190
|
+
case "highpass":
|
|
191
|
+
return this.highpassFilter(t);
|
|
192
|
+
case "bandpass":
|
|
193
|
+
return this.bandpassFilter(t);
|
|
194
|
+
default:
|
|
195
|
+
return t;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
lowpassFilter(t) {
|
|
199
|
+
const n = 2 * Math.PI * this.cutoffFrequency / this.sampleRate, e = n / (1 + n), r = [t[0]];
|
|
200
|
+
for (let o = 1; o < t.length; o++)
|
|
201
|
+
r.push(e * t[o] + (1 - e) * r[o - 1]);
|
|
202
|
+
return r;
|
|
203
|
+
}
|
|
204
|
+
highpassFilter(t) {
|
|
205
|
+
const n = [];
|
|
206
|
+
for (let e = 1; e < t.length; e++)
|
|
207
|
+
n.push(t[e] - t[e - 1]);
|
|
208
|
+
return n;
|
|
209
|
+
}
|
|
210
|
+
bandpassFilter(t) {
|
|
211
|
+
const n = this.lowpassFilter(t);
|
|
212
|
+
return this.highpassFilter(n);
|
|
213
|
+
}
|
|
214
|
+
getInfo() {
|
|
215
|
+
return { ...this.config };
|
|
216
|
+
}
|
|
217
|
+
isReady() {
|
|
218
|
+
return this.ready;
|
|
219
|
+
}
|
|
220
|
+
async warmup() {
|
|
221
|
+
this.ready = !0;
|
|
222
|
+
}
|
|
223
|
+
dispose() {
|
|
224
|
+
this.ready = !1;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function q(i) {
|
|
228
|
+
switch (i.type) {
|
|
229
|
+
case "neural-network":
|
|
230
|
+
return new b(i);
|
|
231
|
+
case "linear-regression":
|
|
232
|
+
return new R(i);
|
|
233
|
+
case "signal-processor":
|
|
234
|
+
return new k(i);
|
|
235
|
+
default:
|
|
236
|
+
return new R(i);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function L(i) {
|
|
240
|
+
const t = i.length, n = new Array(t), e = new Array(t);
|
|
241
|
+
for (let r = 0; r < t; r++) {
|
|
242
|
+
let o = 0, s = 0;
|
|
243
|
+
for (let l = 0; l < t; l++) {
|
|
244
|
+
const a = -2 * Math.PI * r * l / t;
|
|
245
|
+
o += i[l] * Math.cos(a), s += i[l] * Math.sin(a);
|
|
246
|
+
}
|
|
247
|
+
n[r] = o, e[r] = s;
|
|
248
|
+
}
|
|
249
|
+
return { real: n, imag: e };
|
|
250
|
+
}
|
|
251
|
+
function F(i) {
|
|
252
|
+
return i.reduce((t, n) => t + n, 0) / i.length;
|
|
253
|
+
}
|
|
254
|
+
function Y(i) {
|
|
255
|
+
const t = F(i), n = i.reduce((e, r) => e + Math.pow(r - t, 2), 0) / i.length;
|
|
256
|
+
return Math.sqrt(n);
|
|
257
|
+
}
|
|
258
|
+
function z(i, t) {
|
|
259
|
+
const n = i.length, e = F(i), r = F(t);
|
|
260
|
+
let o = 0, s = 0, l = 0;
|
|
261
|
+
for (let a = 0; a < n; a++) {
|
|
262
|
+
const c = i[a] - e, f = t[a] - r;
|
|
263
|
+
o += c * f, s += c * c, l += f * f;
|
|
264
|
+
}
|
|
265
|
+
return o / Math.sqrt(s * l);
|
|
266
|
+
}
|
|
267
|
+
const N = {
|
|
268
|
+
name: "velo-plot-ml-integration",
|
|
269
|
+
version: "1.0.0",
|
|
270
|
+
description: "Machine Learning Integration Bridge for Sci Plot",
|
|
271
|
+
provides: ["ml", "prediction", "inference"],
|
|
272
|
+
tags: ["ml", "ai", "analysis"]
|
|
273
|
+
};
|
|
274
|
+
function $(i = {}) {
|
|
275
|
+
let t = null;
|
|
276
|
+
const n = /* @__PURE__ */ new Map(), e = /* @__PURE__ */ new Map();
|
|
277
|
+
i.models && i.models.forEach((s) => n.set(s.id, q(s)));
|
|
278
|
+
const r = {
|
|
279
|
+
registerModel(s) {
|
|
280
|
+
if (!s.id) {
|
|
281
|
+
t == null || t.log.error("Cannot register model without id");
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
n.set(s.id, s), t == null || t.log.info(`Model registered: ${s.name || "Unnamed"} (${s.id})`);
|
|
285
|
+
},
|
|
286
|
+
async runInference(s, l) {
|
|
287
|
+
const a = n.get(s);
|
|
288
|
+
if (!a) throw new Error(`Model not found: ${s}`);
|
|
289
|
+
const c = t == null ? void 0 : t.data.getSeriesData(l);
|
|
290
|
+
if (!c) throw new Error(`Series not found: ${l}`);
|
|
291
|
+
const f = new Float32Array(c.y), m = await a.predict({ data: f });
|
|
292
|
+
return m.xValues = c.x, m;
|
|
293
|
+
},
|
|
294
|
+
visualizeResults(s, l = {}) {
|
|
295
|
+
const a = `ml-viz-${Math.random().toString(36).substr(2, 9)}`;
|
|
296
|
+
return e.set(a, {
|
|
297
|
+
result: s,
|
|
298
|
+
config: { ...i.defaultVisualization, ...l }
|
|
299
|
+
}), t == null || t.requestRender(), a;
|
|
300
|
+
},
|
|
301
|
+
clearResults(s) {
|
|
302
|
+
s ? e.delete(s) : e.clear(), t == null || t.requestRender();
|
|
303
|
+
},
|
|
304
|
+
stats: {
|
|
305
|
+
fft: L,
|
|
306
|
+
mean: F,
|
|
307
|
+
standardDeviation: Y,
|
|
308
|
+
correlation: z
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
function o(s) {
|
|
312
|
+
const { render: l, coords: a } = s, { ctx2d: c } = l;
|
|
313
|
+
c && e.forEach((f) => {
|
|
314
|
+
var S, I, P, D;
|
|
315
|
+
const { result: m, config: p } = f, { output: w, xValues: y, confidence: v } = m;
|
|
316
|
+
if (!y) return;
|
|
317
|
+
const M = Math.min(y.length, w.length);
|
|
318
|
+
if (c.save(), p.showConfidenceInterval && v && v.length === M) {
|
|
319
|
+
c.beginPath();
|
|
320
|
+
const d = p.intervalOpacity ?? 0.2;
|
|
321
|
+
c.fillStyle = (((S = p.lineStyle) == null ? void 0 : S.color) || "#3b82f6") + Math.floor(d * 255).toString(16).padStart(2, "0");
|
|
322
|
+
for (let u = 0; u < M; u++) {
|
|
323
|
+
const g = a.dataToPixelX(y[u]), T = a.dataToPixelY(w[u] + v[u]);
|
|
324
|
+
u === 0 ? c.moveTo(g, T) : c.lineTo(g, T);
|
|
325
|
+
}
|
|
326
|
+
for (let u = M - 1; u >= 0; u--) {
|
|
327
|
+
const g = a.dataToPixelX(y[u]), T = a.dataToPixelY(w[u] - v[u]);
|
|
328
|
+
c.lineTo(g, T);
|
|
329
|
+
}
|
|
330
|
+
c.closePath(), c.fill();
|
|
331
|
+
}
|
|
332
|
+
c.beginPath(), c.strokeStyle = ((I = p.lineStyle) == null ? void 0 : I.color) || "#3b82f6", c.lineWidth = ((P = p.lineStyle) == null ? void 0 : P.width) || 2, (D = p.lineStyle) != null && D.dash && c.setLineDash(p.lineStyle.dash);
|
|
333
|
+
for (let d = 0; d < M; d++) {
|
|
334
|
+
const u = a.dataToPixelX(y[d]), g = a.dataToPixelY(w[d]);
|
|
335
|
+
d === 0 ? c.moveTo(u, g) : c.lineTo(u, g);
|
|
336
|
+
}
|
|
337
|
+
c.stroke(), c.restore();
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
manifest: N,
|
|
342
|
+
onInit(s) {
|
|
343
|
+
t = s;
|
|
344
|
+
},
|
|
345
|
+
onRenderOverlay(s, l) {
|
|
346
|
+
o(s);
|
|
347
|
+
},
|
|
348
|
+
api: r
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
export {
|
|
352
|
+
$ as PluginMLIntegration,
|
|
353
|
+
$ as default
|
|
354
|
+
};
|
|
355
|
+
//# sourceMappingURL=ml-integration.js.map
|