exploreda 0.0.5 → 0.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 (208) hide show
  1. package/README.md +144 -0
  2. package/dist/ExplorEda.cjs +4608 -10858
  3. package/dist/ExplorEda.cjs.map +1 -1
  4. package/dist/ExplorEda.css +2332 -1653
  5. package/dist/ExplorEda.css.map +1 -1
  6. package/dist/ExplorEda.d.cts +125 -278
  7. package/dist/ExplorEda.d.ts +125 -278
  8. package/dist/ExplorEda.js +4521 -10782
  9. package/dist/ExplorEda.js.map +1 -1
  10. package/dist/calculations.cjs +18 -0
  11. package/dist/calculations.cjs.map +1 -0
  12. package/dist/calculations.d.cts +63 -0
  13. package/dist/calculations.d.ts +63 -0
  14. package/dist/calculations.js +3 -0
  15. package/dist/calculations.js.map +1 -0
  16. package/dist/charts/bar.cjs +27 -0
  17. package/dist/charts/bar.cjs.map +1 -0
  18. package/dist/charts/bar.d.cts +2 -0
  19. package/dist/charts/bar.d.ts +2 -0
  20. package/dist/charts/bar.js +18 -0
  21. package/dist/charts/bar.js.map +1 -0
  22. package/dist/charts/box-plot.cjs +26 -0
  23. package/dist/charts/box-plot.cjs.map +1 -0
  24. package/dist/charts/box-plot.d.cts +2 -0
  25. package/dist/charts/box-plot.d.ts +2 -0
  26. package/dist/charts/box-plot.js +17 -0
  27. package/dist/charts/box-plot.js.map +1 -0
  28. package/dist/charts/color-legend.cjs +22 -0
  29. package/dist/charts/color-legend.cjs.map +1 -0
  30. package/dist/charts/color-legend.d.cts +2 -0
  31. package/dist/charts/color-legend.d.ts +2 -0
  32. package/dist/charts/color-legend.js +13 -0
  33. package/dist/charts/color-legend.js.map +1 -0
  34. package/dist/charts/data-table.cjs +22 -0
  35. package/dist/charts/data-table.cjs.map +1 -0
  36. package/dist/charts/data-table.d.cts +2 -0
  37. package/dist/charts/data-table.d.ts +2 -0
  38. package/dist/charts/data-table.js +13 -0
  39. package/dist/charts/data-table.js.map +1 -0
  40. package/dist/charts/line.cjs +30 -0
  41. package/dist/charts/line.cjs.map +1 -0
  42. package/dist/charts/line.d.cts +2 -0
  43. package/dist/charts/line.d.ts +2 -0
  44. package/dist/charts/line.js +17 -0
  45. package/dist/charts/line.js.map +1 -0
  46. package/dist/charts/markdown.cjs +16 -0
  47. package/dist/charts/markdown.cjs.map +1 -0
  48. package/dist/charts/markdown.css +77 -0
  49. package/dist/charts/markdown.css.map +1 -0
  50. package/dist/charts/markdown.d.cts +2 -0
  51. package/dist/charts/markdown.d.ts +2 -0
  52. package/dist/charts/markdown.js +7 -0
  53. package/dist/charts/markdown.js.map +1 -0
  54. package/dist/charts/pivot-table.cjs +23 -0
  55. package/dist/charts/pivot-table.cjs.map +1 -0
  56. package/dist/charts/pivot-table.d.cts +2 -0
  57. package/dist/charts/pivot-table.d.ts +2 -0
  58. package/dist/charts/pivot-table.js +14 -0
  59. package/dist/charts/pivot-table.js.map +1 -0
  60. package/dist/charts/row.cjs +27 -0
  61. package/dist/charts/row.cjs.map +1 -0
  62. package/dist/charts/row.d.cts +6 -0
  63. package/dist/charts/row.d.ts +6 -0
  64. package/dist/charts/row.js +18 -0
  65. package/dist/charts/row.js.map +1 -0
  66. package/dist/charts/scatter.cjs +24 -0
  67. package/dist/charts/scatter.cjs.map +1 -0
  68. package/dist/charts/scatter.d.cts +2 -0
  69. package/dist/charts/scatter.d.ts +2 -0
  70. package/dist/charts/scatter.js +15 -0
  71. package/dist/charts/scatter.js.map +1 -0
  72. package/dist/charts/summary-table.cjs +19 -0
  73. package/dist/charts/summary-table.cjs.map +1 -0
  74. package/dist/charts/summary-table.d.cts +2 -0
  75. package/dist/charts/summary-table.d.ts +2 -0
  76. package/dist/charts/summary-table.js +10 -0
  77. package/dist/charts/summary-table.js.map +1 -0
  78. package/dist/charts/three-d-scatter.cjs +24 -0
  79. package/dist/charts/three-d-scatter.cjs.map +1 -0
  80. package/dist/charts/three-d-scatter.d.cts +6 -0
  81. package/dist/charts/three-d-scatter.d.ts +6 -0
  82. package/dist/charts/three-d-scatter.js +15 -0
  83. package/dist/charts/three-d-scatter.js.map +1 -0
  84. package/dist/chunk-3PGYFLE3.cjs +499 -0
  85. package/dist/chunk-3PGYFLE3.cjs.map +1 -0
  86. package/dist/chunk-4HNDKMWF.js +167 -0
  87. package/dist/chunk-4HNDKMWF.js.map +1 -0
  88. package/dist/chunk-4QNENKTV.cjs +1214 -0
  89. package/dist/chunk-4QNENKTV.cjs.map +1 -0
  90. package/dist/chunk-54M32JJB.js +132 -0
  91. package/dist/chunk-54M32JJB.js.map +1 -0
  92. package/dist/chunk-5B23JVH3.cjs +2238 -0
  93. package/dist/chunk-5B23JVH3.cjs.map +1 -0
  94. package/dist/chunk-5LH6NSNL.js +456 -0
  95. package/dist/chunk-5LH6NSNL.js.map +1 -0
  96. package/dist/chunk-6DOKKCJ5.cjs +313 -0
  97. package/dist/chunk-6DOKKCJ5.cjs.map +1 -0
  98. package/dist/chunk-6HZX5CBT.cjs +1074 -0
  99. package/dist/chunk-6HZX5CBT.cjs.map +1 -0
  100. package/dist/chunk-6U5DOIQM.js +1071 -0
  101. package/dist/chunk-6U5DOIQM.js.map +1 -0
  102. package/dist/chunk-7GBZIK2R.cjs +80 -0
  103. package/dist/chunk-7GBZIK2R.cjs.map +1 -0
  104. package/dist/chunk-7PTJNIOD.js +520 -0
  105. package/dist/chunk-7PTJNIOD.js.map +1 -0
  106. package/dist/chunk-AHZYQ7FN.js +319 -0
  107. package/dist/chunk-AHZYQ7FN.js.map +1 -0
  108. package/dist/chunk-AOODAOL4.cjs +55 -0
  109. package/dist/chunk-AOODAOL4.cjs.map +1 -0
  110. package/dist/chunk-ASKFIRMC.cjs +165 -0
  111. package/dist/chunk-ASKFIRMC.cjs.map +1 -0
  112. package/dist/chunk-B7OQUBH4.cjs +171 -0
  113. package/dist/chunk-B7OQUBH4.cjs.map +1 -0
  114. package/dist/chunk-BIMEHDLB.js +72 -0
  115. package/dist/chunk-BIMEHDLB.js.map +1 -0
  116. package/dist/chunk-C62KHV7S.js +1225 -0
  117. package/dist/chunk-C62KHV7S.js.map +1 -0
  118. package/dist/chunk-C7GQT65O.cjs +1119 -0
  119. package/dist/chunk-C7GQT65O.cjs.map +1 -0
  120. package/dist/chunk-CGDWDV4Z.js +1211 -0
  121. package/dist/chunk-CGDWDV4Z.js.map +1 -0
  122. package/dist/chunk-CJQQFNEY.js +69 -0
  123. package/dist/chunk-CJQQFNEY.js.map +1 -0
  124. package/dist/chunk-DHYLSXNR.js +964 -0
  125. package/dist/chunk-DHYLSXNR.js.map +1 -0
  126. package/dist/chunk-DKFA4KOJ.cjs +87 -0
  127. package/dist/chunk-DKFA4KOJ.cjs.map +1 -0
  128. package/dist/chunk-DS5BS7PP.cjs +357 -0
  129. package/dist/chunk-DS5BS7PP.cjs.map +1 -0
  130. package/dist/chunk-EGMFQSGK.js +909 -0
  131. package/dist/chunk-EGMFQSGK.js.map +1 -0
  132. package/dist/chunk-EU5EFHO5.cjs +53 -0
  133. package/dist/chunk-EU5EFHO5.cjs.map +1 -0
  134. package/dist/chunk-FM46QSDM.js +837 -0
  135. package/dist/chunk-FM46QSDM.js.map +1 -0
  136. package/dist/chunk-GV2LRR32.cjs +843 -0
  137. package/dist/chunk-GV2LRR32.cjs.map +1 -0
  138. package/dist/chunk-H3XKFSA5.cjs +322 -0
  139. package/dist/chunk-H3XKFSA5.cjs.map +1 -0
  140. package/dist/chunk-H5AVMMCE.js +347 -0
  141. package/dist/chunk-H5AVMMCE.js.map +1 -0
  142. package/dist/chunk-JDMUN4VK.cjs +986 -0
  143. package/dist/chunk-JDMUN4VK.cjs.map +1 -0
  144. package/dist/chunk-JNO7OXCC.js +2171 -0
  145. package/dist/chunk-JNO7OXCC.js.map +1 -0
  146. package/dist/chunk-JQMG4ZR7.js +111 -0
  147. package/dist/chunk-JQMG4ZR7.js.map +1 -0
  148. package/dist/chunk-L2Q2R43U.cjs +118 -0
  149. package/dist/chunk-L2Q2R43U.cjs.map +1 -0
  150. package/dist/chunk-LBTZVERO.js +466 -0
  151. package/dist/chunk-LBTZVERO.js.map +1 -0
  152. package/dist/chunk-LUUGGTTK.cjs +1227 -0
  153. package/dist/chunk-LUUGGTTK.cjs.map +1 -0
  154. package/dist/chunk-MEEPH7ZC.cjs +911 -0
  155. package/dist/chunk-MEEPH7ZC.cjs.map +1 -0
  156. package/dist/chunk-MJPDJ5AS.js +184 -0
  157. package/dist/chunk-MJPDJ5AS.js.map +1 -0
  158. package/dist/chunk-MJROUIDZ.cjs +219 -0
  159. package/dist/chunk-MJROUIDZ.cjs.map +1 -0
  160. package/dist/chunk-MUWSBYJS.js +528 -0
  161. package/dist/chunk-MUWSBYJS.js.map +1 -0
  162. package/dist/chunk-NDF5LCST.js +1088 -0
  163. package/dist/chunk-NDF5LCST.js.map +1 -0
  164. package/dist/chunk-NGWTPED4.js +311 -0
  165. package/dist/chunk-NGWTPED4.js.map +1 -0
  166. package/dist/chunk-PP4VCONW.js +739 -0
  167. package/dist/chunk-PP4VCONW.js.map +1 -0
  168. package/dist/chunk-PRMC2A6P.cjs +488 -0
  169. package/dist/chunk-PRMC2A6P.cjs.map +1 -0
  170. package/dist/chunk-PST6UU6S.cjs +742 -0
  171. package/dist/chunk-PST6UU6S.cjs.map +1 -0
  172. package/dist/chunk-Q7LK2UWH.js +33 -0
  173. package/dist/chunk-Q7LK2UWH.js.map +1 -0
  174. package/dist/chunk-SFV5LZPD.js +162 -0
  175. package/dist/chunk-SFV5LZPD.js.map +1 -0
  176. package/dist/chunk-SKXGYJJG.cjs +370 -0
  177. package/dist/chunk-SKXGYJJG.cjs.map +1 -0
  178. package/dist/chunk-SWLNKY6R.js +477 -0
  179. package/dist/chunk-SWLNKY6R.js.map +1 -0
  180. package/dist/chunk-TGVLNHUB.cjs +483 -0
  181. package/dist/chunk-TGVLNHUB.cjs.map +1 -0
  182. package/dist/chunk-TLLRW6S3.js +74 -0
  183. package/dist/chunk-TLLRW6S3.js.map +1 -0
  184. package/dist/chunk-TRAIXZ6M.cjs +140 -0
  185. package/dist/chunk-TRAIXZ6M.cjs.map +1 -0
  186. package/dist/chunk-U74A5VK5.cjs +74 -0
  187. package/dist/chunk-U74A5VK5.cjs.map +1 -0
  188. package/dist/chunk-UAVDLBTA.cjs +74 -0
  189. package/dist/chunk-UAVDLBTA.cjs.map +1 -0
  190. package/dist/chunk-UJWS6TRV.js +354 -0
  191. package/dist/chunk-UJWS6TRV.js.map +1 -0
  192. package/dist/chunk-UUJMUPB3.cjs +531 -0
  193. package/dist/chunk-UUJMUPB3.cjs.map +1 -0
  194. package/dist/chunk-VTKHZIJB.cjs +549 -0
  195. package/dist/chunk-VTKHZIJB.cjs.map +1 -0
  196. package/dist/chunk-YXPAWUXO.js +51 -0
  197. package/dist/chunk-YXPAWUXO.js.map +1 -0
  198. package/dist/chunk-ZD64SCZB.js +80 -0
  199. package/dist/chunk-ZD64SCZB.js.map +1 -0
  200. package/dist/core.cjs +28 -0
  201. package/dist/core.cjs.map +1 -0
  202. package/dist/core.d.cts +22 -0
  203. package/dist/core.d.ts +22 -0
  204. package/dist/core.js +3 -0
  205. package/dist/core.js.map +1 -0
  206. package/dist/dataLayerState-B4XmQjQN.d.cts +258 -0
  207. package/dist/dataLayerState-B4XmQjQN.d.ts +258 -0
  208. package/package.json +32 -52
