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,843 @@
1
+ 'use strict';
2
+
3
+ var chunkB7OQUBH4_cjs = require('./chunk-B7OQUBH4.cjs');
4
+ var chunkU74A5VK5_cjs = require('./chunk-U74A5VK5.cjs');
5
+ var chunkDS5BS7PP_cjs = require('./chunk-DS5BS7PP.cjs');
6
+ var chunkUUJMUPB3_cjs = require('./chunk-UUJMUPB3.cjs');
7
+ var chunkASKFIRMC_cjs = require('./chunk-ASKFIRMC.cjs');
8
+ var chunkAOODAOL4_cjs = require('./chunk-AOODAOL4.cjs');
9
+ var chunkDKFA4KOJ_cjs = require('./chunk-DKFA4KOJ.cjs');
10
+ var chunkEU5EFHO5_cjs = require('./chunk-EU5EFHO5.cjs');
11
+ var chunkMJROUIDZ_cjs = require('./chunk-MJROUIDZ.cjs');
12
+ var chunk5B23JVH3_cjs = require('./chunk-5B23JVH3.cjs');
13
+ var d3Scale = require('d3-scale');
14
+ var natsort = require('natsort');
15
+ var react = require('react');
16
+ var jsxRuntime = require('react/jsx-runtime');
17
+
18
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
19
+
20
+ var natsort__default = /*#__PURE__*/_interopDefault(natsort);
21
+
22
+ // src/components/charts/BoxPlot/boxPlotCalculations.ts
23
+ var MAX_BEE_SWARM_POINTS_PER_GROUP = 300;
24
+ function getQuartile(sortedData, q) {
25
+ const pos = (sortedData.length - 1) * q;
26
+ const base = Math.floor(pos);
27
+ const rest = pos - base;
28
+ const value = sortedData[base];
29
+ const next = sortedData[base + 1];
30
+ if (next !== void 0) {
31
+ return value + rest * (next - value);
32
+ } else {
33
+ return value;
34
+ }
35
+ }
36
+ function calculateBoxPlotStats(data, whiskerType) {
37
+ if (data.length === 0) {
38
+ return {
39
+ q1: 0,
40
+ median: 0,
41
+ q3: 0,
42
+ iqr: 0,
43
+ whiskerLow: 0,
44
+ whiskerHigh: 0,
45
+ outliers: [],
46
+ totalCount: 0
47
+ };
48
+ }
49
+ const sortedData = [...data].sort((a, b) => a - b);
50
+ const q1 = getQuartile(sortedData, 0.25);
51
+ const median = getQuartile(sortedData, 0.5);
52
+ const q3 = getQuartile(sortedData, 0.75);
53
+ const iqr = q3 - q1;
54
+ let whiskerLow;
55
+ let whiskerHigh;
56
+ let outliers;
57
+ switch (whiskerType) {
58
+ case "tukey": {
59
+ const lowerFence = q1 - 1.5 * iqr;
60
+ const upperFence = q3 + 1.5 * iqr;
61
+ whiskerLow = sortedData.find((value) => value >= lowerFence) ?? sortedData[0];
62
+ whiskerHigh = [...sortedData].reverse().find((value) => value <= upperFence) ?? sortedData[sortedData.length - 1];
63
+ if (whiskerLow > whiskerHigh) {
64
+ whiskerLow = sortedData[0];
65
+ whiskerHigh = sortedData[sortedData.length - 1];
66
+ }
67
+ outliers = sortedData.filter((x) => x < whiskerLow || x > whiskerHigh);
68
+ break;
69
+ }
70
+ case "minmax": {
71
+ whiskerLow = sortedData[0];
72
+ whiskerHigh = sortedData[sortedData.length - 1];
73
+ outliers = [];
74
+ break;
75
+ }
76
+ case "stdDev": {
77
+ const mean = sortedData.reduce((sum, x) => sum + x, 0) / sortedData.length;
78
+ const stdDev = Math.sqrt(
79
+ sortedData.reduce((sum, x) => sum + Math.pow(x - mean, 2), 0) / sortedData.length
80
+ );
81
+ whiskerLow = mean - 2 * stdDev;
82
+ whiskerHigh = mean + 2 * stdDev;
83
+ outliers = sortedData.filter((x) => x < whiskerLow || x > whiskerHigh);
84
+ break;
85
+ }
86
+ }
87
+ return {
88
+ q1,
89
+ median,
90
+ q3,
91
+ iqr,
92
+ whiskerLow,
93
+ whiskerHigh,
94
+ outliers,
95
+ totalCount: data.length
96
+ };
97
+ }
98
+ function calculateKernelDensity(data, bandwidth, numPoints = 100) {
99
+ const sortedData = [...data].sort((a, b) => a - b);
100
+ if (sortedData.length === 0) {
101
+ return [];
102
+ }
103
+ const min = sortedData[0];
104
+ const max = sortedData[sortedData.length - 1];
105
+ const range = max - min;
106
+ const points = Array.from({ length: numPoints }, (_, i) => {
107
+ const t = i / (numPoints - 1);
108
+ return min + t * range;
109
+ });
110
+ const density = points.map((x) => {
111
+ const sum = sortedData.reduce((acc, xi) => {
112
+ const diff = x - xi;
113
+ return acc + Math.exp(-(diff * diff) / (2 * bandwidth * bandwidth));
114
+ }, 0);
115
+ const densityValue = sum / (sortedData.length * bandwidth * Math.sqrt(2 * Math.PI));
116
+ return [x, densityValue];
117
+ });
118
+ const maxDensity = Math.max(...density.map(([, y]) => y));
119
+ return density.map(([x, y]) => [x, y / maxDensity]);
120
+ }
121
+ function calculateBeeSwarmPositions(data, width, maxPoints = MAX_BEE_SWARM_POINTS_PER_GROUP, seed = 0, yToPixel = (value) => value) {
122
+ if (data.length > maxPoints) {
123
+ const shuffled = [...data];
124
+ let state = seed >>> 0;
125
+ const random = () => {
126
+ state = state * 1664525 + 1013904223 >>> 0;
127
+ return state / 2 ** 32;
128
+ };
129
+ for (let i = shuffled.length - 1; i > 0; i--) {
130
+ const j = Math.floor(random() * (i + 1));
131
+ const value = shuffled[i];
132
+ shuffled[i] = shuffled[j];
133
+ shuffled[j] = value;
134
+ }
135
+ const sampledData = shuffled.slice(0, maxPoints);
136
+ return calculateBeeSwarmPositionsForData(sampledData, width, yToPixel);
137
+ }
138
+ return calculateBeeSwarmPositionsForData(data, width, yToPixel);
139
+ }
140
+ function calculateBeeSwarmPositionsForData(data, width, yToPixel) {
141
+ const positions = [];
142
+ const radius = 2;
143
+ const spacing = radius * 2;
144
+ const sortedData = [...data].sort((a, b) => a - b);
145
+ const screenY = sortedData.map(yToPixel);
146
+ for (let index = 0; index < sortedData.length; index++) {
147
+ const value = sortedData[index];
148
+ const pointY = screenY[index];
149
+ let x = 0;
150
+ let attempts = 0;
151
+ const maxAttempts = 100;
152
+ while (attempts < maxAttempts) {
153
+ const overlaps = positions.some(([px], positionIndex) => {
154
+ const dx = x - px;
155
+ const dy = pointY - screenY[positionIndex];
156
+ return dx * dx + dy * dy < spacing * spacing;
157
+ });
158
+ if (!overlaps) {
159
+ break;
160
+ }
161
+ x = (x + spacing) % width;
162
+ attempts++;
163
+ }
164
+ positions.push([x, value]);
165
+ }
166
+ return positions;
167
+ }
168
+ var Y_SCALE_PADDING = 0.1;
169
+ var BOX_PADDING = 0.2;
170
+ function BoxPlot({
171
+ settings,
172
+ width,
173
+ height,
174
+ facetIds
175
+ }) {
176
+ const [tooltip, setTooltip] = react.useState(null);
177
+ const updateChart = chunk5B23JVH3_cjs.useDataLayer((s) => s.updateChart);
178
+ const getFieldLabel = chunk5B23JVH3_cjs.useDataLayer((s) => s.getFieldLabel);
179
+ const fieldSettings = chunk5B23JVH3_cjs.useDataLayer((s) => s.fieldSettings);
180
+ const formatFieldValue = chunk5B23JVH3_cjs.useDataLayer((s) => s.formatFieldValue);
181
+ const { getColorForValue } = chunkB7OQUBH4_cjs.useColorScales();
182
+ void fieldSettings[settings.field];
183
+ if (settings.colorField) void fieldSettings[settings.colorField];
184
+ const allData = chunkDKFA4KOJ_cjs.useGetColumnDataForIds(settings.field);
185
+ const allGroupData = chunkDKFA4KOJ_cjs.useGetColumnDataForIds(settings.colorField);
186
+ const liveData = chunkDKFA4KOJ_cjs.useGetLiveData(settings, settings.field, facetIds);
187
+ const colorFieldData = chunkDKFA4KOJ_cjs.useGetLiveData(
188
+ settings,
189
+ settings.colorField,
190
+ facetIds
191
+ );
192
+ const hasColorField = !!settings.colorField;
193
+ const axisFields = chunk5B23JVH3_cjs.getChartAxisFields(settings);
194
+ const xAxisLabel = chunk5B23JVH3_cjs.getChartAxisLabel(
195
+ axisFields.x,
196
+ settings.xAxisLabel,
197
+ getFieldLabel
198
+ );
199
+ const yAxisLabel = chunk5B23JVH3_cjs.getChartAxisLabel(
200
+ axisFields.y,
201
+ settings.yAxisLabel,
202
+ getFieldLabel
203
+ );
204
+ const margin = {
205
+ ...settings.margin,
206
+ left: Math.max(settings.margin.left, yAxisLabel ? 64 : 42),
207
+ bottom: Math.max(settings.margin.bottom, xAxisLabel ? 44 : 28)
208
+ };
209
+ const innerWidth = width - margin.left - margin.right;
210
+ const innerHeight = height - margin.top - margin.bottom;
211
+ const groupedData = react.useMemo(() => {
212
+ if (!hasColorField) {
213
+ const validData = chunk5B23JVH3_cjs.finiteNumbers(liveData);
214
+ const result2 = [
215
+ {
216
+ group: "All Data",
217
+ data: validData
218
+ }
219
+ ];
220
+ return result2;
221
+ }
222
+ const groups = /* @__PURE__ */ new Map();
223
+ liveData.forEach((value, index) => {
224
+ const colorValue = chunk5B23JVH3_cjs.categoryValue(colorFieldData[index]);
225
+ const numValue = chunk5B23JVH3_cjs.finiteNumber(value);
226
+ if (numValue === void 0) return;
227
+ if (!groups.has(colorValue)) groups.set(colorValue, []);
228
+ groups.get(colorValue).push(numValue);
229
+ });
230
+ const result = Array.from(groups.entries()).map(([group, data]) => ({
231
+ group,
232
+ data
233
+ }));
234
+ return result;
235
+ }, [liveData, colorFieldData, hasColorField]);
236
+ const groupStats = react.useMemo(() => {
237
+ const stats = groupedData.map(({ group, data }) => ({
238
+ group,
239
+ stats: calculateBoxPlotStats(data, settings.whiskerType)
240
+ }));
241
+ return stats;
242
+ }, [groupedData, settings.whiskerType]);
243
+ const groupKDEs = react.useMemo(() => {
244
+ if (!settings.violinOverlay) {
245
+ return null;
246
+ }
247
+ return groupedData.map(({ group, data }) => {
248
+ const mean = data.reduce((sum, value) => sum + value, 0) / data.length;
249
+ const stdDev = Math.sqrt(
250
+ data.reduce((sum, value) => sum + (value - mean) ** 2, 0) / data.length
251
+ );
252
+ const autoBandwidth = Math.max(
253
+ 1e-3,
254
+ 1.06 * (stdDev || 1) * Math.pow(Math.max(1, data.length), -0.2)
255
+ );
256
+ const bandwidth = settings.autoBandwidth ? autoBandwidth : settings.violinBandwidth;
257
+ return {
258
+ group,
259
+ kde: calculateKernelDensity(data, bandwidth)
260
+ };
261
+ });
262
+ }, [
263
+ settings.violinOverlay,
264
+ settings.autoBandwidth,
265
+ settings.violinBandwidth,
266
+ groupedData
267
+ ]);
268
+ const xScale = react.useMemo(() => {
269
+ const groups = settings.colorField ? [...new Set(allGroupData.map(chunk5B23JVH3_cjs.categoryLabel))] : ["All Data"];
270
+ const medians = /* @__PURE__ */ new Map();
271
+ if (settings.sortBy === "median") {
272
+ const values = /* @__PURE__ */ new Map();
273
+ allData.forEach((value, index) => {
274
+ const number = chunk5B23JVH3_cjs.finiteNumber(value);
275
+ if (number === void 0) return;
276
+ const group = settings.colorField ? chunk5B23JVH3_cjs.categoryLabel(allGroupData[index]) : "All Data";
277
+ if (!values.has(group)) values.set(group, []);
278
+ values.get(group).push(number);
279
+ });
280
+ values.forEach(
281
+ (data, group) => medians.set(
282
+ group,
283
+ calculateBoxPlotStats(data, settings.whiskerType).median
284
+ )
285
+ );
286
+ }
287
+ const sortedGroups = [...groups].sort((a, b) => {
288
+ if (settings.sortBy === "median") {
289
+ return (medians.get(b) ?? 0) - (medians.get(a) ?? 0);
290
+ }
291
+ return natsort__default.default()(a, b);
292
+ });
293
+ const scale = d3Scale.scaleBand().domain(sortedGroups).range([0, innerWidth]).padding(BOX_PADDING);
294
+ return scale;
295
+ }, [
296
+ allData,
297
+ allGroupData,
298
+ settings.colorField,
299
+ innerWidth,
300
+ settings.sortBy,
301
+ settings.whiskerType
302
+ ]);
303
+ const createPath = react.useCallback((points) => {
304
+ if (points.length === 0) {
305
+ return "";
306
+ }
307
+ return points.map((point, i) => `${i === 0 ? "M" : "L"} ${point[0]} ${point[1]}`).join(" ");
308
+ }, []);
309
+ const yScale = react.useMemo(() => {
310
+ const values = chunk5B23JVH3_cjs.finiteNumbers(allData);
311
+ const min = Math.min(...values);
312
+ const max = Math.max(...values);
313
+ const range = max - min;
314
+ const padding = range * Y_SCALE_PADDING;
315
+ const scale = chunkUUJMUPB3_cjs.numericScale(settings.yAxis).domain([
316
+ settings.yAxis.scaleType === "symlog" ? min : min - padding,
317
+ max + padding
318
+ ]).range([innerHeight, 0]);
319
+ return scale;
320
+ }, [allData, innerHeight, settings.yAxis]);
321
+ const groupBeeSwarmPositions = react.useMemo(() => {
322
+ if (!settings.beeSwarmOverlay) {
323
+ return null;
324
+ }
325
+ return groupedData.map(({ group, data }) => ({
326
+ group,
327
+ positions: calculateBeeSwarmPositions(
328
+ data,
329
+ xScale.bandwidth(),
330
+ MAX_BEE_SWARM_POINTS_PER_GROUP,
331
+ 0,
332
+ yScale
333
+ )
334
+ }));
335
+ }, [groupedData, settings.beeSwarmOverlay, xScale, yScale]);
336
+ const beeSwarmIsSampled = settings.beeSwarmOverlay && groupedData.some(
337
+ ({ data }) => data.length > MAX_BEE_SWARM_POINTS_PER_GROUP
338
+ );
339
+ const activeFilter = react.useMemo(() => {
340
+ return settings.filters.find(
341
+ (f) => f.field === settings.colorField
342
+ );
343
+ }, [settings.filters, settings.colorField]);
344
+ const handleBoxClick = react.useCallback(
345
+ (group) => {
346
+ if (!settings.colorField) {
347
+ return;
348
+ }
349
+ let newValues = [];
350
+ if (activeFilter && activeFilter.type === "value") {
351
+ if (chunk5B23JVH3_cjs.categoryIncludes(activeFilter.values, group)) {
352
+ newValues = activeFilter.values.filter(
353
+ (v) => !chunk5B23JVH3_cjs.categoryEqual(v, group)
354
+ );
355
+ } else {
356
+ newValues = [...activeFilter.values, group];
357
+ }
358
+ } else {
359
+ newValues = [group];
360
+ }
361
+ const newFilters = settings.filters.filter(
362
+ (f) => f.field !== settings.colorField
363
+ );
364
+ if (newValues.length > 0) {
365
+ newFilters.push({
366
+ type: "value",
367
+ field: settings.colorField,
368
+ values: newValues
369
+ });
370
+ }
371
+ updateChart(settings.id, { filters: newFilters });
372
+ },
373
+ [
374
+ settings.colorField,
375
+ settings.filters,
376
+ settings.id,
377
+ activeFilter,
378
+ updateChart
379
+ ]
380
+ );
381
+ const isGroupFiltered = react.useCallback(
382
+ (group) => {
383
+ if (!settings.colorField) {
384
+ return true;
385
+ }
386
+ if (!activeFilter || activeFilter.type !== "value" || !activeFilter.values) {
387
+ return true;
388
+ }
389
+ return chunkEU5EFHO5_cjs.applyFilter(group, activeFilter);
390
+ },
391
+ [settings.colorField, activeFilter]
392
+ );
393
+ return /* @__PURE__ */ jsxRuntime.jsxs(
394
+ "div",
395
+ {
396
+ className: "relative",
397
+ style: { width, height },
398
+ onPointerLeave: () => setTooltip(null),
399
+ children: [
400
+ tooltip && /* @__PURE__ */ jsxRuntime.jsx("div", { role: "tooltip", className: "eda-tooltip", children: tooltip }),
401
+ /* @__PURE__ */ jsxRuntime.jsxs(
402
+ chunkDS5BS7PP_cjs.BaseChart,
403
+ {
404
+ width,
405
+ height,
406
+ xScale,
407
+ yScale,
408
+ brushingMode: "none",
409
+ settings: { ...settings, margin },
410
+ children: [
411
+ beeSwarmIsSampled && /* @__PURE__ */ jsxRuntime.jsxs(
412
+ "text",
413
+ {
414
+ x: innerWidth,
415
+ y: 14,
416
+ textAnchor: "end",
417
+ fontSize: 10,
418
+ className: "fill-muted-foreground",
419
+ pointerEvents: "none",
420
+ children: [
421
+ "Sample \u2264",
422
+ MAX_BEE_SWARM_POINTS_PER_GROUP,
423
+ "/group \xB7 boxes use all rows"
424
+ ]
425
+ }
426
+ ),
427
+ groupStats.filter(({ stats }) => stats.totalCount > 0).map(({ group, stats }) => {
428
+ const isFiltered = isGroupFiltered(group);
429
+ const boxColor = isFiltered ? getColorForValue(
430
+ settings.colorScaleId,
431
+ group,
432
+ settings.styles.boxFill
433
+ ) : "rgb(156 163 175)";
434
+ const xPos = xScale(chunk5B23JVH3_cjs.categoryLabel(group)) ?? 0;
435
+ const boxWidth = xScale.bandwidth();
436
+ const kde = groupKDEs?.find((g) => g.group === group)?.kde;
437
+ const firstKde = kde?.[0];
438
+ const lastKde = kde?.at(-1);
439
+ const beeSwarmPositions = groupBeeSwarmPositions?.find(
440
+ (g) => g.group === group
441
+ )?.positions;
442
+ const format = (value) => formatFieldValue(settings.field, value);
443
+ const formatGroup = (value) => settings.colorField ? formatFieldValue(settings.colorField, value) : chunk5B23JVH3_cjs.categoryLabel(value);
444
+ const boxTooltipContent = /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
445
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "font-medium", children: [
446
+ formatGroup(group),
447
+ " ",
448
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-normal text-muted-foreground", children: [
449
+ "\xB7 ",
450
+ stats.totalCount,
451
+ " rows"
452
+ ] })
453
+ ] }),
454
+ /* @__PURE__ */ jsxRuntime.jsxs("dl", { className: "grid grid-cols-[auto_auto] gap-x-3", children: [
455
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Median" }),
456
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { className: "text-right tabular-nums", children: format(stats.median) }),
457
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Middle 50%" }),
458
+ /* @__PURE__ */ jsxRuntime.jsxs("dd", { className: "text-right tabular-nums", children: [
459
+ format(stats.q1),
460
+ "\u2013",
461
+ format(stats.q3)
462
+ ] }),
463
+ stats.outliers.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
464
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Outliers" }),
465
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { className: "text-right", children: stats.outliers.length })
466
+ ] })
467
+ ] })
468
+ ] });
469
+ const whiskerTooltipContent = /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
470
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium", children: formatGroup(group) }),
471
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
472
+ "Whiskers ",
473
+ format(stats.whiskerLow),
474
+ "\u2013",
475
+ format(stats.whiskerHigh)
476
+ ] })
477
+ ] });
478
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${xPos}, 0)`, children: [
479
+ /* @__PURE__ */ jsxRuntime.jsx(
480
+ "line",
481
+ {
482
+ onPointerEnter: () => setTooltip(whiskerTooltipContent),
483
+ onPointerLeave: () => setTooltip(null),
484
+ x1: boxWidth / 2,
485
+ x2: boxWidth / 2,
486
+ y1: yScale(stats.whiskerHigh),
487
+ y2: yScale(stats.whiskerLow),
488
+ stroke: boxColor,
489
+ strokeWidth: settings.styles.whiskerStrokeWidth
490
+ }
491
+ ),
492
+ /* @__PURE__ */ jsxRuntime.jsx(
493
+ "rect",
494
+ {
495
+ onPointerEnter: () => setTooltip(boxTooltipContent),
496
+ onPointerMove: () => setTooltip(boxTooltipContent),
497
+ onPointerLeave: () => setTooltip(null),
498
+ onFocus: () => setTooltip(boxTooltipContent),
499
+ onBlur: () => setTooltip(null),
500
+ role: settings.colorField ? "button" : void 0,
501
+ tabIndex: settings.colorField ? 0 : void 0,
502
+ "aria-label": `${group}: median ${stats.median.toFixed(2)}, ${stats.totalCount} records`,
503
+ "aria-pressed": activeFilter?.type === "value" ? chunk5B23JVH3_cjs.categoryIncludes(activeFilter.values, group) : false,
504
+ onKeyDown: (event) => {
505
+ if (event.key === "Enter" || event.key === " ") {
506
+ event.preventDefault();
507
+ handleBoxClick(group);
508
+ }
509
+ },
510
+ className: "chart-mark",
511
+ rx: 2,
512
+ x: boxWidth * 0.15,
513
+ y: yScale(stats.q3),
514
+ width: boxWidth * 0.7,
515
+ height: yScale(stats.q1) - yScale(stats.q3),
516
+ fill: boxColor,
517
+ stroke: settings.styles.boxStroke,
518
+ strokeWidth: settings.styles.boxStrokeWidth,
519
+ onClick: () => handleBoxClick(group),
520
+ style: {
521
+ cursor: settings.colorField ? "pointer" : "default"
522
+ }
523
+ }
524
+ ),
525
+ /* @__PURE__ */ jsxRuntime.jsx(
526
+ "line",
527
+ {
528
+ pointerEvents: "none",
529
+ x1: 0,
530
+ x2: boxWidth,
531
+ y1: yScale(stats.median),
532
+ y2: yScale(stats.median),
533
+ stroke: settings.styles.medianStroke,
534
+ strokeWidth: settings.styles.medianStrokeWidth
535
+ }
536
+ ),
537
+ settings.showOutliers && stats.outliers.map((value, i) => /* @__PURE__ */ jsxRuntime.jsx(
538
+ "circle",
539
+ {
540
+ onPointerEnter: () => setTooltip(/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
541
+ "Outlier: ",
542
+ format(value)
543
+ ] })),
544
+ onPointerLeave: () => setTooltip(null),
545
+ cx: boxWidth / 2,
546
+ cy: yScale(value),
547
+ r: settings.styles.outlierSize,
548
+ fill: boxColor,
549
+ stroke: settings.styles.outlierStroke
550
+ },
551
+ i
552
+ )),
553
+ settings.violinOverlay && kde && firstKde && lastKde && /* @__PURE__ */ jsxRuntime.jsx("g", { children: /* @__PURE__ */ jsxRuntime.jsx(
554
+ "path",
555
+ {
556
+ d: createPath(
557
+ settings.beeSwarmOverlay ? (
558
+ // If bee swarm is enabled, only show left half of violin
559
+ [
560
+ [boxWidth / 2, yScale(firstKde[0])],
561
+ ...kde.map(
562
+ ([x, y]) => [
563
+ boxWidth / 2 - y * boxWidth * 0.4,
564
+ yScale(x)
565
+ ]
566
+ ),
567
+ [boxWidth / 2, yScale(lastKde[0])]
568
+ ]
569
+ ) : (
570
+ // Otherwise show full violin
571
+ [
572
+ [boxWidth / 2, yScale(firstKde[0])],
573
+ ...kde.map(
574
+ ([x, y]) => [
575
+ boxWidth / 2 + y * boxWidth * 0.4,
576
+ yScale(x)
577
+ ]
578
+ ),
579
+ ...[...kde].reverse().map(
580
+ ([x, y]) => [
581
+ boxWidth / 2 - y * boxWidth * 0.4,
582
+ yScale(x)
583
+ ]
584
+ )
585
+ ]
586
+ )
587
+ ),
588
+ fill: boxColor,
589
+ fillOpacity: 0.2,
590
+ stroke: boxColor,
591
+ strokeWidth: 1,
592
+ pointerEvents: "none"
593
+ }
594
+ ) }),
595
+ settings.beeSwarmOverlay && beeSwarmPositions && /* @__PURE__ */ jsxRuntime.jsx("g", { children: beeSwarmPositions.map(([x, y], i) => /* @__PURE__ */ jsxRuntime.jsx(
596
+ "circle",
597
+ {
598
+ cx: settings.violinOverlay ? boxWidth / 2 + Math.abs(x) : boxWidth / 2 + x,
599
+ cy: yScale(y),
600
+ r: 2,
601
+ fill: boxColor,
602
+ fillOpacity: 0.5,
603
+ stroke: "none",
604
+ pointerEvents: "none"
605
+ },
606
+ i
607
+ )) })
608
+ ] }, chunk5B23JVH3_cjs.categoryLabel(group));
609
+ })
610
+ ]
611
+ }
612
+ )
613
+ ]
614
+ }
615
+ );
616
+ }
617
+ function BoxPlotSettingsPanel({
618
+ settings,
619
+ onSettingsChange
620
+ }) {
621
+ const { getOrCreateScaleForField } = chunkB7OQUBH4_cjs.useColorScales();
622
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
623
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[120px_1fr] items-center gap-4", children: [
624
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { htmlFor: "field", children: "Field" }),
625
+ /* @__PURE__ */ jsxRuntime.jsx(
626
+ chunkASKFIRMC_cjs.FieldSelector,
627
+ {
628
+ label: "",
629
+ value: settings.field,
630
+ onChange: (value) => onSettingsChange({ ...settings, field: value })
631
+ }
632
+ )
633
+ ] }),
634
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[120px_1fr] items-center gap-4", children: [
635
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { htmlFor: "colorField", children: "Color Field" }),
636
+ /* @__PURE__ */ jsxRuntime.jsx(
637
+ chunkASKFIRMC_cjs.FieldSelector,
638
+ {
639
+ label: "",
640
+ value: settings.colorField ?? "",
641
+ allowClear: true,
642
+ onChange: (value) => onSettingsChange({
643
+ ...settings,
644
+ colorField: value || void 0,
645
+ colorScaleId: value ? getOrCreateScaleForField(value) : void 0
646
+ })
647
+ }
648
+ )
649
+ ] }),
650
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[120px_1fr] items-center gap-4", children: [
651
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { htmlFor: "whiskerType", children: "Whisker Type" }),
652
+ /* @__PURE__ */ jsxRuntime.jsx(
653
+ chunkASKFIRMC_cjs.ComboBox,
654
+ {
655
+ value: settings.whiskerType,
656
+ options: ["tukey", "minmax", "stdDev"],
657
+ onChange: (value) => onSettingsChange({
658
+ ...settings,
659
+ whiskerType: value
660
+ }),
661
+ placeholder: "Select whisker type",
662
+ optionToString: (option) => option
663
+ }
664
+ )
665
+ ] }),
666
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[120px_1fr] items-center gap-4", children: [
667
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { htmlFor: "showOutliers", children: "Show Outliers" }),
668
+ /* @__PURE__ */ jsxRuntime.jsx(
669
+ chunkAOODAOL4_cjs.Switch,
670
+ {
671
+ id: "showOutliers",
672
+ checked: settings.showOutliers,
673
+ onCheckedChange: (checked) => onSettingsChange({ ...settings, showOutliers: checked })
674
+ }
675
+ )
676
+ ] }),
677
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[120px_1fr] items-center gap-4", children: [
678
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { htmlFor: "sortBy", children: "Sort By" }),
679
+ /* @__PURE__ */ jsxRuntime.jsx(
680
+ chunkASKFIRMC_cjs.ComboBox,
681
+ {
682
+ value: settings.sortBy,
683
+ options: ["median", "label"],
684
+ onChange: (value) => onSettingsChange({
685
+ ...settings,
686
+ sortBy: value
687
+ }),
688
+ placeholder: "Select sorting method",
689
+ optionToString: (option) => option
690
+ }
691
+ )
692
+ ] }),
693
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[120px_1fr] items-center gap-4", children: [
694
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { htmlFor: "violinOverlay", children: "Violin Overlay" }),
695
+ /* @__PURE__ */ jsxRuntime.jsx(
696
+ chunkAOODAOL4_cjs.Switch,
697
+ {
698
+ id: "violinOverlay",
699
+ checked: settings.violinOverlay,
700
+ onCheckedChange: (checked) => onSettingsChange({ ...settings, violinOverlay: checked })
701
+ }
702
+ )
703
+ ] }),
704
+ settings.violinOverlay && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
705
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[120px_1fr] items-center gap-4", children: [
706
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { htmlFor: "autoBandwidth", children: "Auto Bandwidth" }),
707
+ /* @__PURE__ */ jsxRuntime.jsx(
708
+ chunkAOODAOL4_cjs.Switch,
709
+ {
710
+ id: "autoBandwidth",
711
+ checked: settings.autoBandwidth,
712
+ onCheckedChange: (checked) => onSettingsChange({ ...settings, autoBandwidth: checked })
713
+ }
714
+ )
715
+ ] }),
716
+ !settings.autoBandwidth && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[120px_1fr] items-center gap-4", children: [
717
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { htmlFor: "violinBandwidth", children: "Bandwidth" }),
718
+ /* @__PURE__ */ jsxRuntime.jsx(
719
+ "input",
720
+ {
721
+ type: "number",
722
+ id: "violinBandwidth",
723
+ min: "0.1",
724
+ max: "1",
725
+ step: "0.1",
726
+ value: settings.violinBandwidth,
727
+ onChange: (e) => onSettingsChange({
728
+ ...settings,
729
+ violinBandwidth: parseFloat(e.target.value)
730
+ }),
731
+ className: "w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
732
+ }
733
+ )
734
+ ] })
735
+ ] }),
736
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[120px_1fr] items-center gap-4", children: [
737
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMJROUIDZ_cjs.Label, { htmlFor: "beeSwarmOverlay", children: "Bee Swarm" }),
738
+ /* @__PURE__ */ jsxRuntime.jsx(
739
+ chunkAOODAOL4_cjs.Switch,
740
+ {
741
+ id: "beeSwarmOverlay",
742
+ checked: settings.beeSwarmOverlay,
743
+ onCheckedChange: (checked) => onSettingsChange({ ...settings, beeSwarmOverlay: checked })
744
+ }
745
+ )
746
+ ] })
747
+ ] });
748
+ }
749
+ function BoxPlotIcon({ className }) {
750
+ return /* @__PURE__ */ jsxRuntime.jsxs(
751
+ "svg",
752
+ {
753
+ xmlns: "http://www.w3.org/2000/svg",
754
+ width: "200",
755
+ height: "200",
756
+ viewBox: "0 0 32 32",
757
+ className,
758
+ children: [
759
+ /* @__PURE__ */ jsxRuntime.jsx(
760
+ "path",
761
+ {
762
+ fill: "currentColor",
763
+ d: "M22 6V4H12v2h4v2h-4v12h4v2h-4v2h10v-2h-4v-2h4V8h-4V6Zm-8 12v-3h6v3Zm6-5h-6v-3h6Z"
764
+ }
765
+ ),
766
+ /* @__PURE__ */ jsxRuntime.jsx("path", { fill: "currentColor", d: "M30 30H4a2 2 0 0 1-2-2V2h2v26h26Z" })
767
+ ]
768
+ }
769
+ );
770
+ }
771
+
772
+ // src/components/charts/BoxPlot/definition.ts
773
+ var boxPlotDefinition = {
774
+ type: "boxplot",
775
+ name: "Box Plot",
776
+ description: "Display distribution of values with quartiles and outliers",
777
+ icon: BoxPlotIcon,
778
+ component: BoxPlot,
779
+ settingsPanel: BoxPlotSettingsPanel,
780
+ createDefaultSettings: (layout, field) => ({
781
+ ...chunkU74A5VK5_cjs.DEFAULT_CHART_SETTINGS,
782
+ id: crypto.randomUUID(),
783
+ field: field ?? "",
784
+ type: "boxplot",
785
+ title: "Box Plot",
786
+ layout,
787
+ whiskerType: "tukey",
788
+ showOutliers: true,
789
+ violinOverlay: false,
790
+ beeSwarmOverlay: false,
791
+ sortBy: "label",
792
+ violinBandwidth: 0.3,
793
+ autoBandwidth: true,
794
+ styles: {
795
+ boxFill: "hsl(217.2 91.2% 59.8%)",
796
+ boxStroke: "black",
797
+ boxStrokeWidth: 1,
798
+ medianStroke: "white",
799
+ medianStrokeWidth: 2,
800
+ whiskerStroke: "black",
801
+ whiskerStrokeWidth: 1,
802
+ outlierSize: 3,
803
+ outlierStroke: "black",
804
+ outlierFill: "none"
805
+ },
806
+ filters: [],
807
+ xAxis: chunkU74A5VK5_cjs.DEFAULT_CHART_SETTINGS.xAxis,
808
+ yAxis: chunkU74A5VK5_cjs.DEFAULT_CHART_SETTINGS.yAxis,
809
+ margin: chunkU74A5VK5_cjs.DEFAULT_CHART_SETTINGS.margin,
810
+ facet: chunkU74A5VK5_cjs.DEFAULT_CHART_SETTINGS.facet,
811
+ colorScaleId: void 0,
812
+ colorField: void 0,
813
+ xAxisLabel: "",
814
+ yAxisLabel: "",
815
+ xGridLines: 5,
816
+ yGridLines: 5
817
+ }),
818
+ validateSettings: (settings) => {
819
+ return !!settings.field;
820
+ },
821
+ getFilterFunction: (settings, fieldGetter) => {
822
+ if (!settings.colorField) {
823
+ return () => true;
824
+ }
825
+ const dataHash = fieldGetter(settings.colorField);
826
+ const filter = settings.filters.find(
827
+ (f) => f.field === settings.colorField
828
+ );
829
+ return (d) => {
830
+ const value = dataHash[d];
831
+ if (filter) {
832
+ if (!chunkEU5EFHO5_cjs.applyFilter(value, filter)) {
833
+ return false;
834
+ }
835
+ }
836
+ return true;
837
+ };
838
+ }
839
+ };
840
+
841
+ exports.boxPlotDefinition = boxPlotDefinition;
842
+ //# sourceMappingURL=chunk-GV2LRR32.cjs.map
843
+ //# sourceMappingURL=chunk-GV2LRR32.cjs.map