@haniffalab/cherita-react 1.4.1-dev.2025-08-13.6fc43290 → 1.4.1-dev.2025-08-13.8f63c242

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 (31) hide show
  1. package/dist/cjs/components/dotplot/Dotplot.js +12 -16
  2. package/dist/cjs/components/heatmap/Heatmap.js +11 -16
  3. package/dist/cjs/components/matrixplot/Matrixplot.js +11 -16
  4. package/dist/cjs/components/obs-list/ObsItem.js +14 -14
  5. package/dist/cjs/components/obs-list/ObsList.js +24 -23
  6. package/dist/cjs/components/pseudospatial/Pseudospatial.js +25 -31
  7. package/dist/cjs/components/scatterplot/Scatterplot.js +14 -23
  8. package/dist/cjs/components/scatterplot/ScatterplotControls.js +9 -3
  9. package/dist/cjs/components/var-list/VarList.js +16 -14
  10. package/dist/cjs/components/violin/Violin.js +21 -25
  11. package/dist/cjs/context/DatasetContext.js +4 -4
  12. package/dist/cjs/context/SettingsContext.js +175 -40
  13. package/dist/cjs/utils/Filter.js +15 -10
  14. package/dist/cjs/utils/Resolver.js +188 -0
  15. package/dist/cjs/utils/zarrData.js +16 -17
  16. package/dist/esm/components/dotplot/Dotplot.js +12 -16
  17. package/dist/esm/components/heatmap/Heatmap.js +11 -16
  18. package/dist/esm/components/matrixplot/Matrixplot.js +11 -16
  19. package/dist/esm/components/obs-list/ObsItem.js +14 -14
  20. package/dist/esm/components/obs-list/ObsList.js +24 -23
  21. package/dist/esm/components/pseudospatial/Pseudospatial.js +25 -31
  22. package/dist/esm/components/scatterplot/Scatterplot.js +14 -23
  23. package/dist/esm/components/scatterplot/ScatterplotControls.js +9 -3
  24. package/dist/esm/components/var-list/VarList.js +16 -14
  25. package/dist/esm/components/violin/Violin.js +21 -25
  26. package/dist/esm/context/DatasetContext.js +4 -4
  27. package/dist/esm/context/SettingsContext.js +176 -41
  28. package/dist/esm/utils/Filter.js +15 -10
  29. package/dist/esm/utils/Resolver.js +176 -0
  30. package/dist/esm/utils/zarrData.js +16 -17
  31. package/package.json +2 -2
@@ -10,6 +10,7 @@ exports.useSettingsDispatch = useSettingsDispatch;
10
10
  var _react = _interopRequireWildcard(require("react"));
11
11
  var _lodash = _interopRequireDefault(require("lodash"));
12
12
  var _constants = require("../constants/constants");
13
+ var _Resolver = require("../utils/Resolver");
13
14
  const _excluded = ["buster", "timestamp"];
14
15
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
16
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
@@ -22,20 +23,20 @@ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i
22
23
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
23
24
  const SettingsContext = exports.SettingsContext = /*#__PURE__*/(0, _react.createContext)(null);
24
25
  const SettingsDispatchContext = exports.SettingsDispatchContext = /*#__PURE__*/(0, _react.createContext)(null);