@@ -0,0 +1,1214 @@
1
+ 'use strict';
2
+
3
+ var chunkDS5BS7PP_cjs = require('./chunk-DS5BS7PP.cjs');
4
+ var chunkUUJMUPB3_cjs = require('./chunk-UUJMUPB3.cjs');
5
+ var chunkASKFIRMC_cjs = require('./chunk-ASKFIRMC.cjs');
6
+ var chunkUAVDLBTA_cjs = require('./chunk-UAVDLBTA.cjs');
7
+ var chunkAOODAOL4_cjs = require('./chunk-AOODAOL4.cjs');
8
+ var chunkDKFA4KOJ_cjs = require('./chunk-DKFA4KOJ.cjs');
9
+ var chunkEU5EFHO5_cjs = require('./chunk-EU5EFHO5.cjs');
10
+ var chunk3PGYFLE3_cjs = require('./chunk-3PGYFLE3.cjs');
11
+ var chunkMJROUIDZ_cjs = require('./chunk-MJROUIDZ.cjs');
12
+ var chunk5B23JVH3_cjs = require('./chunk-5B23JVH3.cjs');
13
+ var lucideReact = require('lucide-react');
14
+ var jsxRuntime = require('react/jsx-runtime');
15
+ var d3Array = require('d3-array');
16
+ var d3Scale = require('d3-scale');
17
+ var react = require('react');
18
+
19
+ function AxisReadout({
20
+ x: x2,
21
+ y: y2,
22
+ xValue,
23
+ yValue,
24
+ width,
25
+ height,
26
+ color,
27
+ label,
28
+ rightAxis = false,
29
+ radius = 4,
30
+ xFormatter = chunkDS5BS7PP_cjs.formatTick,
31
+ yFormatter = chunkDS5BS7PP_cjs.formatTick
32
+ }) {
33
+ if (![x2, y2, xValue, yValue].every(Number.isFinite)) return null;
34
+ const xText = xFormatter(xValue);
35
+ const yText = yFormatter(yValue);
36
+ const xLabelWidth = xText.length * 6 + 12;
37
+ const yLabelWidth = yText.length * 6 + 12;
38
+ const labelX = Math.max(
39
+ xLabelWidth / 2,
40
+ Math.min(width - xLabelWidth / 2, x2)
41
+ );
42
+ const edge = rightAxis ? width : 0;
43
+ return /* @__PURE__ */ jsxRuntime.jsxs(
44
+ "g",
45
+ {
46
+ className: "eda-axis-readout",
47
+ pointerEvents: "none",
48
+ role: "img",
49
+ "aria-label": label,
50
+ children: [
51
+ /* @__PURE__ */ jsxRuntime.jsxs(
52
+ "g",
53
+ {
54
+ stroke: color,
55
+ strokeOpacity: 0.4,
56
+ strokeWidth: 1,
57
+ strokeDasharray: "2 3",
58
+ children: [
59
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: x2, x2, y1: y2, y2: height + 3 }),
60
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: x2, x2: edge, y1: y2, y2 })
61
+ ]
62
+ }
63
+ ),
64
+ /* @__PURE__ */ jsxRuntime.jsx(
65
+ "circle",
66
+ {
67
+ cx: x2,
68
+ cy: y2,
69
+ r: radius,
70
+ fill: "var(--card)",
71
+ stroke: color,
72
+ strokeWidth: 1.5
73
+ }
74
+ ),
75
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x2, cy: y2, r: 2, fill: color }),
76
+ /* @__PURE__ */ jsxRuntime.jsxs("g", { fill: "var(--card)", children: [
77
+ /* @__PURE__ */ jsxRuntime.jsx(
78
+ "rect",
79
+ {
80
+ x: labelX - xLabelWidth / 2,
81
+ y: height + 5,
82
+ width: xLabelWidth,
83
+ height: 20
84
+ }
85
+ ),
86
+ /* @__PURE__ */ jsxRuntime.jsx(
87
+ "rect",
88
+ {
89
+ x: rightAxis ? edge + 3 : -yLabelWidth - 3,
90
+ y: y2 - 10,
91
+ width: yLabelWidth,
92
+ height: 20
93
+ }
94
+ )
95
+ ] }),
96
+ /* @__PURE__ */ jsxRuntime.jsxs("g", { fill: color, fontSize: 10, fontWeight: 600, children: [
97
+ /* @__PURE__ */ jsxRuntime.jsx("text", { x: labelX, y: height + 18, textAnchor: "middle", children: xText }),
98
+ /* @__PURE__ */ jsxRuntime.jsx(
99
+ "text",
100
+ {
101
+ x: rightAxis ? edge + 8 : -8,
102
+ y: y2,
103
+ dy: ".32em",
104
+ textAnchor: rightAxis ? "start" : "end",
105
+ children: yText
106
+ }
107
+ )
108
+ ] })
109
+ ]
110
+ }
111
+ );
112
+ }
113
+
114
+ // src/lib/chartUtils.ts
115
+ function reduceDataPoints(data, numBuckets) {
116
+ if (!data || data.length === 0) {
117
+ return [];
118
+ }
119
+ const validBuckets = Math.max(1, Math.min(1e3, Math.floor(numBuckets)));
120
+ const orderedData = [...data].sort((a, b) => {
121
+ const aFinite = Number.isFinite(a.x);
122
+ const bFinite = Number.isFinite(b.x);
123
+ if (aFinite !== bFinite) return aFinite ? -1 : 1;
124
+ return aFinite ? a.x - b.x : 0;
125
+ });
126
+ if (data.length <= validBuckets * 3) {
127
+ return orderedData.map((point2) => ({ ...point2, type: "start" }));
128
+ }
129
+ const xExtent = {
130
+ min: Math.min(...orderedData.map((d) => d.x)),
131
+ max: Math.max(...orderedData.map((d) => d.x))
132
+ };
133
+ if (xExtent.min === xExtent.max) {
134
+ const firstPoint = data[0];
135
+ return firstPoint ? [{ ...firstPoint, type: "start" }] : [];
136
+ }
137
+ const buckets = Array(validBuckets).fill(null).map(() => []);
138
+ orderedData.forEach((point2) => {
139
+ const bucketIndex = Math.min(
140
+ Math.floor(
141
+ (point2.x - xExtent.min) / (xExtent.max - xExtent.min) * validBuckets
142
+ ),
143
+ validBuckets - 1
144
+ );
145
+ buckets[bucketIndex]?.push({ ...point2, type: "start" });
146
+ });
147
+ const result = [];
148
+ buckets.forEach((bucket) => {
149
+ if (bucket.length === 0) {
150
+ return;
151
+ }
152
+ const firstPoint = bucket[0];
153
+ if (!firstPoint) {
154
+ return;
155
+ }
156
+ result.push({ ...firstPoint, type: "start" });
157
+ if (bucket.length > 1) {
158
+ const minPoint = bucket.reduce((min, p) => p.y < min.y ? p : min);
159
+ const maxPoint = bucket.reduce((max, p) => p.y > max.y ? p : max);
160
+ if (minPoint !== firstPoint) {
161
+ result.push({ ...minPoint, type: "min" });
162
+ }
163
+ if (maxPoint !== firstPoint && maxPoint !== minPoint) {
164
+ result.push({ ...maxPoint, type: "max" });
165
+ }
166
+ }
167
+ });
168
+ return result.sort((a, b) => a.x - b.x);
169
+ }
170
+
171
+ // ../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/constant.js
172
+ function constant_default(x2) {
173
+ return function constant() {
174
+ return x2;
175
+ };
176
+ }
177
+
178
+ // ../../node_modules/.pnpm/d3-path@3.1.0/node_modules/d3-path/src/path.js
179
+ var pi = Math.PI;
180
+ var tau = 2 * pi;
181
+ var epsilon = 1e-6;
182
+ var tauEpsilon = tau - epsilon;
183
+ function append(strings) {
184
+ this._ += strings[0];
185
+ for (let i = 1, n = strings.length; i < n; ++i) {
186
+ this._ += arguments[i] + strings[i];
187
+ }
188
+ }
189
+ function appendRound(digits) {
190
+ let d = Math.floor(digits);
191
+ if (!(d >= 0)) throw new Error(`invalid digits: ${digits}`);
192
+ if (d > 15) return append;
193
+ const k = 10 ** d;
194
+ return function(strings) {
195
+ this._ += strings[0];
196
+ for (let i = 1, n = strings.length; i < n; ++i) {
197
+ this._ += Math.round(arguments[i] * k) / k + strings[i];
198
+ }
199
+ };
200
+ }
201
+ var Path = class {
202
+ constructor(digits) {
203
+ this._x0 = this._y0 = // start of current subpath
204
+ this._x1 = this._y1 = null;
205
+ this._ = "";
206
+ this._append = digits == null ? append : appendRound(digits);
207
+ }
208
+ moveTo(x2, y2) {
209
+ this._append`M${this._x0 = this._x1 = +x2},${this._y0 = this._y1 = +y2}`;
210
+ }
211
+ closePath() {
212
+ if (this._x1 !== null) {
213
+ this._x1 = this._x0, this._y1 = this._y0;
214
+ this._append`Z`;
215
+ }
216
+ }
217
+ lineTo(x2, y2) {
218
+ this._append`L${this._x1 = +x2},${this._y1 = +y2}`;
219
+ }
220
+ quadraticCurveTo(x1, y1, x2, y2) {
221
+ this._append`Q${+x1},${+y1},${this._x1 = +x2},${this._y1 = +y2}`;
222
+ }
223
+ bezierCurveTo(x1, y1, x2, y2, x3, y3) {
224
+ this._append`C${+x1},${+y1},${+x2},${+y2},${this._x1 = +x3},${this._y1 = +y3}`;
225
+ }
226
+ arcTo(x1, y1, x2, y2, r) {
227
+ x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;
228
+ if (r < 0) throw new Error(`negative radius: ${r}`);
229
+ let x0 = this._x1, y0 = this._y1, x21 = x2 - x1, y21 = y2 - y1, x01 = x0 - x1, y01 = y0 - y1, l01_2 = x01 * x01 + y01 * y01;
230
+ if (this._x1 === null) {
231
+ this._append`M${this._x1 = x1},${this._y1 = y1}`;
232
+ } else if (!(l01_2 > epsilon)) ;
233
+ else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {
234
+ this._append`L${this._x1 = x1},${this._y1 = y1}`;
235
+ } else {
236
+ let x20 = x2 - x0, y20 = y2 - y0, l21_2 = x21 * x21 + y21 * y21, l20_2 = x20 * x20 + y20 * y20, l21 = Math.sqrt(l21_2), l01 = Math.sqrt(l01_2), l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2), t01 = l / l01, t21 = l / l21;
237
+ if (Math.abs(t01 - 1) > epsilon) {
238
+ this._append`L${x1 + t01 * x01},${y1 + t01 * y01}`;
239
+ }
240
+ this._append`A${r},${r},0,0,${+(y01 * x20 > x01 * y20)},${this._x1 = x1 + t21 * x21},${this._y1 = y1 + t21 * y21}`;
241
+ }
242
+ }
243
+ arc(x2, y2, r, a0, a1, ccw) {
244
+ x2 = +x2, y2 = +y2, r = +r, ccw = !!ccw;
245
+ if (r < 0) throw new Error(`negative radius: ${r}`);
246
+ let dx = r * Math.cos(a0), dy = r * Math.sin(a0), x0 = x2 + dx, y0 = y2 + dy, cw = 1 ^ ccw, da = ccw ? a0 - a1 : a1 - a0;
247
+ if (this._x1 === null) {
248
+ this._append`M${x0},${y0}`;
249
+ } else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {
250
+ this._append`L${x0},${y0}`;
251
+ }
252
+ if (!r) return;
253
+ if (da < 0) da = da % tau + tau;
254
+ if (da > tauEpsilon) {
255
+ this._append`A${r},${r},0,1,${cw},${x2 - dx},${y2 - dy}A${r},${r},0,1,${cw},${this._x1 = x0},${this._y1 = y0}`;
256
+ } else if (da > epsilon) {
257
+ this._append`A${r},${r},0,${+(da >= pi)},${cw},${this._x1 = x2 + r * Math.cos(a1)},${this._y1 = y2 + r * Math.sin(a1)}`;
258
+ }
259
+ }
260
+ rect(x2, y2, w, h) {
261
+ this._append`M${this._x0 = this._x1 = +x2},${this._y0 = this._y1 = +y2}h${w = +w}v${+h}h${-w}Z`;
262
+ }
263
+ toString() {
264
+ return this._;
265
+ }
266
+ };
267
+
268
+ // ../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/path.js
269
+ function withPath(shape) {
270
+ let digits = 3;
271
+ shape.digits = function(_) {
272
+ if (!arguments.length) return digits;
273
+ if (_ == null) {
274
+ digits = null;
275
+ } else {
276
+ const d = Math.floor(_);
277
+ if (!(d >= 0)) throw new RangeError(`invalid digits: ${_}`);
278
+ digits = d;
279
+ }
280
+ return shape;
281
+ };
282
+ return () => new Path(digits);
283
+ }
284
+ function array_default(x2) {
285
+ return typeof x2 === "object" && "length" in x2 ? x2 : Array.from(x2);
286
+ }
287
+
288
+ // ../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/curve/linear.js
289
+ function Linear(context) {
290
+ this._context = context;
291
+ }
292
+ Linear.prototype = {
293
+ areaStart: function() {
294
+ this._line = 0;
295
+ },
296
+ areaEnd: function() {
297
+ this._line = NaN;
298
+ },
299
+ lineStart: function() {
300
+ this._point = 0;
301
+ },
302
+ lineEnd: function() {
303
+ if (this._line || this._line !== 0 && this._point === 1) this._context.closePath();
304
+ this._line = 1 - this._line;
305
+ },
306
+ point: function(x2, y2) {
307
+ x2 = +x2, y2 = +y2;
308
+ switch (this._point) {
309
+ case 0:
310
+ this._point = 1;
311
+ this._line ? this._context.lineTo(x2, y2) : this._context.moveTo(x2, y2);
312
+ break;
313
+ case 1:
314
+ this._point = 2;
315
+ // falls through
316
+ default:
317
+ this._context.lineTo(x2, y2);
318
+ break;
319
+ }
320
+ }
321
+ };
322
+ function linear_default(context) {
323
+ return new Linear(context);
324
+ }
325
+
326
+ // ../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/point.js
327
+ function x(p) {
328
+ return p[0];
329
+ }
330
+ function y(p) {
331
+ return p[1];
332
+ }
333
+
334
+ // ../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/line.js
335
+ function line_default(x2, y2) {
336
+ var defined = constant_default(true), context = null, curve = linear_default, output = null, path2 = withPath(line);
337
+ x2 = typeof x2 === "function" ? x2 : x2 === void 0 ? x : constant_default(x2);
338
+ y2 = typeof y2 === "function" ? y2 : y2 === void 0 ? y : constant_default(y2);
339
+ function line(data) {
340
+ var i, n = (data = array_default(data)).length, d, defined0 = false, buffer;
341
+ if (context == null) output = curve(buffer = path2());
342
+ for (i = 0; i <= n; ++i) {
343
+ if (!(i < n && defined(d = data[i], i, data)) === defined0) {
344
+ if (defined0 = !defined0) output.lineStart();
345
+ else output.lineEnd();
346
+ }
347
+ if (defined0) output.point(+x2(d, i, data), +y2(d, i, data));
348
+ }
349
+ if (buffer) return output = null, buffer + "" || null;
350
+ }
351
+ line.x = function(_) {
352
+ return arguments.length ? (x2 = typeof _ === "function" ? _ : constant_default(+_), line) : x2;
353
+ };
354
+ line.y = function(_) {
355
+ return arguments.length ? (y2 = typeof _ === "function" ? _ : constant_default(+_), line) : y2;
356
+ };
357
+ line.defined = function(_) {
358
+ return arguments.length ? (defined = typeof _ === "function" ? _ : constant_default(!!_), line) : defined;
359
+ };
360
+ line.curve = function(_) {
361
+ return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;
362
+ };
363
+ line.context = function(_) {
364
+ return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;
365
+ };
366
+ return line;
367
+ }
368
+
369
+ // ../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/curve/monotone.js
370
+ function sign(x2) {
371
+ return x2 < 0 ? -1 : 1;
372
+ }
373
+ function slope3(that, x2, y2) {
374
+ var h0 = that._x1 - that._x0, h1 = x2 - that._x1, s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0), s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0), p = (s0 * h1 + s1 * h0) / (h0 + h1);
375
+ return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;
376
+ }
377
+ function slope2(that, t) {
378
+ var h = that._x1 - that._x0;
379
+ return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;
380
+ }
381
+ function point(that, t0, t1) {
382
+ var x0 = that._x0, y0 = that._y0, x1 = that._x1, y1 = that._y1, dx = (x1 - x0) / 3;
383
+ that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);
384
+ }
385
+ function MonotoneX(context) {
386
+ this._context = context;
387
+ }
388
+ MonotoneX.prototype = {
389
+ areaStart: function() {
390
+ this._line = 0;
391
+ },
392
+ areaEnd: function() {
393
+ this._line = NaN;
394
+ },
395
+ lineStart: function() {
396
+ this._x0 = this._x1 = this._y0 = this._y1 = this._t0 = NaN;
397
+ this._point = 0;
398
+ },
399
+ lineEnd: function() {
400
+ switch (this._point) {
401
+ case 2:
402
+ this._context.lineTo(this._x1, this._y1);
403
+ break;
404
+ case 3:
405
+ point(this, this._t0, slope2(this, this._t0));
406
+ break;
407
+ }
408
+ if (this._line || this._line !== 0 && this._point === 1) this._context.closePath();
409
+ this._line = 1 - this._line;
410
+ },
411
+ point: function(x2, y2) {
412
+ var t1 = NaN;
413
+ x2 = +x2, y2 = +y2;
414
+ if (x2 === this._x1 && y2 === this._y1) return;
415
+ switch (this._point) {
416
+ case 0:
417
+ this._point = 1;
418
+ this._line ? this._context.lineTo(x2, y2) : this._context.moveTo(x2, y2);
419
+ break;
420
+ case 1:
421
+ this._point = 2;
422
+ break;
423
+ case 2:
424
+ this._point = 3;
425
+ point(this, slope2(this, t1 = slope3(this, x2, y2)), t1);
426
+ break;
427
+ default:
428
+ point(this, this._t0, t1 = slope3(this, x2, y2));
429
+ break;
430
+ }
431
+ this._x0 = this._x1, this._x1 = x2;
432
+ this._y0 = this._y1, this._y1 = y2;
433
+ this._t0 = t1;
434
+ }
435
+ };
436
+ (Object.create(MonotoneX.prototype)).point = function(x2, y2) {
437
+ MonotoneX.prototype.point.call(this, y2, x2);
438
+ };
439
+ function monotoneX(context) {
440
+ return new MonotoneX(context);
441
+ }
442
+
443
+ // ../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/curve/step.js
444
+ function Step(context, t) {
445
+ this._context = context;
446
+ this._t = t;
447
+ }
448
+ Step.prototype = {
449
+ areaStart: function() {
450
+ this._line = 0;
451
+ },
452
+ areaEnd: function() {
453
+ this._line = NaN;
454
+ },
455
+ lineStart: function() {
456
+ this._x = this._y = NaN;
457
+ this._point = 0;
458
+ },
459
+ lineEnd: function() {
460
+ if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);
461
+ if (this._line || this._line !== 0 && this._point === 1) this._context.closePath();
462
+ if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;
463
+ },
464
+ point: function(x2, y2) {
465
+ x2 = +x2, y2 = +y2;
466
+ switch (this._point) {
467
+ case 0:
468
+ this._point = 1;
469
+ this._line ? this._context.lineTo(x2, y2) : this._context.moveTo(x2, y2);
470
+ break;
471
+ case 1:
472
+ this._point = 2;
473
+ // falls through
474
+ default: {
475
+ if (this._t <= 0) {
476
+ this._context.lineTo(this._x, y2);
477
+ this._context.lineTo(x2, y2);
478
+ } else {
479
+ var x1 = this._x * (1 - this._t) + x2 * this._t;
480
+ this._context.lineTo(x1, this._y);
481
+ this._context.lineTo(x1, y2);
482
+ }
483
+ break;
484
+ }
485
+ }
486
+ this._x = x2, this._y = y2;
487
+ }
488
+ };
489
+ function stepAfter(context) {
490
+ return new Step(context, 1);
491
+ }
492
+ var curveTypes = {
493
+ linear: linear_default,
494
+ monotoneX,
495
+ step: stepAfter
496
+ };
497
+ var COLOR_PALETTES = {
498
+ default: [
499
+ "#2563eb",
500
+ // blue-600
501
+ "#dc2626",
502
+ // red-600
503
+ "#9333ea",
504
+ // purple-600
505
+ "#ea580c",
506
+ // orange-600
507
+ "#0891b2",
508
+ // cyan-600
509
+ "#4f46e5",
510
+ // indigo-600
511
+ "#be123c",
512
+ // rose-600
513
+ "#ca8a04",
514
+ // yellow-600
515
+ "#16a34a",
516
+ // green-600
517
+ "#059669"
518
+ // emerald-600
519
+ ]
520
+ };
521
+ var LineChart = ({
522
+ settings,
523
+ width,
524
+ height,
525
+ facetIds
526
+ }) => {
527
+ const [hovered, setHovered] = react.useState(null);
528
+ const updateChart = chunk5B23JVH3_cjs.useDataLayer((state) => state.updateChart);
529
+ const getFieldLabel = chunk5B23JVH3_cjs.useDataLayer((state) => state.getFieldLabel);
530
+ const formatFieldValue = chunk5B23JVH3_cjs.useDataLayer((state) => state.formatFieldValue);
531
+ const fieldSettings = chunk5B23JVH3_cjs.useDataLayer((state) => state.fieldSettings);
532
+ const displayValue = (field, value) => chunk5B23JVH3_cjs.hasFieldDisplayFormat(fieldSettings[field]) ? formatFieldValue?.(field, value) ?? String(value) : String(value);
533
+ const allXData = chunkDKFA4KOJ_cjs.useGetColumnDataForIds(settings.xField);
534
+ const liveIds = chunkDKFA4KOJ_cjs.useGetLiveIds(settings);
535
+ const selectedIds = react.useMemo(
536
+ () => facetIds ? liveIds.filter((id) => facetIds.includes(id)) : liveIds,
537
+ [liveIds, facetIds]
538
+ );
539
+ const liveXData = chunkDKFA4KOJ_cjs.useGetColumnDataForIds(settings.xField, selectedIds);
540
+ const allSeriesData = chunkDKFA4KOJ_cjs.useGetColumnDataForMultipleIds(settings.seriesField);
541
+ const liveSeriesData = chunkDKFA4KOJ_cjs.useGetColumnDataForMultipleIds(
542
+ settings.seriesField,
543
+ selectedIds
544
+ );
545
+ const baseMargin = settings.margin;
546
+ const yValuesByAxis = settings.seriesField.reduce(
547
+ (values, field) => {
548
+ const useRightAxis = settings.seriesSettings[field]?.useRightAxis;
549
+ (allSeriesData[field] ?? []).forEach((value) => {
550
+ const y2 = chunk5B23JVH3_cjs.finiteNumber(value) ?? NaN;
551
+ if (Number.isFinite(y2)) {
552
+ values[useRightAxis ? "right" : "left"].push(y2);
553
+ }
554
+ });
555
+ return values;
556
+ },
557
+ { left: [], right: [] }
558
+ );
559
+ const leftYExtent = d3Array.extent(yValuesByAxis.left);
560
+ const leftYTicks = Number.isFinite(leftYExtent[0]) ? d3Scale.scaleLinear().domain(leftYExtent).nice().ticks(5) : [];
561
+ const axisFields = chunk5B23JVH3_cjs.getChartAxisFields(settings);
562
+ const xAxisLabel = chunk5B23JVH3_cjs.getChartAxisLabel(
563
+ axisFields.x,
564
+ settings.xAxisLabel,
565
+ getFieldLabel
566
+ );
567
+ const yAxisLabel = chunk5B23JVH3_cjs.getChartAxisLabel(
568
+ axisFields.y,
569
+ settings.yAxisLabel,
570
+ getFieldLabel
571
+ );
572
+ const requestedLabelMargin = Math.max(
573
+ baseMargin.left,
574
+ ...leftYTicks.map(
575
+ (tick) => String(tick).length * 7 + (yAxisLabel ? 38 : 18)
576
+ )
577
+ );
578
+ const minPlotWidth = Math.min(
579
+ 80,
580
+ Math.max(0, width - baseMargin.left - baseMargin.right)
581
+ );
582
+ const maxLabelMargin = Math.max(0, width - baseMargin.right - minPlotWidth);
583
+ const margin = {
584
+ ...baseMargin,
585
+ left: Math.min(requestedLabelMargin, maxLabelMargin),
586
+ bottom: Math.max(baseMargin.bottom, xAxisLabel ? 46 : 28)
587
+ };
588
+ if (settings.seriesField.some(
589
+ (field) => settings.seriesSettings[field]?.useRightAxis
590
+ )) {
591
+ margin.right = Math.max(margin.right, 60);
592
+ }
593
+ if (settings.showLegend) {
594
+ switch (settings.legendPosition) {
595
+ case "top":
596
+ margin.top += 18;
597
+ break;
598
+ case "bottom":
599
+ margin.bottom += 18;
600
+ break;
601
+ case "right":
602
+ margin.right += Math.min(110, width * 0.24);
603
+ break;
604
+ case "left":
605
+ margin.left += Math.min(110, width * 0.24);
606
+ break;
607
+ }
608
+ }
609
+ const innerWidth = width - margin.left - margin.right;
610
+ const innerHeight = height - margin.top - margin.bottom;
611
+ const processedLiveSeriesData = react.useMemo(() => {
612
+ const orderedIndices = liveXData.map((_, index) => index).sort((a, b) => {
613
+ const aValue = liveXData[a];
614
+ const bValue = liveXData[b];
615
+ const aX = chunk5B23JVH3_cjs.finiteNumber(aValue) ?? NaN;
616
+ const bX = chunk5B23JVH3_cjs.finiteNumber(bValue) ?? NaN;
617
+ const aFinite = Number.isFinite(aX);
618
+ const bFinite = Number.isFinite(bX);
619
+ if (aFinite !== bFinite) return aFinite ? -1 : 1;
620
+ return aFinite ? aX - bX || a - b : a - b;
621
+ });
622
+ return settings.seriesField.map((field) => {
623
+ const data = liveSeriesData[field] ?? [];
624
+ const reducedData = [];
625
+ let segment = [];
626
+ const flushSegment = () => {
627
+ if (segment.length > 0) {
628
+ reducedData.push(...reduceDataPoints(segment, innerWidth));
629
+ segment = [];
630
+ }
631
+ };
632
+ orderedIndices.forEach((i) => {
633
+ const value = data[i];
634
+ const xValue = liveXData[i];
635
+ const x2 = chunk5B23JVH3_cjs.finiteNumber(xValue) ?? NaN;
636
+ const y2 = chunk5B23JVH3_cjs.finiteNumber(value) ?? NaN;
637
+ if (!Number.isFinite(x2) || !Number.isFinite(y2)) {
638
+ flushSegment();
639
+ reducedData.push({ x: x2, y: null });
640
+ return;
641
+ }
642
+ segment.push({ x: x2, y: y2 });
643
+ });
644
+ flushSegment();
645
+ return { name: field, data: reducedData };
646
+ });
647
+ }, [settings.seriesField, liveSeriesData, liveXData, innerWidth]);
648
+ const seriesColors = react.useMemo(() => {
649
+ const colors = {};
650
+ const palette = COLOR_PALETTES.default;
651
+ const usedPaletteColors = /* @__PURE__ */ new Set();
652
+ settings.seriesField.forEach((field) => {
653
+ const existingColor = settings.seriesSettings[field]?.lineColor;
654
+ if (existingColor && existingColor !== "#000000") {
655
+ colors[field] = existingColor;
656
+ if (palette.includes(existingColor)) {
657
+ usedPaletteColors.add(existingColor);
658
+ }
659
+ }
660
+ });
661
+ const unusedPaletteColors = palette.filter(
662
+ (color) => !usedPaletteColors.has(color)
663
+ );
664
+ settings.seriesField.forEach((field) => {
665
+ if (colors[field]) return;
666
+ const nextColor = unusedPaletteColors.shift();
667
+ colors[field] = nextColor ?? palette[settings.seriesField.indexOf(field) % palette.length];
668
+ });
669
+ return colors;
670
+ }, [settings.seriesField, settings.seriesSettings]);
671
+ react.useEffect(() => {
672
+ requestAnimationFrame(() => {
673
+ const newSeriesSettings = { ...settings.seriesSettings };
674
+ let hasChanges = false;
675
+ settings.seriesField.forEach((field) => {
676
+ if (!newSeriesSettings[field]) {
677
+ newSeriesSettings[field] = { ...DEFAULT_SERIES_SETTINGS };
678
+ hasChanges = true;
679
+ }
680
+ if (!newSeriesSettings[field]?.lineColor || newSeriesSettings[field]?.lineColor === "default") {
681
+ newSeriesSettings[field] = {
682
+ ...newSeriesSettings[field],
683
+ lineColor: seriesColors[field]
684
+ };
685
+ hasChanges = true;
686
+ }
687
+ });
688
+ if (hasChanges) {
689
+ updateChart(settings.id, {
690
+ seriesSettings: newSeriesSettings
691
+ });
692
+ }
693
+ });
694
+ }, [
695
+ seriesColors,
696
+ settings.id,
697
+ settings.seriesField,
698
+ settings.seriesSettings,
699
+ updateChart
700
+ ]);
701
+ if (processedLiveSeriesData.length === 0) {
702
+ return null;
703
+ }
704
+ const xExtent = d3Array.extent(
705
+ allXData.map((value) => chunk5B23JVH3_cjs.finiteNumber(value) ?? NaN).filter(Number.isFinite)
706
+ );
707
+ const rightAxisSeries = processedLiveSeriesData.filter(
708
+ (series) => settings.seriesSettings[series.name]?.useRightAxis
709
+ );
710
+ const rightYExtent = d3Array.extent(yValuesByAxis.right);
711
+ const xScale = chunkUUJMUPB3_cjs.numericScale(settings.xAxis).domain(xExtent).range([0, innerWidth]).nice();
712
+ const leftYScale = chunkUUJMUPB3_cjs.numericScale(settings.yAxis).domain(leftYExtent).range([innerHeight, 0]).nice();
713
+ const rightYScale = chunkUUJMUPB3_cjs.numericScale(settings.yAxis).domain(rightYExtent).range([innerHeight, 0]).nice();
714
+ const createLineGenerator = (yField) => line_default().defined((d) => d.y != null && Number.isFinite(d.x)).x((d) => xScale(d.x)).y(
715
+ (d) => settings.seriesSettings[yField]?.useRightAxis ? rightYScale(d.y ?? 0) : leftYScale(d.y ?? 0)
716
+ ).curve(curveTypes[settings.styles.curveType]);
717
+ const Legend = () => {
718
+ if (!settings.showLegend) return null;
719
+ const vertical = settings.legendPosition === "left" || settings.legendPosition === "right";
720
+ const sideWidth = Math.min(100, width * 0.22);
721
+ const position = settings.legendPosition === "top" ? { top: 0, left: margin.left, right: baseMargin.right } : settings.legendPosition === "bottom" ? { bottom: 0, left: margin.left, right: baseMargin.right } : settings.legendPosition === "left" ? { left: 0, top: margin.top, width: sideWidth } : { right: 0, top: margin.top, width: sideWidth };
722
+ return /* @__PURE__ */ jsxRuntime.jsx(
723
+ "div",
724
+ {
725
+ className: "eda-line-legend",
726
+ style: { ...position, flexDirection: vertical ? "column" : "row" },
727
+ "aria-label": "Chart series",
728
+ children: settings.seriesField.map((name) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "eda-line-legend-item", children: [
729
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "14", height: "6", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(
730
+ "line",
731
+ {
732
+ x1: "0",
733
+ x2: "14",
734
+ y1: "3",
735
+ y2: "3",
736
+ stroke: seriesColors[name],
737
+ strokeWidth: "2",
738
+ strokeDasharray: settings.seriesSettings[name]?.lineStyle === "dashed" ? "4 2" : settings.seriesSettings[name]?.lineStyle === "dotted" ? "1 2" : void 0
739
+ }
740
+ ) }),
741
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
742
+ name,
743
+ settings.seriesSettings[name]?.useRightAxis ? " \u2197" : ""
744
+ ] })
745
+ ] }, name))
746
+ }
747
+ );
748
+ };
749
+ const hoverX = hovered ? hovered.x : NaN;
750
+ const hoverY = hovered ? hovered.y : NaN;
751
+ const hoverRight = hovered ? settings.seriesSettings[hovered.field]?.useRightAxis : false;
752
+ return /* @__PURE__ */ jsxRuntime.jsxs(
753
+ "div",
754
+ {
755
+ className: "relative",
756
+ style: { width, height },
757
+ onPointerLeave: () => setHovered(null),
758
+ onPointerDownCapture: () => setHovered(null),
759
+ onKeyDownCapture: (event) => {
760
+ if (event.key === "Escape") setHovered(null);
761
+ },
762
+ onPointerMove: (event) => {
763
+ if (event.buttons) return;
764
+ const rect = event.currentTarget.getBoundingClientRect();
765
+ const x2 = event.clientX - rect.left - margin.left;
766
+ const y2 = event.clientY - rect.top - margin.top;
767
+ if (x2 < 0 || x2 > innerWidth || y2 < 0 || y2 > innerHeight) {
768
+ setHovered(null);
769
+ return;
770
+ }
771
+ const target = xScale.invert(x2);
772
+ let nearestX = NaN;
773
+ let distance = Infinity;
774
+ for (const series of processedLiveSeriesData) {
775
+ for (const point2 of series.data) {
776
+ if (!Number.isFinite(point2.x)) continue;
777
+ const next = Math.abs(point2.x - target);
778
+ if (next < distance) {
779
+ nearestX = point2.x;
780
+ distance = next;
781
+ }
782
+ }
783
+ }
784
+ if (!Number.isFinite(nearestX)) {
785
+ setHovered(null);
786
+ return;
787
+ }
788
+ let field = null;
789
+ let valueAtX = NaN;
790
+ distance = Infinity;
791
+ for (const series of processedLiveSeriesData) {
792
+ for (const point2 of series.data) {
793
+ if (point2.x !== nearestX || point2.y == null) continue;
794
+ const scale = settings.seriesSettings[series.name]?.useRightAxis ? rightYScale : leftYScale;
795
+ const next = Math.abs(scale(point2.y) - y2);
796
+ if (next < distance) {
797
+ field = series.name;
798
+ valueAtX = point2.y;
799
+ distance = next;
800
+ }
801
+ }
802
+ }
803
+ setHovered(field === null ? null : { x: nearestX, y: valueAtX, field });
804
+ },
805
+ children: [
806
+ /* @__PURE__ */ jsxRuntime.jsx(
807
+ chunkDS5BS7PP_cjs.BaseChart,
808
+ {
809
+ width,
810
+ height,
811
+ xScale,
812
+ yScale: leftYScale,
813
+ settings: {
814
+ ...settings,
815
+ margin,
816
+ xAxis: {
817
+ ...settings.xAxis,
818
+ grid: settings.xAxis.grid ?? settings.showYGrid
819
+ },
820
+ yAxis: {
821
+ ...settings.yAxis,
822
+ grid: settings.yAxis.grid ?? settings.showXGrid
823
+ }
824
+ },
825
+ overlay: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
826
+ rightAxisSeries.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("g", { transform: `translate(${innerWidth}, 0)`, children: rightYScale.ticks(5).map((tick) => /* @__PURE__ */ jsxRuntime.jsxs(
827
+ "g",
828
+ {
829
+ transform: `translate(0, ${rightYScale(tick)})`,
830
+ children: [
831
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: 0, x2: 6, y1: 0, y2: 0, stroke: "currentColor" }),
832
+ /* @__PURE__ */ jsxRuntime.jsx(
833
+ "text",
834
+ {
835
+ x: 9,
836
+ y: 0,
837
+ dy: ".32em",
838
+ fontSize: 10,
839
+ textAnchor: "start",
840
+ fill: "currentColor",
841
+ children: tick
842
+ }
843
+ )
844
+ ]
845
+ },
846
+ tick
847
+ )) }),
848
+ hovered && /* @__PURE__ */ jsxRuntime.jsx(
849
+ AxisReadout,
850
+ {
851
+ x: xScale(hoverX),
852
+ y: (hoverRight ? rightYScale : leftYScale)(hoverY),
853
+ xValue: hoverX,
854
+ yValue: hoverY,
855
+ width: innerWidth,
856
+ height: innerHeight,
857
+ color: seriesColors[hovered.field],
858
+ rightAxis: hoverRight,
859
+ xFormatter: (value) => displayValue(settings.xField, value),
860
+ yFormatter: (value) => displayValue(hovered.field, value),
861
+ label: `${getFieldLabel?.(settings.xField) ?? settings.xField}: ${displayValue(settings.xField, hoverX)}; ${getFieldLabel?.(hovered.field) ?? hovered.field}: ${displayValue(hovered.field, hoverY)}`
862
+ }
863
+ )
864
+ ] }),
865
+ brushingMode: "horizontal",
866
+ onBrushChange: (extent2) => updateChart(settings.id, {
867
+ filters: [
868
+ ...settings.filters.filter(
869
+ (filter) => filter.field !== settings.xField
870
+ ),
871
+ ...extent2 ? [
872
+ {
873
+ type: "range",
874
+ field: settings.xField,
875
+ min: xScale.invert(extent2[0][0]),
876
+ max: xScale.invert(extent2[1][0])
877
+ }
878
+ ] : []
879
+ ]
880
+ }),
881
+ children: /* @__PURE__ */ jsxRuntime.jsx("g", { children: processedLiveSeriesData.map((series) => {
882
+ const lineGenerator = createLineGenerator(series.name);
883
+ const seriesSettings = settings.seriesSettings[series.name] ?? {
884
+ showPoints: false,
885
+ pointSize: 4,
886
+ pointOpacity: 1,
887
+ lineWidth: 2,
888
+ lineOpacity: 0.8,
889
+ lineStyle: "solid",
890
+ useRightAxis: false
891
+ };
892
+ const seriesColor = seriesColors[series.name];
893
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
894
+ /* @__PURE__ */ jsxRuntime.jsx(
895
+ "path",
896
+ {
897
+ d: lineGenerator(series.data) || void 0,
898
+ fill: "none",
899
+ stroke: seriesColor,
900
+ strokeWidth: seriesSettings.lineWidth,
901
+ strokeOpacity: seriesSettings.lineOpacity,
902
+ strokeDasharray: seriesSettings.lineStyle === "dashed" ? "5,5" : seriesSettings.lineStyle === "dotted" ? "2,2" : void 0
903
+ }
904
+ ),
905
+ seriesSettings.showPoints && series.data.map(
906
+ (d, j) => d.y == null ? null : /* @__PURE__ */ jsxRuntime.jsx(
907
+ "circle",
908
+ {
909
+ cx: xScale(d.x),
910
+ cy: (seriesSettings.useRightAxis ? rightYScale : leftYScale)(d.y),
911
+ r: seriesSettings.pointSize,
912
+ fill: seriesColor,
913
+ fillOpacity: seriesSettings.pointOpacity
914
+ },
915
+ j
916
+ )
917
+ )
918
+ ] }, series.name);
919
+ }) })
920
+ }
921
+ ),
922
+ /* @__PURE__ */ jsxRuntime.jsx(Legend, {})
923
+ ]
924
+ }
925
+ );
926
+ };
927
+ function LineSeriesSettings({
928
+ seriesName,
929
+ settings,
930
+ onSettingsChange
931
+ }) {
932
+ const id = react.useId();
933
+ const update = (next) => onSettingsChange({ ...settings, ...next });
934
+ const numericFields = [
935
+ { key: "lineWidth", label: "Line width", min: 1, max: 10, step: 0.5 },
936
+ { key: "lineOpacity", label: "Line opacity", min: 0, max: 1, step: 0.1 },
937
+ ...settings.showPoints ? [
938
+ { key: "pointSize", label: "Point size", min: 1, max: 20, step: 1 },
939
+ {
940
+ key: "pointOpacity",
941
+ label: "Point opacity",
942
+ min: 0,
943
+ max: 1,
944
+ step: 0.1
945
+ }
946
+ ] : []
947
+ ];
948
+ return /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { className: "space-y-3 border-t border-border pt-3", children: [
949
+ /* @__PURE__ */ jsxRuntime.jsx("legend", { className: "px-1 text-sm font-semibold", children: seriesName }),
950
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-5", children: [
951
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
952
+ /* @__PURE__ */ jsxRuntime.jsx(
953
+ chunkAOODAOL4_cjs.Switch,
954
+ {
955
+ id: `${id}-points`,
956
+ "aria-label": `${seriesName} points`,
957
+ checked: settings.showPoints,
958
+ onCheckedChange: (showPoints) => update({ showPoints })
959
+ }
960
+ ),
961
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { htmlFor: `${id}-points`, children: "Show points" })
962
+ ] }),
963
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
964
+ /* @__PURE__ */ jsxRuntime.jsx(
965
+ chunkAOODAOL4_cjs.Switch,
966
+ {
967
+ id: `${id}-axis`,
968
+ "aria-label": `${seriesName} right axis`,
969
+ checked: settings.useRightAxis,
970
+ onCheckedChange: (useRightAxis) => update({ useRightAxis })
971
+ }
972
+ ),
973
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { htmlFor: `${id}-axis`, children: "Right axis" })
974
+ ] })
975
+ ] }),
976
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
977
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
978
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { htmlFor: `${id}-color`, children: "Color" }),
979
+ /* @__PURE__ */ jsxRuntime.jsx(
980
+ "input",
981
+ {
982
+ id: `${id}-color`,
983
+ "aria-label": `${seriesName} color`,
984
+ type: "color",
985
+ value: settings.lineColor ?? "#3479a8",
986
+ onChange: (event) => update({ lineColor: event.target.value }),
987
+ className: "h-8 w-full rounded border"
988
+ }
989
+ )
990
+ ] }),
991
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
992
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { htmlFor: `${id}-style`, children: "Line style" }),
993
+ /* @__PURE__ */ jsxRuntime.jsxs(
994
+ "select",
995
+ {
996
+ id: `${id}-style`,
997
+ value: settings.lineStyle,
998
+ onChange: (event) => update({
999
+ lineStyle: event.target.value
1000
+ }),
1001
+ className: "h-8 w-full rounded border bg-background px-2 text-sm",
1002
+ children: [
1003
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "solid", children: "Solid" }),
1004
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "dashed", children: "Dashed" }),
1005
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "dotted", children: "Dotted" })
1006
+ ]
1007
+ }
1008
+ )
1009
+ ] }),
1010
+ numericFields.map(({ key, label, min, max, step }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
1011
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { htmlFor: `${id}-${key}`, children: label }),
1012
+ /* @__PURE__ */ jsxRuntime.jsx(
1013
+ chunkUAVDLBTA_cjs.NumericInputEnter,
1014
+ {
1015
+ id: `${id}-${key}`,
1016
+ value: settings[key],
1017
+ onChange: (value) => update({ [key]: value }),
1018
+ min,
1019
+ max,
1020
+ stepSmall: step,
1021
+ className: "h-8"
1022
+ }
1023
+ )
1024
+ ] }, key))
1025
+ ] })
1026
+ ] });
1027
+ }
1028
+ var LineChartSettingsPanel = ({ settings, onSettingsChange }) => {
1029
+ const updateSettings = (updates) => {
1030
+ onSettingsChange({ ...settings, ...updates });
1031
+ };
1032
+ const updateStyles = (updates) => {
1033
+ updateSettings({
1034
+ styles: { ...settings.styles, ...updates }
1035
+ });
1036
+ };
1037
+ const updateSeriesSettings = (seriesName, seriesSettings) => {
1038
+ updateSettings({
1039
+ seriesSettings: {
1040
+ ...settings.seriesSettings,
1041
+ [seriesName]: seriesSettings
1042
+ }
1043
+ });
1044
+ };
1045
+ const availableFields = chunk3PGYFLE3_cjs.useColumnNames();
1046
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
1047
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[120px_1fr] items-center gap-4", children: [
1048
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { children: "X Field" }),
1049
+ /* @__PURE__ */ jsxRuntime.jsx(
1050
+ chunkASKFIRMC_cjs.FieldSelector,
1051
+ {
1052
+ label: "",
1053
+ value: settings.xField,
1054
+ onChange: (value) => updateSettings({ xField: value })
1055
+ }
1056
+ ),
1057
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { children: "Series Fields" }),
1058
+ /* @__PURE__ */ jsxRuntime.jsx(
1059
+ chunk3PGYFLE3_cjs.multi_select_default,
1060
+ {
1061
+ options: availableFields.map((f) => ({
1062
+ label: f,
1063
+ value: f
1064
+ })),
1065
+ value: settings.seriesField.map((f) => ({
1066
+ label: f,
1067
+ value: f
1068
+ })),
1069
+ onChange: (values) => {
1070
+ const newSeriesFields = values.map((v) => v.value);
1071
+ const newSeriesSettings = { ...settings.seriesSettings };
1072
+ newSeriesFields.forEach((field) => {
1073
+ if (!newSeriesSettings[field]) {
1074
+ newSeriesSettings[field] = { ...DEFAULT_SERIES_SETTINGS };
1075
+ }
1076
+ });
1077
+ Object.keys(newSeriesSettings).forEach((field) => {
1078
+ if (!newSeriesFields.includes(field)) {
1079
+ delete newSeriesSettings[field];
1080
+ }
1081
+ });
1082
+ updateSettings({
1083
+ seriesField: newSeriesFields,
1084
+ seriesSettings: newSeriesSettings
1085
+ });
1086
+ }
1087
+ }
1088
+ )
1089
+ ] }),
1090
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[120px_1fr] items-center gap-4", children: [
1091
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { children: "Line Style" }),
1092
+ /* @__PURE__ */ jsxRuntime.jsx(
1093
+ chunkASKFIRMC_cjs.ComboBox,
1094
+ {
1095
+ value: {
1096
+ label: settings.styles.curveType === "linear" ? "Linear" : settings.styles.curveType === "monotoneX" ? "Smooth" : "Step",
1097
+ value: settings.styles.curveType
1098
+ },
1099
+ options: [
1100
+ { label: "Linear", value: "linear" },
1101
+ { label: "Smooth", value: "monotoneX" },
1102
+ { label: "Step", value: "step" }
1103
+ ],
1104
+ onChange: (option) => updateStyles({ curveType: option?.value ?? "linear" }),
1105
+ optionToString: (option) => option.label
1106
+ }
1107
+ ),
1108
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { children: "Show Legend" }),
1109
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
1110
+ chunkAOODAOL4_cjs.Switch,
1111
+ {
1112
+ checked: settings.showLegend,
1113
+ onCheckedChange: (checked) => updateSettings({ showLegend: checked })
1114
+ }
1115
+ ) }),
1116
+ settings.showLegend && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1117
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { children: "Legend Position" }),
1118
+ /* @__PURE__ */ jsxRuntime.jsx(
1119
+ chunkASKFIRMC_cjs.ComboBox,
1120
+ {
1121
+ value: {
1122
+ label: settings.legendPosition.charAt(0).toUpperCase() + settings.legendPosition.slice(1),
1123
+ value: settings.legendPosition
1124
+ },
1125
+ options: [
1126
+ { label: "Top", value: "top" },
1127
+ { label: "Right", value: "right" },
1128
+ { label: "Bottom", value: "bottom" },
1129
+ { label: "Left", value: "left" }
1130
+ ],
1131
+ onChange: (option) => updateSettings({
1132
+ legendPosition: option?.value ?? "top"
1133
+ }),
1134
+ optionToString: (option) => option.label
1135
+ }
1136
+ )
1137
+ ] })
1138
+ ] }),
1139
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children: settings.seriesField.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
1140
+ LineSeriesSettings,
1141
+ {
1142
+ seriesName: field,
1143
+ settings: settings.seriesSettings[field] ?? DEFAULT_SERIES_SETTINGS,
1144
+ onSettingsChange: (next) => updateSeriesSettings(field, next)
1145
+ },
1146
+ field
1147
+ )) })
1148
+ ] });
1149
+ };
1150
+
1151
+ // src/components/charts/LineChart/definition.ts
1152
+ var DEFAULT_SERIES_SETTINGS = {
1153
+ showPoints: false,
1154
+ pointSize: 4,
1155
+ pointOpacity: 1,
1156
+ lineWidth: 2,
1157
+ lineOpacity: 0.8,
1158
+ lineStyle: "solid",
1159
+ useRightAxis: false
1160
+ };
1161
+ var lineChartDefinition = {
1162
+ type: "line",
1163
+ name: "Line Chart",
1164
+ description: "Display data as connected points over time or sequence",
1165
+ icon: lucideReact.LineChart,
1166
+ component: LineChart,
1167
+ settingsPanel: LineChartSettingsPanel,
1168
+ createDefaultSettings: (layout) => ({
1169
+ id: "",
1170
+ type: "line",
1171
+ title: "",
1172
+ field: "",
1173
+ layout,
1174
+ colorScaleId: void 0,
1175
+ colorField: void 0,
1176
+ facet: {
1177
+ enabled: false,
1178
+ type: "grid",
1179
+ rowVariable: "",
1180
+ columnVariable: ""
1181
+ },
1182
+ xAxis: {},
1183
+ yAxis: {},
1184
+ margin: { top: 20, right: 60, bottom: 30, left: 60 },
1185
+ filters: [],
1186
+ xAxisLabel: "",
1187
+ yAxisLabel: "",
1188
+ xGridLines: 5,
1189
+ yGridLines: 5,
1190
+ xField: "",
1191
+ seriesField: [],
1192
+ seriesSettings: {},
1193
+ styles: {
1194
+ curveType: "linear"
1195
+ },
1196
+ showXGrid: true,
1197
+ showYGrid: true,
1198
+ showLegend: true,
1199
+ legendPosition: "top"
1200
+ }),
1201
+ validateSettings: (settings) => {
1202
+ return settings.xField !== "" && settings.seriesField.length > 0;
1203
+ },
1204
+ getFilterFunction: (settings, fieldGetter) => {
1205
+ return (d) => settings.filters.every(
1206
+ (filter) => chunkEU5EFHO5_cjs.applyFilter(fieldGetter(filter.field)[d], filter)
1207
+ );
1208
+ }
1209
+ };
1210
+
1211
+ exports.DEFAULT_SERIES_SETTINGS = DEFAULT_SERIES_SETTINGS;
1212
+ exports.lineChartDefinition = lineChartDefinition;
1213
+ //# sourceMappingURL=chunk-4QNENKTV.cjs.map
1214
+ //# sourceMappingURL=chunk-4QNENKTV.cjs.map