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.
Files changed (153) hide show
  1. package/README.md +14 -0
  2. package/dist/{index.core-xiNcuFfJ.js → ChartCore-DQ691eXH.js} +1807 -1287
  3. package/dist/ChartCore-DQ691eXH.js.map +1 -0
  4. package/dist/assets/downsample.worker-C70QJ04y.js +2 -0
  5. package/dist/assets/downsample.worker-C70QJ04y.js.map +1 -0
  6. package/dist/assets/indicator.worker-bv0zC4EX.js +2 -0
  7. package/dist/assets/indicator.worker-bv0zC4EX.js.map +1 -0
  8. package/dist/core/OverlayRenderer.d.ts +2 -0
  9. package/dist/core/chart/ChartAlerts.d.ts +42 -0
  10. package/dist/core/chart/ChartCore.d.ts +20 -1
  11. package/dist/core/chart/ChartRenderLoop.d.ts +4 -2
  12. package/dist/core/chart/ChartRenderer.d.ts +3 -2
  13. package/dist/core/chart/candlestickMarkers.d.ts +23 -0
  14. package/dist/core/chart/exporter/SVGExporter.d.ts +7 -2
  15. package/dist/core/chart/heikinAshi.d.ts +10 -0
  16. package/dist/core/chart/series/types.d.ts +2 -2
  17. package/dist/core/chart/types.d.ts +9 -0
  18. package/dist/core/indicator/addIndicator.d.ts +36 -0
  19. package/dist/core/indicator/index.d.ts +2 -0
  20. package/dist/core/indicator/indicatorPresets.d.ts +37 -0
  21. package/dist/core/render/pixelSnap.d.ts +8 -0
  22. package/dist/core/series/Series.d.ts +3 -0
  23. package/dist/core/stacked/index.d.ts +3 -1
  24. package/dist/core/stacked/paneResize.d.ts +15 -18
  25. package/dist/core/stacked/stackExport.d.ts +18 -0
  26. package/dist/core/stacked/types.d.ts +42 -5
  27. package/dist/core/time/TimeScale.d.ts +31 -0
  28. package/dist/createStackedChart-BPooTQ9z.js +1164 -0
  29. package/dist/createStackedChart-BPooTQ9z.js.map +1 -0
  30. package/dist/gpu/adapter/gpuRenderer.d.ts +21 -0
  31. package/dist/gpu/backends/webgpu/WebGPUBackend.d.ts +2 -1
  32. package/dist/gpuRenderer-BpaMYz-k.js +1848 -0
  33. package/dist/gpuRenderer-BpaMYz-k.js.map +1 -0
  34. package/dist/index-CUGS98p4.js +277 -0
  35. package/dist/index-CUGS98p4.js.map +1 -0
  36. package/dist/index-D7dTq6VB.js +503 -0
  37. package/dist/index-D7dTq6VB.js.map +1 -0
  38. package/dist/{index-Ce2JgkH_.js → index-DoYxf1cV.js} +86 -43
  39. package/dist/{index-Ce2JgkH_.js.map → index-DoYxf1cV.js.map} +1 -1
  40. package/dist/index.core-BtGFYMOu.js +167 -0
  41. package/dist/index.core-BtGFYMOu.js.map +1 -0
  42. package/dist/index.d.ts +12 -4
  43. package/dist/indicators--eJGmVox.js +302 -0
  44. package/dist/indicators--eJGmVox.js.map +1 -0
  45. package/dist/math-Ddm2EZjj.js +85 -0
  46. package/dist/math-Ddm2EZjj.js.map +1 -0
  47. package/dist/plugins/analysis.js +543 -818
  48. package/dist/plugins/analysis.js.map +1 -1
  49. package/dist/plugins/anomaly-detection.d.ts +1 -0
  50. package/dist/plugins/anomaly-detection.js +221 -0
  51. package/dist/plugins/anomaly-detection.js.map +1 -0
  52. package/dist/plugins/broken-axis.d.ts +3 -0
  53. package/dist/plugins/broken-axis.js +262 -0
  54. package/dist/plugins/broken-axis.js.map +1 -0
  55. package/dist/plugins/caching.d.ts +3 -0
  56. package/dist/plugins/caching.js +187 -0
  57. package/dist/plugins/caching.js.map +1 -0
  58. package/dist/plugins/data-transform.d.ts +3 -0
  59. package/dist/plugins/data-transform.js +146 -0
  60. package/dist/plugins/data-transform.js.map +1 -0
  61. package/dist/plugins/debug.js +12 -11
  62. package/dist/plugins/debug.js.map +1 -1
  63. package/dist/plugins/drawing-tools/index.d.ts +16 -0
  64. package/dist/plugins/forecasting.d.ts +1 -0
  65. package/dist/plugins/forecasting.js +236 -0
  66. package/dist/plugins/forecasting.js.map +1 -0
  67. package/dist/plugins/gpu.js +202 -1895
  68. package/dist/plugins/gpu.js.map +1 -1
  69. package/dist/plugins/index.d.ts +2 -0
  70. package/dist/plugins/keyboard/index.d.ts +1 -7
  71. package/dist/plugins/keyboard.js +1 -1
  72. package/dist/plugins/latex.d.ts +1 -0
  73. package/dist/plugins/latex.js +454 -0
  74. package/dist/plugins/latex.js.map +1 -0
  75. package/dist/plugins/lazy-load/types.d.ts +7 -0
  76. package/dist/plugins/lazy-load.d.ts +3 -0
  77. package/dist/plugins/lazy-load.js +212 -0
  78. package/dist/plugins/lazy-load.js.map +1 -0
  79. package/dist/plugins/ml-integration.d.ts +3 -0
  80. package/dist/plugins/ml-integration.js +355 -0
  81. package/dist/plugins/ml-integration.js.map +1 -0
  82. package/dist/plugins/offscreen.d.ts +3 -0
  83. package/dist/plugins/offscreen.js +169 -0
  84. package/dist/plugins/offscreen.js.map +1 -0
  85. package/dist/plugins/pattern-recognition.d.ts +3 -0
  86. package/dist/plugins/pattern-recognition.js +690 -0
  87. package/dist/plugins/pattern-recognition.js.map +1 -0
  88. package/dist/plugins/radar.d.ts +3 -0
  89. package/dist/plugins/radar.js +103 -0
  90. package/dist/plugins/radar.js.map +1 -0
  91. package/dist/plugins/regression.d.ts +3 -0
  92. package/dist/plugins/regression.js +634 -0
  93. package/dist/plugins/regression.js.map +1 -0
  94. package/dist/plugins/replay/index.d.ts +19 -0
  95. package/dist/plugins/roi.d.ts +1 -0
  96. package/dist/plugins/roi.js +223 -0
  97. package/dist/plugins/roi.js.map +1 -0
  98. package/dist/plugins/snapshot/types.d.ts +1 -1
  99. package/dist/plugins/snapshot.d.ts +3 -0
  100. package/dist/plugins/snapshot.js +90 -0
  101. package/dist/plugins/snapshot.js.map +1 -0
  102. package/dist/plugins/sync/index.d.ts +2 -1
  103. package/dist/plugins/sync.js +13 -269
  104. package/dist/plugins/sync.js.map +1 -1
  105. package/dist/plugins/video-recorder.d.ts +3 -0
  106. package/dist/plugins/video-recorder.js +104 -0
  107. package/dist/plugins/video-recorder.js.map +1 -0
  108. package/dist/plugins/virtualization/types.d.ts +12 -0
  109. package/dist/plugins/virtualization.d.ts +3 -0
  110. package/dist/plugins/virtualization.js +6 -0
  111. package/dist/plugins/virtualization.js.map +1 -0
  112. package/dist/pool-15HMCNv8.js +88 -0
  113. package/dist/pool-15HMCNv8.js.map +1 -0
  114. package/dist/react.d.ts +1 -0
  115. package/dist/react.js +31 -0
  116. package/dist/react.js.map +1 -0
  117. package/dist/renderer/CandlestickRenderer.d.ts +1 -1
  118. package/dist/renderer/ChartSeriesRenderer.d.ts +6 -0
  119. package/dist/renderer/GpuChartRenderer.d.ts +23 -0
  120. package/dist/renderer/index.d.ts +3 -0
  121. package/dist/renderer/spike/WebGLGridSpike.d.ts +40 -0
  122. package/dist/testing/baselines/v1.15.0.json.d.ts +51 -0
  123. package/dist/testing/gridSpikeBenchmark.d.ts +49 -0
  124. package/dist/testing/index.d.ts +5 -0
  125. package/dist/testing/rendererBenchmark.d.ts +13 -0
  126. package/dist/testing/stage1BrowserBench.d.ts +42 -0
  127. package/dist/types.d.ts +21 -1
  128. package/dist/utils-BK5UUXxj.js +172 -0
  129. package/dist/utils-BK5UUXxj.js.map +1 -0
  130. package/dist/velo-plot.full.js +1382 -5932
  131. package/dist/velo-plot.full.js.map +1 -1
  132. package/dist/velo-plot.js +26 -25
  133. package/dist/velo-plot.js.map +1 -1
  134. package/dist/workers/downsample.d.ts +38 -0
  135. package/dist/workers/downsampleAsync.d.ts +6 -0
  136. package/dist/workers/indicator.worker.d.ts +32 -0
  137. package/dist/workers/indicatorsAsync.d.ts +26 -0
  138. package/dist/workers/pool.d.ts +36 -0
  139. package/package.json +19 -2
  140. package/dist/core/OverlayRenderer.test.d.ts +0 -1
  141. package/dist/core/chart/ChartScaling.test.d.ts +0 -1
  142. package/dist/core/chart/NavigationUtils.test.d.ts +0 -1
  143. package/dist/core/format/axisFormat.test.d.ts +0 -1
  144. package/dist/core/indicator/buildIndicatorSeries.test.d.ts +0 -1
  145. package/dist/core/series/SeriesBounds.test.d.ts +0 -1
  146. package/dist/core/stacked/createStackedChart.test.d.ts +0 -1
  147. package/dist/core/stacked/paneAxis.test.d.ts +0 -1
  148. package/dist/core/stacked/paneResize.test.d.ts +0 -1
  149. package/dist/core/sync/index.test.d.ts +0 -1
  150. package/dist/index.core-xiNcuFfJ.js.map +0 -1
  151. package/dist/plugins/tools/tooltip/format.test.d.ts +0 -1
  152. package/dist/utils-Dbro9-qM.js +0 -254
  153. package/dist/utils-Dbro9-qM.js.map +0 -1
