velo-plot 3.1.0 → 4.0.0-alpha.1

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 (116) hide show
  1. package/dist/{ChartCore-AnR_3Xkb.js → ChartCore-KYG2HTcK.js} +1349 -1213
  2. package/dist/ChartCore-KYG2HTcK.js.map +1 -0
  3. package/dist/{PluginRegistry-CzMHebYP.js → PluginRegistry-CDf_jcnp.js} +2 -2
  4. package/dist/{PluginRegistry-CzMHebYP.js.map → PluginRegistry-CDf_jcnp.js.map} +1 -1
  5. package/dist/SVGDocumentBuilder-C-uLkcFW.js +83 -0
  6. package/dist/SVGDocumentBuilder-C-uLkcFW.js.map +1 -0
  7. package/dist/angular-hooks.js +1 -1
  8. package/dist/angular.js +4 -4
  9. package/dist/{chartSyncBridge-D_rCtbFq.js → chartSyncBridge-C1uRy0ZS.js} +3 -3
  10. package/dist/{chartSyncBridge-D_rCtbFq.js.map → chartSyncBridge-C1uRy0ZS.js.map} +1 -1
  11. package/dist/core/chart/ChartCore.d.ts +7 -3
  12. package/dist/core/chart/ChartRenderLoop.d.ts +5 -0
  13. package/dist/core/chart/ChartRenderer.d.ts +9 -0
  14. package/dist/core/chart/ChartSetup.d.ts +1 -0
  15. package/dist/core/chart/exporter/SVGExporter.d.ts +9 -7
  16. package/dist/core/chart/exporter/svg/SVGDocumentBuilder.d.ts +27 -0
  17. package/dist/core/chart/exporter/svg/SVGExportContext.d.ts +147 -0
  18. package/dist/core/chart/exporter/svg/SVGOrchestrator.d.ts +3 -0
  19. package/dist/core/chart/exporter/svg/SVGThemeAdapter.d.ts +22 -0
  20. package/dist/core/chart/exporter/svg/__tests__/testFixtures.d.ts +46 -0
  21. package/dist/core/chart/exporter/svg/__tests__/visualTestUtils.d.ts +12 -0
  22. package/dist/core/chart/exporter/svg/overlay/axes.d.ts +4 -0
  23. package/dist/core/chart/exporter/svg/overlay/border.d.ts +4 -0
  24. package/dist/core/chart/exporter/svg/overlay/errorBars.d.ts +7 -0
  25. package/dist/core/chart/exporter/svg/overlay/grid.d.ts +4 -0
  26. package/dist/core/chart/exporter/svg/overlay/index.d.ts +12 -0
  27. package/dist/core/chart/exporter/svg/overlay/legend.d.ts +4 -0
  28. package/dist/core/chart/exporter/svg/overlay/pluginCharts.d.ts +6 -0
  29. package/dist/core/chart/exporter/svg/overlay/polarGrid.d.ts +4 -0
  30. package/dist/core/chart/exporter/svg/overlay/specialChart.d.ts +15 -0
  31. package/dist/core/chart/exporter/svg/overlay/title.d.ts +4 -0
  32. package/dist/core/chart/exporter/svg/plugins/annotations.d.ts +5 -0
  33. package/dist/core/chart/exporter/svg/plugins/brokenAxis.d.ts +20 -0
  34. package/dist/core/chart/exporter/svg/plugins/latex.d.ts +9 -0
  35. package/dist/core/chart/exporter/svg/plugins/register.d.ts +8 -0
  36. package/dist/core/chart/exporter/svg/plugins/regression.d.ts +33 -0
  37. package/dist/core/chart/exporter/svg/plugins/roi.d.ts +12 -0
  38. package/dist/core/chart/exporter/svg/plugins/tradeMarkers.d.ts +3 -0
  39. package/dist/core/chart/exporter/svg/plugins/types.d.ts +28 -0
  40. package/dist/core/chart/exporter/svg/plugins/watermark.d.ts +13 -0
  41. package/dist/core/chart/exporter/svg/series/band.d.ts +6 -0
  42. package/dist/core/chart/exporter/svg/series/bar.d.ts +6 -0
  43. package/dist/core/chart/exporter/svg/series/boxplot.d.ts +6 -0
  44. package/dist/core/chart/exporter/svg/series/candlestick.d.ts +6 -0
  45. package/dist/core/chart/exporter/svg/series/finitePoints.d.ts +6 -0
  46. package/dist/core/chart/exporter/svg/series/gauge.d.ts +5 -0
  47. package/dist/core/chart/exporter/svg/series/heatmap.d.ts +6 -0
  48. package/dist/core/chart/exporter/svg/series/indicator.d.ts +6 -0
  49. package/dist/core/chart/exporter/svg/series/line.d.ts +12 -0
  50. package/dist/core/chart/exporter/svg/series/polar.d.ts +6 -0
  51. package/dist/core/chart/exporter/svg/series/radar.d.ts +5 -0
  52. package/dist/core/chart/exporter/svg/series/registry.d.ts +10 -0
  53. package/dist/core/chart/exporter/svg/series/sankey.d.ts +5 -0
  54. package/dist/core/chart/exporter/svg/series/scatter.d.ts +1 -0
  55. package/dist/core/chart/exporter/svg/series/ternary.d.ts +7 -0
  56. package/dist/core/chart/exporter/svg/series/waterfall.d.ts +6 -0
  57. package/dist/core/chart/exporter/svg/seriesAtTimestamp.d.ts +4 -0
  58. package/dist/core/chart/exporter/svg/seriesUtils.d.ts +3 -0
  59. package/dist/core/chart/exporter/svg/symbols.d.ts +5 -0
  60. package/dist/core/chart/exporter/svg/tickUtils.d.ts +9 -0
  61. package/dist/core/chart/mountSVGString.d.ts +5 -0
  62. package/dist/core/chart/types.d.ts +2 -2
  63. package/dist/core/stacked/StackSVGComposer.d.ts +14 -0
  64. package/dist/core/stacked/index.d.ts +3 -2
  65. package/dist/core/stacked/types.d.ts +12 -4
  66. package/dist/createStackedChart-DjA3aJAu.js +2761 -0
  67. package/dist/createStackedChart-DjA3aJAu.js.map +1 -0
  68. package/dist/{hooks-DH-3bewj.js → hooks-4wQH27r9.js} +3 -3
  69. package/dist/{hooks-DH-3bewj.js.map → hooks-4wQH27r9.js.map} +1 -1
  70. package/dist/index-Bj-xyXY6.js +582 -0
  71. package/dist/index-Bj-xyXY6.js.map +1 -0
  72. package/dist/plugins/PluginManager.d.ts +5 -0
  73. package/dist/plugins/annotations.js +8 -7
  74. package/dist/plugins/annotations.js.map +1 -1
  75. package/dist/plugins/broken-axis.js +198 -152
  76. package/dist/plugins/broken-axis.js.map +1 -1
  77. package/dist/plugins/forecasting.js +273 -258
  78. package/dist/plugins/forecasting.js.map +1 -1
  79. package/dist/plugins/ml-integration.js +107 -93
  80. package/dist/plugins/ml-integration.js.map +1 -1
  81. package/dist/plugins/radar/types.d.ts +11 -0
  82. package/dist/plugins/radar.js +64 -53
  83. package/dist/plugins/radar.js.map +1 -1
  84. package/dist/plugins/roi/index.d.ts +2 -0
  85. package/dist/plugins/roi.js +184 -145
  86. package/dist/plugins/roi.js.map +1 -1
  87. package/dist/plugins/snapshot.js +20 -15
  88. package/dist/plugins/snapshot.js.map +1 -1
  89. package/dist/plugins/types.d.ts +4 -0
  90. package/dist/react.js +2 -2
  91. package/dist/regression-HNdyk1Dm.js +28 -0
  92. package/dist/regression-HNdyk1Dm.js.map +1 -0
  93. package/dist/renderer/ChartSeriesRenderer.d.ts +3 -2
  94. package/dist/renderer/SVGChartRenderer.d.ts +15 -0
  95. package/dist/renderer/SankeyRenderer.d.ts +1 -0
  96. package/dist/renderer/registerSVG.d.ts +5 -0
  97. package/dist/renderer/sankeyLayout.d.ts +29 -0
  98. package/dist/scientific.js +2 -2
  99. package/dist/solid.js +2 -2
  100. package/dist/svelte.js +2 -2
  101. package/dist/tickUtils-B_X-ha13.js +41 -0
  102. package/dist/tickUtils-B_X-ha13.js.map +1 -0
  103. package/dist/trading.js +3 -3
  104. package/dist/types.d.ts +2 -1
  105. package/dist/velo-plot.full.js +1107 -1292
  106. package/dist/velo-plot.full.js.map +1 -1
  107. package/dist/velo-plot.js +2 -2
  108. package/dist/vue/VeloPlot.vue.d.ts +1 -1
  109. package/dist/vue/index.d.ts +33 -33
  110. package/dist/vue.js +2 -2
  111. package/package.json +6 -1
  112. package/dist/ChartCore-AnR_3Xkb.js.map +0 -1
  113. package/dist/createStackedChart-DqcLCFGS.js +0 -1338
  114. package/dist/createStackedChart-DqcLCFGS.js.map +0 -1
  115. package/dist/index-Cv6ZDLWf.js +0 -521
  116. package/dist/index-Cv6ZDLWf.js.map +0 -1
