velo-plot 2.20.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (287) hide show
  1. package/README.md +26 -12
  2. package/dist/ChartCore-AnR_3Xkb.js +7338 -0
  3. package/dist/ChartCore-AnR_3Xkb.js.map +1 -0
  4. package/dist/GpuChartRenderer-Dxc0hrQA.js +75 -0
  5. package/dist/GpuChartRenderer-Dxc0hrQA.js.map +1 -0
  6. package/dist/{index.core-COREBDNq.js → PluginRegistry-CzMHebYP.js} +24 -38
  7. package/dist/PluginRegistry-CzMHebYP.js.map +1 -0
  8. package/dist/a11y-Bw6urYpr.js +105 -0
  9. package/dist/a11y-Bw6urYpr.js.map +1 -0
  10. package/dist/angular/hooks-entry.d.ts +1 -0
  11. package/dist/angular/hooks.d.ts +26 -0
  12. package/dist/angular/index.d.ts +8 -0
  13. package/dist/angular/velo-plot.component.d.ts +46 -0
  14. package/dist/angular-hooks.d.ts +1 -0
  15. package/dist/angular-hooks.js +9 -0
  16. package/dist/angular-hooks.js.map +1 -0
  17. package/dist/angular.d.ts +1 -0
  18. package/dist/angular.js +166 -0
  19. package/dist/angular.js.map +1 -0
  20. package/dist/assets/indicator.worker-bv0zC4EX.js.map +1 -1
  21. package/dist/astro/StackedPlot.astro +19 -0
  22. package/dist/astro/VeloPlot.astro +23 -0
  23. package/dist/{axisFormat-CzumxpCL.js → axisFormat-Sz4WIJfQ.js} +2 -2
  24. package/dist/{axisFormat-CzumxpCL.js.map → axisFormat-Sz4WIJfQ.js.map} +1 -1
  25. package/dist/bindings/shared/a11y.d.ts +26 -0
  26. package/dist/bindings/shared/chartLifecycle.d.ts +16 -0
  27. package/dist/bindings/shared/chartSyncBridge.d.ts +8 -0
  28. package/dist/bindings/shared/dimensions.d.ts +1 -0
  29. package/dist/bindings/shared/index.d.ts +9 -0
  30. package/dist/bindings/shared/indicatorBridge.d.ts +11 -0
  31. package/dist/bindings/shared/optionsSync.d.ts +7 -0
  32. package/dist/bindings/shared/seriesDiff.d.ts +8 -0
  33. package/dist/bindings/shared/stackedSync.d.ts +9 -0
  34. package/dist/bindings/shared/types.d.ts +46 -0
  35. package/dist/bindings/test-utils/index.d.ts +35 -0
  36. package/dist/bindings/test-utils/mockLifecycle.d.ts +120 -0
  37. package/dist/bindings/test-utils/vitestSveltePlugin.d.ts +3 -0
  38. package/dist/chartSyncBridge-D_rCtbFq.js +58 -0
  39. package/dist/chartSyncBridge-D_rCtbFq.js.map +1 -0
  40. package/dist/core/Chart.d.ts +1 -1
  41. package/dist/core/ChartStatistics.d.ts +1 -1
  42. package/dist/core/InteractionManager.d.ts +7 -1
  43. package/dist/core/OverlayRenderer.d.ts +5 -0
  44. package/dist/core/annotations/types.d.ts +1 -1
  45. package/dist/core/chart/ChartCore.d.ts +14 -19
  46. package/dist/core/chart/ChartFeatureHooks.d.ts +7 -0
  47. package/dist/core/chart/chartExportPatch.d.ts +2 -0
  48. package/dist/core/chart/overlaySeriesRegistry.d.ts +7 -0
  49. package/dist/core/chart/series/SeriesActions.d.ts +1 -0
  50. package/dist/core/chart/series/SeriesBufferLite.d.ts +13 -0
  51. package/dist/core/chart/series/seriesOptionsRegistry.d.ts +8 -0
  52. package/dist/core/chart/series/seriesTypeRegistry.d.ts +5 -0
  53. package/dist/core/chart/types.d.ts +1 -1
  54. package/dist/core/clipboard/index.d.ts +1 -1
  55. package/dist/core/debug/index.d.ts +1 -1
  56. package/dist/core/keybindings/index.d.ts +1 -1
  57. package/dist/core/loading/index.d.ts +1 -1
  58. package/dist/core/locale/index.d.ts +1 -1
  59. package/dist/core/stacked/paneResize.d.ts +3 -0
  60. package/dist/core/stacked/types.d.ts +10 -0
  61. package/dist/core/theme-editor/index.d.ts +1 -1
  62. package/dist/createStackedChart-DqcLCFGS.js +1338 -0
  63. package/dist/createStackedChart-DqcLCFGS.js.map +1 -0
  64. package/dist/examples/PluginDemonstration.d.ts +1 -1
  65. package/dist/hooks-DH-3bewj.js +69 -0
  66. package/dist/hooks-DH-3bewj.js.map +1 -0
  67. package/dist/{index-BBpJwOct.js → index-0InEyj0q.js} +119 -121
  68. package/dist/index-0InEyj0q.js.map +1 -0
  69. package/dist/{index-qunX30Xu.js → index-B7PTX94B.js} +2133 -2133
  70. package/dist/index-B7PTX94B.js.map +1 -0
  71. package/dist/{index-BMiZoKmm.js → index-BgrvqltV.js} +67 -67
  72. package/dist/index-BgrvqltV.js.map +1 -0
  73. package/dist/{index-DoYxf1cV.js → index-CWxIHdwX.js} +38 -98
  74. package/dist/index-CWxIHdwX.js.map +1 -0
  75. package/dist/index-CaXWSOTk.js.map +1 -1
  76. package/dist/{mockDatafeed-927foCM4.js → index-Cv6ZDLWf.js} +227 -217
  77. package/dist/index-Cv6ZDLWf.js.map +1 -0
  78. package/dist/index-Dag88bW4.js.map +1 -1
  79. package/dist/index-qhscKTDy.js.map +1 -1
  80. package/dist/index.core.d.ts +9 -7
  81. package/dist/index.d.ts +2 -15
  82. package/dist/indicators--eJGmVox.js.map +1 -1
  83. package/dist/optionsSync-QUiN4Inw.js +119 -0
  84. package/dist/optionsSync-QUiN4Inw.js.map +1 -0
  85. package/dist/plugins/3d/index.d.ts +2 -2
  86. package/dist/plugins/3d.d.ts +2 -2
  87. package/dist/plugins/3d.js +3 -1
  88. package/dist/plugins/3d.js.map +1 -1
  89. package/dist/plugins/analysis/index.d.ts +1 -1
  90. package/dist/plugins/analysis/indicators.d.ts +1 -1
  91. package/dist/plugins/analysis.d.ts +2 -2
  92. package/dist/plugins/analysis.js +2 -2
  93. package/dist/plugins/analysis.js.map +1 -1
  94. package/dist/plugins/annotations/index.d.ts +1 -1
  95. package/dist/plugins/annotations.d.ts +2 -2
  96. package/dist/plugins/annotations.js.map +1 -1
  97. package/dist/plugins/anomaly-detection.js +1 -1
  98. package/dist/plugins/anomaly-detection.js.map +1 -1
  99. package/dist/plugins/broken-axis.d.ts +2 -2
  100. package/dist/plugins/builtins/crosshair/CrosshairPlugin.d.ts +1 -1
  101. package/dist/plugins/builtins/index.d.ts +1 -1
  102. package/dist/plugins/caching.d.ts +2 -2
  103. package/dist/plugins/clipboard/index.d.ts +2 -2
  104. package/dist/plugins/clipboard.d.ts +2 -2
  105. package/dist/plugins/clipboard.js.map +1 -1
  106. package/dist/plugins/context-menu/index.d.ts +1 -1
  107. package/dist/plugins/context-menu.d.ts +2 -2
  108. package/dist/plugins/context-menu.js +1 -1
  109. package/dist/plugins/context-menu.js.map +1 -1
  110. package/dist/plugins/createPlugin.d.ts +8 -0
  111. package/dist/plugins/data-export/index.d.ts +1 -1
  112. package/dist/plugins/data-export.d.ts +2 -2
  113. package/dist/plugins/data-export.js +2 -2
  114. package/dist/plugins/data-export.js.map +1 -1
  115. package/dist/plugins/data-transform.d.ts +2 -2
  116. package/dist/plugins/data-transform.js +19 -19
  117. package/dist/plugins/data-transform.js.map +1 -1
  118. package/dist/plugins/debug/index.d.ts +2 -2
  119. package/dist/plugins/debug.d.ts +2 -2
  120. package/dist/plugins/debug.js +33 -33
  121. package/dist/plugins/debug.js.map +1 -1
  122. package/dist/plugins/forecasting/index.d.ts +1 -1
  123. package/dist/plugins/forecasting.js.map +1 -1
  124. package/dist/plugins/gpu/index.d.ts +2 -2
  125. package/dist/plugins/gpu.d.ts +2 -2
  126. package/dist/plugins/gpu.js +2033 -209
  127. package/dist/plugins/gpu.js.map +1 -1
  128. package/dist/plugins/i18n/index.d.ts +2 -2
  129. package/dist/plugins/i18n.d.ts +2 -2
  130. package/dist/plugins/i18n.js +286 -23
  131. package/dist/plugins/i18n.js.map +1 -1
  132. package/dist/plugins/index.d.ts +1 -1
  133. package/dist/plugins/keyboard.d.ts +2 -2
  134. package/dist/plugins/keyboard.js +65 -5
  135. package/dist/plugins/keyboard.js.map +1 -1
  136. package/dist/plugins/latex.js +766 -207
  137. package/dist/plugins/latex.js.map +1 -1
  138. package/dist/plugins/lazy-load.d.ts +2 -2
  139. package/dist/plugins/loading/index.d.ts +2 -3
  140. package/dist/plugins/loading.d.ts +2 -2
  141. package/dist/plugins/loading.js +3 -4
  142. package/dist/plugins/ml-integration.d.ts +2 -2
  143. package/dist/plugins/ml-integration.js +5 -5
  144. package/dist/plugins/ml-integration.js.map +1 -1
  145. package/dist/plugins/offscreen.d.ts +2 -2
  146. package/dist/plugins/offscreen.js +11 -10
  147. package/dist/plugins/offscreen.js.map +1 -1
  148. package/dist/plugins/pattern-recognition.d.ts +2 -2
  149. package/dist/plugins/pattern-recognition.js +1 -1
  150. package/dist/plugins/pattern-recognition.js.map +1 -1
  151. package/dist/plugins/radar.d.ts +2 -2
  152. package/dist/plugins/regression.d.ts +2 -2
  153. package/dist/plugins/regression.js +255 -257
  154. package/dist/plugins/regression.js.map +1 -1
  155. package/dist/plugins/roi.js +9 -9
  156. package/dist/plugins/roi.js.map +1 -1
  157. package/dist/plugins/snapshot/index.d.ts +1 -1
  158. package/dist/plugins/snapshot/types.d.ts +1 -1
  159. package/dist/plugins/snapshot.d.ts +2 -2
  160. package/dist/plugins/snapshot.js.map +1 -1
  161. package/dist/plugins/streaming/index.d.ts +2 -2
  162. package/dist/plugins/streaming.d.ts +2 -2
  163. package/dist/plugins/streaming.js +1 -1
  164. package/dist/plugins/sync/index.d.ts +3 -2
  165. package/dist/plugins/sync.d.ts +2 -2
  166. package/dist/plugins/sync.js.map +1 -1
  167. package/dist/plugins/theme-editor/index.d.ts +1 -1
  168. package/dist/plugins/theme-editor.d.ts +2 -2
  169. package/dist/plugins/tools/index.d.ts +1 -1
  170. package/dist/plugins/tools/tooltip/index.d.ts +1 -1
  171. package/dist/plugins/tools.d.ts +2 -2
  172. package/dist/plugins/tools.js +1 -1
  173. package/dist/plugins/types.d.ts +1 -1
  174. package/dist/plugins/video-recorder.d.ts +2 -2
  175. package/dist/plugins/virtualization.d.ts +2 -2
  176. package/dist/plugins/virtualization.js +1 -1
  177. package/dist/pool-DZ8shSqv.js +109 -0
  178. package/dist/pool-DZ8shSqv.js.map +1 -0
  179. package/dist/react/StackedPlot.d.ts +31 -0
  180. package/dist/react/VeloPlot.d.ts +29 -0
  181. package/dist/react/index.d.ts +25 -3
  182. package/dist/react/useChartSync.d.ts +8 -0
  183. package/dist/react/useIndicator.d.ts +12 -0
  184. package/dist/react/useVeloPlot.d.ts +19 -0
  185. package/dist/react.js +325 -24
  186. package/dist/react.js.map +1 -1
  187. package/dist/renderer/NativeWebGLRenderer.d.ts +2 -1
  188. package/dist/renderer/native/NativeWebGLRenderer.d.ts +5 -1
  189. package/dist/renderer/native/draw.d.ts +2 -47
  190. package/dist/renderer/native/drawCore.d.ts +27 -0
  191. package/dist/renderer/native/drawExtended.d.ts +29 -0
  192. package/dist/renderer/native/frameRenderExtended.d.ts +1 -0
  193. package/dist/renderer/native/frameRenderRegistry.d.ts +27 -0
  194. package/dist/renderer/native/programFactoryCore.d.ts +6 -0
  195. package/dist/renderer/native/programFactoryExtended.d.ts +4 -0
  196. package/dist/renderer/native/utils.d.ts +3 -29
  197. package/dist/renderer/native/utilsCore.d.ts +14 -0
  198. package/dist/renderer/native/utilsExtended.d.ts +17 -0
  199. package/dist/renderer/overlaySeriesExtended.d.ts +1 -0
  200. package/dist/renderer/registerExtendedSeries.d.ts +1 -0
  201. package/dist/renderer/registerWebGPU.d.ts +2 -0
  202. package/dist/renderer/seriesBufferExtended.d.ts +4 -0
  203. package/dist/scientific/index.d.ts +44 -0
  204. package/dist/scientific/registerScientific.d.ts +1 -0
  205. package/dist/scientific.d.ts +1 -0
  206. package/dist/scientific.js +91 -0
  207. package/dist/scientific.js.map +1 -0
  208. package/dist/solid/VeloPlot.d.ts +16 -0
  209. package/dist/solid/index.d.ts +13 -0
  210. package/dist/solid/useChartSync.d.ts +6 -0
  211. package/dist/solid/useIndicator.d.ts +11 -0
  212. package/dist/solid/useStackedPlot.d.ts +14 -0
  213. package/dist/solid/useVeloPlot.d.ts +18 -0
  214. package/dist/solid.d.ts +1 -0
  215. package/dist/solid.js +169 -0
  216. package/dist/solid.js.map +1 -0
  217. package/dist/stackedSync-tnrunZMt.js +100 -0
  218. package/dist/stackedSync-tnrunZMt.js.map +1 -0
  219. package/dist/svelte/StackedPlot.svelte +29 -0
  220. package/dist/svelte/StackedPlot.test.ts +114 -0
  221. package/dist/svelte/VeloPlot.svelte +44 -0
  222. package/dist/svelte/VeloPlot.test.ts +105 -0
  223. package/dist/svelte/index.d.ts +11 -0
  224. package/dist/svelte/index.test.ts +20 -0
  225. package/dist/svelte/index.ts +15 -0
  226. package/dist/svelte/useChartSync.d.ts +8 -0
  227. package/dist/svelte/useChartSync.test.ts +49 -0
  228. package/dist/svelte/useChartSync.ts +29 -0
  229. package/dist/svelte/useIndicator.d.ts +13 -0
  230. package/dist/svelte/useIndicator.test.ts +67 -0
  231. package/dist/svelte/useIndicator.ts +43 -0
  232. package/dist/svelte/useStackedPlot.d.ts +16 -0
  233. package/dist/svelte/useStackedPlot.test.ts +76 -0
  234. package/dist/svelte/useStackedPlot.ts +54 -0
  235. package/dist/svelte/useVeloPlot.d.ts +21 -0
  236. package/dist/svelte/useVeloPlot.test.ts +100 -0
  237. package/dist/svelte/useVeloPlot.ts +81 -0
  238. package/dist/svelte.d.ts +1 -0
  239. package/dist/svelte.js +140 -0
  240. package/dist/svelte.js.map +1 -0
  241. package/dist/testing/index.d.ts +1 -1
  242. package/dist/theme/index.d.ts +2 -1
  243. package/dist/trading/index.d.ts +1 -4
  244. package/dist/trading/registerTrading.d.ts +3 -0
  245. package/dist/trading.js +42 -42
  246. package/dist/types.d.ts +4 -4
  247. package/dist/{utils-BK5UUXxj.js → utils-Dx0h0bgQ.js} +9 -9
  248. package/dist/{utils-BK5UUXxj.js.map → utils-Dx0h0bgQ.js.map} +1 -1
  249. package/dist/velo-plot.full.js +2216 -1346
  250. package/dist/velo-plot.full.js.map +1 -1
  251. package/dist/velo-plot.js +33 -28
  252. package/dist/velo-plot.js.map +1 -1
  253. package/dist/vue/StackedPlot.vue.d.ts +48 -0
  254. package/dist/vue/VeloPlot.vue.d.ts +64 -0
  255. package/dist/vue/index.d.ts +250 -0
  256. package/dist/vue/useChartSync.d.ts +52 -0
  257. package/dist/vue/useIndicator.d.ts +23 -0
  258. package/dist/vue/useStackedPlot.d.ts +15 -0
  259. package/dist/vue/useVeloPlot.d.ts +20 -0
  260. package/dist/vue.d.ts +1 -0
  261. package/dist/vue.js +309 -0
  262. package/dist/vue.js.map +1 -0
  263. package/dist/workers/indicatorsAsync.d.ts +2 -0
  264. package/dist/workers/pool.d.ts +9 -0
  265. package/package.json +96 -10
  266. package/dist/ChartCore-ivzLqxVb.js +0 -8350
  267. package/dist/ChartCore-ivzLqxVb.js.map +0 -1
  268. package/dist/SciPlot-CEU4ApgD.js +0 -463
  269. package/dist/SciPlot-CEU4ApgD.js.map +0 -1
  270. package/dist/createStackedChart-DxNW0VkF.js +0 -705
  271. package/dist/createStackedChart-DxNW0VkF.js.map +0 -1
  272. package/dist/gpuRenderer-BpaMYz-k.js +0 -1848
  273. package/dist/gpuRenderer-BpaMYz-k.js.map +0 -1
  274. package/dist/index-BBpJwOct.js.map +0 -1
  275. package/dist/index-BMiZoKmm.js.map +0 -1
  276. package/dist/index-DoYxf1cV.js.map +0 -1
  277. package/dist/index-qunX30Xu.js.map +0 -1
  278. package/dist/index-x4stH3jD.js +0 -282
  279. package/dist/index-x4stH3jD.js.map +0 -1
  280. package/dist/index.core-COREBDNq.js.map +0 -1
  281. package/dist/mockDatafeed-927foCM4.js.map +0 -1
  282. package/dist/pool-15HMCNv8.js +0 -88
  283. package/dist/pool-15HMCNv8.js.map +0 -1
  284. package/dist/react/SciPlot.d.ts +0 -60
  285. package/dist/react/useSciPlot.d.ts +0 -56
  286. package/dist/symbols-DT0eLlpW.js +0 -568
  287. package/dist/symbols-DT0eLlpW.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"regression.js","sources":["../../src/plugins/regression/algorithms.ts","../../src/plugins/regression/index.ts"],"sourcesContent":["/**\n * Regression Plugin - Core Algorithms\n * \n * Implements regression algorithms for scientific curve fitting.\n * Includes linear, polynomial, exponential, and non-linear models.\n * \n * @packageDocumentation\n * @module plugins/regression\n */\n\nimport type {\n RegressionData,\n RegressionResult,\n LinearRegressionConfig,\n PolynomialRegressionConfig,\n ExponentialRegressionConfig,\n GaussianRegressionConfig\n} from './types';\nimport { solveLinearSystem } from '../analysis/math';\n\n// ============================================\n// Utility Functions\n// ============================================\n\nfunction toArray(data: Float32Array | Float64Array | number[]): number[] {\n return Array.from(data);\n}\n\nfunction toFloat32Array(data: number[]): Float32Array {\n return new Float32Array(data);\n}\n\nfunction calculateMean(data: number[]): number {\n return data.reduce((sum, val) => sum + val, 0) / data.length;\n}\n\nfunction calculateVariance(data: number[]): number {\n const mean = calculateMean(data);\n return data.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / data.length;\n}\n\nfunction calculateRSquared(observed: number[], fitted: number[]): number {\n const meanObserved = calculateMean(observed);\n let ssRes = 0;\n let ssTot = 0;\n \n for (let i = 0; i < observed.length; i++) {\n ssRes += Math.pow(observed[i] - fitted[i], 2);\n ssTot += Math.pow(observed[i] - meanObserved, 2);\n }\n \n return 1 - (ssRes / ssTot);\n}\n\nfunction calculateAdjustedRSquared(rSquared: number, n: number, k: number): number {\n return 1 - ((1 - rSquared) * (n - 1)) / (n - k - 1);\n}\n\nfunction calculateRMSE(observed: number[], fitted: number[]): number {\n let sumSquaredErrors = 0;\n for (let i = 0; i < observed.length; i++) {\n sumSquaredErrors += Math.pow(observed[i] - fitted[i], 2);\n }\n return Math.sqrt(sumSquaredErrors / observed.length);\n}\n/*\nfunction _calculateStatistics(data: RegressionData, predictions: Float32Array): { rSquared: number; rmse: number; mae: number; residuals: number[] } {\n const n = data.x.length;\n const yMean = Array.from(data.y).reduce((sum, y) => sum + y, 0) / n;\n \n let ssTotal = 0;\n let ssResidual = 0;\n \n for (let i = 0; i < n; i++) {\n const yActual = data.y[i];\n const yPred = predictions[i];\n \n ssTotal += Math.pow(yActual - yMean, 2);\n ssResidual += Math.pow(yActual - yPred, 2);\n }\n \n const rSquared = 1 - (ssResidual / ssTotal);\n const rmse = Math.sqrt(ssResidual / n);\n const mae = Array.from(data.y).reduce((sum, y, i) => sum + Math.abs(y - predictions[i]), 0) / n;\n \n return {\n rSquared,\n rmse,\n mae,\n residuals: Array.from(data.y).map((y, i) => y - predictions[i])\n };\n}\n*/\n// ============================================\n// Linear Regression\n// ============================================\n\nexport function linearRegression(\n data: RegressionData,\n config: LinearRegressionConfig = {}\n): RegressionResult {\n const startTime = performance.now();\n \n const x = toArray(data.x);\n const y = toArray(data.y);\n const weights = data.weights ? toArray(data.weights) : null;\n const { forceOrigin = false } = config;\n \n const n = x.length;\n \n if (forceOrigin) {\n // Forced through origin: y = bx\n let numerator = 0;\n let denominator = 0;\n \n for (let i = 0; i < n; i++) {\n const weight = weights ? weights[i] : 1;\n numerator += weight * x[i] * y[i];\n denominator += weight * x[i] * x[i];\n }\n \n const slope = numerator / denominator;\n const fittedValues = x.map(xi => slope * xi);\n const residuals = y.map((yi, i) => yi - fittedValues[i]);\n \n const rSquared = calculateRSquared(y, fittedValues);\n const adjustedRSquared = calculateAdjustedRSquared(rSquared, n, 1);\n const rmse = calculateRMSE(y, fittedValues);\n \n return {\n method: 'linear',\n parameters: {\n parameters: [slope],\n uncertainties: [Math.sqrt(denominator / (n * numerator))], // Simplified\n correlationMatrix: [[1]]\n },\n statistics: {\n rSquared,\n adjustedRSquared,\n rmse,\n rss: residuals.reduce((sum, r) => sum + r * r, 0),\n tss: y.reduce((sum, yi) => sum + Math.pow(yi - calculateMean(y), 2), 0),\n n,\n k: 1\n },\n fittedValues: toFloat32Array(fittedValues),\n residuals: toFloat32Array(residuals),\n goodnessOfFit: rSquared > 0.9 ? 'excellent' : rSquared > 0.7 ? 'good' : rSquared > 0.5 ? 'fair' : 'poor',\n converged: true,\n iterations: 1,\n processingTime: performance.now() - startTime\n };\n } else {\n // Standard linear regression: y = ax + b\n let sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0, sumY2 = 0;\n let sumWeights = 0;\n \n for (let i = 0; i < n; i++) {\n const weight = weights ? weights[i] : 1;\n sumX += weight * x[i];\n sumY += weight * y[i];\n sumXY += weight * x[i] * y[i];\n sumX2 += weight * x[i] * x[i];\n sumY2 += weight * y[i] * y[i];\n sumWeights += weight;\n }\n \n const meanX = sumX / sumWeights;\n const meanY = sumY / sumWeights;\n \n const slope = (sumXY - sumWeights * meanX * meanY) / (sumX2 - sumWeights * meanX * meanX);\n const intercept = meanY - slope * meanX;\n \n const fittedValues = x.map(xi => slope * xi + intercept);\n const residuals = y.map((yi, i) => yi - fittedValues[i]);\n \n const rSquared = calculateRSquared(y, fittedValues);\n const adjustedRSquared = calculateAdjustedRSquared(rSquared, n, 2);\n const rmse = calculateRMSE(y, fittedValues);\n \n return {\n method: 'linear',\n parameters: {\n parameters: [slope, intercept],\n uncertainties: [0.1, 0.1], // Simplified\n correlationMatrix: [[1, -0.5], [-0.5, 1]] // Simplified\n },\n statistics: {\n rSquared,\n adjustedRSquared,\n rmse,\n rss: residuals.reduce((sum, r) => sum + r * r, 0),\n tss: y.reduce((sum, yi) => sum + Math.pow(yi - meanY, 2), 0),\n n,\n k: 2\n },\n fittedValues: toFloat32Array(fittedValues),\n residuals: toFloat32Array(residuals),\n goodnessOfFit: rSquared > 0.9 ? 'excellent' : rSquared > 0.7 ? 'good' : rSquared > 0.5 ? 'fair' : 'poor',\n converged: true,\n iterations: 1,\n processingTime: performance.now() - startTime\n };\n }\n}\n\n// ============================================\n// Polynomial Regression\n// ============================================\n\nexport function polynomialRegression(\n data: RegressionData,\n config: PolynomialRegressionConfig\n): RegressionResult {\n const startTime = performance.now();\n \n const x = toArray(data.x);\n const y = toArray(data.y);\n const { degree } = config;\n \n const n = x.length;\n const m = degree + 1; // Number of parameters\n \n // Build Vandermonde matrix\n const X: number[][] = [];\n for (let i = 0; i < n; i++) {\n const row: number[] = [];\n for (let j = 0; j <= degree; j++) {\n row.push(Math.pow(x[i], j));\n }\n X.push(row);\n }\n \n // Solve using least squares (simplified implementation)\n // In practice, would use QR decomposition or SVD\n const parameters = solveLeastSquares(X, y, 0);\n \n const fittedValues = x.map(xi => {\n let value = 0;\n for (let j = 0; j <= degree; j++) {\n value += parameters[j] * Math.pow(xi, j);\n }\n return value;\n });\n \n const residuals = y.map((yi, i) => yi - fittedValues[i]);\n \n const rSquared = calculateRSquared(y, fittedValues);\n const adjustedRSquared = calculateAdjustedRSquared(rSquared, n, m);\n const rmse = calculateRMSE(y, fittedValues);\n \n return {\n method: 'polynomial',\n parameters: {\n parameters,\n uncertainties: new Array(m).fill(0.1), // Simplified\n correlationMatrix: Array(m).fill(0).map(() => Array(m).fill(0)) // Simplified\n },\n statistics: {\n rSquared,\n adjustedRSquared,\n rmse,\n rss: residuals.reduce((sum, r) => sum + r * r, 0),\n tss: y.reduce((sum, yi) => sum + Math.pow(yi - calculateMean(y), 2), 0),\n n,\n k: m\n },\n fittedValues: toFloat32Array(fittedValues),\n residuals: toFloat32Array(residuals),\n goodnessOfFit: rSquared > 0.9 ? 'excellent' : rSquared > 0.7 ? 'good' : rSquared > 0.5 ? 'fair' : 'poor',\n converged: true,\n iterations: 10, // Simplified\n processingTime: performance.now() - startTime\n };\n}\n\n// ============================================\n// Exponential Regression\n// ============================================\n\nexport function exponentialRegression(\n data: RegressionData,\n _config: ExponentialRegressionConfig = {}\n): RegressionResult {\n const startTime = performance.now();\n \n const x = toArray(data.x);\n const y = toArray(data.y);\n \n // Transform to linear: ln(y - offset) = ln(amplitude) + rate * x\n // Need to estimate offset first (simplified)\n let offset = Math.min(...y) - 1;\n \n const transformedY = y.map(yi => {\n const adjusted = yi - offset;\n return adjusted > 0 ? Math.log(adjusted) : 0;\n });\n \n // Linear regression on transformed data\n const linearResult = linearRegression(\n { x, y: transformedY },\n { forceOrigin: false }\n );\n \n const [rate, logAmplitude] = linearResult.parameters.parameters;\n const amplitude = Math.exp(logAmplitude);\n \n const fittedValues = x.map(xi => amplitude * Math.exp(rate * xi) + offset);\n const residuals = y.map((yi, i) => yi - fittedValues[i]);\n \n const rSquared = calculateRSquared(y, fittedValues);\n const adjustedRSquared = calculateAdjustedRSquared(rSquared, x.length, 3);\n const rmse = calculateRMSE(y, fittedValues);\n \n return {\n method: 'exponential',\n parameters: {\n parameters: [amplitude, rate, offset],\n uncertainties: [0.1, 0.01, 0.1], // Simplified\n correlationMatrix: [[1, 0.5, 0.2], [0.5, 1, 0.3], [0.2, 0.3, 1]] // Simplified\n },\n statistics: {\n rSquared,\n adjustedRSquared,\n rmse,\n rss: residuals.reduce((sum, r) => sum + r * r, 0),\n tss: y.reduce((sum, yi) => sum + Math.pow(yi - calculateMean(y), 2), 0),\n n: x.length,\n k: 3\n },\n fittedValues: toFloat32Array(fittedValues),\n residuals: toFloat32Array(residuals),\n goodnessOfFit: rSquared > 0.9 ? 'excellent' : rSquared > 0.7 ? 'good' : rSquared > 0.5 ? 'fair' : 'poor',\n converged: true,\n iterations: 5, // Simplified\n processingTime: performance.now() - startTime\n };\n}\n\n// ============================================\n// Gaussian Regression\n// ============================================\n\nexport function gaussianRegression(\n data: RegressionData,\n _config: GaussianRegressionConfig = {}\n): RegressionResult {\n const startTime = performance.now();\n \n const x = toArray(data.x);\n const y = toArray(data.y);\n \n // Non-linear fitting using simplified gradient descent\n let amplitude = Math.max(...y);\n let mean = x.reduce((sum, xi) => sum + xi, 0) / x.length;\n let std = Math.sqrt(calculateVariance(x));\n let offset = Math.min(...y);\n \n const learningRate = 0.001;\n const maxIterations = 100;\n const tolerance = 1e-6;\n \n for (let iter = 0; iter < maxIterations; iter++) {\n let gradAmplitude = 0, gradMean = 0, gradStd = 0, gradOffset = 0;\n let totalError = 0;\n \n for (let i = 0; i < x.length; i++) {\n const xi = x[i];\n const yi = y[i];\n \n // Gaussian function: A * exp(-((x - μ)² / (2σ²))) + offset\n const exponent = -Math.pow(xi - mean, 2) / (2 * std * std);\n const predicted = amplitude * Math.exp(exponent) + offset;\n const error = yi - predicted;\n totalError += error * error;\n \n // Gradients\n const expTerm = Math.exp(exponent);\n gradAmplitude += error * expTerm;\n gradMean += error * amplitude * expTerm * (xi - mean) / (std * std);\n gradStd += error * amplitude * expTerm * Math.pow(xi - mean, 2) / (Math.pow(std, 3));\n gradOffset += error;\n }\n \n // Update parameters\n amplitude += learningRate * gradAmplitude;\n mean += learningRate * gradMean;\n std += learningRate * gradStd;\n offset += learningRate * gradOffset;\n \n // Ensure std is positive\n std = Math.max(std, 0.01);\n \n if (totalError < tolerance) break;\n }\n \n const fittedValues = x.map(xi => {\n const exponent = -Math.pow(xi - mean, 2) / (2 * std * std);\n return amplitude * Math.exp(exponent) + offset;\n });\n \n const residuals = y.map((yi, i) => yi - fittedValues[i]);\n \n const rSquared = calculateRSquared(y, fittedValues);\n const adjustedRSquared = calculateAdjustedRSquared(rSquared, x.length, 4);\n const rmse = calculateRMSE(y, fittedValues);\n \n return {\n method: 'gaussian',\n parameters: {\n parameters: [amplitude, mean, std, offset],\n uncertainties: [0.1, 0.1, 0.01, 0.1], // Simplified\n correlationMatrix: Array(4).fill(0).map(() => Array(4).fill(0)) // Simplified\n },\n statistics: {\n rSquared,\n adjustedRSquared,\n rmse,\n rss: residuals.reduce((sum, r) => sum + r * r, 0),\n tss: y.reduce((sum, yi) => sum + Math.pow(yi - calculateMean(y), 2), 0),\n n: x.length,\n k: 4\n },\n fittedValues: toFloat32Array(fittedValues),\n residuals: toFloat32Array(residuals),\n goodnessOfFit: rSquared > 0.9 ? 'excellent' : rSquared > 0.7 ? 'good' : rSquared > 0.5 ? 'fair' : 'poor',\n converged: true,\n iterations: maxIterations,\n processingTime: performance.now() - startTime\n };\n}\n\n// ============================================\n// Helper Functions\n// ============================================\n\nfunction solveLeastSquares(X: number[][], y: number[], regularization: number = 0): number[] {\n const n = X.length;\n const m = X[0].length;\n \n // Compute X^T * X\n const XtX: number[][] = Array(m).fill(0).map(() => Array(m).fill(0));\n const Xty: number[] = Array(m).fill(0);\n \n for (let i = 0; i < n; i++) {\n for (let j = 0; j < m; j++) {\n for (let k = 0; k < m; k++) {\n XtX[j][k] += X[i][j] * X[i][k];\n }\n Xty[j] += X[i][j] * y[i];\n }\n }\n \n // Add L2 regularization if needed\n if (regularization > 0) {\n for (let i = 0; i < m; i++) {\n XtX[i][i] += regularization;\n }\n }\n \n // Solve using Gaussian elimination\n return solveLinearSystem(XtX, Xty);\n}","/**\n * Regression Plugin - Main Implementation\n * \n * Provides advanced scientific regression and curve fitting capabilities.\n * Supports multiple regression methods with automatic model selection.\n * \n * @example\n * ```typescript\n * import { PluginRegression } from 'velo-plot/plugins/regression';\n * \n * chart.use(PluginRegression({\n * defaultMethod: 'polynomial',\n * enableAutoSelection: true,\n * modelSelectionCriteria: 'aic',\n * maxIterations: 100\n * }));\n * \n * // Fit polynomial regression\n * const result = await chart.regression.fit('series1', {\n * x: seriesData.x,\n * y: seriesData.y\n * }, 'polynomial', { degree: 3 });\n * \n * console.log(`R² = ${result.statistics.rSquared}`);\n * console.log(`Parameters: ${result.parameters.parameters}`);\n * \n * // Auto-fit best model\n * const bestFit = await chart.regression.autoFit('series1', data);\n * \n * // Visualize fit\n * chart.regression.visualizeFit('series1');\n * ```\n * \n * @packageDocumentation\n * @module plugins/regression\n */\n\nimport type { \n PluginManifest, \n ChartPlugin, \n PluginContext,\n BeforeRenderEvent,\n DataUpdateEvent\n} from '../types';\n\nimport type {\n PluginRegressionConfig,\n RegressionAPI,\n RegressionResult,\n RegressionData,\n RegressionMethod,\n LinearRegressionConfig,\n PolynomialRegressionConfig,\n ExponentialRegressionConfig,\n GaussianRegressionConfig,\n RegressionCompletedEvent,\n RegressionFailedEvent,\n ModelSelectedEvent,\n RegressionStatistics\n} from './types';\n\nimport {\n linearRegression,\n polynomialRegression,\n exponentialRegression,\n gaussianRegression\n} from './algorithms';\n\n// ============================================\n// Plugin Manifest\n// ============================================\n\nconst manifestRegression: PluginManifest = {\n name: 'regression',\n version: '1.0.0',\n description: 'Advanced scientific regression and curve fitting',\n author: 'Sci Plot Team',\n provides: ['regression', 'curve-fitting', 'scientific-analysis']\n};\n\n// ============================================\n// Default Configuration\n// ============================================\n\nconst DEFAULT_CONFIG: Required<PluginRegressionConfig> = {\n defaultMethod: 'linear',\n enableAutoSelection: false,\n modelSelectionCriteria: 'aic',\n enableWeightedRegression: false,\n enableRobustRegression: false,\n robustMethod: 'huber',\n maxIterations: 100,\n convergenceTolerance: 1e-6,\n defaultConfidenceLevel: 0.95,\n enableParallelProcessing: false,\n parallelChunkSize: 1000\n};\n\n// ============================================\n// Regression Plugin Implementation\n// ============================================\n\nexport function PluginRegression(\n userConfig: Partial<PluginRegressionConfig> = {}\n): ChartPlugin<PluginRegressionConfig> {\n const config = { ...DEFAULT_CONFIG, ...userConfig };\n let ctx: PluginContext | null = null;\n \n // Results storage\n const regressionResults = new Map<string, RegressionResult[]>();\n const realtimeSeries = new Set<string>();\n const debounceTimers = new Map<string, any>();\n \n // ============================================\n // Core Regression Methods\n // ============================================\n \n async function fit(\n seriesId: string,\n data: RegressionData,\n method: RegressionMethod = config.defaultMethod,\n methodConfig: any = {}\n ): Promise<RegressionResult> {\n try {\n // Clear previous visualization before fitting new model\n api.hideVisualization(seriesId);\n \n let result: RegressionResult;\n \n switch (method) {\n case 'linear':\n result = linearRegression(data, methodConfig as LinearRegressionConfig);\n break;\n case 'polynomial':\n result = polynomialRegression(data, methodConfig as PolynomialRegressionConfig);\n break;\n case 'exponential':\n result = exponentialRegression(data, methodConfig as ExponentialRegressionConfig);\n break;\n case 'gaussian':\n result = gaussianRegression(data, methodConfig as GaussianRegressionConfig);\n break;\n case 'logarithmic':\n // Transform y = a * log(x) + b to linear\n const logX = Array.from(data.x).map(xi => Math.log(xi));\n result = linearRegression({ ...data, x: new Float32Array(logX) }, methodConfig as LinearRegressionConfig);\n result.method = 'logarithmic';\n break;\n case 'power':\n // Transform to linear: log(y) = log(a) + b * log(x)\n const logY = Array.from(data.y).map(yi => Math.log(yi));\n const logXPow = Array.from(data.x).map(xi => Math.log(xi));\n result = linearRegression({ ...data, x: new Float32Array(logXPow), y: new Float32Array(logY) }, methodConfig as LinearRegressionConfig);\n result.method = 'power';\n break;\n case 'lorentzian':\n case 'sigmoid':\n case 'custom':\n // For now, fall back to linear for unsupported methods\n result = linearRegression(data, methodConfig as LinearRegressionConfig);\n break;\n default:\n throw new Error(`Unsupported regression method: ${method}`);\n }\n \n // Clear and store new result (replace, don't accumulate)\n regressionResults.set(seriesId, [result]);\n \n // Emit event\n if (ctx) {\n ctx.events.emit('regression:completed', {\n result,\n seriesId,\n method,\n timestamp: Date.now()\n } as RegressionCompletedEvent);\n }\n \n ctx?.log.info(`Regression completed for ${seriesId}: ${method} (R² = ${result.statistics.rSquared.toFixed(3)})`);\n \n return result;\n } catch (error) {\n if (ctx) {\n ctx.events.emit('regression:failed', {\n error: error as Error,\n seriesId,\n method,\n reason: `Fitting failed: ${error}`,\n timestamp: Date.now()\n } as RegressionFailedEvent);\n }\n \n throw error;\n }\n }\n \n async function fitAndCompare(\n seriesId: string,\n data: RegressionData,\n methods: RegressionMethod[],\n configs?: any[]\n ): Promise<RegressionResult[]> {\n const results: RegressionResult[] = [];\n \n for (let i = 0; i < methods.length; i++) {\n const method = methods[i];\n const methodConfig = configs ? configs[i] : {};\n \n try {\n const result = await fit(seriesId, data, method, methodConfig);\n results.push(result);\n } catch (error) {\n ctx?.log.warn(`Regression failed for ${method}: ${error}`);\n }\n }\n \n // Sort by criteria\n const criteria = config.modelSelectionCriteria;\n results.sort((a, b) => {\n switch (criteria) {\n case 'aic':\n return (a.statistics.aic || 0) - (b.statistics.aic || 0);\n case 'bic':\n return (a.statistics.bic || 0) - (b.statistics.bic || 0);\n case 'adjusted-r2':\n return b.statistics.adjustedRSquared - a.statistics.adjustedRSquared;\n default:\n return b.statistics.rSquared - a.statistics.rSquared;\n }\n });\n \n return results;\n }\n \n async function autoFit(\n seriesId: string,\n data: RegressionData,\n candidateMethods: RegressionMethod[] = ['linear', 'polynomial', 'exponential', 'gaussian']\n ): Promise<RegressionResult> {\n const configs = candidateMethods.map(method => {\n switch (method) {\n case 'polynomial':\n return { degree: 2 } as PolynomialRegressionConfig;\n case 'exponential':\n return {} as ExponentialRegressionConfig;\n case 'gaussian':\n return {} as GaussianRegressionConfig;\n default:\n return {} as LinearRegressionConfig;\n }\n });\n \n const results = await fitAndCompare(seriesId, data, candidateMethods, configs);\n \n if (results.length === 0) {\n throw new Error('No regression methods succeeded');\n }\n \n const bestResult = results[0];\n \n // Emit model selection event\n if (ctx) {\n ctx.events.emit('model:selected', {\n selectedMethod: bestResult.method,\n candidateResults: results,\n selectionCriteria: config.modelSelectionCriteria,\n seriesId,\n timestamp: Date.now()\n } as ModelSelectedEvent);\n }\n \n ctx?.log.info(`Auto-fit selected ${bestResult.method} for ${seriesId} (R² = ${bestResult.statistics.rSquared.toFixed(3)})`);\n \n return bestResult;\n }\n \n // ============================================\n // API Implementation\n // ============================================\n \n const api: RegressionAPI & Record<string, unknown> = {\n fit,\n \n fitAndCompare,\n \n autoFit,\n \n getResults(seriesId: string): RegressionResult[] {\n return regressionResults.get(seriesId) || [];\n },\n \n clearResults(seriesId: string): void {\n regressionResults.delete(seriesId);\n ctx?.log.info(`Regression results cleared for series: ${seriesId}`);\n },\n \n predict(\n seriesId: string,\n xValues: Float32Array | Float64Array | number[],\n resultIndex = 0\n ): Float32Array {\n const results = regressionResults.get(seriesId);\n if (!results || results.length === 0) {\n throw new Error(`No regression results found for series: ${seriesId}`);\n }\n \n const result = results[Math.min(resultIndex, results.length - 1)];\n const x = Array.from(xValues);\n const params = result.parameters.parameters;\n \n const predictions = x.map(xi => {\n switch (result.method) {\n case 'linear':\n return params[0] * xi + (params[1] || 0);\n case 'polynomial':\n let value = 0;\n for (let j = 0; j < params.length; j++) {\n value += params[j] * Math.pow(xi, j);\n }\n return value;\n case 'exponential':\n return params[0] * Math.exp(params[1] * xi) + (params[2] || 0);\n case 'gaussian':\n const exponent = -Math.pow(xi - params[1], 2) / (2 * params[2] * params[2]);\n return params[0] * Math.exp(exponent) + (params[3] || 0);\n case 'logarithmic':\n return params[0] * Math.log(xi) + (params[1] || 0);\n case 'power':\n return params[0] * Math.pow(xi, params[1]);\n default:\n return 0;\n }\n });\n \n return new Float32Array(predictions);\n },\n \n getConfidenceIntervals(\n seriesId: string,\n xValues: Float32Array | Float64Array | number[],\n _level = config.defaultConfidenceLevel,\n resultIndex = 0\n ): { lower: Float32Array; upper: Float32Array } {\n // Simplified confidence intervals\n const predictions = this.predict(seriesId, xValues, resultIndex);\n const margin = 0.1; // Simplified margin\n \n const lower = predictions.map(p => p - margin);\n const upper = predictions.map(p => p + margin);\n \n return {\n lower: new Float32Array(lower),\n upper: new Float32Array(upper)\n };\n },\n \n evaluate(seriesId: string, data: RegressionData, resultIndex = 0): RegressionStatistics {\n const results = regressionResults.get(seriesId);\n if (!results || results.length === 0) {\n throw new Error(`No regression results found for series: ${seriesId}`);\n }\n \n const result = results[Math.min(resultIndex, results.length - 1)];\n const x = Array.from(data.x);\n const y = Array.from(data.y);\n \n // Use existing model to predict\n const predictions = api.predict(seriesId, x, resultIndex);\n const predArray = Array.from(predictions);\n \n const rSquared = calculateRSquared(y, predArray);\n const adjustedRSquared = calculateAdjustedRSquared(rSquared, y.length, result.parameters.parameters.length);\n const rmse = calculateRMSE(y, predArray);\n \n return {\n rSquared,\n adjustedRSquared,\n rmse,\n rss: y.reduce((sum, yi, i) => sum + Math.pow(yi - predArray[i], 2), 0),\n tss: y.reduce((sum, yi) => sum + Math.pow(yi - calculateMean(y), 2), 0),\n n: y.length,\n k: result.parameters.parameters.length\n };\n },\n \n enableRealtimeFitting(\n seriesId: string,\n method: RegressionMethod = config.defaultMethod,\n methodConfig: any = {}\n ): void {\n realtimeSeries.add(seriesId);\n \n // Run initial fitting\n const chart = ctx?.chart;\n if (chart) {\n const series = chart.getSeries(seriesId);\n if (series) {\n const data = series.getData();\n if (data && data.x.length > 0) {\n fit(seriesId, {\n x: data.x,\n y: data.y\n }, method, methodConfig);\n }\n }\n }\n \n ctx?.log.info(`Real-time regression fitting enabled for series: ${seriesId}`);\n },\n \n disableRealtimeFitting(seriesId: string): void {\n realtimeSeries.delete(seriesId);\n \n // Clear debounce timer\n const timer = debounceTimers.get(seriesId);\n if (timer) {\n clearTimeout(timer);\n debounceTimers.delete(seriesId);\n }\n \n ctx?.log.info(`Real-time regression fitting disabled for series: ${seriesId}`);\n },\n \n getStatistics(seriesId?: string) {\n if (seriesId) {\n const results = regressionResults.get(seriesId) || [];\n const methodsUsed: Record<RegressionMethod, number> = {} as any;\n \n for (const result of results) {\n methodsUsed[result.method] = (methodsUsed[result.method] || 0) + 1;\n }\n \n return {\n totalFittings: results.length,\n methodsUsed,\n averageRSquared: results.length > 0 ? results.reduce((sum, r) => sum + r.statistics.rSquared, 0) / results.length : 0,\n averageProcessingTime: results.length > 0 ? results.reduce((sum, r) => sum + r.processingTime, 0) / results.length : 0\n };\n } else {\n // Global statistics\n let totalFittings = 0;\n const allMethodsUsed: Record<RegressionMethod, number> = {} as any;\n const allRSquared: number[] = [];\n const allProcessingTimes: number[] = [];\n \n for (const results of regressionResults.values()) {\n totalFittings += results.length;\n allRSquared.push(...results.map(r => r.statistics.rSquared));\n allProcessingTimes.push(...results.map(r => r.processingTime));\n \n for (const result of results) {\n allMethodsUsed[result.method] = (allMethodsUsed[result.method] || 0) + 1;\n }\n }\n \n return {\n totalFittings,\n methodsUsed: allMethodsUsed,\n averageRSquared: allRSquared.length > 0 ? allRSquared.reduce((sum, r) => sum + r, 0) / allRSquared.length : 0,\n averageProcessingTime: allProcessingTimes.length > 0 ? allProcessingTimes.reduce((sum, t) => sum + t, 0) / allProcessingTimes.length : 0\n };\n }\n },\n \n updateConfig: (newConfig: Partial<PluginRegressionConfig>) => {\n Object.assign(config, newConfig);\n },\n \n getConfig: () => ({ ...config }),\n \n visualizeFit(seriesId: string, resultIndex = 0): void {\n const chart = ctx?.chart;\n if (!chart) return;\n \n const results = regressionResults.get(seriesId);\n if (!results || results.length === 0) return;\n \n const result = results[Math.min(resultIndex, results.length - 1)];\n const series = chart.getSeries(seriesId);\n if (!series) return;\n \n const data = series.getData();\n if (!data) return;\n \n // Remove existing fit visualization\n this.hideVisualization(seriesId);\n \n // Add fitted curve\n const fitSeriesId = `${seriesId}_fit_${result.method}`;\n const fittedValues = api.predict(seriesId, data.x, resultIndex);\n \n chart.addSeries({\n id: fitSeriesId,\n type: 'line',\n data: {\n x: new Float32Array(Array.from(data.x)),\n y: new Float32Array(fittedValues)\n },\n style: {\n color: '#ff6b6b',\n width: 2,\n opacity: 0.8,\n lineDash: [5, 5]\n }\n });\n \n // Add equation annotation\n const equation = formatEquation(result);\n const annotationId = `${seriesId}_equation_${result.method}`;\n \n chart.addAnnotation({\n id: annotationId,\n type: 'text',\n text: `${result.method.toUpperCase()}: ${equation}\\\\nR² = ${result.statistics.rSquared.toFixed(3)}`,\n x: data.x[0],\n y: Math.max(...Array.from(fittedValues)),\n style: {\n color: '#ff6b6b',\n fontSize: 12,\n backgroundColor: 'rgba(255, 255, 255, 0.9)'\n }\n } as any);\n },\n \n hideVisualization(seriesId: string): void {\n const chart = ctx?.chart;\n if (!chart) return;\n \n // List all possible regression methods to ensure cleanup\n const allMethods: RegressionMethod[] = [\n 'linear', 'polynomial', 'exponential', 'gaussian', \n 'logarithmic', 'power', 'lorentzian', 'sigmoid', 'custom'\n ];\n \n for (const method of allMethods) {\n // Remove fit series\n const fitSeriesId = `${seriesId}_fit_${method}`;\n if (chart.getSeries(fitSeriesId)) {\n chart.removeSeries(fitSeriesId);\n }\n \n // Remove equation annotation\n const annotationId = `${seriesId}_equation_${method}`;\n if (chart.getAnnotation(annotationId)) {\n chart.removeAnnotation(annotationId);\n }\n }\n },\n \n exportResults(seriesId: string, format = 'json'): string {\n const results = regressionResults.get(seriesId) || [];\n \n switch (format) {\n case 'json':\n return JSON.stringify(results, null, 2);\n case 'csv':\n let csv = 'Method,R²,RMSE,Parameters,ProcessingTime\\n';\n for (const result of results) {\n csv += `${result.method},${result.statistics.rSquared},${result.statistics.rmse},\"${result.parameters.parameters.join(', ')}\",${result.processingTime}\\n`;\n }\n return csv;\n case 'matlab':\n let matlab = `% Regression results for ${seriesId}\\n`;\n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n matlab += `result${i + 1}.method = '${result.method}';\\n`;\n matlab += `result${i + 1}.rSquared = ${result.statistics.rSquared};\\n`;\n matlab += `result${i + 1}.parameters = [${result.parameters.parameters.join(', ')}];\\n`;\n }\n return matlab;\n default:\n return JSON.stringify(results, null, 2);\n }\n }\n };\n \n // ============================================\n // Helper Functions\n // ============================================\n \n function calculateMean(data: number[]): number {\n return data.reduce((sum, val) => sum + val, 0) / data.length;\n }\n \n function calculateRSquared(observed: number[], fitted: number[]): number {\n const meanObserved = calculateMean(observed);\n let ssRes = 0;\n let ssTot = 0;\n \n for (let i = 0; i < observed.length; i++) {\n ssRes += Math.pow(observed[i] - fitted[i], 2);\n ssTot += Math.pow(observed[i] - meanObserved, 2);\n }\n \n return 1 - (ssRes / ssTot);\n }\n \n function calculateAdjustedRSquared(rSquared: number, n: number, k: number): number {\n return 1 - ((1 - rSquared) * (n - 1)) / (n - k - 1);\n }\n \n function calculateRMSE(observed: number[], fitted: number[]): number {\n let sumSquaredErrors = 0;\n for (let i = 0; i < observed.length; i++) {\n sumSquaredErrors += Math.pow(observed[i] - fitted[i], 2);\n }\n return Math.sqrt(sumSquaredErrors / observed.length);\n }\n \n function formatEquation(result: RegressionResult): string {\n const params = result.parameters.parameters;\n \n switch (result.method) {\n case 'linear':\n return params.length === 1 ? `y = ${params[0].toFixed(3)}x` : `y = ${params[0].toFixed(3)}x + ${params[1].toFixed(3)}`;\n case 'polynomial':\n let equation = 'y = ';\n for (let i = params.length - 1; i >= 0; i--) {\n if (params[i] !== 0) {\n if (i === 0) {\n equation += params[i].toFixed(3);\n } else if (i === 1) {\n equation += `${params[i].toFixed(3)}x + `;\n } else {\n equation += `${params[i].toFixed(3)}x^${i} + `;\n }\n }\n }\n return equation.replace(' + ', '').trim();\n case 'exponential':\n return `y = ${params[0].toFixed(3)} * exp(${params[1].toFixed(3)}x) + ${params[2]?.toFixed(3) || 0}`;\n case 'gaussian':\n return `y = ${params[0].toFixed(3)} * exp(-((x - ${params[1].toFixed(3)})² / (2 * ${params[2].toFixed(3)}²))) + ${params[3]?.toFixed(3) || 0}`;\n default:\n return 'y = f(x, parameters)';\n }\n }\n \n // ============================================\n // Event Handlers\n // ============================================\n \n function handleDataUpdate(context: PluginContext, event: DataUpdateEvent): void {\n const { seriesId } = event;\n \n if (realtimeSeries.has(seriesId)) {\n // Debounce fitting\n const timer = debounceTimers.get(seriesId);\n if (timer) {\n clearTimeout(timer);\n }\n \n const newTimer = setTimeout(() => {\n const chart = context.chart;\n if (chart) {\n const series = chart.getSeries(seriesId);\n if (series) {\n const data = series.getData();\n if (data && data.x.length > 0) {\n fit(seriesId, {\n x: data.x,\n y: data.y\n });\n \n // Update visualization\n api.visualizeFit(seriesId);\n }\n }\n }\n }, 500); // 500ms debounce\n \n debounceTimers.set(seriesId, newTimer);\n }\n }\n \n // ============================================\n // Plugin Definition\n // ============================================\n \n return {\n manifest: manifestRegression,\n \n onInit(context: PluginContext) {\n ctx = context;\n ctx.log.info('Regression plugin initialized');\n },\n \n onConfigChange(_context: PluginContext, _newConfig: PluginRegressionConfig) {\n // Handle config changes\n },\n \n onBeforeRender(_context: PluginContext, _event: BeforeRenderEvent) {\n // Handle pre-render tasks if needed\n },\n \n onDataUpdate: handleDataUpdate,\n \n onDestroy(_context: PluginContext) {\n // Clean up timers\n for (const timer of debounceTimers.values()) {\n clearTimeout(timer);\n }\n debounceTimers.clear();\n \n // Clear results\n regressionResults.clear();\n realtimeSeries.clear();\n },\n \n api\n };\n}\n\nexport default PluginRegression;\n\n// Re-export types for convenience\nexport type {\n RegressionMethod,\n RegressionData,\n RegressionParameters,\n RegressionStatistics,\n RegressionResult,\n LinearRegressionConfig,\n PolynomialRegressionConfig,\n ExponentialRegressionConfig,\n LogarithmicRegressionConfig,\n PowerRegressionConfig,\n GaussianRegressionConfig,\n LorentzianRegressionConfig,\n SigmoidRegressionConfig,\n CustomRegressionConfig,\n PluginRegressionConfig,\n RegressionCompletedEvent,\n RegressionFailedEvent,\n ModelSelectedEvent,\n RegressionAPI\n} from './types';"],"names":["toArray","data","toFloat32Array","calculateMean","sum","val","calculateVariance","mean","calculateRSquared","observed","fitted","meanObserved","ssRes","ssTot","i","calculateAdjustedRSquared","rSquared","n","k","calculateRMSE","sumSquaredErrors","linearRegression","config","startTime","x","y","weights","forceOrigin","numerator","denominator","weight","slope","fittedValues","xi","residuals","yi","adjustedRSquared","rmse","r","sumX","sumY","sumXY","sumX2","sumY2","sumWeights","meanX","meanY","intercept","polynomialRegression","degree","m","X","row","j","parameters","solveLeastSquares","value","exponentialRegression","_config","offset","transformedY","adjusted","linearResult","rate","logAmplitude","amplitude","gaussianRegression","std","learningRate","maxIterations","tolerance","iter","gradAmplitude","gradMean","gradStd","gradOffset","totalError","exponent","predicted","error","expTerm","regularization","XtX","Xty","solveLinearSystem","manifestRegression","DEFAULT_CONFIG","PluginRegression","userConfig","ctx","regressionResults","realtimeSeries","debounceTimers","fit","seriesId","method","methodConfig","api","result","logX","logY","logXPow","fitAndCompare","methods","configs","results","criteria","b","autoFit","candidateMethods","bestResult","xValues","resultIndex","params","predictions","_level","margin","lower","p","upper","predArray","chart","series","timer","methodsUsed","totalFittings","allMethodsUsed","allRSquared","allProcessingTimes","t","newConfig","fitSeriesId","equation","formatEquation","annotationId","allMethods","format","csv","matlab","_a","_b","handleDataUpdate","context","event","newTimer","_context","_newConfig","_event"],"mappings":"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"}