@@ -0,0 +1,187 @@
1
+ const x = {
2
+ name: "velo-plot-caching",
3
+ version: "1.0.0",
4
+ description: "Advanced caching system for performance optimization",
5
+ provides: ["caching", "performance"],
6
+ tags: ["optimization", "cache", "memory"]
7
+ }, $ = {
8
+ enabled: !0,
9
+ maxSize: 50 * 1024 * 1024,
10
+ // 50MB
11
+ strategy: "lru",
12
+ defaultTTL: void 0,
13
+ autoInvalidate: !0,
14
+ cacheTypes: {
15
+ transforms: !0,
16
+ analysis: !0,
17
+ frames: !1,
18
+ bounds: !0
19
+ },
20
+ onInvalidate: () => {
21
+ },
22
+ debug: !1
23
+ };
24
+ function k(p = {}) {
25
+ const s = { ...$, ...p };
26
+ let f = null;
27
+ const o = /* @__PURE__ */ new Map(), r = {
28
+ hits: 0,
29
+ misses: 0,
30
+ evictions: 0
31
+ };
32
+ let c = 0;
33
+ function u(e) {
34
+ if (e == null) return 0;
35
+ const t = typeof e;
36
+ return t === "boolean" ? 4 : t === "number" ? 8 : t === "string" ? e.length * 2 : e instanceof Float32Array || e instanceof Float64Array ? e.byteLength : Array.isArray(e) ? e.reduce((i, n) => i + u(n), 0) : t === "object" ? Object.keys(e).reduce(
37
+ (i, n) => i + n.length * 2 + u(e[n]),
38
+ 0
39
+ ) : 100;
40
+ }
41
+ function z(e) {
42
+ if (o.size === 0) return;
43
+ const t = Array.from(o.entries());
44
+ s.strategy === "lru" ? t.sort((a, l) => a[1].lastAccess - l[1].lastAccess) : s.strategy === "lfu" && t.sort((a, l) => a[1].hits - l[1].hits);
45
+ let i = 0;
46
+ const n = [];
47
+ for (const [a, l] of t) {
48
+ if (i >= e) break;
49
+ n.push(a), i += l.size, c -= l.size, r.evictions++;
50
+ }
51
+ for (const a of n)
52
+ o.delete(a);
53
+ s.debug && n.length > 0 && console.log(`[Cache] Evicted ${n.length} entries, freed ${i} bytes`);
54
+ }
55
+ function g() {
56
+ const e = Date.now(), t = [];
57
+ for (const [i, n] of o.entries())
58
+ n.ttl && e - n.timestamp > n.ttl && (t.push(i), c -= n.size);
59
+ for (const i of t)
60
+ o.delete(i);
61
+ return s.debug && t.length > 0 && console.log(`[Cache] Pruned ${t.length} expired entries`), t.length;
62
+ }
63
+ function b(e) {
64
+ if (!s.enabled) return;
65
+ const t = o.get(e);
66
+ if (!t) {
67
+ r.misses++;
68
+ return;
69
+ }
70
+ if (t.ttl && Date.now() - t.timestamp > t.ttl) {
71
+ o.delete(e), c -= t.size, r.misses++;
72
+ return;
73
+ }
74
+ return t.lastAccess = Date.now(), t.hits++, r.hits++, s.debug && console.log(`[Cache] HIT: ${e}`), t.value;
75
+ }
76
+ function v(e, t, i = {}) {
77
+ if (!s.enabled) return;
78
+ const n = i.size ?? u(t);
79
+ if (c + n > s.maxSize) {
80
+ const A = c + n - s.maxSize;
81
+ z(A);
82
+ }
83
+ if (n > s.maxSize) {
84
+ console.warn(`[Cache] Value too large to cache: ${e} (${n} bytes)`);
85
+ return;
86
+ }
87
+ const a = o.get(e);
88
+ a && (c -= a.size);
89
+ const l = {
90
+ value: t,
91
+ timestamp: Date.now(),
92
+ lastAccess: Date.now(),
93
+ hits: 0,
94
+ size: n,
95
+ ttl: i.ttl ?? s.defaultTTL,
96
+ tags: i.tags
97
+ };
98
+ o.set(e, l), c += n, s.debug && console.log(`[Cache] SET: ${e} (${n} bytes)`);
99
+ }
100
+ function T(e) {
101
+ return o.has(e);
102
+ }
103
+ function I(e) {
104
+ const t = o.get(e);
105
+ return t ? (c -= t.size, o.delete(e)) : !1;
106
+ }
107
+ function h() {
108
+ const e = o.size;
109
+ o.clear(), c = 0, s.debug && console.log(`[Cache] Cleared ${e} entries`), s.onInvalidate && s.onInvalidate({
110
+ keys: [],
111
+ reason: "manual",
112
+ timestamp: Date.now()
113
+ });
114
+ }
115
+ function y(e) {
116
+ const t = [];
117
+ for (const [i, n] of o.entries())
118
+ n.tags && n.tags.some((a) => e.includes(a)) && (t.push(i), c -= n.size);
119
+ for (const i of t)
120
+ o.delete(i);
121
+ return s.debug && t.length > 0 && console.log(`[Cache] Invalidated ${t.length} entries by tags:`, e), s.onInvalidate && t.length > 0 && s.onInvalidate({
122
+ keys: t,
123
+ reason: "tag",
124
+ timestamp: Date.now()
125
+ }), t.length;
126
+ }
127
+ function C() {
128
+ const e = r.hits + r.misses;
129
+ return {
130
+ hits: r.hits,
131
+ misses: r.misses,
132
+ hitRatio: e > 0 ? r.hits / e : 0,
133
+ currentSize: c,
134
+ maxSize: s.maxSize,
135
+ entryCount: o.size,
136
+ evictions: r.evictions
137
+ };
138
+ }
139
+ function D() {
140
+ r.hits = 0, r.misses = 0, r.evictions = 0;
141
+ }
142
+ function S() {
143
+ return Array.from(o.keys());
144
+ }
145
+ function w() {
146
+ return o.size;
147
+ }
148
+ const m = {
149
+ get: b,
150
+ set: v,
151
+ has: T,
152
+ delete: I,
153
+ clear: h,
154
+ invalidateByTags: y,
155
+ getStats: C,
156
+ resetStats: D,
157
+ keys: S,
158
+ size: w,
159
+ prune: g,
160
+ updateConfig(e) {
161
+ Object.assign(s, e);
162
+ }
163
+ };
164
+ let d = null;
165
+ return {
166
+ manifest: x,
167
+ onInit(e) {
168
+ f = e, f.chart.caching = m, d = window.setInterval(() => {
169
+ g();
170
+ }, 6e4);
171
+ },
172
+ onDataUpdate(e) {
173
+ if (!s.autoInvalidate) return;
174
+ const t = [];
175
+ s.cacheTypes.transforms && t.push("transform"), s.cacheTypes.analysis && t.push("analysis"), s.cacheTypes.bounds && t.push("bounds"), t.length > 0 && y(t);
176
+ },
177
+ onDestroy(e) {
178
+ d !== null && clearInterval(d), h(), delete e.chart.caching, f = null;
179
+ },
180
+ api: m
181
+ };
182
+ }
183
+ export {
184
+ k as PluginCaching,
185
+ k as default
186
+ };
187
+ //# sourceMappingURL=caching.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caching.js","sources":["../../src/plugins/caching/index.ts"],"sourcesContent":["/**\n * @fileoverview Advanced caching plugin for performance optimization\n * @module plugins/caching\n */\n\nimport type {\n PluginCachingConfig,\n CachingAPI,\n CacheEntry,\n CacheStats,\n} from './types';\nimport type {\n ChartPlugin,\n PluginContext,\n PluginManifest,\n} from '../types';\n\nconst manifest: PluginManifest = {\n name: 'velo-plot-caching',\n version: '1.0.0',\n description: 'Advanced caching system for performance optimization',\n provides: ['caching', 'performance'],\n tags: ['optimization', 'cache', 'memory'],\n};\n\nconst DEFAULT_CONFIG: Required<PluginCachingConfig> = {\n enabled: true,\n maxSize: 50 * 1024 * 1024, // 50MB\n strategy: 'lru',\n defaultTTL: undefined as any,\n autoInvalidate: true,\n cacheTypes: {\n transforms: true,\n analysis: true,\n frames: false,\n bounds: true,\n },\n onInvalidate: () => {},\n debug: false,\n};\n\nexport function PluginCaching(\n userConfig: Partial<PluginCachingConfig> = {}\n): ChartPlugin<PluginCachingConfig> {\n const config = { ...DEFAULT_CONFIG, ...userConfig };\n let ctx: PluginContext | null = null;\n\n // Cache storage\n const cache = new Map<string, CacheEntry>();\n \n // Statistics\n const stats = {\n hits: 0,\n misses: 0,\n evictions: 0,\n };\n \n let currentSize = 0;\n\n /**\n * Estimate size of value in bytes\n */\n function estimateSize(value: any): number {\n if (value === null || value === undefined) return 0;\n \n const type = typeof value;\n \n if (type === 'boolean') return 4;\n if (type === 'number') return 8;\n if (type === 'string') return value.length * 2;\n \n if (value instanceof Float32Array || value instanceof Float64Array) {\n return value.byteLength;\n }\n \n if (Array.isArray(value)) {\n return value.reduce((sum, item) => sum + estimateSize(item), 0);\n }\n \n if (type === 'object') {\n return Object.keys(value).reduce(\n (sum, key) => sum + key.length * 2 + estimateSize(value[key]),\n 0\n );\n }\n \n return 100; // Default estimate\n }\n\n /**\n * Evict entries based on strategy\n */\n function evict(requiredSpace: number): void {\n if (cache.size === 0) return;\n\n const entries = Array.from(cache.entries());\n \n // Sort based on strategy\n if (config.strategy === 'lru') {\n // Least recently used\n entries.sort((a, b) => a[1].lastAccess - b[1].lastAccess);\n } else if (config.strategy === 'lfu') {\n // Least frequently used\n entries.sort((a, b) => a[1].hits - b[1].hits);\n }\n // FIFO is already in insertion order (Map preserves order)\n \n let freedSpace = 0;\n const keysToDelete: string[] = [];\n \n for (const [key, entry] of entries) {\n if (freedSpace >= requiredSpace) break;\n \n keysToDelete.push(key);\n freedSpace += entry.size;\n currentSize -= entry.size;\n stats.evictions++;\n }\n \n // Delete entries\n for (const key of keysToDelete) {\n cache.delete(key);\n }\n \n if (config.debug && keysToDelete.length > 0) {\n console.log(`[Cache] Evicted ${keysToDelete.length} entries, freed ${freedSpace} bytes`);\n }\n }\n\n /**\n * Prune expired entries\n */\n function pruneExpired(): number {\n const now = Date.now();\n const keysToDelete: string[] = [];\n \n for (const [key, entry] of cache.entries()) {\n if (entry.ttl && now - entry.timestamp > entry.ttl) {\n keysToDelete.push(key);\n currentSize -= entry.size;\n }\n }\n \n for (const key of keysToDelete) {\n cache.delete(key);\n }\n \n if (config.debug && keysToDelete.length > 0) {\n console.log(`[Cache] Pruned ${keysToDelete.length} expired entries`);\n }\n \n return keysToDelete.length;\n }\n\n /**\n * Get value from cache\n */\n function get<T>(key: string): T | undefined {\n if (!config.enabled) return undefined;\n \n const entry = cache.get(key);\n \n if (!entry) {\n stats.misses++;\n return undefined;\n }\n \n // Check TTL\n if (entry.ttl) {\n const age = Date.now() - entry.timestamp;\n if (age > entry.ttl) {\n cache.delete(key);\n currentSize -= entry.size;\n stats.misses++;\n return undefined;\n }\n }\n \n // Update access metadata\n entry.lastAccess = Date.now();\n entry.hits++;\n stats.hits++;\n \n if (config.debug) {\n console.log(`[Cache] HIT: ${key}`);\n }\n \n return entry.value as T;\n }\n\n /**\n * Set value in cache\n */\n function set<T>(\n key: string,\n value: T,\n options: { ttl?: number; tags?: string[]; size?: number } = {}\n ): void {\n if (!config.enabled) return;\n \n // Estimate size\n const size = options.size ?? estimateSize(value);\n \n // Check if we need to evict\n if (currentSize + size > config.maxSize) {\n const requiredSpace = currentSize + size - config.maxSize;\n evict(requiredSpace);\n }\n \n // Still too large after eviction?\n if (size > config.maxSize) {\n console.warn(`[Cache] Value too large to cache: ${key} (${size} bytes)`);\n return;\n }\n \n // Remove old entry if exists\n const oldEntry = cache.get(key);\n if (oldEntry) {\n currentSize -= oldEntry.size;\n }\n \n // Create entry\n const entry: CacheEntry<T> = {\n value,\n timestamp: Date.now(),\n lastAccess: Date.now(),\n hits: 0,\n size,\n ttl: options.ttl ?? config.defaultTTL,\n tags: options.tags,\n };\n \n cache.set(key, entry);\n currentSize += size;\n \n if (config.debug) {\n console.log(`[Cache] SET: ${key} (${size} bytes)`);\n }\n }\n\n /**\n * Check if key exists\n */\n function has(key: string): boolean {\n return cache.has(key);\n }\n\n /**\n * Delete specific key\n */\n function deleteKey(key: string): boolean {\n const entry = cache.get(key);\n if (entry) {\n currentSize -= entry.size;\n return cache.delete(key);\n }\n return false;\n }\n\n /**\n * Clear all cache\n */\n function clear(): void {\n const count = cache.size;\n cache.clear();\n currentSize = 0;\n \n if (config.debug) {\n console.log(`[Cache] Cleared ${count} entries`);\n }\n \n if (config.onInvalidate) {\n config.onInvalidate({\n keys: [],\n reason: 'manual',\n timestamp: Date.now(),\n });\n }\n }\n\n /**\n * Invalidate by tags\n */\n function invalidateByTags(tags: string[]): number {\n const keysToDelete: string[] = [];\n \n for (const [key, entry] of cache.entries()) {\n if (entry.tags && entry.tags.some(tag => tags.includes(tag))) {\n keysToDelete.push(key);\n currentSize -= entry.size;\n }\n }\n \n for (const key of keysToDelete) {\n cache.delete(key);\n }\n \n if (config.debug && keysToDelete.length > 0) {\n console.log(`[Cache] Invalidated ${keysToDelete.length} entries by tags:`, tags);\n }\n \n if (config.onInvalidate && keysToDelete.length > 0) {\n config.onInvalidate({\n keys: keysToDelete,\n reason: 'tag',\n timestamp: Date.now(),\n });\n }\n \n return keysToDelete.length;\n }\n\n /**\n * Get cache statistics\n */\n function getStats(): CacheStats {\n const total = stats.hits + stats.misses;\n \n return {\n hits: stats.hits,\n misses: stats.misses,\n hitRatio: total > 0 ? stats.hits / total : 0,\n currentSize,\n maxSize: config.maxSize,\n entryCount: cache.size,\n evictions: stats.evictions,\n };\n }\n\n /**\n * Reset statistics\n */\n function resetStats(): void {\n stats.hits = 0;\n stats.misses = 0;\n stats.evictions = 0;\n }\n\n /**\n * Get all keys\n */\n function keys(): string[] {\n return Array.from(cache.keys());\n }\n\n /**\n * Get cache size\n */\n function size(): number {\n return cache.size;\n }\n\n // API implementation\n const api: CachingAPI & Record<string, unknown> = {\n get,\n set,\n has,\n delete: deleteKey,\n clear,\n invalidateByTags,\n getStats,\n resetStats,\n keys,\n size,\n prune: pruneExpired,\n updateConfig(newConfig: Partial<PluginCachingConfig>) {\n Object.assign(config, newConfig);\n },\n };\n\n // Periodic cleanup\n let cleanupInterval: number | null = null;\n\n return {\n manifest,\n\n onInit(pluginCtx: PluginContext) {\n ctx = pluginCtx;\n\n // Attach to chart API\n (ctx.chart as any).caching = api;\n\n // Setup periodic cleanup (every 60 seconds)\n cleanupInterval = window.setInterval(() => {\n pruneExpired();\n }, 60000);\n },\n\n onDataUpdate(_pluginCtx: PluginContext) {\n if (!config.autoInvalidate) return;\n\n const tags: string[] = [];\n if (config.cacheTypes.transforms) tags.push(\"transform\");\n if (config.cacheTypes.analysis) tags.push(\"analysis\");\n if (config.cacheTypes.bounds) tags.push(\"bounds\");\n\n if (tags.length > 0) {\n invalidateByTags(tags);\n }\n },\n\n onDestroy(pluginCtx: PluginContext) {\n // Clear cleanup interval\n if (cleanupInterval !== null) {\n clearInterval(cleanupInterval);\n }\n\n // Clear cache\n clear();\n\n // Remove from chart API\n delete (pluginCtx.chart as any).caching;\n\n ctx = null;\n },\n\n api,\n };\n}\n\nexport default PluginCaching;\n\n// Type exports\nexport type {\n PluginCachingConfig,\n CachingAPI,\n CacheEntry,\n CacheStats,\n CacheStrategy,\n CacheInvalidationEvent,\n} from './types';\n"],"names":["manifest","DEFAULT_CONFIG","PluginCaching","userConfig","config","ctx","cache","stats","currentSize","estimateSize","value","type","sum","item","key","evict","requiredSpace","entries","b","freedSpace","keysToDelete","entry","pruneExpired","now","get","set","options","size","oldEntry","has","deleteKey","clear","count","invalidateByTags","tags","tag","getStats","total","resetStats","keys","api","newConfig","cleanupInterval","pluginCtx","_pluginCtx"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export * from './data-transform/index'
2
+ import SciPlot from './data-transform/index'
3
+ export default SciPlot
@@ -0,0 +1,146 @@
1
+ import { c as S, d as T } from "../math-Ddm2EZjj.js";
2
+ import { s as $, m as k } from "../utils-BK5UUXxj.js";
3
+ const z = {
4
+ name: "data-transform",
5
+ version: "1.0.0",
6
+ description: "Advanced data transformation pipeline",
7
+ provides: ["data-transform", "processing"],
8
+ author: "Sci Plot Team"
9
+ };
10
+ function X(y = {}) {
11
+ const v = {
12
+ precision: 6,
13
+ ...y
14
+ };
15
+ let u = null;
16
+ const g = /* @__PURE__ */ new Map();
17
+ async function b(t, e) {
18
+ if (!u) return;
19
+ const i = u.chart, s = i.getSeries(t);
20
+ if (!s)
21
+ throw new Error(`Series ${t} not found`);
22
+ if (!g.has(t)) {
23
+ const o = s.getData();
24
+ g.set(t, {
25
+ x: new Float32Array(o.x.buffer.slice(0)),
26
+ y: new Float32Array(o.y.buffer.slice(0))
27
+ });
28
+ }
29
+ const n = g.get(t);
30
+ let a = new Float32Array(n.x.buffer.slice(0)), r = new Float32Array(n.y.buffer.slice(0));
31
+ for (const o of e) {
32
+ const l = await A(a, r, o);
33
+ a = l.x, r = l.y;
34
+ }
35
+ i.updateSeries(t, { x: a, y: r });
36
+ }
37
+ async function A(t, e, i) {
38
+ const s = i.parameters || i;
39
+ switch (i.type) {
40
+ case "normalize": {
41
+ const n = s.range || [0, 1];
42
+ let a = 1 / 0, r = -1 / 0;
43
+ for (let c = 0; c < e.length; c++)
44
+ e[c] < a && (a = e[c]), e[c] > r && (r = e[c]);
45
+ const o = r - a, l = n[1] - n[0], f = new Float32Array(e.length);
46
+ if (o === 0)
47
+ f.fill(n[0]);
48
+ else
49
+ for (let c = 0; c < e.length; c++)
50
+ f[c] = n[0] + (e[c] - a) / o * l;
51
+ return { x: t, y: f };
52
+ }
53
+ case "smooth":
54
+ case "moving-average": {
55
+ const n = s.window || 5, a = k(e, n);
56
+ return { x: t, y: a };
57
+ }
58
+ case "derivative": {
59
+ const n = s.order || 1;
60
+ let a = e;
61
+ for (let r = 0; r < n; r++)
62
+ a = T(t, a);
63
+ return { x: t, y: a };
64
+ }
65
+ case "integral": {
66
+ const n = S(t, e);
67
+ return { x: t, y: n };
68
+ }
69
+ case "scale-offset": {
70
+ const n = s.scale ?? 1, a = s.offset ?? 0, r = new Float32Array(e.length);
71
+ for (let o = 0; o < e.length; o++)
72
+ r[o] = e[o] * n + a;
73
+ return { x: t, y: r };
74
+ }
75
+ case "resample": {
76
+ const n = s.points || 1e3;
77
+ return M(t, e, n);
78
+ }
79
+ case "baseline-removal": {
80
+ const n = s.x1 ?? t[0], a = s.x2 ?? t[t.length - 1], r = $(t, e, n, a);
81
+ return { x: t, y: r };
82
+ }
83
+ case "abs": {
84
+ const n = e.map((a) => Math.abs(a));
85
+ return { x: t, y: n };
86
+ }
87
+ case "log": {
88
+ const n = s.base || Math.E, a = Math.log(n), r = e.map((o) => o > 0 ? Math.log(o) / a : 0);
89
+ return { x: t, y: r };
90
+ }
91
+ case "power": {
92
+ const n = s.exponent || 2, a = e.map((r) => Math.pow(r, n));
93
+ return { x: t, y: a };
94
+ }
95
+ default:
96
+ return console.warn(`Unknown transform type: ${i.type}`), { x: t, y: e };
97
+ }
98
+ }
99
+ function M(t, e, i) {
100
+ if (t.length <= 1 || i <= 1) return { x: t, y: e };
101
+ const s = new Float32Array(i), n = new Float32Array(i), a = t[0], o = (t[t.length - 1] - a) / (i - 1);
102
+ for (let l = 0; l < i; l++) {
103
+ const f = a + l * o;
104
+ s[l] = f;
105
+ let c = 0, w = t.length - 2, m = 0;
106
+ for (; c <= w; ) {
107
+ const p = c + w >> 1;
108
+ if (t[p] <= f && f <= t[p + 1]) {
109
+ m = p;
110
+ break;
111
+ }
112
+ t[p] < f ? c = p + 1 : w = p - 1;
113
+ }
114
+ const h = t[m], F = t[m + 1], d = e[m], D = e[m + 1], Y = (f - h) / (F - h);
115
+ n[l] = d + Y * (D - d);
116
+ }
117
+ return { x: s, y: n };
118
+ }
119
+ return {
120
+ manifest: z,
121
+ onInit(t) {
122
+ var e;
123
+ u = t, (e = u.log) == null || e.info(`DataTransform plugin initialized (precision: ${v.precision})`);
124
+ },
125
+ onDestroy() {
126
+ g.clear(), u = null;
127
+ },
128
+ api: {
129
+ transform: b,
130
+ resetTransform(t) {
131
+ if (g.has(t) && u) {
132
+ const e = g.get(t);
133
+ u.chart.updateSeries(t, { x: e.x, y: e.y }), g.delete(t);
134
+ }
135
+ },
136
+ getOriginalData(t) {
137
+ return g.get(t) || null;
138
+ }
139
+ }
140
+ };
141
+ }
142
+ export {
143
+ X as PluginDataTransform,
144
+ X as default
145
+ };
146
+ //# sourceMappingURL=data-transform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-transform.js","sources":["../../src/plugins/data-transform/index.ts"],"sourcesContent":["/**\n * PluginDataTransform - Implementation\n * \n * Provides a pipeline-based data transformation system for Sci Plot.\n */\n\nimport type { \n PluginManifest, \n ChartPlugin, \n PluginContext,\n} from '../types';\n\nimport type {\n PluginDataTransformConfig,\n DataTransformAPI,\n TransformOp\n} from './types';\n\n// Import algorithms from analysis plugin where available\nimport { \n movingAverage, \n derivative as calcDerivative, \n cumulativeIntegral as calcIntegral,\n subtractBaseline\n} from '../analysis';\n\nimport { Series } from '../../core/series/Series';\n\nconst manifest: PluginManifest = {\n name: 'data-transform',\n version: '1.0.0',\n description: 'Advanced data transformation pipeline',\n provides: ['data-transform', 'processing'],\n author: 'Sci Plot Team'\n};\n\nexport function PluginDataTransform(\n userConfig: Partial<PluginDataTransformConfig> = {}\n): ChartPlugin<PluginDataTransformConfig> {\n const _config: Required<PluginDataTransformConfig> = {\n autoApply: false,\n createDerivativeSeries: false,\n precision: 6,\n ...userConfig\n };\n\n let ctx: PluginContext | null = null;\n const originalDataStore = new Map<string, { x: Float32Array; y: Float32Array }>();\n\n /**\n * Core transformation logic\n */\n async function applyTransform(\n seriesId: string, \n pipeline: TransformOp[]\n ): Promise<void> {\n if (!ctx) return;\n \n const chart = ctx.chart;\n const series = chart.getSeries(seriesId) as unknown as Series;\n if (!series) {\n throw new Error(`Series ${seriesId} not found`);\n }\n\n // Capture original data if not already captured\n if (!originalDataStore.has(seriesId)) {\n const currentData = series.getData();\n originalDataStore.set(seriesId, {\n x: new Float32Array(currentData.x.buffer.slice(0)),\n y: new Float32Array(currentData.y.buffer.slice(0))\n });\n }\n\n const original = originalDataStore.get(seriesId)!;\n let x = new Float32Array(original.x.buffer.slice(0));\n let y = new Float32Array(original.y.buffer.slice(0));\n\n // Apply pipeline\n for (const op of pipeline) {\n const result = await executeOp(x, y, op);\n x = result.x;\n y = result.y;\n }\n\n // Update series with transformed data\n chart.updateSeries(seriesId, { x, y });\n }\n\n async function executeOp(\n x: Float32Array, \n y: Float32Array, \n op: TransformOp\n ): Promise<{ x: Float32Array; y: Float32Array }> {\n const params = op.parameters || (op as any);\n\n switch (op.type) {\n case 'normalize': {\n const range = params.range || [0, 1];\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < y.length; i++) {\n if (y[i] < min) min = y[i];\n if (y[i] > max) max = y[i];\n }\n const rangeWidth = max - min;\n const targetRange = range[1] - range[0];\n const newY = new Float32Array(y.length);\n if (rangeWidth === 0) {\n newY.fill(range[0]);\n } else {\n for (let i = 0; i < y.length; i++) {\n newY[i] = range[0] + ((y[i] - min) / rangeWidth) * targetRange;\n }\n }\n return { x, y: newY };\n }\n\n case 'smooth':\n case 'moving-average': {\n const window = params.window || 5;\n const smoothedY = movingAverage(y, window);\n return { x, y: smoothedY };\n }\n\n case 'derivative': {\n const order = params.order || 1;\n let dy = y;\n for (let i = 0; i < order; i++) {\n dy = calcDerivative(x, dy);\n }\n return { x, y: dy };\n }\n\n case 'integral': {\n const iy = calcIntegral(x, y);\n return { x, y: iy };\n }\n\n case 'scale-offset': {\n const scale = params.scale ?? 1;\n const offset = params.offset ?? 0;\n const newY = new Float32Array(y.length);\n for (let i = 0; i < y.length; i++) {\n newY[i] = y[i] * scale + offset;\n }\n return { x, y: newY };\n }\n\n case 'resample': {\n const points = params.points || 1000;\n return resample(x, y, points);\n }\n\n case 'baseline-removal': {\n const x1 = params.x1 ?? x[0];\n const x2 = params.x2 ?? x[x.length - 1];\n const result = subtractBaseline(x, y, x1, x2);\n return { x, y: result };\n }\n\n case 'abs': {\n const newY = y.map(v => Math.abs(v));\n return { x, y: newY };\n }\n\n case 'log': {\n const base = params.base || Math.E;\n const logBase = Math.log(base);\n const newY = y.map(v => v > 0 ? Math.log(v) / logBase : 0);\n return { x, y: newY };\n }\n\n case 'power': {\n const exp = params.exponent || 2;\n const newY = y.map(v => Math.pow(v, exp));\n return { x, y: newY };\n }\n\n default:\n console.warn(`Unknown transform type: ${op.type}`);\n return { x, y };\n }\n }\n\n function resample(\n x: Float32Array, \n y: Float32Array, \n numPoints: number\n ): { x: Float32Array; y: Float32Array } {\n if (x.length <= 1 || numPoints <= 1) return { x, y };\n \n const newX = new Float32Array(numPoints);\n const newY = new Float32Array(numPoints);\n \n const xMin = x[0];\n const xMax = x[x.length - 1];\n const dx = (xMax - xMin) / (numPoints - 1);\n \n for (let i = 0; i < numPoints; i++) {\n const targetX = xMin + i * dx;\n newX[i] = targetX;\n \n let low = 0;\n let high = x.length - 2;\n let found = 0;\n \n while (low <= high) {\n const mid = (low + high) >> 1;\n if (x[mid] <= targetX && targetX <= x[mid + 1]) {\n found = mid;\n break;\n }\n if (x[mid] < targetX) low = mid + 1;\n else high = mid - 1;\n }\n \n const x0 = x[found];\n const x1 = x[found + 1];\n const y0 = y[found];\n const y1 = y[found + 1];\n const t = (targetX - x0) / (x1 - x0);\n newY[i] = y0 + t * (y1 - y0);\n }\n \n return { x: newX, y: newY };\n }\n\n const api: DataTransformAPI & Record<string, unknown> = {\n transform: applyTransform,\n \n resetTransform(seriesId: string) {\n if (originalDataStore.has(seriesId) && ctx) {\n const original = originalDataStore.get(seriesId)!;\n ctx.chart.updateSeries(seriesId, { x: original.x, y: original.y });\n originalDataStore.delete(seriesId);\n }\n },\n \n getOriginalData(seriesId: string) {\n return originalDataStore.get(seriesId) || null;\n }\n };\n\n return {\n manifest,\n onInit(context: PluginContext) {\n ctx = context;\n ctx.log?.info(`DataTransform plugin initialized (precision: ${_config.precision})`);\n },\n onDestroy() {\n originalDataStore.clear();\n ctx = null;\n },\n api\n };\n}\n\nexport default PluginDataTransform;\n\nexport type {\n TransformType,\n TransformOp,\n PluginDataTransformConfig,\n DataTransformAPI\n} from './types';\n"],"names":["manifest","PluginDataTransform","userConfig","_config","ctx","originalDataStore","applyTransform","seriesId","pipeline","chart","series","currentData","original","x","y","op","result","executeOp","params","range","min","max","i","rangeWidth","targetRange","newY","window","smoothedY","movingAverage","order","dy","calcDerivative","iy","calcIntegral","scale","offset","points","resample","x1","x2","subtractBaseline","v","base","logBase","exp","numPoints","newX","xMin","dx","targetX","low","high","found","mid","x0","y0","y1","t","context","_a"],"mappings":";;AA4BA,MAAMA,IAA2B;AAAA,EAC/B,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,UAAU,CAAC,kBAAkB,YAAY;AAAA,EACzC,QAAQ;AACV;AAEO,SAASC,EACdC,IAAiD,IACT;AACxC,QAAMC,IAA+C;AAAA,IAGnD,WAAW;AAAA,IACX,GAAGD;AAAA,EAAA;AAGL,MAAIE,IAA4B;AAChC,QAAMC,wBAAwB,IAAA;AAK9B,iBAAeC,EACbC,GACAC,GACe;AACf,QAAI,CAACJ,EAAK;AAEV,UAAMK,IAAQL,EAAI,OACZM,IAASD,EAAM,UAAUF,CAAQ;AACvC,QAAI,CAACG;AACH,YAAM,IAAI,MAAM,UAAUH,CAAQ,YAAY;AAIhD,QAAI,CAACF,EAAkB,IAAIE,CAAQ,GAAG;AACpC,YAAMI,IAAcD,EAAO,QAAA;AAC3B,MAAAL,EAAkB,IAAIE,GAAU;AAAA,QAC9B,GAAG,IAAI,aAAaI,EAAY,EAAE,OAAO,MAAM,CAAC,CAAC;AAAA,QACjD,GAAG,IAAI,aAAaA,EAAY,EAAE,OAAO,MAAM,CAAC,CAAC;AAAA,MAAA,CAClD;AAAA,IACH;AAEA,UAAMC,IAAWP,EAAkB,IAAIE,CAAQ;AAC/C,QAAIM,IAAI,IAAI,aAAaD,EAAS,EAAE,OAAO,MAAM,CAAC,CAAC,GAC/CE,IAAI,IAAI,aAAaF,EAAS,EAAE,OAAO,MAAM,CAAC,CAAC;AAGnD,eAAWG,KAAMP,GAAU;AACzB,YAAMQ,IAAS,MAAMC,EAAUJ,GAAGC,GAAGC,CAAE;AACvC,MAAAF,IAAIG,EAAO,GACXF,IAAIE,EAAO;AAAA,IACb;AAGA,IAAAP,EAAM,aAAaF,GAAU,EAAE,GAAAM,GAAG,GAAAC,GAAG;AAAA,EACvC;AAEA,iBAAeG,EACbJ,GACAC,GACAC,GAC+C;AAC/C,UAAMG,IAASH,EAAG,cAAeA;AAEjC,YAAQA,EAAG,MAAA;AAAA,MACT,KAAK,aAAa;AAChB,cAAMI,IAAQD,EAAO,SAAS,CAAC,GAAG,CAAC;AACnC,YAAIE,IAAM,OACNC,IAAM;AACV,iBAASC,IAAI,GAAGA,IAAIR,EAAE,QAAQQ;AAC5B,UAAIR,EAAEQ,CAAC,IAAIF,MAAKA,IAAMN,EAAEQ,CAAC,IACrBR,EAAEQ,CAAC,IAAID,MAAKA,IAAMP,EAAEQ,CAAC;AAE3B,cAAMC,IAAaF,IAAMD,GACnBI,IAAcL,EAAM,CAAC,IAAIA,EAAM,CAAC,GAChCM,IAAO,IAAI,aAAaX,EAAE,MAAM;AACtC,YAAIS,MAAe;AACjB,UAAAE,EAAK,KAAKN,EAAM,CAAC,CAAC;AAAA;AAElB,mBAASG,IAAI,GAAGA,IAAIR,EAAE,QAAQQ;AAC5B,YAAAG,EAAKH,CAAC,IAAIH,EAAM,CAAC,KAAML,EAAEQ,CAAC,IAAIF,KAAOG,IAAcC;AAGvD,eAAO,EAAE,GAAAX,GAAG,GAAGY,EAAA;AAAA,MACjB;AAAA,MAEA,KAAK;AAAA,MACL,KAAK,kBAAkB;AACrB,cAAMC,IAASR,EAAO,UAAU,GAC1BS,IAAYC,EAAcd,GAAGY,CAAM;AACzC,eAAO,EAAE,GAAAb,GAAG,GAAGc,EAAA;AAAA,MACjB;AAAA,MAEA,KAAK,cAAc;AACjB,cAAME,IAAQX,EAAO,SAAS;AAC9B,YAAIY,IAAKhB;AACT,iBAASQ,IAAI,GAAGA,IAAIO,GAAOP;AACzB,UAAAQ,IAAKC,EAAelB,GAAGiB,CAAE;AAE3B,eAAO,EAAE,GAAAjB,GAAG,GAAGiB,EAAA;AAAA,MACjB;AAAA,MAEA,KAAK,YAAY;AACf,cAAME,IAAKC,EAAapB,GAAGC,CAAC;AAC5B,eAAO,EAAE,GAAAD,GAAG,GAAGmB,EAAA;AAAA,MACjB;AAAA,MAEA,KAAK,gBAAgB;AACnB,cAAME,IAAQhB,EAAO,SAAS,GACxBiB,IAASjB,EAAO,UAAU,GAC1BO,IAAO,IAAI,aAAaX,EAAE,MAAM;AACtC,iBAASQ,IAAI,GAAGA,IAAIR,EAAE,QAAQQ;AAC5B,UAAAG,EAAKH,CAAC,IAAIR,EAAEQ,CAAC,IAAIY,IAAQC;AAE3B,eAAO,EAAE,GAAAtB,GAAG,GAAGY,EAAA;AAAA,MACjB;AAAA,MAEA,KAAK,YAAY;AACf,cAAMW,IAASlB,EAAO,UAAU;AAChC,eAAOmB,EAASxB,GAAGC,GAAGsB,CAAM;AAAA,MAC9B;AAAA,MAEA,KAAK,oBAAoB;AACvB,cAAME,IAAKpB,EAAO,MAAML,EAAE,CAAC,GACrB0B,IAAKrB,EAAO,MAAML,EAAEA,EAAE,SAAS,CAAC,GAChCG,IAASwB,EAAiB3B,GAAGC,GAAGwB,GAAIC,CAAE;AAC5C,eAAO,EAAE,GAAA1B,GAAG,GAAGG,EAAA;AAAA,MACjB;AAAA,MAEA,KAAK,OAAO;AACV,cAAMS,IAAOX,EAAE,IAAI,OAAK,KAAK,IAAI2B,CAAC,CAAC;AACnC,eAAO,EAAE,GAAA5B,GAAG,GAAGY,EAAA;AAAA,MACjB;AAAA,MAEA,KAAK,OAAO;AACV,cAAMiB,IAAOxB,EAAO,QAAQ,KAAK,GAC3ByB,IAAU,KAAK,IAAID,CAAI,GACvBjB,IAAOX,EAAE,IAAI,CAAA2B,MAAKA,IAAI,IAAI,KAAK,IAAIA,CAAC,IAAIE,IAAU,CAAC;AACzD,eAAO,EAAE,GAAA9B,GAAG,GAAGY,EAAA;AAAA,MACjB;AAAA,MAEA,KAAK,SAAS;AACZ,cAAMmB,IAAM1B,EAAO,YAAY,GACzBO,IAAOX,EAAE,IAAI,CAAA2B,MAAK,KAAK,IAAIA,GAAGG,CAAG,CAAC;AACxC,eAAO,EAAE,GAAA/B,GAAG,GAAGY,EAAA;AAAA,MACjB;AAAA,MAEA;AACE,uBAAQ,KAAK,2BAA2BV,EAAG,IAAI,EAAE,GAC1C,EAAE,GAAAF,GAAG,GAAAC,EAAA;AAAA,IAAE;AAAA,EAEpB;AAEA,WAASuB,EACPxB,GACAC,GACA+B,GACsC;AACtC,QAAIhC,EAAE,UAAU,KAAKgC,KAAa,EAAG,QAAO,EAAE,GAAAhC,GAAG,GAAAC,EAAA;AAEjD,UAAMgC,IAAO,IAAI,aAAaD,CAAS,GACjCpB,IAAO,IAAI,aAAaoB,CAAS,GAEjCE,IAAOlC,EAAE,CAAC,GAEVmC,KADOnC,EAAEA,EAAE,SAAS,CAAC,IACRkC,MAASF,IAAY;AAExC,aAASvB,IAAI,GAAGA,IAAIuB,GAAWvB,KAAK;AAClC,YAAM2B,IAAUF,IAAOzB,IAAI0B;AAC3B,MAAAF,EAAKxB,CAAC,IAAI2B;AAEV,UAAIC,IAAM,GACNC,IAAOtC,EAAE,SAAS,GAClBuC,IAAQ;AAEZ,aAAOF,KAAOC,KAAM;AAClB,cAAME,IAAOH,IAAMC,KAAS;AAC5B,YAAItC,EAAEwC,CAAG,KAAKJ,KAAWA,KAAWpC,EAAEwC,IAAM,CAAC,GAAG;AAC9C,UAAAD,IAAQC;AACR;AAAA,QACF;AACA,QAAIxC,EAAEwC,CAAG,IAAIJ,QAAeI,IAAM,QACtBA,IAAM;AAAA,MACpB;AAEA,YAAMC,IAAKzC,EAAEuC,CAAK,GACZd,IAAKzB,EAAEuC,IAAQ,CAAC,GAChBG,IAAKzC,EAAEsC,CAAK,GACZI,IAAK1C,EAAEsC,IAAQ,CAAC,GAChBK,KAAKR,IAAUK,MAAOhB,IAAKgB;AACjC,MAAA7B,EAAKH,CAAC,IAAIiC,IAAKE,KAAKD,IAAKD;AAAA,IAC3B;AAEA,WAAO,EAAE,GAAGT,GAAM,GAAGrB,EAAA;AAAA,EACvB;AAkBA,SAAO;AAAA,IACL,UAAAzB;AAAA,IACA,OAAO0D,GAAwB;;AAC7B,MAAAtD,IAAMsD,IACNC,IAAAvD,EAAI,QAAJ,QAAAuD,EAAS,KAAK,gDAAgDxD,EAAQ,SAAS;AAAA,IACjF;AAAA,IACA,YAAY;AACV,MAAAE,EAAkB,MAAA,GAClBD,IAAM;AAAA,IACR;AAAA,IACA,KA1BsD;AAAA,MACtD,WAAWE;AAAA,MAEX,eAAeC,GAAkB;AAC/B,YAAIF,EAAkB,IAAIE,CAAQ,KAAKH,GAAK;AAC1C,gBAAMQ,IAAWP,EAAkB,IAAIE,CAAQ;AAC/C,UAAAH,EAAI,MAAM,aAAaG,GAAU,EAAE,GAAGK,EAAS,GAAG,GAAGA,EAAS,EAAA,CAAG,GACjEP,EAAkB,OAAOE,CAAQ;AAAA,QACnC;AAAA,MACF;AAAA,MAEA,gBAAgBA,GAAkB;AAChC,eAAOF,EAAkB,IAAIE,CAAQ,KAAK;AAAA,MAC5C;AAAA,IAAA;AAAA,EAaA;AAEJ;"}
@@ -1,7 +1,8 @@
1
1
  var c = Object.defineProperty;