@@ -1,223 +1,262 @@
1
- const v = (M = {}) => {
2
- let o = null, u = M.defaultTool || "rectangle", x = [], h = !1, a = null, P = M.enabled !== !1, d = M.mask === !0;
1
+ import { f as M } from "../SVGDocumentBuilder-C-uLkcFW.js";
2
+ import { p as j } from "../tickUtils-B_X-ha13.js";
3
+ function O(p, i) {
4
+ if (!p.builder || i.length === 0) return;
5
+ const h = j(p.yScales);
6
+ if (!h) return;
7
+ const m = (u) => ({
8
+ x: p.xScale.transform(u.x),
9
+ y: h.transform(u.y)
10
+ });
11
+ for (const u of i) {
12
+ const l = u.color ?? "#00f2ff", w = u.fill ?? "rgba(0, 242, 255, 0.15)", c = u.points.map(m);
13
+ if (!(c.length < 2)) {
14
+ if (u.tool === "rectangle") {
15
+ const g = Math.min(c[0].x, c[1].x), d = Math.min(c[0].y, c[1].y), P = Math.abs(c[1].x - c[0].x), S = Math.abs(c[1].y - c[0].y);
16
+ p.builder.push(
17
+ "plugins",
18
+ `<rect x="${M(g)}" y="${M(d)}" width="${M(P)}" height="${M(S)}" fill="${w}" stroke="${l}" stroke-width="1.5"/>`
19
+ );
20
+ } else if (u.tool === "circle") {
21
+ const g = c[1].x - c[0].x, d = c[1].y - c[0].y, P = Math.sqrt(g * g + d * d);
22
+ p.builder.push(
23
+ "plugins",
24
+ `<circle cx="${M(c[0].x)}" cy="${M(c[0].y)}" r="${M(P)}" fill="${w}" stroke="${l}" stroke-width="1.5"/>`
25
+ );
26
+ } else if (u.tool === "polygon" || u.tool === "lasso") {
27
+ const g = c.map((d) => `${M(d.x)},${M(d.y)}`).join(" ");
28
+ p.builder.push(
29
+ "plugins",
30
+ `<polygon points="${g}" fill="${w}" stroke="${l}" stroke-width="1.5"/>`
31
+ );
32
+ }
33
+ }
34
+ }
35
+ }
36
+ const _ = (p = {}) => {
37
+ let i = null, h = p.defaultTool || "rectangle", m = [], u = !1, l = null, w = p.enabled !== !1, c = p.mask === !0;
3
38
  const g = /* @__PURE__ */ new Map();
4
- let p = null, R = null;
5
- const q = {
39
+ let d = null, P = null;
40
+ const S = {
6
41
  name: "roi",
7
42
  description: "Region of Interest selection tool and masking",
8
43
  version: "1.1.0",
9
44
  author: "VeloPlot"
10
45
  };
11
- function D(t) {
46
+ function D(e) {
12
47
  return {
13
48
  id: Math.random().toString(36).substring(2, 11),
14
- tool: t,
49
+ tool: e,
15
50
  points: [],
16
- color: M.stroke || "#00f2ff",
17
- fill: M.fill || "rgba(0, 242, 255, 0.15)"
51
+ color: p.stroke || "#00f2ff",
52
+ fill: p.fill || "rgba(0, 242, 255, 0.15)"
18
53
  };
19
54
  }
20
- function m(t) {
21
- return o ? {
22
- x: o.coords.pixelToDataX(t.x),
23
- y: o.coords.pixelToDataY(t.y)
55
+ function R(e) {
56
+ return i ? {
57
+ x: i.coords.pixelToDataX(e.x),
58
+ y: i.coords.pixelToDataY(e.y)
24
59
  } : { x: 0, y: 0 };
25
60
  }
26
- function F(t) {
27
- return o ? {
28
- x: o.coords.dataToPixelX(t.x),
29
- y: o.coords.dataToPixelY(t.y)
61
+ function Y(e) {
62
+ return i ? {
63
+ x: i.coords.dataToPixelX(e.x),
64
+ y: i.coords.dataToPixelY(e.y)
30
65
  } : { x: 0, y: 0 };
31
66
  }
32
- function T(t) {
33
- return x.length === 0 ? !0 : x.some((e) => b(t, e));
67
+ function A(e) {
68
+ return m.length === 0 ? !0 : m.some((t) => T(e, t));
34
69
  }
35
- function A() {
36
- if (!(!o || !d))
37
- for (const [t, e] of g.entries()) {
70
+ function k() {
71
+ if (!(!i || !c))
72
+ for (const [e, t] of g.entries()) {
38
73
  const n = [];
39
- for (let s = 0; s < e.x.length; s++)
40
- T({ x: e.x[s], y: e.y[s] }) && n.push(s);
41
- const i = new Float32Array(n.length), l = new Float32Array(n.length);
74
+ for (let s = 0; s < t.x.length; s++)
75
+ A({ x: t.x[s], y: t.y[s] }) && n.push(s);
76
+ const o = new Float32Array(n.length), a = new Float32Array(n.length);
42
77
  for (let s = 0; s < n.length; s++)
43
- i[s] = e.x[n[s]], l[s] = e.y[n[s]];
44
- p && p(t, { x: i, y: l });
78
+ o[s] = t.x[n[s]], a[s] = t.y[n[s]];
79
+ d && d(e, { x: o, y: a });
45
80
  }
46
81
  }
47
- function b(t, e) {
48
- const { tool: n, points: i } = e;
49
- if (i.length < 2) return !1;
82
+ function T(e, t) {
83
+ const { tool: n, points: o } = t;
84
+ if (o.length < 2) return !1;
50
85
  if (n === "rectangle") {
51
- const l = Math.min(i[0].x, i[1].x), s = Math.max(i[0].x, i[1].x), r = Math.min(i[0].y, i[1].y), c = Math.max(i[0].y, i[1].y);
52
- return t.x >= l && t.x <= s && t.y >= r && t.y <= c;
86
+ const a = Math.min(o[0].x, o[1].x), s = Math.max(o[0].x, o[1].x), r = Math.min(o[0].y, o[1].y), y = Math.max(o[0].y, o[1].y);
87
+ return e.x >= a && e.x <= s && e.y >= r && e.y <= y;
53
88
  }
54
89
  if (n === "circle") {
55
- const l = t.x - i[0].x, s = t.y - i[0].y, r = Math.sqrt(
56
- Math.pow(i[1].x - i[0].x, 2) + Math.pow(i[1].y - i[0].y, 2)
90
+ const a = e.x - o[0].x, s = e.y - o[0].y, r = Math.sqrt(
91
+ Math.pow(o[1].x - o[0].x, 2) + Math.pow(o[1].y - o[0].y, 2)
57
92
  );
58
- return Math.sqrt(l * l + s * s) <= r;
93
+ return Math.sqrt(a * a + s * s) <= r;
59
94
  }
60
95
  if (n === "polygon" || n === "lasso") {
61
- let l = !1;
62
- for (let s = 0, r = i.length - 1; s < i.length; r = s++) {
63
- const c = i[s].x, f = i[s].y, y = i[r].x, w = i[r].y;
64
- f > t.y != w > t.y && t.x < (y - c) * (t.y - f) / (w - f) + c && (l = !l);
96
+ let a = !1;
97
+ for (let s = 0, r = o.length - 1; s < o.length; r = s++) {
98
+ const y = o[s].x, f = o[s].y, x = o[r].x, b = o[r].y;
99
+ f > e.y != b > e.y && e.x < (x - y) * (e.y - f) / (b - f) + y && (a = !a);
65
100
  }
66
- return l;
101
+ return a;
67
102
  }
68
103
  return !1;
69
104
  }
70
- function I(t) {
71
- const e = x.find((i) => i.id === t);
72
- if (!e || !o) return [];
105
+ function I(e) {
106
+ const t = m.find((o) => o.id === e);
107
+ if (!t || !i) return [];
73
108
  const n = [];
74
- return o.chart.getAllSeries().forEach((i) => {
75
- const l = i.getData();
76
- if (!l) return;
77
- const s = new Array(l.x.length);
78
- for (let r = 0; r < l.x.length; r++)
79
- s[r] = b({ x: l.x[r], y: l.y[r] }, e);
109
+ return i.chart.getAllSeries().forEach((o) => {
110
+ const a = o.getData();
111
+ if (!a) return;
112
+ const s = new Array(a.x.length);
113
+ for (let r = 0; r < a.x.length; r++)
114
+ s[r] = T({ x: a.x[r], y: a.y[r] }, t);
80
115
  n.push({
81
- regionId: t,
82
- seriesId: i.getId(),
116
+ regionId: e,
117
+ seriesId: o.getId(),
83
118
  masks: s
84
119
  });
85
120
  }), n;
86
121
  }
87
- function S() {
88
- if (!a || !o) return;
89
- a.tool === "polygon" && a.points.length > 1 && a.points.pop(), x.push(a), d && A();
90
- const t = {
91
- region: a,
92
- seriesIds: o.chart.getAllSeries().map((e) => e.getId()),
93
- masks: I(a.id)
122
+ function $() {
123
+ if (!l || !i) return;
124
+ l.tool === "polygon" && l.points.length > 1 && l.points.pop(), m.push(l), c && k();
125
+ const e = {
126
+ region: l,
127
+ seriesIds: i.chart.getAllSeries().map((t) => t.getId()),
128
+ masks: I(l.id)
94
129
  };
95
- o.events.emit("roi:selected", t), o.chart.events && o.chart.events.emit("roi:selected", t), o.events.emit("roi:created", {
96
- region: a,
97
- seriesIds: t.seriesIds
98
- }), a = null, h = !1, o.requestRender();
130
+ i.events.emit("roi:selected", e), i.chart.events && i.chart.events.emit("roi:selected", e), i.events.emit("roi:created", {
131
+ region: l,
132
+ seriesIds: e.seriesIds
133
+ }), l = null, u = !1, i.requestRender();
99
134
  }
100
- function X(t) {
101
- if (!P || !t.inPlotArea) return;
102
- if (u === "polygon" && a) {
103
- const n = m({ x: t.pixelX, y: t.pixelY });
104
- a.points.push(n), t.preventDefault(), o == null || o.requestRender();
135
+ function F(e) {
136
+ if (!w || !e.inPlotArea) return;
137
+ if (h === "polygon" && l) {
138
+ const n = R({ x: e.pixelX, y: e.pixelY });
139
+ l.points.push(n), e.preventDefault(), i == null || i.requestRender();
105
140
  return;
106
141
  }
107
- h = !0, a = D(u);
108
- const e = m({ x: t.pixelX, y: t.pixelY });
109
- a.points.push(e), u === "rectangle" || u === "circle" ? a.points.push({ ...e }) : u === "polygon" && a.points.push({ ...e }), t.preventDefault(), o == null || o.requestRender();
142
+ u = !0, l = D(h);
143
+ const t = R({ x: e.pixelX, y: e.pixelY });
144
+ l.points.push(t), h === "rectangle" || h === "circle" ? l.points.push({ ...t }) : h === "polygon" && l.points.push({ ...t }), e.preventDefault(), i == null || i.requestRender();
110
145
  }
111
- function Y(t) {
112
- if (!(!P || !h || !a)) {
113
- if (u === "rectangle" || u === "circle")
114
- a.points[1] = m({ x: t.pixelX, y: t.pixelY });
115
- else if (u === "lasso") {
116
- const e = a.points[a.points.length - 1], n = m({ x: t.pixelX, y: t.pixelY }), i = o.coords.dataToPixelX(n.x) - o.coords.dataToPixelX(e.x), l = o.coords.dataToPixelY(n.y) - o.coords.dataToPixelY(e.y);
117
- Math.sqrt(i * i + l * l) > 5 && a.points.push(n);
118
- } else if (u === "polygon") {
119
- const e = a.points.length - 1;
120
- e >= 0 && (a.points[e] = m({ x: t.pixelX, y: t.pixelY }));
146
+ function X(e) {
147
+ if (!(!w || !u || !l)) {
148
+ if (h === "rectangle" || h === "circle")
149
+ l.points[1] = R({ x: e.pixelX, y: e.pixelY });
150
+ else if (h === "lasso") {
151
+ const t = l.points[l.points.length - 1], n = R({ x: e.pixelX, y: e.pixelY }), o = i.coords.dataToPixelX(n.x) - i.coords.dataToPixelX(t.x), a = i.coords.dataToPixelY(n.y) - i.coords.dataToPixelY(t.y);
152
+ Math.sqrt(o * o + a * a) > 5 && l.points.push(n);
153
+ } else if (h === "polygon") {
154
+ const t = l.points.length - 1;
155
+ t >= 0 && (l.points[t] = R({ x: e.pixelX, y: e.pixelY }));
121
156
  }
122
- o == null || o.requestRender();
157
+ i == null || i.requestRender();
123
158
  }
124
159
  }
125
- function E(t) {
126
- !h || !a || u !== "polygon" && S();
160
+ function E(e) {
161
+ !u || !l || h !== "polygon" && $();
127
162
  }
128
- function k(t, e) {
129
- const { tool: n, points: i, color: l, fill: s } = t;
130
- if (i.length < 1) return;
131
- const r = i.map((c) => F(c));
132
- if (e.strokeStyle = l || "#00f2ff", e.fillStyle = s || "rgba(0, 242, 255, 0.15)", e.lineWidth = 2, n === "rectangle" && r.length >= 2) {
133
- const c = Math.min(r[0].x, r[1].x), f = Math.min(r[0].y, r[1].y), y = Math.abs(r[0].x - r[1].x), w = Math.abs(r[0].y - r[1].y);
134
- e.fillRect(c, f, y, w), e.strokeRect(c, f, y, w);
163
+ function q(e, t) {
164
+ const { tool: n, points: o, color: a, fill: s } = e;
165
+ if (o.length < 1) return;
166
+ const r = o.map((y) => Y(y));
167
+ if (t.strokeStyle = a || "#00f2ff", t.fillStyle = s || "rgba(0, 242, 255, 0.15)", t.lineWidth = 2, n === "rectangle" && r.length >= 2) {
168
+ const y = Math.min(r[0].x, r[1].x), f = Math.min(r[0].y, r[1].y), x = Math.abs(r[0].x - r[1].x), b = Math.abs(r[0].y - r[1].y);
169
+ t.fillRect(y, f, x, b), t.strokeRect(y, f, x, b);
135
170
  } else if (n === "circle" && r.length >= 2) {
136
- const c = r[1].x - r[0].x, f = r[1].y - r[0].y, y = Math.sqrt(c * c + f * f);
137
- e.beginPath(), e.arc(r[0].x, r[0].y, y, 0, Math.PI * 2), e.fill(), e.stroke();
138
- } else (n === "polygon" || n === "lasso") && r.length >= 2 && (e.beginPath(), e.moveTo(r[0].x, r[0].y), r.slice(1).forEach((c) => e.lineTo(c.x, c.y)), (n === "lasso" || !h || t !== a) && e.closePath(), e.fill(), e.stroke());
171
+ const y = r[1].x - r[0].x, f = r[1].y - r[0].y, x = Math.sqrt(y * y + f * f);
172
+ t.beginPath(), t.arc(r[0].x, r[0].y, x, 0, Math.PI * 2), t.fill(), t.stroke();
173
+ } else (n === "polygon" || n === "lasso") && r.length >= 2 && (t.beginPath(), t.moveTo(r[0].x, r[0].y), r.slice(1).forEach((y) => t.lineTo(y.x, y.y)), (n === "lasso" || !u || e !== l) && t.closePath(), t.fill(), t.stroke());
139
174
  }
140
175
  return {
141
- manifest: q,
142
- onInit(t) {
143
- o = t;
144
- const e = o.chart;
145
- p = e.updateSeries.bind(e), R = e.addSeries.bind(e), e.addSeries = (n) => {
146
- var i, l;
147
- if (n.id && ((i = n.data) != null && i.x) && g.set(n.id, {
176
+ manifest: S,
177
+ onInit(e) {
178
+ i = e;
179
+ const t = i.chart;
180
+ d = t.updateSeries.bind(t), P = t.addSeries.bind(t), t.addSeries = (n) => {
181
+ var o, a;
182
+ if (n.id && ((o = n.data) != null && o.x) && g.set(n.id, {
148
183
  x: new Float32Array(n.data.x),
149
184
  y: new Float32Array(n.data.y)
150
- }), d && ((l = n.data) != null && l.x)) {
185
+ }), c && ((a = n.data) != null && a.x)) {
151
186
  const s = g.get(n.id), r = [];
152
- for (let y = 0; y < s.x.length; y++)
153
- T({ x: s.x[y], y: s.y[y] }) && r.push(y);
154
- const c = new Float32Array(r.length), f = new Float32Array(r.length);
155
- for (let y = 0; y < r.length; y++)
156
- c[y] = s.x[r[y]], f[y] = s.y[r[y]];
157
- R({ ...n, data: { ...n.data, x: c, y: f } });
187
+ for (let x = 0; x < s.x.length; x++)
188
+ A({ x: s.x[x], y: s.y[x] }) && r.push(x);
189
+ const y = new Float32Array(r.length), f = new Float32Array(r.length);
190
+ for (let x = 0; x < r.length; x++)
191
+ y[x] = s.x[r[x]], f[x] = s.y[r[x]];
192
+ P({ ...n, data: { ...n.data, x: y, y: f } });
158
193
  } else
159
- R(n);
160
- }, e.updateSeries = (n, i) => {
161
- if (i.x && g.set(n, {
162
- x: new Float32Array(i.x),
163
- y: new Float32Array(i.y)
164
- }), d && i.x) {
165
- const l = g.get(n), s = [];
166
- for (let f = 0; f < l.x.length; f++)
167
- T({ x: l.x[f], y: l.y[f] }) && s.push(f);
168
- const r = new Float32Array(s.length), c = new Float32Array(s.length);
194
+ P(n);
195
+ }, t.updateSeries = (n, o) => {
196
+ if (o.x && g.set(n, {
197
+ x: new Float32Array(o.x),
198
+ y: new Float32Array(o.y)
199
+ }), c && o.x) {
200
+ const a = g.get(n), s = [];
201
+ for (let f = 0; f < a.x.length; f++)
202
+ A({ x: a.x[f], y: a.y[f] }) && s.push(f);
203
+ const r = new Float32Array(s.length), y = new Float32Array(s.length);
169
204
  for (let f = 0; f < s.length; f++)
170
- r[f] = l.x[s[f]], c[f] = l.y[s[f]];
171
- p(n, { ...i, x: r, y: c });
205
+ r[f] = a.x[s[f]], y[f] = a.y[s[f]];
206
+ d(n, { ...o, x: r, y });
172
207
  } else
173
- p(n, i);
208
+ d(n, o);
174
209
  };
175
210
  },
176
211
  onDestroy() {
177
- if (o) {
178
- const t = o.chart;
179
- t.addSeries = R, t.updateSeries = p;
212
+ if (i) {
213
+ const e = i.chart;
214
+ e.addSeries = P, e.updateSeries = d;
180
215
  }
181
- o = null, g.clear();
216
+ i = null, g.clear();
217
+ },
218
+ onInteraction(e, t) {
219
+ t.type === "mousedown" && F(t), t.type === "mousemove" && X(t), t.type === "mouseup" && E(), t.type, t.originalEvent instanceof MouseEvent && t.originalEvent.detail === 2 && h === "polygon" && ($(), t.preventDefault());
182
220
  },
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" && (S(), e.preventDefault());
221
+ onRenderOverlay(e) {
222
+ const t = e.render.ctx2d;
223
+ t && (m.forEach((n) => q(n, t)), l && q(l, t));
185
224
  },
186
- onRenderOverlay(t) {
187
- const e = t.render.ctx2d;
188
- e && (x.forEach((n) => k(n, e)), a && k(a, e));
225
+ onExportSVG(e) {
226
+ var t;
227
+ !e.builder || ((t = e.exportContext) == null ? void 0 : t.options.includeOverlays) === !1 || O(e, m);
189
228
  },
190
229
  api: {
191
- setTool(t) {
192
- u = t, h && S();
230
+ setTool(e) {
231
+ h = e, u && $();
193
232
  },
194
233
  clear() {
195
- x = [], a = null, h = !1, d && A(), o && (o.events.emit("roi:cleared", {}), o.requestRender());
234
+ m = [], l = null, u = !1, c && k(), i && (i.events.emit("roi:cleared", {}), i.requestRender());
196
235
  },
197
236
  getRegions() {
198
- return [...x];
237
+ return [...m];
199
238
  },
200
- removeRegion(t) {
201
- x = x.filter((e) => e.id !== t), d && A(), o && o.requestRender();
239
+ removeRegion(e) {
240
+ m = m.filter((t) => t.id !== e), c && k(), i && i.requestRender();
202
241
  },
203
242
  calculateMasks: I,
204
- isEnabled: () => P,
205
- setEnabled: (t) => {
206
- P = t;
243
+ isEnabled: () => w,
244
+ setEnabled: (e) => {
245
+ w = e;
207
246
  },
208
- setMasking(t) {
209
- if (d = t, t)
210
- A();
211
- else if (o) {
212
- for (const [e, n] of g.entries())
213
- p(e, n);
214
- o.requestRender();
247
+ setMasking(e) {
248
+ if (c = e, e)
249
+ k();
250
+ else if (i) {
251
+ for (const [t, n] of g.entries())
252
+ d(t, n);
253
+ i.requestRender();
215
254
  }
216
255
  }
217
256
  }
218
257
  };
219
258
  };
220
259
  export {
221
- v as PluginROI
260
+ _ as PluginROI
222
261
  };
223
262
  //# sourceMappingURL=roi.js.map
@@ -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: \"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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"}
1
+ {"version":3,"file":"roi.js","sources":["../../src/core/chart/exporter/svg/plugins/roi.ts","../../src/plugins/roi/index.ts"],"sourcesContent":["import type { SVGExportPluginContext } from \"./types\";\nimport { fmt } from \"../SVGDocumentBuilder\";\nimport { primaryYScale } from \"../tickUtils\";\n\nexport interface RoiExportRegion {\n tool: \"rectangle\" | \"circle\" | \"polygon\" | \"lasso\";\n points: Array<{ x: number; y: number }>;\n color?: string;\n fill?: string;\n}\n\nexport function exportRoiRegions(ctx: SVGExportPluginContext, regions: RoiExportRegion[]): void {\n if (!ctx.builder || regions.length === 0) return;\n\n const yScale = primaryYScale(ctx.yScales);\n if (!yScale) return;\n\n const toPx = (p: { x: number; y: number }) => ({\n x: ctx.xScale.transform(p.x),\n y: yScale.transform(p.y),\n });\n\n for (const region of regions) {\n const stroke = region.color ?? \"#00f2ff\";\n const fill = region.fill ?? \"rgba(0, 242, 255, 0.15)\";\n const pixels = region.points.map(toPx);\n if (pixels.length < 2) continue;\n\n if (region.tool === \"rectangle\") {\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[1].x - pixels[0].x);\n const h = Math.abs(pixels[1].y - pixels[0].y);\n ctx.builder.push(\n \"plugins\",\n `<rect x=\"${fmt(x)}\" y=\"${fmt(y)}\" width=\"${fmt(w)}\" height=\"${fmt(h)}\" fill=\"${fill}\" stroke=\"${stroke}\" stroke-width=\"1.5\"/>`,\n );\n } else if (region.tool === \"circle\") {\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 ctx.builder.push(\n \"plugins\",\n `<circle cx=\"${fmt(pixels[0].x)}\" cy=\"${fmt(pixels[0].y)}\" r=\"${fmt(r)}\" fill=\"${fill}\" stroke=\"${stroke}\" stroke-width=\"1.5\"/>`,\n );\n } else if (region.tool === \"polygon\" || region.tool === \"lasso\") {\n const pts = pixels.map((p) => `${fmt(p.x)},${fmt(p.y)}`).join(\" \");\n ctx.builder.push(\n \"plugins\",\n `<polygon points=\"${pts}\" fill=\"${fill}\" stroke=\"${stroke}\" stroke-width=\"1.5\"/>`,\n );\n }\n }\n}\n","import type { PluginContext, InteractionEvent, PluginManifest } from \"../types\";\nimport type { SVGExportPluginContext } from \"../../core/chart/exporter/svg/plugins/types\";\nimport { exportRoiRegions } from \"../../core/chart/exporter/svg/plugins/roi\";\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 onExportSVG(svgCtx: SVGExportPluginContext) {\n if (!svgCtx.builder || svgCtx.exportContext?.options.includeOverlays === false) return;\n exportRoiRegions(svgCtx, regions);\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":["exportRoiRegions","ctx","regions","yScale","primaryYScale","toPx","p","region","stroke","fill","pixels","x","y","w","h","fmt","dx","dy","r","pts","PluginROI","config","activeTool","isDrawing","activeRegion","enabled","isMasking","rawDataStore","originalUpdateSeries","originalAddSeries","manifest","createRegion","tool","pixelToData","pixel","dataToPixel","point","isPointInAnyRegion","isPointInRegion","applyMasking","id","raw","indices","i","filteredX","filteredY","points","xMin","xMax","yMin","yMax","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","pluginCtx","chart","options","_a","_b","fx","fy","_pluginCtx","svgCtx","mask"],"mappings":"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"}