1
+ {"version":3,"file":"regression.js","sources":["../../src/plugins/regression/algorithms.ts","../../src/plugins/regression/index.ts"],"sourcesContent":["/**\n * Regression Plugin - Core Algorithms\n * \n * Implements regression algorithms for scientific curve fitting.\n * Includes linear, polynomial, exponential, and non-linear models.\n * \n * @packageDocumentation\n * @module plugins/regression\n */\n\nimport type {\n RegressionData,\n RegressionResult,\n LinearRegressionConfig,\n PolynomialRegressionConfig,\n ExponentialRegressionConfig,\n GaussianRegressionConfig\n} from './types';\nimport { solveLinearSystem } from '../analysis/math';\n\n// ============================================\n// Utility Functions\n// ============================================\n\nfunction toArray(data: Float32Array | Float64Array | number[]): number[] {\n return Array.from(data);\n}\n\nfunction toFloat32Array(data: number[]): Float32Array {\n return new Float32Array(data);\n}\n\nfunction calculateMean(data: number[]): number {\n return data.reduce((sum, val) => sum + val, 0) / data.length;\n}\n\nfunction calculateVariance(data: number[]): number {\n const mean = calculateMean(data);\n return data.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / data.length;\n}\n\nfunction calculateRSquared(observed: number[], fitted: number[]): number {\n const meanObserved = calculateMean(observed);\n let ssRes = 0;\n let ssTot = 0;\n \n for (let i = 0; i < observed.length; i++) {\n ssRes += Math.pow(observed[i] - fitted[i], 2);\n ssTot += Math.pow(observed[i] - meanObserved, 2);\n }\n \n return 1 - (ssRes / ssTot);\n}\n\nfunction calculateAdjustedRSquared(rSquared: number, n: number, k: number): number {\n return 1 - ((1 - rSquared) * (n - 1)) / (n - k - 1);\n}\n\nfunction calculateRMSE(observed: number[], fitted: number[]): number {\n let sumSquaredErrors = 0;\n for (let i = 0; i < observed.length; i++) {\n sumSquaredErrors += Math.pow(observed[i] - fitted[i], 2);\n }\n return Math.sqrt(sumSquaredErrors / observed.length);\n}\n/*\nfunction _calculateStatistics(data: RegressionData, predictions: Float32Array): { rSquared: number; rmse: number; mae: number; residuals: number[] } {\n const n = data.x.length;\n const yMean = Array.from(data.y).reduce((sum, y) => sum + y, 0) / n;\n \n let ssTotal = 0;\n let ssResidual = 0;\n \n for (let i = 0; i < n; i++) {\n const yActual = data.y[i];\n const yPred = predictions[i];\n \n ssTotal += Math.pow(yActual - yMean, 2);\n ssResidual += Math.pow(yActual - yPred, 2);\n }\n \n const rSquared = 1 - (ssResidual / ssTotal);\n const rmse = Math.sqrt(ssResidual / n);\n const mae = Array.from(data.y).reduce((sum, y, i) => sum + Math.abs(y - predictions[i]), 0) / n;\n \n return {\n rSquared,\n rmse,\n mae,\n residuals: Array.from(data.y).map((y, i) => y - predictions[i])\n };\n}\n*/\n// ============================================\n// Linear Regression\n// ============================================\n\nexport function linearRegression(\n data: RegressionData,\n config: LinearRegressionConfig = {}\n): RegressionResult {\n const startTime = performance.now();\n \n const x = toArray(data.x);\n const y = toArray(data.y);\n const weights = data.weights ? toArray(data.weights) : null;\n const { forceOrigin = false } = config;\n \n const n = x.length;\n \n if (forceOrigin) {\n // Forced through origin: y = bx\n let numerator = 0;\n let denominator = 0;\n \n for (let i = 0; i < n; i++) {\n const weight = weights ? weights[i] : 1;\n numerator += weight * x[i] * y[i];\n denominator += weight * x[i] * x[i];\n }\n \n const slope = numerator / denominator;\n const fittedValues = x.map(xi => slope * xi);\n const residuals = y.map((yi, i) => yi - fittedValues[i]);\n \n const rSquared = calculateRSquared(y, fittedValues);\n const adjustedRSquared = calculateAdjustedRSquared(rSquared, n, 1);\n const rmse = calculateRMSE(y, fittedValues);\n \n return {\n method: 'linear',\n parameters: {\n parameters: [slope],\n uncertainties: [Math.sqrt(denominator / (n * numerator))], // Simplified\n correlationMatrix: [[1]]\n },\n statistics: {\n rSquared,\n adjustedRSquared,\n rmse,\n rss: residuals.reduce((sum, r) => sum + r * r, 0),\n tss: y.reduce((sum, yi) => sum + Math.pow(yi - calculateMean(y), 2), 0),\n n,\n k: 1\n },\n fittedValues: toFloat32Array(fittedValues),\n residuals: toFloat32Array(residuals),\n goodnessOfFit: rSquared > 0.9 ? 'excellent' : rSquared > 0.7 ? 'good' : rSquared > 0.5 ? 'fair' : 'poor',\n converged: true,\n iterations: 1,\n processingTime: performance.now() - startTime\n };\n } else {\n // Standard linear regression: y = ax + b\n let sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;\n let sumWeights = 0;\n \n for (let i = 0; i < n; i++) {\n const weight = weights ? weights[i] : 1;\n sumX += weight * x[i];\n sumY += weight * y[i];\n sumXY += weight * x[i] * y[i];\n sumX2 += weight * x[i] * x[i];\n sumWeights += weight;\n }\n \n const meanX = sumX / sumWeights;\n const meanY = sumY / sumWeights;\n \n const slope = (sumXY - sumWeights * meanX * meanY) / (sumX2 - sumWeights * meanX * meanX);\n const intercept = meanY - slope * meanX;\n \n const fittedValues = x.map(xi => slope * xi + intercept);\n const residuals = y.map((yi, i) => yi - fittedValues[i]);\n \n const rSquared = calculateRSquared(y, fittedValues);\n const adjustedRSquared = calculateAdjustedRSquared(rSquared, n, 2);\n const rmse = calculateRMSE(y, fittedValues);\n \n return {\n method: 'linear',\n parameters: {\n parameters: [slope, intercept],\n uncertainties: [0.1, 0.1], // Simplified\n correlationMatrix: [[1, -0.5], [-0.5, 1]] // Simplified\n },\n statistics: {\n rSquared,\n adjustedRSquared,\n rmse,\n rss: residuals.reduce((sum, r) => sum + r * r, 0),\n tss: y.reduce((sum, yi) => sum + Math.pow(yi - meanY, 2), 0),\n n,\n k: 2\n },\n fittedValues: toFloat32Array(fittedValues),\n residuals: toFloat32Array(residuals),\n goodnessOfFit: rSquared > 0.9 ? 'excellent' : rSquared > 0.7 ? 'good' : rSquared > 0.5 ? 'fair' : 'poor',\n converged: true,\n iterations: 1,\n processingTime: performance.now() - startTime\n };\n }\n}\n\n// ============================================\n// Polynomial Regression\n// ============================================\n\nexport function polynomialRegression(\n data: RegressionData,\n config: PolynomialRegressionConfig\n): RegressionResult {\n const startTime = performance.now();\n \n const x = toArray(data.x);\n const y = toArray(data.y);\n const { degree } = config;\n \n const n = x.length;\n const m = degree + 1; // Number of parameters\n \n // Build Vandermonde matrix\n const X: number[][] = [];\n for (let i = 0; i < n; i++) {\n const row: number[] = [];\n for (let j = 0; j <= degree; j++) {\n row.push(Math.pow(x[i], j));\n }\n X.push(row);\n }\n \n // Solve using least squares (simplified implementation)\n // In practice, would use QR decomposition or SVD\n const parameters = solveLeastSquares(X, y, 0);\n \n const fittedValues = x.map(xi => {\n let value = 0;\n for (let j = 0; j <= degree; j++) {\n value += parameters[j] * Math.pow(xi, j);\n }\n return value;\n });\n \n const residuals = y.map((yi, i) => yi - fittedValues[i]);\n \n const rSquared = calculateRSquared(y, fittedValues);\n const adjustedRSquared = calculateAdjustedRSquared(rSquared, n, m);\n const rmse = calculateRMSE(y, fittedValues);\n \n return {\n method: 'polynomial',\n parameters: {\n parameters,\n uncertainties: new Array(m).fill(0.1), // Simplified\n correlationMatrix: Array(m).fill(0).map(() => Array(m).fill(0)) // Simplified\n },\n statistics: {\n rSquared,\n adjustedRSquared,\n rmse,\n rss: residuals.reduce((sum, r) => sum + r * r, 0),\n tss: y.reduce((sum, yi) => sum + Math.pow(yi - calculateMean(y), 2), 0),\n n,\n k: m\n },\n fittedValues: toFloat32Array(fittedValues),\n residuals: toFloat32Array(residuals),\n goodnessOfFit: rSquared > 0.9 ? 'excellent' : rSquared > 0.7 ? 'good' : rSquared > 0.5 ? 'fair' : 'poor',\n converged: true,\n iterations: 10, // Simplified\n processingTime: performance.now() - startTime\n };\n}\n\n// ============================================\n// Exponential Regression\n// ============================================\n\nexport function exponentialRegression(\n data: RegressionData,\n _config: ExponentialRegressionConfig = {}\n): RegressionResult {\n const startTime = performance.now();\n \n const x = toArray(data.x);\n const y = toArray(data.y);\n \n // Transform to linear: ln(y - offset) = ln(amplitude) + rate * x\n // Need to estimate offset first (simplified)\n const offset = Math.min(...y) - 1;\n \n const transformedY = y.map(yi => {\n const adjusted = yi - offset;\n return adjusted > 0 ? Math.log(adjusted) : 0;\n });\n \n // Linear regression on transformed data\n const linearResult = linearRegression(\n { x, y: transformedY },\n { forceOrigin: false }\n );\n \n const [rate, logAmplitude] = linearResult.parameters.parameters;\n const amplitude = Math.exp(logAmplitude);\n \n const fittedValues = x.map(xi => amplitude * Math.exp(rate * xi) + offset);\n const residuals = y.map((yi, i) => yi - fittedValues[i]);\n \n const rSquared = calculateRSquared(y, fittedValues);\n const adjustedRSquared = calculateAdjustedRSquared(rSquared, x.length, 3);\n const rmse = calculateRMSE(y, fittedValues);\n \n return {\n method: 'exponential',\n parameters: {\n parameters: [amplitude, rate, offset],\n uncertainties: [0.1, 0.01, 0.1], // Simplified\n correlationMatrix: [[1, 0.5, 0.2], [0.5, 1, 0.3], [0.2, 0.3, 1]] // Simplified\n },\n statistics: {\n rSquared,\n adjustedRSquared,\n rmse,\n rss: residuals.reduce((sum, r) => sum + r * r, 0),\n tss: y.reduce((sum, yi) => sum + Math.pow(yi - calculateMean(y), 2), 0),\n n: x.length,\n k: 3\n },\n fittedValues: toFloat32Array(fittedValues),\n residuals: toFloat32Array(residuals),\n goodnessOfFit: rSquared > 0.9 ? 'excellent' : rSquared > 0.7 ? 'good' : rSquared > 0.5 ? 'fair' : 'poor',\n converged: true,\n iterations: 5, // Simplified\n processingTime: performance.now() - startTime\n };\n}\n\n// ============================================\n// Gaussian Regression\n// ============================================\n\nexport function gaussianRegression(\n data: RegressionData,\n _config: GaussianRegressionConfig = {}\n): RegressionResult {\n const startTime = performance.now();\n \n const x = toArray(data.x);\n const y = toArray(data.y);\n \n // Non-linear fitting using simplified gradient descent\n let amplitude = Math.max(...y);\n let mean = x.reduce((sum, xi) => sum + xi, 0) / x.length;\n let std = Math.sqrt(calculateVariance(x));\n let offset = Math.min(...y);\n \n const learningRate = 0.001;\n const maxIterations = 100;\n const tolerance = 1e-6;\n \n for (let iter = 0; iter < maxIterations; iter++) {\n let gradAmplitude = 0, gradMean = 0, gradStd = 0, gradOffset = 0;\n let totalError = 0;\n \n for (let i = 0; i < x.length; i++) {\n const xi = x[i];\n const yi = y[i];\n \n // Gaussian function: A * exp(-((x - μ)² / (2σ²))) + offset\n const exponent = -Math.pow(xi - mean, 2) / (2 * std * std);\n const predicted = amplitude * Math.exp(exponent) + offset;\n const error = yi - predicted;\n totalError += error * error;\n \n // Gradients\n const expTerm = Math.exp(exponent);\n gradAmplitude += error * expTerm;\n gradMean += error * amplitude * expTerm * (xi - mean) / (std * std);\n gradStd += error * amplitude * expTerm * Math.pow(xi - mean, 2) / (Math.pow(std, 3));\n gradOffset += error;\n }\n \n // Update parameters\n amplitude += learningRate * gradAmplitude;\n mean += learningRate * gradMean;\n std += learningRate * gradStd;\n offset += learningRate * gradOffset;\n \n // Ensure std is positive\n std = Math.max(std, 0.01);\n \n if (totalError < tolerance) break;\n }\n \n const fittedValues = x.map(xi => {\n const exponent = -Math.pow(xi - mean, 2) / (2 * std * std);\n return amplitude * Math.exp(exponent) + offset;\n });\n \n const residuals = y.map((yi, i) => yi - fittedValues[i]);\n \n const rSquared = calculateRSquared(y, fittedValues);\n const adjustedRSquared = calculateAdjustedRSquared(rSquared, x.length, 4);\n const rmse = calculateRMSE(y, fittedValues);\n \n return {\n method: 'gaussian',\n parameters: {\n parameters: [amplitude, mean, std, offset],\n uncertainties: [0.1, 0.1, 0.01, 0.1], // Simplified\n correlationMatrix: Array(4).fill(0).map(() => Array(4).fill(0)) // Simplified\n },\n statistics: {\n rSquared,\n adjustedRSquared,\n rmse,\n rss: residuals.reduce((sum, r) => sum + r * r, 0),\n tss: y.reduce((sum, yi) => sum + Math.pow(yi - calculateMean(y), 2), 0),\n n: x.length,\n k: 4\n },\n fittedValues: toFloat32Array(fittedValues),\n residuals: toFloat32Array(residuals),\n goodnessOfFit: rSquared > 0.9 ? 'excellent' : rSquared > 0.7 ? 'good' : rSquared > 0.5 ? 'fair' : 'poor',\n converged: true,\n iterations: maxIterations,\n processingTime: performance.now() - startTime\n };\n}\n\n// ============================================\n// Helper Functions\n// ============================================\n\nfunction solveLeastSquares(X: number[][], y: number[], regularization: number = 0): number[] {\n const n = X.length;\n const m = X[0].length;\n \n // Compute X^T * X\n const XtX: number[][] = Array(m).fill(0).map(() => Array(m).fill(0));\n const Xty: number[] = Array(m).fill(0);\n \n for (let i = 0; i < n; i++) {\n for (let j = 0; j < m; j++) {\n for (let k = 0; k < m; k++) {\n XtX[j][k] += X[i][j] * X[i][k];\n }\n Xty[j] += X[i][j] * y[i];\n }\n }\n \n // Add L2 regularization if needed\n if (regularization > 0) {\n for (let i = 0; i < m; i++) {\n XtX[i][i] += regularization;\n }\n }\n \n // Solve using Gaussian elimination\n return solveLinearSystem(XtX, Xty);\n}","/**\n * Regression Plugin - Main Implementation\n * \n * Provides advanced scientific regression and curve fitting capabilities.\n * Supports multiple regression methods with automatic model selection.\n * \n * @example\n * ```typescript\n * import { PluginRegression } from 'velo-plot/plugins/regression';\n * \n * chart.use(PluginRegression({\n * defaultMethod: 'polynomial',\n * enableAutoSelection: true,\n * modelSelectionCriteria: 'aic',\n * maxIterations: 100\n * }));\n * \n * // Fit polynomial regression\n * const result = await chart.regression.fit('series1', {\n * x: seriesData.x,\n * y: seriesData.y\n * }, 'polynomial', { degree: 3 });\n * \n * console.log(`R² = ${result.statistics.rSquared}`);\n * console.log(`Parameters: ${result.parameters.parameters}`);\n * \n * // Auto-fit best model\n * const bestFit = await chart.regression.autoFit('series1', data);\n * \n * // Visualize fit\n * chart.regression.visualizeFit('series1');\n * ```\n * \n * @packageDocumentation\n * @module plugins/regression\n */\n\nimport type { \n PluginManifest, \n ChartPlugin, \n PluginContext,\n BeforeRenderEvent,\n DataUpdateEvent\n} from '../types';\n\nimport type {\n PluginRegressionConfig,\n RegressionAPI,\n RegressionResult,\n RegressionData,\n RegressionMethod,\n LinearRegressionConfig,\n PolynomialRegressionConfig,\n ExponentialRegressionConfig,\n GaussianRegressionConfig,\n RegressionCompletedEvent,\n RegressionFailedEvent,\n ModelSelectedEvent,\n RegressionStatistics\n} from './types';\n\nimport {\n linearRegression,\n polynomialRegression,\n exponentialRegression,\n gaussianRegression\n} from './algorithms';\n\n// ============================================\n// Plugin Manifest\n// ============================================\n\nconst manifestRegression: PluginManifest = {\n name: 'regression',\n version: '1.0.0',\n description: 'Advanced scientific regression and curve fitting',\n author: 'Velo Plot Team',\n provides: ['regression', 'curve-fitting', 'scientific-analysis']\n};\n\n// ============================================\n// Default Configuration\n// ============================================\n\nconst DEFAULT_CONFIG: Required<PluginRegressionConfig> = {\n defaultMethod: 'linear',\n enableAutoSelection: false,\n modelSelectionCriteria: 'aic',\n enableWeightedRegression: false,\n enableRobustRegression: false,\n robustMethod: 'huber',\n maxIterations: 100,\n convergenceTolerance: 1e-6,\n defaultConfidenceLevel: 0.95,\n enableParallelProcessing: false,\n parallelChunkSize: 1000\n};\n\n// ============================================\n// Regression Plugin Implementation\n// ============================================\n\nexport function PluginRegression(\n userConfig: Partial<PluginRegressionConfig> = {}\n): ChartPlugin<PluginRegressionConfig> {\n const config = { ...DEFAULT_CONFIG, ...userConfig };\n let ctx: PluginContext | null = null;\n \n // Results storage\n const regressionResults = new Map<string, RegressionResult[]>();\n const realtimeSeries = new Set<string>();\n const debounceTimers = new Map<string, any>();\n \n // ============================================\n // Core Regression Methods\n // ============================================\n \n async function fit(\n seriesId: string,\n data: RegressionData,\n method: RegressionMethod = config.defaultMethod,\n methodConfig: any = {}\n ): Promise<RegressionResult> {\n try {\n // Clear previous visualization before fitting new model\n api.hideVisualization(seriesId);\n \n let result: RegressionResult;\n \n switch (method) {\n case 'linear':\n result = linearRegression(data, methodConfig as LinearRegressionConfig);\n break;\n case 'polynomial':\n result = polynomialRegression(data, methodConfig as PolynomialRegressionConfig);\n break;\n case 'exponential':\n result = exponentialRegression(data, methodConfig as ExponentialRegressionConfig);\n break;\n case 'gaussian':\n result = gaussianRegression(data, methodConfig as GaussianRegressionConfig);\n break;\n case 'logarithmic':\n // Transform y = a * log(x) + b to linear\n const logX = Array.from(data.x).map(xi => Math.log(xi));\n result = linearRegression({ ...data, x: new Float32Array(logX) }, methodConfig as LinearRegressionConfig);\n result.method = 'logarithmic';\n break;\n case 'power':\n // Transform to linear: log(y) = log(a) + b * log(x)\n const logY = Array.from(data.y).map(yi => Math.log(yi));\n const logXPow = Array.from(data.x).map(xi => Math.log(xi));\n result = linearRegression({ ...data, x: new Float32Array(logXPow), y: new Float32Array(logY) }, methodConfig as LinearRegressionConfig);\n result.method = 'power';\n break;\n case 'lorentzian':\n case 'sigmoid':\n case 'custom':\n // For now, fall back to linear for unsupported methods\n result = linearRegression(data, methodConfig as LinearRegressionConfig);\n break;\n default:\n throw new Error(`Unsupported regression method: ${method}`);\n }\n \n // Clear and store new result (replace, don't accumulate)\n regressionResults.set(seriesId, [result]);\n \n // Emit event\n if (ctx) {\n ctx.events.emit('regression:completed', {\n result,\n seriesId,\n method,\n timestamp: Date.now()\n } as RegressionCompletedEvent);\n }\n \n ctx?.log.info(`Regression completed for ${seriesId}: ${method} (R² = ${result.statistics.rSquared.toFixed(3)})`);\n \n return result;\n } catch (error) {\n if (ctx) {\n ctx.events.emit('regression:failed', {\n error: error as Error,\n seriesId,\n method,\n reason: `Fitting failed: ${error}`,\n timestamp: Date.now()\n } as RegressionFailedEvent);\n }\n \n throw error;\n }\n }\n \n async function fitAndCompare(\n seriesId: string,\n data: RegressionData,\n methods: RegressionMethod[],\n configs?: any[]\n ): Promise<RegressionResult[]> {\n const results: RegressionResult[] = [];\n \n for (let i = 0; i < methods.length; i++) {\n const method = methods[i];\n const methodConfig = configs ? configs[i] : {};\n \n try {\n const result = await fit(seriesId, data, method, methodConfig);\n results.push(result);\n } catch (error) {\n ctx?.log.warn(`Regression failed for ${method}: ${error}`);\n }\n }\n \n // Sort by criteria\n const criteria = config.modelSelectionCriteria;\n results.sort((a, b) => {\n switch (criteria) {\n case 'aic':\n return (a.statistics.aic || 0) - (b.statistics.aic || 0);\n case 'bic':\n return (a.statistics.bic || 0) - (b.statistics.bic || 0);\n case 'adjusted-r2':\n return b.statistics.adjustedRSquared - a.statistics.adjustedRSquared;\n default:\n return b.statistics.rSquared - a.statistics.rSquared;\n }\n });\n \n return results;\n }\n \n async function autoFit(\n seriesId: string,\n data: RegressionData,\n candidateMethods: RegressionMethod[] = ['linear', 'polynomial', 'exponential', 'gaussian']\n ): Promise<RegressionResult> {\n const configs = candidateMethods.map(method => {\n switch (method) {\n case 'polynomial':\n return { degree: 2 } as PolynomialRegressionConfig;\n case 'exponential':\n return {} as ExponentialRegressionConfig;\n case 'gaussian':\n return {} as GaussianRegressionConfig;\n default:\n return {} as LinearRegressionConfig;\n }\n });\n \n const results = await fitAndCompare(seriesId, data, candidateMethods, configs);\n \n if (results.length === 0) {\n throw new Error('No regression methods succeeded');\n }\n \n const bestResult = results[0];\n \n // Emit model selection event\n if (ctx) {\n ctx.events.emit('model:selected', {\n selectedMethod: bestResult.method,\n candidateResults: results,\n selectionCriteria: config.modelSelectionCriteria,\n seriesId,\n timestamp: Date.now()\n } as ModelSelectedEvent);\n }\n \n ctx?.log.info(`Auto-fit selected ${bestResult.method} for ${seriesId} (R² = ${bestResult.statistics.rSquared.toFixed(3)})`);\n \n return bestResult;\n }\n \n // ============================================\n // API Implementation\n // ============================================\n \n const api: RegressionAPI & Record<string, unknown> = {\n fit,\n \n fitAndCompare,\n \n autoFit,\n \n getResults(seriesId: string): RegressionResult[] {\n return regressionResults.get(seriesId) || [];\n },\n \n clearResults(seriesId: string): void {\n regressionResults.delete(seriesId);\n ctx?.log.info(`Regression results cleared for series: ${seriesId}`);\n },\n \n predict(\n seriesId: string,\n xValues: Float32Array | Float64Array | number[],\n resultIndex = 0\n ): Float32Array {\n const results = regressionResults.get(seriesId);\n if (!results || results.length === 0) {\n throw new Error(`No regression results found for series: ${seriesId}`);\n }\n \n const result = results[Math.min(resultIndex, results.length - 1)];\n const x = Array.from(xValues);\n const params = result.parameters.parameters;\n \n const predictions = x.map(xi => {\n switch (result.method) {\n case 'linear':\n return params[0] * xi + (params[1] || 0);\n case 'polynomial':\n let value = 0;\n for (let j = 0; j < params.length; j++) {\n value += params[j] * Math.pow(xi, j);\n }\n return value;\n case 'exponential':\n return params[0] * Math.exp(params[1] * xi) + (params[2] || 0);\n case 'gaussian':\n const exponent = -Math.pow(xi - params[1], 2) / (2 * params[2] * params[2]);\n return params[0] * Math.exp(exponent) + (params[3] || 0);\n case 'logarithmic':\n return params[0] * Math.log(xi) + (params[1] || 0);\n case 'power':\n return params[0] * Math.pow(xi, params[1]);\n default:\n return 0;\n }\n });\n \n return new Float32Array(predictions);\n },\n \n getConfidenceIntervals(\n seriesId: string,\n xValues: Float32Array | Float64Array | number[],\n _level = config.defaultConfidenceLevel,\n resultIndex = 0\n ): { lower: Float32Array; upper: Float32Array } {\n // Simplified confidence intervals\n const predictions = this.predict(seriesId, xValues, resultIndex);\n const margin = 0.1; // Simplified margin\n \n const lower = predictions.map(p => p - margin);\n const upper = predictions.map(p => p + margin);\n \n return {\n lower: new Float32Array(lower),\n upper: new Float32Array(upper)\n };\n },\n \n evaluate(seriesId: string, data: RegressionData, resultIndex = 0): RegressionStatistics {\n const results = regressionResults.get(seriesId);\n if (!results || results.length === 0) {\n throw new Error(`No regression results found for series: ${seriesId}`);\n }\n \n const result = results[Math.min(resultIndex, results.length - 1)];\n const x = Array.from(data.x);\n const y = Array.from(data.y);\n \n // Use existing model to predict\n const predictions = api.predict(seriesId, x, resultIndex);\n const predArray = Array.from(predictions);\n \n const rSquared = calculateRSquared(y, predArray);\n const adjustedRSquared = calculateAdjustedRSquared(rSquared, y.length, result.parameters.parameters.length);\n const rmse = calculateRMSE(y, predArray);\n \n return {\n rSquared,\n adjustedRSquared,\n rmse,\n rss: y.reduce((sum, yi, i) => sum + Math.pow(yi - predArray[i], 2), 0),\n tss: y.reduce((sum, yi) => sum + Math.pow(yi - calculateMean(y), 2), 0),\n n: y.length,\n k: result.parameters.parameters.length\n };\n },\n \n enableRealtimeFitting(\n seriesId: string,\n method: RegressionMethod = config.defaultMethod,\n methodConfig: any = {}\n ): void {\n realtimeSeries.add(seriesId);\n \n // Run initial fitting\n const chart = ctx?.chart;\n if (chart) {\n const series = chart.getSeries(seriesId);\n if (series) {\n const data = series.getData();\n if (data && data.x.length > 0) {\n fit(seriesId, {\n x: data.x,\n y: data.y\n }, method, methodConfig);\n }\n }\n }\n \n ctx?.log.info(`Real-time regression fitting enabled for series: ${seriesId}`);\n },\n \n disableRealtimeFitting(seriesId: string): void {\n realtimeSeries.delete(seriesId);\n \n // Clear debounce timer\n const timer = debounceTimers.get(seriesId);\n if (timer) {\n clearTimeout(timer);\n debounceTimers.delete(seriesId);\n }\n \n ctx?.log.info(`Real-time regression fitting disabled for series: ${seriesId}`);\n },\n \n getStatistics(seriesId?: string) {\n if (seriesId) {\n const results = regressionResults.get(seriesId) || [];\n const methodsUsed: Record<RegressionMethod, number> = {} as any;\n \n for (const result of results) {\n methodsUsed[result.method] = (methodsUsed[result.method] || 0) + 1;\n }\n \n return {\n totalFittings: results.length,\n methodsUsed,\n averageRSquared: results.length > 0 ? results.reduce((sum, r) => sum + r.statistics.rSquared, 0) / results.length : 0,\n averageProcessingTime: results.length > 0 ? results.reduce((sum, r) => sum + r.processingTime, 0) / results.length : 0\n };\n } else {\n // Global statistics\n let totalFittings = 0;\n const allMethodsUsed: Record<RegressionMethod, number> = {} as any;\n const allRSquared: number[] = [];\n const allProcessingTimes: number[] = [];\n \n for (const results of regressionResults.values()) {\n totalFittings += results.length;\n allRSquared.push(...results.map(r => r.statistics.rSquared));\n allProcessingTimes.push(...results.map(r => r.processingTime));\n \n for (const result of results) {\n allMethodsUsed[result.method] = (allMethodsUsed[result.method] || 0) + 1;\n }\n }\n \n return {\n totalFittings,\n methodsUsed: allMethodsUsed,\n averageRSquared: allRSquared.length > 0 ? allRSquared.reduce((sum, r) => sum + r, 0) / allRSquared.length : 0,\n averageProcessingTime: allProcessingTimes.length > 0 ? allProcessingTimes.reduce((sum, t) => sum + t, 0) / allProcessingTimes.length : 0\n };\n }\n },\n \n updateConfig: (newConfig: Partial<PluginRegressionConfig>) => {\n Object.assign(config, newConfig);\n },\n \n getConfig: () => ({ ...config }),\n \n visualizeFit(seriesId: string, resultIndex = 0): void {\n const chart = ctx?.chart;\n if (!chart) return;\n \n const results = regressionResults.get(seriesId);\n if (!results || results.length === 0) return;\n \n const result = results[Math.min(resultIndex, results.length - 1)];\n const series = chart.getSeries(seriesId);\n if (!series) return;\n \n const data = series.getData();\n if (!data) return;\n \n // Remove existing fit visualization\n this.hideVisualization(seriesId);\n \n // Add fitted curve\n const fitSeriesId = `${seriesId}_fit_${result.method}`;\n const fittedValues = api.predict(seriesId, data.x, resultIndex);\n \n chart.addSeries({\n id: fitSeriesId,\n type: 'line',\n data: {\n x: new Float32Array(Array.from(data.x)),\n y: new Float32Array(fittedValues)\n },\n style: {\n color: '#ff6b6b',\n width: 2,\n opacity: 0.8,\n lineDash: [5, 5]\n }\n });\n \n // Add equation annotation\n const equation = formatEquation(result);\n const annotationId = `${seriesId}_equation_${result.method}`;\n \n chart.addAnnotation({\n id: annotationId,\n type: 'text',\n text: `${result.method.toUpperCase()}: ${equation}\\\\nR² = ${result.statistics.rSquared.toFixed(3)}`,\n x: data.x[0],\n y: Math.max(...Array.from(fittedValues)),\n style: {\n color: '#ff6b6b',\n fontSize: 12,\n backgroundColor: 'rgba(255, 255, 255, 0.9)'\n }\n } as any);\n },\n \n hideVisualization(seriesId: string): void {\n const chart = ctx?.chart;\n if (!chart) return;\n \n // List all possible regression methods to ensure cleanup\n const allMethods: RegressionMethod[] = [\n 'linear', 'polynomial', 'exponential', 'gaussian', \n 'logarithmic', 'power', 'lorentzian', 'sigmoid', 'custom'\n ];\n \n for (const method of allMethods) {\n // Remove fit series\n const fitSeriesId = `${seriesId}_fit_${method}`;\n if (chart.getSeries(fitSeriesId)) {\n chart.removeSeries(fitSeriesId);\n }\n \n // Remove equation annotation\n const annotationId = `${seriesId}_equation_${method}`;\n if (chart.getAnnotation(annotationId)) {\n chart.removeAnnotation(annotationId);\n }\n }\n },\n \n exportResults(seriesId: string, format = 'json'): string {\n const results = regressionResults.get(seriesId) || [];\n \n switch (format) {\n case 'json':\n return JSON.stringify(results, null, 2);\n case 'csv':\n let csv = 'Method,R²,RMSE,Parameters,ProcessingTime\\n';\n for (const result of results) {\n csv += `${result.method},${result.statistics.rSquared},${result.statistics.rmse},\"${result.parameters.parameters.join(', ')}\",${result.processingTime}\\n`;\n }\n return csv;\n case 'matlab':\n let matlab = `% Regression results for ${seriesId}\\n`;\n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n matlab += `result${i + 1}.method = '${result.method}';\\n`;\n matlab += `result${i + 1}.rSquared = ${result.statistics.rSquared};\\n`;\n matlab += `result${i + 1}.parameters = [${result.parameters.parameters.join(', ')}];\\n`;\n }\n return matlab;\n default:\n return JSON.stringify(results, null, 2);\n }\n }\n };\n \n // ============================================\n // Helper Functions\n // ============================================\n \n function calculateMean(data: number[]): number {\n return data.reduce((sum, val) => sum + val, 0) / data.length;\n }\n \n function calculateRSquared(observed: number[], fitted: number[]): number {\n const meanObserved = calculateMean(observed);\n let ssRes = 0;\n let ssTot = 0;\n \n for (let i = 0; i < observed.length; i++) {\n ssRes += Math.pow(observed[i] - fitted[i], 2);\n ssTot += Math.pow(observed[i] - meanObserved, 2);\n }\n \n return 1 - (ssRes / ssTot);\n }\n \n function calculateAdjustedRSquared(rSquared: number, n: number, k: number): number {\n return 1 - ((1 - rSquared) * (n - 1)) / (n - k - 1);\n }\n \n function calculateRMSE(observed: number[], fitted: number[]): number {\n let sumSquaredErrors = 0;\n for (let i = 0; i < observed.length; i++) {\n sumSquaredErrors += Math.pow(observed[i] - fitted[i], 2);\n }\n return Math.sqrt(sumSquaredErrors / observed.length);\n }\n \n function formatEquation(result: RegressionResult): string {\n const params = result.parameters.parameters;\n \n switch (result.method) {\n case 'linear':\n return params.length === 1 ? `y = ${params[0].toFixed(3)}x` : `y = ${params[0].toFixed(3)}x + ${params[1].toFixed(3)}`;\n case 'polynomial':\n let equation = 'y = ';\n for (let i = params.length - 1; i >= 0; i--) {\n if (params[i] !== 0) {\n if (i === 0) {\n equation += params[i].toFixed(3);\n } else if (i === 1) {\n equation += `${params[i].toFixed(3)}x + `;\n } else {\n equation += `${params[i].toFixed(3)}x^${i} + `;\n }\n }\n }\n return equation.replace(' + ', '').trim();\n case 'exponential':\n return `y = ${params[0].toFixed(3)} * exp(${params[1].toFixed(3)}x) + ${params[2]?.toFixed(3) || 0}`;\n case 'gaussian':\n return `y = ${params[0].toFixed(3)} * exp(-((x - ${params[1].toFixed(3)})² / (2 * ${params[2].toFixed(3)}²))) + ${params[3]?.toFixed(3) || 0}`;\n default:\n return 'y = f(x, parameters)';\n }\n }\n \n // ============================================\n // Event Handlers\n // ============================================\n \n function handleDataUpdate(context: PluginContext, event: DataUpdateEvent): void {\n const { seriesId } = event;\n \n if (realtimeSeries.has(seriesId)) {\n // Debounce fitting\n const timer = debounceTimers.get(seriesId);\n if (timer) {\n clearTimeout(timer);\n }\n \n const newTimer = setTimeout(() => {\n const chart = context.chart;\n if (chart) {\n const series = chart.getSeries(seriesId);\n if (series) {\n const data = series.getData();\n if (data && data.x.length > 0) {\n fit(seriesId, {\n x: data.x,\n y: data.y\n });\n \n // Update visualization\n api.visualizeFit(seriesId);\n }\n }\n }\n }, 500); // 500ms debounce\n \n debounceTimers.set(seriesId, newTimer);\n }\n }\n \n // ============================================\n // Plugin Definition\n // ============================================\n \n return {\n manifest: manifestRegression,\n \n onInit(context: PluginContext) {\n ctx = context;\n ctx.log.info('Regression plugin initialized');\n },\n \n onConfigChange(_context: PluginContext, _newConfig: PluginRegressionConfig) {\n // Handle config changes\n },\n \n onBeforeRender(_context: PluginContext, _event: BeforeRenderEvent) {\n // Handle pre-render tasks if needed\n },\n \n onDataUpdate: handleDataUpdate,\n \n onDestroy(_context: PluginContext) {\n // Clean up timers\n for (const timer of debounceTimers.values()) {\n clearTimeout(timer);\n }\n debounceTimers.clear();\n \n // Clear results\n regressionResults.clear();\n realtimeSeries.clear();\n },\n \n api\n };\n}\n\nexport default PluginRegression;\n\n// Re-export types for convenience\nexport type {\n RegressionMethod,\n RegressionData,\n RegressionParameters,\n RegressionStatistics,\n RegressionResult,\n LinearRegressionConfig,\n PolynomialRegressionConfig,\n ExponentialRegressionConfig,\n LogarithmicRegressionConfig,\n PowerRegressionConfig,\n GaussianRegressionConfig,\n LorentzianRegressionConfig,\n SigmoidRegressionConfig,\n CustomRegressionConfig,\n PluginRegressionConfig,\n RegressionCompletedEvent,\n RegressionFailedEvent,\n ModelSelectedEvent,\n RegressionAPI\n} from './types';"],"names":["toArray","data","toFloat32Array","calculateMean","sum","val","calculateVariance","mean","calculateRSquared","observed","fitted","meanObserved","ssRes","ssTot","i","calculateAdjustedRSquared","rSquared","n","k","calculateRMSE","sumSquaredErrors","linearRegression","config","startTime","x","y","weights","forceOrigin","numerator","denominator","weight","slope","fittedValues","xi","residuals","yi","adjustedRSquared","rmse","r","sumX","sumY","sumXY","sumX2","sumWeights","meanX","meanY","intercept","polynomialRegression","degree","m","X","row","j","parameters","solveLeastSquares","value","exponentialRegression","_config","offset","transformedY","adjusted","linearResult","rate","logAmplitude","amplitude","gaussianRegression","std","learningRate","maxIterations","tolerance","iter","gradAmplitude","gradMean","gradStd","gradOffset","totalError","exponent","predicted","error","expTerm","regularization","XtX","Xty","solveLinearSystem","manifestRegression","DEFAULT_CONFIG","PluginRegression","userConfig","ctx","regressionResults","realtimeSeries","debounceTimers","fit","seriesId","method","methodConfig","api","result","logX","logY","logXPow","fitAndCompare","methods","configs","results","criteria","a","b","autoFit","candidateMethods","bestResult","xValues","resultIndex","params","predictions","_level","margin","lower","p","upper","predArray","chart","series","timer","methodsUsed","totalFittings","allMethodsUsed","allRSquared","allProcessingTimes","t","newConfig","fitSeriesId","equation","formatEquation","annotationId","allMethods","format","csv","matlab","_a","_b","handleDataUpdate","context","event","newTimer","_context","_newConfig","_event"],"mappings":"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"}
@@ -6,7 +6,7 @@ const v = (M = {}) => {
6
6
  name: "roi",
7
7
  description: "Region of Interest selection tool and masking",
8
8
  version: "1.1.0",
9
- author: "SciPlot"
9
+ author: "VeloPlot"
10
10
  };