2
- var f = (r, e, t) => e in r ? c(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
3
- var n = (r, e, t) => f(r, typeof e != "symbol" ? e + "" : e, t);
4
- import { c as m, i as g } from "../utils-Dbro9-qM.js";
2
+ var m = (r, e, t) => e in r ? c(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
3
+ var n = (r, e, t) => m(r, typeof e != "symbol" ? e + "" : e, t);
4
+ import { i as f } from "../math-Ddm2EZjj.js";
5
+ import { c as g } from "../utils-BK5UUXxj.js";
5
6
  class u {
6
7
  constructor(e, t) {
7
8
  n(this, "container");
@@ -177,10 +178,10 @@ class u {
177
178
  return isFinite(e) ? Math.abs(e) >= 1e6 || Math.abs(e) < 1e-3 && e !== 0 ? e.toExponential(2) : e.toFixed(3) : e.toString();
178
179
  }
179
180
  }
180
- function w(r, e) {
181
+ function S(r, e) {
181
182
  return new u(r, e);
182
183
  }
183
- function S(r) {
184
+ function C(r) {
184
185
  const e = document.querySelector(".velo-plot-container");
185
186
  if (!e)
186
187
  return console.warn("[SciPlot] No chart container found for debug overlay"), null;
@@ -243,7 +244,7 @@ class x {
243
244
  for (let a = 0; a < i.x.length; a++)
244
245
  i.x[a] >= e.xMin && i.x[a] <= e.xMax && (o.push(i.x[a]), s.push(i.y[a]));
245
246
  if (s.length === 0) return;
246
- const l = m(s), p = g(o, s), h = t.getStyle(), d = document.createElement("div");
247
+ const l = g(s), p = f(o, s), h = t.getStyle(), d = document.createElement("div");
247
248
  d.style.cssText = `
248
249
  padding: 8px 0;
249
250
  border-top: 1px solid ${this.isDarkTheme() ? "rgba(255,255,255,0.05)" : "rgba(0,0,0,0.05)"};
@@ -279,7 +280,7 @@ const v = {
279
280
  provides: ["ui"],
280
281
  tags: ["debug", "performance", "fps", "monitoring"]
281
282
  };
282
- function C(r = {}) {
283
+ function F(r = {}) {
283
284
  let e = null, t = null, i;
284
285
  return {
285
286
  manifest: v,
@@ -322,9 +323,9 @@ function C(r = {}) {
322
323
  }
323
324
  export {
324
325
  u as DebugOverlay,
325
- C as PluginDebug,
326
- w as createDebugOverlay,
327
- C as default,
328
- S as enableDebugMode
326
+ F as PluginDebug,
327
+ S as createDebugOverlay,
328
+ F as default,
329
+ C as enableDebugMode
329
330
  };
330
331
  //# sourceMappingURL=debug.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"debug.js","sources":["../../src/core/debug/index.ts","../../src/core/ChartStatistics.ts","../../src/plugins/debug/index.ts"],"sourcesContent":["/**\n * Sci Plot - Debug Overlay Module\n * \n * Provides a visual debug overlay showing performance metrics,\n * rendering info, and chart state for development and debugging.\n * \n * @module debug\n */\n\n// ============================================\n// Types\n// ============================================\n\nexport interface DebugStats {\n /** Current frames per second */\n fps: number;\n /** Average frame time in ms */\n frameTime: number;\n /** Total number of points being rendered */\n pointCount: number;\n /** Number of visible series */\n seriesCount: number;\n /** Current view bounds */\n viewBounds: {\n xMin: number;\n xMax: number;\n yMin: number;\n yMax: number;\n };\n /** WebGL/WebGPU renderer info */\n rendererInfo: {\n type: 'webgl' | 'webgpu' | 'unknown';\n vendor?: string;\n renderer?: string;\n };\n /** Memory usage estimate (bytes) */\n memoryEstimate: number;\n /** Number of draw calls per frame */\n drawCalls: number;\n /** Whether GPU downsampling is active */\n downsamplingActive: boolean;\n /** Device pixel ratio */\n devicePixelRatio: number;\n /** Canvas dimensions */\n canvasSize: { width: number; height: number };\n /** Plot area dimensions */\n plotArea: { x: number; y: number; width: number; height: number };\n}\n\nexport interface DebugOverlayOptions {\n /** Show FPS counter (default: true) */\n showFps?: boolean;\n /** Show point count (default: true) */\n showPointCount?: boolean;\n /** Show view bounds (default: true) */\n showBounds?: boolean;\n /** Show renderer info (default: true) */\n showRendererInfo?: boolean;\n /** Show memory estimate (default: true) */\n showMemory?: boolean;\n /** Show draw calls (default: true) */\n showDrawCalls?: boolean;\n /** Position: 'top-left', 'top-right', 'bottom-left', 'bottom-right' */\n position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n /** Background opacity (0-1, default: 0.8) */\n opacity?: number;\n /** Font size in pixels (default: 11) */\n fontSize?: number;\n /** Update interval in ms (default: 250) */\n updateInterval?: number;\n /** Custom CSS class name */\n className?: string;\n}\n\n// ============================================\n// Debug Overlay Implementation\n// ============================================\n\nexport class DebugOverlay {\n private container: HTMLElement;\n private element: HTMLDivElement | null = null;\n private options: Required<DebugOverlayOptions>;\n private visible: boolean = false;\n private updateIntervalId: number | null = null;\n private statsProvider: (() => Partial<DebugStats>) | null = null;\n private lastStats: Partial<DebugStats> = {};\n\n // FPS calculation\n private frameCount: number = 0;\n private lastFpsUpdate: number = 0;\n private currentFps: number = 0;\n private frameTimes: number[] = [];\n\n constructor(container: HTMLElement, options?: DebugOverlayOptions) {\n this.container = container;\n this.options = {\n showFps: true,\n showPointCount: true,\n showBounds: true,\n showRendererInfo: true,\n showMemory: true,\n showDrawCalls: true,\n position: 'top-left',\n opacity: 0.8,\n fontSize: 11,\n updateInterval: 250,\n className: 'velo-plot-debug-overlay',\n ...options,\n };\n }\n\n /**\n * Set the stats provider function\n */\n setStatsProvider(provider: () => Partial<DebugStats>): void {\n this.statsProvider = provider;\n }\n\n /**\n * Record a frame for FPS calculation\n */\n recordFrame(frameTime?: number): void {\n const now = performance.now();\n this.frameCount++;\n\n if (frameTime !== undefined) {\n this.frameTimes.push(frameTime);\n if (this.frameTimes.length > 60) {\n this.frameTimes.shift();\n }\n }\n\n // Update FPS every second\n if (now - this.lastFpsUpdate >= 1000) {\n this.currentFps = Math.round((this.frameCount * 1000) / (now - this.lastFpsUpdate));\n this.frameCount = 0;\n this.lastFpsUpdate = now;\n }\n }\n\n /**\n * Show the debug overlay\n */\n show(): void {\n if (this.visible) return;\n \n this.visible = true;\n this.createElement();\n this.startUpdates();\n }\n\n /**\n * Hide the debug overlay\n */\n hide(): void {\n if (!this.visible) return;\n \n this.visible = false;\n this.stopUpdates();\n this.destroyElement();\n }\n\n /**\n * Toggle visibility\n */\n toggle(): void {\n if (this.visible) {\n this.hide();\n } else {\n this.show();\n }\n }\n\n /**\n * Check if visible\n */\n isVisible(): boolean {\n return this.visible;\n }\n\n /**\n * Update the display with new stats\n */\n update(stats?: Partial<DebugStats>): void {\n if (!this.visible || !this.element) return;\n\n // Merge with provider stats\n const providerStats = this.statsProvider?.() || {};\n this.lastStats = {\n ...this.lastStats,\n ...providerStats,\n ...stats,\n fps: this.currentFps,\n frameTime: this.getAverageFrameTime(),\n };\n\n this.renderStats();\n }\n\n /**\n * Get current stats\n */\n getStats(): Partial<DebugStats> {\n return {\n ...this.lastStats,\n fps: this.currentFps,\n frameTime: this.getAverageFrameTime(),\n };\n }\n\n /**\n * Destroy the overlay\n */\n destroy(): void {\n this.hide();\n this.statsProvider = null;\n }\n\n // ============================================\n // Private Methods\n // ============================================\n\n private createElement(): void {\n if (this.element) return;\n\n this.element = document.createElement('div');\n this.element.className = this.options.className;\n \n // Apply styles\n Object.assign(this.element.style, {\n position: 'absolute',\n zIndex: '9999',\n fontFamily: 'monospace',\n fontSize: `${this.options.fontSize}px`,\n lineHeight: '1.4',\n padding: '8px 12px',\n backgroundColor: `rgba(0, 0, 0, ${this.options.opacity})`,\n color: '#00ff00',\n borderRadius: '4px',\n pointerEvents: 'none',\n userSelect: 'none',\n whiteSpace: 'pre',\n ...this.getPositionStyles(),\n });\n\n this.container.style.position = 'relative';\n this.container.appendChild(this.element);\n }\n\n private destroyElement(): void {\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n this.element = null;\n }\n\n private getPositionStyles(): Partial<CSSStyleDeclaration> {\n switch (this.options.position) {\n case 'top-right':\n return { top: '8px', right: '8px' };\n case 'bottom-left':\n return { bottom: '8px', left: '8px' };\n case 'bottom-right':\n return { bottom: '8px', right: '8px' };\n case 'top-left':\n default:\n return { top: '8px', left: '8px' };\n }\n }\n\n private startUpdates(): void {\n if (this.updateIntervalId !== null) return;\n \n this.updateIntervalId = window.setInterval(() => {\n this.update();\n }, this.options.updateInterval);\n }\n\n private stopUpdates(): void {\n if (this.updateIntervalId !== null) {\n clearInterval(this.updateIntervalId);\n this.updateIntervalId = null;\n }\n }\n\n private getAverageFrameTime(): number {\n if (this.frameTimes.length === 0) return 0;\n const sum = this.frameTimes.reduce((a, b) => a + b, 0);\n return sum / this.frameTimes.length;\n }\n\n private renderStats(): void {\n if (!this.element) return;\n\n const lines: string[] = [];\n const stats = this.lastStats;\n\n // FPS\n if (this.options.showFps && stats.fps !== undefined) {\n const fpsColor = stats.fps >= 55 ? '#00ff00' : stats.fps >= 30 ? '#ffff00' : '#ff4444';\n lines.push(`<span style=\"color:${fpsColor}\">FPS: ${stats.fps}</span>`);\n if (stats.frameTime) {\n lines.push(`Frame: ${stats.frameTime.toFixed(2)}ms`);\n }\n }\n\n // Point count\n if (this.options.showPointCount && stats.pointCount !== undefined) {\n lines.push(`Points: ${this.formatNumber(stats.pointCount)}`);\n }\n\n // Series count\n if (stats.seriesCount !== undefined) {\n lines.push(`Series: ${stats.seriesCount}`);\n }\n\n // Draw calls\n if (this.options.showDrawCalls && stats.drawCalls !== undefined) {\n lines.push(`Draw calls: ${stats.drawCalls}`);\n }\n\n // Memory\n if (this.options.showMemory && stats.memoryEstimate !== undefined) {\n lines.push(`Memory: ${this.formatBytes(stats.memoryEstimate)}`);\n }\n\n // Bounds\n if (this.options.showBounds && stats.viewBounds) {\n const b = stats.viewBounds;\n lines.push(`X: [${this.formatValue(b.xMin)}, ${this.formatValue(b.xMax)}]`);\n lines.push(`Y: [${this.formatValue(b.yMin)}, ${this.formatValue(b.yMax)}]`);\n }\n\n // Renderer info\n if (this.options.showRendererInfo && stats.rendererInfo) {\n const info = stats.rendererInfo;\n lines.push(`Renderer: ${info.type.toUpperCase()}`);\n if (info.renderer) {\n // Truncate long renderer names\n const shortRenderer = info.renderer.length > 30 \n ? info.renderer.substring(0, 27) + '...'\n : info.renderer;\n lines.push(`GPU: ${shortRenderer}`);\n }\n }\n\n // Canvas size\n if (stats.canvasSize) {\n lines.push(`Canvas: ${stats.canvasSize.width}×${stats.canvasSize.height}`);\n }\n\n // Downsampling\n if (stats.downsamplingActive !== undefined) {\n lines.push(`Downsampling: ${stats.downsamplingActive ? 'ON' : 'OFF'}`);\n }\n\n // DPR\n if (stats.devicePixelRatio !== undefined) {\n lines.push(`DPR: ${stats.devicePixelRatio}`);\n }\n\n this.element.innerHTML = lines.join('\\n');\n }\n\n private formatNumber(n: number): string {\n if (n >= 1e9) return (n / 1e9).toFixed(1) + 'B';\n if (n >= 1e6) return (n / 1e6).toFixed(1) + 'M';\n if (n >= 1e3) return (n / 1e3).toFixed(1) + 'K';\n return n.toLocaleString();\n }\n\n private formatBytes(bytes: number): string {\n if (bytes >= 1e9) return (bytes / 1e9).toFixed(2) + ' GB';\n if (bytes >= 1e6) return (bytes / 1e6).toFixed(2) + ' MB';\n if (bytes >= 1e3) return (bytes / 1e3).toFixed(2) + ' KB';\n return bytes + ' B';\n }\n\n private formatValue(v: number): string {\n if (!isFinite(v)) return v.toString();\n if (Math.abs(v) >= 1e6 || (Math.abs(v) < 0.001 && v !== 0)) {\n return v.toExponential(2);\n }\n return v.toFixed(3);\n }\n}\n\n// ============================================\n// Convenience Functions\n// ============================================\n\n/**\n * Create a debug overlay for a chart container\n */\nexport function createDebugOverlay(\n container: HTMLElement,\n options?: DebugOverlayOptions\n): DebugOverlay {\n return new DebugOverlay(container, options);\n}\n\n/**\n * Quick enable debug mode (attaches to first chart container found)\n */\nexport function enableDebugMode(options?: DebugOverlayOptions): DebugOverlay | null {\n const container = document.querySelector('.velo-plot-container') as HTMLElement;\n if (!container) {\n console.warn('[SciPlot] No chart container found for debug overlay');\n return null;\n }\n \n const overlay = new DebugOverlay(container, options);\n overlay.show();\n return overlay;\n}\n","/**\n * ChartStatistics - In-chart statistics panel\n * \n * Displays real-time statistics (Min, Max, Mean, StdDev, Area) \n * for the visible data range of active series.\n */\n\nimport { ChartTheme } from \"../theme\";\nimport { Series } from \"./Series\";\nimport { calculateStats, integrate } from \"../plugins/analysis\";\nimport { Bounds } from \"../types\";\n\nexport class ChartStatistics {\n private container: HTMLDivElement;\n private content: HTMLDivElement;\n private theme: ChartTheme;\n private series: Map<string, Series>;\n private isExpanded = false;\n\n constructor(\n parent: HTMLElement,\n theme: ChartTheme,\n series: Map<string, Series>\n ) {\n this.theme = theme;\n this.series = series;\n\n this.container = document.createElement(\"div\");\n this.container.className = \"velo-plot-stats-panel\";\n this.updateContainerStyle();\n\n const title = document.createElement(\"div\");\n title.innerHTML = \"📊 Statistics\";\n title.style.cssText = `\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n `;\n title.onclick = () => this.toggle();\n\n this.content = document.createElement(\"div\");\n this.content.style.display = \"none\";\n \n this.container.appendChild(title);\n this.container.appendChild(this.content);\n parent.appendChild(this.container);\n }\n\n private isDarkTheme(): boolean {\n const name = this.theme.name.toLowerCase();\n return name.includes(\"dark\") || name.includes(\"midnight\") || name.includes(\"electro\");\n }\n\n private updateContainerStyle(): void {\n const isDark = this.isDarkTheme();\n const bg = isDark ? \"rgba(15, 23, 42, 0.85)\" : \"rgba(255, 255, 255, 0.95)\";\n const color = isDark ? \"#f1f5f9\" : \"#1e293b\";\n const borderColor = isDark ? \"rgba(255, 255, 255, 0.1)\" : \"rgba(0, 0, 0, 0.1)\";\n const shadow = isDark ? \"0 4px 12px rgba(0, 0, 0, 0.5)\" : \"0 4px 12px rgba(0, 0, 0, 0.1)\";\n\n this.container.style.cssText = `\n position: absolute;\n bottom: 8px;\n right: 8px;\n width: 240px;\n background: ${bg};\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n border: 1px solid ${borderColor};\n border-radius: 8px;\n box-shadow: ${shadow};\n color: ${color};\n font-family: system-ui, -apple-system, sans-serif;\n padding: 8px 12px;\n z-index: 90;\n transition: all 0.3s ease;\n font-size: 12px;\n pointer-events: auto;\n `;\n }\n\n public update(viewBounds: Bounds): void {\n if (!this.isExpanded) return;\n\n this.content.innerHTML = \"\";\n \n this.series.forEach((s) => {\n if (!s.getVisible()) return;\n\n const data = s.getData();\n if (!data) return;\n\n // Filter data in visible range\n const visibleY: number[] = [];\n const visibleX: number[] = [];\n for (let i = 0; i < data.x.length; i++) {\n if (data.x[i] >= viewBounds.xMin && data.x[i] <= viewBounds.xMax) {\n visibleX.push(data.x[i]);\n visibleY.push(data.y[i]);\n }\n }\n\n if (visibleY.length === 0) return;\n\n const stats = calculateStats(visibleY);\n const area = integrate(visibleX as any, visibleY as any);\n const style = s.getStyle();\n\n const item = document.createElement(\"div\");\n item.style.cssText = `\n padding: 8px 0;\n border-top: 1px solid ${this.isDarkTheme() ? \"rgba(255,255,255,0.05)\" : \"rgba(0,0,0,0.05)\"};\n `;\n\n item.innerHTML = `\n <div style=\"display: flex; align-items: center; gap: 6px; margin-bottom: 4px; font-weight: 600;\">\n <div style=\"width: 8px; height: 8px; border-radius: 2px; background: ${style.color}\"></div>\n ${s.getId()}\n </div>\n <div style=\"display: grid; grid-template-columns: 1fr 1fr; gap: 4px; opacity: 0.9; font-size: 11px;\">\n <span>Min: ${stats.min.toExponential(3)}</span>\n <span>Max: ${stats.max.toExponential(3)}</span>\n <span>Mean: ${stats.mean.toExponential(3)}</span>\n <span>Count: ${stats.count}</span>\n <span style=\"grid-column: span 2;\">Area: ${area.toExponential(4)}</span>\n </div>\n `;\n\n this.content.appendChild(item);\n });\n\n if (this.content.innerHTML === \"\") {\n this.content.innerHTML = \"<div style='opacity: 0.5; font-style: italic;'>No series visible in range</div>\";\n }\n }\n\n public toggle(): void {\n this.isExpanded = !this.isExpanded;\n this.content.style.display = this.isExpanded ? \"block\" : \"none\";\n if (this.isExpanded) {\n // Redraw immediately will be handled by the chart's next render\n }\n }\n\n public updateTheme(theme: ChartTheme): void {\n this.theme = theme;\n this.updateContainerStyle();\n }\n\n public destroy(): void {\n this.container.remove();\n }\n}\n","/**\n * SciPlot Engine - Debug Overlay Plugin\n * \n * Provides performance metrics and debugging information.\n * \n * @module plugins/debug\n */\n\nexport * from \"../../core/debug\";\nimport type { PluginManifest, ChartPlugin, PluginContext, AfterRenderEvent } from \"../types\";\n\nexport interface PluginDebugConfig extends Partial<DebugOverlayOptions> {\n /** Show FPS counter */\n showFPS?: boolean;\n /** Show data stats */\n showDataStats?: boolean;\n}\n\nconst manifestDebug: PluginManifest = {\n name: \"velo-plot-debug\",\n version: \"1.0.0\",\n description: \"Performance monitoring and debugging overlay for velo-plot\",\n provides: [\"ui\"],\n tags: [\"debug\", \"performance\", \"fps\", \"monitoring\"],\n};\n\nimport { DebugOverlay, DebugOverlayOptions } from \"../../core/debug\";\nimport { ChartStatistics } from \"../../core/ChartStatistics\";\n\n/**\n * SciPlot Debug Plugin\n * \n * Adds a useful overlay with real-time performance metrics and debugging info.\n */\nexport function PluginDebug(config: PluginDebugConfig = {}): ChartPlugin<PluginDebugConfig> {\n let overlay: DebugOverlay | null = null;\n let stats: ChartStatistics | null = null;\n\n let ctx: PluginContext;\n\n return {\n manifest: manifestDebug,\n\n onInit(pCtx: PluginContext) {\n ctx = pCtx;\n\n // Initialize FPS/Performance overlay\n if (config.showFPS !== false) {\n overlay = new DebugOverlay(ctx.ui.container, {\n showFps: true,\n showMemory: true,\n showPointCount: true,\n updateInterval: 500,\n ...config\n });\n overlay.show();\n\n // Set stats provider for more detailed info\n overlay.setStatsProvider(() => {\n const series = ctx.data.getAllSeries();\n const pointCount = series.reduce((sum, s) => sum + s.getData().x.length, 0);\n\n return {\n pointCount,\n seriesCount: series.length,\n viewBounds: ctx.data.getViewBounds(),\n devicePixelRatio: (ctx.chart as any).dpr || 1,\n };\n });\n }\n\n // Initialize data statistics panel\n if (config.showDataStats) {\n stats = new ChartStatistics(\n ctx.ui.container,\n (ctx.chart as any).theme,\n (ctx.chart as any).series\n );\n }\n },\n\n onBeforeRender() {\n if (overlay) {\n overlay.recordFrame();\n }\n },\n\n onAfterRender(_ctx, event: AfterRenderEvent) {\n if (overlay) {\n overlay.update({\n frameTime: (event as any).frameTime || event.renderTime,\n });\n }\n },\n\n onRenderOverlay(_ctx) {\n if (stats) {\n stats.update(ctx.data.getViewBounds());\n }\n },\n\n onDestroy(_ctx: PluginContext) {\n if (overlay) {\n overlay.destroy();\n overlay = null;\n }\n if (stats) {\n stats.destroy();\n stats = null;\n }\n }\n };\n}\n\nexport { DebugOverlay };\nexport default PluginDebug;\n"],"names":["DebugOverlay","container","options","__publicField","provider","frameTime","now","stats","providerStats","_a","a","b","lines","fpsColor","info","shortRenderer","n","bytes","v","createDebugOverlay","enableDebugMode","overlay","ChartStatistics","parent","theme","series","title","name","isDark","bg","color","borderColor","shadow","viewBounds","s","data","visibleY","visibleX","i","calculateStats","area","integrate","style","item","manifestDebug","PluginDebug","config","ctx","pCtx","sum","_ctx","event"],"mappings":";;;;AA8EO,MAAMA,EAAa;AAAA,EAexB,YAAYC,GAAwBC,GAA+B;AAd3D,IAAAC,EAAA;AACA,IAAAA,EAAA,iBAAiC;AACjC,IAAAA,EAAA;AACA,IAAAA,EAAA,iBAAmB;AACnB,IAAAA,EAAA,0BAAkC;AAClC,IAAAA,EAAA,uBAAoD;AACpD,IAAAA,EAAA,mBAAiC,CAAA;AAGjC;AAAA,IAAAA,EAAA,oBAAqB;AACrB,IAAAA,EAAA,uBAAwB;AACxB,IAAAA,EAAA,oBAAqB;AACrB,IAAAA,EAAA,oBAAuB,CAAA;AAG7B,SAAK,YAAYF,GACjB,KAAK,UAAU;AAAA,MACb,SAAS;AAAA,MACT,gBAAgB;AAAA,MAChB,YAAY;AAAA,MACZ,kBAAkB;AAAA,MAClB,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,UAAU;AAAA,MACV,SAAS;AAAA,MACT,UAAU;AAAA,MACV,gBAAgB;AAAA,MAChB,WAAW;AAAA,MACX,GAAGC;AAAA,IAAA;AAAA,EAEP;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiBE,GAA2C;AAC1D,SAAK,gBAAgBA;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,YAAYC,GAA0B;AACpC,UAAMC,IAAM,YAAY,IAAA;AACxB,SAAK,cAEDD,MAAc,WAChB,KAAK,WAAW,KAAKA,CAAS,GAC1B,KAAK,WAAW,SAAS,MAC3B,KAAK,WAAW,MAAA,IAKhBC,IAAM,KAAK,iBAAiB,QAC9B,KAAK,aAAa,KAAK,MAAO,KAAK,aAAa,OAASA,IAAM,KAAK,cAAc,GAClF,KAAK,aAAa,GAClB,KAAK,gBAAgBA;AAAA,EAEzB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAa;AACX,IAAI,KAAK,YAET,KAAK,UAAU,IACf,KAAK,cAAA,GACL,KAAK,aAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKA,OAAa;AACX,IAAK,KAAK,YAEV,KAAK,UAAU,IACf,KAAK,YAAA,GACL,KAAK,eAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKA,SAAe;AACb,IAAI,KAAK,UACP,KAAK,KAAA,IAEL,KAAK,KAAA;AAAA,EAET;AAAA;AAAA;AAAA;AAAA,EAKA,YAAqB;AACnB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,OAAOC,GAAmC;;AACxC,QAAI,CAAC,KAAK,WAAW,CAAC,KAAK,QAAS;AAGpC,UAAMC,MAAgBC,IAAA,KAAK,kBAAL,gBAAAA,EAAA,eAA0B,CAAA;AAChD,SAAK,YAAY;AAAA,MACf,GAAG,KAAK;AAAA,MACR,GAAGD;AAAA,MACH,GAAGD;AAAA,MACH,KAAK,KAAK;AAAA,MACV,WAAW,KAAK,oBAAA;AAAA,IAAoB,GAGtC,KAAK,YAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKA,WAAgC;AAC9B,WAAO;AAAA,MACL,GAAG,KAAK;AAAA,MACR,KAAK,KAAK;AAAA,MACV,WAAW,KAAK,oBAAA;AAAA,IAAoB;AAAA,EAExC;AAAA;AAAA;AAAA;AAAA,EAKA,UAAgB;AACd,SAAK,KAAA,GACL,KAAK,gBAAgB;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAMQ,gBAAsB;AAC5B,IAAI,KAAK,YAET,KAAK,UAAU,SAAS,cAAc,KAAK,GAC3C,KAAK,QAAQ,YAAY,KAAK,QAAQ,WAGtC,OAAO,OAAO,KAAK,QAAQ,OAAO;AAAA,MAChC,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,UAAU,GAAG,KAAK,QAAQ,QAAQ;AAAA,MAClC,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,iBAAiB,iBAAiB,KAAK,QAAQ,OAAO;AAAA,MACtD,OAAO;AAAA,MACP,cAAc;AAAA,MACd,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,GAAG,KAAK,kBAAA;AAAA,IAAkB,CAC3B,GAED,KAAK,UAAU,MAAM,WAAW,YAChC,KAAK,UAAU,YAAY,KAAK,OAAO;AAAA,EACzC;AAAA,EAEQ,iBAAuB;AAC7B,IAAI,KAAK,WAAW,KAAK,QAAQ,cAC/B,KAAK,QAAQ,WAAW,YAAY,KAAK,OAAO,GAElD,KAAK,UAAU;AAAA,EACjB;AAAA,EAEQ,oBAAkD;AACxD,YAAQ,KAAK,QAAQ,UAAA;AAAA,MACnB,KAAK;AACH,eAAO,EAAE,KAAK,OAAO,OAAO,MAAA;AAAA,MAC9B,KAAK;AACH,eAAO,EAAE,QAAQ,OAAO,MAAM,MAAA;AAAA,MAChC,KAAK;AACH,eAAO,EAAE,QAAQ,OAAO,OAAO,MAAA;AAAA,MACjC,KAAK;AAAA,MACL;AACE,eAAO,EAAE,KAAK,OAAO,MAAM,MAAA;AAAA,IAAM;AAAA,EAEvC;AAAA,EAEQ,eAAqB;AAC3B,IAAI,KAAK,qBAAqB,SAE9B,KAAK,mBAAmB,OAAO,YAAY,MAAM;AAC/C,WAAK,OAAA;AAAA,IACP,GAAG,KAAK,QAAQ,cAAc;AAAA,EAChC;AAAA,EAEQ,cAAoB;AAC1B,IAAI,KAAK,qBAAqB,SAC5B,cAAc,KAAK,gBAAgB,GACnC,KAAK,mBAAmB;AAAA,EAE5B;AAAA,EAEQ,sBAA8B;AACpC,WAAI,KAAK,WAAW,WAAW,IAAU,IAC7B,KAAK,WAAW,OAAO,CAACG,GAAGC,MAAMD,IAAIC,GAAG,CAAC,IACxC,KAAK,WAAW;AAAA,EAC/B;AAAA,EAEQ,cAAoB;AAC1B,QAAI,CAAC,KAAK,QAAS;AAEnB,UAAMC,IAAkB,CAAA,GAClBL,IAAQ,KAAK;AAGnB,QAAI,KAAK,QAAQ,WAAWA,EAAM,QAAQ,QAAW;AACnD,YAAMM,IAAWN,EAAM,OAAO,KAAK,YAAYA,EAAM,OAAO,KAAK,YAAY;AAC7E,MAAAK,EAAM,KAAK,sBAAsBC,CAAQ,UAAUN,EAAM,GAAG,SAAS,GACjEA,EAAM,aACRK,EAAM,KAAK,UAAUL,EAAM,UAAU,QAAQ,CAAC,CAAC,IAAI;AAAA,IAEvD;AAuBA,QApBI,KAAK,QAAQ,kBAAkBA,EAAM,eAAe,UACtDK,EAAM,KAAK,WAAW,KAAK,aAAaL,EAAM,UAAU,CAAC,EAAE,GAIzDA,EAAM,gBAAgB,UACxBK,EAAM,KAAK,WAAWL,EAAM,WAAW,EAAE,GAIvC,KAAK,QAAQ,iBAAiBA,EAAM,cAAc,UACpDK,EAAM,KAAK,eAAeL,EAAM,SAAS,EAAE,GAIzC,KAAK,QAAQ,cAAcA,EAAM,mBAAmB,UACtDK,EAAM,KAAK,WAAW,KAAK,YAAYL,EAAM,cAAc,CAAC,EAAE,GAI5D,KAAK,QAAQ,cAAcA,EAAM,YAAY;AAC/C,YAAMI,IAAIJ,EAAM;AAChB,MAAAK,EAAM,KAAK,OAAO,KAAK,YAAYD,EAAE,IAAI,CAAC,KAAK,KAAK,YAAYA,EAAE,IAAI,CAAC,GAAG,GAC1EC,EAAM,KAAK,OAAO,KAAK,YAAYD,EAAE,IAAI,CAAC,KAAK,KAAK,YAAYA,EAAE,IAAI,CAAC,GAAG;AAAA,IAC5E;AAGA,QAAI,KAAK,QAAQ,oBAAoBJ,EAAM,cAAc;AACvD,YAAMO,IAAOP,EAAM;AAEnB,UADAK,EAAM,KAAK,aAAaE,EAAK,KAAK,YAAA,CAAa,EAAE,GAC7CA,EAAK,UAAU;AAEjB,cAAMC,IAAgBD,EAAK,SAAS,SAAS,KACzCA,EAAK,SAAS,UAAU,GAAG,EAAE,IAAI,QACjCA,EAAK;AACT,QAAAF,EAAM,KAAK,QAAQG,CAAa,EAAE;AAAA,MACpC;AAAA,IACF;AAGA,IAAIR,EAAM,cACRK,EAAM,KAAK,WAAWL,EAAM,WAAW,KAAK,IAAIA,EAAM,WAAW,MAAM,EAAE,GAIvEA,EAAM,uBAAuB,UAC/BK,EAAM,KAAK,iBAAiBL,EAAM,qBAAqB,OAAO,KAAK,EAAE,GAInEA,EAAM,qBAAqB,UAC7BK,EAAM,KAAK,QAAQL,EAAM,gBAAgB,EAAE,GAG7C,KAAK,QAAQ,YAAYK,EAAM,KAAK;AAAA,CAAI;AAAA,EAC1C;AAAA,EAEQ,aAAaI,GAAmB;AACtC,WAAIA,KAAK,OAAaA,IAAI,KAAK,QAAQ,CAAC,IAAI,MACxCA,KAAK,OAAaA,IAAI,KAAK,QAAQ,CAAC,IAAI,MACxCA,KAAK,OAAaA,IAAI,KAAK,QAAQ,CAAC,IAAI,MACrCA,EAAE,eAAA;AAAA,EACX;AAAA,EAEQ,YAAYC,GAAuB;AACzC,WAAIA,KAAS,OAAaA,IAAQ,KAAK,QAAQ,CAAC,IAAI,QAChDA,KAAS,OAAaA,IAAQ,KAAK,QAAQ,CAAC,IAAI,QAChDA,KAAS,OAAaA,IAAQ,KAAK,QAAQ,CAAC,IAAI,QAC7CA,IAAQ;AAAA,EACjB;AAAA,EAEQ,YAAYC,GAAmB;AACrC,WAAK,SAASA,CAAC,IACX,KAAK,IAAIA,CAAC,KAAK,OAAQ,KAAK,IAAIA,CAAC,IAAI,QAASA,MAAM,IAC/CA,EAAE,cAAc,CAAC,IAEnBA,EAAE,QAAQ,CAAC,IAJOA,EAAE,SAAA;AAAA,EAK7B;AACF;AASO,SAASC,EACdlB,GACAC,GACc;AACd,SAAO,IAAIF,EAAaC,GAAWC,CAAO;AAC5C;AAKO,SAASkB,EAAgBlB,GAAoD;AAClF,QAAMD,IAAY,SAAS,cAAc,sBAAsB;AAC/D,MAAI,CAACA;AACH,mBAAQ,KAAK,sDAAsD,GAC5D;AAGT,QAAMoB,IAAU,IAAIrB,EAAaC,GAAWC,CAAO;AACnD,SAAAmB,EAAQ,KAAA,GACDA;AACT;AClZO,MAAMC,EAAgB;AAAA,EAO3B,YACEC,GACAC,GACAC,GACA;AAVM,IAAAtB,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA,oBAAa;AAOnB,SAAK,QAAQqB,GACb,KAAK,SAASC,GAEd,KAAK,YAAY,SAAS,cAAc,KAAK,GAC7C,KAAK,UAAU,YAAY,yBAC3B,KAAK,qBAAA;AAEL,UAAMC,IAAQ,SAAS,cAAc,KAAK;AAC1C,IAAAA,EAAM,YAAY,iBAClBA,EAAM,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAWtBA,EAAM,UAAU,MAAM,KAAK,OAAA,GAE3B,KAAK,UAAU,SAAS,cAAc,KAAK,GAC3C,KAAK,QAAQ,MAAM,UAAU,QAE7B,KAAK,UAAU,YAAYA,CAAK,GAChC,KAAK,UAAU,YAAY,KAAK,OAAO,GACvCH,EAAO,YAAY,KAAK,SAAS;AAAA,EACnC;AAAA,EAEQ,cAAuB;AAC7B,UAAMI,IAAO,KAAK,MAAM,KAAK,YAAA;AAC7B,WAAOA,EAAK,SAAS,MAAM,KAAKA,EAAK,SAAS,UAAU,KAAKA,EAAK,SAAS,SAAS;AAAA,EACtF;AAAA,EAEQ,uBAA6B;AACnC,UAAMC,IAAS,KAAK,YAAA,GACdC,IAAKD,IAAS,2BAA2B,6BACzCE,IAAQF,IAAS,YAAY,WAC7BG,IAAcH,IAAS,6BAA6B,sBACpDI,IAASJ,IAAS,kCAAkC;AAE1D,SAAK,UAAU,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,oBAKfC,CAAE;AAAA;AAAA;AAAA,0BAGIE,CAAW;AAAA;AAAA,oBAEjBC,CAAM;AAAA,eACXF,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQlB;AAAA,EAEO,OAAOG,GAA0B;AACtC,IAAK,KAAK,eAEV,KAAK,QAAQ,YAAY,IAEzB,KAAK,OAAO,QAAQ,CAACC,MAAM;AACzB,UAAI,CAACA,EAAE,aAAc;AAErB,YAAMC,IAAOD,EAAE,QAAA;AACf,UAAI,CAACC,EAAM;AAGX,YAAMC,IAAqB,CAAA,GACrBC,IAAqB,CAAA;AAC3B,eAASC,IAAI,GAAGA,IAAIH,EAAK,EAAE,QAAQG;AACjC,QAAIH,EAAK,EAAEG,CAAC,KAAKL,EAAW,QAAQE,EAAK,EAAEG,CAAC,KAAKL,EAAW,SAC1DI,EAAS,KAAKF,EAAK,EAAEG,CAAC,CAAC,GACvBF,EAAS,KAAKD,EAAK,EAAEG,CAAC,CAAC;AAI3B,UAAIF,EAAS,WAAW,EAAG;AAE3B,YAAM7B,IAAQgC,EAAeH,CAAQ,GAC/BI,IAAOC,EAAUJ,GAAiBD,CAAe,GACjDM,IAAQR,EAAE,SAAA,GAEVS,IAAO,SAAS,cAAc,KAAK;AACzC,MAAAA,EAAK,MAAM,UAAU;AAAA;AAAA,gCAEK,KAAK,gBAAgB,2BAA2B,kBAAkB;AAAA,SAG5FA,EAAK,YAAY;AAAA;AAAA,iFAE0DD,EAAM,KAAK;AAAA,YAChFR,EAAE,OAAO;AAAA;AAAA;AAAA,uBAGE3B,EAAM,IAAI,cAAc,CAAC,CAAC;AAAA,uBAC1BA,EAAM,IAAI,cAAc,CAAC,CAAC;AAAA,wBACzBA,EAAM,KAAK,cAAc,CAAC,CAAC;AAAA,yBAC1BA,EAAM,KAAK;AAAA,qDACiBiC,EAAK,cAAc,CAAC,CAAC;AAAA;AAAA,SAIpE,KAAK,QAAQ,YAAYG,CAAI;AAAA,IAC/B,CAAC,GAEG,KAAK,QAAQ,cAAc,OAC3B,KAAK,QAAQ,YAAY;AAAA,EAE/B;AAAA,EAEO,SAAe;AACpB,SAAK,aAAa,CAAC,KAAK,YACxB,KAAK,QAAQ,MAAM,UAAU,KAAK,aAAa,UAAU,QACrD,KAAK;AAAA,EAGX;AAAA,EAEO,YAAYnB,GAAyB;AAC1C,SAAK,QAAQA,GACb,KAAK,qBAAA;AAAA,EACP;AAAA,EAEO,UAAgB;AACrB,SAAK,UAAU,OAAA;AAAA,EACjB;AACF;AC5IA,MAAMoB,IAAgC;AAAA,EAClC,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,UAAU,CAAC,IAAI;AAAA,EACf,MAAM,CAAC,SAAS,eAAe,OAAO,YAAY;AACtD;AAUO,SAASC,EAAYC,IAA4B,IAAoC;AACxF,MAAIzB,IAA+B,MAC/Bd,IAAgC,MAEhCwC;AAEJ,SAAO;AAAA,IACH,UAAUH;AAAA,IAEV,OAAOI,GAAqB;AACxB,MAAAD,IAAMC,GAGFF,EAAO,YAAY,OACnBzB,IAAU,IAAIrB,EAAa+C,EAAI,GAAG,WAAW;AAAA,QACzC,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,gBAAgB;AAAA,QAChB,GAAGD;AAAA,MAAA,CACN,GACDzB,EAAQ,KAAA,GAGRA,EAAQ,iBAAiB,MAAM;AAC3B,cAAMI,IAASsB,EAAI,KAAK,aAAA;AAGxB,eAAO;AAAA,UACH,YAHetB,EAAO,OAAO,CAACwB,GAAKf,MAAMe,IAAMf,EAAE,QAAA,EAAU,EAAE,QAAQ,CAAC;AAAA,UAItE,aAAaT,EAAO;AAAA,UACpB,YAAYsB,EAAI,KAAK,cAAA;AAAA,UACrB,kBAAmBA,EAAI,MAAc,OAAO;AAAA,QAAA;AAAA,MAEpD,CAAC,IAIDD,EAAO,kBACPvC,IAAQ,IAAIe;AAAA,QACRyB,EAAI,GAAG;AAAA,QACNA,EAAI,MAAc;AAAA,QAClBA,EAAI,MAAc;AAAA,MAAA;AAAA,IAG/B;AAAA,IAEA,iBAAiB;AACb,MAAI1B,KACAA,EAAQ,YAAA;AAAA,IAEhB;AAAA,IAEA,cAAc6B,GAAMC,GAAyB;AACzC,MAAI9B,KACAA,EAAQ,OAAO;AAAA,QACX,WAAY8B,EAAc,aAAaA,EAAM;AAAA,MAAA,CAChD;AAAA,IAET;AAAA,IAEA,gBAAgBD,GAAM;AAClB,MAAI3C,KACAA,EAAM,OAAOwC,EAAI,KAAK,cAAA,CAAe;AAAA,IAE7C;AAAA,IAEA,UAAUG,GAAqB;AACvB,MAAI7B,MACJA,EAAQ,QAAA,GACRA,IAAU,OAEVd,MACAA,EAAM,QAAA,GACNA,IAAQ;AAAA,IAEhB;AAAA,EAAA;AAER;"}
1
+ {"version":3,"file":"debug.js","sources":["../../src/core/debug/index.ts","../../src/core/ChartStatistics.ts","../../src/plugins/debug/index.ts"],"sourcesContent":["/**\n * Sci Plot - Debug Overlay Module\n * \n * Provides a visual debug overlay showing performance metrics,\n * rendering info, and chart state for development and debugging.\n * \n * @module debug\n */\n\n// ============================================\n// Types\n// ============================================\n\nexport interface DebugStats {\n /** Current frames per second */\n fps: number;\n /** Average frame time in ms */\n frameTime: number;\n /** Total number of points being rendered */\n pointCount: number;\n /** Number of visible series */\n seriesCount: number;\n /** Current view bounds */\n viewBounds: {\n xMin: number;\n xMax: number;\n yMin: number;\n yMax: number;\n };\n /** WebGL/WebGPU renderer info */\n rendererInfo: {\n type: 'webgl' | 'webgpu' | 'unknown';\n vendor?: string;\n renderer?: string;\n };\n /** Memory usage estimate (bytes) */\n memoryEstimate: number;\n /** Number of draw calls per frame */\n drawCalls: number;\n /** Whether GPU downsampling is active */\n downsamplingActive: boolean;\n /** Device pixel ratio */\n devicePixelRatio: number;\n /** Canvas dimensions */\n canvasSize: { width: number; height: number };\n /** Plot area dimensions */\n plotArea: { x: number; y: number; width: number; height: number };\n}\n\nexport interface DebugOverlayOptions {\n /** Show FPS counter (default: true) */\n showFps?: boolean;\n /** Show point count (default: true) */\n showPointCount?: boolean;\n /** Show view bounds (default: true) */\n showBounds?: boolean;\n /** Show renderer info (default: true) */\n showRendererInfo?: boolean;\n /** Show memory estimate (default: true) */\n showMemory?: boolean;\n /** Show draw calls (default: true) */\n showDrawCalls?: boolean;\n /** Position: 'top-left', 'top-right', 'bottom-left', 'bottom-right' */\n position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n /** Background opacity (0-1, default: 0.8) */\n opacity?: number;\n /** Font size in pixels (default: 11) */\n fontSize?: number;\n /** Update interval in ms (default: 250) */\n updateInterval?: number;\n /** Custom CSS class name */\n className?: string;\n}\n\n// ============================================\n// Debug Overlay Implementation\n// ============================================\n\nexport class DebugOverlay {\n private container: HTMLElement;\n private element: HTMLDivElement | null = null;\n private options: Required<DebugOverlayOptions>;\n private visible: boolean = false;\n private updateIntervalId: number | null = null;\n private statsProvider: (() => Partial<DebugStats>) | null = null;\n private lastStats: Partial<DebugStats> = {};\n\n // FPS calculation\n private frameCount: number = 0;\n private lastFpsUpdate: number = 0;\n private currentFps: number = 0;\n private frameTimes: number[] = [];\n\n constructor(container: HTMLElement, options?: DebugOverlayOptions) {\n this.container = container;\n this.options = {\n showFps: true,\n showPointCount: true,\n showBounds: true,\n showRendererInfo: true,\n showMemory: true,\n showDrawCalls: true,\n position: 'top-left',\n opacity: 0.8,\n fontSize: 11,\n updateInterval: 250,\n className: 'velo-plot-debug-overlay',\n ...options,\n };\n }\n\n /**\n * Set the stats provider function\n */\n setStatsProvider(provider: () => Partial<DebugStats>): void {\n this.statsProvider = provider;\n }\n\n /**\n * Record a frame for FPS calculation\n */\n recordFrame(frameTime?: number): void {\n const now = performance.now();\n this.frameCount++;\n\n if (frameTime !== undefined) {\n this.frameTimes.push(frameTime);\n if (this.frameTimes.length > 60) {\n this.frameTimes.shift();\n }\n }\n\n // Update FPS every second\n if (now - this.lastFpsUpdate >= 1000) {\n this.currentFps = Math.round((this.frameCount * 1000) / (now - this.lastFpsUpdate));\n this.frameCount = 0;\n this.lastFpsUpdate = now;\n }\n }\n\n /**\n * Show the debug overlay\n */\n show(): void {\n if (this.visible) return;\n \n this.visible = true;\n this.createElement();\n this.startUpdates();\n }\n\n /**\n * Hide the debug overlay\n */\n hide(): void {\n if (!this.visible) return;\n \n this.visible = false;\n this.stopUpdates();\n this.destroyElement();\n }\n\n /**\n * Toggle visibility\n */\n toggle(): void {\n if (this.visible) {\n this.hide();\n } else {\n this.show();\n }\n }\n\n /**\n * Check if visible\n */\n isVisible(): boolean {\n return this.visible;\n }\n\n /**\n * Update the display with new stats\n */\n update(stats?: Partial<DebugStats>): void {\n if (!this.visible || !this.element) return;\n\n // Merge with provider stats\n const providerStats = this.statsProvider?.() || {};\n this.lastStats = {\n ...this.lastStats,\n ...providerStats,\n ...stats,\n fps: this.currentFps,\n frameTime: this.getAverageFrameTime(),\n };\n\n this.renderStats();\n }\n\n /**\n * Get current stats\n */\n getStats(): Partial<DebugStats> {\n return {\n ...this.lastStats,\n fps: this.currentFps,\n frameTime: this.getAverageFrameTime(),\n };\n }\n\n /**\n * Destroy the overlay\n */\n destroy(): void {\n this.hide();\n this.statsProvider = null;\n }\n\n // ============================================\n // Private Methods\n // ============================================\n\n private createElement(): void {\n if (this.element) return;\n\n this.element = document.createElement('div');\n this.element.className = this.options.className;\n \n // Apply styles\n Object.assign(this.element.style, {\n position: 'absolute',\n zIndex: '9999',\n fontFamily: 'monospace',\n fontSize: `${this.options.fontSize}px`,\n lineHeight: '1.4',\n padding: '8px 12px',\n backgroundColor: `rgba(0, 0, 0, ${this.options.opacity})`,\n color: '#00ff00',\n borderRadius: '4px',\n pointerEvents: 'none',\n userSelect: 'none',\n whiteSpace: 'pre',\n ...this.getPositionStyles(),\n });\n\n this.container.style.position = 'relative';\n this.container.appendChild(this.element);\n }\n\n private destroyElement(): void {\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n this.element = null;\n }\n\n private getPositionStyles(): Partial<CSSStyleDeclaration> {\n switch (this.options.position) {\n case 'top-right':\n return { top: '8px', right: '8px' };\n case 'bottom-left':\n return { bottom: '8px', left: '8px' };\n case 'bottom-right':\n return { bottom: '8px', right: '8px' };\n case 'top-left':\n default:\n return { top: '8px', left: '8px' };\n }\n }\n\n private startUpdates(): void {\n if (this.updateIntervalId !== null) return;\n \n this.updateIntervalId = window.setInterval(() => {\n this.update();\n }, this.options.updateInterval);\n }\n\n private stopUpdates(): void {\n if (this.updateIntervalId !== null) {\n clearInterval(this.updateIntervalId);\n this.updateIntervalId = null;\n }\n }\n\n private getAverageFrameTime(): number {\n if (this.frameTimes.length === 0) return 0;\n const sum = this.frameTimes.reduce((a, b) => a + b, 0);\n return sum / this.frameTimes.length;\n }\n\n private renderStats(): void {\n if (!this.element) return;\n\n const lines: string[] = [];\n const stats = this.lastStats;\n\n // FPS\n if (this.options.showFps && stats.fps !== undefined) {\n const fpsColor = stats.fps >= 55 ? '#00ff00' : stats.fps >= 30 ? '#ffff00' : '#ff4444';\n lines.push(`<span style=\"color:${fpsColor}\">FPS: ${stats.fps}</span>`);\n if (stats.frameTime) {\n lines.push(`Frame: ${stats.frameTime.toFixed(2)}ms`);\n }\n }\n\n // Point count\n if (this.options.showPointCount && stats.pointCount !== undefined) {\n lines.push(`Points: ${this.formatNumber(stats.pointCount)}`);\n }\n\n // Series count\n if (stats.seriesCount !== undefined) {\n lines.push(`Series: ${stats.seriesCount}`);\n }\n\n // Draw calls\n if (this.options.showDrawCalls && stats.drawCalls !== undefined) {\n lines.push(`Draw calls: ${stats.drawCalls}`);\n }\n\n // Memory\n if (this.options.showMemory && stats.memoryEstimate !== undefined) {\n lines.push(`Memory: ${this.formatBytes(stats.memoryEstimate)}`);\n }\n\n // Bounds\n if (this.options.showBounds && stats.viewBounds) {\n const b = stats.viewBounds;\n lines.push(`X: [${this.formatValue(b.xMin)}, ${this.formatValue(b.xMax)}]`);\n lines.push(`Y: [${this.formatValue(b.yMin)}, ${this.formatValue(b.yMax)}]`);\n }\n\n // Renderer info\n if (this.options.showRendererInfo && stats.rendererInfo) {\n const info = stats.rendererInfo;\n lines.push(`Renderer: ${info.type.toUpperCase()}`);\n if (info.renderer) {\n // Truncate long renderer names\n const shortRenderer = info.renderer.length > 30 \n ? info.renderer.substring(0, 27) + '...'\n : info.renderer;\n lines.push(`GPU: ${shortRenderer}`);\n }\n }\n\n // Canvas size\n if (stats.canvasSize) {\n lines.push(`Canvas: ${stats.canvasSize.width}×${stats.canvasSize.height}`);\n }\n\n // Downsampling\n if (stats.downsamplingActive !== undefined) {\n lines.push(`Downsampling: ${stats.downsamplingActive ? 'ON' : 'OFF'}`);\n }\n\n // DPR\n if (stats.devicePixelRatio !== undefined) {\n lines.push(`DPR: ${stats.devicePixelRatio}`);\n }\n\n this.element.innerHTML = lines.join('\\n');\n }\n\n private formatNumber(n: number): string {\n if (n >= 1e9) return (n / 1e9).toFixed(1) + 'B';\n if (n >= 1e6) return (n / 1e6).toFixed(1) + 'M';\n if (n >= 1e3) return (n / 1e3).toFixed(1) + 'K';\n return n.toLocaleString();\n }\n\n private formatBytes(bytes: number): string {\n if (bytes >= 1e9) return (bytes / 1e9).toFixed(2) + ' GB';\n if (bytes >= 1e6) return (bytes / 1e6).toFixed(2) + ' MB';\n if (bytes >= 1e3) return (bytes / 1e3).toFixed(2) + ' KB';\n return bytes + ' B';\n }\n\n private formatValue(v: number): string {\n if (!isFinite(v)) return v.toString();\n if (Math.abs(v) >= 1e6 || (Math.abs(v) < 0.001 && v !== 0)) {\n return v.toExponential(2);\n }\n return v.toFixed(3);\n }\n}\n\n// ============================================\n// Convenience Functions\n// ============================================\n\n/**\n * Create a debug overlay for a chart container\n */\nexport function createDebugOverlay(\n container: HTMLElement,\n options?: DebugOverlayOptions\n): DebugOverlay {\n return new DebugOverlay(container, options);\n}\n\n/**\n * Quick enable debug mode (attaches to first chart container found)\n */\nexport function enableDebugMode(options?: DebugOverlayOptions): DebugOverlay | null {\n const container = document.querySelector('.velo-plot-container') as HTMLElement;\n if (!container) {\n console.warn('[SciPlot] No chart container found for debug overlay');\n return null;\n }\n \n const overlay = new DebugOverlay(container, options);\n overlay.show();\n return overlay;\n}\n","/**\n * ChartStatistics - In-chart statistics panel\n * \n * Displays real-time statistics (Min, Max, Mean, StdDev, Area) \n * for the visible data range of active series.\n */\n\nimport { ChartTheme } from \"../theme\";\nimport { Series } from \"./Series\";\nimport { calculateStats, integrate } from \"../plugins/analysis\";\nimport { Bounds } from \"../types\";\n\nexport class ChartStatistics {\n private container: HTMLDivElement;\n private content: HTMLDivElement;\n private theme: ChartTheme;\n private series: Map<string, Series>;\n private isExpanded = false;\n\n constructor(\n parent: HTMLElement,\n theme: ChartTheme,\n series: Map<string, Series>\n ) {\n this.theme = theme;\n this.series = series;\n\n this.container = document.createElement(\"div\");\n this.container.className = \"velo-plot-stats-panel\";\n this.updateContainerStyle();\n\n const title = document.createElement(\"div\");\n title.innerHTML = \"📊 Statistics\";\n title.style.cssText = `\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n `;\n title.onclick = () => this.toggle();\n\n this.content = document.createElement(\"div\");\n this.content.style.display = \"none\";\n \n this.container.appendChild(title);\n this.container.appendChild(this.content);\n parent.appendChild(this.container);\n }\n\n private isDarkTheme(): boolean {\n const name = this.theme.name.toLowerCase();\n return name.includes(\"dark\") || name.includes(\"midnight\") || name.includes(\"electro\");\n }\n\n private updateContainerStyle(): void {\n const isDark = this.isDarkTheme();\n const bg = isDark ? \"rgba(15, 23, 42, 0.85)\" : \"rgba(255, 255, 255, 0.95)\";\n const color = isDark ? \"#f1f5f9\" : \"#1e293b\";\n const borderColor = isDark ? \"rgba(255, 255, 255, 0.1)\" : \"rgba(0, 0, 0, 0.1)\";\n const shadow = isDark ? \"0 4px 12px rgba(0, 0, 0, 0.5)\" : \"0 4px 12px rgba(0, 0, 0, 0.1)\";\n\n this.container.style.cssText = `\n position: absolute;\n bottom: 8px;\n right: 8px;\n width: 240px;\n background: ${bg};\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n border: 1px solid ${borderColor};\n border-radius: 8px;\n box-shadow: ${shadow};\n color: ${color};\n font-family: system-ui, -apple-system, sans-serif;\n padding: 8px 12px;\n z-index: 90;\n transition: all 0.3s ease;\n font-size: 12px;\n pointer-events: auto;\n `;\n }\n\n public update(viewBounds: Bounds): void {\n if (!this.isExpanded) return;\n\n this.content.innerHTML = \"\";\n \n this.series.forEach((s) => {\n if (!s.getVisible()) return;\n\n const data = s.getData();\n if (!data) return;\n\n // Filter data in visible range\n const visibleY: number[] = [];\n const visibleX: number[] = [];\n for (let i = 0; i < data.x.length; i++) {\n if (data.x[i] >= viewBounds.xMin && data.x[i] <= viewBounds.xMax) {\n visibleX.push(data.x[i]);\n visibleY.push(data.y[i]);\n }\n }\n\n if (visibleY.length === 0) return;\n\n const stats = calculateStats(visibleY);\n const area = integrate(visibleX as any, visibleY as any);\n const style = s.getStyle();\n\n const item = document.createElement(\"div\");\n item.style.cssText = `\n padding: 8px 0;\n border-top: 1px solid ${this.isDarkTheme() ? \"rgba(255,255,255,0.05)\" : \"rgba(0,0,0,0.05)\"};\n `;\n\n item.innerHTML = `\n <div style=\"display: flex; align-items: center; gap: 6px; margin-bottom: 4px; font-weight: 600;\">\n <div style=\"width: 8px; height: 8px; border-radius: 2px; background: ${style.color}\"></div>\n ${s.getId()}\n </div>\n <div style=\"display: grid; grid-template-columns: 1fr 1fr; gap: 4px; opacity: 0.9; font-size: 11px;\">\n <span>Min: ${stats.min.toExponential(3)}</span>\n <span>Max: ${stats.max.toExponential(3)}</span>\n <span>Mean: ${stats.mean.toExponential(3)}</span>\n <span>Count: ${stats.count}</span>\n <span style=\"grid-column: span 2;\">Area: ${area.toExponential(4)}</span>\n </div>\n `;\n\n this.content.appendChild(item);\n });\n\n if (this.content.innerHTML === \"\") {\n this.content.innerHTML = \"<div style='opacity: 0.5; font-style: italic;'>No series visible in range</div>\";\n }\n }\n\n public toggle(): void {\n this.isExpanded = !this.isExpanded;\n this.content.style.display = this.isExpanded ? \"block\" : \"none\";\n if (this.isExpanded) {\n // Redraw immediately will be handled by the chart's next render\n }\n }\n\n public updateTheme(theme: ChartTheme): void {\n this.theme = theme;\n this.updateContainerStyle();\n }\n\n public destroy(): void {\n this.container.remove();\n }\n}\n","/**\n * SciPlot Engine - Debug Overlay Plugin\n * \n * Provides performance metrics and debugging information.\n * \n * @module plugins/debug\n */\n\nexport * from \"../../core/debug\";\nimport type { PluginManifest, ChartPlugin, PluginContext, AfterRenderEvent } from \"../types\";\n\nexport interface PluginDebugConfig extends Partial<DebugOverlayOptions> {\n /** Show FPS counter */\n showFPS?: boolean;\n /** Show data stats */\n showDataStats?: boolean;\n}\n\nconst manifestDebug: PluginManifest = {\n name: \"velo-plot-debug\",\n version: \"1.0.0\",\n description: \"Performance monitoring and debugging overlay for velo-plot\",\n provides: [\"ui\"],\n tags: [\"debug\", \"performance\", \"fps\", \"monitoring\"],\n};\n\nimport { DebugOverlay, DebugOverlayOptions } from \"../../core/debug\";\nimport { ChartStatistics } from \"../../core/ChartStatistics\";\n\n/**\n * SciPlot Debug Plugin\n * \n * Adds a useful overlay with real-time performance metrics and debugging info.\n */\nexport function PluginDebug(config: PluginDebugConfig = {}): ChartPlugin<PluginDebugConfig> {\n let overlay: DebugOverlay | null = null;\n let stats: ChartStatistics | null = null;\n\n let ctx: PluginContext;\n\n return {\n manifest: manifestDebug,\n\n onInit(pCtx: PluginContext) {\n ctx = pCtx;\n\n // Initialize FPS/Performance overlay\n if (config.showFPS !== false) {\n overlay = new DebugOverlay(ctx.ui.container, {\n showFps: true,\n showMemory: true,\n showPointCount: true,\n updateInterval: 500,\n ...config\n });\n overlay.show();\n\n // Set stats provider for more detailed info\n overlay.setStatsProvider(() => {\n const series = ctx.data.getAllSeries();\n const pointCount = series.reduce((sum, s) => sum + s.getData().x.length, 0);\n\n return {\n pointCount,\n seriesCount: series.length,\n viewBounds: ctx.data.getViewBounds(),\n devicePixelRatio: (ctx.chart as any).dpr || 1,\n };\n });\n }\n\n // Initialize data statistics panel\n if (config.showDataStats) {\n stats = new ChartStatistics(\n ctx.ui.container,\n (ctx.chart as any).theme,\n (ctx.chart as any).series\n );\n }\n },\n\n onBeforeRender() {\n if (overlay) {\n overlay.recordFrame();\n }\n },\n\n onAfterRender(_ctx, event: AfterRenderEvent) {\n if (overlay) {\n overlay.update({\n frameTime: (event as any).frameTime || event.renderTime,\n });\n }\n },\n\n onRenderOverlay(_ctx) {\n if (stats) {\n stats.update(ctx.data.getViewBounds());\n }\n },\n\n onDestroy(_ctx: PluginContext) {\n if (overlay) {\n overlay.destroy();\n overlay = null;\n }\n if (stats) {\n stats.destroy();\n stats = null;\n }\n }\n };\n}\n\nexport { DebugOverlay };\nexport default PluginDebug;\n"],"names":["DebugOverlay","container","options","__publicField","provider","frameTime","now","stats","providerStats","_a","a","b","lines","fpsColor","info","shortRenderer","n","bytes","v","createDebugOverlay","enableDebugMode","overlay","ChartStatistics","parent","theme","series","title","name","isDark","bg","color","borderColor","shadow","viewBounds","s","data","visibleY","visibleX","i","calculateStats","area","integrate","style","item","manifestDebug","PluginDebug","config","ctx","pCtx","sum","_ctx","event"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { ChartPlugin } from '../types';
2
+
3
+ export type DrawingMode = "none" | "pan" | "trendline" | "horizontal" | "vertical" | "rectangle";
4
+ export interface PluginDrawingToolsConfig {
5
+ /** Default stroke color */
6
+ color?: string;
7
+ }
8
+ export interface DrawingToolsAPI {
9
+ setMode(mode: DrawingMode): void;
10
+ getMode(): DrawingMode;
11
+ undo(): boolean;
12
+ redo(): boolean;
13
+ clear(): void;
14
+ }
15
+ export declare function PluginDrawingTools(config?: PluginDrawingToolsConfig): ChartPlugin<PluginDrawingToolsConfig>;
16
+ export default PluginDrawingTools;
@@ -0,0 +1 @@
1
+ export * from './forecasting/index'