25
-
26
- // @TODO: consider splitting constant values and dataset-resolved values
27
- // e.g. store only obs name in selectedObs, and resolved obs data (counts, values, etc.) elsewhere
28
- // e.g. store only var name in selectedVar, and resolved var data (index, matrix_index) elsewhere
29
- // would simplify passing and validating defaultSettings and localSettings
30
26
  const initialSettings = {
31
27
  selectedObs: null,
28
+ // { name: "obs_name", omit: ["obs_item"], bins: {} }
32
29
  selectedVar: null,
30
+ // { name: "var_name", isSet: false } or { name: "var_set_name", isSet: true, vars: [{ name: "var1" }, { name: "var2" }] }
33
31
  selectedObsm: null,
34
- selectedMultiObs: [],
32
+ // "obsm_name" (e.g. "X_umap")
35
33
  selectedMultiVar: [],
36
- colorEncoding: null,
34
+ // [{ name: "var_name", isSet: false }, { name: "var_set_name", isSet: true, vars: [{ name: "var1" }, { name: "var2" }] }]
37
35
  labelObs: [],
36
+ // [ "obs_name1", "obs_name2" ]
38
37
  vars: [],
38
+ // [{ name: "var_name", isSet: false }, { name: "var_set_name", isSet: true, vars: [{ name: "var1" }, { name: "var2" }] }]
39
+ colorEncoding: null,
39
40
  sliceBy: {
40
41
  obs: false,
41
42
  polygons: false
@@ -43,8 +44,8 @@ const initialSettings = {
43
44
  polygons: {},
44
45
  controls: {
45
46
  colorScale: "Viridis",
46
- valueRange: [0, 1],
47
47
  range: [0, 1],
48
+ // normalized
48
49
  colorAxis: {
49
50
  dmin: 0,
50
51
  dmax: 1,
@@ -73,11 +74,19 @@ const initialSettings = {
73
74
  maskSet: null,
74
75
  maskValues: null,
75
76
  categoricalMode: _constants.PSEUDOSPATIAL_CATEGORICAL_MODES.ACROSS.value
77
+ },
78
+ // dataset resolved values
79
+ data: {
80
+ // store resolved obs and vars from selectedObs, selectedVar, selectedMultiVar, vars, labelObs
81
+ // keys to be removed when not in any selection
82
+ obs: {},
83
+ vars: {}
76
84
  }
77
85
  };
78
86
 
79
87
  // validate on initialization and reducer
80
88
  const validateSettings = settings => {
89
+ var _settings$selectedObs;
81
90
  // make sure selectedVar is in vars
82
91
  if (settings.selectedVar) {
83
92
  const inVars = _lodash.default.some(settings.vars, v => v.name === settings.selectedVar.name);
@@ -110,6 +119,18 @@ const validateSettings = settings => {
110
119
  settings.colorEncoding = null;
111
120
  }
112
121
  }
122
+
123
+ // @TODO: validate pseudospatial settings
124
+
125
+ // Keep only obs in use (selectedObs, labelObs) in data.obs
126
+ const obsNames = _lodash.default.uniq(_lodash.default.compact([(_settings$selectedObs = settings.selectedObs) === null || _settings$selectedObs === void 0 ? void 0 : _settings$selectedObs.name, ...settings.labelObs]));
127
+ const intersectionObs = _lodash.default.intersection(_lodash.default.keys(settings.data.obs), obsNames);
128
+ settings.data.obs = _lodash.default.pick(settings.data.obs, intersectionObs);
129
+
130
+ // Keep only vars in use (settings.vars) in data.vars
131
+ const varNames = _lodash.default.flatMap(settings.vars, v => v.isSet ? _lodash.default.map(v.vars, vv => vv.name) : v.name);
132
+ const intersectionVars = _lodash.default.intersection(_lodash.default.keys(settings.data.vars), varNames);
133
+ settings.data.vars = _lodash.default.pick(settings.data.vars, intersectionVars);
113
134
  return settings;
114
135
  };
115
136
  const initializer = _ref => {
@@ -121,6 +142,9 @@ const initializer = _ref => {
121
142
  const mergedSettings = canOverrideSettings ? _lodash.default.defaultsDeep({}, localSettings, defaultSettings, initialSettings) : _lodash.default.defaultsDeep({}, defaultSettings, initialSettings);
122
143
  return validateSettings(mergedSettings);
123
144
  };
145
+ const validate = settings => {
146
+ return settings ? validateSettings(settings) : null;
147
+ };
124
148
  function SettingsProvider(_ref2) {
125
149
  let {
126
150
  dataset_url,
@@ -140,21 +164,34 @@ function SettingsProvider(_ref2) {
140
164
 
141
165
  // If the buster is not set or does not match the current package version,
142
166
  // reset localSettings to avoid stale data
143
- if (!buster || buster !== "1.4.1-dev.2025-08-13.6fc43290") {
167
+ if (!buster || buster !== "1.4.1-dev.2025-08-13.8f63c242") {
144
168
  localSettings = {};
145
169
  }
146
- const [settings, dispatch] = (0, _react.useReducer)(settingsReducer, {
170
+ const initSettings = (0, _react.useRef)(initializer({
147
171
  canOverrideSettings,
148
172
  defaultSettings,
149
173
  localSettings
150
- }, initializer);
174
+ }));
175
+ const resolvedSettings = (0, _Resolver.useResolver)(initSettings.current);
176
+ const [settings, dispatch] = (0, _react.useReducer)(settingsReducer, resolvedSettings, validate);
177
+ (0, _react.useEffect)(() => {
178
+ // If resolvedSettings is null, do not update settings
179
+ if (resolvedSettings) {
180
+ const validatedSettings = validateSettings(resolvedSettings);
181
+ console.log("Initial settings:", validatedSettings);
182
+ dispatch({
183
+ type: "init",
184
+ settings: validatedSettings
185
+ });
186
+ }
187
+ }, [resolvedSettings]);
151
188
  (0, _react.useEffect)(() => {
152
189
  if (canOverrideSettings) {
153
190
  try {
154
- localStorage.setItem(DATASET_STORAGE_KEY, JSON.stringify(_objectSpread({
155
- buster: "1.4.1-dev.2025-08-13.6fc43290" || "0.0.0",
191
+ localStorage.setItem(DATASET_STORAGE_KEY, JSON.stringify(_objectSpread(_objectSpread({
192
+ buster: "1.4.1-dev.2025-08-13.8f63c242" || "0.0.0",
156
193
  timestamp: Date.now()
157
- }, settings)));
194
+ }, _lodash.default.omit(settings, "data")), settings)));
158
195
  } catch (err) {
159
196
  if (err.code === 22 || err.code === 1014 || err.name === "QuotaExceededError" || err.name === "NS_ERROR_DOM_QUOTA_REACHED") {
160
197
  console.err("Browser storage quota exceeded");
@@ -168,7 +205,7 @@ function SettingsProvider(_ref2) {
168
205
  value: settings
169
206
  }, /*#__PURE__*/_react.default.createElement(SettingsDispatchContext.Provider, {
170
207
  value: dispatch
171
- }, children));
208
+ }, settings && children));
172
209
  }
173
210
  function useSettings() {
174
211
  return (0, _react.useContext)(SettingsContext);
@@ -176,13 +213,70 @@ function useSettings() {
176
213
  function useSettingsDispatch() {
177
214
  return (0, _react.useContext)(SettingsDispatchContext);
178
215
  }
216
+ const OBS_DATA_KEYS = ["name", "type",
217
+ // categorical and numerical
218
+ "codes", "codesMap", "values", "n_values", "value_counts",
219
+ // numerical
220
+ "bins", "min", "max", "mean", "median", "n_unique"];
221
+ const splitObs = obs => {
222
+ if (!obs) return {
223
+ settings: null,
224
+ data: {}
225
+ };
226
+ const settings = _lodash.default.pick(obs, ["name", "omit", "bins"]);
227
+ const data = obs ? {
228
+ [obs.name]: _lodash.default.pick(obs, OBS_DATA_KEYS)
229
+ } : {};
230
+ return {
231
+ settings,
232
+ data
233
+ };
234
+ };
235
+ const splitVar = v => {
236
+ if (!v) return {
237
+ settings: null,
238
+ data: {}
239
+ };
240
+ let settings, data;
241
+ if (v.isSet) {
242
+ settings = _objectSpread(_objectSpread({}, _lodash.default.pick(v, ["name", "isSet"])), {}, {
243
+ vars: _lodash.default.map(v.vars, vv => ({
244
+ name: vv.name
245
+ }))
246
+ });
247
+ data = _lodash.default.fromPairs(_lodash.default.map(v.vars, vv => [vv.name, _lodash.default.pick(vv, ["name", "index", "matrix_index"])]));
248
+ } else {
249
+ settings = _lodash.default.pick(v, ["name", "isSet"]);
250
+ data = {
251
+ [v.name]: _lodash.default.pick(v, ["name", "index", "matrix_index"])
252
+ };
253
+ }
254
+ return {
255
+ settings,
256
+ data
257
+ };
258
+ };
179
259
  function settingsReducer(settings, action) {
180
260
  switch (action.type) {
261
+ case "init":
262
+ {
263
+ return action.settings;
264
+ }
181
265
  case "select.obs":
182
266
  {
183
267
  var _action$obs;
184
- return _objectSpread(_objectSpread({}, settings), {}, {
185
- selectedObs: action.obs,
268
+ const {
269
+ settings: obsSettings,
270
+ data: obsData
271
+ } = splitObs(action.obs);
272
+ return _objectSpread(_objectSpread(_objectSpread({}, settings), action.obs ? {
273
+ selectedObs: obsSettings,
274
+ data: _objectSpread(_objectSpread({}, settings.data), {}, {
275
+ obs: _objectSpread(_objectSpread({}, settings.data.obs), obsData)
276
+ })
277
+ } : {
278
+ selectedObs: null
279
+ }), {}, {
186
280
  controls: _objectSpread(_objectSpread({}, settings.controls), {}, {
187
281
  range: ((_action$obs = action.obs) === null || _action$obs === void 0 ? void 0 : _action$obs.type) === _constants.OBS_TYPES.CATEGORICAL ? [0, 1] : settings.controls.range
188
282
  }),
@@ -200,8 +294,15 @@ function settingsReducer(settings, action) {
200
294
  }
201
295
  case "select.var":
202
296
  {
297
+ const {
298
+ settings: varSettings,
299
+ data: varData
300
+ } = splitVar(action.var);
203
301
  return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
204
- selectedVar: action.var
302
+ selectedVar: varSettings,
303
+ data: _objectSpread(_objectSpread({}, settings.data), {}, {
304
+ vars: _objectSpread(_objectSpread({}, settings.data.vars), varData)
305
+ })
205
306
  }));
206
307
  }
207
308
  case "select.multivar":
@@ -210,8 +311,15 @@ function settingsReducer(settings, action) {
210
311
  if (inMultiVar) {
211
312
  return validateSettings(_objectSpread({}, settings));
212
313
  } else {
314
+ const {
315
+ settings: varSettings,
316
+ data: varData
317
+ } = splitVar(action.var);
213
318
  return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
214
- selectedMultiVar: [...settings.selectedMultiVar, action.var]
319
+ selectedMultiVar: [...settings.selectedMultiVar, varSettings],
320
+ data: _objectSpread(_objectSpread({}, settings.data), {}, {
321
+ vars: _objectSpread(_objectSpread({}, settings.data.vars), varData)
322
+ })
215
323
  }));
216
324
  }
217
325
  }
@@ -229,8 +337,15 @@ function settingsReducer(settings, action) {
229
337
  selectedMultiVar: settings.selectedMultiVar.filter(v => v.name !== action.var.name)
230
338
  }));
231
339
  } else {
340
+ const {
341
+ settings: varSettings,
342
+ data: varData
343
+ } = splitVar(action.var);
232
344
  return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
233
- selectedMultiVar: [...settings.selectedMultiVar, action.var]
345
+ selectedMultiVar: [...settings.selectedMultiVar, varSettings],
346
+ data: _objectSpread(_objectSpread({}, settings.data), {}, {
347
+ vars: _objectSpread(_objectSpread({}, settings.data.vars), varData)
348
+ })
234
349
  }));
235
350
  }
236
351
  }
@@ -265,8 +380,15 @@ function settingsReducer(settings, action) {
265
380
  if (settings.vars.find(v => v.name === action.var.name)) {
266
381
  return settings;
267
382
  } else {
383
+ const {
384
+ settings: varSettings,
385
+ data: varData
386
+ } = splitVar(action.var);
268
387
  return _objectSpread(_objectSpread({}, settings), {}, {
269
- vars: [...settings.vars, action.var]
388
+ vars: [...settings.vars, varSettings],
389
+ data: _objectSpread(_objectSpread({}, settings.data), {}, {
390
+ vars: _objectSpread(_objectSpread({}, settings.data.vars), varData)
391
+ })
270
392
  });
271
393
  }
272
394
  }
@@ -291,7 +413,11 @@ function settingsReducer(settings, action) {
291
413
  return settings;
292
414
  } else {
293
415
  var _settings$selectedVar2;
294
- const varSetVars = [...varSet.vars, action.var];
416
+ const {
417
+ settings: varSettings,
418
+ data: varData
419
+ } = splitVar(action.var);
420
+ const varSetVars = [...varSet.vars, varSettings];
295
421
  const vars = settings.vars.map(v => {
296
422
  if (v.name === varSet.name) {
297
423
  return _objectSpread(_objectSpread({}, v), {}, {
@@ -316,7 +442,10 @@ function settingsReducer(settings, action) {
316
442
  return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
317
443
  vars: vars,
318
444
  selectedVar: selectedVar,
319
- selectedMultiVar: selectedMultiVar
445
+ selectedMultiVar: selectedMultiVar,
446
+ data: _objectSpread(_objectSpread({}, settings.data), {}, {
447
+ vars: _objectSpread(_objectSpread({}, settings.data.vars), varData)
448
+ })
320
449
  }));
321
450
  }
322
451
  }
@@ -380,14 +509,6 @@ function settingsReducer(settings, action) {
380
509
  })
381
510
  });
382
511
  }
383
- case "set.controls.valueRange":
384
- {
385
- return _objectSpread(_objectSpread({}, settings), {}, {
386
- controls: _objectSpread(_objectSpread({}, settings.controls), {}, {
387
- valueRange: action.valueRange
388
- })
389
- });
390
- }
391
512
  case "set.controls.range":
392
513
  {
393
514
  return _objectSpread(_objectSpread({}, settings), {}, {
@@ -463,15 +584,22 @@ function settingsReducer(settings, action) {
463
584
  }
464
585
  case "toggle.slice.obs":
465
586
  {
466
- if (_lodash.default.isEqual(settings.selectedObs, action.obs)) {
587
+ if (settings.selectedObs && settings.selectedObs.name === action.obs.name) {
467
588
  return _objectSpread(_objectSpread({}, settings), {}, {
468
589
  sliceBy: _objectSpread(_objectSpread({}, settings.sliceBy), {}, {
469
590
  obs: !settings.sliceBy.obs
470
591
  })
471
592
  });
472
593
  } else {
594
+ const {
595
+ settings: obsSettings,
596
+ data: obsData
597
+ } = splitObs(action.obs);
473
598
  return _objectSpread(_objectSpread({}, settings), {}, {
474
- selectedObs: action.obs,
599
+ selectedObs: obsSettings,
600
+ data: _objectSpread(_objectSpread({}, settings.data), {}, {
601
+ obs: _objectSpread(_objectSpread({}, settings.data.obs), obsData)
602
+ }),
475
603
  sliceBy: _objectSpread(_objectSpread({}, settings.sliceBy), {}, {
476
604
  obs: true
477
605
  })
@@ -496,25 +624,32 @@ function settingsReducer(settings, action) {
496
624
  }
497
625
  case "add.label.obs":
498
626
  {
499
- if (settings.labelObs.find(i => _lodash.default.isEqual(i, action.obs))) {
627
+ if (_lodash.default.includes(settings.labelObs, action.obs.name)) {
500
628
  return settings;
501
629
  } else {
630
+ const {
631
+ settings: obsSettings,
632
+ data: obsData
633
+ } = splitObs(action.obs);
502
634
  return _objectSpread(_objectSpread({}, settings), {}, {
503
- labelObs: [...settings.labelObs, action.obs]
635
+ labelObs: [...settings.labelObs, obsSettings.name],
636
+ data: _objectSpread(_objectSpread({}, settings.data), {}, {
637
+ obs: _objectSpread(_objectSpread({}, settings.data.obs), obsData)
638
+ })
504
639
  });
505
640
  }
506
641
  }
507
642
  case "remove.label.obs":
508
643
  {
509
- return _objectSpread(_objectSpread({}, settings), {}, {
510
- labelObs: settings.labelObs.filter(a => a.name !== action.obsName)
511
- });
644
+ return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
645
+ labelObs: settings.labelObs.filter(a => a !== action.obsName)
646
+ }));
512
647
  }
513
648
  case "reset.label.obs":
514
649
  {
515
- return _objectSpread(_objectSpread({}, settings), {}, {
650
+ return validateSettings(_objectSpread(_objectSpread({}, settings), {}, {
516
651
  labelObs: []
517
- });
652
+ }));
518
653
  }
519
654
  case "set.varSort":
520
655
  {
@@ -7,6 +7,7 @@ exports.useFilter = void 0;
7
7
  var _react = require("react");
8
8
  var _turf = require("@turf/turf");
9
9
  var _lodash = _interopRequireDefault(require("lodash"));
10
+ var _Resolver = require("./Resolver");
10
11
  var _constants = require("../constants/constants");
11
12
  var _FilterContext = require("../context/FilterContext");
12
13
  var _SettingsContext = require("../context/SettingsContext");
@@ -36,9 +37,14 @@ const isInValues = (omit, value) => {
36
37
  return !_lodash.default.includes(omit, value);
37
38
  };
38
39
  const useFilter = data => {
39
- var _settings$selectedObs, _settings$selectedObs2, _settings$selectedObs3, _settings$selectedObs4, _settings$selectedObs7, _settings$selectedObs8;
40
+ var _selectedObs$omit, _selectedObs$bins2;
40
41
  const settings = (0, _SettingsContext.useSettings)();
41
42
  const filterDataDispatch = (0, _FilterContext.useFilteredDataDispatch)();
43
+ const selectedObs = (0, _Resolver.useSelectedObs)();
44
+ const omitCodes = _lodash.default.map((selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.omit) || [], o => {
45
+ var _selectedObs$codes;
46
+ return selectedObs === null || selectedObs === void 0 || (_selectedObs$codes = selectedObs.codes) === null || _selectedObs$codes === void 0 ? void 0 : _selectedObs$codes[o];
47
+ });
42
48
  const {
43
49
  obsmData,
44
50
  xData,
@@ -46,26 +52,25 @@ const useFilter = data => {
46
52
  isPending,
47
53
  serverError
48
54
  } = data;
49
- const isCategorical = ((_settings$selectedObs = settings.selectedObs) === null || _settings$selectedObs === void 0 ? void 0 : _settings$selectedObs.type) === _constants.OBS_TYPES.CATEGORICAL || ((_settings$selectedObs2 = settings.selectedObs) === null || _settings$selectedObs2 === void 0 ? void 0 : _settings$selectedObs2.type) === _constants.OBS_TYPES.BOOLEAN;
50
- const isContinuous = ((_settings$selectedObs3 = settings.selectedObs) === null || _settings$selectedObs3 === void 0 ? void 0 : _settings$selectedObs3.type) === _constants.OBS_TYPES.CONTINUOUS;
51
- const sliceByObs = settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS && !!((_settings$selectedObs4 = settings.selectedObs) !== null && _settings$selectedObs4 !== void 0 && _settings$selectedObs4.omit.length) || settings.sliceBy.obs;
55
+ const isCategorical = (selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.type) === _constants.OBS_TYPES.CATEGORICAL || (selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.type) === _constants.OBS_TYPES.BOOLEAN;
56
+ const isContinuous = (selectedObs === null || selectedObs === void 0 ? void 0 : selectedObs.type) === _constants.OBS_TYPES.CONTINUOUS;
57
+ const sliceByObs = settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS && !!(selectedObs !== null && selectedObs !== void 0 && (_selectedObs$omit = selectedObs.omit) !== null && _selectedObs$omit !== void 0 && _selectedObs$omit.length) || settings.sliceBy.obs;
52
58
  const isInObsSlice = (0, _react.useCallback)((index, values) => {
53
59
  let inSlice = true;
54
60
  if (values && sliceByObs) {
55
61
  if (isCategorical) {
56
- var _settings$selectedObs5;
57
- inSlice &= isInValues((_settings$selectedObs5 = settings.selectedObs) === null || _settings$selectedObs5 === void 0 ? void 0 : _settings$selectedObs5.omit, values[index]);
62
+ inSlice &= isInValues(omitCodes, values[index]);
58
63
  } else if (isContinuous) {
59
64
  if (isNaN(values[index])) {
60
- var _settings$selectedObs6;
61
- inSlice &= isInValues((_settings$selectedObs6 = settings.selectedObs) === null || _settings$selectedObs6 === void 0 ? void 0 : _settings$selectedObs6.omit, -1);
65
+ inSlice &= isInValues(omitCodes, -1);
62
66
  } else {
63
- inSlice &= isInBins(values[index], settings.selectedObs.bins.binEdges, _lodash.default.without(settings.selectedObs.omit, -1));
67
+ var _selectedObs$bins;
68
+ inSlice &= isInBins(values[index], selectedObs === null || selectedObs === void 0 || (_selectedObs$bins = selectedObs.bins) === null || _selectedObs$bins === void 0 ? void 0 : _selectedObs$bins.binEdges, _lodash.default.without(omitCodes, -1));
64
69
  }
65
70
  }
66
71
  }
67
72
  return inSlice;
68
- }, [(_settings$selectedObs7 = settings.selectedObs) === null || _settings$selectedObs7 === void 0 || (_settings$selectedObs7 = _settings$selectedObs7.bins) === null || _settings$selectedObs7 === void 0 ? void 0 : _settings$selectedObs7.binEdges, (_settings$selectedObs8 = settings.selectedObs) === null || _settings$selectedObs8 === void 0 ? void 0 : _settings$selectedObs8.omit, isCategorical, isContinuous, sliceByObs]);
73
+ }, [sliceByObs, isCategorical, isContinuous, omitCodes, selectedObs === null || selectedObs === void 0 || (_selectedObs$bins2 = selectedObs.bins) === null || _selectedObs$bins2 === void 0 ? void 0 : _selectedObs$bins2.binEdges]);
69
74
  const isInPolygonsSlice = (0, _react.useCallback)((index, positions) => {
70
75
  let inSlice = true;
71
76
  if (settings.sliceBy.polygons && positions) {
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useSettingsVars = exports.useSelectedVar = exports.useSelectedObs = exports.useSelectedMultiVar = exports.useResolver = void 0;
7
+ var _react = require("react");
8
+ var _lodash = _interopRequireDefault(require("lodash"));
9
+ var _requests = require("./requests");
10
+ var _DatasetContext = require("../context/DatasetContext");
11
+ var _SettingsContext = require("../context/SettingsContext");
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
14
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
15
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
16
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
17
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
18
+ const cleanSettings = settings => {
19
+ // Remove obs and vars from settings that are not in data
20
+
21
+ const selectedObs = settings.selectedObs && settings.data.obs[settings.selectedObs.name] ? settings.selectedObs : null;
22
+ const labelObs = _lodash.default.filter(settings.labelObs, obsName => settings.data.obs[obsName]);
23
+ const selectedVar = settings.selectedVar && (settings.selectedVar.isSet ? _lodash.default.every(settings.selectedVar.vars, vv => settings.data.vars[vv.name]) : settings.data.vars[settings.selectedVar.name]) ? settings.selectedVar : null;
24
+ const selectedMultiVar = _lodash.default.filter(settings.selectedMultiVar, v => {
25
+ if (v.isSet) {
26
+ return _lodash.default.every(v.vars, vv => settings.data.vars[vv.name]);
27
+ } else {
28
+ return settings.data.vars[v.name];
29
+ }
30
+ });
31
+ const vars = _lodash.default.filter(settings.vars, v => {
32
+ if (v.isSet) {
33
+ return _lodash.default.every(v.vars, vv => settings.data.vars[vv.name]);
34
+ } else {
35
+ return settings.data.vars[v.name];
36
+ }
37
+ });
38
+ return _objectSpread(_objectSpread({}, settings), {}, {
39
+ selectedObs: selectedObs,
40
+ labelObs: labelObs,
41
+ selectedVar: selectedVar,
42
+ selectedMultiVar: selectedMultiVar,
43
+ vars: vars
44
+ });
45
+ };
46
+ const useResolver = initSettings => {
47
+ var _initSettings$selecte;
48
+ const dataset = (0, _DatasetContext.useDataset)();
49
+ const [data, setData] = (0, _react.useState)({
50
+ obs: {},
51
+ vars: {}
52
+ });
53
+ const [resolvedObs, setResolvedObs] = (0, _react.useState)(false);
54
+ const [resolvedVars, setResolvedVars] = (0, _react.useState)(false);
55
+ const [resolvedSettings, setResolvedSettings] = (0, _react.useState)(null);
56
+
57
+ // obs
58
+ // all obs should be in initSettings.selectedObs and initSettings.labelObs
59
+ const initObs = _lodash.default.uniqBy(_lodash.default.compact([initSettings.selectedObs, ..._lodash.default.map(initSettings.labelObs, o => ({
60
+ name: o
61
+ }))]), "name");
62
+ const initObsNames = _lodash.default.map(initObs, o => o.name);
63
+ const [obsParams] = (0, _react.useState)({
64
+ url: dataset.url,
65
+ cols: initObsNames,
66
+ obsParams: _lodash.default.fromPairs(_lodash.default.map(initObs, o => [o.name, {
67
+ bins: o.bins || {}
68
+ }]))
69
+ });
70
+ const {
71
+ fetchedData: obsData,
72
+ isPending: obsDataPending,
73
+ serverError: obsDataError
74
+ } = (0, _requests.useFetch)("obs/cols", obsParams, {
75
+ enabled: !!initObsNames.length
76
+ });
77
+
78
+ // vars
79
+ // all vars should be in initSettings.vars from validation
80
+ const initVars = initSettings.vars;
81
+ const initVarsNames = _lodash.default.flatMap(initVars, v => v.isSet ? _lodash.default.map(v.vars, vv => vv.name) : v.name);
82
+ const [varParams] = (0, _react.useState)({
83
+ url: dataset.url,
84
+ col: dataset.varNamesCol,
85
+ names: initVarsNames
86
+ });
87
+ const {
88
+ fetchedData: varData,
89
+ isPending: varDataPending,
90
+ serverError: varDataError
91
+ } = (0, _requests.useFetch)("var/cols/names", varParams, {
92
+ enabled: !!varParams.names.length
93
+ });
94
+ (0, _react.useEffect)(() => {
95
+ if (!obsDataPending) {
96
+ if (obsDataError) {
97
+ console.error("Error fetching obs data:", obsDataError);
98
+ setResolvedObs(true);
99
+ return;
100
+ }
101
+ if (obsData) {
102
+ setData(d => _objectSpread(_objectSpread({}, d), {}, {
103
+ obs: _lodash.default.fromPairs(_lodash.default.map(obsData, o => [o.name, o]))
104
+ }));
105
+ }
106
+ setResolvedObs(true);
107
+ }
108
+ }, [obsData, obsDataError, obsDataPending, (_initSettings$selecte = initSettings.selectedObs) === null || _initSettings$selecte === void 0 ? void 0 : _initSettings$selecte.omit]);
109
+ (0, _react.useEffect)(() => {
110
+ if (!varDataPending) {
111
+ if (varDataError) {
112
+ console.error("Error fetching var data:", varDataError);
113
+ setResolvedVars(true);
114
+ return;
115
+ }
116
+ if (varData) {
117
+ setData(d => _objectSpread(_objectSpread({}, d), {}, {
118
+ vars: _lodash.default.fromPairs(_lodash.default.map(varData, v => [v.name, v]))
119
+ }));
120
+ }
121
+ setResolvedVars(true);
122
+ }
123
+ }, [initSettings.vars, varData, varDataError, varDataPending]);
124
+ (0, _react.useEffect)(() => {
125
+ if (resolvedObs && resolvedVars) {
126
+ const cleanedSettings = cleanSettings(_objectSpread(_objectSpread({}, initSettings), {}, {
127
+ data: data
128
+ }));
129
+ setResolvedSettings(cleanedSettings);
130
+ }
131
+ }, [data, initSettings, resolvedObs, resolvedVars, setResolvedSettings]);
132
+ return resolvedSettings;
133
+ };
134
+ exports.useResolver = useResolver;
135
+ const useSelectedObs = () => {
136
+ const settings = (0, _SettingsContext.useSettings)();
137
+ return (0, _react.useMemo)(() => {
138
+ return settings.selectedObs ? _objectSpread(_objectSpread({}, settings.selectedObs), settings.data.obs[settings.selectedObs.name]) : null;
139
+ }, [settings.data.obs, settings.selectedObs]);
140
+ };
141
+ exports.useSelectedObs = useSelectedObs;
142
+ const useSelectedVar = () => {
143
+ const settings = (0, _SettingsContext.useSettings)();
144
+ return (0, _react.useMemo)(() => {
145
+ if (settings.selectedVar) {
146
+ if (settings.selectedVar.isSet) {
147
+ return _objectSpread(_objectSpread({}, settings.selectedVar), {}, {
148
+ vars: settings.selectedVar.vars.map(v => _objectSpread({}, settings.data.vars[v.name]))
149
+ });
150
+ } else {
151
+ return _objectSpread(_objectSpread({}, settings.selectedVar), settings.data.vars[settings.selectedVar.name]);
152
+ }
153
+ } else {
154
+ return null;
155
+ }
156
+ }, [settings.data.vars, settings.selectedVar]);
157
+ };
158
+ exports.useSelectedVar = useSelectedVar;
159
+ const useSelectedMultiVar = () => {
160
+ const settings = (0, _SettingsContext.useSettings)();
161
+ return (0, _react.useMemo)(() => {
162
+ return _lodash.default.map(settings.selectedMultiVar, v => {
163
+ if (v.isSet) {
164
+ return _objectSpread(_objectSpread({}, v), {}, {
165
+ vars: v.vars.map(vv => _objectSpread({}, settings.data.vars[vv.name]))
166
+ });
167
+ } else {
168
+ return _objectSpread(_objectSpread({}, v), settings.data.vars[v.name]);
169
+ }
170
+ });
171
+ }, [settings.data.vars, settings.selectedMultiVar]);
172
+ };
173
+ exports.useSelectedMultiVar = useSelectedMultiVar;
174
+ const useSettingsVars = () => {
175
+ const settings = (0, _SettingsContext.useSettings)();
176
+ return (0, _react.useMemo)(() => {
177
+ return _lodash.default.map(settings.vars, v => {
178
+ if (v.isSet) {
179
+ return _objectSpread(_objectSpread({}, v), {}, {
180
+ vars: v.vars.map(vv => _objectSpread({}, settings.data.vars[vv.name]))
181
+ });
182
+ } else {
183
+ return _objectSpread(_objectSpread({}, v), settings.data.vars[v.name]);
184
+ }
185
+ });
186
+ }, [settings.data.vars, settings.vars]);
187
+ };
188
+ exports.useSettingsVars = useSettingsVars;