11
11
  function D(t) {
12
12
  return {
@@ -29,7 +29,7 @@ const v = (M = {}) => {
29
29
  y: o.coords.dataToPixelY(t.y)
30
30
  } : { x: 0, y: 0 };
31
31
  }
32
- function S(t) {
32
+ function T(t) {
33
33
  return x.length === 0 ? !0 : x.some((e) => b(t, e));
34
34
  }
35
35
  function A() {
@@ -37,7 +37,7 @@ const v = (M = {}) => {
37
37
  for (const [t, e] of g.entries()) {
38
38
  const n = [];
39
39
  for (let s = 0; s < e.x.length; s++)
40
- S({ x: e.x[s], y: e.y[s] }) && n.push(s);
40
+ T({ x: e.x[s], y: e.y[s] }) && n.push(s);
41
41
  const i = new Float32Array(n.length), l = new Float32Array(n.length);
42
42
  for (let s = 0; s < n.length; s++)
43
43
  i[s] = e.x[n[s]], l[s] = e.y[n[s]];
@@ -84,7 +84,7 @@ const v = (M = {}) => {
84
84
  });
85
85
  }), n;
86
86
  }
87
- function T() {
87
+ function S() {
88
88
  if (!a || !o) return;
89
89
  a.tool === "polygon" && a.points.length > 1 && a.points.pop(), x.push(a), d && A();
90
90
  const t = {
@@ -123,7 +123,7 @@ const v = (M = {}) => {
123
123
  }
124
124
  }
125
125
  function E(t) {
126
- !h || !a || u !== "polygon" && T();
126
+ !h || !a || u !== "polygon" && S();
127
127
  }
128
128
  function k(t, e) {
129
129
  const { tool: n, points: i, color: l, fill: s } = t;
@@ -150,7 +150,7 @@ const v = (M = {}) => {
150
150
  }), d && ((l = n.data) != null && l.x)) {
151
151
  const s = g.get(n.id), r = [];
152
152
  for (let y = 0; y < s.x.length; y++)
153
- S({ x: s.x[y], y: s.y[y] }) && r.push(y);
153
+ T({ x: s.x[y], y: s.y[y] }) && r.push(y);
154
154
  const c = new Float32Array(r.length), f = new Float32Array(r.length);
155
155
  for (let y = 0; y < r.length; y++)
156
156
  c[y] = s.x[r[y]], f[y] = s.y[r[y]];
@@ -164,7 +164,7 @@ const v = (M = {}) => {
164
164
  }), d && i.x) {
165
165
  const l = g.get(n), s = [];
166
166
  for (let f = 0; f < l.x.length; f++)
167
- S({ x: l.x[f], y: l.y[f] }) && s.push(f);
167
+ T({ x: l.x[f], y: l.y[f] }) && s.push(f);
168
168
  const r = new Float32Array(s.length), c = new Float32Array(s.length);
169
169
  for (let f = 0; f < s.length; f++)
170
170
  r[f] = l.x[s[f]], c[f] = l.y[s[f]];
@@ -181,7 +181,7 @@ const v = (M = {}) => {
181
181
  o = null, g.clear();
182
182
  },
183
183
  onInteraction(t, e) {
184
- e.type === "mousedown" && X(e), e.type === "mousemove" && Y(e), e.type === "mouseup" && E(), e.type, e.originalEvent instanceof MouseEvent && e.originalEvent.detail === 2 && u === "polygon" && (T(), e.preventDefault());
184
+ e.type === "mousedown" && X(e), e.type === "mousemove" && Y(e), e.type === "mouseup" && E(), e.type, e.originalEvent instanceof MouseEvent && e.originalEvent.detail === 2 && u === "polygon" && (S(), e.preventDefault());
185
185
  },
186
186
  onRenderOverlay(t) {
187
187
  const e = t.render.ctx2d;
@@ -189,7 +189,7 @@ const v = (M = {}) => {
189
189
  },
190
190
  api: {
191
191
  setTool(t) {
192
- u = t, h && T();
192
+ u = t, h && S();
193
193
  },
194
194
  clear() {
195
195
  x = [], a = null, h = !1, d && A(), o && (o.events.emit("roi:cleared", {}), o.requestRender());
@@ -1 +1 @@
1
- {"version":3,"file":"roi.js","sources":["../../src/plugins/roi/index.ts"],"sourcesContent":["import type { PluginContext, InteractionEvent, PluginManifest } from \"../types\";\n\nexport interface RoiPoint {\n x: number;\n y: number;\n}\n\nexport interface RoiRegion {\n id: string;\n tool: \"rectangle\" | \"circle\" | \"polygon\" | \"lasso\";\n points: RoiPoint[];\n color?: string;\n fill?: string;\n}\n\nexport interface RoiMaskResult {\n regionId: string;\n seriesId: string;\n masks: boolean[];\n}\n\nexport interface RoiSelectedEvent {\n region: RoiRegion;\n seriesIds: string[];\n masks: RoiMaskResult[];\n}\n\nexport interface RoiAPI {\n setTool(tool: RoiTool): void;\n clear(): void;\n getRegions(): RoiRegion[];\n removeRegion(id: string): void;\n calculateMasks(regionId: string): RoiMaskResult[];\n isEnabled(): boolean;\n setEnabled(enabled: boolean): void;\n}\n\nexport type RoiTool = \"rectangle\" | \"circle\" | \"polygon\" | \"lasso\";\n\nexport interface PluginROIConfig {\n defaultTool?: RoiTool;\n stroke?: string;\n fill?: string;\n enabled?: boolean;\n mask?: boolean;\n}\n\nexport const PluginROI = (config: PluginROIConfig = {}) => {\n let ctx: PluginContext | null = null;\n let activeTool: RoiTool = config.defaultTool || \"rectangle\";\n let regions: RoiRegion[] = [];\n let isDrawing = false;\n let activeRegion: RoiRegion | null = null;\n let enabled = config.enabled !== false;\n let isMasking = config.mask === true;\n\n // Store for original data when masking is active\n const rawDataStore = new Map<string, { x: Float32Array; y: Float32Array }>();\n let originalUpdateSeries: any = null;\n let originalAddSeries: any = null;\n\n const manifest: PluginManifest = {\n name: \"roi\",\n description: \"Region of Interest selection tool and masking\",\n version: \"1.1.0\",\n author: \"SciPlot\",\n };\n\n function createRegion(tool: RoiTool): RoiRegion {\n return {\n id: Math.random().toString(36).substring(2, 11),\n tool,\n points: [],\n color: config.stroke || \"#00f2ff\",\n fill: config.fill || \"rgba(0, 242, 255, 0.15)\",\n };\n }\n\n function pixelToData(pixel: { x: number; y: number }): RoiPoint {\n if (!ctx) return { x: 0, y: 0 };\n return {\n x: ctx.coords.pixelToDataX(pixel.x),\n y: ctx.coords.pixelToDataY(pixel.y),\n };\n }\n\n function dataToPixel(point: RoiPoint): { x: number; y: number } {\n if (!ctx) return { x: 0, y: 0 };\n return {\n x: ctx.coords.dataToPixelX(point.x),\n y: ctx.coords.dataToPixelY(point.y),\n };\n }\n\n function isPointInAnyRegion(point: RoiPoint): boolean {\n if (regions.length === 0) return true; // Show all if no regions defined\n return regions.some((r) => isPointInRegion(point, r));\n }\n\n function applyMasking(): void {\n if (!ctx || !isMasking) return;\n\n for (const [id, raw] of rawDataStore.entries()) {\n const indices: number[] = [];\n for (let i = 0; i < raw.x.length; i++) {\n if (isPointInAnyRegion({ x: raw.x[i], y: raw.y[i] })) {\n indices.push(i);\n }\n }\n\n const filteredX = new Float32Array(indices.length);\n const filteredY = new Float32Array(indices.length);\n for (let i = 0; i < indices.length; i++) {\n filteredX[i] = raw.x[indices[i]];\n filteredY[i] = raw.y[indices[i]];\n }\n\n if (originalUpdateSeries) {\n originalUpdateSeries(id, { x: filteredX, y: filteredY });\n }\n }\n }\n\n function isPointInRegion(point: RoiPoint, region: RoiRegion): boolean {\n const { tool, points } = region;\n if (points.length < 2) return false;\n\n if (tool === \"rectangle\") {\n const xMin = Math.min(points[0].x, points[1].x);\n const xMax = Math.max(points[0].x, points[1].x);\n const yMin = Math.min(points[0].y, points[1].y);\n const yMax = Math.max(points[0].y, points[1].y);\n return point.x >= xMin && point.x <= xMax && point.y >= yMin && point.y <= yMax;\n }\n\n if (tool === \"circle\") {\n const dx = point.x - points[0].x;\n const dy = point.y - points[0].y;\n const r = Math.sqrt(\n Math.pow(points[1].x - points[0].x, 2) + Math.pow(points[1].y - points[0].y, 2)\n );\n return Math.sqrt(dx * dx + dy * dy) <= r;\n }\n\n if (tool === \"polygon\" || tool === \"lasso\") {\n // Ray casting algorithm\n let inside = false;\n for (let i = 0, j = points.length - 1; i < points.length; j = i++) {\n const xi = points[i].x, yi = points[i].y;\n const xj = points[j].x, yj = points[j].y;\n const intersect = yi > point.y !== yj > point.y &&\n point.x < ((xj - xi) * (point.y - yi)) / (yj - yi) + xi;\n if (intersect) inside = !inside;\n }\n return inside;\n }\n\n return false;\n }\n\n function calculateMasks(regionId: string): RoiMaskResult[] {\n const region = regions.find((r) => r.id === regionId);\n if (!region || !ctx) return [];\n\n const results: RoiMaskResult[] = [];\n ctx.chart.getAllSeries().forEach((series) => {\n const data = series.getData();\n if (!data) return;\n\n const masks = new Array(data.x.length);\n for (let i = 0; i < data.x.length; i++) {\n masks[i] = isPointInRegion({ x: data.x[i], y: data.y[i] }, region);\n }\n\n results.push({\n regionId,\n seriesId: series.getId(),\n masks,\n });\n });\n\n return results;\n }\n\n function finishRegion(): void {\n if (!activeRegion || !ctx) return;\n \n // Clean up preview points for polygon\n if (activeRegion.tool === \"polygon\" && activeRegion.points.length > 1) {\n // Remove the preview point\n activeRegion.points.pop();\n }\n\n regions.push(activeRegion);\n\n if (isMasking) {\n applyMasking();\n }\n\n const event: RoiSelectedEvent = {\n region: activeRegion,\n seriesIds: ctx.chart.getAllSeries().map((s) => s.getId()),\n masks: calculateMasks(activeRegion.id),\n };\n\n // Emit on both plugin context and chart\n ctx.events.emit(\"roi:selected\", event);\n if (ctx.chart.events) {\n ctx.chart.events.emit(\"roi:selected\" as any, event);\n }\n \n ctx.events.emit(\"roi:created\", {\n region: activeRegion,\n seriesIds: event.seriesIds,\n });\n\n activeRegion = null;\n isDrawing = false;\n ctx.requestRender();\n }\n\n function handlePointerDown(event: InteractionEvent): void {\n if (!enabled || !event.inPlotArea) return;\n\n if (activeTool === \"polygon\" && activeRegion) {\n // For polygon, we keep adding points on click\n // But first, replace the preview point with a permanent one\n const previewPoint = pixelToData({ x: event.pixelX, y: event.pixelY });\n activeRegion.points.push(previewPoint);\n event.preventDefault();\n ctx?.requestRender();\n return;\n }\n\n isDrawing = true;\n activeRegion = createRegion(activeTool);\n const startPoint = pixelToData({ x: event.pixelX, y: event.pixelY });\n activeRegion.points.push(startPoint);\n \n if (activeTool === \"rectangle\" || activeTool === \"circle\") {\n activeRegion.points.push({ ...startPoint });\n } else if (activeTool === \"polygon\") {\n // Add a second point for preview\n activeRegion.points.push({ ...startPoint });\n }\n \n event.preventDefault(); // Stop chart from panning\n ctx?.requestRender();\n }\n\n function handlePointerMove(event: InteractionEvent): void {\n if (!enabled || !isDrawing || !activeRegion) return;\n\n if (activeTool === \"rectangle\" || activeTool === \"circle\") {\n activeRegion.points[1] = pixelToData({ x: event.pixelX, y: event.pixelY });\n } else if (activeTool === \"lasso\") {\n // For lasso, we capture points during movement\n const lastPoint = activeRegion.points[activeRegion.points.length - 1];\n const newPoint = pixelToData({ x: event.pixelX, y: event.pixelY });\n \n // Basic distance filter to avoid too many points\n const dx = ctx!.coords.dataToPixelX(newPoint.x) - ctx!.coords.dataToPixelX(lastPoint.x);\n const dy = ctx!.coords.dataToPixelY(newPoint.y) - ctx!.coords.dataToPixelY(lastPoint.y);\n if (Math.sqrt(dx*dx + dy*dy) > 5) {\n activeRegion.points.push(newPoint);\n }\n } else if (activeTool === \"polygon\") {\n // Update the preview point (the last one)\n const lastIndex = activeRegion.points.length - 1;\n if (lastIndex >= 0) {\n activeRegion.points[lastIndex] = pixelToData({ x: event.pixelX, y: event.pixelY });\n }\n }\n ctx?.requestRender();\n }\n\n function handlePointerUp(_event: InteractionEvent): void {\n if (!isDrawing || !activeRegion) return;\n\n if (activeTool !== \"polygon\") {\n finishRegion();\n }\n }\n\n function drawRegion(region: RoiRegion, ctx2d: CanvasRenderingContext2D): void {\n const { tool, points, color, fill } = region;\n if (points.length < 1) return;\n\n const pixels = points.map((p) => dataToPixel(p));\n\n ctx2d.strokeStyle = color || \"#00f2ff\";\n ctx2d.fillStyle = fill || \"rgba(0, 242, 255, 0.15)\";\n ctx2d.lineWidth = 2;\n\n if (tool === \"rectangle\" && pixels.length >= 2) {\n const x = Math.min(pixels[0].x, pixels[1].x);\n const y = Math.min(pixels[0].y, pixels[1].y);\n const w = Math.abs(pixels[0].x - pixels[1].x);\n const h = Math.abs(pixels[0].y - pixels[1].y);\n ctx2d.fillRect(x, y, w, h);\n ctx2d.strokeRect(x, y, w, h);\n } else if (tool === \"circle\" && pixels.length >= 2) {\n const dx = pixels[1].x - pixels[0].x;\n const dy = pixels[1].y - pixels[0].y;\n const r = Math.sqrt(dx * dx + dy * dy);\n ctx2d.beginPath();\n ctx2d.arc(pixels[0].x, pixels[0].y, r, 0, Math.PI * 2);\n ctx2d.fill();\n ctx2d.stroke();\n } else if ((tool === \"polygon\" || tool === \"lasso\") && pixels.length >= 2) {\n ctx2d.beginPath();\n ctx2d.moveTo(pixels[0].x, pixels[0].y);\n pixels.slice(1).forEach((p) => ctx2d.lineTo(p.x, p.y));\n if (tool === \"lasso\") {\n ctx2d.closePath();\n } else if (!isDrawing || region !== activeRegion) {\n ctx2d.closePath();\n }\n ctx2d.fill();\n ctx2d.stroke();\n }\n }\n\n return {\n manifest,\n onInit(pluginCtx: PluginContext) {\n ctx = pluginCtx;\n const chart = ctx.chart as any;\n\n // Hijack series methods if masking is enabled\n originalUpdateSeries = chart.updateSeries.bind(chart);\n originalAddSeries = chart.addSeries.bind(chart);\n\n chart.addSeries = (options: any) => {\n if (options.id && options.data?.x) {\n rawDataStore.set(options.id, {\n x: new Float32Array(options.data.x),\n y: new Float32Array(options.data.y),\n });\n }\n if (isMasking && options.data?.x) {\n // Apply initial mask\n const raw = rawDataStore.get(options.id)!;\n const indices: number[] = [];\n for (let i = 0; i < raw.x.length; i++) {\n if (isPointInAnyRegion({ x: raw.x[i], y: raw.y[i] })) indices.push(i);\n }\n const fx = new Float32Array(indices.length);\n const fy = new Float32Array(indices.length);\n for (let i = 0; i < indices.length; i++) {\n fx[i] = raw.x[indices[i]];\n fy[i] = raw.y[indices[i]];\n }\n originalAddSeries({ ...options, data: { ...options.data, x: fx, y: fy } });\n } else {\n originalAddSeries(options);\n }\n };\n\n chart.updateSeries = (id: string, data: any) => {\n if (data.x) {\n rawDataStore.set(id, {\n x: new Float32Array(data.x),\n y: new Float32Array(data.y),\n });\n }\n if (isMasking && data.x) {\n const raw = rawDataStore.get(id)!;\n const indices: number[] = [];\n for (let i = 0; i < raw.x.length; i++) {\n if (isPointInAnyRegion({ x: raw.x[i], y: raw.y[i] })) indices.push(i);\n }\n const fx = new Float32Array(indices.length);\n const fy = new Float32Array(indices.length);\n for (let i = 0; i < indices.length; i++) {\n fx[i] = raw.x[indices[i]];\n fy[i] = raw.y[indices[i]];\n }\n originalUpdateSeries(id, { ...data, x: fx, y: fy });\n } else {\n originalUpdateSeries(id, data);\n }\n };\n },\n onDestroy() {\n if (ctx) {\n const chart = ctx.chart as any;\n chart.addSeries = originalAddSeries;\n chart.updateSeries = originalUpdateSeries;\n }\n ctx = null;\n rawDataStore.clear();\n },\n onInteraction(_pluginCtx: PluginContext, event: InteractionEvent) {\n if (event.type === \"mousedown\") handlePointerDown(event);\n if (event.type === \"mousemove\") handlePointerMove(event);\n if (event.type === \"mouseup\") handlePointerUp(event);\n \n // Handle double click to finish polygon\n if (event.type === \"mouseup\" && activeTool === \"polygon\" && isDrawing) {\n // Simple double click detection\n // For now, let's just use a more complex logic or a button if needed.\n // In this implementation, let's say 3 clicks on the same area or just let it be.\n }\n \n // Special: right click or double click to finish polygon\n if (event.originalEvent instanceof MouseEvent && event.originalEvent.detail === 2 && activeTool === \"polygon\") {\n finishRegion();\n event.preventDefault();\n }\n },\n onRenderOverlay(pluginCtx: PluginContext) {\n const ctx2d = pluginCtx.render.ctx2d;\n if (!ctx2d) return;\n\n regions.forEach((region) => drawRegion(region, ctx2d));\n if (activeRegion) drawRegion(activeRegion, ctx2d);\n },\n api: {\n setTool(tool: RoiTool) {\n activeTool = tool;\n if (isDrawing) finishRegion();\n },\n clear() {\n regions = [];\n activeRegion = null;\n isDrawing = false;\n if (isMasking) applyMasking();\n if (ctx) {\n ctx.events.emit(\"roi:cleared\", {});\n ctx.requestRender();\n }\n },\n getRegions() {\n return [...regions];\n },\n removeRegion(id: string) {\n regions = regions.filter((r) => r.id !== id);\n if (isMasking) applyMasking();\n if (ctx) ctx.requestRender();\n },\n calculateMasks,\n isEnabled: () => enabled,\n setEnabled: (e: boolean) => {\n enabled = e;\n },\n setMasking(mask: boolean) {\n isMasking = mask;\n if (mask) {\n applyMasking();\n } else {\n // Restore all original data\n if (ctx) {\n for (const [id, raw] of rawDataStore.entries()) {\n originalUpdateSeries(id, raw);\n }\n ctx.requestRender();\n }\n }\n },\n } as RoiAPI,\n };\n};\n\nexport type RoiEvent = \"roi:selected\" | \"roi:created\" | \"roi:cleared\";\n"],"names":["PluginROI","config","ctx","activeTool","regions","isDrawing","activeRegion","enabled","isMasking","rawDataStore","originalUpdateSeries","originalAddSeries","manifest","createRegion","tool","pixelToData","pixel","dataToPixel","point","isPointInAnyRegion","r","isPointInRegion","applyMasking","id","raw","indices","i","filteredX","filteredY","region","points","xMin","xMax","yMin","yMax","dx","dy","inside","j","xi","yi","xj","yj","calculateMasks","regionId","results","series","data","masks","finishRegion","event","s","handlePointerDown","previewPoint","startPoint","handlePointerMove","lastPoint","newPoint","lastIndex","handlePointerUp","_event","drawRegion","ctx2d","color","fill","pixels","p","x","y","w","h","pluginCtx","chart","options","_a","_b","fx","fy","_pluginCtx","e","mask"],"mappings":"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"}
1
+ {"version":3,"file":"roi.js","sources":["../../src/plugins/roi/index.ts"],"sourcesContent":["import type { PluginContext, InteractionEvent, PluginManifest } from \"../types\";\n\nexport interface RoiPoint {\n x: number;\n y: number;\n}\n\nexport interface RoiRegion {\n id: string;\n tool: \"rectangle\" | \"circle\" | \"polygon\" | \"lasso\";\n points: RoiPoint[];\n color?: string;\n fill?: string;\n}\n\nexport interface RoiMaskResult {\n regionId: string;\n seriesId: string;\n masks: boolean[];\n}\n\nexport interface RoiSelectedEvent {\n region: RoiRegion;\n seriesIds: string[];\n masks: RoiMaskResult[];\n}\n\nexport interface RoiAPI {\n setTool(tool: RoiTool): void;\n clear(): void;\n getRegions(): RoiRegion[];\n removeRegion(id: string): void;\n calculateMasks(regionId: string): RoiMaskResult[];\n isEnabled(): boolean;\n setEnabled(enabled: boolean): void;\n}\n\nexport type RoiTool = \"rectangle\" | \"circle\" | \"polygon\" | \"lasso\";\n\nexport interface PluginROIConfig {\n defaultTool?: RoiTool;\n stroke?: string;\n fill?: string;\n enabled?: boolean;\n mask?: boolean;\n}\n\nexport const PluginROI = (config: PluginROIConfig = {}) => {\n let ctx: PluginContext | null = null;\n let activeTool: RoiTool = config.defaultTool || \"rectangle\";\n let regions: RoiRegion[] = [];\n let isDrawing = false;\n let activeRegion: RoiRegion | null = null;\n let enabled = config.enabled !== false;\n let isMasking = config.mask === true;\n\n // Store for original data when masking is active\n const rawDataStore = new Map<string, { x: Float32Array; y: Float32Array }>();\n let originalUpdateSeries: any = null;\n let originalAddSeries: any = null;\n\n const manifest: PluginManifest = {\n name: \"roi\",\n description: \"Region of Interest selection tool and masking\",\n version: \"1.1.0\",\n author: \"VeloPlot\",\n };\n\n function createRegion(tool: RoiTool): RoiRegion {\n return {\n id: Math.random().toString(36).substring(2, 11),\n tool,\n points: [],\n color: config.stroke || \"#00f2ff\",\n fill: config.fill || \"rgba(0, 242, 255, 0.15)\",\n };\n }\n\n function pixelToData(pixel: { x: number; y: number }): RoiPoint {\n if (!ctx) return { x: 0, y: 0 };\n return {\n x: ctx.coords.pixelToDataX(pixel.x),\n y: ctx.coords.pixelToDataY(pixel.y),\n };\n }\n\n function dataToPixel(point: RoiPoint): { x: number; y: number } {\n if (!ctx) return { x: 0, y: 0 };\n return {\n x: ctx.coords.dataToPixelX(point.x),\n y: ctx.coords.dataToPixelY(point.y),\n };\n }\n\n function isPointInAnyRegion(point: RoiPoint): boolean {\n if (regions.length === 0) return true; // Show all if no regions defined\n return regions.some((r) => isPointInRegion(point, r));\n }\n\n function applyMasking(): void {\n if (!ctx || !isMasking) return;\n\n for (const [id, raw] of rawDataStore.entries()) {\n const indices: number[] = [];\n for (let i = 0; i < raw.x.length; i++) {\n if (isPointInAnyRegion({ x: raw.x[i], y: raw.y[i] })) {\n indices.push(i);\n }\n }\n\n const filteredX = new Float32Array(indices.length);\n const filteredY = new Float32Array(indices.length);\n for (let i = 0; i < indices.length; i++) {\n filteredX[i] = raw.x[indices[i]];\n filteredY[i] = raw.y[indices[i]];\n }\n\n if (originalUpdateSeries) {\n originalUpdateSeries(id, { x: filteredX, y: filteredY });\n }\n }\n }\n\n function isPointInRegion(point: RoiPoint, region: RoiRegion): boolean {\n const { tool, points } = region;\n if (points.length < 2) return false;\n\n if (tool === \"rectangle\") {\n const xMin = Math.min(points[0].x, points[1].x);\n const xMax = Math.max(points[0].x, points[1].x);\n const yMin = Math.min(points[0].y, points[1].y);\n const yMax = Math.max(points[0].y, points[1].y);\n return point.x >= xMin && point.x <= xMax && point.y >= yMin && point.y <= yMax;\n }\n\n if (tool === \"circle\") {\n const dx = point.x - points[0].x;\n const dy = point.y - points[0].y;\n const r = Math.sqrt(\n Math.pow(points[1].x - points[0].x, 2) + Math.pow(points[1].y - points[0].y, 2)\n );\n return Math.sqrt(dx * dx + dy * dy) <= r;\n }\n\n if (tool === \"polygon\" || tool === \"lasso\") {\n // Ray casting algorithm\n let inside = false;\n for (let i = 0, j = points.length - 1; i < points.length; j = i++) {\n const xi = points[i].x, yi = points[i].y;\n const xj = points[j].x, yj = points[j].y;\n const intersect = yi > point.y !== yj > point.y &&\n point.x < ((xj - xi) * (point.y - yi)) / (yj - yi) + xi;\n if (intersect) inside = !inside;\n }\n return inside;\n }\n\n return false;\n }\n\n function calculateMasks(regionId: string): RoiMaskResult[] {\n const region = regions.find((r) => r.id === regionId);\n if (!region || !ctx) return [];\n\n const results: RoiMaskResult[] = [];\n ctx.chart.getAllSeries().forEach((series) => {\n const data = series.getData();\n if (!data) return;\n\n const masks = new Array(data.x.length);\n for (let i = 0; i < data.x.length; i++) {\n masks[i] = isPointInRegion({ x: data.x[i], y: data.y[i] }, region);\n }\n\n results.push({\n regionId,\n seriesId: series.getId(),\n masks,\n });\n });\n\n return results;\n }\n\n function finishRegion(): void {\n if (!activeRegion || !ctx) return;\n \n // Clean up preview points for polygon\n if (activeRegion.tool === \"polygon\" && activeRegion.points.length > 1) {\n // Remove the preview point\n activeRegion.points.pop();\n }\n\n regions.push(activeRegion);\n\n if (isMasking) {\n applyMasking();\n }\n\n const event: RoiSelectedEvent = {\n region: activeRegion,\n seriesIds: ctx.chart.getAllSeries().map((s) => s.getId()),\n masks: calculateMasks(activeRegion.id),\n };\n\n // Emit on both plugin context and chart\n ctx.events.emit(\"roi:selected\", event);\n if (ctx.chart.events) {\n ctx.chart.events.emit(\"roi:selected\" as any, event);\n }\n \n ctx.events.emit(\"roi:created\", {\n region: activeRegion,\n seriesIds: event.seriesIds,\n });\n\n activeRegion = null;\n isDrawing = false;\n ctx.requestRender();\n }\n\n function handlePointerDown(event: InteractionEvent): void {\n if (!enabled || !event.inPlotArea) return;\n\n if (activeTool === \"polygon\" && activeRegion) {\n // For polygon, we keep adding points on click\n // But first, replace the preview point with a permanent one\n const previewPoint = pixelToData({ x: event.pixelX, y: event.pixelY });\n activeRegion.points.push(previewPoint);\n event.preventDefault();\n ctx?.requestRender();\n return;\n }\n\n isDrawing = true;\n activeRegion = createRegion(activeTool);\n const startPoint = pixelToData({ x: event.pixelX, y: event.pixelY });\n activeRegion.points.push(startPoint);\n \n if (activeTool === \"rectangle\" || activeTool === \"circle\") {\n activeRegion.points.push({ ...startPoint });\n } else if (activeTool === \"polygon\") {\n // Add a second point for preview\n activeRegion.points.push({ ...startPoint });\n }\n \n event.preventDefault(); // Stop chart from panning\n ctx?.requestRender();\n }\n\n function handlePointerMove(event: InteractionEvent): void {\n if (!enabled || !isDrawing || !activeRegion) return;\n\n if (activeTool === \"rectangle\" || activeTool === \"circle\") {\n activeRegion.points[1] = pixelToData({ x: event.pixelX, y: event.pixelY });\n } else if (activeTool === \"lasso\") {\n // For lasso, we capture points during movement\n const lastPoint = activeRegion.points[activeRegion.points.length - 1];\n const newPoint = pixelToData({ x: event.pixelX, y: event.pixelY });\n \n // Basic distance filter to avoid too many points\n const dx = ctx!.coords.dataToPixelX(newPoint.x) - ctx!.coords.dataToPixelX(lastPoint.x);\n const dy = ctx!.coords.dataToPixelY(newPoint.y) - ctx!.coords.dataToPixelY(lastPoint.y);\n if (Math.sqrt(dx*dx + dy*dy) > 5) {\n activeRegion.points.push(newPoint);\n }\n } else if (activeTool === \"polygon\") {\n // Update the preview point (the last one)\n const lastIndex = activeRegion.points.length - 1;\n if (lastIndex >= 0) {\n activeRegion.points[lastIndex] = pixelToData({ x: event.pixelX, y: event.pixelY });\n }\n }\n ctx?.requestRender();\n }\n\n function handlePointerUp(_event: InteractionEvent): void {\n if (!isDrawing || !activeRegion) return;\n\n if (activeTool !== \"polygon\") {\n finishRegion();\n }\n }\n\n function drawRegion(region: RoiRegion, ctx2d: CanvasRenderingContext2D): void {\n const { tool, points, color, fill } = region;\n if (points.length < 1) return;\n\n const pixels = points.map((p) => dataToPixel(p));\n\n ctx2d.strokeStyle = color || \"#00f2ff\";\n ctx2d.fillStyle = fill || \"rgba(0, 242, 255, 0.15)\";\n ctx2d.lineWidth = 2;\n\n if (tool === \"rectangle\" && pixels.length >= 2) {\n const x = Math.min(pixels[0].x, pixels[1].x);\n const y = Math.min(pixels[0].y, pixels[1].y);\n const w = Math.abs(pixels[0].x - pixels[1].x);\n const h = Math.abs(pixels[0].y - pixels[1].y);\n ctx2d.fillRect(x, y, w, h);\n ctx2d.strokeRect(x, y, w, h);\n } else if (tool === \"circle\" && pixels.length >= 2) {\n const dx = pixels[1].x - pixels[0].x;\n const dy = pixels[1].y - pixels[0].y;\n const r = Math.sqrt(dx * dx + dy * dy);\n ctx2d.beginPath();\n ctx2d.arc(pixels[0].x, pixels[0].y, r, 0, Math.PI * 2);\n ctx2d.fill();\n ctx2d.stroke();\n } else if ((tool === \"polygon\" || tool === \"lasso\") && pixels.length >= 2) {\n ctx2d.beginPath();\n ctx2d.moveTo(pixels[0].x, pixels[0].y);\n pixels.slice(1).forEach((p) => ctx2d.lineTo(p.x, p.y));\n if (tool === \"lasso\") {\n ctx2d.closePath();\n } else if (!isDrawing || region !== activeRegion) {\n ctx2d.closePath();\n }\n ctx2d.fill();\n ctx2d.stroke();\n }\n }\n\n return {\n manifest,\n onInit(pluginCtx: PluginContext) {\n ctx = pluginCtx;\n const chart = ctx.chart as any;\n\n // Hijack series methods if masking is enabled\n originalUpdateSeries = chart.updateSeries.bind(chart);\n originalAddSeries = chart.addSeries.bind(chart);\n\n chart.addSeries = (options: any) => {\n if (options.id && options.data?.x) {\n rawDataStore.set(options.id, {\n x: new Float32Array(options.data.x),\n y: new Float32Array(options.data.y),\n });\n }\n if (isMasking && options.data?.x) {\n // Apply initial mask\n const raw = rawDataStore.get(options.id)!;\n const indices: number[] = [];\n for (let i = 0; i < raw.x.length; i++) {\n if (isPointInAnyRegion({ x: raw.x[i], y: raw.y[i] })) indices.push(i);\n }\n const fx = new Float32Array(indices.length);\n const fy = new Float32Array(indices.length);\n for (let i = 0; i < indices.length; i++) {\n fx[i] = raw.x[indices[i]];\n fy[i] = raw.y[indices[i]];\n }\n originalAddSeries({ ...options, data: { ...options.data, x: fx, y: fy } });\n } else {\n originalAddSeries(options);\n }\n };\n\n chart.updateSeries = (id: string, data: any) => {\n if (data.x) {\n rawDataStore.set(id, {\n x: new Float32Array(data.x),\n y: new Float32Array(data.y),\n });\n }\n if (isMasking && data.x) {\n const raw = rawDataStore.get(id)!;\n const indices: number[] = [];\n for (let i = 0; i < raw.x.length; i++) {\n if (isPointInAnyRegion({ x: raw.x[i], y: raw.y[i] })) indices.push(i);\n }\n const fx = new Float32Array(indices.length);\n const fy = new Float32Array(indices.length);\n for (let i = 0; i < indices.length; i++) {\n fx[i] = raw.x[indices[i]];\n fy[i] = raw.y[indices[i]];\n }\n originalUpdateSeries(id, { ...data, x: fx, y: fy });\n } else {\n originalUpdateSeries(id, data);\n }\n };\n },\n onDestroy() {\n if (ctx) {\n const chart = ctx.chart as any;\n chart.addSeries = originalAddSeries;\n chart.updateSeries = originalUpdateSeries;\n }\n ctx = null;\n rawDataStore.clear();\n },\n onInteraction(_pluginCtx: PluginContext, event: InteractionEvent) {\n if (event.type === \"mousedown\") handlePointerDown(event);\n if (event.type === \"mousemove\") handlePointerMove(event);\n if (event.type === \"mouseup\") handlePointerUp(event);\n \n // Handle double click to finish polygon\n if (event.type === \"mouseup\" && activeTool === \"polygon\" && isDrawing) {\n // Simple double click detection\n // For now, let's just use a more complex logic or a button if needed.\n // In this implementation, let's say 3 clicks on the same area or just let it be.\n }\n \n // Special: right click or double click to finish polygon\n if (event.originalEvent instanceof MouseEvent && event.originalEvent.detail === 2 && activeTool === \"polygon\") {\n finishRegion();\n event.preventDefault();\n }\n },\n onRenderOverlay(pluginCtx: PluginContext) {\n const ctx2d = pluginCtx.render.ctx2d;\n if (!ctx2d) return;\n\n regions.forEach((region) => drawRegion(region, ctx2d));\n if (activeRegion) drawRegion(activeRegion, ctx2d);\n },\n api: {\n setTool(tool: RoiTool) {\n activeTool = tool;\n if (isDrawing) finishRegion();\n },\n clear() {\n regions = [];\n activeRegion = null;\n isDrawing = false;\n if (isMasking) applyMasking();\n if (ctx) {\n ctx.events.emit(\"roi:cleared\", {});\n ctx.requestRender();\n }\n },\n getRegions() {\n return [...regions];\n },\n removeRegion(id: string) {\n regions = regions.filter((r) => r.id !== id);\n if (isMasking) applyMasking();\n if (ctx) ctx.requestRender();\n },\n calculateMasks,\n isEnabled: () => enabled,\n setEnabled: (e: boolean) => {\n enabled = e;\n },\n setMasking(mask: boolean) {\n isMasking = mask;\n if (mask) {\n applyMasking();\n } else {\n // Restore all original data\n if (ctx) {\n for (const [id, raw] of rawDataStore.entries()) {\n originalUpdateSeries(id, raw);\n }\n ctx.requestRender();\n }\n }\n },\n } as RoiAPI,\n };\n};\n\nexport type RoiEvent = \"roi:selected\" | \"roi:created\" | \"roi:cleared\";\n"],"names":["PluginROI","config","ctx","activeTool","regions","isDrawing","activeRegion","enabled","isMasking","rawDataStore","originalUpdateSeries","originalAddSeries","manifest","createRegion","tool","pixelToData","pixel","dataToPixel","point","isPointInAnyRegion","r","isPointInRegion","applyMasking","id","raw","indices","i","filteredX","filteredY","region","points","xMin","xMax","yMin","yMax","dx","dy","inside","j","xi","yi","xj","yj","calculateMasks","regionId","results","series","data","masks","finishRegion","event","s","handlePointerDown","previewPoint","startPoint","handlePointerMove","lastPoint","newPoint","lastIndex","handlePointerUp","_event","drawRegion","ctx2d","color","fill","pixels","p","x","y","w","h","pluginCtx","chart","options","_a","_b","fx","fy","_pluginCtx","e","mask"],"mappings":"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"}
@@ -2,7 +2,7 @@ import { ChartPlugin } from '../types';
2
2
  import { PluginSnapshotConfig } from './types';
3
3
 
4
4
  /**
5
- * SciPlot Snapshot Plugin
5
+ * VeloPlot Snapshot Plugin
6
6
  *
7
7
  * Captures the current chart view with all layers (WebGL + Overlay).
8
8
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * SciPlot - Snapshot Export Plugin Types
2
+ * VeloPlot - Snapshot Export Plugin Types
3
3
  */
4
4
  export type SnapshotFormat = 'png' | 'jpeg' | 'webp' | 'svg';
5
5
  /**
@@ -1,3 +1,3 @@
1
1
  export * from './snapshot/index'
2
- import SciPlot from './snapshot/index'
3
- export default SciPlot
2
+ import VeloPlot from './snapshot/index'
3
+ export default VeloPlot
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.js","sources":["../../src/plugins/snapshot/index.ts"],"sourcesContent":["/**\n * SciPlot - Snapshot Plugin\n * \n * Provides high-resolution image export capabilities.\n * Supports different formats (PNG, JPEG, WebP) and resolutions (Standard, 2K, 4K, 8K).\n * \n * @module plugins/snapshot\n */\n\nimport type { \n PluginManifest, \n ChartPlugin, \n PluginContext,\n} from '../types';\n\nimport type {\n PluginSnapshotConfig,\n SnapshotExportAPI,\n SnapshotExportOptions,\n SnapshotResolution,\n} from './types';\n\nconst manifestSnapshot: PluginManifest = {\n name: \"velo-plot-snapshot\",\n version: \"1.0.0\",\n description: \"High-resolution image export for velo-plot\",\n provides: [\"export\", \"snapshot\"],\n tags: [\"snapshot\", \"export\", \"publication\", \"image\"],\n};\n\nconst DEFAULT_OPTIONS: Required<SnapshotExportOptions> = {\n format: 'png',\n quality: 0.9,\n resolution: 'standard',\n includeBackground: true,\n includeOverlays: true,\n watermarkText: '',\n transparent: false,\n fileName: 'velo-plot-snapshot-export',\n download: false\n};\n\nfunction resolutionToScale(res: SnapshotResolution): number {\n if (typeof res === 'number') return res;\n switch (res) {\n case '8k': return 8;\n case '4k': return 4;\n case '2k': return 2;\n case 'standard': return 1;\n default: return 1;\n }\n}\n\n/**\n * SciPlot Snapshot Plugin\n * \n * Captures the current chart view with all layers (WebGL + Overlay).\n */\nexport function PluginSnapshot(\n config: PluginSnapshotConfig = {}\n): ChartPlugin<PluginSnapshotConfig> {\n let ctx: PluginContext | null = null;\n\n /**\n * Captures the chart as an image\n */\n async function takeSnapshot(options: SnapshotExportOptions = {}): Promise<string | Blob> {\n if (!ctx) throw new Error(\"Snapshot plugin not initialized\");\n \n const opt = { ...DEFAULT_OPTIONS, ...config.defaultOptions, ...options };\n const chart = ctx.chart;\n \n // 1. Determine target resolution scale\n const scale = resolutionToScale(opt.resolution);\n const originalDPR = chart.getDPR();\n \n try {\n if (opt.format === 'svg') {\n const svg = chart.exportSVG();\n if (opt.download) {\n const blob = new Blob([svg], { type: 'image/svg+xml' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.download = `${opt.fileName}.svg`;\n link.href = url;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n }\n return svg;\n }\n\n // High-res re-render if scale > 1.\n // We temporarily lock the device pixel ratio to force a higher-resolution\n // render. Using an explicit override (instead of setDPR) is essential:\n // a plain setDPR gets reverted by the very next resize() call, so the\n // backing stores would stay at screen resolution and every preset would\n // look identical / pixelated. The override survives resize().\n if (scale > 1) {\n if (typeof chart.setDevicePixelRatioOverride === 'function') {\n chart.setDevicePixelRatioOverride(originalDPR * scale);\n } else {\n chart.setDPR(originalDPR * scale);\n }\n // Force a synchronous full render at the boosted DPR before capture.\n if (typeof chart.render === 'function') {\n chart.render();\n }\n // Wait for DOM and GL updates\n await new Promise(r => requestAnimationFrame(r));\n // Second frame ensures the resized backing store has actually been painted.\n await new Promise(r => requestAnimationFrame(r));\n // Small delay to ensure all overlays (which might have their own throttles) are ready\n await new Promise(r => setTimeout(r, 100));\n }\n\n const webglCanvas = (ctx.render.gl?.canvas) as HTMLCanvasElement;\n const overlayCanvas = (ctx.render.ctx2d?.canvas) as HTMLCanvasElement;\n \n if (!webglCanvas) throw new Error(\"WebGL canvas not found\");\n\n // 3. Compose layers into a final canvas\n const compositionCanvas = document.createElement('canvas');\n compositionCanvas.width = webglCanvas.width;\n compositionCanvas.height = webglCanvas.height;\n const compCtx = compositionCanvas.getContext('2d')!;\n \n // Fill background if not transparent\n if (!opt.transparent && opt.includeBackground) {\n compCtx.fillStyle = ctx.ui.theme.backgroundColor || '#ffffff';\n compCtx.fillRect(0, 0, compositionCanvas.width, compositionCanvas.height);\n }\n \n // Draw WebGL layer (bottom)\n compCtx.drawImage(webglCanvas, 0, 0);\n \n // Draw Overlay layer (top) - contains annotations, tooltips, etc.\n if (opt.includeOverlays && overlayCanvas) {\n compCtx.drawImage(overlayCanvas, 0, 0);\n }\n \n // Apply Watermark\n if (opt.watermarkText) {\n drawWatermark(compCtx, opt.watermarkText, compositionCanvas.width, compositionCanvas.height, originalDPR * scale);\n }\n \n const mimeType = `image/${opt.format}`;\n const dataUrl = compositionCanvas.toDataURL(mimeType, opt.quality);\n \n // Automatic download if requested\n if (opt.download) {\n const extension = opt.format === 'jpeg' ? 'jpg' : opt.format;\n const link = document.createElement('a');\n link.download = `${opt.fileName}.${extension}`;\n link.href = dataUrl;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n \n return dataUrl;\n } finally {\n // 4. Restore original resolution\n if (scale > 1) {\n if (typeof chart.setDevicePixelRatioOverride === 'function') {\n chart.setDevicePixelRatioOverride(null);\n } else {\n chart.setDPR(originalDPR);\n }\n }\n }\n }\n\n /**\n * Helper to draw a watermark on the captured image\n */\n function drawWatermark(c: CanvasRenderingContext2D, text: string, w: number, h: number, dpr: number) {\n c.save();\n // Scale font size according to DPR\n const fontSize = Math.max(16, 24 * (dpr / 2));\n c.font = `bold ${fontSize}px Inter, system-ui, sans-serif`;\n c.fillStyle = 'rgba(128, 128, 128, 0.4)';\n c.textAlign = 'right';\n c.textBaseline = 'bottom';\n c.fillText(text, w - (20 * dpr/2), h - (20 * dpr/2));\n c.restore();\n }\n\n const api: SnapshotExportAPI & Record<string, unknown> = {\n takeSnapshot,\n downloadSnapshot: async (opt: SnapshotExportOptions) => {\n await takeSnapshot({ ...opt, download: true });\n }\n };\n\n return {\n manifest: manifestSnapshot,\n onInit(c) { \n ctx = c; \n ctx.log.info(\"Snapshot plugin initialized\");\n },\n onDestroy() {\n ctx = null;\n },\n api\n };\n}\n\nexport default PluginSnapshot;\n\nexport type {\n SnapshotFormat,\n SnapshotResolution,\n SnapshotExportOptions,\n SnapshotExportAPI,\n PluginSnapshotConfig\n} from './types';\n"],"names":["manifestSnapshot","DEFAULT_OPTIONS","resolutionToScale","res","PluginSnapshot","config","ctx","takeSnapshot","options","_a","_b","opt","chart","scale","originalDPR","svg","blob","url","link","r","webglCanvas","overlayCanvas","compositionCanvas","compCtx","drawWatermark","mimeType","dataUrl","extension","c","text","w","h","dpr","fontSize"],"mappings":"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"}
1
+ {"version":3,"file":"snapshot.js","sources":["../../src/plugins/snapshot/index.ts"],"sourcesContent":["/**\n * VeloPlot - Snapshot Plugin\n * \n * Provides high-resolution image export capabilities.\n * Supports different formats (PNG, JPEG, WebP) and resolutions (Standard, 2K, 4K, 8K).\n * \n * @module plugins/snapshot\n */\n\nimport type { \n PluginManifest, \n ChartPlugin, \n PluginContext,\n} from '../types';\n\nimport type {\n PluginSnapshotConfig,\n SnapshotExportAPI,\n SnapshotExportOptions,\n SnapshotResolution,\n} from './types';\n\nconst manifestSnapshot: PluginManifest = {\n name: \"velo-plot-snapshot\",\n version: \"1.0.0\",\n description: \"High-resolution image export for velo-plot\",\n provides: [\"export\", \"snapshot\"],\n tags: [\"snapshot\", \"export\", \"publication\", \"image\"],\n};\n\nconst DEFAULT_OPTIONS: Required<SnapshotExportOptions> = {\n format: 'png',\n quality: 0.9,\n resolution: 'standard',\n includeBackground: true,\n includeOverlays: true,\n watermarkText: '',\n transparent: false,\n fileName: 'velo-plot-snapshot-export',\n download: false\n};\n\nfunction resolutionToScale(res: SnapshotResolution): number {\n if (typeof res === 'number') return res;\n switch (res) {\n case '8k': return 8;\n case '4k': return 4;\n case '2k': return 2;\n case 'standard': return 1;\n default: return 1;\n }\n}\n\n/**\n * VeloPlot Snapshot Plugin\n * \n * Captures the current chart view with all layers (WebGL + Overlay).\n */\nexport function PluginSnapshot(\n config: PluginSnapshotConfig = {}\n): ChartPlugin<PluginSnapshotConfig> {\n let ctx: PluginContext | null = null;\n\n /**\n * Captures the chart as an image\n */\n async function takeSnapshot(options: SnapshotExportOptions = {}): Promise<string | Blob> {\n if (!ctx) throw new Error(\"Snapshot plugin not initialized\");\n \n const opt = { ...DEFAULT_OPTIONS, ...config.defaultOptions, ...options };\n const chart = ctx.chart;\n \n // 1. Determine target resolution scale\n const scale = resolutionToScale(opt.resolution);\n const originalDPR = chart.getDPR();\n \n try {\n if (opt.format === 'svg') {\n const svg = chart.exportSVG();\n if (opt.download) {\n const blob = new Blob([svg], { type: 'image/svg+xml' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.download = `${opt.fileName}.svg`;\n link.href = url;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n }\n return svg;\n }\n\n // High-res re-render if scale > 1.\n // We temporarily lock the device pixel ratio to force a higher-resolution\n // render. Using an explicit override (instead of setDPR) is essential:\n // a plain setDPR gets reverted by the very next resize() call, so the\n // backing stores would stay at screen resolution and every preset would\n // look identical / pixelated. The override survives resize().\n if (scale > 1) {\n if (typeof chart.setDevicePixelRatioOverride === 'function') {\n chart.setDevicePixelRatioOverride(originalDPR * scale);\n } else {\n chart.setDPR(originalDPR * scale);\n }\n // Force a synchronous full render at the boosted DPR before capture.\n if (typeof chart.render === 'function') {\n chart.render();\n }\n // Wait for DOM and GL updates\n await new Promise(r => requestAnimationFrame(r));\n // Second frame ensures the resized backing store has actually been painted.\n await new Promise(r => requestAnimationFrame(r));\n // Small delay to ensure all overlays (which might have their own throttles) are ready\n await new Promise(r => setTimeout(r, 100));\n }\n\n const webglCanvas = (ctx.render.gl?.canvas) as HTMLCanvasElement;\n const overlayCanvas = (ctx.render.ctx2d?.canvas) as HTMLCanvasElement;\n \n if (!webglCanvas) throw new Error(\"WebGL canvas not found\");\n\n // 3. Compose layers into a final canvas\n const compositionCanvas = document.createElement('canvas');\n compositionCanvas.width = webglCanvas.width;\n compositionCanvas.height = webglCanvas.height;\n const compCtx = compositionCanvas.getContext('2d')!;\n \n // Fill background if not transparent\n if (!opt.transparent && opt.includeBackground) {\n compCtx.fillStyle = ctx.ui.theme.backgroundColor || '#ffffff';\n compCtx.fillRect(0, 0, compositionCanvas.width, compositionCanvas.height);\n }\n \n // Draw WebGL layer (bottom)\n compCtx.drawImage(webglCanvas, 0, 0);\n \n // Draw Overlay layer (top) - contains annotations, tooltips, etc.\n if (opt.includeOverlays && overlayCanvas) {\n compCtx.drawImage(overlayCanvas, 0, 0);\n }\n \n // Apply Watermark\n if (opt.watermarkText) {\n drawWatermark(compCtx, opt.watermarkText, compositionCanvas.width, compositionCanvas.height, originalDPR * scale);\n }\n \n const mimeType = `image/${opt.format}`;\n const dataUrl = compositionCanvas.toDataURL(mimeType, opt.quality);\n \n // Automatic download if requested\n if (opt.download) {\n const extension = opt.format === 'jpeg' ? 'jpg' : opt.format;\n const link = document.createElement('a');\n link.download = `${opt.fileName}.${extension}`;\n link.href = dataUrl;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n \n return dataUrl;\n } finally {\n // 4. Restore original resolution\n if (scale > 1) {\n if (typeof chart.setDevicePixelRatioOverride === 'function') {\n chart.setDevicePixelRatioOverride(null);\n } else {\n chart.setDPR(originalDPR);\n }\n }\n }\n }\n\n /**\n * Helper to draw a watermark on the captured image\n */\n function drawWatermark(c: CanvasRenderingContext2D, text: string, w: number, h: number, dpr: number) {\n c.save();\n // Scale font size according to DPR\n const fontSize = Math.max(16, 24 * (dpr / 2));\n c.font = `bold ${fontSize}px Inter, system-ui, sans-serif`;\n c.fillStyle = 'rgba(128, 128, 128, 0.4)';\n c.textAlign = 'right';\n c.textBaseline = 'bottom';\n c.fillText(text, w - (20 * dpr/2), h - (20 * dpr/2));\n c.restore();\n }\n\n const api: SnapshotExportAPI & Record<string, unknown> = {\n takeSnapshot,\n downloadSnapshot: async (opt: SnapshotExportOptions) => {\n await takeSnapshot({ ...opt, download: true });\n }\n };\n\n return {\n manifest: manifestSnapshot,\n onInit(c) { \n ctx = c; \n ctx.log.info(\"Snapshot plugin initialized\");\n },\n onDestroy() {\n ctx = null;\n },\n api\n };\n}\n\nexport default PluginSnapshot;\n\nexport type {\n SnapshotFormat,\n SnapshotResolution,\n SnapshotExportOptions,\n SnapshotExportAPI,\n PluginSnapshotConfig\n} from './types';\n"],"names":["manifestSnapshot","DEFAULT_OPTIONS","resolutionToScale","res","PluginSnapshot","config","ctx","takeSnapshot","options","_a","_b","opt","chart","scale","originalDPR","svg","blob","url","link","r","webglCanvas","overlayCanvas","compositionCanvas","compCtx","drawWatermark","mimeType","dataUrl","extension","c","text","w","h","dpr","fontSize"],"mappings":"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"}